Mercurial > libavcodec.hg
annotate parser.c @ 3198:6b9f0c4fbdbe libavcodec
First part of a series of speed-enchancing patches.
This one sets up a snow.h and makes snow use the dsputil function pointer
framework to access the three functions that will be implemented in asm
in the other parts of the patchset.
Patch by Robert Edele < yartrebo AH earthlink POIS net>
Original thread:
Subject: [Ffmpeg-devel] [PATCH] Snow mmx+sse2 asm optimizations
Date: Sun, 05 Feb 2006 12:47:14 -0500
author | gpoirier |
---|---|
date | Thu, 16 Mar 2006 19:18:18 +0000 |
parents | 78d6bfc238f3 |
children | f9d739057d6c |
rev | line source |
---|---|
1613 | 1 /* |
2 * Audio and Video frame extraction | |
3 * Copyright (c) 2003 Fabrice Bellard. | |
4 * Copyright (c) 2003 Michael Niedermayer. | |
5 * | |
6 * This library is free software; you can redistribute it and/or | |
7 * modify it under the terms of the GNU Lesser General Public | |
8 * License as published by the Free Software Foundation; either | |
9 * version 2 of the License, or (at your option) any later version. | |
10 * | |
11 * This library is distributed in the hope that it will be useful, | |
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 * Lesser General Public License for more details. | |
15 * | |
16 * You should have received a copy of the GNU Lesser General Public | |
17 * License along with this library; if not, write to the Free Software | |
3036
0b546eab515d
Update licensing information: The FSF changed postal address.
diego
parents:
2979
diff
changeset
|
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
1613 | 19 */ |
20 #include "avcodec.h" | |
21 #include "mpegvideo.h" | |
22 #include "mpegaudio.h" | |
23 | |
24 AVCodecParser *av_first_parser = NULL; | |
25 | |
26 void av_register_codec_parser(AVCodecParser *parser) | |
27 { | |
28 parser->next = av_first_parser; | |
29 av_first_parser = parser; | |
30 } | |
31 | |
32 AVCodecParserContext *av_parser_init(int codec_id) | |
33 { | |
34 AVCodecParserContext *s; | |
35 AVCodecParser *parser; | |
36 int ret; | |
2967 | 37 |
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
|
38 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
|
39 return NULL; |
1613 | 40 |
41 for(parser = av_first_parser; parser != NULL; parser = parser->next) { | |
42 if (parser->codec_ids[0] == codec_id || | |
43 parser->codec_ids[1] == codec_id || | |
2348 | 44 parser->codec_ids[2] == codec_id || |
45 parser->codec_ids[3] == codec_id || | |
46 parser->codec_ids[4] == codec_id) | |
1613 | 47 goto found; |
48 } | |
49 return NULL; | |
50 found: | |
51 s = av_mallocz(sizeof(AVCodecParserContext)); | |
52 if (!s) | |
53 return NULL; | |
54 s->parser = parser; | |
55 s->priv_data = av_mallocz(parser->priv_data_size); | |
56 if (!s->priv_data) { | |
57 av_free(s); | |
58 return NULL; | |
59 } | |
60 if (parser->parser_init) { | |
61 ret = parser->parser_init(s); | |
62 if (ret != 0) { | |
63 av_free(s->priv_data); | |
64 av_free(s); | |
65 return NULL; | |
66 } | |
67 } | |
2030 | 68 s->fetch_timestamp=1; |
1613 | 69 return s; |
70 } | |
71 | |
1694
13169235c306
added End Of File handling to return last picture for MPEG1/2/4
bellard
parents:
1681
diff
changeset
|
72 /* NOTE: buf_size == 0 is used to signal EOF so that the last frame |
13169235c306
added End Of File handling to return last picture for MPEG1/2/4
bellard
parents:
1681
diff
changeset
|
73 can be returned if necessary */ |
2967 | 74 int av_parser_parse(AVCodecParserContext *s, |
1613 | 75 AVCodecContext *avctx, |
2967 | 76 uint8_t **poutbuf, int *poutbuf_size, |
1696 | 77 const uint8_t *buf, int buf_size, |
78 int64_t pts, int64_t dts) | |
1613 | 79 { |
1696 | 80 int index, i, k; |
1694
13169235c306
added End Of File handling to return last picture for MPEG1/2/4
bellard
parents:
1681
diff
changeset
|
81 uint8_t dummy_buf[FF_INPUT_BUFFER_PADDING_SIZE]; |
2967 | 82 |
1694
13169235c306
added End Of File handling to return last picture for MPEG1/2/4
bellard
parents:
1681
diff
changeset
|
83 if (buf_size == 0) { |
13169235c306
added End Of File handling to return last picture for MPEG1/2/4
bellard
parents:
1681
diff
changeset
|
84 /* 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
|
85 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
|
86 buf = dummy_buf; |
1696 | 87 } else { |
88 /* add a new packet descriptor */ | |
89 k = (s->cur_frame_start_index + 1) & (AV_PARSER_PTS_NB - 1); | |
90 s->cur_frame_start_index = k; | |
91 s->cur_frame_offset[k] = s->cur_offset; | |
92 s->cur_frame_pts[k] = pts; | |
93 s->cur_frame_dts[k] = dts; | |
94 | |
95 /* fill first PTS/DTS */ | |
2030 | 96 if (s->fetch_timestamp){ |
97 s->fetch_timestamp=0; | |
1696 | 98 s->last_pts = pts; |
99 s->last_dts = dts; | |
2107 | 100 s->cur_frame_pts[k] = |
101 s->cur_frame_dts[k] = AV_NOPTS_VALUE; | |
1696 | 102 } |
1694
13169235c306
added End Of File handling to return last picture for MPEG1/2/4
bellard
parents:
1681
diff
changeset
|
103 } |
13169235c306
added End Of File handling to return last picture for MPEG1/2/4
bellard
parents:
1681
diff
changeset
|
104 |
1613 | 105 /* WARNING: the returned index can be negative */ |
106 index = s->parser->parser_parse(s, avctx, poutbuf, poutbuf_size, buf, buf_size); | |
2107 | 107 //av_log(NULL, AV_LOG_DEBUG, "parser: in:%lld, %lld, out:%lld, %lld, in:%d out:%d id:%d\n", pts, dts, s->last_pts, s->last_dts, buf_size, *poutbuf_size, avctx->codec_id); |
1613 | 108 /* update the file pointer */ |
109 if (*poutbuf_size) { | |
1696 | 110 /* fill the data for the current frame */ |
1613 | 111 s->frame_offset = s->last_frame_offset; |
1696 | 112 s->pts = s->last_pts; |
113 s->dts = s->last_dts; | |
2967 | 114 |
1696 | 115 /* offset of the next frame */ |
1613 | 116 s->last_frame_offset = s->cur_offset + index; |
1696 | 117 /* find the packet in which the new frame starts. It |
118 is tricky because of MPEG video start codes | |
119 which can begin in one packet and finish in | |
120 another packet. In the worst case, an MPEG | |
121 video start code could be in 4 different | |
122 packets. */ | |
123 k = s->cur_frame_start_index; | |
124 for(i = 0; i < AV_PARSER_PTS_NB; i++) { | |
125 if (s->last_frame_offset >= s->cur_frame_offset[k]) | |
126 break; | |
127 k = (k - 1) & (AV_PARSER_PTS_NB - 1); | |
128 } | |
2030 | 129 |
1696 | 130 s->last_pts = s->cur_frame_pts[k]; |
131 s->last_dts = s->cur_frame_dts[k]; | |
2967 | 132 |
2030 | 133 /* some parsers tell us the packet size even before seeing the first byte of the next packet, |
134 so the next pts/dts is in the next chunk */ | |
135 if(index == buf_size){ | |
136 s->fetch_timestamp=1; | |
137 } | |
1613 | 138 } |
139 if (index < 0) | |
140 index = 0; | |
141 s->cur_offset += index; | |
142 return index; | |
143 } | |
144 | |
2777 | 145 /** |
146 * | |
147 * @return 0 if the output buffer is a subset of the input, 1 if it is allocated and must be freed | |
148 */ | |
2769
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
149 int av_parser_change(AVCodecParserContext *s, |
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
150 AVCodecContext *avctx, |
2967 | 151 uint8_t **poutbuf, int *poutbuf_size, |
2769
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
152 const uint8_t *buf, int buf_size, int keyframe){ |
2967 | 153 |
2769
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
154 if(s && s->parser->split){ |
2777 | 155 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
|
156 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
|
157 buf += i; |
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
158 buf_size -= i; |
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
159 } |
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
160 } |
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
161 |
2864
95bac7109ff0
Kill some compiler warnings. Compiled code verified identical after changes.
mru
parents:
2846
diff
changeset
|
162 /* cast to avoid warning about discarding qualifiers */ |
95bac7109ff0
Kill some compiler warnings. Compiled code verified identical after changes.
mru
parents:
2846
diff
changeset
|
163 *poutbuf= (uint8_t *) buf; |
2769
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
164 *poutbuf_size= buf_size; |
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
165 if(avctx->extradata){ |
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
166 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
|
167 /*||(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
|
168 /*||(? && (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
|
169 int size= buf_size + avctx->extradata_size; |
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
170 *poutbuf_size= size; |
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
171 *poutbuf= av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE); |
2967 | 172 |
2769
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
173 memcpy(*poutbuf, avctx->extradata, avctx->extradata_size); |
2777 | 174 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
|
175 return 1; |
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
176 } |
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
177 } |
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
178 |
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
179 return 0; |
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
180 } |
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
181 |
1613 | 182 void av_parser_close(AVCodecParserContext *s) |
183 { | |
184 if (s->parser->parser_close) | |
185 s->parser->parser_close(s); | |
186 av_free(s->priv_data); | |
187 av_free(s); | |
188 } | |
189 | |
190 /*****************************************************/ | |
191 | |
192 //#define END_NOT_FOUND (-100) | |
193 | |
2979 | 194 #define PICTURE_START_CODE 0x00000100 |
195 #define SEQ_START_CODE 0x000001b3 | |
196 #define EXT_START_CODE 0x000001b5 | |
197 #define SLICE_MIN_START_CODE 0x00000101 | |
198 #define SLICE_MAX_START_CODE 0x000001af | |
1613 | 199 |
200 typedef struct ParseContext1{ | |
1988 | 201 ParseContext pc; |
202 /* XXX/FIXME PC1 vs. PC */ | |
1613 | 203 /* MPEG2 specific */ |
204 int frame_rate; | |
205 int progressive_sequence; | |
206 int width, height; | |
1614 | 207 |
1613 | 208 /* XXX: suppress that, needed by MPEG4 */ |
209 MpegEncContext *enc; | |
1614 | 210 int first_picture; |
1613 | 211 } ParseContext1; |
212 | |
213 /** | |
214 * combines the (truncated) bitstream to a complete frame | |
215 * @returns -1 if no complete frame could be created | |
216 */ | |
1988 | 217 int ff_combine_frame(ParseContext *pc, int next, uint8_t **buf, int *buf_size) |
1613 | 218 { |
219 #if 0 | |
220 if(pc->overread){ | |
221 printf("overread %d, state:%X next:%d index:%d o_index:%d\n", pc->overread, pc->state, next, pc->index, pc->overread_index); | |
222 printf("%X %X %X %X\n", (*buf)[0], (*buf)[1],(*buf)[2],(*buf)[3]); | |
223 } | |
224 #endif | |
225 | |
226 /* copy overreaded bytes from last frame into buffer */ | |
227 for(; pc->overread>0; pc->overread--){ | |
228 pc->buffer[pc->index++]= pc->buffer[pc->overread_index++]; | |
229 } | |
2386 | 230 |
231 /* flush remaining if EOF */ | |
232 if(!*buf_size && next == END_NOT_FOUND){ | |
233 next= 0; | |
234 } | |
235 | |
1613 | 236 pc->last_index= pc->index; |
237 | |
238 /* copy into buffer end return */ | |
239 if(next == END_NOT_FOUND){ | |
240 pc->buffer= av_fast_realloc(pc->buffer, &pc->buffer_size, (*buf_size) + pc->index + FF_INPUT_BUFFER_PADDING_SIZE); | |
241 | |
242 memcpy(&pc->buffer[pc->index], *buf, *buf_size); | |
243 pc->index += *buf_size; | |
244 return -1; | |
245 } | |
246 | |
247 *buf_size= | |
248 pc->overread_index= pc->index + next; | |
2967 | 249 |
1613 | 250 /* append to buffer */ |
251 if(pc->index){ | |
252 pc->buffer= av_fast_realloc(pc->buffer, &pc->buffer_size, next + pc->index + FF_INPUT_BUFFER_PADDING_SIZE); | |
253 | |
254 memcpy(&pc->buffer[pc->index], *buf, next + FF_INPUT_BUFFER_PADDING_SIZE ); | |
255 pc->index = 0; | |
256 *buf= pc->buffer; | |
257 } | |
258 | |
259 /* store overread bytes */ | |
260 for(;next < 0; next++){ | |
261 pc->state = (pc->state<<8) | pc->buffer[pc->last_index + next]; | |
262 pc->overread++; | |
263 } | |
264 | |
265 #if 0 | |
266 if(pc->overread){ | |
267 printf("overread %d, state:%X next:%d index:%d o_index:%d\n", pc->overread, pc->state, next, pc->index, pc->overread_index); | |
268 printf("%X %X %X %X\n", (*buf)[0], (*buf)[1],(*buf)[2],(*buf)[3]); | |
269 } | |
270 #endif | |
271 | |
272 return 0; | |
273 } | |
274 | |
275 /* XXX: merge with libavcodec ? */ | |
276 #define MPEG1_FRAME_RATE_BASE 1001 | |
277 | |
278 static const int frame_rate_tab[16] = { | |
2967 | 279 0, |
1613 | 280 24000, |
281 24024, | |
282 25025, | |
283 30000, | |
284 30030, | |
285 50050, | |
286 60000, | |
287 60060, | |
288 // Xing's 15fps: (9) | |
289 15015, | |
290 // libmpeg3's "Unofficial economy rates": (10-13) | |
291 5005, | |
292 10010, | |
293 12012, | |
294 15015, | |
295 // random, just to avoid segfault !never encode these | |
296 25025, | |
297 25025, | |
298 }; | |
299 | |
2637 | 300 //FIXME move into mpeg12.c |
2967 | 301 static void mpegvideo_extract_headers(AVCodecParserContext *s, |
1613 | 302 AVCodecContext *avctx, |
303 const uint8_t *buf, int buf_size) | |
304 { | |
305 ParseContext1 *pc = s->priv_data; | |
306 const uint8_t *buf_end; | |
307 int32_t start_code; | |
308 int frame_rate_index, ext_type, bytes_left; | |
309 int frame_rate_ext_n, frame_rate_ext_d; | |
2119 | 310 int picture_structure, top_field_first, repeat_first_field, progressive_frame; |
2539 | 311 int horiz_size_ext, vert_size_ext, bit_rate_ext; |
2769
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
312 //FIXME replace the crap with get_bits() |
1613 | 313 s->repeat_pict = 0; |
314 buf_end = buf + buf_size; | |
315 while (buf < buf_end) { | |
3086 | 316 start_code= -1; |
317 buf= ff_find_start_code(buf, buf_end, &start_code); | |
1613 | 318 bytes_left = buf_end - buf; |
319 switch(start_code) { | |
320 case PICTURE_START_CODE: | |
321 if (bytes_left >= 2) { | |
322 s->pict_type = (buf[1] >> 3) & 7; | |
323 } | |
324 break; | |
325 case SEQ_START_CODE: | |
2539 | 326 if (bytes_left >= 7) { |
2269 | 327 pc->width = (buf[0] << 4) | (buf[1] >> 4); |
328 pc->height = ((buf[1] & 0x0f) << 8) | buf[2]; | |
2270 | 329 avcodec_set_dimensions(avctx, pc->width, pc->height); |
1613 | 330 frame_rate_index = buf[3] & 0xf; |
2637 | 331 pc->frame_rate = avctx->time_base.den = frame_rate_tab[frame_rate_index]; |
332 avctx->time_base.num = MPEG1_FRAME_RATE_BASE; | |
2539 | 333 avctx->bit_rate = ((buf[4]<<10) | (buf[5]<<2) | (buf[6]>>6))*400; |
1681 | 334 avctx->codec_id = CODEC_ID_MPEG1VIDEO; |
335 avctx->sub_id = 1; | |
1613 | 336 } |
337 break; | |
338 case EXT_START_CODE: | |
339 if (bytes_left >= 1) { | |
340 ext_type = (buf[0] >> 4); | |
341 switch(ext_type) { | |
342 case 0x1: /* sequence extension */ | |
343 if (bytes_left >= 6) { | |
344 horiz_size_ext = ((buf[1] & 1) << 1) | (buf[2] >> 7); | |
345 vert_size_ext = (buf[2] >> 5) & 3; | |
2539 | 346 bit_rate_ext = ((buf[2] & 0x1F)<<7) | (buf[3]>>1); |
1613 | 347 frame_rate_ext_n = (buf[5] >> 5) & 3; |
348 frame_rate_ext_d = (buf[5] & 0x1f); | |
349 pc->progressive_sequence = buf[1] & (1 << 3); | |
2565 | 350 avctx->has_b_frames= !(buf[5] >> 7); |
1613 | 351 |
2269 | 352 pc->width |=(horiz_size_ext << 12); |
353 pc->height |=( vert_size_ext << 12); | |
2539 | 354 avctx->bit_rate += (bit_rate_ext << 18) * 400; |
2270 | 355 avcodec_set_dimensions(avctx, pc->width, pc->height); |
2637 | 356 avctx->time_base.den = pc->frame_rate * (frame_rate_ext_n + 1); |
357 avctx->time_base.num = MPEG1_FRAME_RATE_BASE * (frame_rate_ext_d + 1); | |
1681 | 358 avctx->codec_id = CODEC_ID_MPEG2VIDEO; |
1613 | 359 avctx->sub_id = 2; /* forces MPEG2 */ |
360 } | |
361 break; | |
362 case 0x8: /* picture coding extension */ | |
363 if (bytes_left >= 5) { | |
2120 | 364 picture_structure = buf[2]&3; |
1613 | 365 top_field_first = buf[3] & (1 << 7); |
366 repeat_first_field = buf[3] & (1 << 1); | |
367 progressive_frame = buf[4] & (1 << 7); | |
2967 | 368 |
1613 | 369 /* check if we must repeat the frame */ |
370 if (repeat_first_field) { | |
371 if (pc->progressive_sequence) { | |
372 if (top_field_first) | |
373 s->repeat_pict = 4; | |
374 else | |
375 s->repeat_pict = 2; | |
376 } else if (progressive_frame) { | |
377 s->repeat_pict = 1; | |
378 } | |
379 } | |
2967 | 380 |
381 /* the packet only represents half a frame | |
2119 | 382 XXX,FIXME maybe find a different solution */ |
383 if(picture_structure != 3) | |
384 s->repeat_pict = -1; | |
1613 | 385 } |
386 break; | |
387 } | |
388 } | |
389 break; | |
390 case -1: | |
391 goto the_end; | |
392 default: | |
393 /* we stop parsing when we encounter a slice. It ensures | |
394 that this function takes a negligible amount of time */ | |
2967 | 395 if (start_code >= SLICE_MIN_START_CODE && |
1613 | 396 start_code <= SLICE_MAX_START_CODE) |
397 goto the_end; | |
398 break; | |
399 } | |
400 } | |
401 the_end: ; | |
402 } | |
403 | |
404 static int mpegvideo_parse(AVCodecParserContext *s, | |
405 AVCodecContext *avctx, | |
2967 | 406 uint8_t **poutbuf, int *poutbuf_size, |
1613 | 407 const uint8_t *buf, int buf_size) |
408 { | |
1988 | 409 ParseContext1 *pc1 = s->priv_data; |
410 ParseContext *pc= &pc1->pc; | |
1613 | 411 int next; |
2967 | 412 |
2837 | 413 if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){ |
414 next= buf_size; | |
415 }else{ | |
416 next= ff_mpeg1_find_frame_end(pc, buf, buf_size); | |
2967 | 417 |
2837 | 418 if (ff_combine_frame(pc, next, (uint8_t **)&buf, &buf_size) < 0) { |
419 *poutbuf = NULL; | |
420 *poutbuf_size = 0; | |
421 return buf_size; | |
422 } | |
2967 | 423 |
1613 | 424 } |
425 /* we have a full frame : we just parse the first few MPEG headers | |
426 to have the full timing information. The time take by this | |
427 function should be negligible for uncorrupted streams */ | |
428 mpegvideo_extract_headers(s, avctx, buf, buf_size); | |
429 #if 0 | |
2967 | 430 printf("pict_type=%d frame_rate=%0.3f repeat_pict=%d\n", |
2637 | 431 s->pict_type, (double)avctx->time_base.den / avctx->time_base.num, s->repeat_pict); |
1613 | 432 #endif |
433 | |
434 *poutbuf = (uint8_t *)buf; | |
435 *poutbuf_size = buf_size; | |
436 return next; | |
437 } | |
438 | |
2769
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
439 static int mpegvideo_split(AVCodecContext *avctx, |
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
440 const uint8_t *buf, int buf_size) |
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
441 { |
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
442 int i; |
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
443 uint32_t state= -1; |
2967 | 444 |
2769
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
445 for(i=0; i<buf_size; i++){ |
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
446 state= (state<<8) | buf[i]; |
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
447 if(state != 0x1B3 && state != 0x1B5 && state < 0x200 && state >= 0x100) |
2777 | 448 return i-3; |
2769
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
449 } |
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
450 return 0; |
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
451 } |
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
452 |
1988 | 453 void ff_parse_close(AVCodecParserContext *s) |
1613 | 454 { |
1988 | 455 ParseContext *pc = s->priv_data; |
1613 | 456 |
457 av_free(pc->buffer); | |
1988 | 458 } |
459 | |
460 static void parse1_close(AVCodecParserContext *s) | |
461 { | |
462 ParseContext1 *pc1 = s->priv_data; | |
463 | |
464 av_free(pc1->pc.buffer); | |
465 av_free(pc1->enc); | |
1613 | 466 } |
467 | |
468 /*************************/ | |
469 | |
470 /* used by parser */ | |
471 /* XXX: make it use less memory */ | |
2967 | 472 static int av_mpeg4_decode_header(AVCodecParserContext *s1, |
1613 | 473 AVCodecContext *avctx, |
474 const uint8_t *buf, int buf_size) | |
475 { | |
476 ParseContext1 *pc = s1->priv_data; | |
477 MpegEncContext *s = pc->enc; | |
478 GetBitContext gb1, *gb = &gb1; | |
479 int ret; | |
480 | |
481 s->avctx = avctx; | |
1614 | 482 s->current_picture_ptr = &s->current_picture; |
483 | |
484 if (avctx->extradata_size && pc->first_picture){ | |
485 init_get_bits(gb, avctx->extradata, avctx->extradata_size*8); | |
486 ret = ff_mpeg4_decode_picture_header(s, gb); | |
487 } | |
488 | |
1613 | 489 init_get_bits(gb, buf, 8 * buf_size); |
490 ret = ff_mpeg4_decode_picture_header(s, gb); | |
491 if (s->width) { | |
2270 | 492 avcodec_set_dimensions(avctx, s->width, s->height); |
1613 | 493 } |
2837 | 494 s1->pict_type= s->pict_type; |
1614 | 495 pc->first_picture = 0; |
1613 | 496 return ret; |
497 } | |
498 | |
2024
f65d87bfdd5a
some of the warning fixes by (Michael Roitzsch <mroi at users dot sourceforge dot net>)
michael
parents:
1988
diff
changeset
|
499 static int mpeg4video_parse_init(AVCodecParserContext *s) |
1613 | 500 { |
501 ParseContext1 *pc = s->priv_data; | |
1614 | 502 |
1613 | 503 pc->enc = av_mallocz(sizeof(MpegEncContext)); |
504 if (!pc->enc) | |
505 return -1; | |
1614 | 506 pc->first_picture = 1; |
1613 | 507 return 0; |
508 } | |
509 | |
510 static int mpeg4video_parse(AVCodecParserContext *s, | |
511 AVCodecContext *avctx, | |
2967 | 512 uint8_t **poutbuf, int *poutbuf_size, |
1613 | 513 const uint8_t *buf, int buf_size) |
514 { | |
1988 | 515 ParseContext *pc = s->priv_data; |
1613 | 516 int next; |
2967 | 517 |
2837 | 518 if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){ |
519 next= buf_size; | |
520 }else{ | |
521 next= ff_mpeg4_find_frame_end(pc, buf, buf_size); | |
2967 | 522 |
2837 | 523 if (ff_combine_frame(pc, next, (uint8_t **)&buf, &buf_size) < 0) { |
524 *poutbuf = NULL; | |
525 *poutbuf_size = 0; | |
526 return buf_size; | |
527 } | |
1613 | 528 } |
529 av_mpeg4_decode_header(s, avctx, buf, buf_size); | |
530 | |
531 *poutbuf = (uint8_t *)buf; | |
532 *poutbuf_size = buf_size; | |
533 return next; | |
534 } | |
535 | |
2769
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
536 static int mpeg4video_split(AVCodecContext *avctx, |
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
537 const uint8_t *buf, int buf_size) |
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
538 { |
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
539 int i; |
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
540 uint32_t state= -1; |
2967 | 541 |
2769
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
542 for(i=0; i<buf_size; i++){ |
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
543 state= (state<<8) | buf[i]; |
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
544 if(state == 0x1B3 || state == 0x1B6) |
2777 | 545 return i-3; |
2769
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
546 } |
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
547 return 0; |
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
548 } |
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
549 |
1613 | 550 /*************************/ |
551 | |
552 typedef struct MpegAudioParseContext { | |
2979 | 553 uint8_t inbuf[MPA_MAX_CODED_FRAME_SIZE]; /* input buffer */ |
1613 | 554 uint8_t *inbuf_ptr; |
555 int frame_size; | |
556 int free_format_frame_size; | |
557 int free_format_next_header; | |
2470
06aafb585f69
require a few valid and equal mp3 headers for resync
michael
parents:
2389
diff
changeset
|
558 uint32_t header; |
06aafb585f69
require a few valid and equal mp3 headers for resync
michael
parents:
2389
diff
changeset
|
559 int header_count; |
1613 | 560 } MpegAudioParseContext; |
561 | |
562 #define MPA_HEADER_SIZE 4 | |
563 | |
564 /* header + layer + bitrate + freq + lsf/mpeg25 */ | |
2522
e25782262d7d
kill warnings patch by (M«©ns Rullg«©rd <mru inprovide com>)
michael
parents:
2486
diff
changeset
|
565 #undef SAME_HEADER_MASK /* mpegaudio.h defines different version */ |
1613 | 566 #define SAME_HEADER_MASK \ |
2480 | 567 (0xffe00000 | (3 << 17) | (3 << 10) | (3 << 19)) |
1613 | 568 |
569 static int mpegaudio_parse_init(AVCodecParserContext *s1) | |
570 { | |
571 MpegAudioParseContext *s = s1->priv_data; | |
572 s->inbuf_ptr = s->inbuf; | |
573 return 0; | |
574 } | |
575 | |
576 static int mpegaudio_parse(AVCodecParserContext *s1, | |
577 AVCodecContext *avctx, | |
2967 | 578 uint8_t **poutbuf, int *poutbuf_size, |
1613 | 579 const uint8_t *buf, int buf_size) |
580 { | |
581 MpegAudioParseContext *s = s1->priv_data; | |
2470
06aafb585f69
require a few valid and equal mp3 headers for resync
michael
parents:
2389
diff
changeset
|
582 int len, ret, sr; |
1613 | 583 uint32_t header; |
584 const uint8_t *buf_ptr; | |
585 | |
586 *poutbuf = NULL; | |
587 *poutbuf_size = 0; | |
588 buf_ptr = buf; | |
589 while (buf_size > 0) { | |
2979 | 590 len = s->inbuf_ptr - s->inbuf; |
591 if (s->frame_size == 0) { | |
1613 | 592 /* special case for next header for first frame in free |
593 format case (XXX: find a simpler method) */ | |
594 if (s->free_format_next_header != 0) { | |
595 s->inbuf[0] = s->free_format_next_header >> 24; | |
596 s->inbuf[1] = s->free_format_next_header >> 16; | |
597 s->inbuf[2] = s->free_format_next_header >> 8; | |
598 s->inbuf[3] = s->free_format_next_header; | |
599 s->inbuf_ptr = s->inbuf + 4; | |
600 s->free_format_next_header = 0; | |
601 goto got_header; | |
602 } | |
2979 | 603 /* no header seen : find one. We need at least MPA_HEADER_SIZE |
1613 | 604 bytes to parse it */ |
2979 | 605 len = MPA_HEADER_SIZE - len; |
606 if (len > buf_size) | |
607 len = buf_size; | |
608 if (len > 0) { | |
609 memcpy(s->inbuf_ptr, buf_ptr, len); | |
610 buf_ptr += len; | |
611 buf_size -= len; | |
612 s->inbuf_ptr += len; | |
613 } | |
614 if ((s->inbuf_ptr - s->inbuf) >= MPA_HEADER_SIZE) { | |
1613 | 615 got_header: |
2470
06aafb585f69
require a few valid and equal mp3 headers for resync
michael
parents:
2389
diff
changeset
|
616 sr= avctx->sample_rate; |
2979 | 617 header = (s->inbuf[0] << 24) | (s->inbuf[1] << 16) | |
618 (s->inbuf[2] << 8) | s->inbuf[3]; | |
1613 | 619 |
620 ret = mpa_decode_header(avctx, header); | |
621 if (ret < 0) { | |
2470
06aafb585f69
require a few valid and equal mp3 headers for resync
michael
parents:
2389
diff
changeset
|
622 s->header_count= -2; |
2979 | 623 /* no sync found : move by one byte (inefficient, but simple!) */ |
624 memmove(s->inbuf, s->inbuf + 1, s->inbuf_ptr - s->inbuf - 1); | |
625 s->inbuf_ptr--; | |
1613 | 626 dprintf("skip %x\n", header); |
627 /* reset free format frame size to give a chance | |
628 to get a new bitrate */ | |
629 s->free_format_frame_size = 0; | |
2979 | 630 } else { |
2470
06aafb585f69
require a few valid and equal mp3 headers for resync
michael
parents:
2389
diff
changeset
|
631 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
|
632 s->header_count= -3; |
06aafb585f69
require a few valid and equal mp3 headers for resync
michael
parents:
2389
diff
changeset
|
633 s->header= header; |
06aafb585f69
require a few valid and equal mp3 headers for resync
michael
parents:
2389
diff
changeset
|
634 s->header_count++; |
1613 | 635 s->frame_size = ret; |
2967 | 636 |
1613 | 637 #if 0 |
638 /* free format: prepare to compute frame size */ | |
2979 | 639 if (decode_header(s, header) == 1) { |
640 s->frame_size = -1; | |
1613 | 641 } |
642 #endif | |
2979 | 643 } |
2470
06aafb585f69
require a few valid and equal mp3 headers for resync
michael
parents:
2389
diff
changeset
|
644 if(s->header_count <= 0) |
06aafb585f69
require a few valid and equal mp3 headers for resync
michael
parents:
2389
diff
changeset
|
645 avctx->sample_rate= sr; //FIXME ugly |
2979 | 646 } |
2967 | 647 } else |
1613 | 648 #if 0 |
649 if (s->frame_size == -1) { | |
650 /* free format : find next sync to compute frame size */ | |
2979 | 651 len = MPA_MAX_CODED_FRAME_SIZE - len; |
652 if (len > buf_size) | |
653 len = buf_size; | |
1613 | 654 if (len == 0) { |
2979 | 655 /* frame too long: resync */ |
1613 | 656 s->frame_size = 0; |
2979 | 657 memmove(s->inbuf, s->inbuf + 1, s->inbuf_ptr - s->inbuf - 1); |
658 s->inbuf_ptr--; | |
1613 | 659 } else { |
660 uint8_t *p, *pend; | |
661 uint32_t header1; | |
662 int padding; | |
663 | |
664 memcpy(s->inbuf_ptr, buf_ptr, len); | |
665 /* check for header */ | |
666 p = s->inbuf_ptr - 3; | |
667 pend = s->inbuf_ptr + len - 4; | |
668 while (p <= pend) { | |
669 header = (p[0] << 24) | (p[1] << 16) | | |
670 (p[2] << 8) | p[3]; | |
671 header1 = (s->inbuf[0] << 24) | (s->inbuf[1] << 16) | | |
672 (s->inbuf[2] << 8) | s->inbuf[3]; | |
673 /* check with high probability that we have a | |
674 valid header */ | |
675 if ((header & SAME_HEADER_MASK) == | |
676 (header1 & SAME_HEADER_MASK)) { | |
677 /* header found: update pointers */ | |
678 len = (p + 4) - s->inbuf_ptr; | |
679 buf_ptr += len; | |
680 buf_size -= len; | |
681 s->inbuf_ptr = p; | |
682 /* compute frame size */ | |
683 s->free_format_next_header = header; | |
684 s->free_format_frame_size = s->inbuf_ptr - s->inbuf; | |
685 padding = (header1 >> 9) & 1; | |
686 if (s->layer == 1) | |
687 s->free_format_frame_size -= padding * 4; | |
688 else | |
689 s->free_format_frame_size -= padding; | |
2967 | 690 dprintf("free frame size=%d padding=%d\n", |
1613 | 691 s->free_format_frame_size, padding); |
692 decode_header(s, header1); | |
693 goto next_data; | |
694 } | |
695 p++; | |
696 } | |
697 /* not found: simply increase pointers */ | |
698 buf_ptr += len; | |
699 s->inbuf_ptr += len; | |
700 buf_size -= len; | |
701 } | |
2979 | 702 } else |
1613 | 703 #endif |
704 if (len < s->frame_size) { | |
705 if (s->frame_size > MPA_MAX_CODED_FRAME_SIZE) | |
706 s->frame_size = MPA_MAX_CODED_FRAME_SIZE; | |
2979 | 707 len = s->frame_size - len; |
708 if (len > buf_size) | |
709 len = buf_size; | |
710 memcpy(s->inbuf_ptr, buf_ptr, len); | |
711 buf_ptr += len; | |
712 s->inbuf_ptr += len; | |
713 buf_size -= len; | |
714 } | |
1613 | 715 // next_data: |
2967 | 716 if (s->frame_size > 0 && |
1613 | 717 (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
|
718 if(s->header_count > 0){ |
06aafb585f69
require a few valid and equal mp3 headers for resync
michael
parents:
2389
diff
changeset
|
719 *poutbuf = s->inbuf; |
06aafb585f69
require a few valid and equal mp3 headers for resync
michael
parents:
2389
diff
changeset
|
720 *poutbuf_size = s->inbuf_ptr - s->inbuf; |
06aafb585f69
require a few valid and equal mp3 headers for resync
michael
parents:
2389
diff
changeset
|
721 } |
2979 | 722 s->inbuf_ptr = s->inbuf; |
723 s->frame_size = 0; | |
724 break; | |
725 } | |
1613 | 726 } |
727 return buf_ptr - buf; | |
728 } | |
729 | |
3098 | 730 /* also used for ADTS AAC */ |
1613 | 731 typedef struct AC3ParseContext { |
732 uint8_t inbuf[4096]; /* input buffer */ | |
733 uint8_t *inbuf_ptr; | |
734 int frame_size; | |
3098 | 735 int header_size; |
736 int (*sync)(const uint8_t *buf, int *channels, int *sample_rate, | |
737 int *bit_rate, int *samples); | |
1613 | 738 } AC3ParseContext; |
739 | |
740 #define AC3_HEADER_SIZE 7 | |
3104 | 741 #define AAC_HEADER_SIZE 7 |
3059 | 742 |
743 static const int ac3_sample_rates[4] = { | |
744 48000, 44100, 32000, 0 | |
745 }; | |
746 | |
747 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
|
748 { 64, 69, 96 }, |
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
749 { 64, 70, 96 }, |
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
750 { 80, 87, 120 }, |
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
751 { 80, 88, 120 }, |
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
752 { 96, 104, 144 }, |
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
753 { 96, 105, 144 }, |
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
754 { 112, 121, 168 }, |
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
755 { 112, 122, 168 }, |
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
756 { 128, 139, 192 }, |
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
757 { 128, 140, 192 }, |
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
758 { 160, 174, 240 }, |
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
759 { 160, 175, 240 }, |
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
760 { 192, 208, 288 }, |
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
761 { 192, 209, 288 }, |
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
762 { 224, 243, 336 }, |
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
763 { 224, 244, 336 }, |
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
764 { 256, 278, 384 }, |
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
765 { 256, 279, 384 }, |
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
766 { 320, 348, 480 }, |
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
767 { 320, 349, 480 }, |
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
768 { 384, 417, 576 }, |
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
769 { 384, 418, 576 }, |
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
770 { 448, 487, 672 }, |
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
771 { 448, 488, 672 }, |
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
772 { 512, 557, 768 }, |
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
773 { 512, 558, 768 }, |
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
774 { 640, 696, 960 }, |
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
775 { 640, 697, 960 }, |
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
776 { 768, 835, 1152 }, |
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
777 { 768, 836, 1152 }, |
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
778 { 896, 975, 1344 }, |
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
779 { 896, 976, 1344 }, |
3059 | 780 { 1024, 1114, 1536 }, |
781 { 1024, 1115, 1536 }, | |
782 { 1152, 1253, 1728 }, | |
783 { 1152, 1254, 1728 }, | |
784 { 1280, 1393, 1920 }, | |
785 { 1280, 1394, 1920 }, | |
786 }; | |
787 | |
788 static const int ac3_bitrates[64] = { | |
789 32, 32, 40, 40, 48, 48, 56, 56, 64, 64, 80, 80, 96, 96, 112, 112, | |
790 128, 128, 160, 160, 192, 192, 224, 224, 256, 256, 320, 320, 384, | |
791 384, 448, 448, 512, 512, 576, 576, 640, 640, | |
792 }; | |
793 | |
794 static const int ac3_channels[8] = { | |
795 2, 1, 2, 3, 3, 4, 4, 5 | |
796 }; | |
797 | |
3098 | 798 static int aac_sample_rates[16] = { |
799 96000, 88200, 64000, 48000, 44100, 32000, | |
800 24000, 22050, 16000, 12000, 11025, 8000, 7350 | |
801 }; | |
802 | |
803 static int aac_channels[8] = { | |
804 0, 1, 2, 3, 4, 5, 6, 8 | |
805 }; | |
806 | |
3059 | 807 static int ac3_sync(const uint8_t *buf, int *channels, int *sample_rate, |
3098 | 808 int *bit_rate, int *samples) |
3059 | 809 { |
810 unsigned int fscod, frmsizecod, acmod, bsid, lfeon; | |
811 GetBitContext bits; | |
812 | |
813 init_get_bits(&bits, buf, AC3_HEADER_SIZE * 8); | |
814 | |
815 if(get_bits(&bits, 16) != 0x0b77) | |
3063
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
816 return 0; |
3059 | 817 |
3104 | 818 skip_bits(&bits, 16); /* crc */ |
3059 | 819 fscod = get_bits(&bits, 2); |
820 frmsizecod = get_bits(&bits, 6); | |
821 | |
822 if(!ac3_sample_rates[fscod]) | |
3063
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
823 return 0; |
3059 | 824 |
825 bsid = get_bits(&bits, 5); | |
826 if(bsid > 8) | |
3063
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
827 return 0; |
3104 | 828 skip_bits(&bits, 3); /* bsmod */ |
3059 | 829 acmod = get_bits(&bits, 3); |
830 if(acmod & 1 && acmod != 1) | |
3104 | 831 skip_bits(&bits, 2); /* cmixlev */ |
3059 | 832 if(acmod & 4) |
3104 | 833 skip_bits(&bits, 2); /* surmixlev */ |
3059 | 834 if(acmod & 2) |
3104 | 835 skip_bits(&bits, 2); /* dsurmod */ |
836 lfeon = get_bits1(&bits); | |
3059 | 837 |
838 *sample_rate = ac3_sample_rates[fscod]; | |
839 *bit_rate = ac3_bitrates[frmsizecod] * 1000; | |
840 *channels = ac3_channels[acmod] + lfeon; | |
3098 | 841 *samples = 6 * 256; |
3059 | 842 |
843 return ac3_frame_sizes[frmsizecod][fscod] * 2; | |
844 } | |
1613 | 845 |
3098 | 846 static int aac_sync(const uint8_t *buf, int *channels, int *sample_rate, |
847 int *bit_rate, int *samples) | |
848 { | |
849 GetBitContext bits; | |
850 int size, rdb, ch, sr; | |
851 | |
852 init_get_bits(&bits, buf, AAC_HEADER_SIZE * 8); | |
853 | |
854 if(get_bits(&bits, 12) != 0xfff) | |
855 return 0; | |
856 | |
3104 | 857 skip_bits1(&bits); /* id */ |
858 skip_bits(&bits, 2); /* layer */ | |
859 skip_bits1(&bits); /* protection_absent */ | |
860 skip_bits(&bits, 2); /* profile_objecttype */ | |
861 sr = get_bits(&bits, 4); /* sample_frequency_index */ | |
3098 | 862 if(!aac_sample_rates[sr]) |
863 return 0; | |
3104 | 864 skip_bits1(&bits); /* private_bit */ |
865 ch = get_bits(&bits, 3); /* channel_configuration */ | |
3098 | 866 if(!aac_channels[ch]) |
867 return 0; | |
3104 | 868 skip_bits1(&bits); /* original/copy */ |
869 skip_bits1(&bits); /* home */ | |
3098 | 870 |
871 /* adts_variable_header */ | |
3104 | 872 skip_bits1(&bits); /* copyright_identification_bit */ |
873 skip_bits1(&bits); /* copyright_identification_start */ | |
874 size = get_bits(&bits, 13); /* aac_frame_length */ | |
875 skip_bits(&bits, 11); /* adts_buffer_fullness */ | |
876 rdb = get_bits(&bits, 2); /* number_of_raw_data_blocks_in_frame */ | |
3098 | 877 |
878 *channels = aac_channels[ch]; | |
879 *sample_rate = aac_sample_rates[sr]; | |
880 *samples = (rdb + 1) * 1024; | |
881 *bit_rate = size * 8 * *sample_rate / *samples; | |
882 | |
883 return size; | |
884 } | |
885 | |
1613 | 886 static int ac3_parse_init(AVCodecParserContext *s1) |
887 { | |
888 AC3ParseContext *s = s1->priv_data; | |
889 s->inbuf_ptr = s->inbuf; | |
3098 | 890 s->header_size = AC3_HEADER_SIZE; |
891 s->sync = ac3_sync; | |
1613 | 892 return 0; |
893 } | |
894 | |
3098 | 895 static int aac_parse_init(AVCodecParserContext *s1) |
896 { | |
897 AC3ParseContext *s = s1->priv_data; | |
898 s->inbuf_ptr = s->inbuf; | |
899 s->header_size = AAC_HEADER_SIZE; | |
900 s->sync = aac_sync; | |
901 return 0; | |
902 } | |
903 | |
904 /* also used for ADTS AAC */ | |
1613 | 905 static int ac3_parse(AVCodecParserContext *s1, |
906 AVCodecContext *avctx, | |
2967 | 907 uint8_t **poutbuf, int *poutbuf_size, |
1613 | 908 const uint8_t *buf, int buf_size) |
909 { | |
910 AC3ParseContext *s = s1->priv_data; | |
911 const uint8_t *buf_ptr; | |
3098 | 912 int len, sample_rate, bit_rate, channels, samples; |
1613 | 913 |
914 *poutbuf = NULL; | |
915 *poutbuf_size = 0; | |
916 | |
917 buf_ptr = buf; | |
918 while (buf_size > 0) { | |
919 len = s->inbuf_ptr - s->inbuf; | |
920 if (s->frame_size == 0) { | |
3098 | 921 /* no header seen : find one. We need at least s->header_size |
922 bytes to parse it */ | |
923 len = FFMIN(s->header_size - len, buf_size); | |
3082 | 924 |
1613 | 925 memcpy(s->inbuf_ptr, buf_ptr, len); |
926 buf_ptr += len; | |
927 s->inbuf_ptr += len; | |
928 buf_size -= len; | |
3098 | 929 if ((s->inbuf_ptr - s->inbuf) == s->header_size) { |
930 len = s->sync(s->inbuf, &channels, &sample_rate, &bit_rate, | |
931 &samples); | |
1613 | 932 if (len == 0) { |
933 /* no sync found : move by one byte (inefficient, but simple!) */ | |
3098 | 934 memmove(s->inbuf, s->inbuf + 1, s->header_size - 1); |
1613 | 935 s->inbuf_ptr--; |
936 } else { | |
2979 | 937 s->frame_size = len; |
1613 | 938 /* update codec info */ |
939 avctx->sample_rate = sample_rate; | |
1987 | 940 /* set channels,except if the user explicitly requests 1 or 2 channels, XXX/FIXME this is a bit ugly */ |
3098 | 941 if(avctx->codec_id == CODEC_ID_AC3){ |
942 if(avctx->channels!=1 && avctx->channels!=2){ | |
943 avctx->channels = channels; | |
944 } | |
945 } else { | |
3063
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
946 avctx->channels = channels; |
1987 | 947 } |
2979 | 948 avctx->bit_rate = bit_rate; |
3098 | 949 avctx->frame_size = samples; |
1613 | 950 } |
951 } | |
3082 | 952 } else { |
953 len = FFMIN(s->frame_size - len, buf_size); | |
1613 | 954 |
955 memcpy(s->inbuf_ptr, buf_ptr, len); | |
956 buf_ptr += len; | |
957 s->inbuf_ptr += len; | |
958 buf_size -= len; | |
3082 | 959 |
960 if(s->inbuf_ptr - s->inbuf == s->frame_size){ | |
961 *poutbuf = s->inbuf; | |
962 *poutbuf_size = s->frame_size; | |
963 s->inbuf_ptr = s->inbuf; | |
964 s->frame_size = 0; | |
965 break; | |
966 } | |
1613 | 967 } |
968 } | |
969 return buf_ptr - buf; | |
970 } | |
971 | |
972 AVCodecParser mpegvideo_parser = { | |
973 { CODEC_ID_MPEG1VIDEO, CODEC_ID_MPEG2VIDEO }, | |
974 sizeof(ParseContext1), | |
975 NULL, | |
976 mpegvideo_parse, | |
1988 | 977 parse1_close, |
2769
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
978 mpegvideo_split, |
1613 | 979 }; |
980 | |
981 AVCodecParser mpeg4video_parser = { | |
982 { CODEC_ID_MPEG4 }, | |
983 sizeof(ParseContext1), | |
984 mpeg4video_parse_init, | |
985 mpeg4video_parse, | |
1988 | 986 parse1_close, |
2769
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
987 mpeg4video_split, |
1613 | 988 }; |
989 | |
990 AVCodecParser mpegaudio_parser = { | |
991 { CODEC_ID_MP2, CODEC_ID_MP3 }, | |
992 sizeof(MpegAudioParseContext), | |
993 mpegaudio_parse_init, | |
994 mpegaudio_parse, | |
995 NULL, | |
996 }; | |
997 | |
998 AVCodecParser ac3_parser = { | |
999 { CODEC_ID_AC3 }, | |
1000 sizeof(AC3ParseContext), | |
1001 ac3_parse_init, | |
1002 ac3_parse, | |
1003 NULL, | |
1004 }; | |
3098 | 1005 |
1006 AVCodecParser aac_parser = { | |
1007 { CODEC_ID_AAC }, | |
1008 sizeof(AC3ParseContext), | |
1009 aac_parse_init, | |
1010 ac3_parse, | |
1011 NULL, | |
1012 }; |