Mercurial > mplayer.hg
annotate libmpdemux/demux_aac.c @ 33179:218edd8fc782
Cosmetic: Format to MPlayer coding style.
Additionally: remove needless includes, group and sort includes, group
and sort variables, rename gtkAOFakeSurround declaration gtkAOSurround,
add #ifdefs to variable declarations, group statements by adding or
removing new lines to ease reading, move assignments outside conditions,
add parentheses, avoid mixing declaration and code, revise comments and
add new ones.
author | ib |
---|---|
date | Fri, 15 Apr 2011 14:30:58 +0000 |
parents | 8fa2f43cb760 |
children | 92dd1764392a |
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 | |
32537
8fa2f43cb760
Remove most of the NULL pointer check before free all over the code
cboesch
parents:
31609
diff
changeset
|
68 free(priv->buf); |
15720 | 69 |
70 free(demuxer->priv); | |
71 | |
72 return; | |
73 } | |
74 | |
16175 | 75 /// returns DEMUXER_TYPE_AAC if it finds 8 ADTS frames in 32768 bytes, 0 otherwise |
76 static int demux_aac_probe(demuxer_t *demuxer) | |
15720 | 77 { |
78 int cnt = 0, c, len, srate, num; | |
79 off_t init, probed; | |
80 aac_priv_t *priv; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
81 |
15720 | 82 if(! demux_aac_init(demuxer)) |
83 { | |
84 mp_msg(MSGT_DEMUX, MSGL_ERR, "COULDN'T INIT aac_demux, exit\n"); | |
85 return 0; | |
86 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
87 |
15720 | 88 priv = (aac_priv_t *) demuxer->priv; |
89 | |
90 init = probed = stream_tell(demuxer->stream); | |
91 while(probed-init <= 32768 && cnt < 8) | |
92 { | |
93 c = 0; | |
94 while(c != 0xFF) | |
95 { | |
96 c = stream_read_char(demuxer->stream); | |
97 if(c < 0) | |
98 goto fail; | |
99 } | |
100 priv->buf[0] = 0xFF; | |
101 if(stream_read(demuxer->stream, &(priv->buf[1]), 7) < 7) | |
102 goto fail; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
103 |
15720 | 104 len = aac_parse_frame(priv->buf, &srate, &num); |
105 if(len > 0) | |
106 { | |
107 cnt++; | |
108 stream_skip(demuxer->stream, len - 8); | |
109 } | |
110 probed = stream_tell(demuxer->stream); | |
111 } | |
112 | |
113 stream_seek(demuxer->stream, init); | |
114 if(cnt < 8) | |
115 goto fail; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
116 |
16750
0a31740dd5e6
Use PRI?64 defines as format strings for 64 bit variables.
reimar
parents:
16175
diff
changeset
|
117 mp_msg(MSGT_DEMUX, MSGL_V, "demux_aac_probe, INIT: %"PRIu64", PROBED: %"PRIu64", cnt: %d\n", init, probed, cnt); |
16175 | 118 return DEMUXER_TYPE_AAC; |
15720 | 119 |
120 fail: | |
121 mp_msg(MSGT_DEMUX, MSGL_V, "demux_aac_probe, failed to detect an AAC stream\n"); | |
122 return 0; | |
123 } | |
124 | |
16175 | 125 static demuxer_t* demux_aac_open(demuxer_t *demuxer) |
15720 | 126 { |
127 sh_audio_t *sh; | |
128 | |
31609
cd81fce1f010
Make the stream language an argument to the stream creation function
reimar
parents:
30702
diff
changeset
|
129 sh = new_sh_audio(demuxer, 0, NULL); |
15720 | 130 sh->ds = demuxer->audio; |
131 sh->format = mmioFOURCC('M', 'P', '4', 'A'); | |
26299
4d56038ec730
Fix lots and lots of other demuxers broken by r26301
reimar
parents:
25883
diff
changeset
|
132 demuxer->audio->id = 0; |
15720 | 133 demuxer->audio->sh = sh; |
134 | |
135 demuxer->filepos = stream_tell(demuxer->stream); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
136 |
16175 | 137 return demuxer; |
15720 | 138 } |
139 | |
16175 | 140 static int demux_aac_fill_buffer(demuxer_t *demuxer, demux_stream_t *ds) |
15720 | 141 { |
142 aac_priv_t *priv = (aac_priv_t *) demuxer->priv; | |
143 demux_packet_t *dp; | |
144 int c1, c2, len, srate, num; | |
145 float tm = 0; | |
146 | |
147 if(demuxer->stream->eof || (demuxer->movi_end && stream_tell(demuxer->stream) >= demuxer->movi_end)) | |
148 return 0; | |
149 | |
150 while(! demuxer->stream->eof) | |
151 { | |
152 c1 = c2 = 0; | |
153 while(c1 != 0xFF) | |
154 { | |
155 c1 = stream_read_char(demuxer->stream); | |
156 if(c1 < 0) | |
157 return 0; | |
158 } | |
159 c2 = stream_read_char(demuxer->stream); | |
160 if(c2 < 0) | |
161 return 0; | |
162 if((c2 & 0xF6) != 0xF0) | |
163 continue; | |
164 | |
165 priv->buf[0] = (unsigned char) c1; | |
166 priv->buf[1] = (unsigned char) c2; | |
167 if(stream_read(demuxer->stream, &(priv->buf[2]), 6) < 6) | |
168 return 0; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
169 |
15720 | 170 len = aac_parse_frame(priv->buf, &srate, &num); |
171 if(len > 0) | |
172 { | |
173 dp = new_demux_packet(len); | |
174 if(! dp) | |
175 { | |
176 mp_msg(MSGT_DEMUX, MSGL_ERR, "fill_buffer, NEW_ADD_PACKET(%d)FAILED\n", len); | |
177 return 0; | |
178 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
179 |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
180 |
15720 | 181 memcpy(dp->buffer, priv->buf, 8); |
182 stream_read(demuxer->stream, &(dp->buffer[8]), len-8); | |
183 if(srate) | |
184 tm = (float) (num * 1024.0/srate); | |
185 priv->last_pts += tm; | |
186 dp->pts = priv->last_pts; | |
187 //fprintf(stderr, "\nPTS: %.3f\n", dp->pts); | |
188 ds_add_packet(demuxer->audio, dp); | |
189 priv->size += len; | |
190 priv->time += tm; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
191 |
15720 | 192 priv->bitrate = (int) (priv->size / priv->time); |
193 demuxer->filepos = stream_tell(demuxer->stream); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
194 |
15720 | 195 return len; |
196 } | |
197 else | |
198 stream_skip(demuxer->stream, -6); | |
199 } | |
200 | |
201 return 0; | |
202 } | |
203 | |
204 | |
205 //This is an almost verbatim copy of high_res_mp3_seek(), from demux_audio.c | |
17636 | 206 static void demux_aac_seek(demuxer_t *demuxer, float rel_seek_secs, float audio_delay, int flags) |
15720 | 207 { |
208 aac_priv_t *priv = (aac_priv_t *) demuxer->priv; | |
209 demux_stream_t *d_audio=demuxer->audio; | |
210 sh_audio_t *sh_audio=d_audio->sh; | |
211 float time; | |
212 | |
213 ds_free_packs(d_audio); | |
214 | |
25883
baf32110d3fc
Use defines to give names to the different seek flags.
reimar
parents:
25707
diff
changeset
|
215 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
|
216 if(time < 0) |
15720 | 217 { |
218 stream_seek(demuxer->stream, demuxer->movi_start); | |
219 time = priv->last_pts + time; | |
220 priv->last_pts = 0; | |
221 } | |
222 | |
223 if(time > 0) | |
224 { | |
225 int len, nf, srate, num; | |
226 | |
227 nf = time * sh_audio->samplerate/1024; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
228 |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
229 while(nf > 0) |
15720 | 230 { |
231 if(stream_read(demuxer->stream,priv->buf, 8) < 8) | |
232 break; | |
233 len = aac_parse_frame(priv->buf, &srate, &num); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
234 if(len <= 0) |
15720 | 235 { |
236 stream_skip(demuxer->stream, -7); | |
237 continue; | |
238 } | |
239 stream_skip(demuxer->stream, len - 8); | |
240 priv->last_pts += (float) (num*1024.0/srate); | |
241 nf -= num; | |
242 } | |
243 } | |
244 } | |
245 | |
16175 | 246 |
25707
d4fe6e23283e
Make all demuxer_desc_t const, thus moving them to .rodata
reimar
parents:
22605
diff
changeset
|
247 const demuxer_desc_t demuxer_desc_aac = { |
16175 | 248 "AAC demuxer", |
249 "aac", | |
250 "AAC", | |
251 "Nico Sabbi", | |
252 "Raw AAC files ", | |
253 DEMUXER_TYPE_AAC, | |
254 0, // unsafe autodetect | |
255 demux_aac_probe, | |
256 demux_aac_fill_buffer, | |
257 demux_aac_open, | |
258 demux_close_aac, | |
259 demux_aac_seek, | |
260 NULL | |
261 }; |