comparison mpeg12.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 85438e10d72d
children 93baab5a86d2
comparison
equal deleted inserted replaced
4149:3118e8afb8a5 4150:2205aefb22b7
3310 .flush= ff_mpeg_flush, 3310 .flush= ff_mpeg_flush,
3311 }; 3311 };
3312 3312
3313 #endif 3313 #endif
3314 3314
3315 #ifdef CONFIG_MPEGVIDEO_PARSER
3316 static void mpegvideo_extract_headers(AVCodecParserContext *s,
3317 AVCodecContext *avctx,
3318 const uint8_t *buf, int buf_size)
3319 {
3320 ParseContext1 *pc = s->priv_data;
3321 const uint8_t *buf_end;
3322 uint32_t start_code;
3323 int frame_rate_index, ext_type, bytes_left;
3324 int frame_rate_ext_n, frame_rate_ext_d;
3325 int picture_structure, top_field_first, repeat_first_field, progressive_frame;
3326 int horiz_size_ext, vert_size_ext, bit_rate_ext;
3327 //FIXME replace the crap with get_bits()
3328 s->repeat_pict = 0;
3329 buf_end = buf + buf_size;
3330 while (buf < buf_end) {
3331 start_code= -1;
3332 buf= ff_find_start_code(buf, buf_end, &start_code);
3333 bytes_left = buf_end - buf;
3334 switch(start_code) {
3335 case PICTURE_START_CODE:
3336 if (bytes_left >= 2) {
3337 s->pict_type = (buf[1] >> 3) & 7;
3338 }
3339 break;
3340 case SEQ_START_CODE:
3341 if (bytes_left >= 7) {
3342 pc->width = (buf[0] << 4) | (buf[1] >> 4);
3343 pc->height = ((buf[1] & 0x0f) << 8) | buf[2];
3344 avcodec_set_dimensions(avctx, pc->width, pc->height);
3345 frame_rate_index = buf[3] & 0xf;
3346 pc->frame_rate.den = avctx->time_base.den = ff_frame_rate_tab[frame_rate_index].num;
3347 pc->frame_rate.num = avctx->time_base.num = ff_frame_rate_tab[frame_rate_index].den;
3348 avctx->bit_rate = ((buf[4]<<10) | (buf[5]<<2) | (buf[6]>>6))*400;
3349 avctx->codec_id = CODEC_ID_MPEG1VIDEO;
3350 avctx->sub_id = 1;
3351 }
3352 break;
3353 case EXT_START_CODE:
3354 if (bytes_left >= 1) {
3355 ext_type = (buf[0] >> 4);
3356 switch(ext_type) {
3357 case 0x1: /* sequence extension */
3358 if (bytes_left >= 6) {
3359 horiz_size_ext = ((buf[1] & 1) << 1) | (buf[2] >> 7);
3360 vert_size_ext = (buf[2] >> 5) & 3;
3361 bit_rate_ext = ((buf[2] & 0x1F)<<7) | (buf[3]>>1);
3362 frame_rate_ext_n = (buf[5] >> 5) & 3;
3363 frame_rate_ext_d = (buf[5] & 0x1f);
3364 pc->progressive_sequence = buf[1] & (1 << 3);
3365 avctx->has_b_frames= !(buf[5] >> 7);
3366
3367 pc->width |=(horiz_size_ext << 12);
3368 pc->height |=( vert_size_ext << 12);
3369 avctx->bit_rate += (bit_rate_ext << 18) * 400;
3370 avcodec_set_dimensions(avctx, pc->width, pc->height);
3371 avctx->time_base.den = pc->frame_rate.den * (frame_rate_ext_n + 1);
3372 avctx->time_base.num = pc->frame_rate.num * (frame_rate_ext_d + 1);
3373 avctx->codec_id = CODEC_ID_MPEG2VIDEO;
3374 avctx->sub_id = 2; /* forces MPEG2 */
3375 }
3376 break;
3377 case 0x8: /* picture coding extension */
3378 if (bytes_left >= 5) {
3379 picture_structure = buf[2]&3;
3380 top_field_first = buf[3] & (1 << 7);
3381 repeat_first_field = buf[3] & (1 << 1);
3382 progressive_frame = buf[4] & (1 << 7);
3383
3384 /* check if we must repeat the frame */
3385 if (repeat_first_field) {
3386 if (pc->progressive_sequence) {
3387 if (top_field_first)
3388 s->repeat_pict = 4;
3389 else
3390 s->repeat_pict = 2;
3391 } else if (progressive_frame) {
3392 s->repeat_pict = 1;
3393 }
3394 }
3395
3396 /* the packet only represents half a frame
3397 XXX,FIXME maybe find a different solution */
3398 if(picture_structure != 3)
3399 s->repeat_pict = -1;
3400 }
3401 break;
3402 }
3403 }
3404 break;
3405 case -1:
3406 goto the_end;
3407 default:
3408 /* we stop parsing when we encounter a slice. It ensures
3409 that this function takes a negligible amount of time */
3410 if (start_code >= SLICE_MIN_START_CODE &&
3411 start_code <= SLICE_MAX_START_CODE)
3412 goto the_end;
3413 break;
3414 }
3415 }
3416 the_end: ;
3417 }
3418
3419 static int mpegvideo_parse(AVCodecParserContext *s,
3420 AVCodecContext *avctx,
3421 uint8_t **poutbuf, int *poutbuf_size,
3422 const uint8_t *buf, int buf_size)
3423 {
3424 ParseContext1 *pc1 = s->priv_data;
3425 ParseContext *pc= &pc1->pc;
3426 int next;
3427
3428 if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){
3429 next= buf_size;
3430 }else{
3431 next= ff_mpeg1_find_frame_end(pc, buf, buf_size);
3432
3433 if (ff_combine_frame(pc, next, (uint8_t **)&buf, &buf_size) < 0) {
3434 *poutbuf = NULL;
3435 *poutbuf_size = 0;
3436 return buf_size;
3437 }
3438
3439 }
3440 /* we have a full frame : we just parse the first few MPEG headers
3441 to have the full timing information. The time take by this
3442 function should be negligible for uncorrupted streams */
3443 mpegvideo_extract_headers(s, avctx, buf, buf_size);
3444 #if 0
3445 printf("pict_type=%d frame_rate=%0.3f repeat_pict=%d\n",
3446 s->pict_type, (double)avctx->time_base.den / avctx->time_base.num, s->repeat_pict);
3447 #endif
3448
3449 *poutbuf = (uint8_t *)buf;
3450 *poutbuf_size = buf_size;
3451 return next;
3452 }
3453
3454 static int mpegvideo_split(AVCodecContext *avctx,
3455 const uint8_t *buf, int buf_size)
3456 {
3457 int i;
3458 uint32_t state= -1;
3459
3460 for(i=0; i<buf_size; i++){
3461 state= (state<<8) | buf[i];
3462 if(state != 0x1B3 && state != 0x1B5 && state < 0x200 && state >= 0x100)
3463 return i-3;
3464 }
3465 return 0;
3466 }
3467
3468 AVCodecParser mpegvideo_parser = {
3469 { CODEC_ID_MPEG1VIDEO, CODEC_ID_MPEG2VIDEO },
3470 sizeof(ParseContext1),
3471 NULL,
3472 mpegvideo_parse,
3473 ff_parse1_close,
3474 mpegvideo_split,
3475 };
3476 #endif /* !CONFIG_MPEGVIDEO_PARSER */
3477
3315 /* this is ugly i know, but the alternative is too make 3478 /* this is ugly i know, but the alternative is too make
3316 hundreds of vars global and prefix them with ff_mpeg1_ 3479 hundreds of vars global and prefix them with ff_mpeg1_
3317 which is far uglier. */ 3480 which is far uglier. */
3318 #include "mdec.c" 3481 #include "mdec.c"