X-Git-Url: http://git.osdn.jp/view?a=blobdiff_plain;f=libhb%2Fscan.c;h=eea1c3f0bf74d6d75423b50551446550b4f85fcf;hb=07cc0ebf6a7141a76fd9b6e2da6cf510def1ebc7;hp=960332dfc204a120edc79a1d02ea6a164f39a90b;hpb=cb5b4d38b6d195d8fe790618be9c359c96b27e1f;p=handbrake-jp%2Fhandbrake-jp-git.git diff --git a/libhb/scan.c b/libhb/scan.c index 960332df..eea1c3f0 100644 --- a/libhb/scan.c +++ b/libhb/scan.c @@ -26,18 +26,15 @@ static int DecodePreviews( hb_scan_t *, hb_title_t * title ); static void LookForAudio( hb_title_t * title, hb_buffer_t * b ); static int AllAudioOK( hb_title_t * title ); -static const char *aspect_to_string( int aspect ) +static const char *aspect_to_string( double aspect ) { - switch ( aspect ) + switch ( (int)(aspect * 9.) ) { - case HB_ASPECT_BASE * 1 / 1: return "1:1"; - case HB_ASPECT_BASE * 4 / 3: return "4:3"; - case HB_ASPECT_BASE * 16 / 9: return "16:9"; - case HB_ASPECT_BASE * 221 / 100: return "2.21:1"; + case 9 * 4 / 3: return "4:3"; + case 9 * 16 / 9: return "16:9"; } static char arstr[32]; - double a = (double)aspect / HB_ASPECT_BASE; - sprintf( arstr, aspect >= 1.? "%.2f:1" : "1:%.2f", a ); + sprintf( arstr, aspect >= 1.? "%.2f:1" : "1:%.2f", aspect ); return arstr; } @@ -198,15 +195,11 @@ static void ScanFunc( void * _data ) job->pixel_aspect_height = title->pixel_aspect_height; } - if( title->aspect == 16 && !job->pixel_aspect_width && !job->pixel_aspect_height) + if( title->aspect != 0 && title->aspect != 1. && + !job->pixel_aspect_width && !job->pixel_aspect_height) { hb_reduce( &job->pixel_aspect_width, &job->pixel_aspect_height, - 16 * title->height, 9 * title->width ); - } - else if( !job->pixel_aspect_width && !job->pixel_aspect_height ) - { - hb_reduce( &job->pixel_aspect_width, &job->pixel_aspect_height, - 4 * title->height, 3 * title->width ); + (int)(title->aspect * title->height), title->width ); } job->width = title->width - job->crop[2] - job->crop[3]; @@ -291,24 +284,26 @@ static int row_all_dark( hb_title_t *title, uint8_t* luma, int row ) return 1; } -static int column_all_dark( hb_title_t *title, uint8_t* luma, int top, int col ) +static int column_all_dark( hb_title_t *title, uint8_t* luma, int top, int bottom, + int col ) { int stride = title->width; + int height = title->height - top - bottom; luma += stride * top + col; // compute the average value of the column - int i = title->height - top, avg = 0, row = 0; + int i = height, avg = 0, row = 0; for ( ; --i >= 0; row += stride ) { avg += clampBlack( luma[row] ); } - avg /= title->height - top; + avg /= height; if ( avg >= DARK ) return 0; // since we're trying to detect smooth borders, only take the column if // all pixels are within +-16 of the average. - i = title->height - top, row = 0; + i = height, row = 0; for ( ; --i >= 0; row += stride ) { if ( absdiff( avg, clampBlack( luma[row] ) ) > 16 ) @@ -499,16 +494,27 @@ static int DecodePreviews( hb_scan_t * data, hb_title_t * title ) /* Get size and rate infos */ hb_work_info_t vid_info; - vid_decoder->info( vid_decoder, &vid_info ); + if( !vid_decoder->info( vid_decoder, &vid_info ) ) + { + /* + * Could not fill vid_info, don't continue and try to use vid_info + * in this case. + */ + vid_decoder->close( vid_decoder ); + free( vid_decoder ); + continue; + } vid_decoder->close( vid_decoder ); free( vid_decoder ); remember_info( info_list, &vid_info ); + title->video_codec_name = strdup( vid_info.name ); title->width = vid_info.width; title->height = vid_info.height; title->rate = vid_info.rate; title->rate_base = vid_info.rate_base; + title->video_bitrate = vid_info.bitrate; if( title->rate_base == 1126125 ) { @@ -581,39 +587,61 @@ static int DecodePreviews( hb_scan_t * data, hb_title_t * title ) #define Y vid_buf->data int top, bottom, left, right; int h4 = title->height / 4, w4 = title->width / 4; - for ( top = 4; top < h4; ++top ) + + // When widescreen content is matted to 16:9 or 4:3 there's sometimes + // a thin border on the outer edge of the matte. On TV content it can be + // "line 21" VBI data that's normally hidden in the overscan. For HD + // content it can just be a diagnostic added in post production so that + // the frame borders are visible. We try to ignore these borders so + // we can crop the matte. The border width depends on the resolution + // (12 pixels on 1080i looks visually the same as 4 pixels on 480i) + // so we allow the border to be up to 1% of the frame height. + const int border = title->height / 100; + + for ( top = border; top < h4; ++top ) { if ( ! row_all_dark( title, Y, top ) ) break; } - if ( top < 5 ) + if ( top <= border ) { - // we started at row 4 to avoid the "line 21" noise that shows - // up on row 0 & 1 of some TV shows. Since we stopped before row 4 - // check if the missed rows are dark or if we shouldn't crop at all. - for ( top = 0; top < 4; ++top ) + // we never made it past the border region - see if the rows we + // didn't check are dark or if we shouldn't crop at all. + for ( top = 0; top < border; ++top ) { if ( ! row_all_dark( title, Y, top ) ) break; } - if ( top >= 4 ) + if ( top >= border ) { top = 0; } } - for ( bottom = 0; bottom < h4; ++bottom ) + for ( bottom = border; bottom < h4; ++bottom ) { if ( ! row_all_dark( title, Y, title->height - 1 - bottom ) ) break; } + if ( bottom <= border ) + { + for ( bottom = 0; bottom < border; ++bottom ) + { + if ( ! row_all_dark( title, Y, title->height - 1 - bottom ) ) + break; + } + if ( bottom >= border ) + { + bottom = 0; + } + } for ( left = 0; left < w4; ++left ) { - if ( ! column_all_dark( title, Y, top, left ) ) + if ( ! column_all_dark( title, Y, top, bottom, left ) ) break; } for ( right = 0; right < w4; ++right ) { - if ( ! column_all_dark( title, Y, top, title->width - 1 - right ) ) + if ( ! column_all_dark( title, Y, top, bottom, title->width - 1 - right ) ) break; } @@ -644,16 +672,29 @@ skip_preview: // compute the aspect ratio based on the storage dimensions and the // pixel aspect ratio (if supplied) or just storage dimensions if no PAR. - title->aspect = ( (double)title->width / (double)title->height + 0.05 ) * - HB_ASPECT_BASE; - - double aspect = (double)title->width / (double)title->height; + title->aspect = (double)title->width / (double)title->height; if( title->pixel_aspect_width && title->pixel_aspect_height ) { - aspect *= (double)title->pixel_aspect_width / - (double)title->pixel_aspect_height; + title->aspect *= (double)title->pixel_aspect_width / + (double)title->pixel_aspect_height; + + // For unknown reasons some French PAL DVDs put the original + // content's aspect ratio into the mpeg PAR even though it's + // the wrong PAR for the DVD. Apparently they rely on the fact + // that DVD players ignore the content PAR and just use the + // aspect ratio from the DVD metadata. So, if the aspect computed + // from the PAR is different from the container's aspect we use + // the container's aspect & recompute the PAR from it. + if( title->container_aspect && title->aspect != title->container_aspect ) + { + hb_log("scan: content PAR gives wrong aspect %.2f; " + "using container aspect %.2f", title->aspect, + title->container_aspect ); + title->aspect = title->container_aspect; + hb_reduce( &title->pixel_aspect_width, &title->pixel_aspect_height, + (int)(title->aspect * title->height), title->width ); + } } - title->aspect = ( aspect + 0.05 ) * HB_ASPECT_BASE; // don't try to crop unless we got at least 3 previews if ( crops->n > 2 )