Mercurial > mplayer.hg
annotate libmpdemux/demux_aac.c @ 27985:1c77b86d355d
Remove a ColorFill that is not necessary since the surface it is used
on has exactly the same size as the video image and the video will
be copied into it before it is used the first time.
author | reimar |
---|---|
date | Mon, 24 Nov 2008 09:46:23 +0000 |
parents | fa91545f01bb |
children | d643e4643313 |
rev | line source |
---|---|
15720 | 1 #include <stdio.h> |
2 #include <stdlib.h> | |
3 #include <string.h> | |
4 | |
5 #include "config.h" | |
6 #include "mp_msg.h" | |
7 #include "help_mp.h" | |
8 | |
22605
4d81dbdf46b9
Add explicit location for headers from the stream/ directory.
diego
parents:
21421
diff
changeset
|
9 #include "stream/stream.h" |
15720 | 10 #include "demuxer.h" |
11 #include "parse_es.h" | |
12 #include "stheader.h" | |
13 | |
14 #include "ms_hdr.h" | |
15 | |
16 typedef struct { | |
17 uint8_t *buf; | |
18 uint64_t size; /// amount of time of data packets pushed to demuxer->audio (in bytes) | |
19 float time; /// amount of time elapsed based upon samples_per_frame/sample_rate (in milliseconds) | |
20 float last_pts; /// last pts seen | |
21 int bitrate; /// bitrate computed as size/time | |
22 } aac_priv_t; | |
23 | |
24 /// \param srate (out) sample rate | |
25 /// \param num (out) number of audio frames in this ADTS frame | |
26 /// \return size of the ADTS frame in bytes | |
27 /// aac_parse_frames needs a buffer at least 8 bytes long | |
26327
fa91545f01bb
Split the aac header parsing out of aac demuxer to allow using libmpmux
albeu
parents:
26299
diff
changeset
|
28 int aac_parse_frame(uint8_t *buf, int *srate, int *num); |
15720 | 29 |
30 static int demux_aac_init(demuxer_t *demuxer) | |
31 { | |
32 aac_priv_t *priv; | |
33 | |
34 priv = calloc(1, sizeof(aac_priv_t)); | |
35 if(!priv) | |
36 return 0; | |
37 | |
38 priv->buf = (uint8_t*) malloc(8); | |
39 if(!priv->buf) | |
17789
9f0c42967ce5
fix minor (i.e. unlikely to ever happen) leak when init fails
reimar
parents:
17636
diff
changeset
|
40 { |
9f0c42967ce5
fix minor (i.e. unlikely to ever happen) leak when init fails
reimar
parents:
17636
diff
changeset
|
41 free(priv); |
15720 | 42 return 0; |
17789
9f0c42967ce5
fix minor (i.e. unlikely to ever happen) leak when init fails
reimar
parents:
17636
diff
changeset
|
43 } |
15720 | 44 |
45 demuxer->priv = priv; | |
46 return 1; | |
47 } | |
48 | |
16175 | 49 static void demux_close_aac(demuxer_t *demuxer) |
15720 | 50 { |
51 aac_priv_t *priv = (aac_priv_t *) demuxer->priv; | |
52 | |
53 if(!priv) | |
54 return; | |
55 | |
56 if(priv->buf) | |
57 free(priv->buf); | |
58 | |
59 free(demuxer->priv); | |
60 | |
61 return; | |
62 } | |
63 | |
16175 | 64 /// returns DEMUXER_TYPE_AAC if it finds 8 ADTS frames in 32768 bytes, 0 otherwise |
65 static int demux_aac_probe(demuxer_t *demuxer) | |
15720 | 66 { |
67 int cnt = 0, c, len, srate, num; | |
68 off_t init, probed; | |
69 aac_priv_t *priv; | |
70 | |
71 if(! demux_aac_init(demuxer)) | |
72 { | |
73 mp_msg(MSGT_DEMUX, MSGL_ERR, "COULDN'T INIT aac_demux, exit\n"); | |
74 return 0; | |
75 } | |
76 | |
77 priv = (aac_priv_t *) demuxer->priv; | |
78 | |
79 init = probed = stream_tell(demuxer->stream); | |
80 while(probed-init <= 32768 && cnt < 8) | |
81 { | |
82 c = 0; | |
83 while(c != 0xFF) | |
84 { | |
85 c = stream_read_char(demuxer->stream); | |
86 if(c < 0) | |
87 goto fail; | |
88 } | |
89 priv->buf[0] = 0xFF; | |
90 if(stream_read(demuxer->stream, &(priv->buf[1]), 7) < 7) | |
91 goto fail; | |
92 | |
93 len = aac_parse_frame(priv->buf, &srate, &num); | |
94 if(len > 0) | |
95 { | |
96 cnt++; | |
97 stream_skip(demuxer->stream, len - 8); | |
98 } | |
99 probed = stream_tell(demuxer->stream); | |
100 } | |
101 | |
102 stream_seek(demuxer->stream, init); | |
103 if(cnt < 8) | |
104 goto fail; | |
105 | |
16750
0a31740dd5e6
Use PRI?64 defines as format strings for 64 bit variables.
reimar
parents:
16175
diff
changeset
|
106 mp_msg(MSGT_DEMUX, MSGL_V, "demux_aac_probe, INIT: %"PRIu64", PROBED: %"PRIu64", cnt: %d\n", init, probed, cnt); |
16175 | 107 return DEMUXER_TYPE_AAC; |
15720 | 108 |
109 fail: | |
110 mp_msg(MSGT_DEMUX, MSGL_V, "demux_aac_probe, failed to detect an AAC stream\n"); | |
111 return 0; | |
112 } | |
113 | |
16175 | 114 static demuxer_t* demux_aac_open(demuxer_t *demuxer) |
15720 | 115 { |
116 sh_audio_t *sh; | |
117 | |
118 sh = new_sh_audio(demuxer, 0); | |
119 sh->ds = demuxer->audio; | |
120 sh->format = mmioFOURCC('M', 'P', '4', 'A'); | |
26299
4d56038ec730
Fix lots and lots of other demuxers broken by r26301
reimar
parents:
25883
diff
changeset
|
121 demuxer->audio->id = 0; |
15720 | 122 demuxer->audio->sh = sh; |
123 | |
124 demuxer->filepos = stream_tell(demuxer->stream); | |
125 | |
16175 | 126 return demuxer; |
15720 | 127 } |
128 | |
16175 | 129 static int demux_aac_fill_buffer(demuxer_t *demuxer, demux_stream_t *ds) |
15720 | 130 { |
131 aac_priv_t *priv = (aac_priv_t *) demuxer->priv; | |
132 demux_packet_t *dp; | |
133 int c1, c2, len, srate, num; | |
134 float tm = 0; | |
135 | |
136 if(demuxer->stream->eof || (demuxer->movi_end && stream_tell(demuxer->stream) >= demuxer->movi_end)) | |
137 return 0; | |
138 | |
139 while(! demuxer->stream->eof) | |
140 { | |
141 c1 = c2 = 0; | |
142 while(c1 != 0xFF) | |
143 { | |
144 c1 = stream_read_char(demuxer->stream); | |
145 if(c1 < 0) | |
146 return 0; | |
147 } | |
148 c2 = stream_read_char(demuxer->stream); | |
149 if(c2 < 0) | |
150 return 0; | |
151 if((c2 & 0xF6) != 0xF0) | |
152 continue; | |
153 | |
154 priv->buf[0] = (unsigned char) c1; | |
155 priv->buf[1] = (unsigned char) c2; | |
156 if(stream_read(demuxer->stream, &(priv->buf[2]), 6) < 6) | |
157 return 0; | |
158 | |
159 len = aac_parse_frame(priv->buf, &srate, &num); | |
160 if(len > 0) | |
161 { | |
162 dp = new_demux_packet(len); | |
163 if(! dp) | |
164 { | |
165 mp_msg(MSGT_DEMUX, MSGL_ERR, "fill_buffer, NEW_ADD_PACKET(%d)FAILED\n", len); | |
166 return 0; | |
167 } | |
168 | |
169 | |
170 memcpy(dp->buffer, priv->buf, 8); | |
171 stream_read(demuxer->stream, &(dp->buffer[8]), len-8); | |
172 if(srate) | |
173 tm = (float) (num * 1024.0/srate); | |
174 priv->last_pts += tm; | |
175 dp->pts = priv->last_pts; | |
176 //fprintf(stderr, "\nPTS: %.3f\n", dp->pts); | |
177 ds_add_packet(demuxer->audio, dp); | |
178 priv->size += len; | |
179 priv->time += tm; | |
180 | |
181 priv->bitrate = (int) (priv->size / priv->time); | |
182 demuxer->filepos = stream_tell(demuxer->stream); | |
183 | |
184 return len; | |
185 } | |
186 else | |
187 stream_skip(demuxer->stream, -6); | |
188 } | |
189 | |
190 return 0; | |
191 } | |
192 | |
193 | |
194 //This is an almost verbatim copy of high_res_mp3_seek(), from demux_audio.c | |
17636 | 195 static void demux_aac_seek(demuxer_t *demuxer, float rel_seek_secs, float audio_delay, int flags) |
15720 | 196 { |
197 aac_priv_t *priv = (aac_priv_t *) demuxer->priv; | |
198 demux_stream_t *d_audio=demuxer->audio; | |
199 sh_audio_t *sh_audio=d_audio->sh; | |
200 float time; | |
201 | |
202 ds_free_packs(d_audio); | |
203 | |
25883
baf32110d3fc
Use defines to give names to the different seek flags.
reimar
parents:
25707
diff
changeset
|
204 time = (flags & SEEK_ABSOLUTE) ? rel_seek_secs - priv->last_pts : rel_seek_secs; |
15720 | 205 if(time < 0) |
206 { | |
207 stream_seek(demuxer->stream, demuxer->movi_start); | |
208 time = priv->last_pts + time; | |
209 priv->last_pts = 0; | |
210 } | |
211 | |
212 if(time > 0) | |
213 { | |
214 int len, nf, srate, num; | |
215 | |
216 nf = time * sh_audio->samplerate/1024; | |
217 | |
218 while(nf > 0) | |
219 { | |
220 if(stream_read(demuxer->stream,priv->buf, 8) < 8) | |
221 break; | |
222 len = aac_parse_frame(priv->buf, &srate, &num); | |
223 if(len <= 0) | |
224 { | |
225 stream_skip(demuxer->stream, -7); | |
226 continue; | |
227 } | |
228 stream_skip(demuxer->stream, len - 8); | |
229 priv->last_pts += (float) (num*1024.0/srate); | |
230 nf -= num; | |
231 } | |
232 } | |
233 } | |
234 | |
16175 | 235 |
25707
d4fe6e23283e
Make all demuxer_desc_t const, thus moving them to .rodata
reimar
parents:
22605
diff
changeset
|
236 const demuxer_desc_t demuxer_desc_aac = { |
16175 | 237 "AAC demuxer", |
238 "aac", | |
239 "AAC", | |
240 "Nico Sabbi", | |
241 "Raw AAC files ", | |
242 DEMUXER_TYPE_AAC, | |
243 0, // unsafe autodetect | |
244 demux_aac_probe, | |
245 demux_aac_fill_buffer, | |
246 demux_aac_open, | |
247 demux_close_aac, | |
248 demux_aac_seek, | |
249 NULL | |
250 }; |