Mercurial > mplayer.hg
annotate libmpcodecs/ad_qtaudio.c @ 11623:ecaf7047b6e8
Patch from the author, Zoltan Hidvegi:
The filmdint filter does not handle NTSC "telecined" 15fps movies
where there is a frame break in the middle of every second NTSC frame,
it outputs only 15 frames for every 30 input frames, ignoring the io
option. You can notice this during encoding such a sequence you will
have lots of diplicate frames / skip frames messages. The patch below
fixes this.
author | rfelker |
---|---|
date | Thu, 11 Dec 2003 04:47:42 +0000 |
parents | 43c6bc4e7e2f |
children | 574f7747d26f |
rev | line source |
---|---|
8008 | 1 #include <stdio.h> |
2 #include <stdlib.h> | |
3 #include <unistd.h> | |
4 #include <inttypes.h> | |
5 | |
6 #include "config.h" | |
7 | |
9502
241bba8f60e8
MACOSX support patch, based on Dan Christiansens work
alex
parents:
9405
diff
changeset
|
8 #if defined(USE_QTX_CODECS) || defined(MACOSX) |
8008 | 9 |
10 #include "ad_internal.h" | |
11 #include "bswap.h" | |
12 | |
9405
a4444e7ee56a
real cygwin support by Sascha Sommer <saschasommer@freenet.de>
alex
parents:
8632
diff
changeset
|
13 #ifdef WIN32_LOADER |
8451 | 14 #include "ldt_keeper.h" |
15 #endif | |
16 | |
9502
241bba8f60e8
MACOSX support patch, based on Dan Christiansens work
alex
parents:
9405
diff
changeset
|
17 #ifdef MACOSX |
241bba8f60e8
MACOSX support patch, based on Dan Christiansens work
alex
parents:
9405
diff
changeset
|
18 #include <QuickTime/QuickTimeComponents.h> |
241bba8f60e8
MACOSX support patch, based on Dan Christiansens work
alex
parents:
9405
diff
changeset
|
19 #endif |
241bba8f60e8
MACOSX support patch, based on Dan Christiansens work
alex
parents:
9405
diff
changeset
|
20 |
8008 | 21 static ad_info_t info = { |
22 "QuickTime Audio Decoder", | |
23 "qtaudio", | |
24 "A'rpi", | |
25 "Sascha Sommer", | |
26 "uses win32 quicktime DLLs" | |
27 }; | |
28 | |
29 LIBAD_EXTERN(qtaudio) | |
30 | |
9502
241bba8f60e8
MACOSX support patch, based on Dan Christiansens work
alex
parents:
9405
diff
changeset
|
31 #ifdef USE_QTX_CODECS |
8008 | 32 typedef struct OpaqueSoundConverter* SoundConverter; |
33 typedef unsigned long OSType; | |
34 typedef unsigned long UnsignedFixed; | |
35 typedef uint8_t Byte; | |
36 typedef struct SoundComponentData { | |
37 long flags; | |
38 OSType format; | |
39 short numChannels; | |
40 short sampleSize; | |
41 UnsignedFixed sampleRate; | |
42 long sampleCount; | |
43 Byte * buffer; | |
44 long reserved; | |
45 }SoundComponentData; | |
46 | |
47 typedef int (__cdecl* LPFUNC1)(long flag); | |
48 typedef int (__cdecl* LPFUNC2)(const SoundComponentData *, const SoundComponentData *,SoundConverter *); | |
49 typedef int (__cdecl* LPFUNC3)(SoundConverter sc); | |
50 typedef int (__cdecl* LPFUNC4)(void); | |
51 typedef int (__cdecl* LPFUNC5)(SoundConverter sc, OSType selector,void * infoPtr); | |
52 typedef int (__cdecl* LPFUNC6)(SoundConverter sc, | |
53 unsigned long inputBytesTarget, | |
54 unsigned long *inputFrames, | |
55 unsigned long *inputBytes, | |
56 unsigned long *outputBytes ); | |
57 typedef int (__cdecl* LPFUNC7)(SoundConverter sc, | |
58 const void *inputPtr, | |
59 unsigned long inputFrames, | |
60 void *outputPtr, | |
61 unsigned long *outputFrames, | |
62 unsigned long *outputBytes ); | |
63 typedef int (__cdecl* LPFUNC8)(SoundConverter sc, | |
64 void *outputPtr, | |
65 unsigned long *outputFrames, | |
66 unsigned long *outputBytes); | |
67 typedef int (__cdecl* LPFUNC9)(SoundConverter sc) ; | |
68 | |
69 static HINSTANCE qtml_dll; | |
70 static LPFUNC1 InitializeQTML; | |
71 static LPFUNC2 SoundConverterOpen; | |
72 static LPFUNC3 SoundConverterClose; | |
73 static LPFUNC4 TerminateQTML; | |
74 static LPFUNC5 SoundConverterSetInfo; | |
75 static LPFUNC6 SoundConverterGetBufferSizes; | |
76 static LPFUNC7 SoundConverterConvertBuffer; | |
77 static LPFUNC8 SoundConverterEndConversion; | |
78 static LPFUNC9 SoundConverterBeginConversion; | |
79 | |
80 #define siDecompressionParams 2002876005 // siDecompressionParams = FOUR_CHAR_CODE('wave') | |
81 | |
82 HMODULE WINAPI LoadLibraryA(LPCSTR); | |
83 FARPROC WINAPI GetProcAddress(HMODULE,LPCSTR); | |
84 int WINAPI FreeLibrary(HMODULE); | |
85 | |
86 static int loader_init() | |
87 { | |
88 | |
9405
a4444e7ee56a
real cygwin support by Sascha Sommer <saschasommer@freenet.de>
alex
parents:
8632
diff
changeset
|
89 #ifdef WIN32_LOADER |
8270 | 90 Setup_LDT_Keeper(); |
91 #endif | |
8008 | 92 qtml_dll = LoadLibraryA("qtmlClient.dll"); |
93 if( qtml_dll == NULL ) | |
94 { | |
95 printf("failed loading dll\n" ); | |
96 return 1; | |
97 } | |
98 #if 1 | |
99 InitializeQTML = (LPFUNC1)GetProcAddress(qtml_dll,"InitializeQTML"); | |
100 if ( InitializeQTML == NULL ) | |
101 { | |
102 printf("failed geting proc address InitializeQTML\n"); | |
103 return 1; | |
104 } | |
105 SoundConverterOpen = (LPFUNC2)GetProcAddress(qtml_dll,"SoundConverterOpen"); | |
106 if ( SoundConverterOpen == NULL ) | |
107 { | |
108 printf("failed getting proc address SoundConverterOpen\n"); | |
109 return 1; | |
110 } | |
111 SoundConverterClose = (LPFUNC3)GetProcAddress(qtml_dll,"SoundConverterClose"); | |
112 if ( SoundConverterClose == NULL ) | |
113 { | |
114 printf("failed getting proc address SoundConverterClose\n"); | |
115 return 1; | |
116 } | |
117 TerminateQTML = (LPFUNC4)GetProcAddress(qtml_dll,"TerminateQTML"); | |
118 if ( TerminateQTML == NULL ) | |
119 { | |
120 printf("failed getting proc address TerminateQTML\n"); | |
121 return 1; | |
122 } | |
123 SoundConverterSetInfo = (LPFUNC5)GetProcAddress(qtml_dll,"SoundConverterSetInfo"); | |
124 if ( SoundConverterSetInfo == NULL ) | |
125 { | |
126 printf("failed getting proc address SoundConverterSetInfo\n"); | |
127 return 1; | |
128 } | |
129 SoundConverterGetBufferSizes = (LPFUNC6)GetProcAddress(qtml_dll,"SoundConverterGetBufferSizes"); | |
130 if ( SoundConverterGetBufferSizes == NULL ) | |
131 { | |
132 printf("failed getting proc address SoundConverterGetBufferSizes\n"); | |
133 return 1; | |
134 } | |
135 SoundConverterConvertBuffer = (LPFUNC7)GetProcAddress(qtml_dll,"SoundConverterConvertBuffer"); | |
136 if ( SoundConverterConvertBuffer == NULL ) | |
137 { | |
138 printf("failed getting proc address SoundConverterConvertBuffer1\n"); | |
139 return 1; | |
140 } | |
141 SoundConverterEndConversion = (LPFUNC8)GetProcAddress(qtml_dll,"SoundConverterEndConversion"); | |
142 if ( SoundConverterEndConversion == NULL ) | |
143 { | |
144 printf("failed getting proc address SoundConverterEndConversion\n"); | |
145 return 1; | |
146 } | |
147 SoundConverterBeginConversion = (LPFUNC9)GetProcAddress(qtml_dll,"SoundConverterBeginConversion"); | |
148 if ( SoundConverterBeginConversion == NULL ) | |
149 { | |
150 printf("failed getting proc address SoundConverterBeginConversion\n"); | |
151 return 1; | |
152 } | |
153 printf("Standard init done you may now call supported functions\n"); | |
154 #endif | |
155 printf("loader_init DONE???\n"); | |
156 return 0; | |
157 } | |
9502
241bba8f60e8
MACOSX support patch, based on Dan Christiansens work
alex
parents:
9405
diff
changeset
|
158 #endif /* USE_QTX_CODECS */ |
8008 | 159 |
160 static SoundConverter myConverter = NULL; | |
161 static SoundComponentData InputFormatInfo,OutputFormatInfo; | |
162 | |
163 static int InFrameSize; | |
164 static int OutFrameSize; | |
165 | |
166 static int preinit(sh_audio_t *sh){ | |
167 int error; | |
168 unsigned long FramesToGet=0; //how many frames the demuxer has to get | |
169 unsigned long InputBufferSize=0; //size of the input buffer | |
170 unsigned long OutputBufferSize=0; //size of the output buffer | |
171 unsigned long WantedBufferSize=0; //the size you want your buffers to be | |
172 | |
173 printf("win32 libquicktime loader (c) Sascha Sommer\n"); | |
174 | |
9502
241bba8f60e8
MACOSX support patch, based on Dan Christiansens work
alex
parents:
9405
diff
changeset
|
175 #ifdef MACOSX |
241bba8f60e8
MACOSX support patch, based on Dan Christiansens work
alex
parents:
9405
diff
changeset
|
176 EnterMovies(); |
241bba8f60e8
MACOSX support patch, based on Dan Christiansens work
alex
parents:
9405
diff
changeset
|
177 #else |
8008 | 178 if(loader_init()) return 0; // failed to load DLL |
179 | |
180 printf("loader_init DONE!\n"); | |
181 | |
8159 | 182 error = InitializeQTML(6+16); |
8008 | 183 printf("InitializeQTML:%i\n",error); |
184 if(error) return 0; | |
9694 | 185 #endif |
8008 | 186 |
9694 | 187 #if 1 |
8008 | 188 OutputFormatInfo.flags = InputFormatInfo.flags = 0; |
189 OutputFormatInfo.sampleCount = InputFormatInfo.sampleCount = 0; | |
190 OutputFormatInfo.buffer = InputFormatInfo.buffer = NULL; | |
191 OutputFormatInfo.reserved = InputFormatInfo.reserved = 0; | |
192 OutputFormatInfo.numChannels = InputFormatInfo.numChannels = sh->wf->nChannels; | |
8159 | 193 InputFormatInfo.sampleSize = sh->wf->wBitsPerSample; |
194 OutputFormatInfo.sampleSize = 16; | |
8008 | 195 OutputFormatInfo.sampleRate = InputFormatInfo.sampleRate = sh->wf->nSamplesPerSec; |
196 InputFormatInfo.format = bswap_32(sh->format); //1363430706;///*1768775988;//*/1902406962;//qdm2//1768775988;//FOUR_CHAR_CODE('ima4'); | |
197 OutputFormatInfo.format = 1313820229;// FOUR_CHAR_CODE('NONE'); | |
198 | |
199 error = SoundConverterOpen(&InputFormatInfo, &OutputFormatInfo, &myConverter); | |
200 printf("SoundConverterOpen:%i\n",error); | |
201 if(error) return 0; | |
202 | |
203 if(sh->codecdata){ | |
204 error = SoundConverterSetInfo(myConverter,siDecompressionParams,sh->codecdata); | |
205 printf("SoundConverterSetInfo:%i\n",error); | |
8632
9cecfb883d85
don't abort if setparams failed - fixes some Qclp files
arpi
parents:
8451
diff
changeset
|
206 // if(error) return 0; |
8008 | 207 } |
208 | |
209 WantedBufferSize=OutputFormatInfo.numChannels*OutputFormatInfo.sampleRate*2; | |
210 error = SoundConverterGetBufferSizes(myConverter, | |
211 WantedBufferSize,&FramesToGet,&InputBufferSize,&OutputBufferSize); | |
8123
9fc45fe0d444
*HUGE* set of compiler warning fixes, unused variables removal
arpi
parents:
8008
diff
changeset
|
212 printf("SoundConverterGetBufferSizes:%i\n",error); |
9fc45fe0d444
*HUGE* set of compiler warning fixes, unused variables removal
arpi
parents:
8008
diff
changeset
|
213 printf("WantedBufferSize = %li\n",WantedBufferSize); |
9fc45fe0d444
*HUGE* set of compiler warning fixes, unused variables removal
arpi
parents:
8008
diff
changeset
|
214 printf("InputBufferSize = %li\n",InputBufferSize); |
9fc45fe0d444
*HUGE* set of compiler warning fixes, unused variables removal
arpi
parents:
8008
diff
changeset
|
215 printf("OutputBufferSize = %li\n",OutputBufferSize); |
9fc45fe0d444
*HUGE* set of compiler warning fixes, unused variables removal
arpi
parents:
8008
diff
changeset
|
216 printf("FramesToGet = %li\n",FramesToGet); |
8008 | 217 |
8389
e8c51ec86340
fixed in/out framesize rounding bug (causing low-rate QCLP hangup/looping)
arpi
parents:
8270
diff
changeset
|
218 InFrameSize=(InputBufferSize+FramesToGet-1)/FramesToGet; |
8008 | 219 OutFrameSize=OutputBufferSize/FramesToGet; |
220 | |
221 printf("FrameSize: %i -> %i\n",InFrameSize,OutFrameSize); | |
222 | |
223 error = SoundConverterBeginConversion(myConverter); | |
224 printf("SoundConverterBeginConversion:%i\n",error); | |
225 if(error) return 0; | |
226 | |
227 sh->audio_out_minsize=OutputBufferSize; | |
228 sh->audio_in_minsize=InputBufferSize; | |
229 | |
230 sh->channels=sh->wf->nChannels; | |
231 sh->samplerate=sh->wf->nSamplesPerSec; | |
8159 | 232 sh->samplesize=2; //(sh->wf->wBitsPerSample+7)/8; |
8008 | 233 |
234 sh->i_bps=sh->wf->nAvgBytesPerSec; | |
235 //InputBufferSize*WantedBufferSize/OutputBufferSize; | |
236 | |
237 #endif | |
8159 | 238 |
239 if(sh->format==0x3343414D){ | |
240 // MACE 3:1 | |
241 sh->ds->ss_div = 2*3; // 1 samples/packet | |
242 sh->ds->ss_mul = sh->channels*2*1; // 1 bytes/packet | |
243 } else | |
244 if(sh->format==0x3643414D){ | |
245 // MACE 6:1 | |
246 sh->ds->ss_div = 2*6; // 1 samples/packet | |
247 sh->ds->ss_mul = sh->channels*2*1; // 1 bytes/packet | |
248 } | |
249 | |
8008 | 250 return 1; // return values: 1=OK 0=ERROR |
251 } | |
252 | |
253 static int init(sh_audio_t *sh_audio){ | |
254 | |
255 return 1; // return values: 1=OK 0=ERROR | |
256 } | |
257 | |
258 static void uninit(sh_audio_t *sh){ | |
259 int error; | |
260 unsigned long ConvertedFrames=0; | |
261 unsigned long ConvertedBytes=0; | |
262 error=SoundConverterEndConversion(myConverter,NULL,&ConvertedFrames,&ConvertedBytes); | |
263 printf("SoundConverterEndConversion:%i\n",error); | |
264 error = SoundConverterClose(myConverter); | |
265 printf("SoundConverterClose:%i\n",error); | |
8389
e8c51ec86340
fixed in/out framesize rounding bug (causing low-rate QCLP hangup/looping)
arpi
parents:
8270
diff
changeset
|
266 // error = TerminateQTML(); |
e8c51ec86340
fixed in/out framesize rounding bug (causing low-rate QCLP hangup/looping)
arpi
parents:
8270
diff
changeset
|
267 // printf("TerminateQTML:%i\n",error); |
e8c51ec86340
fixed in/out framesize rounding bug (causing low-rate QCLP hangup/looping)
arpi
parents:
8270
diff
changeset
|
268 // FreeLibrary( qtml_dll ); |
e8c51ec86340
fixed in/out framesize rounding bug (causing low-rate QCLP hangup/looping)
arpi
parents:
8270
diff
changeset
|
269 // qtml_dll = NULL; |
e8c51ec86340
fixed in/out framesize rounding bug (causing low-rate QCLP hangup/looping)
arpi
parents:
8270
diff
changeset
|
270 // printf("qt dll loader uninit done\n"); |
9502
241bba8f60e8
MACOSX support patch, based on Dan Christiansens work
alex
parents:
9405
diff
changeset
|
271 #ifdef MACOSX |
241bba8f60e8
MACOSX support patch, based on Dan Christiansens work
alex
parents:
9405
diff
changeset
|
272 ExitMovies(); |
241bba8f60e8
MACOSX support patch, based on Dan Christiansens work
alex
parents:
9405
diff
changeset
|
273 #endif |
8008 | 274 } |
275 | |
276 static int decode_audio(sh_audio_t *sh,unsigned char *buf,int minlen,int maxlen){ | |
277 int error; | |
278 unsigned long FramesToGet=0; //how many frames the demuxer has to get | |
279 unsigned long InputBufferSize=0; //size of the input buffer | |
280 unsigned long ConvertedFrames=0; | |
281 unsigned long ConvertedBytes=0; | |
282 | |
283 FramesToGet=minlen/OutFrameSize; | |
284 if(FramesToGet*OutFrameSize<minlen && | |
285 (FramesToGet+1)*OutFrameSize<=maxlen) ++FramesToGet; | |
286 if(FramesToGet*InFrameSize>sh->a_in_buffer_size) | |
287 FramesToGet=sh->a_in_buffer_size/InFrameSize; | |
288 | |
289 InputBufferSize=FramesToGet*InFrameSize; | |
290 | |
8159 | 291 // printf("FramesToGet = %li (%li -> %li bytes)\n",FramesToGet, |
292 // InputBufferSize, FramesToGet*OutFrameSize); | |
8008 | 293 |
294 if(InputBufferSize>sh->a_in_buffer_len){ | |
295 int x=demux_read_data(sh->ds,&sh->a_in_buffer[sh->a_in_buffer_len], | |
296 InputBufferSize-sh->a_in_buffer_len); | |
297 if(x>0) sh->a_in_buffer_len+=x; | |
298 if(InputBufferSize>sh->a_in_buffer_len) | |
299 FramesToGet=sh->a_in_buffer_len/InFrameSize; // not enough data! | |
300 } | |
301 | |
8159 | 302 // printf("\nSoundConverterConvertBuffer(myConv=%p,inbuf=%p,frames=%d,outbuf=%p,&convframes=%p,&convbytes=%p)\n", |
303 // myConverter,sh->a_in_buffer,FramesToGet,buf,&ConvertedFrames,&ConvertedBytes); | |
8008 | 304 error = SoundConverterConvertBuffer(myConverter,sh->a_in_buffer, |
305 FramesToGet,buf,&ConvertedFrames,&ConvertedBytes); | |
8159 | 306 // printf("SoundConverterConvertBuffer:%i\n",error); |
307 // printf("ConvertedFrames = %li\n",ConvertedFrames); | |
308 // printf("ConvertedBytes = %li\n",ConvertedBytes); | |
8008 | 309 |
8389
e8c51ec86340
fixed in/out framesize rounding bug (causing low-rate QCLP hangup/looping)
arpi
parents:
8270
diff
changeset
|
310 // InputBufferSize=(ConvertedBytes/OutFrameSize)*InFrameSize; // FIXME!! |
e8c51ec86340
fixed in/out framesize rounding bug (causing low-rate QCLP hangup/looping)
arpi
parents:
8270
diff
changeset
|
311 InputBufferSize=FramesToGet*InFrameSize; |
8008 | 312 sh->a_in_buffer_len-=InputBufferSize; |
313 if(sh->a_in_buffer_len<0) sh->a_in_buffer_len=0; // should not happen... | |
314 else if(sh->a_in_buffer_len>0){ | |
315 memcpy(sh->a_in_buffer,&sh->a_in_buffer[InputBufferSize],sh->a_in_buffer_len); | |
316 } | |
317 | |
318 return ConvertedBytes; | |
319 } | |
320 | |
321 static int control(sh_audio_t *sh,int cmd,void* arg, ...){ | |
322 // various optional functions you MAY implement: | |
323 return CONTROL_UNKNOWN; | |
324 } | |
325 | |
326 #endif |