Mercurial > mplayer.hg
annotate dec_audio.c @ 572:9935c60a15a0
added mga_vid support (systemram->videoram tests)
author | arpi_esp |
---|---|
date | Sun, 22 Apr 2001 03:40:45 +0000 |
parents | 5251b0c57e39 |
children | 8511095c5283 |
rev | line source |
---|---|
296 | 1 |
2 int init_audio(sh_audio_t *sh_audio){ | |
303 | 3 |
4 int driver=sh_audio->codec->driver; | |
296 | 5 |
6 sh_audio->samplesize=2; | |
303 | 7 sh_audio->samplerate=0; |
401 | 8 //sh_audio->pcm_bswap=0; |
303 | 9 |
296 | 10 sh_audio->a_buffer_size=16384; // default size, maybe not enough for Win32/ACM |
303 | 11 sh_audio->a_buffer=NULL; |
296 | 12 |
303 | 13 if(driver==4){ |
296 | 14 // Win32 ACM audio codec: |
15 if(init_acm_audio_codec(sh_audio)){ | |
16 sh_audio->channels=sh_audio->o_wf.nChannels; | |
17 sh_audio->samplerate=sh_audio->o_wf.nSamplesPerSec; | |
18 if(sh_audio->a_buffer_size<sh_audio->audio_out_minsize+OUTBURST) | |
19 sh_audio->a_buffer_size=sh_audio->audio_out_minsize+OUTBURST; | |
20 } else { | |
21 printf("Could not load/initialize Win32/ACM AUDIO codec (missing DLL file?)\n"); | |
303 | 22 driver=0; |
296 | 23 } |
24 } | |
25 | |
303 | 26 if(driver==7){ |
296 | 27 #ifndef USE_DIRECTSHOW |
28 printf("Compiled without DirectShow support -> force nosound :(\n"); | |
303 | 29 driver=0; |
296 | 30 #else |
31 // Win32 DShow audio codec: | |
340 | 32 // printf("DShow_audio: channs=%d rate=%d\n",sh_audio->channels,sh_audio->samplerate); |
296 | 33 |
432
5251b0c57e39
sh_audio->wf and sh_video->bih changed to dynamic (thanx to Jens Hoffmann)
arpi_esp
parents:
401
diff
changeset
|
34 if(DS_AudioDecoder_Open(sh_audio->codec->dll,&sh_audio->codec->guid,sh_audio->wf)){ |
303 | 35 printf("ERROR: Could not load/initialize Win32/DirctShow AUDIO codec: %s\n",sh_audio->codec->dll); |
36 driver=0; | |
37 } else { | |
432
5251b0c57e39
sh_audio->wf and sh_video->bih changed to dynamic (thanx to Jens Hoffmann)
arpi_esp
parents:
401
diff
changeset
|
38 sh_audio->channels=sh_audio->wf->nChannels; |
5251b0c57e39
sh_audio->wf and sh_video->bih changed to dynamic (thanx to Jens Hoffmann)
arpi_esp
parents:
401
diff
changeset
|
39 sh_audio->samplerate=sh_audio->wf->nSamplesPerSec; |
5251b0c57e39
sh_audio->wf and sh_video->bih changed to dynamic (thanx to Jens Hoffmann)
arpi_esp
parents:
401
diff
changeset
|
40 sh_audio->audio_in_minsize=2*sh_audio->wf->nBlockAlign; |
296 | 41 if(sh_audio->audio_in_minsize<8192) sh_audio->audio_in_minsize=8192; |
42 sh_audio->a_in_buffer_size=sh_audio->audio_in_minsize; | |
43 sh_audio->a_in_buffer=malloc(sh_audio->a_in_buffer_size); | |
44 sh_audio->a_in_buffer_len=0; | |
45 } | |
46 #endif | |
47 } | |
48 | |
303 | 49 if(!driver) return 0; |
296 | 50 |
51 // allocate audio out buffer: | |
52 sh_audio->a_buffer=malloc(sh_audio->a_buffer_size); | |
53 memset(sh_audio->a_buffer,0,sh_audio->a_buffer_size); | |
54 sh_audio->a_buffer_len=0; | |
55 | |
303 | 56 switch(driver){ |
57 case 4: { | |
296 | 58 int ret=acm_decode_audio(sh_audio,sh_audio->a_buffer,sh_audio->a_buffer_size); |
59 if(ret<0){ | |
303 | 60 printf("ACM decoding error: %d\n",ret); |
61 driver=0; | |
296 | 62 } |
303 | 63 break; |
296 | 64 } |
303 | 65 case 2: { |
296 | 66 // AVI PCM Audio: |
432
5251b0c57e39
sh_audio->wf and sh_video->bih changed to dynamic (thanx to Jens Hoffmann)
arpi_esp
parents:
401
diff
changeset
|
67 WAVEFORMATEX *h=sh_audio->wf; |
296 | 68 sh_audio->channels=h->nChannels; |
69 sh_audio->samplerate=h->nSamplesPerSec; | |
70 sh_audio->samplesize=(h->wBitsPerSample+7)/8; | |
401 | 71 break; |
72 } | |
73 case 8: { | |
74 // DVD PCM Audio: | |
75 sh_audio->channels=2; | |
76 sh_audio->samplerate=48000; | |
296 | 77 // sh_audio->pcm_bswap=1; |
303 | 78 break; |
79 } | |
80 case 3: { | |
296 | 81 // Dolby AC3 audio: |
82 ac3_config.fill_buffer_callback = ac3_fill_buffer; | |
83 ac3_config.num_output_ch = 2; | |
84 ac3_config.flags = 0; | |
85 #ifdef HAVE_MMX | |
86 ac3_config.flags |= AC3_MMX_ENABLE; | |
87 #endif | |
88 #ifdef HAVE_3DNOW | |
89 ac3_config.flags |= AC3_3DNOW_ENABLE; | |
90 #endif | |
91 ac3_init(); | |
92 sh_audio->ac3_frame = ac3_decode_frame(); | |
93 if(sh_audio->ac3_frame){ | |
94 sh_audio->samplerate=sh_audio->ac3_frame->sampling_rate; | |
95 sh_audio->channels=2; | |
303 | 96 } else { |
97 driver=0; // bad frame -> disable audio | |
98 } | |
99 break; | |
100 } | |
101 case 5: { | |
296 | 102 // aLaw audio codec: |
103 Gen_aLaw_2_Signed(); // init table | |
432
5251b0c57e39
sh_audio->wf and sh_video->bih changed to dynamic (thanx to Jens Hoffmann)
arpi_esp
parents:
401
diff
changeset
|
104 sh_audio->channels=sh_audio->wf->nChannels; |
5251b0c57e39
sh_audio->wf and sh_video->bih changed to dynamic (thanx to Jens Hoffmann)
arpi_esp
parents:
401
diff
changeset
|
105 sh_audio->samplerate=sh_audio->wf->nSamplesPerSec; |
303 | 106 break; |
107 } | |
108 case 6: { | |
296 | 109 // MS-GSM audio codec: |
110 GSM_Init(); | |
432
5251b0c57e39
sh_audio->wf and sh_video->bih changed to dynamic (thanx to Jens Hoffmann)
arpi_esp
parents:
401
diff
changeset
|
111 sh_audio->channels=sh_audio->wf->nChannels; |
5251b0c57e39
sh_audio->wf and sh_video->bih changed to dynamic (thanx to Jens Hoffmann)
arpi_esp
parents:
401
diff
changeset
|
112 sh_audio->samplerate=sh_audio->wf->nSamplesPerSec; |
303 | 113 break; |
296 | 114 } |
303 | 115 case 1: { |
296 | 116 // MPEG Audio: |
117 MP3_Init(); | |
118 MP3_samplerate=MP3_channels=0; | |
119 // printf("[\n"); | |
120 sh_audio->a_buffer_len=MP3_DecodeFrame(sh_audio->a_buffer,-1); | |
121 // printf("]\n"); | |
122 sh_audio->channels=2; // hack | |
123 sh_audio->samplerate=MP3_samplerate; | |
303 | 124 break; |
125 } | |
296 | 126 } |
127 | |
128 if(!sh_audio->channels || !sh_audio->samplerate){ | |
129 printf("Unknown/missing audio format, using nosound\n"); | |
303 | 130 driver=0; |
296 | 131 } |
132 | |
303 | 133 if(!driver){ |
134 if(sh_audio->a_buffer) free(sh_audio->a_buffer); | |
135 sh_audio->o_bps=0; | |
136 return 0; | |
137 } | |
296 | 138 |
303 | 139 sh_audio->o_bps=sh_audio->channels*sh_audio->samplerate*sh_audio->samplesize; |
140 return driver; | |
296 | 141 } |
291 | 142 |
143 // Audio decoding | |
144 | |
145 int decode_audio(sh_audio_t *sh_audio,unsigned char *buf,int maxlen){ | |
146 int len=-1; | |
303 | 147 switch(sh_audio->codec->driver){ |
291 | 148 case 1: // MPEG layer 2 or 3 |
149 len=MP3_DecodeFrame(buf,-1); | |
296 | 150 sh_audio->channels=2; // hack |
291 | 151 break; |
401 | 152 case 2: // AVI PCM |
291 | 153 { len=demux_read_data(sh_audio->ds,buf,OUTBURST); |
401 | 154 break; |
155 } | |
156 case 8: // DVD PCM | |
157 { int j; | |
158 len=demux_read_data(sh_audio->ds,buf,OUTBURST); | |
291 | 159 //if(i&1){ printf("Warning! pcm_audio_size&1 !=0 (%d)\n",i);i&=~1; } |
160 for(j=0;j<len;j+=2){ | |
161 char x=buf[j]; | |
162 buf[j]=buf[j+1]; | |
163 buf[j+1]=x; | |
164 } | |
165 break; | |
166 } | |
167 case 5: // aLaw decoder | |
168 { int l=demux_read_data(sh_audio->ds,buf,OUTBURST/2); | |
169 unsigned short *d=(unsigned short *) buf; | |
170 unsigned char *s=buf; | |
171 len=2*l; | |
172 while(l>0){ | |
173 --l; | |
174 d[l]=xa_alaw_2_sign[s[l]]; | |
175 } | |
176 break; | |
177 } | |
178 case 6: // MS-GSM decoder | |
179 { unsigned char buf[65]; // 65 bytes / frame | |
180 len=0; | |
181 while(len<OUTBURST){ | |
182 if(demux_read_data(d_audio,buf,65)!=65) break; // EOF | |
183 XA_MSGSM_Decoder(buf,(unsigned short *) buf); // decodes 65 byte -> 320 short | |
296 | 184 // XA_GSM_Decoder(buf,(unsigned short *) &sh_audio->a_buffer[sh_audio->a_buffer_len]); // decodes 33 byte -> 160 short |
291 | 185 len+=2*320; |
186 } | |
187 break; | |
188 } | |
189 case 3: // AC3 decoder | |
190 //printf("{1:%d}",avi_header.idx_pos);fflush(stdout); | |
191 if(!sh_audio->ac3_frame) sh_audio->ac3_frame=ac3_decode_frame(); | |
192 //printf("{2:%d}",avi_header.idx_pos);fflush(stdout); | |
193 if(sh_audio->ac3_frame){ | |
296 | 194 len = 256 * 6 *sh_audio->channels*sh_audio->samplesize; |
291 | 195 memcpy(buf,sh_audio->ac3_frame->audio_data,len); |
196 sh_audio->ac3_frame=NULL; | |
197 } | |
198 //printf("{3:%d}",avi_header.idx_pos);fflush(stdout); | |
199 break; | |
200 case 4: | |
201 { len=acm_decode_audio(sh_audio,buf,maxlen); | |
202 break; | |
203 } | |
204 #ifdef USE_DIRECTSHOW | |
205 case 7: // DirectShow | |
206 { int ret; | |
207 int size_in=0; | |
208 int size_out=0; | |
209 int srcsize=DS_AudioDecoder_GetSrcSize(maxlen); | |
210 if(verbose>2)printf("DShow says: srcsize=%d (buffsize=%d) out_size=%d\n",srcsize,sh_audio->a_in_buffer_size,maxlen); | |
211 if(srcsize>sh_audio->a_in_buffer_size) srcsize=sh_audio->a_in_buffer_size; // !!!!!! | |
212 if(sh_audio->a_in_buffer_len<srcsize){ | |
213 sh_audio->a_in_buffer_len+= | |
214 demux_read_data(sh_audio->ds,&sh_audio->a_in_buffer[sh_audio->a_in_buffer_len], | |
215 srcsize-sh_audio->a_in_buffer_len); | |
216 } | |
217 DS_AudioDecoder_Convert(sh_audio->a_in_buffer,sh_audio->a_in_buffer_len, | |
218 buf,maxlen, &size_in,&size_out); | |
219 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); | |
220 if(size_in>=sh_audio->a_in_buffer_len){ | |
221 sh_audio->a_in_buffer_len=0; | |
222 } else { | |
223 sh_audio->a_in_buffer_len-=size_in; | |
224 memcpy(sh_audio->a_in_buffer,&sh_audio->a_in_buffer[size_in],sh_audio->a_in_buffer_len); | |
225 } | |
226 len=size_out; | |
227 break; | |
228 } | |
229 #endif | |
230 } | |
231 return len; | |
232 } | |
233 | |
234 |