Mercurial > mplayer.hg
annotate libmpdemux/demux_audio.c @ 13283:858b7e04718c
This patch moves the directory creation code to a separate function. I have
tried to re-use as much code as possible, to reduce the size of the patch.
All duplicate code is removed, resulting in my first patch that actually
decreases the size of the binary by about 700 bytes :-)
author | ivo |
---|---|
date | Wed, 08 Sep 2004 01:11:16 +0000 |
parents | 9a3e02d65e08 |
children | c605df89ca9f |
rev | line source |
---|---|
4694 | 1 |
2 #include "config.h" | |
4712 | 3 #include "../mp_msg.h" |
4694 | 4 |
5 #include <stdlib.h> | |
6 #include <stdio.h> | |
7 #include "stream.h" | |
8 #include "demuxer.h" | |
9 #include "stheader.h" | |
10 #include "genres.h" | |
6763 | 11 #include "mp3_hdr.h" |
4694 | 12 |
13 #include <string.h> | |
14 #ifdef MP_DEBUG | |
15 #include <assert.h> | |
16 #endif | |
17 | |
18 #define MP3 1 | |
19 #define WAV 2 | |
11004 | 20 #define fLaC 3 |
4694 | 21 |
22 | |
23 #define HDR_SIZE 4 | |
24 | |
25 typedef struct da_priv { | |
26 int frmt; | |
4764
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
27 float last_pts; |
4694 | 28 } da_priv_t; |
29 | |
30 extern void free_sh_audio(sh_audio_t* sh); | |
4700
30131db5dfbb
Improved mp3 detection (don't detect mpeg1/2 as mp3 anymore)
albeu
parents:
4694
diff
changeset
|
31 extern void resync_audio_stream(sh_audio_t *sh_audio); |
8123
9fc45fe0d444
*HUGE* set of compiler warning fixes, unused variables removal
arpi
parents:
8116
diff
changeset
|
32 extern void print_wave_header(WAVEFORMATEX *h); |
4694 | 33 |
7867 | 34 int hr_mp3_seek = 0; |
4694 | 35 |
36 int demux_audio_open(demuxer_t* demuxer) { | |
37 stream_t *s; | |
38 sh_audio_t* sh_audio; | |
39 uint8_t hdr[HDR_SIZE]; | |
6763 | 40 int st_pos = 0,frmt = 0, n = 0, pos = 0, step, mp3_freq,mp3_chans; |
4694 | 41 da_priv_t* priv; |
42 #ifdef MP_DEBUG | |
43 assert(demuxer != NULL); | |
44 assert(demuxer->stream != NULL); | |
45 #endif | |
46 | |
47 s = demuxer->stream; | |
48 | |
49 while(n < 5 && ! s->eof) { | |
50 st_pos = stream_tell(s); | |
51 step = 1; | |
52 if(pos < HDR_SIZE) { | |
53 stream_read(s,&hdr[pos],HDR_SIZE-pos); | |
54 pos = HDR_SIZE; | |
55 } | |
56 | |
57 if( hdr[0] == 'R' && hdr[1] == 'I' && hdr[2] == 'F' && hdr[3] == 'F' ) { | |
58 stream_skip(s,4); | |
59 if(s->eof) | |
60 break; | |
61 stream_read(s,hdr,4); | |
62 if(s->eof) | |
63 break; | |
64 if(hdr[0] != 'W' || hdr[1] != 'A' || hdr[2] != 'V' || hdr[3] != 'E' ) | |
65 stream_skip(s,-8); | |
66 else | |
67 // We found wav header. Now we can have 'fmt ' or a mp3 header | |
68 // empty the buffer | |
69 step = 4; | |
8116 | 70 } else if( hdr[0] == 'I' && hdr[1] == 'D' && hdr[2] == '3' && (hdr[3] >= 2)) { |
71 int len; | |
72 stream_skip(s,2); | |
73 stream_read(s,hdr,4); | |
74 len = (hdr[0]<<21) | (hdr[1]<<14) | (hdr[2]<<7) | hdr[3]; | |
75 stream_skip(s,len); | |
76 step = 4; | |
4694 | 77 } else if( hdr[0] == 'f' && hdr[1] == 'm' && hdr[2] == 't' && hdr[3] == ' ' ) { |
78 frmt = WAV; | |
79 break; | |
6763 | 80 } else if((n = mp_get_mp3_header(hdr,&mp3_chans,&mp3_freq)) > 0) { |
4694 | 81 frmt = MP3; |
82 break; | |
11004 | 83 } else if( hdr[0] == 'f' && hdr[1] == 'L' && hdr[2] == 'a' && hdr[3] == 'C' ) { |
84 frmt = fLaC; | |
85 stream_skip(s,-4); | |
86 break; | |
4694 | 87 } |
88 // Add here some other audio format detection | |
89 if(step < HDR_SIZE) | |
90 memmove(hdr,&hdr[step],HDR_SIZE-step); | |
91 pos -= step; | |
92 } | |
93 | |
94 if(!frmt) | |
95 return 0; | |
96 | |
97 sh_audio = new_sh_audio(demuxer,0); | |
98 | |
99 switch(frmt) { | |
100 case MP3: | |
101 sh_audio->format = 0x55; | |
4717
b7054dadd2c0
We should skip exactly the first frame on mp3 files.
albeu
parents:
4712
diff
changeset
|
102 demuxer->movi_start = st_pos-HDR_SIZE+n; |
6763 | 103 sh_audio->audio.dwSampleSize= 0; |
104 sh_audio->audio.dwScale = 1152; | |
105 sh_audio->audio.dwRate = mp3_freq; | |
106 sh_audio->wf = malloc(sizeof(WAVEFORMATEX)); | |
107 sh_audio->wf->wFormatTag = sh_audio->format; | |
108 sh_audio->wf->nChannels = mp3_chans; | |
109 sh_audio->wf->nSamplesPerSec = mp3_freq; | |
8110 | 110 sh_audio->wf->nBlockAlign = 1152; |
6763 | 111 sh_audio->wf->wBitsPerSample = 16; |
112 sh_audio->wf->cbSize = 0; | |
4700
30131db5dfbb
Improved mp3 detection (don't detect mpeg1/2 as mp3 anymore)
albeu
parents:
4694
diff
changeset
|
113 for(n = 0; n < 5 ; n++) { |
30131db5dfbb
Improved mp3 detection (don't detect mpeg1/2 as mp3 anymore)
albeu
parents:
4694
diff
changeset
|
114 pos = mp_decode_mp3_header(hdr); |
30131db5dfbb
Improved mp3 detection (don't detect mpeg1/2 as mp3 anymore)
albeu
parents:
4694
diff
changeset
|
115 if(pos < 0) |
30131db5dfbb
Improved mp3 detection (don't detect mpeg1/2 as mp3 anymore)
albeu
parents:
4694
diff
changeset
|
116 return 0; |
30131db5dfbb
Improved mp3 detection (don't detect mpeg1/2 as mp3 anymore)
albeu
parents:
4694
diff
changeset
|
117 stream_skip(s,pos-4); |
30131db5dfbb
Improved mp3 detection (don't detect mpeg1/2 as mp3 anymore)
albeu
parents:
4694
diff
changeset
|
118 if(s->eof) |
30131db5dfbb
Improved mp3 detection (don't detect mpeg1/2 as mp3 anymore)
albeu
parents:
4694
diff
changeset
|
119 return 0; |
30131db5dfbb
Improved mp3 detection (don't detect mpeg1/2 as mp3 anymore)
albeu
parents:
4694
diff
changeset
|
120 stream_read(s,hdr,4); |
30131db5dfbb
Improved mp3 detection (don't detect mpeg1/2 as mp3 anymore)
albeu
parents:
4694
diff
changeset
|
121 if(s->eof) |
30131db5dfbb
Improved mp3 detection (don't detect mpeg1/2 as mp3 anymore)
albeu
parents:
4694
diff
changeset
|
122 return 0; |
30131db5dfbb
Improved mp3 detection (don't detect mpeg1/2 as mp3 anymore)
albeu
parents:
4694
diff
changeset
|
123 } |
4694 | 124 if(s->end_pos) { |
125 char tag[4]; | |
126 stream_seek(s,s->end_pos-128); | |
127 stream_read(s,tag,3); | |
128 tag[3] = '\0'; | |
129 if(strcmp(tag,"TAG")) | |
130 demuxer->movi_end = s->end_pos; | |
131 else { | |
132 char buf[31]; | |
133 uint8_t g; | |
134 demuxer->movi_end = stream_tell(s)-3; | |
135 stream_read(s,buf,30); | |
136 buf[30] = '\0'; | |
137 demux_info_add(demuxer,"Title",buf); | |
138 stream_read(s,buf,30); | |
139 buf[30] = '\0'; | |
140 demux_info_add(demuxer,"Artist",buf); | |
141 stream_read(s,buf,30); | |
142 buf[30] = '\0'; | |
143 demux_info_add(demuxer,"Album",buf); | |
144 stream_read(s,buf,4); | |
4764
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
145 buf[4] = '\0'; |
4694 | 146 demux_info_add(demuxer,"Year",buf); |
147 stream_read(s,buf,30); | |
148 buf[30] = '\0'; | |
149 demux_info_add(demuxer,"Comment",buf); | |
150 if(buf[28] == 0 && buf[29] != 0) { | |
151 uint8_t trk = (uint8_t)buf[29]; | |
152 sprintf(buf,"%d",trk); | |
153 demux_info_add(demuxer,"Track",buf); | |
154 } | |
155 g = stream_read_char(s); | |
156 demux_info_add(demuxer,"Genre",genres[g]); | |
157 } | |
158 } | |
159 break; | |
160 case WAV: { | |
4720
10ad330c1733
fixed WAV demuxer so that it skips to the actual start of the audio data
melanson
parents:
4717
diff
changeset
|
161 unsigned int chunk_type; |
10ad330c1733
fixed WAV demuxer so that it skips to the actual start of the audio data
melanson
parents:
4717
diff
changeset
|
162 unsigned int chunk_size; |
4694 | 163 WAVEFORMATEX* w; |
164 int l; | |
165 l = stream_read_dword_le(s); | |
9596 | 166 if(l < 16) { |
9591
3904b95fce8f
Read extradata for wav files, based on patch by <dimakar(at)yahoo.com>. Required for truespeech files.
rtognimp
parents:
8359
diff
changeset
|
167 mp_msg(MSGT_DEMUX,MSGL_ERR,"[demux_audio] Bad wav header length: too short (%d)!!!\n",l); |
4694 | 168 free_sh_audio(sh_audio); |
169 return 0; | |
170 } | |
12213 | 171 sh_audio->wf = w = (WAVEFORMATEX*)malloc(l > sizeof(WAVEFORMATEX) ? l : sizeof(WAVEFORMATEX)); |
4694 | 172 w->wFormatTag = sh_audio->format = stream_read_word_le(s); |
173 w->nChannels = sh_audio->channels = stream_read_word_le(s); | |
174 w->nSamplesPerSec = sh_audio->samplerate = stream_read_dword_le(s); | |
175 w->nAvgBytesPerSec = stream_read_dword_le(s); | |
176 w->nBlockAlign = stream_read_word_le(s); | |
177 w->wBitsPerSample = sh_audio->samplesize = stream_read_word_le(s); | |
9616
a6bbab17a87f
10l cbSize not inited for l=16.\n Could give problem in print_wave_header
rtognimp
parents:
9596
diff
changeset
|
178 w->cbSize = 0; |
9596 | 179 l -= 16; |
180 if (l > 0) { | |
9591
3904b95fce8f
Read extradata for wav files, based on patch by <dimakar(at)yahoo.com>. Required for truespeech files.
rtognimp
parents:
8359
diff
changeset
|
181 w->cbSize = stream_read_word_le(s); |
9596 | 182 l -= 2; |
9655 | 183 if (w->cbSize > 0) { |
9591
3904b95fce8f
Read extradata for wav files, based on patch by <dimakar(at)yahoo.com>. Required for truespeech files.
rtognimp
parents:
8359
diff
changeset
|
184 if (l < w->cbSize) { |
3904b95fce8f
Read extradata for wav files, based on patch by <dimakar(at)yahoo.com>. Required for truespeech files.
rtognimp
parents:
8359
diff
changeset
|
185 mp_msg(MSGT_DEMUX,MSGL_ERR,"[demux_audio] truncated extradata (%d < %d)\n", |
3904b95fce8f
Read extradata for wav files, based on patch by <dimakar(at)yahoo.com>. Required for truespeech files.
rtognimp
parents:
8359
diff
changeset
|
186 l,w->cbSize); |
3904b95fce8f
Read extradata for wav files, based on patch by <dimakar(at)yahoo.com>. Required for truespeech files.
rtognimp
parents:
8359
diff
changeset
|
187 stream_read(s,(char*)((char*)(w)+sizeof(WAVEFORMATEX)),l); |
3904b95fce8f
Read extradata for wav files, based on patch by <dimakar(at)yahoo.com>. Required for truespeech files.
rtognimp
parents:
8359
diff
changeset
|
188 l = 0; |
3904b95fce8f
Read extradata for wav files, based on patch by <dimakar(at)yahoo.com>. Required for truespeech files.
rtognimp
parents:
8359
diff
changeset
|
189 } else { |
3904b95fce8f
Read extradata for wav files, based on patch by <dimakar(at)yahoo.com>. Required for truespeech files.
rtognimp
parents:
8359
diff
changeset
|
190 stream_read(s,(char*)((char*)(w)+sizeof(WAVEFORMATEX)),w->cbSize); |
3904b95fce8f
Read extradata for wav files, based on patch by <dimakar(at)yahoo.com>. Required for truespeech files.
rtognimp
parents:
8359
diff
changeset
|
191 l -= w->cbSize; |
3904b95fce8f
Read extradata for wav files, based on patch by <dimakar(at)yahoo.com>. Required for truespeech files.
rtognimp
parents:
8359
diff
changeset
|
192 } |
9655 | 193 } |
9596 | 194 } |
9591
3904b95fce8f
Read extradata for wav files, based on patch by <dimakar(at)yahoo.com>. Required for truespeech files.
rtognimp
parents:
8359
diff
changeset
|
195 |
7847 | 196 if(verbose>0) print_wave_header(w); |
4694 | 197 if(l) |
198 stream_skip(s,l); | |
4720
10ad330c1733
fixed WAV demuxer so that it skips to the actual start of the audio data
melanson
parents:
4717
diff
changeset
|
199 do |
10ad330c1733
fixed WAV demuxer so that it skips to the actual start of the audio data
melanson
parents:
4717
diff
changeset
|
200 { |
10ad330c1733
fixed WAV demuxer so that it skips to the actual start of the audio data
melanson
parents:
4717
diff
changeset
|
201 chunk_type = stream_read_fourcc(demuxer->stream); |
10ad330c1733
fixed WAV demuxer so that it skips to the actual start of the audio data
melanson
parents:
4717
diff
changeset
|
202 chunk_size = stream_read_dword_le(demuxer->stream); |
10ad330c1733
fixed WAV demuxer so that it skips to the actual start of the audio data
melanson
parents:
4717
diff
changeset
|
203 if (chunk_type != mmioFOURCC('d', 'a', 't', 'a')) |
10ad330c1733
fixed WAV demuxer so that it skips to the actual start of the audio data
melanson
parents:
4717
diff
changeset
|
204 stream_skip(demuxer->stream, chunk_size); |
10ad330c1733
fixed WAV demuxer so that it skips to the actual start of the audio data
melanson
parents:
4717
diff
changeset
|
205 } while (chunk_type != mmioFOURCC('d', 'a', 't', 'a')); |
4694 | 206 demuxer->movi_start = stream_tell(s); |
207 demuxer->movi_end = s->end_pos; | |
7847 | 208 // printf("wav: %X .. %X\n",(int)demuxer->movi_start,(int)demuxer->movi_end); |
13006 | 209 // Check if it contains dts audio |
210 if((w->wFormatTag == 0x01) && (w->nChannels == 2) && (w->nSamplesPerSec == 44100)) { | |
211 unsigned char buf[16384]; // vlc uses 16384*4 (4 dts frames) | |
212 unsigned int i; | |
213 stream_read(s, buf, sizeof(buf)); | |
214 for (i = 0; i < sizeof(buf); i += 2) { | |
215 // DTS, 14 bit, LE | |
216 if((buf[i] == 0xff) && (buf[i+1] == 0x1f) && (buf[i+2] == 0x00) && | |
217 (buf[i+3] == 0xe8) && ((buf[i+4] & 0xfe) == 0xf0) && (buf[i+5] == 0x07)) { | |
218 sh_audio->format = 0x2001; | |
219 mp_msg(MSGT_DEMUX,MSGL_V,"[demux_audio] DTS audio in wav, 14 bit, LE\n"); | |
220 break; | |
221 } | |
222 // DTS, 14 bit, BE | |
223 if((buf[i] == 0x1f) && (buf[i+1] == 0xff) && (buf[i+2] == 0xe8) && | |
224 (buf[i+3] == 0x00) && (buf[i+4] == 0x07) && ((buf[i+5] & 0xfe) == 0xf0)) { | |
225 sh_audio->format = 0x2001; | |
226 mp_msg(MSGT_DEMUX,MSGL_V,"[demux_audio] DTS audio in wav, 14 bit, BE\n"); | |
227 break; | |
228 } | |
229 // DTS, 16 bit, BE | |
230 if((buf[i] == 0x7f) && (buf[i+1] == 0xfe) && (buf[i+2] == 0x80) && | |
231 (buf[i+3] == 0x01)) { | |
232 sh_audio->format = 0x2001; | |
233 mp_msg(MSGT_DEMUX,MSGL_V,"[demux_audio] DTS audio in wav, 16 bit, BE\n"); | |
234 break; | |
235 } | |
236 // DTS, 16 bit, LE | |
237 if((buf[i] == 0xfe) && (buf[i+1] == 0x7f) && (buf[i+2] == 0x01) && | |
238 (buf[i+3] == 0x80)) { | |
239 sh_audio->format = 0x2001; | |
240 mp_msg(MSGT_DEMUX,MSGL_V,"[demux_audio] DTS audio in wav, 16 bit, LE\n"); | |
241 break; | |
242 } | |
243 } | |
244 if (sh_audio->format == 0x2001) | |
245 mp_msg(MSGT_DEMUX,MSGL_DBG2,"[demux_audio] DTS sync offset = %u\n", i); | |
246 | |
247 } | |
248 stream_seek(s,demuxer->movi_start); | |
4694 | 249 } break; |
11004 | 250 case fLaC: |
251 sh_audio->format = mmioFOURCC('f', 'L', 'a', 'C'); | |
252 demuxer->movi_start = stream_tell(s); | |
253 demuxer->movi_end = s->end_pos; | |
254 break; | |
4694 | 255 } |
256 | |
257 priv = (da_priv_t*)malloc(sizeof(da_priv_t)); | |
258 priv->frmt = frmt; | |
4764
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
259 priv->last_pts = -1; |
4694 | 260 demuxer->priv = priv; |
261 demuxer->audio->id = 0; | |
262 demuxer->audio->sh = sh_audio; | |
263 sh_audio->ds = demuxer->audio; | |
10244
a084597140af
don't set audio pts to infinity after seeking in mp3 files :)
rfelker
parents:
9655
diff
changeset
|
264 sh_audio->samplerate = sh_audio->audio.dwRate; |
4694 | 265 |
266 if(stream_tell(s) != demuxer->movi_start) | |
267 stream_seek(s,demuxer->movi_start); | |
268 | |
4712 | 269 mp_msg(MSGT_DEMUX,MSGL_V,"demux_audio: audio data 0x%X - 0x%X \n",demuxer->movi_start,demuxer->movi_end); |
270 | |
4694 | 271 return 1; |
272 } | |
273 | |
274 | |
275 int demux_audio_fill_buffer(demux_stream_t *ds) { | |
276 sh_audio_t* sh_audio; | |
277 demuxer_t* demux; | |
278 da_priv_t* priv; | |
279 stream_t* s; | |
280 #ifdef MP_DEBUG | |
281 assert(ds != NULL); | |
282 assert(ds->sh != NULL); | |
283 assert(ds->demuxer != NULL); | |
284 #endif | |
285 sh_audio = ds->sh; | |
286 demux = ds->demuxer; | |
287 priv = demux->priv; | |
288 s = demux->stream; | |
289 | |
290 if(s->eof || (demux->movi_end && stream_tell(s) >= demux->movi_end) ) | |
291 return 0; | |
292 | |
293 switch(priv->frmt) { | |
294 case MP3 : | |
295 while(! s->eof || (demux->movi_end && stream_tell(s) >= demux->movi_end) ) { | |
296 uint8_t hdr[4]; | |
297 int len; | |
298 stream_read(s,hdr,4); | |
299 len = mp_decode_mp3_header(hdr); | |
300 if(len < 0) { | |
301 stream_skip(s,-3); | |
302 } else { | |
303 demux_packet_t* dp; | |
304 if(s->eof || (demux->movi_end && stream_tell(s) >= demux->movi_end) ) | |
305 return 0; | |
306 dp = new_demux_packet(len); | |
307 memcpy(dp->buffer,hdr,4); | |
308 stream_read(s,dp->buffer + 4,len-4); | |
4764
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
309 priv->last_pts = priv->last_pts < 0 ? 0 : priv->last_pts + 1152/(float)sh_audio->samplerate; |
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
310 ds->pts = priv->last_pts - (ds_tell_pts(demux->audio)-sh_audio->a_in_buffer_len)/(float)sh_audio->i_bps; |
4694 | 311 ds_add_packet(ds,dp); |
312 return 1; | |
313 } | |
4700
30131db5dfbb
Improved mp3 detection (don't detect mpeg1/2 as mp3 anymore)
albeu
parents:
4694
diff
changeset
|
314 } break; |
4694 | 315 case WAV : { |
316 int l = sh_audio->wf->nAvgBytesPerSec; | |
317 demux_packet_t* dp = new_demux_packet(l); | |
10891
65ed62e138fa
Fixed 'reading after EOF'. demuxers didn't check, how many they've read!
lumag
parents:
10882
diff
changeset
|
318 l = stream_read(s,dp->buffer,l); |
65ed62e138fa
Fixed 'reading after EOF'. demuxers didn't check, how many they've read!
lumag
parents:
10882
diff
changeset
|
319 resize_demux_packet(dp, l); |
4764
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
320 priv->last_pts = priv->last_pts < 0 ? 0 : priv->last_pts + l/(float)sh_audio->i_bps; |
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
321 ds->pts = priv->last_pts - (ds_tell_pts(demux->audio)-sh_audio->a_in_buffer_len)/(float)sh_audio->i_bps; |
4694 | 322 ds_add_packet(ds,dp); |
323 return 1; | |
324 } | |
11004 | 325 case fLaC: { |
326 int l = 65535; | |
327 demux_packet_t* dp = new_demux_packet(l); | |
328 l = stream_read(s,dp->buffer,l); | |
329 resize_demux_packet(dp, l); | |
330 priv->last_pts = priv->last_pts < 0 ? 0 : priv->last_pts + l/(float)sh_audio->i_bps; | |
331 ds->pts = priv->last_pts - (ds_tell_pts(demux->audio)-sh_audio->a_in_buffer_len)/(float)sh_audio->i_bps; | |
332 ds_add_packet(ds,dp); | |
333 return 1; | |
334 } | |
4694 | 335 default: |
4720
10ad330c1733
fixed WAV demuxer so that it skips to the actual start of the audio data
melanson
parents:
4717
diff
changeset
|
336 printf("Audio demuxer : unknown format %d\n",priv->frmt); |
4694 | 337 } |
338 | |
339 | |
340 return 0; | |
341 } | |
342 | |
4764
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
343 static void high_res_mp3_seek(demuxer_t *demuxer,float time) { |
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
344 uint8_t hdr[4]; |
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
345 int len,nf; |
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
346 da_priv_t* priv = demuxer->priv; |
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
347 sh_audio_t* sh = (sh_audio_t*)demuxer->audio->sh; |
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
348 |
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
349 nf = time*sh->samplerate/1152; |
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
350 while(nf > 0) { |
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
351 stream_read(demuxer->stream,hdr,4); |
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
352 len = mp_decode_mp3_header(hdr); |
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
353 if(len < 0) { |
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
354 stream_skip(demuxer->stream,-3); |
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
355 continue; |
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
356 } |
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
357 stream_skip(demuxer->stream,len-4); |
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
358 priv->last_pts += 1152/(float)sh->samplerate; |
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
359 nf--; |
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
360 } |
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
361 } |
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
362 |
4694 | 363 void demux_audio_seek(demuxer_t *demuxer,float rel_seek_secs,int flags){ |
364 sh_audio_t* sh_audio; | |
365 stream_t* s; | |
366 int base,pos; | |
367 float len; | |
368 da_priv_t* priv; | |
369 | |
4764
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
370 if(!(sh_audio = demuxer->audio->sh)) |
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
371 return; |
4694 | 372 s = demuxer->stream; |
373 priv = demuxer->priv; | |
374 | |
4764
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
375 if(priv->frmt == MP3 && hr_mp3_seek && !(flags & 2)) { |
13256
9a3e02d65e08
fix seeking with -hr-mp3-seek. maybe not the best fix (why is last_pts
rfelker
parents:
13006
diff
changeset
|
376 if(isinf(priv->last_pts)) priv->last_pts=0; |
4764
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
377 len = (flags & 1) ? rel_seek_secs - priv->last_pts : rel_seek_secs; |
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
378 if(len < 0) { |
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
379 stream_seek(s,demuxer->movi_start); |
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
380 len = priv->last_pts + len; |
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
381 priv->last_pts = 0; |
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
382 } |
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
383 if(len > 0) |
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
384 high_res_mp3_seek(demuxer,len); |
8056
324b6e5387be
A-V sync cleanup: sh_audio->timer replaced by sh_audio->delay, it contains
arpi
parents:
7867
diff
changeset
|
385 sh_audio->delay = priv->last_pts - (ds_tell_pts(demuxer->audio)-sh_audio->a_in_buffer_len)/(float)sh_audio->i_bps; |
4764
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
386 resync_audio_stream(sh_audio); |
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
387 return; |
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
388 } |
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
389 |
5796 | 390 base = flags&1 ? demuxer->movi_start : stream_tell(s); |
391 if(flags&2) | |
392 pos = base + ((demuxer->movi_end - demuxer->movi_start)*rel_seek_secs); | |
393 else | |
394 pos = base + (rel_seek_secs*sh_audio->i_bps); | |
4694 | 395 |
396 if(demuxer->movi_end && pos >= demuxer->movi_end) { | |
8359 | 397 pos = demuxer->movi_end; |
398 //sh_audio->delay = (stream_tell(s) - demuxer->movi_start)/(float)sh_audio->i_bps; | |
399 //return; | |
4694 | 400 } else if(pos < demuxer->movi_start) |
401 pos = demuxer->movi_start; | |
4764
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
402 |
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
403 priv->last_pts = (pos-demuxer->movi_start)/(float)sh_audio->i_bps; |
8056
324b6e5387be
A-V sync cleanup: sh_audio->timer replaced by sh_audio->delay, it contains
arpi
parents:
7867
diff
changeset
|
404 sh_audio->delay = priv->last_pts - (ds_tell_pts(demuxer->audio)-sh_audio->a_in_buffer_len)/(float)sh_audio->i_bps; |
4694 | 405 |
406 switch(priv->frmt) { | |
407 case WAV: | |
4764
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
408 pos -= (pos % (sh_audio->channels * sh_audio->samplesize) ); |
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
409 // We need to decrease the pts by one step to make it the "last one" |
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
410 priv->last_pts -= sh_audio->wf->nAvgBytesPerSec/(float)sh_audio->i_bps; |
4694 | 411 break; |
412 } | |
413 | |
414 stream_seek(s,pos); | |
415 | |
4700
30131db5dfbb
Improved mp3 detection (don't detect mpeg1/2 as mp3 anymore)
albeu
parents:
4694
diff
changeset
|
416 resync_audio_stream(sh_audio); |
30131db5dfbb
Improved mp3 detection (don't detect mpeg1/2 as mp3 anymore)
albeu
parents:
4694
diff
changeset
|
417 |
4694 | 418 } |
4764
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
419 |
5812 | 420 void demux_close_audio(demuxer_t* demuxer) { |
421 da_priv_t* priv = demuxer->priv; | |
422 | |
423 if(!priv) | |
424 return; | |
425 free(priv); | |
426 } | |
427 | |
10882
e46e5a6c53b8
get_percent_pos support in demux_audio, patch by ROSEN Jeremy <jeremy.rosen at c-s.fr>
faust3
parents:
10244
diff
changeset
|
428 int demux_audio_control(demuxer_t *demuxer,int cmd, void *arg){ |
e46e5a6c53b8
get_percent_pos support in demux_audio, patch by ROSEN Jeremy <jeremy.rosen at c-s.fr>
faust3
parents:
10244
diff
changeset
|
429 sh_audio_t *sh_audio=demuxer->audio->sh; |
e46e5a6c53b8
get_percent_pos support in demux_audio, patch by ROSEN Jeremy <jeremy.rosen at c-s.fr>
faust3
parents:
10244
diff
changeset
|
430 int audio_length = demuxer->movi_end / sh_audio->i_bps; |
e46e5a6c53b8
get_percent_pos support in demux_audio, patch by ROSEN Jeremy <jeremy.rosen at c-s.fr>
faust3
parents:
10244
diff
changeset
|
431 da_priv_t* priv = demuxer->priv; |
e46e5a6c53b8
get_percent_pos support in demux_audio, patch by ROSEN Jeremy <jeremy.rosen at c-s.fr>
faust3
parents:
10244
diff
changeset
|
432 |
e46e5a6c53b8
get_percent_pos support in demux_audio, patch by ROSEN Jeremy <jeremy.rosen at c-s.fr>
faust3
parents:
10244
diff
changeset
|
433 switch(cmd) { |
e46e5a6c53b8
get_percent_pos support in demux_audio, patch by ROSEN Jeremy <jeremy.rosen at c-s.fr>
faust3
parents:
10244
diff
changeset
|
434 case DEMUXER_CTRL_GET_TIME_LENGTH: |
e46e5a6c53b8
get_percent_pos support in demux_audio, patch by ROSEN Jeremy <jeremy.rosen at c-s.fr>
faust3
parents:
10244
diff
changeset
|
435 if (audio_length<=0) return DEMUXER_CTRL_DONTKNOW; |
e46e5a6c53b8
get_percent_pos support in demux_audio, patch by ROSEN Jeremy <jeremy.rosen at c-s.fr>
faust3
parents:
10244
diff
changeset
|
436 *((unsigned long *)arg)=(unsigned long)audio_length; |
e46e5a6c53b8
get_percent_pos support in demux_audio, patch by ROSEN Jeremy <jeremy.rosen at c-s.fr>
faust3
parents:
10244
diff
changeset
|
437 return DEMUXER_CTRL_GUESS; |
e46e5a6c53b8
get_percent_pos support in demux_audio, patch by ROSEN Jeremy <jeremy.rosen at c-s.fr>
faust3
parents:
10244
diff
changeset
|
438 |
e46e5a6c53b8
get_percent_pos support in demux_audio, patch by ROSEN Jeremy <jeremy.rosen at c-s.fr>
faust3
parents:
10244
diff
changeset
|
439 case DEMUXER_CTRL_GET_PERCENT_POS: |
e46e5a6c53b8
get_percent_pos support in demux_audio, patch by ROSEN Jeremy <jeremy.rosen at c-s.fr>
faust3
parents:
10244
diff
changeset
|
440 if (audio_length<=0) |
e46e5a6c53b8
get_percent_pos support in demux_audio, patch by ROSEN Jeremy <jeremy.rosen at c-s.fr>
faust3
parents:
10244
diff
changeset
|
441 return DEMUXER_CTRL_DONTKNOW; |
e46e5a6c53b8
get_percent_pos support in demux_audio, patch by ROSEN Jeremy <jeremy.rosen at c-s.fr>
faust3
parents:
10244
diff
changeset
|
442 *((int *)arg)=(int)( (priv->last_pts*100) / audio_length); |
e46e5a6c53b8
get_percent_pos support in demux_audio, patch by ROSEN Jeremy <jeremy.rosen at c-s.fr>
faust3
parents:
10244
diff
changeset
|
443 return DEMUXER_CTRL_OK; |
e46e5a6c53b8
get_percent_pos support in demux_audio, patch by ROSEN Jeremy <jeremy.rosen at c-s.fr>
faust3
parents:
10244
diff
changeset
|
444 |
e46e5a6c53b8
get_percent_pos support in demux_audio, patch by ROSEN Jeremy <jeremy.rosen at c-s.fr>
faust3
parents:
10244
diff
changeset
|
445 default: |
e46e5a6c53b8
get_percent_pos support in demux_audio, patch by ROSEN Jeremy <jeremy.rosen at c-s.fr>
faust3
parents:
10244
diff
changeset
|
446 return DEMUXER_CTRL_NOTIMPL; |
e46e5a6c53b8
get_percent_pos support in demux_audio, patch by ROSEN Jeremy <jeremy.rosen at c-s.fr>
faust3
parents:
10244
diff
changeset
|
447 } |
e46e5a6c53b8
get_percent_pos support in demux_audio, patch by ROSEN Jeremy <jeremy.rosen at c-s.fr>
faust3
parents:
10244
diff
changeset
|
448 } |