Mercurial > libavcodec.hg
annotate parser.c @ 1795:920e6381e1fe libavcodec
2 byte shorter userdata for mpeg4
in the past it was startcode,string,00,7F,startcode
now it is startcode,string,stratcode
both are mpeg4 compliant, as according to the standard the userdata lasts until the next 00 00 01 (startcode prefix) but some very primitive decoders which simply skip until the first 00 byte and then expect the next valid startcode might fail with the old variant, just a theory though (didnt test if quicktime can decode it now)
author | michael |
---|---|
date | Sun, 08 Feb 2004 22:52:35 +0000 |
parents | f5af91b8be17 |
children | d9e067853051 |
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 | |
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
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; | |
37 | |
38 for(parser = av_first_parser; parser != NULL; parser = parser->next) { | |
39 if (parser->codec_ids[0] == codec_id || | |
40 parser->codec_ids[1] == codec_id || | |
41 parser->codec_ids[2] == codec_id) | |
42 goto found; | |
43 } | |
44 return NULL; | |
45 found: | |
46 s = av_mallocz(sizeof(AVCodecParserContext)); | |
47 if (!s) | |
48 return NULL; | |
49 s->parser = parser; | |
50 s->priv_data = av_mallocz(parser->priv_data_size); | |
51 if (!s->priv_data) { | |
52 av_free(s); | |
53 return NULL; | |
54 } | |
55 if (parser->parser_init) { | |
56 ret = parser->parser_init(s); | |
57 if (ret != 0) { | |
58 av_free(s->priv_data); | |
59 av_free(s); | |
60 return NULL; | |
61 } | |
62 } | |
63 return s; | |
64 } | |
65 | |
1694
13169235c306
added End Of File handling to return last picture for MPEG1/2/4
bellard
parents:
1681
diff
changeset
|
66 /* 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
|
67 can be returned if necessary */ |
1613 | 68 int av_parser_parse(AVCodecParserContext *s, |
69 AVCodecContext *avctx, | |
70 uint8_t **poutbuf, int *poutbuf_size, | |
1696 | 71 const uint8_t *buf, int buf_size, |
72 int64_t pts, int64_t dts) | |
1613 | 73 { |
1696 | 74 int index, i, k; |
1694
13169235c306
added End Of File handling to return last picture for MPEG1/2/4
bellard
parents:
1681
diff
changeset
|
75 uint8_t dummy_buf[FF_INPUT_BUFFER_PADDING_SIZE]; |
13169235c306
added End Of File handling to return last picture for MPEG1/2/4
bellard
parents:
1681
diff
changeset
|
76 |
13169235c306
added End Of File handling to return last picture for MPEG1/2/4
bellard
parents:
1681
diff
changeset
|
77 if (buf_size == 0) { |
13169235c306
added End Of File handling to return last picture for MPEG1/2/4
bellard
parents:
1681
diff
changeset
|
78 /* 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
|
79 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
|
80 buf = dummy_buf; |
1696 | 81 } else { |
82 /* add a new packet descriptor */ | |
83 k = (s->cur_frame_start_index + 1) & (AV_PARSER_PTS_NB - 1); | |
84 s->cur_frame_start_index = k; | |
85 s->cur_frame_offset[k] = s->cur_offset; | |
86 s->cur_frame_pts[k] = pts; | |
87 s->cur_frame_dts[k] = dts; | |
88 | |
89 /* fill first PTS/DTS */ | |
90 if (s->cur_offset == 0) { | |
91 s->last_pts = pts; | |
92 s->last_dts = dts; | |
93 } | |
1694
13169235c306
added End Of File handling to return last picture for MPEG1/2/4
bellard
parents:
1681
diff
changeset
|
94 } |
13169235c306
added End Of File handling to return last picture for MPEG1/2/4
bellard
parents:
1681
diff
changeset
|
95 |
1613 | 96 /* WARNING: the returned index can be negative */ |
97 index = s->parser->parser_parse(s, avctx, poutbuf, poutbuf_size, buf, buf_size); | |
98 /* update the file pointer */ | |
99 if (*poutbuf_size) { | |
1696 | 100 /* fill the data for the current frame */ |
1613 | 101 s->frame_offset = s->last_frame_offset; |
1696 | 102 s->pts = s->last_pts; |
103 s->dts = s->last_dts; | |
104 | |
105 /* offset of the next frame */ | |
1613 | 106 s->last_frame_offset = s->cur_offset + index; |
1696 | 107 /* find the packet in which the new frame starts. It |
108 is tricky because of MPEG video start codes | |
109 which can begin in one packet and finish in | |
110 another packet. In the worst case, an MPEG | |
111 video start code could be in 4 different | |
112 packets. */ | |
113 k = s->cur_frame_start_index; | |
114 for(i = 0; i < AV_PARSER_PTS_NB; i++) { | |
115 if (s->last_frame_offset >= s->cur_frame_offset[k]) | |
116 break; | |
117 k = (k - 1) & (AV_PARSER_PTS_NB - 1); | |
118 } | |
119 s->last_pts = s->cur_frame_pts[k]; | |
120 s->last_dts = s->cur_frame_dts[k]; | |
1613 | 121 } |
122 if (index < 0) | |
123 index = 0; | |
124 s->cur_offset += index; | |
125 return index; | |
126 } | |
127 | |
128 void av_parser_close(AVCodecParserContext *s) | |
129 { | |
130 if (s->parser->parser_close) | |
131 s->parser->parser_close(s); | |
132 av_free(s->priv_data); | |
133 av_free(s); | |
134 } | |
135 | |
136 /*****************************************************/ | |
137 | |
138 //#define END_NOT_FOUND (-100) | |
139 | |
140 #define PICTURE_START_CODE 0x00000100 | |
141 #define SEQ_START_CODE 0x000001b3 | |
142 #define EXT_START_CODE 0x000001b5 | |
143 #define SLICE_MIN_START_CODE 0x00000101 | |
144 #define SLICE_MAX_START_CODE 0x000001af | |
145 | |
146 typedef struct ParseContext1{ | |
147 uint8_t *buffer; | |
148 int index; | |
149 int last_index; | |
150 int buffer_size; | |
151 uint32_t state; ///< contains the last few bytes in MSB order | |
152 int frame_start_found; | |
153 int overread; ///< the number of bytes which where irreversibly read from the next frame | |
154 int overread_index; ///< the index into ParseContext1.buffer of the overreaded bytes | |
155 | |
156 /* MPEG2 specific */ | |
157 int frame_rate; | |
158 int progressive_sequence; | |
159 int width, height; | |
1614 | 160 |
1613 | 161 /* XXX: suppress that, needed by MPEG4 */ |
162 MpegEncContext *enc; | |
1614 | 163 int first_picture; |
1613 | 164 } ParseContext1; |
165 | |
166 /** | |
167 * combines the (truncated) bitstream to a complete frame | |
168 * @returns -1 if no complete frame could be created | |
169 */ | |
170 static int ff_combine_frame1(ParseContext1 *pc, int next, uint8_t **buf, int *buf_size) | |
171 { | |
172 #if 0 | |
173 if(pc->overread){ | |
174 printf("overread %d, state:%X next:%d index:%d o_index:%d\n", pc->overread, pc->state, next, pc->index, pc->overread_index); | |
175 printf("%X %X %X %X\n", (*buf)[0], (*buf)[1],(*buf)[2],(*buf)[3]); | |
176 } | |
177 #endif | |
178 | |
179 /* copy overreaded bytes from last frame into buffer */ | |
180 for(; pc->overread>0; pc->overread--){ | |
181 pc->buffer[pc->index++]= pc->buffer[pc->overread_index++]; | |
182 } | |
183 | |
184 pc->last_index= pc->index; | |
185 | |
186 /* copy into buffer end return */ | |
187 if(next == END_NOT_FOUND){ | |
188 pc->buffer= av_fast_realloc(pc->buffer, &pc->buffer_size, (*buf_size) + pc->index + FF_INPUT_BUFFER_PADDING_SIZE); | |
189 | |
190 memcpy(&pc->buffer[pc->index], *buf, *buf_size); | |
191 pc->index += *buf_size; | |
192 return -1; | |
193 } | |
194 | |
195 *buf_size= | |
196 pc->overread_index= pc->index + next; | |
197 | |
198 /* append to buffer */ | |
199 if(pc->index){ | |
200 pc->buffer= av_fast_realloc(pc->buffer, &pc->buffer_size, next + pc->index + FF_INPUT_BUFFER_PADDING_SIZE); | |
201 | |
202 memcpy(&pc->buffer[pc->index], *buf, next + FF_INPUT_BUFFER_PADDING_SIZE ); | |
203 pc->index = 0; | |
204 *buf= pc->buffer; | |
205 } | |
206 | |
207 /* store overread bytes */ | |
208 for(;next < 0; next++){ | |
209 pc->state = (pc->state<<8) | pc->buffer[pc->last_index + next]; | |
210 pc->overread++; | |
211 } | |
212 | |
213 #if 0 | |
214 if(pc->overread){ | |
215 printf("overread %d, state:%X next:%d index:%d o_index:%d\n", pc->overread, pc->state, next, pc->index, pc->overread_index); | |
216 printf("%X %X %X %X\n", (*buf)[0], (*buf)[1],(*buf)[2],(*buf)[3]); | |
217 } | |
218 #endif | |
219 | |
220 return 0; | |
221 } | |
222 | |
223 /** | |
224 * finds the end of the current frame in the bitstream. | |
225 * @return the position of the first byte of the next frame, or -1 | |
226 */ | |
227 static int mpeg1_find_frame_end(ParseContext1 *pc, const uint8_t *buf, int buf_size) | |
228 { | |
229 int i; | |
230 uint32_t state; | |
231 | |
232 state= pc->state; | |
233 | |
234 i=0; | |
235 if(!pc->frame_start_found){ | |
236 for(i=0; i<buf_size; i++){ | |
237 state= (state<<8) | buf[i]; | |
238 if(state >= SLICE_MIN_START_CODE && state <= SLICE_MAX_START_CODE){ | |
239 i++; | |
240 pc->frame_start_found=1; | |
241 break; | |
242 } | |
243 } | |
244 } | |
245 | |
246 if(pc->frame_start_found){ | |
1694
13169235c306
added End Of File handling to return last picture for MPEG1/2/4
bellard
parents:
1681
diff
changeset
|
247 /* EOF considered as end of frame */ |
13169235c306
added End Of File handling to return last picture for MPEG1/2/4
bellard
parents:
1681
diff
changeset
|
248 if (buf_size == 0) |
13169235c306
added End Of File handling to return last picture for MPEG1/2/4
bellard
parents:
1681
diff
changeset
|
249 return 0; |
1613 | 250 for(; i<buf_size; i++){ |
251 state= (state<<8) | buf[i]; | |
252 if((state&0xFFFFFF00) == 0x100){ | |
253 if(state < SLICE_MIN_START_CODE || state > SLICE_MAX_START_CODE){ | |
254 pc->frame_start_found=0; | |
255 pc->state=-1; | |
256 return i-3; | |
257 } | |
258 } | |
259 } | |
260 } | |
261 pc->state= state; | |
262 return END_NOT_FOUND; | |
263 } | |
264 | |
265 static int find_start_code(const uint8_t **pbuf_ptr, const uint8_t *buf_end) | |
266 { | |
267 const uint8_t *buf_ptr; | |
268 unsigned int state=0xFFFFFFFF, v; | |
269 int val; | |
270 | |
271 buf_ptr = *pbuf_ptr; | |
272 while (buf_ptr < buf_end) { | |
273 v = *buf_ptr++; | |
274 if (state == 0x000001) { | |
275 state = ((state << 8) | v) & 0xffffff; | |
276 val = state; | |
277 goto found; | |
278 } | |
279 state = ((state << 8) | v) & 0xffffff; | |
280 } | |
281 val = -1; | |
282 found: | |
283 *pbuf_ptr = buf_ptr; | |
284 return val; | |
285 } | |
286 | |
287 /* XXX: merge with libavcodec ? */ | |
288 #define MPEG1_FRAME_RATE_BASE 1001 | |
289 | |
290 static const int frame_rate_tab[16] = { | |
291 0, | |
292 24000, | |
293 24024, | |
294 25025, | |
295 30000, | |
296 30030, | |
297 50050, | |
298 60000, | |
299 60060, | |
300 // Xing's 15fps: (9) | |
301 15015, | |
302 // libmpeg3's "Unofficial economy rates": (10-13) | |
303 5005, | |
304 10010, | |
305 12012, | |
306 15015, | |
307 // random, just to avoid segfault !never encode these | |
308 25025, | |
309 25025, | |
310 }; | |
311 | |
312 static void mpegvideo_extract_headers(AVCodecParserContext *s, | |
313 AVCodecContext *avctx, | |
314 const uint8_t *buf, int buf_size) | |
315 { | |
316 ParseContext1 *pc = s->priv_data; | |
317 const uint8_t *buf_end; | |
318 int32_t start_code; | |
319 int frame_rate_index, ext_type, bytes_left; | |
320 int frame_rate_ext_n, frame_rate_ext_d; | |
321 int top_field_first, repeat_first_field, progressive_frame; | |
322 int horiz_size_ext, vert_size_ext; | |
323 | |
324 s->repeat_pict = 0; | |
325 buf_end = buf + buf_size; | |
326 while (buf < buf_end) { | |
327 start_code = find_start_code(&buf, buf_end); | |
328 bytes_left = buf_end - buf; | |
329 switch(start_code) { | |
330 case PICTURE_START_CODE: | |
331 if (bytes_left >= 2) { | |
332 s->pict_type = (buf[1] >> 3) & 7; | |
333 } | |
334 break; | |
335 case SEQ_START_CODE: | |
336 if (bytes_left >= 4) { | |
337 pc->width = avctx->width = (buf[0] << 4) | (buf[1] >> 4); | |
338 pc->height = avctx->height = ((buf[1] & 0x0f) << 8) | buf[2]; | |
339 frame_rate_index = buf[3] & 0xf; | |
340 pc->frame_rate = avctx->frame_rate = frame_rate_tab[frame_rate_index]; | |
341 avctx->frame_rate_base = MPEG1_FRAME_RATE_BASE; | |
1681 | 342 avctx->codec_id = CODEC_ID_MPEG1VIDEO; |
343 avctx->sub_id = 1; | |
1613 | 344 } |
345 break; | |
346 case EXT_START_CODE: | |
347 if (bytes_left >= 1) { | |
348 ext_type = (buf[0] >> 4); | |
349 switch(ext_type) { | |
350 case 0x1: /* sequence extension */ | |
351 if (bytes_left >= 6) { | |
352 horiz_size_ext = ((buf[1] & 1) << 1) | (buf[2] >> 7); | |
353 vert_size_ext = (buf[2] >> 5) & 3; | |
354 frame_rate_ext_n = (buf[5] >> 5) & 3; | |
355 frame_rate_ext_d = (buf[5] & 0x1f); | |
356 pc->progressive_sequence = buf[1] & (1 << 3); | |
357 | |
358 avctx->width = pc->width | (horiz_size_ext << 12); | |
359 avctx->height = pc->height | (vert_size_ext << 12); | |
360 avctx->frame_rate = pc->frame_rate * (frame_rate_ext_n + 1); | |
361 avctx->frame_rate_base = MPEG1_FRAME_RATE_BASE * (frame_rate_ext_d + 1); | |
1681 | 362 avctx->codec_id = CODEC_ID_MPEG2VIDEO; |
1613 | 363 avctx->sub_id = 2; /* forces MPEG2 */ |
364 } | |
365 break; | |
366 case 0x8: /* picture coding extension */ | |
367 if (bytes_left >= 5) { | |
368 top_field_first = buf[3] & (1 << 7); | |
369 repeat_first_field = buf[3] & (1 << 1); | |
370 progressive_frame = buf[4] & (1 << 7); | |
371 | |
372 /* check if we must repeat the frame */ | |
373 if (repeat_first_field) { | |
374 if (pc->progressive_sequence) { | |
375 if (top_field_first) | |
376 s->repeat_pict = 4; | |
377 else | |
378 s->repeat_pict = 2; | |
379 } else if (progressive_frame) { | |
380 s->repeat_pict = 1; | |
381 } | |
382 } | |
383 } | |
384 break; | |
385 } | |
386 } | |
387 break; | |
388 case -1: | |
389 goto the_end; | |
390 default: | |
391 /* we stop parsing when we encounter a slice. It ensures | |
392 that this function takes a negligible amount of time */ | |
393 if (start_code >= SLICE_MIN_START_CODE && | |
394 start_code <= SLICE_MAX_START_CODE) | |
395 goto the_end; | |
396 break; | |
397 } | |
398 } | |
399 the_end: ; | |
400 } | |
401 | |
402 static int mpegvideo_parse(AVCodecParserContext *s, | |
403 AVCodecContext *avctx, | |
404 uint8_t **poutbuf, int *poutbuf_size, | |
405 const uint8_t *buf, int buf_size) | |
406 { | |
407 ParseContext1 *pc = s->priv_data; | |
408 int next; | |
409 | |
410 next= mpeg1_find_frame_end(pc, buf, buf_size); | |
411 | |
412 if (ff_combine_frame1(pc, next, (uint8_t **)&buf, &buf_size) < 0) { | |
413 *poutbuf = NULL; | |
414 *poutbuf_size = 0; | |
415 return buf_size; | |
416 } | |
417 /* we have a full frame : we just parse the first few MPEG headers | |
418 to have the full timing information. The time take by this | |
419 function should be negligible for uncorrupted streams */ | |
420 mpegvideo_extract_headers(s, avctx, buf, buf_size); | |
421 #if 0 | |
422 printf("pict_type=%d frame_rate=%0.3f repeat_pict=%d\n", | |
423 s->pict_type, (double)avctx->frame_rate / avctx->frame_rate_base, s->repeat_pict); | |
424 #endif | |
425 | |
426 *poutbuf = (uint8_t *)buf; | |
427 *poutbuf_size = buf_size; | |
428 return next; | |
429 } | |
430 | |
431 static void mpegvideo_parse_close(AVCodecParserContext *s) | |
432 { | |
433 ParseContext1 *pc = s->priv_data; | |
434 | |
435 av_free(pc->buffer); | |
436 av_free(pc->enc); | |
437 } | |
438 | |
439 /*************************/ | |
440 | |
441 /** | |
442 * finds the end of the current frame in the bitstream. | |
443 * @return the position of the first byte of the next frame, or -1 | |
444 */ | |
445 static int mpeg4_find_frame_end(ParseContext1 *pc, | |
446 const uint8_t *buf, int buf_size) | |
447 { | |
448 int vop_found, i; | |
449 uint32_t state; | |
450 | |
451 vop_found= pc->frame_start_found; | |
452 state= pc->state; | |
453 | |
454 i=0; | |
455 if(!vop_found){ | |
456 for(i=0; i<buf_size; i++){ | |
457 state= (state<<8) | buf[i]; | |
458 if(state == 0x1B6){ | |
459 i++; | |
460 vop_found=1; | |
461 break; | |
462 } | |
463 } | |
464 } | |
465 | |
466 if(vop_found){ | |
1694
13169235c306
added End Of File handling to return last picture for MPEG1/2/4
bellard
parents:
1681
diff
changeset
|
467 /* EOF considered as end of frame */ |
13169235c306
added End Of File handling to return last picture for MPEG1/2/4
bellard
parents:
1681
diff
changeset
|
468 if (buf_size == 0) |
13169235c306
added End Of File handling to return last picture for MPEG1/2/4
bellard
parents:
1681
diff
changeset
|
469 return 0; |
13169235c306
added End Of File handling to return last picture for MPEG1/2/4
bellard
parents:
1681
diff
changeset
|
470 for(; i<buf_size; i++){ |
13169235c306
added End Of File handling to return last picture for MPEG1/2/4
bellard
parents:
1681
diff
changeset
|
471 state= (state<<8) | buf[i]; |
13169235c306
added End Of File handling to return last picture for MPEG1/2/4
bellard
parents:
1681
diff
changeset
|
472 if((state&0xFFFFFF00) == 0x100){ |
13169235c306
added End Of File handling to return last picture for MPEG1/2/4
bellard
parents:
1681
diff
changeset
|
473 pc->frame_start_found=0; |
13169235c306
added End Of File handling to return last picture for MPEG1/2/4
bellard
parents:
1681
diff
changeset
|
474 pc->state=-1; |
13169235c306
added End Of File handling to return last picture for MPEG1/2/4
bellard
parents:
1681
diff
changeset
|
475 return i-3; |
13169235c306
added End Of File handling to return last picture for MPEG1/2/4
bellard
parents:
1681
diff
changeset
|
476 } |
1613 | 477 } |
478 } | |
479 pc->frame_start_found= vop_found; | |
480 pc->state= state; | |
481 return END_NOT_FOUND; | |
482 } | |
483 | |
484 /* used by parser */ | |
485 /* XXX: make it use less memory */ | |
486 static int av_mpeg4_decode_header(AVCodecParserContext *s1, | |
487 AVCodecContext *avctx, | |
488 const uint8_t *buf, int buf_size) | |
489 { | |
490 ParseContext1 *pc = s1->priv_data; | |
491 MpegEncContext *s = pc->enc; | |
492 GetBitContext gb1, *gb = &gb1; | |
493 int ret; | |
494 | |
495 s->avctx = avctx; | |
1614 | 496 s->current_picture_ptr = &s->current_picture; |
497 | |
498 if (avctx->extradata_size && pc->first_picture){ | |
499 init_get_bits(gb, avctx->extradata, avctx->extradata_size*8); | |
500 ret = ff_mpeg4_decode_picture_header(s, gb); | |
501 } | |
502 | |
1613 | 503 init_get_bits(gb, buf, 8 * buf_size); |
504 ret = ff_mpeg4_decode_picture_header(s, gb); | |
505 if (s->width) { | |
506 avctx->width = s->width; | |
507 avctx->height = s->height; | |
508 } | |
1614 | 509 pc->first_picture = 0; |
1613 | 510 return ret; |
511 } | |
512 | |
513 int mpeg4video_parse_init(AVCodecParserContext *s) | |
514 { | |
515 ParseContext1 *pc = s->priv_data; | |
1614 | 516 |
1613 | 517 pc->enc = av_mallocz(sizeof(MpegEncContext)); |
518 if (!pc->enc) | |
519 return -1; | |
1614 | 520 pc->first_picture = 1; |
1613 | 521 return 0; |
522 } | |
523 | |
524 static int mpeg4video_parse(AVCodecParserContext *s, | |
525 AVCodecContext *avctx, | |
526 uint8_t **poutbuf, int *poutbuf_size, | |
527 const uint8_t *buf, int buf_size) | |
528 { | |
529 ParseContext1 *pc = s->priv_data; | |
530 int next; | |
531 | |
532 next= mpeg4_find_frame_end(pc, buf, buf_size); | |
533 | |
534 if (ff_combine_frame1(pc, next, (uint8_t **)&buf, &buf_size) < 0) { | |
535 *poutbuf = NULL; | |
536 *poutbuf_size = 0; | |
537 return buf_size; | |
538 } | |
539 av_mpeg4_decode_header(s, avctx, buf, buf_size); | |
540 | |
541 *poutbuf = (uint8_t *)buf; | |
542 *poutbuf_size = buf_size; | |
543 return next; | |
544 } | |
545 | |
546 /*************************/ | |
547 | |
548 static int h263_find_frame_end(ParseContext1 *pc, const uint8_t *buf, int buf_size) | |
549 { | |
550 int vop_found, i; | |
551 uint32_t state; | |
552 | |
553 vop_found= pc->frame_start_found; | |
554 state= pc->state; | |
555 | |
556 i=0; | |
557 if(!vop_found){ | |
558 for(i=0; i<buf_size; i++){ | |
559 state= (state<<8) | buf[i]; | |
560 if(state>>(32-22) == 0x20){ | |
561 i++; | |
562 vop_found=1; | |
563 break; | |
564 } | |
565 } | |
566 } | |
567 | |
568 if(vop_found){ | |
569 for(; i<buf_size; i++){ | |
570 state= (state<<8) | buf[i]; | |
571 if(state>>(32-22) == 0x20){ | |
572 pc->frame_start_found=0; | |
573 pc->state=-1; | |
574 return i-3; | |
575 } | |
576 } | |
577 } | |
578 pc->frame_start_found= vop_found; | |
579 pc->state= state; | |
580 | |
581 return END_NOT_FOUND; | |
582 } | |
583 | |
584 static int h263_parse(AVCodecParserContext *s, | |
585 AVCodecContext *avctx, | |
586 uint8_t **poutbuf, int *poutbuf_size, | |
587 const uint8_t *buf, int buf_size) | |
588 { | |
589 ParseContext1 *pc = s->priv_data; | |
590 int next; | |
591 | |
592 next= h263_find_frame_end(pc, buf, buf_size); | |
593 | |
594 if (ff_combine_frame1(pc, next, (uint8_t **)&buf, &buf_size) < 0) { | |
595 *poutbuf = NULL; | |
596 *poutbuf_size = 0; | |
597 return buf_size; | |
598 } | |
599 | |
600 *poutbuf = (uint8_t *)buf; | |
601 *poutbuf_size = buf_size; | |
602 return next; | |
603 } | |
604 | |
605 /*************************/ | |
606 | |
607 /** | |
608 * finds the end of the current frame in the bitstream. | |
609 * @return the position of the first byte of the next frame, or -1 | |
610 */ | |
611 static int h264_find_frame_end(ParseContext1 *pc, const uint8_t *buf, int buf_size) | |
612 { | |
613 int i; | |
614 uint32_t state; | |
615 //printf("first %02X%02X%02X%02X\n", buf[0], buf[1],buf[2],buf[3]); | |
616 // mb_addr= pc->mb_addr - 1; | |
617 state= pc->state; | |
618 //FIXME this will fail with slices | |
619 for(i=0; i<buf_size; i++){ | |
620 state= (state<<8) | buf[i]; | |
621 if((state&0xFFFFFF1F) == 0x101 || (state&0xFFFFFF1F) == 0x102 || (state&0xFFFFFF1F) == 0x105){ | |
622 if(pc->frame_start_found){ | |
623 pc->state=-1; | |
624 pc->frame_start_found= 0; | |
625 return i-3; | |
626 } | |
627 pc->frame_start_found= 1; | |
628 } | |
629 } | |
630 | |
631 pc->state= state; | |
632 return END_NOT_FOUND; | |
633 } | |
634 | |
635 static int h264_parse(AVCodecParserContext *s, | |
636 AVCodecContext *avctx, | |
637 uint8_t **poutbuf, int *poutbuf_size, | |
638 const uint8_t *buf, int buf_size) | |
639 { | |
640 ParseContext1 *pc = s->priv_data; | |
641 int next; | |
642 | |
643 next= h264_find_frame_end(pc, buf, buf_size); | |
644 | |
645 if (ff_combine_frame1(pc, next, (uint8_t **)&buf, &buf_size) < 0) { | |
646 *poutbuf = NULL; | |
647 *poutbuf_size = 0; | |
648 return buf_size; | |
649 } | |
650 | |
651 *poutbuf = (uint8_t *)buf; | |
652 *poutbuf_size = buf_size; | |
653 return next; | |
654 } | |
655 | |
656 /*************************/ | |
657 | |
658 typedef struct MpegAudioParseContext { | |
659 uint8_t inbuf[MPA_MAX_CODED_FRAME_SIZE]; /* input buffer */ | |
660 uint8_t *inbuf_ptr; | |
661 int frame_size; | |
662 int free_format_frame_size; | |
663 int free_format_next_header; | |
664 } MpegAudioParseContext; | |
665 | |
666 #define MPA_HEADER_SIZE 4 | |
667 | |
668 /* header + layer + bitrate + freq + lsf/mpeg25 */ | |
669 #define SAME_HEADER_MASK \ | |
670 (0xffe00000 | (3 << 17) | (0xf << 12) | (3 << 10) | (3 << 19)) | |
671 | |
672 static int mpegaudio_parse_init(AVCodecParserContext *s1) | |
673 { | |
674 MpegAudioParseContext *s = s1->priv_data; | |
675 s->inbuf_ptr = s->inbuf; | |
676 return 0; | |
677 } | |
678 | |
679 static int mpegaudio_parse(AVCodecParserContext *s1, | |
680 AVCodecContext *avctx, | |
681 uint8_t **poutbuf, int *poutbuf_size, | |
682 const uint8_t *buf, int buf_size) | |
683 { | |
684 MpegAudioParseContext *s = s1->priv_data; | |
685 int len, ret; | |
686 uint32_t header; | |
687 const uint8_t *buf_ptr; | |
688 | |
689 *poutbuf = NULL; | |
690 *poutbuf_size = 0; | |
691 buf_ptr = buf; | |
692 while (buf_size > 0) { | |
693 len = s->inbuf_ptr - s->inbuf; | |
694 if (s->frame_size == 0) { | |
695 /* special case for next header for first frame in free | |
696 format case (XXX: find a simpler method) */ | |
697 if (s->free_format_next_header != 0) { | |
698 s->inbuf[0] = s->free_format_next_header >> 24; | |
699 s->inbuf[1] = s->free_format_next_header >> 16; | |
700 s->inbuf[2] = s->free_format_next_header >> 8; | |
701 s->inbuf[3] = s->free_format_next_header; | |
702 s->inbuf_ptr = s->inbuf + 4; | |
703 s->free_format_next_header = 0; | |
704 goto got_header; | |
705 } | |
706 /* no header seen : find one. We need at least MPA_HEADER_SIZE | |
707 bytes to parse it */ | |
708 len = MPA_HEADER_SIZE - len; | |
709 if (len > buf_size) | |
710 len = buf_size; | |
711 if (len > 0) { | |
712 memcpy(s->inbuf_ptr, buf_ptr, len); | |
713 buf_ptr += len; | |
714 buf_size -= len; | |
715 s->inbuf_ptr += len; | |
716 } | |
717 if ((s->inbuf_ptr - s->inbuf) >= MPA_HEADER_SIZE) { | |
718 got_header: | |
719 header = (s->inbuf[0] << 24) | (s->inbuf[1] << 16) | | |
720 (s->inbuf[2] << 8) | s->inbuf[3]; | |
721 | |
722 ret = mpa_decode_header(avctx, header); | |
723 if (ret < 0) { | |
724 /* no sync found : move by one byte (inefficient, but simple!) */ | |
725 memmove(s->inbuf, s->inbuf + 1, s->inbuf_ptr - s->inbuf - 1); | |
726 s->inbuf_ptr--; | |
727 dprintf("skip %x\n", header); | |
728 /* reset free format frame size to give a chance | |
729 to get a new bitrate */ | |
730 s->free_format_frame_size = 0; | |
731 } else { | |
732 s->frame_size = ret; | |
733 #if 0 | |
734 /* free format: prepare to compute frame size */ | |
735 if (decode_header(s, header) == 1) { | |
736 s->frame_size = -1; | |
737 } | |
738 #endif | |
739 } | |
740 } | |
741 } else | |
742 #if 0 | |
743 if (s->frame_size == -1) { | |
744 /* free format : find next sync to compute frame size */ | |
745 len = MPA_MAX_CODED_FRAME_SIZE - len; | |
746 if (len > buf_size) | |
747 len = buf_size; | |
748 if (len == 0) { | |
749 /* frame too long: resync */ | |
750 s->frame_size = 0; | |
751 memmove(s->inbuf, s->inbuf + 1, s->inbuf_ptr - s->inbuf - 1); | |
752 s->inbuf_ptr--; | |
753 } else { | |
754 uint8_t *p, *pend; | |
755 uint32_t header1; | |
756 int padding; | |
757 | |
758 memcpy(s->inbuf_ptr, buf_ptr, len); | |
759 /* check for header */ | |
760 p = s->inbuf_ptr - 3; | |
761 pend = s->inbuf_ptr + len - 4; | |
762 while (p <= pend) { | |
763 header = (p[0] << 24) | (p[1] << 16) | | |
764 (p[2] << 8) | p[3]; | |
765 header1 = (s->inbuf[0] << 24) | (s->inbuf[1] << 16) | | |
766 (s->inbuf[2] << 8) | s->inbuf[3]; | |
767 /* check with high probability that we have a | |
768 valid header */ | |
769 if ((header & SAME_HEADER_MASK) == | |
770 (header1 & SAME_HEADER_MASK)) { | |
771 /* header found: update pointers */ | |
772 len = (p + 4) - s->inbuf_ptr; | |
773 buf_ptr += len; | |
774 buf_size -= len; | |
775 s->inbuf_ptr = p; | |
776 /* compute frame size */ | |
777 s->free_format_next_header = header; | |
778 s->free_format_frame_size = s->inbuf_ptr - s->inbuf; | |
779 padding = (header1 >> 9) & 1; | |
780 if (s->layer == 1) | |
781 s->free_format_frame_size -= padding * 4; | |
782 else | |
783 s->free_format_frame_size -= padding; | |
784 dprintf("free frame size=%d padding=%d\n", | |
785 s->free_format_frame_size, padding); | |
786 decode_header(s, header1); | |
787 goto next_data; | |
788 } | |
789 p++; | |
790 } | |
791 /* not found: simply increase pointers */ | |
792 buf_ptr += len; | |
793 s->inbuf_ptr += len; | |
794 buf_size -= len; | |
795 } | |
796 } else | |
797 #endif | |
798 if (len < s->frame_size) { | |
799 if (s->frame_size > MPA_MAX_CODED_FRAME_SIZE) | |
800 s->frame_size = MPA_MAX_CODED_FRAME_SIZE; | |
801 len = s->frame_size - len; | |
802 if (len > buf_size) | |
803 len = buf_size; | |
804 memcpy(s->inbuf_ptr, buf_ptr, len); | |
805 buf_ptr += len; | |
806 s->inbuf_ptr += len; | |
807 buf_size -= len; | |
808 } | |
809 // next_data: | |
810 if (s->frame_size > 0 && | |
811 (s->inbuf_ptr - s->inbuf) >= s->frame_size) { | |
812 *poutbuf = s->inbuf; | |
813 *poutbuf_size = s->inbuf_ptr - s->inbuf; | |
814 s->inbuf_ptr = s->inbuf; | |
815 s->frame_size = 0; | |
816 break; | |
817 } | |
818 } | |
819 return buf_ptr - buf; | |
820 } | |
821 | |
822 #ifdef CONFIG_AC3 | |
823 extern int a52_syncinfo (const uint8_t * buf, int * flags, | |
824 int * sample_rate, int * bit_rate); | |
825 | |
826 typedef struct AC3ParseContext { | |
827 uint8_t inbuf[4096]; /* input buffer */ | |
828 uint8_t *inbuf_ptr; | |
829 int frame_size; | |
830 int flags; | |
831 } AC3ParseContext; | |
832 | |
833 #define AC3_HEADER_SIZE 7 | |
834 #define A52_LFE 16 | |
835 | |
836 static int ac3_parse_init(AVCodecParserContext *s1) | |
837 { | |
838 AC3ParseContext *s = s1->priv_data; | |
839 s->inbuf_ptr = s->inbuf; | |
840 return 0; | |
841 } | |
842 | |
843 static int ac3_parse(AVCodecParserContext *s1, | |
844 AVCodecContext *avctx, | |
845 uint8_t **poutbuf, int *poutbuf_size, | |
846 const uint8_t *buf, int buf_size) | |
847 { | |
848 AC3ParseContext *s = s1->priv_data; | |
849 const uint8_t *buf_ptr; | |
850 int len, sample_rate, bit_rate; | |
851 static const int ac3_channels[8] = { | |
852 2, 1, 2, 3, 3, 4, 4, 5 | |
853 }; | |
854 | |
855 *poutbuf = NULL; | |
856 *poutbuf_size = 0; | |
857 | |
858 buf_ptr = buf; | |
859 while (buf_size > 0) { | |
860 len = s->inbuf_ptr - s->inbuf; | |
861 if (s->frame_size == 0) { | |
862 /* no header seen : find one. We need at least 7 bytes to parse it */ | |
863 len = AC3_HEADER_SIZE - len; | |
864 if (len > buf_size) | |
865 len = buf_size; | |
866 memcpy(s->inbuf_ptr, buf_ptr, len); | |
867 buf_ptr += len; | |
868 s->inbuf_ptr += len; | |
869 buf_size -= len; | |
870 if ((s->inbuf_ptr - s->inbuf) == AC3_HEADER_SIZE) { | |
871 len = a52_syncinfo(s->inbuf, &s->flags, &sample_rate, &bit_rate); | |
872 if (len == 0) { | |
873 /* no sync found : move by one byte (inefficient, but simple!) */ | |
874 memmove(s->inbuf, s->inbuf + 1, AC3_HEADER_SIZE - 1); | |
875 s->inbuf_ptr--; | |
876 } else { | |
877 s->frame_size = len; | |
878 /* update codec info */ | |
879 avctx->sample_rate = sample_rate; | |
880 avctx->channels = ac3_channels[s->flags & 7]; | |
881 if (s->flags & A52_LFE) | |
882 avctx->channels++; | |
883 avctx->bit_rate = bit_rate; | |
884 avctx->frame_size = 6 * 256; | |
885 } | |
886 } | |
887 } else if (len < s->frame_size) { | |
888 len = s->frame_size - len; | |
889 if (len > buf_size) | |
890 len = buf_size; | |
891 | |
892 memcpy(s->inbuf_ptr, buf_ptr, len); | |
893 buf_ptr += len; | |
894 s->inbuf_ptr += len; | |
895 buf_size -= len; | |
896 } else { | |
897 *poutbuf = s->inbuf; | |
898 *poutbuf_size = s->frame_size; | |
899 s->inbuf_ptr = s->inbuf; | |
900 s->frame_size = 0; | |
901 break; | |
902 } | |
903 } | |
904 return buf_ptr - buf; | |
905 } | |
906 #endif | |
907 | |
908 AVCodecParser mpegvideo_parser = { | |
909 { CODEC_ID_MPEG1VIDEO, CODEC_ID_MPEG2VIDEO }, | |
910 sizeof(ParseContext1), | |
911 NULL, | |
912 mpegvideo_parse, | |
913 mpegvideo_parse_close, | |
914 }; | |
915 | |
916 AVCodecParser mpeg4video_parser = { | |
917 { CODEC_ID_MPEG4 }, | |
918 sizeof(ParseContext1), | |
919 mpeg4video_parse_init, | |
920 mpeg4video_parse, | |
921 mpegvideo_parse_close, | |
922 }; | |
923 | |
924 AVCodecParser h263_parser = { | |
925 { CODEC_ID_H263 }, | |
926 sizeof(ParseContext1), | |
927 NULL, | |
928 h263_parse, | |
929 mpegvideo_parse_close, | |
930 }; | |
931 | |
932 AVCodecParser h264_parser = { | |
933 { CODEC_ID_H264 }, | |
934 sizeof(ParseContext1), | |
935 NULL, | |
936 h264_parse, | |
937 mpegvideo_parse_close, | |
938 }; | |
939 | |
940 AVCodecParser mpegaudio_parser = { | |
941 { CODEC_ID_MP2, CODEC_ID_MP3 }, | |
942 sizeof(MpegAudioParseContext), | |
943 mpegaudio_parse_init, | |
944 mpegaudio_parse, | |
945 NULL, | |
946 }; | |
947 | |
948 #ifdef CONFIG_AC3 | |
949 AVCodecParser ac3_parser = { | |
950 { CODEC_ID_AC3 }, | |
951 sizeof(AC3ParseContext), | |
952 ac3_parse_init, | |
953 ac3_parse, | |
954 NULL, | |
955 }; | |
956 #endif |