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