Mercurial > libavcodec.hg
annotate parser.c @ 4166:eced83504436 libavcodec
mp3 header (de)compression bitstream filter
this will make mp3 frames 4 bytes smaller, it will not give you binary identical mp3 files, but it will give you mp3 files which decode to binary identical output
this will only work in containers providing at least packet size, sample_rate and number of channels
bugreports about mp3 files for which this fails are welcome
and this is experimental (dont expect compatibility and dont even expect to be able to decompress what you compressed, hell dont even expect this to work without editing the source a little)
author | michael |
---|---|
date | Fri, 10 Nov 2006 01:41:53 +0000 |
parents | 2205aefb22b7 |
children | b3328ed50a5e |
rev | line source |
---|---|
1613 | 1 /* |
2 * Audio and Video frame extraction | |
3 * Copyright (c) 2003 Fabrice Bellard. | |
4 * Copyright (c) 2003 Michael Niedermayer. | |
5 * | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3776
diff
changeset
|
6 * This file is part of FFmpeg. |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3776
diff
changeset
|
7 * |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3776
diff
changeset
|
8 * FFmpeg is free software; you can redistribute it and/or |
1613 | 9 * modify it under the terms of the GNU Lesser General Public |
10 * License as published by the Free Software Foundation; either | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3776
diff
changeset
|
11 * version 2.1 of the License, or (at your option) any later version. |
1613 | 12 * |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3776
diff
changeset
|
13 * FFmpeg is distributed in the hope that it will be useful, |
1613 | 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
16 * Lesser General Public License for more details. | |
17 * | |
18 * You should have received a copy of the GNU Lesser General Public | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3776
diff
changeset
|
19 * License along with FFmpeg; if not, write to the Free Software |
3036
0b546eab515d
Update licensing information: The FSF changed postal address.
diego
parents:
2979
diff
changeset
|
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
1613 | 21 */ |
22 #include "avcodec.h" | |
23 #include "mpegvideo.h" | |
24 #include "mpegaudio.h" | |
4150
2205aefb22b7
move AVCodecParser prototypes and definitions to parser.h, and move mpegvideo parser to mpeg12.c
bcoudurier
parents:
4146
diff
changeset
|
25 #include "parser.h" |
1613 | 26 |
27 AVCodecParser *av_first_parser = NULL; | |
28 | |
29 void av_register_codec_parser(AVCodecParser *parser) | |
30 { | |
31 parser->next = av_first_parser; | |
32 av_first_parser = parser; | |
33 } | |
34 | |
35 AVCodecParserContext *av_parser_init(int codec_id) | |
36 { | |
37 AVCodecParserContext *s; | |
38 AVCodecParser *parser; | |
39 int ret; | |
2967 | 40 |
2486
f2a9559db6ac
10l (array gets padded with 0 which is CODEC_ID_NONE -> parsers claim to support CODEC_ID_NONE)
michael
parents:
2480
diff
changeset
|
41 if(codec_id == CODEC_ID_NONE) |
f2a9559db6ac
10l (array gets padded with 0 which is CODEC_ID_NONE -> parsers claim to support CODEC_ID_NONE)
michael
parents:
2480
diff
changeset
|
42 return NULL; |
1613 | 43 |
44 for(parser = av_first_parser; parser != NULL; parser = parser->next) { | |
45 if (parser->codec_ids[0] == codec_id || | |
46 parser->codec_ids[1] == codec_id || | |
2348 | 47 parser->codec_ids[2] == codec_id || |
48 parser->codec_ids[3] == codec_id || | |
49 parser->codec_ids[4] == codec_id) | |
1613 | 50 goto found; |
51 } | |
52 return NULL; | |
53 found: | |
54 s = av_mallocz(sizeof(AVCodecParserContext)); | |
55 if (!s) | |
56 return NULL; | |
57 s->parser = parser; | |
58 s->priv_data = av_mallocz(parser->priv_data_size); | |
59 if (!s->priv_data) { | |
60 av_free(s); | |
61 return NULL; | |
62 } | |
63 if (parser->parser_init) { | |
64 ret = parser->parser_init(s); | |
65 if (ret != 0) { | |
66 av_free(s->priv_data); | |
67 av_free(s); | |
68 return NULL; | |
69 } | |
70 } | |
2030 | 71 s->fetch_timestamp=1; |
1613 | 72 return s; |
73 } | |
74 | |
3989 | 75 /** |
76 * | |
77 * @param buf input | |
78 * @param buf_size input length, to signal EOF, this should be 0 (so that the last frame can be output) | |
79 * @param pts input presentation timestamp | |
80 * @param dts input decoding timestamp | |
81 * @param poutbuf will contain a pointer to the first byte of the output frame | |
82 * @param poutbuf_size will contain the length of the output frame | |
83 * @return the number of bytes of the input bitstream used | |
84 * | |
85 * Example: | |
86 * @code | |
87 * while(in_len){ | |
88 * len = av_parser_parse(myparser, AVCodecContext, &data, &size, | |
89 * in_data, in_len, | |
90 * pts, dts); | |
91 * in_data += len; | |
92 * in_len -= len; | |
93 * | |
94 * decode_frame(data, size); | |
95 * } | |
96 * @endcode | |
97 */ | |
2967 | 98 int av_parser_parse(AVCodecParserContext *s, |
1613 | 99 AVCodecContext *avctx, |
2967 | 100 uint8_t **poutbuf, int *poutbuf_size, |
1696 | 101 const uint8_t *buf, int buf_size, |
102 int64_t pts, int64_t dts) | |
1613 | 103 { |
1696 | 104 int index, i, k; |
1694
13169235c306
added End Of File handling to return last picture for MPEG1/2/4
bellard
parents:
1681
diff
changeset
|
105 uint8_t dummy_buf[FF_INPUT_BUFFER_PADDING_SIZE]; |
2967 | 106 |
1694
13169235c306
added End Of File handling to return last picture for MPEG1/2/4
bellard
parents:
1681
diff
changeset
|
107 if (buf_size == 0) { |
13169235c306
added End Of File handling to return last picture for MPEG1/2/4
bellard
parents:
1681
diff
changeset
|
108 /* padding is always necessary even if EOF, so we add it here */ |
13169235c306
added End Of File handling to return last picture for MPEG1/2/4
bellard
parents:
1681
diff
changeset
|
109 memset(dummy_buf, 0, sizeof(dummy_buf)); |
13169235c306
added End Of File handling to return last picture for MPEG1/2/4
bellard
parents:
1681
diff
changeset
|
110 buf = dummy_buf; |
1696 | 111 } else { |
112 /* add a new packet descriptor */ | |
113 k = (s->cur_frame_start_index + 1) & (AV_PARSER_PTS_NB - 1); | |
114 s->cur_frame_start_index = k; | |
115 s->cur_frame_offset[k] = s->cur_offset; | |
116 s->cur_frame_pts[k] = pts; | |
117 s->cur_frame_dts[k] = dts; | |
118 | |
119 /* fill first PTS/DTS */ | |
2030 | 120 if (s->fetch_timestamp){ |
121 s->fetch_timestamp=0; | |
1696 | 122 s->last_pts = pts; |
123 s->last_dts = dts; | |
2107 | 124 s->cur_frame_pts[k] = |
125 s->cur_frame_dts[k] = AV_NOPTS_VALUE; | |
1696 | 126 } |
1694
13169235c306
added End Of File handling to return last picture for MPEG1/2/4
bellard
parents:
1681
diff
changeset
|
127 } |
13169235c306
added End Of File handling to return last picture for MPEG1/2/4
bellard
parents:
1681
diff
changeset
|
128 |
1613 | 129 /* WARNING: the returned index can be negative */ |
130 index = s->parser->parser_parse(s, avctx, poutbuf, poutbuf_size, buf, buf_size); | |
4122
daae66c03857
Replace most of the %lld and %llx by their (cleaner) PRI*64 counterparts.
diego
parents:
4104
diff
changeset
|
131 //av_log(NULL, AV_LOG_DEBUG, "parser: in:%"PRId64", %"PRId64", out:%"PRId64", %"PRId64", in:%d out:%d id:%d\n", pts, dts, s->last_pts, s->last_dts, buf_size, *poutbuf_size, avctx->codec_id); |
1613 | 132 /* update the file pointer */ |
133 if (*poutbuf_size) { | |
1696 | 134 /* fill the data for the current frame */ |
1613 | 135 s->frame_offset = s->last_frame_offset; |
1696 | 136 s->pts = s->last_pts; |
137 s->dts = s->last_dts; | |
2967 | 138 |
1696 | 139 /* offset of the next frame */ |
1613 | 140 s->last_frame_offset = s->cur_offset + index; |
1696 | 141 /* find the packet in which the new frame starts. It |
142 is tricky because of MPEG video start codes | |
143 which can begin in one packet and finish in | |
144 another packet. In the worst case, an MPEG | |
145 video start code could be in 4 different | |
146 packets. */ | |
147 k = s->cur_frame_start_index; | |
148 for(i = 0; i < AV_PARSER_PTS_NB; i++) { | |
149 if (s->last_frame_offset >= s->cur_frame_offset[k]) | |
150 break; | |
151 k = (k - 1) & (AV_PARSER_PTS_NB - 1); | |
152 } | |
2030 | 153 |
1696 | 154 s->last_pts = s->cur_frame_pts[k]; |
155 s->last_dts = s->cur_frame_dts[k]; | |
2967 | 156 |
2030 | 157 /* some parsers tell us the packet size even before seeing the first byte of the next packet, |
158 so the next pts/dts is in the next chunk */ | |
159 if(index == buf_size){ | |
160 s->fetch_timestamp=1; | |
161 } | |
1613 | 162 } |
163 if (index < 0) | |
164 index = 0; | |
165 s->cur_offset += index; | |
166 return index; | |
167 } | |
168 | |
2777 | 169 /** |
170 * | |
171 * @return 0 if the output buffer is a subset of the input, 1 if it is allocated and must be freed | |
3421
b7826511f7b6
AVBitStreamFilter (some thingy which can modify the bitstream like add or remove global headers or change the headers or ...)
michael
parents:
3395
diff
changeset
|
172 * @deprecated use AVBitstreamFilter |
2777 | 173 */ |
2769
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
174 int av_parser_change(AVCodecParserContext *s, |
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
175 AVCodecContext *avctx, |
2967 | 176 uint8_t **poutbuf, int *poutbuf_size, |
2769
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
177 const uint8_t *buf, int buf_size, int keyframe){ |
2967 | 178 |
2769
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
179 if(s && s->parser->split){ |
2777 | 180 if((avctx->flags & CODEC_FLAG_GLOBAL_HEADER) || (avctx->flags2 & CODEC_FLAG2_LOCAL_HEADER)){ |
2769
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
181 int i= s->parser->split(avctx, buf, buf_size); |
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
182 buf += i; |
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
183 buf_size -= i; |
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
184 } |
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
185 } |
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
186 |
2864
95bac7109ff0
Kill some compiler warnings. Compiled code verified identical after changes.
mru
parents:
2846
diff
changeset
|
187 /* cast to avoid warning about discarding qualifiers */ |
95bac7109ff0
Kill some compiler warnings. Compiled code verified identical after changes.
mru
parents:
2846
diff
changeset
|
188 *poutbuf= (uint8_t *) buf; |
2769
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
189 *poutbuf_size= buf_size; |
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
190 if(avctx->extradata){ |
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
191 if( (keyframe && (avctx->flags2 & CODEC_FLAG2_LOCAL_HEADER)) |
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
192 /*||(s->pict_type != I_TYPE && (s->flags & PARSER_FLAG_DUMP_EXTRADATA_AT_NOKEY))*/ |
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
193 /*||(? && (s->flags & PARSER_FLAG_DUMP_EXTRADATA_AT_BEGIN)*/){ |
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
194 int size= buf_size + avctx->extradata_size; |
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
195 *poutbuf_size= size; |
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
196 *poutbuf= av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE); |
2967 | 197 |
2769
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
198 memcpy(*poutbuf, avctx->extradata, avctx->extradata_size); |
2777 | 199 memcpy((*poutbuf) + avctx->extradata_size, buf, buf_size + FF_INPUT_BUFFER_PADDING_SIZE); |
2769
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
200 return 1; |
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
201 } |
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
202 } |
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
203 |
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
204 return 0; |
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
205 } |
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
206 |
1613 | 207 void av_parser_close(AVCodecParserContext *s) |
208 { | |
209 if (s->parser->parser_close) | |
210 s->parser->parser_close(s); | |
211 av_free(s->priv_data); | |
212 av_free(s); | |
213 } | |
214 | |
215 /*****************************************************/ | |
216 | |
217 /** | |
218 * combines the (truncated) bitstream to a complete frame | |
219 * @returns -1 if no complete frame could be created | |
220 */ | |
1988 | 221 int ff_combine_frame(ParseContext *pc, int next, uint8_t **buf, int *buf_size) |
1613 | 222 { |
223 #if 0 | |
224 if(pc->overread){ | |
225 printf("overread %d, state:%X next:%d index:%d o_index:%d\n", pc->overread, pc->state, next, pc->index, pc->overread_index); | |
226 printf("%X %X %X %X\n", (*buf)[0], (*buf)[1],(*buf)[2],(*buf)[3]); | |
227 } | |
228 #endif | |
229 | |
230 /* copy overreaded bytes from last frame into buffer */ | |
231 for(; pc->overread>0; pc->overread--){ | |
232 pc->buffer[pc->index++]= pc->buffer[pc->overread_index++]; | |
233 } | |
2386 | 234 |
235 /* flush remaining if EOF */ | |
236 if(!*buf_size && next == END_NOT_FOUND){ | |
237 next= 0; | |
238 } | |
239 | |
1613 | 240 pc->last_index= pc->index; |
241 | |
242 /* copy into buffer end return */ | |
243 if(next == END_NOT_FOUND){ | |
244 pc->buffer= av_fast_realloc(pc->buffer, &pc->buffer_size, (*buf_size) + pc->index + FF_INPUT_BUFFER_PADDING_SIZE); | |
245 | |
246 memcpy(&pc->buffer[pc->index], *buf, *buf_size); | |
247 pc->index += *buf_size; | |
248 return -1; | |
249 } | |
250 | |
251 *buf_size= | |
252 pc->overread_index= pc->index + next; | |
2967 | 253 |
1613 | 254 /* append to buffer */ |
255 if(pc->index){ | |
256 pc->buffer= av_fast_realloc(pc->buffer, &pc->buffer_size, next + pc->index + FF_INPUT_BUFFER_PADDING_SIZE); | |
257 | |
258 memcpy(&pc->buffer[pc->index], *buf, next + FF_INPUT_BUFFER_PADDING_SIZE ); | |
259 pc->index = 0; | |
260 *buf= pc->buffer; | |
261 } | |
262 | |
263 /* store overread bytes */ | |
264 for(;next < 0; next++){ | |
265 pc->state = (pc->state<<8) | pc->buffer[pc->last_index + next]; | |
266 pc->overread++; | |
267 } | |
268 | |
269 #if 0 | |
270 if(pc->overread){ | |
271 printf("overread %d, state:%X next:%d index:%d o_index:%d\n", pc->overread, pc->state, next, pc->index, pc->overread_index); | |
272 printf("%X %X %X %X\n", (*buf)[0], (*buf)[1],(*buf)[2],(*buf)[3]); | |
273 } | |
274 #endif | |
275 | |
276 return 0; | |
277 } | |
278 | |
1988 | 279 void ff_parse_close(AVCodecParserContext *s) |
1613 | 280 { |
1988 | 281 ParseContext *pc = s->priv_data; |
1613 | 282 |
283 av_free(pc->buffer); | |
1988 | 284 } |
285 | |
4150
2205aefb22b7
move AVCodecParser prototypes and definitions to parser.h, and move mpegvideo parser to mpeg12.c
bcoudurier
parents:
4146
diff
changeset
|
286 void ff_parse1_close(AVCodecParserContext *s) |
1988 | 287 { |
288 ParseContext1 *pc1 = s->priv_data; | |
289 | |
290 av_free(pc1->pc.buffer); | |
291 av_free(pc1->enc); | |
1613 | 292 } |
293 | |
294 /*************************/ | |
295 | |
3455
cc4b4ea83e29
--enable/disable parsers. Warning: some combinations are broken.
mru
parents:
3432
diff
changeset
|
296 #ifdef CONFIG_MPEG4VIDEO_PARSER |
1613 | 297 /* used by parser */ |
298 /* XXX: make it use less memory */ | |
2967 | 299 static int av_mpeg4_decode_header(AVCodecParserContext *s1, |
1613 | 300 AVCodecContext *avctx, |
301 const uint8_t *buf, int buf_size) | |
302 { | |
303 ParseContext1 *pc = s1->priv_data; | |
304 MpegEncContext *s = pc->enc; | |
305 GetBitContext gb1, *gb = &gb1; | |
306 int ret; | |
307 | |
308 s->avctx = avctx; | |
1614 | 309 s->current_picture_ptr = &s->current_picture; |
310 | |
311 if (avctx->extradata_size && pc->first_picture){ | |
312 init_get_bits(gb, avctx->extradata, avctx->extradata_size*8); | |
313 ret = ff_mpeg4_decode_picture_header(s, gb); | |
314 } | |
315 | |
1613 | 316 init_get_bits(gb, buf, 8 * buf_size); |
317 ret = ff_mpeg4_decode_picture_header(s, gb); | |
318 if (s->width) { | |
2270 | 319 avcodec_set_dimensions(avctx, s->width, s->height); |
1613 | 320 } |
2837 | 321 s1->pict_type= s->pict_type; |
1614 | 322 pc->first_picture = 0; |
1613 | 323 return ret; |
324 } | |
325 | |
2024
f65d87bfdd5a
some of the warning fixes by (Michael Roitzsch <mroi at users dot sourceforge dot net>)
michael
parents:
1988
diff
changeset
|
326 static int mpeg4video_parse_init(AVCodecParserContext *s) |
1613 | 327 { |
328 ParseContext1 *pc = s->priv_data; | |
1614 | 329 |
1613 | 330 pc->enc = av_mallocz(sizeof(MpegEncContext)); |
331 if (!pc->enc) | |
332 return -1; | |
1614 | 333 pc->first_picture = 1; |
1613 | 334 return 0; |
335 } | |
336 | |
337 static int mpeg4video_parse(AVCodecParserContext *s, | |
338 AVCodecContext *avctx, | |
2967 | 339 uint8_t **poutbuf, int *poutbuf_size, |
1613 | 340 const uint8_t *buf, int buf_size) |
341 { | |
1988 | 342 ParseContext *pc = s->priv_data; |
1613 | 343 int next; |
2967 | 344 |
2837 | 345 if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){ |
346 next= buf_size; | |
347 }else{ | |
348 next= ff_mpeg4_find_frame_end(pc, buf, buf_size); | |
2967 | 349 |
2837 | 350 if (ff_combine_frame(pc, next, (uint8_t **)&buf, &buf_size) < 0) { |
351 *poutbuf = NULL; | |
352 *poutbuf_size = 0; | |
353 return buf_size; | |
354 } | |
1613 | 355 } |
356 av_mpeg4_decode_header(s, avctx, buf, buf_size); | |
357 | |
358 *poutbuf = (uint8_t *)buf; | |
359 *poutbuf_size = buf_size; | |
360 return next; | |
361 } | |
3455
cc4b4ea83e29
--enable/disable parsers. Warning: some combinations are broken.
mru
parents:
3432
diff
changeset
|
362 #endif |
1613 | 363 |
3455
cc4b4ea83e29
--enable/disable parsers. Warning: some combinations are broken.
mru
parents:
3432
diff
changeset
|
364 #ifdef CONFIG_CAVSVIDEO_PARSER |
3395
adccbf4a1040
CAVS decoder by (Stefan Gehrer stefan.gehrer gmx.de)
michael
parents:
3344
diff
changeset
|
365 static int cavsvideo_parse(AVCodecParserContext *s, |
adccbf4a1040
CAVS decoder by (Stefan Gehrer stefan.gehrer gmx.de)
michael
parents:
3344
diff
changeset
|
366 AVCodecContext *avctx, |
adccbf4a1040
CAVS decoder by (Stefan Gehrer stefan.gehrer gmx.de)
michael
parents:
3344
diff
changeset
|
367 uint8_t **poutbuf, int *poutbuf_size, |
adccbf4a1040
CAVS decoder by (Stefan Gehrer stefan.gehrer gmx.de)
michael
parents:
3344
diff
changeset
|
368 const uint8_t *buf, int buf_size) |
adccbf4a1040
CAVS decoder by (Stefan Gehrer stefan.gehrer gmx.de)
michael
parents:
3344
diff
changeset
|
369 { |
adccbf4a1040
CAVS decoder by (Stefan Gehrer stefan.gehrer gmx.de)
michael
parents:
3344
diff
changeset
|
370 ParseContext *pc = s->priv_data; |
adccbf4a1040
CAVS decoder by (Stefan Gehrer stefan.gehrer gmx.de)
michael
parents:
3344
diff
changeset
|
371 int next; |
adccbf4a1040
CAVS decoder by (Stefan Gehrer stefan.gehrer gmx.de)
michael
parents:
3344
diff
changeset
|
372 |
adccbf4a1040
CAVS decoder by (Stefan Gehrer stefan.gehrer gmx.de)
michael
parents:
3344
diff
changeset
|
373 if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){ |
adccbf4a1040
CAVS decoder by (Stefan Gehrer stefan.gehrer gmx.de)
michael
parents:
3344
diff
changeset
|
374 next= buf_size; |
adccbf4a1040
CAVS decoder by (Stefan Gehrer stefan.gehrer gmx.de)
michael
parents:
3344
diff
changeset
|
375 }else{ |
adccbf4a1040
CAVS decoder by (Stefan Gehrer stefan.gehrer gmx.de)
michael
parents:
3344
diff
changeset
|
376 next= ff_cavs_find_frame_end(pc, buf, buf_size); |
adccbf4a1040
CAVS decoder by (Stefan Gehrer stefan.gehrer gmx.de)
michael
parents:
3344
diff
changeset
|
377 |
adccbf4a1040
CAVS decoder by (Stefan Gehrer stefan.gehrer gmx.de)
michael
parents:
3344
diff
changeset
|
378 if (ff_combine_frame(pc, next, (uint8_t **)&buf, &buf_size) < 0) { |
adccbf4a1040
CAVS decoder by (Stefan Gehrer stefan.gehrer gmx.de)
michael
parents:
3344
diff
changeset
|
379 *poutbuf = NULL; |
adccbf4a1040
CAVS decoder by (Stefan Gehrer stefan.gehrer gmx.de)
michael
parents:
3344
diff
changeset
|
380 *poutbuf_size = 0; |
adccbf4a1040
CAVS decoder by (Stefan Gehrer stefan.gehrer gmx.de)
michael
parents:
3344
diff
changeset
|
381 return buf_size; |
adccbf4a1040
CAVS decoder by (Stefan Gehrer stefan.gehrer gmx.de)
michael
parents:
3344
diff
changeset
|
382 } |
adccbf4a1040
CAVS decoder by (Stefan Gehrer stefan.gehrer gmx.de)
michael
parents:
3344
diff
changeset
|
383 } |
adccbf4a1040
CAVS decoder by (Stefan Gehrer stefan.gehrer gmx.de)
michael
parents:
3344
diff
changeset
|
384 *poutbuf = (uint8_t *)buf; |
adccbf4a1040
CAVS decoder by (Stefan Gehrer stefan.gehrer gmx.de)
michael
parents:
3344
diff
changeset
|
385 *poutbuf_size = buf_size; |
adccbf4a1040
CAVS decoder by (Stefan Gehrer stefan.gehrer gmx.de)
michael
parents:
3344
diff
changeset
|
386 return next; |
adccbf4a1040
CAVS decoder by (Stefan Gehrer stefan.gehrer gmx.de)
michael
parents:
3344
diff
changeset
|
387 } |
3455
cc4b4ea83e29
--enable/disable parsers. Warning: some combinations are broken.
mru
parents:
3432
diff
changeset
|
388 #endif /* CONFIG_CAVSVIDEO_PARSER */ |
3395
adccbf4a1040
CAVS decoder by (Stefan Gehrer stefan.gehrer gmx.de)
michael
parents:
3344
diff
changeset
|
389 |
2769
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
390 static int mpeg4video_split(AVCodecContext *avctx, |
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
391 const uint8_t *buf, int buf_size) |
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
392 { |
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
393 int i; |
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
394 uint32_t state= -1; |
2967 | 395 |
2769
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
396 for(i=0; i<buf_size; i++){ |
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
397 state= (state<<8) | buf[i]; |
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
398 if(state == 0x1B3 || state == 0x1B6) |
2777 | 399 return i-3; |
2769
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
400 } |
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
401 return 0; |
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
402 } |
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
403 |
1613 | 404 /*************************/ |
405 | |
3455
cc4b4ea83e29
--enable/disable parsers. Warning: some combinations are broken.
mru
parents:
3432
diff
changeset
|
406 #ifdef CONFIG_MPEGAUDIO_PARSER |
1613 | 407 typedef struct MpegAudioParseContext { |
2979 | 408 uint8_t inbuf[MPA_MAX_CODED_FRAME_SIZE]; /* input buffer */ |
1613 | 409 uint8_t *inbuf_ptr; |
410 int frame_size; | |
411 int free_format_frame_size; | |
412 int free_format_next_header; | |
2470
06aafb585f69
require a few valid and equal mp3 headers for resync
michael
parents:
2389
diff
changeset
|
413 uint32_t header; |
06aafb585f69
require a few valid and equal mp3 headers for resync
michael
parents:
2389
diff
changeset
|
414 int header_count; |
1613 | 415 } MpegAudioParseContext; |
416 | |
417 #define MPA_HEADER_SIZE 4 | |
418 | |
419 /* header + layer + bitrate + freq + lsf/mpeg25 */ | |
2522
e25782262d7d
kill warnings patch by (M«©ns Rullg«©rd <mru inprovide com>)
michael
parents:
2486
diff
changeset
|
420 #undef SAME_HEADER_MASK /* mpegaudio.h defines different version */ |
1613 | 421 #define SAME_HEADER_MASK \ |
2480 | 422 (0xffe00000 | (3 << 17) | (3 << 10) | (3 << 19)) |
1613 | 423 |
424 static int mpegaudio_parse_init(AVCodecParserContext *s1) | |
425 { | |
426 MpegAudioParseContext *s = s1->priv_data; | |
427 s->inbuf_ptr = s->inbuf; | |
428 return 0; | |
429 } | |
430 | |
431 static int mpegaudio_parse(AVCodecParserContext *s1, | |
432 AVCodecContext *avctx, | |
2967 | 433 uint8_t **poutbuf, int *poutbuf_size, |
1613 | 434 const uint8_t *buf, int buf_size) |
435 { | |
436 MpegAudioParseContext *s = s1->priv_data; | |
2470
06aafb585f69
require a few valid and equal mp3 headers for resync
michael
parents:
2389
diff
changeset
|
437 int len, ret, sr; |
1613 | 438 uint32_t header; |
439 const uint8_t *buf_ptr; | |
440 | |
441 *poutbuf = NULL; | |
442 *poutbuf_size = 0; | |
443 buf_ptr = buf; | |
444 while (buf_size > 0) { | |
2979 | 445 len = s->inbuf_ptr - s->inbuf; |
446 if (s->frame_size == 0) { | |
1613 | 447 /* special case for next header for first frame in free |
448 format case (XXX: find a simpler method) */ | |
449 if (s->free_format_next_header != 0) { | |
450 s->inbuf[0] = s->free_format_next_header >> 24; | |
451 s->inbuf[1] = s->free_format_next_header >> 16; | |
452 s->inbuf[2] = s->free_format_next_header >> 8; | |
453 s->inbuf[3] = s->free_format_next_header; | |
454 s->inbuf_ptr = s->inbuf + 4; | |
455 s->free_format_next_header = 0; | |
456 goto got_header; | |
457 } | |
2979 | 458 /* no header seen : find one. We need at least MPA_HEADER_SIZE |
1613 | 459 bytes to parse it */ |
3639
949bc256f1e3
dont copy frame if the whole mp1/2/3 frame is available in one piece in the input
michael
parents:
3456
diff
changeset
|
460 len = FFMIN(MPA_HEADER_SIZE - len, buf_size); |
2979 | 461 if (len > 0) { |
462 memcpy(s->inbuf_ptr, buf_ptr, len); | |
463 buf_ptr += len; | |
464 buf_size -= len; | |
465 s->inbuf_ptr += len; | |
466 } | |
467 if ((s->inbuf_ptr - s->inbuf) >= MPA_HEADER_SIZE) { | |
1613 | 468 got_header: |
2979 | 469 header = (s->inbuf[0] << 24) | (s->inbuf[1] << 16) | |
470 (s->inbuf[2] << 8) | s->inbuf[3]; | |
1613 | 471 |
4104
04ff8026d9c0
dont set the sampling rate just because 1 mp3 packet header says so (fixes playback speed on some old mencoder generated avis which where then dumped to mp3)
michael
parents:
3989
diff
changeset
|
472 ret = mpa_decode_header(avctx, header, &sr); |
1613 | 473 if (ret < 0) { |
2470
06aafb585f69
require a few valid and equal mp3 headers for resync
michael
parents:
2389
diff
changeset
|
474 s->header_count= -2; |
2979 | 475 /* no sync found : move by one byte (inefficient, but simple!) */ |
476 memmove(s->inbuf, s->inbuf + 1, s->inbuf_ptr - s->inbuf - 1); | |
477 s->inbuf_ptr--; | |
1613 | 478 dprintf("skip %x\n", header); |
479 /* reset free format frame size to give a chance | |
480 to get a new bitrate */ | |
481 s->free_format_frame_size = 0; | |
2979 | 482 } else { |
2470
06aafb585f69
require a few valid and equal mp3 headers for resync
michael
parents:
2389
diff
changeset
|
483 if((header&SAME_HEADER_MASK) != (s->header&SAME_HEADER_MASK) && s->header) |
06aafb585f69
require a few valid and equal mp3 headers for resync
michael
parents:
2389
diff
changeset
|
484 s->header_count= -3; |
06aafb585f69
require a few valid and equal mp3 headers for resync
michael
parents:
2389
diff
changeset
|
485 s->header= header; |
06aafb585f69
require a few valid and equal mp3 headers for resync
michael
parents:
2389
diff
changeset
|
486 s->header_count++; |
1613 | 487 s->frame_size = ret; |
2967 | 488 |
1613 | 489 #if 0 |
490 /* free format: prepare to compute frame size */ | |
2979 | 491 if (decode_header(s, header) == 1) { |
492 s->frame_size = -1; | |
1613 | 493 } |
494 #endif | |
2979 | 495 } |
4104
04ff8026d9c0
dont set the sampling rate just because 1 mp3 packet header says so (fixes playback speed on some old mencoder generated avis which where then dumped to mp3)
michael
parents:
3989
diff
changeset
|
496 if(s->header_count > 1) |
04ff8026d9c0
dont set the sampling rate just because 1 mp3 packet header says so (fixes playback speed on some old mencoder generated avis which where then dumped to mp3)
michael
parents:
3989
diff
changeset
|
497 avctx->sample_rate= sr; |
2979 | 498 } |
2967 | 499 } else |
1613 | 500 #if 0 |
501 if (s->frame_size == -1) { | |
502 /* free format : find next sync to compute frame size */ | |
2979 | 503 len = MPA_MAX_CODED_FRAME_SIZE - len; |
504 if (len > buf_size) | |
505 len = buf_size; | |
1613 | 506 if (len == 0) { |
2979 | 507 /* frame too long: resync */ |
1613 | 508 s->frame_size = 0; |
2979 | 509 memmove(s->inbuf, s->inbuf + 1, s->inbuf_ptr - s->inbuf - 1); |
510 s->inbuf_ptr--; | |
1613 | 511 } else { |
512 uint8_t *p, *pend; | |
513 uint32_t header1; | |
514 int padding; | |
515 | |
516 memcpy(s->inbuf_ptr, buf_ptr, len); | |
517 /* check for header */ | |
518 p = s->inbuf_ptr - 3; | |
519 pend = s->inbuf_ptr + len - 4; | |
520 while (p <= pend) { | |
521 header = (p[0] << 24) | (p[1] << 16) | | |
522 (p[2] << 8) | p[3]; | |
523 header1 = (s->inbuf[0] << 24) | (s->inbuf[1] << 16) | | |
524 (s->inbuf[2] << 8) | s->inbuf[3]; | |
525 /* check with high probability that we have a | |
526 valid header */ | |
527 if ((header & SAME_HEADER_MASK) == | |
528 (header1 & SAME_HEADER_MASK)) { | |
529 /* header found: update pointers */ | |
530 len = (p + 4) - s->inbuf_ptr; | |
531 buf_ptr += len; | |
532 buf_size -= len; | |
533 s->inbuf_ptr = p; | |
534 /* compute frame size */ | |
535 s->free_format_next_header = header; | |
536 s->free_format_frame_size = s->inbuf_ptr - s->inbuf; | |
537 padding = (header1 >> 9) & 1; | |
538 if (s->layer == 1) | |
539 s->free_format_frame_size -= padding * 4; | |
540 else | |
541 s->free_format_frame_size -= padding; | |
2967 | 542 dprintf("free frame size=%d padding=%d\n", |
1613 | 543 s->free_format_frame_size, padding); |
544 decode_header(s, header1); | |
545 goto next_data; | |
546 } | |
547 p++; | |
548 } | |
549 /* not found: simply increase pointers */ | |
550 buf_ptr += len; | |
551 s->inbuf_ptr += len; | |
552 buf_size -= len; | |
553 } | |
2979 | 554 } else |
1613 | 555 #endif |
556 if (len < s->frame_size) { | |
557 if (s->frame_size > MPA_MAX_CODED_FRAME_SIZE) | |
558 s->frame_size = MPA_MAX_CODED_FRAME_SIZE; | |
3639
949bc256f1e3
dont copy frame if the whole mp1/2/3 frame is available in one piece in the input
michael
parents:
3456
diff
changeset
|
559 len = FFMIN(s->frame_size - len, buf_size); |
2979 | 560 memcpy(s->inbuf_ptr, buf_ptr, len); |
561 buf_ptr += len; | |
562 s->inbuf_ptr += len; | |
563 buf_size -= len; | |
564 } | |
3639
949bc256f1e3
dont copy frame if the whole mp1/2/3 frame is available in one piece in the input
michael
parents:
3456
diff
changeset
|
565 |
949bc256f1e3
dont copy frame if the whole mp1/2/3 frame is available in one piece in the input
michael
parents:
3456
diff
changeset
|
566 if(s->frame_size > 0 && buf_ptr - buf == s->inbuf_ptr - s->inbuf |
949bc256f1e3
dont copy frame if the whole mp1/2/3 frame is available in one piece in the input
michael
parents:
3456
diff
changeset
|
567 && buf_size + buf_ptr - buf >= s->frame_size){ |
949bc256f1e3
dont copy frame if the whole mp1/2/3 frame is available in one piece in the input
michael
parents:
3456
diff
changeset
|
568 if(s->header_count > 0){ |
949bc256f1e3
dont copy frame if the whole mp1/2/3 frame is available in one piece in the input
michael
parents:
3456
diff
changeset
|
569 *poutbuf = buf; |
949bc256f1e3
dont copy frame if the whole mp1/2/3 frame is available in one piece in the input
michael
parents:
3456
diff
changeset
|
570 *poutbuf_size = s->frame_size; |
949bc256f1e3
dont copy frame if the whole mp1/2/3 frame is available in one piece in the input
michael
parents:
3456
diff
changeset
|
571 } |
949bc256f1e3
dont copy frame if the whole mp1/2/3 frame is available in one piece in the input
michael
parents:
3456
diff
changeset
|
572 buf_ptr = buf + s->frame_size; |
949bc256f1e3
dont copy frame if the whole mp1/2/3 frame is available in one piece in the input
michael
parents:
3456
diff
changeset
|
573 s->inbuf_ptr = s->inbuf; |
949bc256f1e3
dont copy frame if the whole mp1/2/3 frame is available in one piece in the input
michael
parents:
3456
diff
changeset
|
574 s->frame_size = 0; |
949bc256f1e3
dont copy frame if the whole mp1/2/3 frame is available in one piece in the input
michael
parents:
3456
diff
changeset
|
575 break; |
949bc256f1e3
dont copy frame if the whole mp1/2/3 frame is available in one piece in the input
michael
parents:
3456
diff
changeset
|
576 } |
949bc256f1e3
dont copy frame if the whole mp1/2/3 frame is available in one piece in the input
michael
parents:
3456
diff
changeset
|
577 |
1613 | 578 // next_data: |
2967 | 579 if (s->frame_size > 0 && |
1613 | 580 (s->inbuf_ptr - s->inbuf) >= s->frame_size) { |
2470
06aafb585f69
require a few valid and equal mp3 headers for resync
michael
parents:
2389
diff
changeset
|
581 if(s->header_count > 0){ |
06aafb585f69
require a few valid and equal mp3 headers for resync
michael
parents:
2389
diff
changeset
|
582 *poutbuf = s->inbuf; |
06aafb585f69
require a few valid and equal mp3 headers for resync
michael
parents:
2389
diff
changeset
|
583 *poutbuf_size = s->inbuf_ptr - s->inbuf; |
06aafb585f69
require a few valid and equal mp3 headers for resync
michael
parents:
2389
diff
changeset
|
584 } |
2979 | 585 s->inbuf_ptr = s->inbuf; |
586 s->frame_size = 0; | |
587 break; | |
588 } | |
1613 | 589 } |
590 return buf_ptr - buf; | |
591 } | |
3455
cc4b4ea83e29
--enable/disable parsers. Warning: some combinations are broken.
mru
parents:
3432
diff
changeset
|
592 #endif /* CONFIG_MPEGAUDIO_PARSER */ |
1613 | 593 |
3455
cc4b4ea83e29
--enable/disable parsers. Warning: some combinations are broken.
mru
parents:
3432
diff
changeset
|
594 #if defined(CONFIG_AC3_PARSER) || defined(CONFIG_AAC_PARSER) |
3098 | 595 /* also used for ADTS AAC */ |
1613 | 596 typedef struct AC3ParseContext { |
597 uint8_t *inbuf_ptr; | |
598 int frame_size; | |
3098 | 599 int header_size; |
600 int (*sync)(const uint8_t *buf, int *channels, int *sample_rate, | |
601 int *bit_rate, int *samples); | |
3344
f9d739057d6c
The AAC frame header uses 13 bits for the frame size, so the buffer should
mru
parents:
3104
diff
changeset
|
602 uint8_t inbuf[8192]; /* input buffer */ |
1613 | 603 } AC3ParseContext; |
604 | |
605 #define AC3_HEADER_SIZE 7 | |
3104 | 606 #define AAC_HEADER_SIZE 7 |
3059 | 607 |
3455
cc4b4ea83e29
--enable/disable parsers. Warning: some combinations are broken.
mru
parents:
3432
diff
changeset
|
608 #ifdef CONFIG_AC3_PARSER |
3059 | 609 static const int ac3_sample_rates[4] = { |
610 48000, 44100, 32000, 0 | |
611 }; | |
612 | |
613 static const int ac3_frame_sizes[64][3] = { | |
3063
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
614 { 64, 69, 96 }, |
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
615 { 64, 70, 96 }, |
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
616 { 80, 87, 120 }, |
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
617 { 80, 88, 120 }, |
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
618 { 96, 104, 144 }, |
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
619 { 96, 105, 144 }, |
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
620 { 112, 121, 168 }, |
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
621 { 112, 122, 168 }, |
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
622 { 128, 139, 192 }, |
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
623 { 128, 140, 192 }, |
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
624 { 160, 174, 240 }, |
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
625 { 160, 175, 240 }, |
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
626 { 192, 208, 288 }, |
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
627 { 192, 209, 288 }, |
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
628 { 224, 243, 336 }, |
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
629 { 224, 244, 336 }, |
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
630 { 256, 278, 384 }, |
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
631 { 256, 279, 384 }, |
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
632 { 320, 348, 480 }, |
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
633 { 320, 349, 480 }, |
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
634 { 384, 417, 576 }, |
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
635 { 384, 418, 576 }, |
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
636 { 448, 487, 672 }, |
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
637 { 448, 488, 672 }, |
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
638 { 512, 557, 768 }, |
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
639 { 512, 558, 768 }, |
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
640 { 640, 696, 960 }, |
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
641 { 640, 697, 960 }, |
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
642 { 768, 835, 1152 }, |
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
643 { 768, 836, 1152 }, |
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
644 { 896, 975, 1344 }, |
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
645 { 896, 976, 1344 }, |
3059 | 646 { 1024, 1114, 1536 }, |
647 { 1024, 1115, 1536 }, | |
648 { 1152, 1253, 1728 }, | |
649 { 1152, 1254, 1728 }, | |
650 { 1280, 1393, 1920 }, | |
651 { 1280, 1394, 1920 }, | |
652 }; | |
653 | |
654 static const int ac3_bitrates[64] = { | |
655 32, 32, 40, 40, 48, 48, 56, 56, 64, 64, 80, 80, 96, 96, 112, 112, | |
656 128, 128, 160, 160, 192, 192, 224, 224, 256, 256, 320, 320, 384, | |
657 384, 448, 448, 512, 512, 576, 576, 640, 640, | |
658 }; | |
659 | |
660 static const int ac3_channels[8] = { | |
661 2, 1, 2, 3, 3, 4, 4, 5 | |
662 }; | |
3455
cc4b4ea83e29
--enable/disable parsers. Warning: some combinations are broken.
mru
parents:
3432
diff
changeset
|
663 #endif /* CONFIG_AC3_PARSER */ |
3059 | 664 |
3455
cc4b4ea83e29
--enable/disable parsers. Warning: some combinations are broken.
mru
parents:
3432
diff
changeset
|
665 #ifdef CONFIG_AAC_PARSER |
3456 | 666 static const int aac_sample_rates[16] = { |
3098 | 667 96000, 88200, 64000, 48000, 44100, 32000, |
668 24000, 22050, 16000, 12000, 11025, 8000, 7350 | |
669 }; | |
670 | |
3456 | 671 static const int aac_channels[8] = { |
3098 | 672 0, 1, 2, 3, 4, 5, 6, 8 |
673 }; | |
3455
cc4b4ea83e29
--enable/disable parsers. Warning: some combinations are broken.
mru
parents:
3432
diff
changeset
|
674 #endif |
3098 | 675 |
3455
cc4b4ea83e29
--enable/disable parsers. Warning: some combinations are broken.
mru
parents:
3432
diff
changeset
|
676 #ifdef CONFIG_AC3_PARSER |
3059 | 677 static int ac3_sync(const uint8_t *buf, int *channels, int *sample_rate, |
3098 | 678 int *bit_rate, int *samples) |
3059 | 679 { |
680 unsigned int fscod, frmsizecod, acmod, bsid, lfeon; | |
681 GetBitContext bits; | |
682 | |
683 init_get_bits(&bits, buf, AC3_HEADER_SIZE * 8); | |
684 | |
685 if(get_bits(&bits, 16) != 0x0b77) | |
3063
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
686 return 0; |
3059 | 687 |
3104 | 688 skip_bits(&bits, 16); /* crc */ |
3059 | 689 fscod = get_bits(&bits, 2); |
690 frmsizecod = get_bits(&bits, 6); | |
691 | |
692 if(!ac3_sample_rates[fscod]) | |
3063
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
693 return 0; |
3059 | 694 |
695 bsid = get_bits(&bits, 5); | |
696 if(bsid > 8) | |
3063
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
697 return 0; |
3104 | 698 skip_bits(&bits, 3); /* bsmod */ |
3059 | 699 acmod = get_bits(&bits, 3); |
700 if(acmod & 1 && acmod != 1) | |
3104 | 701 skip_bits(&bits, 2); /* cmixlev */ |
3059 | 702 if(acmod & 4) |
3104 | 703 skip_bits(&bits, 2); /* surmixlev */ |
3059 | 704 if(acmod & 2) |
3104 | 705 skip_bits(&bits, 2); /* dsurmod */ |
706 lfeon = get_bits1(&bits); | |
3059 | 707 |
708 *sample_rate = ac3_sample_rates[fscod]; | |
709 *bit_rate = ac3_bitrates[frmsizecod] * 1000; | |
710 *channels = ac3_channels[acmod] + lfeon; | |
3098 | 711 *samples = 6 * 256; |
3059 | 712 |
713 return ac3_frame_sizes[frmsizecod][fscod] * 2; | |
714 } | |
3455
cc4b4ea83e29
--enable/disable parsers. Warning: some combinations are broken.
mru
parents:
3432
diff
changeset
|
715 #endif /* CONFIG_AC3_PARSER */ |
1613 | 716 |
3455
cc4b4ea83e29
--enable/disable parsers. Warning: some combinations are broken.
mru
parents:
3432
diff
changeset
|
717 #ifdef CONFIG_AAC_PARSER |
3098 | 718 static int aac_sync(const uint8_t *buf, int *channels, int *sample_rate, |
719 int *bit_rate, int *samples) | |
720 { | |
721 GetBitContext bits; | |
722 int size, rdb, ch, sr; | |
723 | |
724 init_get_bits(&bits, buf, AAC_HEADER_SIZE * 8); | |
725 | |
726 if(get_bits(&bits, 12) != 0xfff) | |
727 return 0; | |
728 | |
3104 | 729 skip_bits1(&bits); /* id */ |
730 skip_bits(&bits, 2); /* layer */ | |
731 skip_bits1(&bits); /* protection_absent */ | |
732 skip_bits(&bits, 2); /* profile_objecttype */ | |
733 sr = get_bits(&bits, 4); /* sample_frequency_index */ | |
3098 | 734 if(!aac_sample_rates[sr]) |
735 return 0; | |
3104 | 736 skip_bits1(&bits); /* private_bit */ |
737 ch = get_bits(&bits, 3); /* channel_configuration */ | |
3098 | 738 if(!aac_channels[ch]) |
739 return 0; | |
3104 | 740 skip_bits1(&bits); /* original/copy */ |
741 skip_bits1(&bits); /* home */ | |
3098 | 742 |
743 /* adts_variable_header */ | |
3104 | 744 skip_bits1(&bits); /* copyright_identification_bit */ |
745 skip_bits1(&bits); /* copyright_identification_start */ | |
746 size = get_bits(&bits, 13); /* aac_frame_length */ | |
747 skip_bits(&bits, 11); /* adts_buffer_fullness */ | |
748 rdb = get_bits(&bits, 2); /* number_of_raw_data_blocks_in_frame */ | |
3098 | 749 |
750 *channels = aac_channels[ch]; | |
751 *sample_rate = aac_sample_rates[sr]; | |
752 *samples = (rdb + 1) * 1024; | |
753 *bit_rate = size * 8 * *sample_rate / *samples; | |
754 | |
755 return size; | |
756 } | |
3455
cc4b4ea83e29
--enable/disable parsers. Warning: some combinations are broken.
mru
parents:
3432
diff
changeset
|
757 #endif /* CONFIG_AAC_PARSER */ |
3098 | 758 |
3455
cc4b4ea83e29
--enable/disable parsers. Warning: some combinations are broken.
mru
parents:
3432
diff
changeset
|
759 #ifdef CONFIG_AC3_PARSER |
1613 | 760 static int ac3_parse_init(AVCodecParserContext *s1) |
761 { | |
762 AC3ParseContext *s = s1->priv_data; | |
763 s->inbuf_ptr = s->inbuf; | |
3098 | 764 s->header_size = AC3_HEADER_SIZE; |
765 s->sync = ac3_sync; | |
1613 | 766 return 0; |
767 } | |
3455
cc4b4ea83e29
--enable/disable parsers. Warning: some combinations are broken.
mru
parents:
3432
diff
changeset
|
768 #endif |
1613 | 769 |
3455
cc4b4ea83e29
--enable/disable parsers. Warning: some combinations are broken.
mru
parents:
3432
diff
changeset
|
770 #ifdef CONFIG_AAC_PARSER |
3098 | 771 static int aac_parse_init(AVCodecParserContext *s1) |
772 { | |
773 AC3ParseContext *s = s1->priv_data; | |
774 s->inbuf_ptr = s->inbuf; | |
775 s->header_size = AAC_HEADER_SIZE; | |
776 s->sync = aac_sync; | |
777 return 0; | |
778 } | |
3455
cc4b4ea83e29
--enable/disable parsers. Warning: some combinations are broken.
mru
parents:
3432
diff
changeset
|
779 #endif |
3098 | 780 |
781 /* also used for ADTS AAC */ | |
1613 | 782 static int ac3_parse(AVCodecParserContext *s1, |
783 AVCodecContext *avctx, | |
2967 | 784 uint8_t **poutbuf, int *poutbuf_size, |
1613 | 785 const uint8_t *buf, int buf_size) |
786 { | |
787 AC3ParseContext *s = s1->priv_data; | |
788 const uint8_t *buf_ptr; | |
3098 | 789 int len, sample_rate, bit_rate, channels, samples; |
1613 | 790 |
791 *poutbuf = NULL; | |
792 *poutbuf_size = 0; | |
793 | |
794 buf_ptr = buf; | |
795 while (buf_size > 0) { | |
796 len = s->inbuf_ptr - s->inbuf; | |
797 if (s->frame_size == 0) { | |
3098 | 798 /* no header seen : find one. We need at least s->header_size |
799 bytes to parse it */ | |
800 len = FFMIN(s->header_size - len, buf_size); | |
3082 | 801 |
1613 | 802 memcpy(s->inbuf_ptr, buf_ptr, len); |
803 buf_ptr += len; | |
804 s->inbuf_ptr += len; | |
805 buf_size -= len; | |
3098 | 806 if ((s->inbuf_ptr - s->inbuf) == s->header_size) { |
807 len = s->sync(s->inbuf, &channels, &sample_rate, &bit_rate, | |
808 &samples); | |
1613 | 809 if (len == 0) { |
810 /* no sync found : move by one byte (inefficient, but simple!) */ | |
3098 | 811 memmove(s->inbuf, s->inbuf + 1, s->header_size - 1); |
1613 | 812 s->inbuf_ptr--; |
813 } else { | |
2979 | 814 s->frame_size = len; |
1613 | 815 /* update codec info */ |
816 avctx->sample_rate = sample_rate; | |
1987 | 817 /* set channels,except if the user explicitly requests 1 or 2 channels, XXX/FIXME this is a bit ugly */ |
3098 | 818 if(avctx->codec_id == CODEC_ID_AC3){ |
819 if(avctx->channels!=1 && avctx->channels!=2){ | |
820 avctx->channels = channels; | |
821 } | |
822 } else { | |
3063
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
823 avctx->channels = channels; |
1987 | 824 } |
2979 | 825 avctx->bit_rate = bit_rate; |
3098 | 826 avctx->frame_size = samples; |
1613 | 827 } |
828 } | |
3082 | 829 } else { |
830 len = FFMIN(s->frame_size - len, buf_size); | |
1613 | 831 |
832 memcpy(s->inbuf_ptr, buf_ptr, len); | |
833 buf_ptr += len; | |
834 s->inbuf_ptr += len; | |
835 buf_size -= len; | |
3082 | 836 |
837 if(s->inbuf_ptr - s->inbuf == s->frame_size){ | |
838 *poutbuf = s->inbuf; | |
839 *poutbuf_size = s->frame_size; | |
840 s->inbuf_ptr = s->inbuf; | |
841 s->frame_size = 0; | |
842 break; | |
843 } | |
1613 | 844 } |
845 } | |
846 return buf_ptr - buf; | |
847 } | |
3455
cc4b4ea83e29
--enable/disable parsers. Warning: some combinations are broken.
mru
parents:
3432
diff
changeset
|
848 #endif /* CONFIG_AC3_PARSER || CONFIG_AAC_PARSER */ |
1613 | 849 |
3455
cc4b4ea83e29
--enable/disable parsers. Warning: some combinations are broken.
mru
parents:
3432
diff
changeset
|
850 #ifdef CONFIG_MPEG4VIDEO_PARSER |
1613 | 851 AVCodecParser mpeg4video_parser = { |
852 { CODEC_ID_MPEG4 }, | |
853 sizeof(ParseContext1), | |
854 mpeg4video_parse_init, | |
855 mpeg4video_parse, | |
4150
2205aefb22b7
move AVCodecParser prototypes and definitions to parser.h, and move mpegvideo parser to mpeg12.c
bcoudurier
parents:
4146
diff
changeset
|
856 ff_parse1_close, |
2769
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
857 mpeg4video_split, |
1613 | 858 }; |
3455
cc4b4ea83e29
--enable/disable parsers. Warning: some combinations are broken.
mru
parents:
3432
diff
changeset
|
859 #endif |
cc4b4ea83e29
--enable/disable parsers. Warning: some combinations are broken.
mru
parents:
3432
diff
changeset
|
860 #ifdef CONFIG_CAVSVIDEO_PARSER |
3395
adccbf4a1040
CAVS decoder by (Stefan Gehrer stefan.gehrer gmx.de)
michael
parents:
3344
diff
changeset
|
861 AVCodecParser cavsvideo_parser = { |
adccbf4a1040
CAVS decoder by (Stefan Gehrer stefan.gehrer gmx.de)
michael
parents:
3344
diff
changeset
|
862 { CODEC_ID_CAVS }, |
adccbf4a1040
CAVS decoder by (Stefan Gehrer stefan.gehrer gmx.de)
michael
parents:
3344
diff
changeset
|
863 sizeof(ParseContext1), |
adccbf4a1040
CAVS decoder by (Stefan Gehrer stefan.gehrer gmx.de)
michael
parents:
3344
diff
changeset
|
864 NULL, |
adccbf4a1040
CAVS decoder by (Stefan Gehrer stefan.gehrer gmx.de)
michael
parents:
3344
diff
changeset
|
865 cavsvideo_parse, |
4150
2205aefb22b7
move AVCodecParser prototypes and definitions to parser.h, and move mpegvideo parser to mpeg12.c
bcoudurier
parents:
4146
diff
changeset
|
866 ff_parse1_close, |
3395
adccbf4a1040
CAVS decoder by (Stefan Gehrer stefan.gehrer gmx.de)
michael
parents:
3344
diff
changeset
|
867 mpeg4video_split, |
adccbf4a1040
CAVS decoder by (Stefan Gehrer stefan.gehrer gmx.de)
michael
parents:
3344
diff
changeset
|
868 }; |
3432 | 869 #endif |
3455
cc4b4ea83e29
--enable/disable parsers. Warning: some combinations are broken.
mru
parents:
3432
diff
changeset
|
870 #ifdef CONFIG_MPEGAUDIO_PARSER |
1613 | 871 AVCodecParser mpegaudio_parser = { |
872 { CODEC_ID_MP2, CODEC_ID_MP3 }, | |
873 sizeof(MpegAudioParseContext), | |
874 mpegaudio_parse_init, | |
875 mpegaudio_parse, | |
876 NULL, | |
877 }; | |
3455
cc4b4ea83e29
--enable/disable parsers. Warning: some combinations are broken.
mru
parents:
3432
diff
changeset
|
878 #endif |
cc4b4ea83e29
--enable/disable parsers. Warning: some combinations are broken.
mru
parents:
3432
diff
changeset
|
879 #ifdef CONFIG_AC3_PARSER |
1613 | 880 AVCodecParser ac3_parser = { |
881 { CODEC_ID_AC3 }, | |
882 sizeof(AC3ParseContext), | |
883 ac3_parse_init, | |
884 ac3_parse, | |
885 NULL, | |
886 }; | |
3455
cc4b4ea83e29
--enable/disable parsers. Warning: some combinations are broken.
mru
parents:
3432
diff
changeset
|
887 #endif |
cc4b4ea83e29
--enable/disable parsers. Warning: some combinations are broken.
mru
parents:
3432
diff
changeset
|
888 #ifdef CONFIG_AAC_PARSER |
3098 | 889 AVCodecParser aac_parser = { |
890 { CODEC_ID_AAC }, | |
891 sizeof(AC3ParseContext), | |
892 aac_parse_init, | |
893 ac3_parse, | |
894 NULL, | |
895 }; | |
3455
cc4b4ea83e29
--enable/disable parsers. Warning: some combinations are broken.
mru
parents:
3432
diff
changeset
|
896 #endif |