X-Git-Url: http://git.osdn.jp/view?a=blobdiff_plain;f=libhb%2Fdecmpeg2.c;h=e2deae0ceebaaf7f82d57eac8e804fde584d36f0;hb=34d71bfabf0ae29e7124d144d12cfcbb786d5df5;hp=4fb6ad76b4c3c933e1659150fe548024f864bf35;hpb=c7d8a4c93c59999481f91333ebdebde830575dbf;p=handbrake-jp%2Fhandbrake-jp-git.git diff --git a/libhb/decmpeg2.c b/libhb/decmpeg2.c index 4fb6ad76..e2deae0c 100644 --- a/libhb/decmpeg2.c +++ b/libhb/decmpeg2.c @@ -8,6 +8,26 @@ #include "mpeg2dec/mpeg2.h" +/* Cadence tracking */ +#ifndef PIC_FLAG_REPEAT_FIRST_FIELD +#define PIC_FLAG_REPEAT_FIRST_FIELD 256 +#endif +#define TOP_FIRST PIC_FLAG_TOP_FIELD_FIRST +#define PROGRESSIVE PIC_FLAG_PROGRESSIVE_FRAME +#define COMPOSITE PIC_FLAG_COMPOSITE_DISPLAY +#define SKIP PIC_FLAG_SKIP +#define TAGS PIC_FLAG_TAGS +#define REPEAT_FIRST PIC_FLAG_REPEAT_FIRST_FIELD +#define COMPOSITE_MASK PIC_MASK_COMPOSITE_DISPLAY +#define TB 8 +#define BT 16 +#define BT_PROG 32 +#define BTB_PROG 64 +#define TB_PROG 128 +#define TBT_PROG 256 +int cadence[12]; +int flag = 0; + /********************************************************************** * hb_libmpeg2_t ********************************************************************** @@ -20,6 +40,7 @@ struct hb_libmpeg2_s int width; int height; int rate; + int aspect_ratio; int got_iframe; int look_for_break; int64_t last_pts; @@ -79,19 +100,33 @@ int hb_libmpeg2_decode( hb_libmpeg2_t * m, hb_buffer_t * buf_es, m->width = m->info->sequence->width; m->height = m->info->sequence->height; m->rate = m->info->sequence->frame_period; - - if( m->rate == 900900 ) + } + if ( m->aspect_ratio <= 0 ) + { + // We can parse out the aspect ratio from the Sequence Start Header data in buf_es->data + + // Make sure we have the correct data in the buffer + if ((buf_es->data[0] == 0x00) && (buf_es->data[1] == 0x00) && (buf_es->data[2] == 0x01) && (buf_es->data[3] == 0xb3)) + { + unsigned char ar_fr = buf_es->data[7]; // Top 4 bits == aspect ratio flag - bottom 4 bits == rate flags + switch ((ar_fr & 0xf0) >> 4) { - /* 29.97 fps. 3:2 pulldown might, or might not be - used. I can't find a way to know, so we always - output 23.976 */ - m->rate = 1126125; + case 2: + m->aspect_ratio = HB_ASPECT_BASE * 4 / 3; // 4:3 + break; + case 3: + m->aspect_ratio = HB_ASPECT_BASE * 16 / 9; // 16:9 + break; + default: + hb_log("hb_libmpeg2_decode - STATE_SEQUENCE unexpected aspect ratio/frame rate 0x%x\n", ar_fr); + break; } + } } } else if( state == STATE_GOP && m->look_for_break == 2) { - printf("MPEG2: Group of pictures found, searching for I-Frame\n"); + hb_log("MPEG2: Group of pictures found, searching for I-Frame"); m->look_for_break = 1; } else if( ( state == STATE_SLICE || state == STATE_END ) && @@ -105,7 +140,7 @@ int hb_libmpeg2_decode( hb_libmpeg2_t * m, hb_buffer_t * buf_es, // If we are looking for a break, insert the chapter break on an I-Frame if( m->look_for_break == 1 ) { - printf("MPEG2: I-Frame Found\n"); + hb_log("MPEG2: I-Frame Found"); m->look_for_break = 0; chap_break = 1; } @@ -116,10 +151,12 @@ int hb_libmpeg2_decode( hb_libmpeg2_t * m, hb_buffer_t * buf_es, buf = hb_buffer_init( m->width * m->height * 3 / 2 ); data = buf->data; + buf->sequence = buf_es->sequence; + // Was a good break point found? if( chap_break ) { - printf("MPEG2: Chapter Break Inserted\n"); + hb_log("MPEG2: Chapter Break Inserted"); chap_break = 0; buf->new_chap = 1; } @@ -138,6 +175,10 @@ int hb_libmpeg2_decode( hb_libmpeg2_t * m, hb_buffer_t * buf_es, buf->start = ( (uint64_t) m->info->display_picture->tag << 32 ) | ( (uint64_t) m->info->display_picture->tag2 ); + /* + * Add back in again to track PTS of MPEG2 frames + * hb_log("MPEG2: Normal buf->start = %lld", buf->start); + */ } else if( m->last_pts > -1 ) { @@ -153,6 +194,95 @@ int hb_libmpeg2_decode( hb_libmpeg2_t * m, hb_buffer_t * buf_es, } m->last_pts = buf->start; + flag = m->info->display_picture->flags; + +/* Uncomment this block to see frame-by-frame picture flags, as the video encodes. + hb_log("***** MPEG 2 Picture Info for PTS %lld *****", buf->start); + if( flag & TOP_FIRST ) + hb_log("MPEG2 Flag: Top field first"); + if( flag & PROGRESSIVE ) + hb_log("MPEG2 Flag: Progressive"); + if( flag & COMPOSITE ) + hb_log("MPEG2 Flag: Composite"); + if( flag & SKIP ) + hb_log("MPEG2 Flag: Skip!"); + if( flag & TAGS ) + hb_log("MPEG2 Flag: TAGS"); + if(flag & REPEAT_FIRST ) + hb_log("MPEG2 Flag: Repeat first field"); + if( flag & COMPOSITE_MASK ) + hb_log("MPEG2 Flag: Composite mask"); + hb_log("fields: %d", m->info->display_picture->nb_fields); +*/ + /* Rotate the cadence tracking. */ + int i = 0; + for(i=11; i > 0; i--) + { + cadence[i] = cadence[i-1]; + } + + if ( !(flag & PROGRESSIVE) && !(flag & TOP_FIRST) ) + { + /* Not progressive, not top first... + That means it's probably bottom + first, 2 fields displayed. + */ + //hb_log("MPEG2 Flag: Bottom field first, 2 fields displayed."); + cadence[0] = BT; + } + else if ( !(flag & PROGRESSIVE) && (flag & TOP_FIRST) ) + { + /* Not progressive, top is first, + Two fields displayed. + */ + //hb_log("MPEG2 Flag: Top field first, 2 fields displayed."); + cadence[0] = TB; + } + else if ( (flag & PROGRESSIVE) && !(flag & TOP_FIRST) && !( flag & REPEAT_FIRST ) ) + { + /* Progressive, but noting else. + That means Bottom first, + 2 fields displayed. + */ + //hb_log("MPEG2 Flag: Progressive. Bottom field first, 2 fields displayed."); + cadence[0] = BT_PROG; + } + else if ( (flag & PROGRESSIVE) && !(flag & TOP_FIRST) && ( flag & REPEAT_FIRST ) ) + { + /* Progressive, and repeat. . + That means Bottom first, + 3 fields displayed. + */ + //hb_log("MPEG2 Flag: Progressive repeat. Bottom field first, 3 fields displayed."); + cadence[0] = BTB_PROG; + } + else if ( (flag & PROGRESSIVE) && (flag & TOP_FIRST) && !( flag & REPEAT_FIRST ) ) + { + /* Progressive, top first. + That means top first, + 2 fields displayed. + */ + //hb_log("MPEG2 Flag: Progressive. Top field first, 2 fields displayed."); + cadence[0] = TB_PROG; + } + else if ( (flag & PROGRESSIVE) && (flag & TOP_FIRST) && ( flag & REPEAT_FIRST ) ) + { + /* Progressive, top, repeat. + That means top first, + 3 fields displayed. + */ + //hb_log("MPEG2 Flag: Progressive repeat. Top field first, 3 fields displayed."); + cadence[0] = TBT_PROG; + } + + if ( (cadence[2] <= TB) && (cadence[1] <= TB) && (cadence[0] > TB) && (cadence[11]) ) + hb_log("%fs: Interlaced -> Progressive", (float)buf->start / 90000); + if ( (cadence[2] > TB) && (cadence[1] <= TB) && (cadence[0] <= TB) && (cadence[11]) ) + hb_log("%fs: Progressive -> Interlaced", (float)buf->start / 90000); + + /* Store picture flags for later use by filters */ + buf->flags = m->info->display_picture->flags; + hb_list_add( list_raw, buf ); } } @@ -170,11 +300,25 @@ int hb_libmpeg2_decode( hb_libmpeg2_t * m, hb_buffer_t * buf_es, * *********************************************************************/ void hb_libmpeg2_info( hb_libmpeg2_t * m, int * width, int * height, - int * rate ) + int * rate, int *aspect_ratio ) { *width = m->width; *height = m->height; + if (m->info->display_fbuf) + { + if( (m->info->display_picture->flags & PROGRESSIVE) && (m->height == 480) ) + { + /* The frame is progressive and it's NTSC DVD height, so change its FPS to 23.976. + This might not be correct for the title. It's really just for scan.c's benefit. + Scan.c will reset the fps to 29.97, until a simple majority of the preview + frames report at 23.976. + */ + //hb_log("Detecting NTSC Progressive Frame"); + m->rate = 1126125; + } + } *rate = m->rate; + *aspect_ratio = m->aspect_ratio; } /********************************************************************** @@ -236,7 +380,7 @@ int decmpeg2Work( hb_work_object_t * w, hb_buffer_t ** buf_in, // stream. We need to shift it. if( (*buf_in)->new_chap ) { - printf("MPEG2: Chapter Break Cell Found, searching for GOP\n"); + hb_log("MPEG2: Chapter Break Cell Found, searching for GOP"); pv->libmpeg2->look_for_break = 2; (*buf_in)->new_chap = 0; }