Mercurial > mplayer.hg
comparison dec_audio.c @ 746:cd1f0d4de0b8
new audio playback and A-V sync code
author | arpi_esp |
---|---|
date | Thu, 10 May 2001 03:39:54 +0000 |
parents | e14114170e01 |
children | 32a8e9e43d94 |
comparison
equal
deleted
inserted
replaced
745:c653430f0789 | 746:cd1f0d4de0b8 |
---|---|
50 | 50 |
51 sh_audio->samplesize=2; | 51 sh_audio->samplesize=2; |
52 sh_audio->samplerate=0; | 52 sh_audio->samplerate=0; |
53 //sh_audio->pcm_bswap=0; | 53 //sh_audio->pcm_bswap=0; |
54 | 54 |
55 sh_audio->a_buffer_size=16384; // default size, maybe not enough for Win32/ACM | 55 sh_audio->a_buffer_size=2*MAX_OUTBURST; // default size, maybe not enough for Win32/ACM |
56 sh_audio->a_buffer=NULL; | 56 sh_audio->a_buffer=NULL; |
57 | |
58 sh_audio->a_in_buffer_len=0; | |
57 | 59 |
58 if(driver==4){ | 60 if(driver==4){ |
59 // Win32 ACM audio codec: | 61 // Win32 ACM audio codec: |
60 if(init_acm_audio_codec(sh_audio)){ | 62 if(init_acm_audio_codec(sh_audio)){ |
63 sh_audio->i_bps=sh_audio->wf->nAvgBytesPerSec; | |
61 sh_audio->channels=sh_audio->o_wf.nChannels; | 64 sh_audio->channels=sh_audio->o_wf.nChannels; |
62 sh_audio->samplerate=sh_audio->o_wf.nSamplesPerSec; | 65 sh_audio->samplerate=sh_audio->o_wf.nSamplesPerSec; |
63 if(sh_audio->a_buffer_size<sh_audio->audio_out_minsize+OUTBURST) | 66 if(sh_audio->a_buffer_size<sh_audio->audio_out_minsize+MAX_OUTBURST) |
64 sh_audio->a_buffer_size=sh_audio->audio_out_minsize+OUTBURST; | 67 sh_audio->a_buffer_size=sh_audio->audio_out_minsize+MAX_OUTBURST; |
65 } else { | 68 } else { |
66 printf("Could not load/initialize Win32/ACM AUDIO codec (missing DLL file?)\n"); | 69 printf("Could not load/initialize Win32/ACM AUDIO codec (missing DLL file?)\n"); |
67 driver=0; | 70 driver=0; |
68 } | 71 } |
69 } | 72 } |
78 | 81 |
79 if(DS_AudioDecoder_Open(sh_audio->codec->dll,&sh_audio->codec->guid,sh_audio->wf)){ | 82 if(DS_AudioDecoder_Open(sh_audio->codec->dll,&sh_audio->codec->guid,sh_audio->wf)){ |
80 printf("ERROR: Could not load/initialize Win32/DirctShow AUDIO codec: %s\n",sh_audio->codec->dll); | 83 printf("ERROR: Could not load/initialize Win32/DirctShow AUDIO codec: %s\n",sh_audio->codec->dll); |
81 driver=0; | 84 driver=0; |
82 } else { | 85 } else { |
86 sh_audio->i_bps=sh_audio->wf->nAvgBytesPerSec; | |
83 sh_audio->channels=sh_audio->wf->nChannels; | 87 sh_audio->channels=sh_audio->wf->nChannels; |
84 sh_audio->samplerate=sh_audio->wf->nSamplesPerSec; | 88 sh_audio->samplerate=sh_audio->wf->nSamplesPerSec; |
85 sh_audio->audio_in_minsize=2*sh_audio->wf->nBlockAlign; | 89 sh_audio->audio_in_minsize=2*sh_audio->wf->nBlockAlign; |
86 if(sh_audio->audio_in_minsize<8192) sh_audio->audio_in_minsize=8192; | 90 if(sh_audio->audio_in_minsize<8192) sh_audio->audio_in_minsize=8192; |
87 sh_audio->a_in_buffer_size=sh_audio->audio_in_minsize; | 91 sh_audio->a_in_buffer_size=sh_audio->audio_in_minsize; |
109 break; | 113 break; |
110 } | 114 } |
111 case 2: { | 115 case 2: { |
112 // AVI PCM Audio: | 116 // AVI PCM Audio: |
113 WAVEFORMATEX *h=sh_audio->wf; | 117 WAVEFORMATEX *h=sh_audio->wf; |
118 sh_audio->i_bps=h->nAvgBytesPerSec; | |
114 sh_audio->channels=h->nChannels; | 119 sh_audio->channels=h->nChannels; |
115 sh_audio->samplerate=h->nSamplesPerSec; | 120 sh_audio->samplerate=h->nSamplesPerSec; |
116 sh_audio->samplesize=(h->wBitsPerSample+7)/8; | 121 sh_audio->samplesize=(h->wBitsPerSample+7)/8; |
117 break; | 122 break; |
118 } | 123 } |
119 case 8: { | 124 case 8: { |
120 // DVD PCM Audio: | 125 // DVD PCM Audio: |
121 sh_audio->channels=2; | 126 sh_audio->channels=2; |
122 sh_audio->samplerate=48000; | 127 sh_audio->samplerate=48000; |
128 sh_audio->i_bps=2*2*48000; | |
123 // sh_audio->pcm_bswap=1; | 129 // sh_audio->pcm_bswap=1; |
124 break; | 130 break; |
125 } | 131 } |
126 case 3: { | 132 case 3: { |
127 // Dolby AC3 audio: | 133 // Dolby AC3 audio: |
136 ac3_config.flags |= AC3_3DNOW_ENABLE; | 142 ac3_config.flags |= AC3_3DNOW_ENABLE; |
137 #endif | 143 #endif |
138 ac3_init(); | 144 ac3_init(); |
139 sh_audio->ac3_frame = ac3_decode_frame(); | 145 sh_audio->ac3_frame = ac3_decode_frame(); |
140 if(sh_audio->ac3_frame){ | 146 if(sh_audio->ac3_frame){ |
141 sh_audio->samplerate=((ac3_frame_t*)sh_audio->ac3_frame)->sampling_rate; | 147 ac3_frame_t* fr=(ac3_frame_t*)sh_audio->ac3_frame; |
148 sh_audio->samplerate=fr->sampling_rate; | |
142 sh_audio->channels=2; | 149 sh_audio->channels=2; |
150 // 1 frame: 6*256 samples 1 sec: sh_audio->samplerate samples | |
151 //sh_audio->i_bps=fr->frame_size*fr->sampling_rate/(6*256); | |
152 sh_audio->i_bps=fr->bit_rate*(1000/8); | |
143 } else { | 153 } else { |
144 driver=0; // bad frame -> disable audio | 154 driver=0; // bad frame -> disable audio |
145 } | 155 } |
146 break; | 156 break; |
147 } | 157 } |
148 case 5: { | 158 case 5: { |
149 // aLaw audio codec: | 159 // aLaw audio codec: |
150 Gen_aLaw_2_Signed(); // init table | 160 Gen_aLaw_2_Signed(); // init table |
151 sh_audio->channels=sh_audio->wf->nChannels; | 161 sh_audio->channels=sh_audio->wf->nChannels; |
152 sh_audio->samplerate=sh_audio->wf->nSamplesPerSec; | 162 sh_audio->samplerate=sh_audio->wf->nSamplesPerSec; |
163 sh_audio->i_bps=sh_audio->channels*sh_audio->samplerate; | |
153 break; | 164 break; |
154 } | 165 } |
155 case 6: { | 166 case 6: { |
156 // MS-GSM audio codec: | 167 // MS-GSM audio codec: |
157 GSM_Init(); | 168 GSM_Init(); |
158 sh_audio->channels=sh_audio->wf->nChannels; | 169 sh_audio->channels=sh_audio->wf->nChannels; |
159 sh_audio->samplerate=sh_audio->wf->nSamplesPerSec; | 170 sh_audio->samplerate=sh_audio->wf->nSamplesPerSec; |
171 // decodes 65 byte -> 320 short | |
172 // 1 sec: sh_audio->channels*sh_audio->samplerate samples | |
173 // 1 frame: 320 samples | |
174 sh_audio->i_bps=65*(sh_audio->channels*sh_audio->samplerate)/320; // 1:10 | |
160 break; | 175 break; |
161 } | 176 } |
162 case 1: { | 177 case 1: { |
163 // MPEG Audio: | 178 // MPEG Audio: |
164 #ifdef USE_FAKE_MONO | 179 #ifdef USE_FAKE_MONO |
170 // printf("[\n"); | 185 // printf("[\n"); |
171 sh_audio->a_buffer_len=MP3_DecodeFrame(sh_audio->a_buffer,-1); | 186 sh_audio->a_buffer_len=MP3_DecodeFrame(sh_audio->a_buffer,-1); |
172 // printf("]\n"); | 187 // printf("]\n"); |
173 sh_audio->channels=2; // hack | 188 sh_audio->channels=2; // hack |
174 sh_audio->samplerate=MP3_samplerate; | 189 sh_audio->samplerate=MP3_samplerate; |
190 sh_audio->i_bps=MP3_bitrate*(1000/8); | |
175 break; | 191 break; |
176 } | 192 } |
177 } | 193 } |
178 | 194 |
179 if(!sh_audio->channels || !sh_audio->samplerate){ | 195 if(!sh_audio->channels || !sh_audio->samplerate){ |
189 | 205 |
190 sh_audio->o_bps=sh_audio->channels*sh_audio->samplerate*sh_audio->samplesize; | 206 sh_audio->o_bps=sh_audio->channels*sh_audio->samplerate*sh_audio->samplesize; |
191 return driver; | 207 return driver; |
192 } | 208 } |
193 | 209 |
194 // Audio decoding | 210 // Audio decoding: |
195 | 211 |
196 int decode_audio(sh_audio_t *sh_audio,unsigned char *buf,int maxlen){ | 212 // Decode a single frame (mp3,acm etc) or 'minlen' bytes (pcm/alaw etc) |
213 // buffer length is 'maxlen' bytes, it shouldn't be exceeded... | |
214 | |
215 int decode_audio(sh_audio_t *sh_audio,unsigned char *buf,int minlen,int maxlen){ | |
197 int len=-1; | 216 int len=-1; |
198 switch(sh_audio->codec->driver){ | 217 switch(sh_audio->codec->driver){ |
199 case 1: // MPEG layer 2 or 3 | 218 case 1: // MPEG layer 2 or 3 |
200 len=MP3_DecodeFrame(buf,-1); | 219 len=MP3_DecodeFrame(buf,-1); |
201 sh_audio->channels=2; // hack | 220 sh_audio->channels=2; // hack |
202 break; | 221 break; |
203 case 2: // AVI PCM | 222 case 2: // AVI PCM |
204 { len=demux_read_data(sh_audio->ds,buf,OUTBURST); | 223 { len=demux_read_data(sh_audio->ds,buf,minlen); |
205 break; | 224 break; |
206 } | 225 } |
207 case 8: // DVD PCM | 226 case 8: // DVD PCM |
208 { int j; | 227 { int j; |
209 len=demux_read_data(sh_audio->ds,buf,OUTBURST); | 228 len=demux_read_data(sh_audio->ds,buf,minlen); |
210 //if(i&1){ printf("Warning! pcm_audio_size&1 !=0 (%d)\n",i);i&=~1; } | 229 //if(i&1){ printf("Warning! pcm_audio_size&1 !=0 (%d)\n",i);i&=~1; } |
230 // swap endian: | |
211 for(j=0;j<len;j+=2){ | 231 for(j=0;j<len;j+=2){ |
212 char x=buf[j]; | 232 char x=buf[j]; |
213 buf[j]=buf[j+1]; | 233 buf[j]=buf[j+1]; |
214 buf[j+1]=x; | 234 buf[j+1]=x; |
215 } | 235 } |
216 break; | 236 break; |
217 } | 237 } |
218 case 5: // aLaw decoder | 238 case 5: // aLaw decoder |
219 { int l=demux_read_data(sh_audio->ds,buf,OUTBURST/2); | 239 { int l=demux_read_data(sh_audio->ds,buf,minlen/2); |
220 unsigned short *d=(unsigned short *) buf; | 240 unsigned short *d=(unsigned short *) buf; |
221 unsigned char *s=buf; | 241 unsigned char *s=buf; |
222 len=2*l; | 242 len=2*l; |
223 while(l>0){ | 243 while(l>0){ |
224 --l; | 244 --l; |
226 } | 246 } |
227 break; | 247 break; |
228 } | 248 } |
229 case 6: // MS-GSM decoder | 249 case 6: // MS-GSM decoder |
230 { unsigned char buf[65]; // 65 bytes / frame | 250 { unsigned char buf[65]; // 65 bytes / frame |
231 len=0; | 251 if(demux_read_data(sh_audio->ds,buf,65)!=65) break; // EOF |
232 while(len<OUTBURST){ | 252 XA_MSGSM_Decoder(buf,(unsigned short *) buf); // decodes 65 byte -> 320 short |
233 if(demux_read_data(sh_audio->ds,buf,65)!=65) break; // EOF | 253 // XA_GSM_Decoder(buf,(unsigned short *) &sh_audio->a_buffer[sh_audio->a_buffer_len]); // decodes 33 byte -> 160 short |
234 XA_MSGSM_Decoder(buf,(unsigned short *) buf); // decodes 65 byte -> 320 short | 254 len=2*320; |
235 // XA_GSM_Decoder(buf,(unsigned short *) &sh_audio->a_buffer[sh_audio->a_buffer_len]); // decodes 33 byte -> 160 short | |
236 len+=2*320; | |
237 } | |
238 break; | 255 break; |
239 } | 256 } |
240 case 3: // AC3 decoder | 257 case 3: // AC3 decoder |
241 //printf("{1:%d}",avi_header.idx_pos);fflush(stdout); | 258 //printf("{1:%d}",avi_header.idx_pos);fflush(stdout); |
242 if(!sh_audio->ac3_frame) sh_audio->ac3_frame=ac3_decode_frame(); | 259 if(!sh_audio->ac3_frame) sh_audio->ac3_frame=ac3_decode_frame(); |
247 sh_audio->ac3_frame=NULL; | 264 sh_audio->ac3_frame=NULL; |
248 } | 265 } |
249 //printf("{3:%d}",avi_header.idx_pos);fflush(stdout); | 266 //printf("{3:%d}",avi_header.idx_pos);fflush(stdout); |
250 break; | 267 break; |
251 case 4: | 268 case 4: |
252 { len=acm_decode_audio(sh_audio,buf,maxlen); | 269 len=acm_decode_audio(sh_audio,buf,maxlen); |
253 break; | 270 // len=acm_decode_audio(sh_audio,buf,minlen); |
254 } | 271 break; |
272 | |
255 #ifdef USE_DIRECTSHOW | 273 #ifdef USE_DIRECTSHOW |
256 case 7: // DirectShow | 274 case 7: // DirectShow |
257 { int ret; | 275 { int ret; |
258 int size_in=0; | 276 int size_in=0; |
259 int size_out=0; | 277 int size_out=0; |
265 demux_read_data(sh_audio->ds,&sh_audio->a_in_buffer[sh_audio->a_in_buffer_len], | 283 demux_read_data(sh_audio->ds,&sh_audio->a_in_buffer[sh_audio->a_in_buffer_len], |
266 srcsize-sh_audio->a_in_buffer_len); | 284 srcsize-sh_audio->a_in_buffer_len); |
267 } | 285 } |
268 DS_AudioDecoder_Convert(sh_audio->a_in_buffer,sh_audio->a_in_buffer_len, | 286 DS_AudioDecoder_Convert(sh_audio->a_in_buffer,sh_audio->a_in_buffer_len, |
269 buf,maxlen, &size_in,&size_out); | 287 buf,maxlen, &size_in,&size_out); |
270 if(verbose>2)printf("DShow: audio %d -> %d converted (in_buf_len=%d of %d)\n",size_in,size_out,sh_audio->a_in_buffer_len,sh_audio->a_in_buffer_size); | 288 //if(verbose>2) |
289 printf("DShow: audio %d -> %d converted (in_buf_len=%d of %d) %d\n",size_in,size_out,sh_audio->a_in_buffer_len,sh_audio->a_in_buffer_size,ds_tell_pts(sh_audio->ds)); | |
271 if(size_in>=sh_audio->a_in_buffer_len){ | 290 if(size_in>=sh_audio->a_in_buffer_len){ |
272 sh_audio->a_in_buffer_len=0; | 291 sh_audio->a_in_buffer_len=0; |
273 } else { | 292 } else { |
274 sh_audio->a_in_buffer_len-=size_in; | 293 sh_audio->a_in_buffer_len-=size_in; |
275 memcpy(sh_audio->a_in_buffer,&sh_audio->a_in_buffer[size_in],sh_audio->a_in_buffer_len); | 294 memcpy(sh_audio->a_in_buffer,&sh_audio->a_in_buffer[size_in],sh_audio->a_in_buffer_len); |