Mercurial > mplayer.hg
annotate libmpdemux/demux_aac.c @ 31632:fc6f2b4e8a26
Avoid calling av_resample_init again when the values are the same as before.
The init function can be called multiple times when e.g. additional format
filters are inserted, so this speeds things up.
Patch by Dan Oscarsson [Dan.Oscarsson tieto com].
author | reimar |
---|---|
date | Sun, 11 Jul 2010 09:46:58 +0000 |
parents | cd81fce1f010 |
children | 8fa2f43cb760 |
rev | line source |
---|---|
29238
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
26327
diff
changeset
|
1 /* |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
26327
diff
changeset
|
2 * This file is part of MPlayer. |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
26327
diff
changeset
|
3 * |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
26327
diff
changeset
|
4 * MPlayer is free software; you can redistribute it and/or modify |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
26327
diff
changeset
|
5 * it under the terms of the GNU General Public License as published by |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
26327
diff
changeset
|
6 * the Free Software Foundation; either version 2 of the License, or |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
26327
diff
changeset
|
7 * (at your option) any later version. |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
26327
diff
changeset
|
8 * |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
26327
diff
changeset
|
9 * MPlayer is distributed in the hope that it will be useful, |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
26327
diff
changeset
|
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
26327
diff
changeset
|
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
26327
diff
changeset
|
12 * GNU General Public License for more details. |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
26327
diff
changeset
|
13 * |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
26327
diff
changeset
|
14 * You should have received a copy of the GNU General Public License along |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
26327
diff
changeset
|
15 * with MPlayer; if not, write to the Free Software Foundation, Inc., |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
26327
diff
changeset
|
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
26327
diff
changeset
|
17 */ |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
26327
diff
changeset
|
18 |
15720 | 19 #include <stdio.h> |
20 #include <stdlib.h> | |
21 #include <string.h> | |
22 | |
23 #include "config.h" | |
24 #include "mp_msg.h" | |
25 #include "help_mp.h" | |
26 | |
22605
4d81dbdf46b9
Add explicit location for headers from the stream/ directory.
diego
parents:
21421
diff
changeset
|
27 #include "stream/stream.h" |
15720 | 28 #include "demuxer.h" |
29 #include "parse_es.h" | |
30 #include "stheader.h" | |
30574
928359c13d93
Add separate header for aac_parse_frame(); avoids forward declarations.
diego
parents:
29263
diff
changeset
|
31 #include "aac_hdr.h" |
15720 | 32 #include "ms_hdr.h" |
33 | |
34 typedef struct { | |
35 uint8_t *buf; | |
36 uint64_t size; /// amount of time of data packets pushed to demuxer->audio (in bytes) | |
37 float time; /// amount of time elapsed based upon samples_per_frame/sample_rate (in milliseconds) | |
38 float last_pts; /// last pts seen | |
39 int bitrate; /// bitrate computed as size/time | |
40 } aac_priv_t; | |
41 | |
42 static int demux_aac_init(demuxer_t *demuxer) | |
43 { | |
44 aac_priv_t *priv; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
45 |
15720 | 46 priv = calloc(1, sizeof(aac_priv_t)); |
47 if(!priv) | |
48 return 0; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
49 |
30702 | 50 priv->buf = malloc(8); |
15720 | 51 if(!priv->buf) |
17789
9f0c42967ce5
fix minor (i.e. unlikely to ever happen) leak when init fails
reimar
parents:
17636
diff
changeset
|
52 { |
9f0c42967ce5
fix minor (i.e. unlikely to ever happen) leak when init fails
reimar
parents:
17636
diff
changeset
|
53 free(priv); |
15720 | 54 return 0; |
17789
9f0c42967ce5
fix minor (i.e. unlikely to ever happen) leak when init fails
reimar
parents:
17636
diff
changeset
|
55 } |
15720 | 56 |
57 demuxer->priv = priv; | |
58 return 1; | |
59 } | |
60 | |
16175 | 61 static void demux_close_aac(demuxer_t *demuxer) |
15720 | 62 { |
63 aac_priv_t *priv = (aac_priv_t *) demuxer->priv; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
64 |
15720 | 65 if(!priv) |
66 return; | |
67 | |
68 if(priv->buf) | |
69 free(priv->buf); | |
70 | |
71 free(demuxer->priv); | |
72 | |
73 return; | |
74 } | |
75 | |
16175 | 76 /// returns DEMUXER_TYPE_AAC if it finds 8 ADTS frames in 32768 bytes, 0 otherwise |
77 static int demux_aac_probe(demuxer_t *demuxer) | |
15720 | 78 { |
79 int cnt = 0, c, len, srate, num; | |
80 off_t init, probed; | |
81 aac_priv_t *priv; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
82 |
15720 | 83 if(! demux_aac_init(demuxer)) |
84 { | |
85 mp_msg(MSGT_DEMUX, MSGL_ERR, "COULDN'T INIT aac_demux, exit\n"); | |
86 return 0; | |
87 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
88 |
15720 | 89 priv = (aac_priv_t *) demuxer->priv; |
90 | |
91 init = probed = stream_tell(demuxer->stream); | |
92 while(probed-init <= 32768 && cnt < 8) | |
93 { | |
94 c = 0; | |
95 while(c != 0xFF) | |
96 { | |
97 c = stream_read_char(demuxer->stream); | |
98 if(c < 0) | |
99 goto fail; | |
100 } | |
101 priv->buf[0] = 0xFF; | |
102 if(stream_read(demuxer->stream, &(priv->buf[1]), 7) < 7) | |
103 goto fail; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
104 |
15720 | 105 len = aac_parse_frame(priv->buf, &srate, &num); |
106 if(len > 0) | |
107 { | |
108 cnt++; | |
109 stream_skip(demuxer->stream, len - 8); | |
110 } | |
111 probed = stream_tell(demuxer->stream); | |
112 } | |
113 | |
114 stream_seek(demuxer->stream, init); | |
115 if(cnt < 8) | |
116 goto fail; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
117 |
16750
0a31740dd5e6
Use PRI?64 defines as format strings for 64 bit variables.
reimar
parents:
16175
diff
changeset
|
118 mp_msg(MSGT_DEMUX, MSGL_V, "demux_aac_probe, INIT: %"PRIu64", PROBED: %"PRIu64", cnt: %d\n", init, probed, cnt); |
16175 | 119 return DEMUXER_TYPE_AAC; |
15720 | 120 |
121 fail: | |
122 mp_msg(MSGT_DEMUX, MSGL_V, "demux_aac_probe, failed to detect an AAC stream\n"); | |
123 return 0; | |
124 } | |
125 | |
16175 | 126 static demuxer_t* demux_aac_open(demuxer_t *demuxer) |
15720 | 127 { |
128 sh_audio_t *sh; | |
129 | |
31609
cd81fce1f010
Make the stream language an argument to the stream creation function
reimar
parents:
30702
diff
changeset
|
130 sh = new_sh_audio(demuxer, 0, NULL); |
15720 | 131 sh->ds = demuxer->audio; |
132 sh->format = mmioFOURCC('M', 'P', '4', 'A'); | |
26299
4d56038ec730
Fix lots and lots of other demuxers broken by r26301
reimar
parents:
25883
diff
changeset
|
133 demuxer->audio->id = 0; |
15720 | 134 demuxer->audio->sh = sh; |
135 | |
136 demuxer->filepos = stream_tell(demuxer->stream); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
137 |
16175 | 138 return demuxer; |
15720 | 139 } |
140 | |
16175 | 141 static int demux_aac_fill_buffer(demuxer_t *demuxer, demux_stream_t *ds) |
15720 | 142 { |
143 aac_priv_t *priv = (aac_priv_t *) demuxer->priv; | |
144 demux_packet_t *dp; | |
145 int c1, c2, len, srate, num; | |
146 float tm = 0; | |
147 | |
148 if(demuxer->stream->eof || (demuxer->movi_end && stream_tell(demuxer->stream) >= demuxer->movi_end)) | |
149 return 0; | |
150 | |
151 while(! demuxer->stream->eof) | |
152 { | |
153 c1 = c2 = 0; | |
154 while(c1 != 0xFF) | |
155 { | |
156 c1 = stream_read_char(demuxer->stream); | |
157 if(c1 < 0) | |
158 return 0; | |
159 } | |
160 c2 = stream_read_char(demuxer->stream); | |
161 if(c2 < 0) | |
162 return 0; | |
163 if((c2 & 0xF6) != 0xF0) | |
164 continue; | |
165 | |
166 priv->buf[0] = (unsigned char) c1; | |
167 priv->buf[1] = (unsigned char) c2; | |
168 if(stream_read(demuxer->stream, &(priv->buf[2]), 6) < 6) | |
169 return 0; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
170 |
15720 | 171 len = aac_parse_frame(priv->buf, &srate, &num); |
172 if(len > 0) | |
173 { | |
174 dp = new_demux_packet(len); | |
175 if(! dp) | |
176 { | |
177 mp_msg(MSGT_DEMUX, MSGL_ERR, "fill_buffer, NEW_ADD_PACKET(%d)FAILED\n", len); | |
178 return 0; | |
179 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
180 |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
181 |
15720 | 182 memcpy(dp->buffer, priv->buf, 8); |
183 stream_read(demuxer->stream, &(dp->buffer[8]), len-8); | |
184 if(srate) | |
185 tm = (float) (num * 1024.0/srate); | |
186 priv->last_pts += tm; | |
187 dp->pts = priv->last_pts; | |
188 //fprintf(stderr, "\nPTS: %.3f\n", dp->pts); | |
189 ds_add_packet(demuxer->audio, dp); | |
190 priv->size += len; | |
191 priv->time += tm; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
192 |
15720 | 193 priv->bitrate = (int) (priv->size / priv->time); |
194 demuxer->filepos = stream_tell(demuxer->stream); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
195 |
15720 | 196 return len; |
197 } | |
198 else | |
199 stream_skip(demuxer->stream, -6); | |
200 } | |
201 | |
202 return 0; | |
203 } | |
204 | |
205 | |
206 //This is an almost verbatim copy of high_res_mp3_seek(), from demux_audio.c | |
17636 | 207 static void demux_aac_seek(demuxer_t *demuxer, float rel_seek_secs, float audio_delay, int flags) |
15720 | 208 { |
209 aac_priv_t *priv = (aac_priv_t *) demuxer->priv; | |
210 demux_stream_t *d_audio=demuxer->audio; | |
211 sh_audio_t *sh_audio=d_audio->sh; | |
212 float time; | |
213 | |
214 ds_free_packs(d_audio); | |
215 | |
25883
baf32110d3fc
Use defines to give names to the different seek flags.
reimar
parents:
25707
diff
changeset
|
216 time = (flags & SEEK_ABSOLUTE) ? rel_seek_secs - priv->last_pts : rel_seek_secs; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
217 if(time < 0) |
15720 | 218 { |
219 stream_seek(demuxer->stream, demuxer->movi_start); | |
220 time = priv->last_pts + time; | |
221 priv->last_pts = 0; | |
222 } | |
223 | |
224 if(time > 0) | |
225 { | |
226 int len, nf, srate, num; | |
227 | |
228 nf = time * sh_audio->samplerate/1024; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
229 |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
230 while(nf > 0) |
15720 | 231 { |
232 if(stream_read(demuxer->stream,priv->buf, 8) < 8) | |
233 break; | |
234 len = aac_parse_frame(priv->buf, &srate, &num); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
235 if(len <= 0) |
15720 | 236 { |
237 stream_skip(demuxer->stream, -7); | |
238 continue; | |
239 } | |
240 stream_skip(demuxer->stream, len - 8); | |
241 priv->last_pts += (float) (num*1024.0/srate); | |
242 nf -= num; | |
243 } | |
244 } | |
245 } | |
246 | |
16175 | 247 |
25707
d4fe6e23283e
Make all demuxer_desc_t const, thus moving them to .rodata
reimar
parents:
22605
diff
changeset
|
248 const demuxer_desc_t demuxer_desc_aac = { |
16175 | 249 "AAC demuxer", |
250 "aac", | |
251 "AAC", | |
252 "Nico Sabbi", | |
253 "Raw AAC files ", | |
254 DEMUXER_TYPE_AAC, | |
255 0, // unsafe autodetect | |
256 demux_aac_probe, | |
257 demux_aac_fill_buffer, | |
258 demux_aac_open, | |
259 demux_close_aac, | |
260 demux_aac_seek, | |
261 NULL | |
262 }; |