Mercurial > libavcodec.hg
comparison parser.c @ 4150:2205aefb22b7 libavcodec
move AVCodecParser prototypes and definitions to parser.h, and move mpegvideo parser to mpeg12.c
author | bcoudurier |
---|---|
date | Mon, 06 Nov 2006 10:43:49 +0000 |
parents | c09e31f70a30 |
children | b3328ed50a5e |
comparison
equal
deleted
inserted
replaced
4149:3118e8afb8a5 | 4150:2205aefb22b7 |
---|---|
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | 20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
21 */ | 21 */ |
22 #include "avcodec.h" | 22 #include "avcodec.h" |
23 #include "mpegvideo.h" | 23 #include "mpegvideo.h" |
24 #include "mpegaudio.h" | 24 #include "mpegaudio.h" |
25 #include "parser.h" | |
25 | 26 |
26 AVCodecParser *av_first_parser = NULL; | 27 AVCodecParser *av_first_parser = NULL; |
27 | 28 |
28 void av_register_codec_parser(AVCodecParser *parser) | 29 void av_register_codec_parser(AVCodecParser *parser) |
29 { | 30 { |
211 av_free(s); | 212 av_free(s); |
212 } | 213 } |
213 | 214 |
214 /*****************************************************/ | 215 /*****************************************************/ |
215 | 216 |
216 //#define END_NOT_FOUND (-100) | |
217 | |
218 #define PICTURE_START_CODE 0x00000100 | |
219 #define SEQ_START_CODE 0x000001b3 | |
220 #define EXT_START_CODE 0x000001b5 | |
221 #define SLICE_MIN_START_CODE 0x00000101 | |
222 #define SLICE_MAX_START_CODE 0x000001af | |
223 | |
224 typedef struct ParseContext1{ | |
225 ParseContext pc; | |
226 /* XXX/FIXME PC1 vs. PC */ | |
227 /* MPEG2 specific */ | |
228 AVRational frame_rate; | |
229 int progressive_sequence; | |
230 int width, height; | |
231 | |
232 /* XXX: suppress that, needed by MPEG4 */ | |
233 MpegEncContext *enc; | |
234 int first_picture; | |
235 } ParseContext1; | |
236 | |
237 /** | 217 /** |
238 * combines the (truncated) bitstream to a complete frame | 218 * combines the (truncated) bitstream to a complete frame |
239 * @returns -1 if no complete frame could be created | 219 * @returns -1 if no complete frame could be created |
240 */ | 220 */ |
241 int ff_combine_frame(ParseContext *pc, int next, uint8_t **buf, int *buf_size) | 221 int ff_combine_frame(ParseContext *pc, int next, uint8_t **buf, int *buf_size) |
294 #endif | 274 #endif |
295 | 275 |
296 return 0; | 276 return 0; |
297 } | 277 } |
298 | 278 |
299 #ifdef CONFIG_MPEGVIDEO_PARSER | |
300 | |
301 extern const AVRational ff_frame_rate_tab[]; | |
302 | |
303 //FIXME move into mpeg12.c | |
304 static void mpegvideo_extract_headers(AVCodecParserContext *s, | |
305 AVCodecContext *avctx, | |
306 const uint8_t *buf, int buf_size) | |
307 { | |
308 ParseContext1 *pc = s->priv_data; | |
309 const uint8_t *buf_end; | |
310 uint32_t start_code; | |
311 int frame_rate_index, ext_type, bytes_left; | |
312 int frame_rate_ext_n, frame_rate_ext_d; | |
313 int picture_structure, top_field_first, repeat_first_field, progressive_frame; | |
314 int horiz_size_ext, vert_size_ext, bit_rate_ext; | |
315 //FIXME replace the crap with get_bits() | |
316 s->repeat_pict = 0; | |
317 buf_end = buf + buf_size; | |
318 while (buf < buf_end) { | |
319 start_code= -1; | |
320 buf= ff_find_start_code(buf, buf_end, &start_code); | |
321 bytes_left = buf_end - buf; | |
322 switch(start_code) { | |
323 case PICTURE_START_CODE: | |
324 if (bytes_left >= 2) { | |
325 s->pict_type = (buf[1] >> 3) & 7; | |
326 } | |
327 break; | |
328 case SEQ_START_CODE: | |
329 if (bytes_left >= 7) { | |
330 pc->width = (buf[0] << 4) | (buf[1] >> 4); | |
331 pc->height = ((buf[1] & 0x0f) << 8) | buf[2]; | |
332 avcodec_set_dimensions(avctx, pc->width, pc->height); | |
333 frame_rate_index = buf[3] & 0xf; | |
334 pc->frame_rate.den = avctx->time_base.den = ff_frame_rate_tab[frame_rate_index].num; | |
335 pc->frame_rate.num = avctx->time_base.num = ff_frame_rate_tab[frame_rate_index].den; | |
336 avctx->bit_rate = ((buf[4]<<10) | (buf[5]<<2) | (buf[6]>>6))*400; | |
337 avctx->codec_id = CODEC_ID_MPEG1VIDEO; | |
338 avctx->sub_id = 1; | |
339 } | |
340 break; | |
341 case EXT_START_CODE: | |
342 if (bytes_left >= 1) { | |
343 ext_type = (buf[0] >> 4); | |
344 switch(ext_type) { | |
345 case 0x1: /* sequence extension */ | |
346 if (bytes_left >= 6) { | |
347 horiz_size_ext = ((buf[1] & 1) << 1) | (buf[2] >> 7); | |
348 vert_size_ext = (buf[2] >> 5) & 3; | |
349 bit_rate_ext = ((buf[2] & 0x1F)<<7) | (buf[3]>>1); | |
350 frame_rate_ext_n = (buf[5] >> 5) & 3; | |
351 frame_rate_ext_d = (buf[5] & 0x1f); | |
352 pc->progressive_sequence = buf[1] & (1 << 3); | |
353 avctx->has_b_frames= !(buf[5] >> 7); | |
354 | |
355 pc->width |=(horiz_size_ext << 12); | |
356 pc->height |=( vert_size_ext << 12); | |
357 avctx->bit_rate += (bit_rate_ext << 18) * 400; | |
358 avcodec_set_dimensions(avctx, pc->width, pc->height); | |
359 avctx->time_base.den = pc->frame_rate.den * (frame_rate_ext_n + 1); | |
360 avctx->time_base.num = pc->frame_rate.num * (frame_rate_ext_d + 1); | |
361 avctx->codec_id = CODEC_ID_MPEG2VIDEO; | |
362 avctx->sub_id = 2; /* forces MPEG2 */ | |
363 } | |
364 break; | |
365 case 0x8: /* picture coding extension */ | |
366 if (bytes_left >= 5) { | |
367 picture_structure = buf[2]&3; | |
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 /* the packet only represents half a frame | |
385 XXX,FIXME maybe find a different solution */ | |
386 if(picture_structure != 3) | |
387 s->repeat_pict = -1; | |
388 } | |
389 break; | |
390 } | |
391 } | |
392 break; | |
393 case -1: | |
394 goto the_end; | |
395 default: | |
396 /* we stop parsing when we encounter a slice. It ensures | |
397 that this function takes a negligible amount of time */ | |
398 if (start_code >= SLICE_MIN_START_CODE && | |
399 start_code <= SLICE_MAX_START_CODE) | |
400 goto the_end; | |
401 break; | |
402 } | |
403 } | |
404 the_end: ; | |
405 } | |
406 | |
407 static int mpegvideo_parse(AVCodecParserContext *s, | |
408 AVCodecContext *avctx, | |
409 uint8_t **poutbuf, int *poutbuf_size, | |
410 const uint8_t *buf, int buf_size) | |
411 { | |
412 ParseContext1 *pc1 = s->priv_data; | |
413 ParseContext *pc= &pc1->pc; | |
414 int next; | |
415 | |
416 if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){ | |
417 next= buf_size; | |
418 }else{ | |
419 next= ff_mpeg1_find_frame_end(pc, buf, buf_size); | |
420 | |
421 if (ff_combine_frame(pc, next, (uint8_t **)&buf, &buf_size) < 0) { | |
422 *poutbuf = NULL; | |
423 *poutbuf_size = 0; | |
424 return buf_size; | |
425 } | |
426 | |
427 } | |
428 /* we have a full frame : we just parse the first few MPEG headers | |
429 to have the full timing information. The time take by this | |
430 function should be negligible for uncorrupted streams */ | |
431 mpegvideo_extract_headers(s, avctx, buf, buf_size); | |
432 #if 0 | |
433 printf("pict_type=%d frame_rate=%0.3f repeat_pict=%d\n", | |
434 s->pict_type, (double)avctx->time_base.den / avctx->time_base.num, s->repeat_pict); | |
435 #endif | |
436 | |
437 *poutbuf = (uint8_t *)buf; | |
438 *poutbuf_size = buf_size; | |
439 return next; | |
440 } | |
441 | |
442 static int mpegvideo_split(AVCodecContext *avctx, | |
443 const uint8_t *buf, int buf_size) | |
444 { | |
445 int i; | |
446 uint32_t state= -1; | |
447 | |
448 for(i=0; i<buf_size; i++){ | |
449 state= (state<<8) | buf[i]; | |
450 if(state != 0x1B3 && state != 0x1B5 && state < 0x200 && state >= 0x100) | |
451 return i-3; | |
452 } | |
453 return 0; | |
454 } | |
455 #endif /* CONFIG_MPEGVIDEO_PARSER */ | |
456 | |
457 void ff_parse_close(AVCodecParserContext *s) | 279 void ff_parse_close(AVCodecParserContext *s) |
458 { | 280 { |
459 ParseContext *pc = s->priv_data; | 281 ParseContext *pc = s->priv_data; |
460 | 282 |
461 av_free(pc->buffer); | 283 av_free(pc->buffer); |
462 } | 284 } |
463 | 285 |
464 static void parse1_close(AVCodecParserContext *s) | 286 void ff_parse1_close(AVCodecParserContext *s) |
465 { | 287 { |
466 ParseContext1 *pc1 = s->priv_data; | 288 ParseContext1 *pc1 = s->priv_data; |
467 | 289 |
468 av_free(pc1->pc.buffer); | 290 av_free(pc1->pc.buffer); |
469 av_free(pc1->enc); | 291 av_free(pc1->enc); |
1023 } | 845 } |
1024 return buf_ptr - buf; | 846 return buf_ptr - buf; |
1025 } | 847 } |
1026 #endif /* CONFIG_AC3_PARSER || CONFIG_AAC_PARSER */ | 848 #endif /* CONFIG_AC3_PARSER || CONFIG_AAC_PARSER */ |
1027 | 849 |
1028 #ifdef CONFIG_MPEGVIDEO_PARSER | |
1029 AVCodecParser mpegvideo_parser = { | |
1030 { CODEC_ID_MPEG1VIDEO, CODEC_ID_MPEG2VIDEO }, | |
1031 sizeof(ParseContext1), | |
1032 NULL, | |
1033 mpegvideo_parse, | |
1034 parse1_close, | |
1035 mpegvideo_split, | |
1036 }; | |
1037 #endif | |
1038 #ifdef CONFIG_MPEG4VIDEO_PARSER | 850 #ifdef CONFIG_MPEG4VIDEO_PARSER |
1039 AVCodecParser mpeg4video_parser = { | 851 AVCodecParser mpeg4video_parser = { |
1040 { CODEC_ID_MPEG4 }, | 852 { CODEC_ID_MPEG4 }, |
1041 sizeof(ParseContext1), | 853 sizeof(ParseContext1), |
1042 mpeg4video_parse_init, | 854 mpeg4video_parse_init, |
1043 mpeg4video_parse, | 855 mpeg4video_parse, |
1044 parse1_close, | 856 ff_parse1_close, |
1045 mpeg4video_split, | 857 mpeg4video_split, |
1046 }; | 858 }; |
1047 #endif | 859 #endif |
1048 #ifdef CONFIG_CAVSVIDEO_PARSER | 860 #ifdef CONFIG_CAVSVIDEO_PARSER |
1049 AVCodecParser cavsvideo_parser = { | 861 AVCodecParser cavsvideo_parser = { |
1050 { CODEC_ID_CAVS }, | 862 { CODEC_ID_CAVS }, |
1051 sizeof(ParseContext1), | 863 sizeof(ParseContext1), |
1052 NULL, | 864 NULL, |
1053 cavsvideo_parse, | 865 cavsvideo_parse, |
1054 parse1_close, | 866 ff_parse1_close, |
1055 mpeg4video_split, | 867 mpeg4video_split, |
1056 }; | 868 }; |
1057 #endif | 869 #endif |
1058 #ifdef CONFIG_MPEGAUDIO_PARSER | 870 #ifdef CONFIG_MPEGAUDIO_PARSER |
1059 AVCodecParser mpegaudio_parser = { | 871 AVCodecParser mpegaudio_parser = { |