diff options
-rw-r--r-- | libhb/hb.c | 119 | ||||
-rw-r--r-- | libhb/hb.h | 2 | ||||
-rw-r--r-- | libhb/work.c | 70 | ||||
-rw-r--r-- | test/test.c | 20 |
4 files changed, 155 insertions, 56 deletions
diff --git a/libhb/hb.c b/libhb/hb.c index a53bd1f4a..b2d672872 100644 --- a/libhb/hb.c +++ b/libhb/hb.c @@ -431,75 +431,90 @@ void hb_get_preview( hb_handle_t * h, hb_title_t * title, int picture, * @param job Handle to hb_job_t. * @param aspect Desired aspect ratio. Value of -1 uses title aspect. * @param pixels Maximum desired pixel count. + * @param par If true, skip the cropping and keep-aspect-ratio stuff. */ -void hb_set_size( hb_job_t * job, int aspect, int pixels ) +void hb_set_size( hb_job_t * job, int aspect, int pixels, int par ) { hb_title_t * title = job->title; int croppedWidth = title->width - title->crop[2] - title->crop[3]; int croppedHeight = title->height - title->crop[0] - title->crop[1]; - int croppedAspect = title->aspect * title->height * croppedWidth / - croppedHeight / title->width; - int addCrop; - int i, w, h; - - if( aspect <= 0 ) + + int croppedAspect; + if (par) { - /* Keep the best possible aspect ratio */ + /* That means we're setting size for video with non-square pixels */ + croppedAspect = croppedWidth * HB_ASPECT_BASE / croppedHeight; aspect = croppedAspect; } - - /* Crop if necessary to obtain the desired ratio */ - memcpy( job->crop, title->crop, 4 * sizeof( int ) ); - if( aspect < croppedAspect ) - { - /* Need to crop on the left and right */ - addCrop = croppedWidth - aspect * croppedHeight * title->width / - title->aspect / title->height; - if( addCrop & 3 ) - { - addCrop = ( addCrop + 1 ) / 2; - job->crop[2] += addCrop; - job->crop[3] += addCrop; - } - else if( addCrop & 2 ) - { - addCrop /= 2; - job->crop[2] += addCrop - 1; - job->crop[3] += addCrop + 1; - } - else - { - addCrop /= 2; - job->crop[2] += addCrop; - job->crop[3] += addCrop; - } - } - else if( aspect > croppedAspect ) + else { - /* Need to crop on the top and bottom */ - addCrop = croppedHeight - croppedWidth * title->aspect * - title->height / aspect / title->width; - if( addCrop & 3 ) + /* We're free to change cropping and maintain display aspect ratio */ + croppedAspect = title->aspect * title->height * croppedWidth / + croppedHeight / title->width; + + int addCrop; + + if( aspect <= 0 ) { - addCrop = ( addCrop + 1 ) / 2; - job->crop[0] += addCrop; - job->crop[1] += addCrop; + /* Keep the best possible aspect ratio */ + aspect = croppedAspect; } - else if( addCrop & 2 ) + + /* Crop if necessary to obtain the desired ratio */ + memcpy( job->crop, title->crop, 4 * sizeof( int ) ); + if( aspect < croppedAspect ) { - addCrop /= 2; - job->crop[0] += addCrop - 1; - job->crop[1] += addCrop + 1; + /* Need to crop on the left and right */ + addCrop = croppedWidth - aspect * croppedHeight * title->width / + title->aspect / title->height; + if( addCrop & 3 ) + { + addCrop = ( addCrop + 1 ) / 2; + job->crop[2] += addCrop; + job->crop[3] += addCrop; + } + else if( addCrop & 2 ) + { + addCrop /= 2; + job->crop[2] += addCrop - 1; + job->crop[3] += addCrop + 1; + } + else + { + addCrop /= 2; + job->crop[2] += addCrop; + job->crop[3] += addCrop; + } } - else + else if( aspect > croppedAspect ) { - addCrop /= 2; - job->crop[0] += addCrop; - job->crop[1] += addCrop; + /* Need to crop on the top and bottom */ + addCrop = croppedHeight - croppedWidth * title->aspect * + title->height / aspect / title->width; + if( addCrop & 3 ) + { + addCrop = ( addCrop + 1 ) / 2; + job->crop[0] += addCrop; + job->crop[1] += addCrop; + } + else if( addCrop & 2 ) + { + addCrop /= 2; + job->crop[0] += addCrop - 1; + job->crop[1] += addCrop + 1; + } + else + { + addCrop /= 2; + job->crop[0] += addCrop; + job->crop[1] += addCrop; + } } - } + } + + int i, w, h; /* Compute a resolution from the number of pixels and aspect */ for( i = 0;; i++ ) { diff --git a/libhb/hb.h b/libhb/hb.h index 6f8af2aee..c33f70f62 100644 --- a/libhb/hb.h +++ b/libhb/hb.h @@ -77,7 +77,7 @@ hb_list_t * hb_get_titles( hb_handle_t * ); void hb_get_preview( hb_handle_t *, hb_title_t *, int, uint8_t * ); -void hb_set_size( hb_job_t *, int ratio, int pixels ); +void hb_set_size( hb_job_t *, int ratio, int pixels, int par ); /* Handling jobs */ int hb_count( hb_handle_t * ); diff --git a/libhb/work.c b/libhb/work.c index 5b3f914c2..70ca36a1e 100644 --- a/libhb/work.c +++ b/libhb/work.c @@ -128,6 +128,76 @@ static void do_job( hb_job_t * job, int cpu_count ) job->height=title->height-job->crop[0]-job->crop[1]; job->width=title->width-job->crop[2]-job->crop[3]; } + else if ( job->pixel_ratio == 2 ) + { + /* "Loose" anamorphic. + - Uses mod16-compliant dimensions, + - Allows users to set the width + - Handles ITU pixel aspects + */ + /* Use mod16 values for better compression */ + job->width = MULTIPLE_16( job->width ); + job->height = MULTIPLE_16( job->height ); + job->width = MAX( 16, job->width ); + job->height = MAX( 16, job->height ); + + /* Set up some variables to make the math easier to follow. */ + int cropped_width = title->width - job->crop[2] - job->crop[3] ; + int cropped_height = title->height - job->crop[0] - job->crop[1] ; + int storage_aspect = cropped_width * HB_ASPECT_BASE / cropped_height; + int pixels = job->width * (job->width / storage_aspect * HB_ASPECT_BASE); + + /* While keeping the DVD storage aspect, resize the job width and height + so they fit into the user's specified dimensions. */ + hb_set_size(job, -1, pixels, 1); + + if (cropped_width <= 706) + { + /* Handle ITU PARs */ + if (title->height == 480) + { + /* It's NTSC */ + if (title->aspect == 16) + { + /* It's widescreen */ + job->pixel_aspect_width = 40; + job->pixel_aspect_height = 33; + } + else + { + /*It's 4:3 */ + job->pixel_aspect_width = 10; + job->pixel_aspect_height = 11; + } + } + else if (title->height == 576) + { + /* It's PAL */ + if(title->aspect == 16) + { + /* It's widescreen */ + job->pixel_aspect_width = 16; + job->pixel_aspect_height = 11; + } + else + { + /* It's 4:3 */ + job->pixel_aspect_width = 12; + job->pixel_aspect_height = 11; + } + } + } + + /* Figure out what dimensions the source would display at. */ + int source_display_width = cropped_width * ((float)job->pixel_aspect_width / (float)job->pixel_aspect_height) ; + + /* The film AR is the source's display width / cropped source height. + The output display width is the output height * film AR. + The output PAR is the output display width / output storage width. */ + job->pixel_aspect_width = job->height * source_display_width / cropped_height; + job->pixel_aspect_height = job->width; + + } /* Keep width and height within these boundaries */ if (job->maxHeight && (job->height > job->maxHeight) ) diff --git a/test/test.c b/test/test.c index a5ddddf25..e1b72a974 100644 --- a/test/test.c +++ b/test/test.c @@ -53,6 +53,7 @@ static int abitrate = 0; static int mux = 0; static int acodec = 0; static int pixelratio = 0; +static int loosePixelratio = 0; static int chapter_start = 0; static int chapter_end = 0; static int chapter_markers = 0; @@ -447,7 +448,6 @@ static int HandleEvents( hb_handle_t * h ) job->deinterlace = deinterlace; job->grayscale = grayscale; - job->pixel_ratio = pixelratio; /* Add selected filters */ job->filters = hb_list_init(); @@ -471,7 +471,16 @@ static int HandleEvents( hb_handle_t * h ) hb_filter_denoise.settings = denoise_opt; hb_list_add( job->filters, &hb_filter_denoise ); } - + + if (loosePixelratio) + { + job->pixel_ratio = 2; + } + else + { + job->pixel_ratio = pixelratio; + } + if( width && height ) { job->width = width; @@ -870,6 +879,7 @@ static void ShowHelp() " <L:R:T:B:SB:MP> (default 1:1:4:4:0:0)\n" " -g, --grayscale Grayscale encoding\n" " -p, --pixelratio Store pixel aspect ratio in video stream\n" + " -P, --loosePixelratio Store pixel aspect ratio with specified x*y\n" "\n" @@ -945,6 +955,7 @@ static int ParseOptions( int argc, char ** argv ) { "detelecine", optional_argument, NULL, '9' }, { "grayscale", no_argument, NULL, 'g' }, { "pixelratio", no_argument, NULL, 'p' }, + { "loosePixelratio", no_argument, NULL, 'P' }, { "width", required_argument, NULL, 'w' }, { "height", required_argument, NULL, 'l' }, { "crop", required_argument, NULL, 'n' }, @@ -969,7 +980,7 @@ static int ParseOptions( int argc, char ** argv ) int c; c = getopt_long( argc, argv, - "hvuC:f:4i:o:t:Lc:ma:6:s:UFN:e:E:2d789gpw:l:n:b:q:S:B:r:R:Qx:TY:X:", + "hvuC:f:4i:o:t:Lc:ma:6:s:UFN:e:E:2d789gpPw:l:n:b:q:S:B:r:R:Qx:TY:X:", long_options, &option_index ); if( c < 0 ) { @@ -1111,6 +1122,9 @@ static int ParseOptions( int argc, char ** argv ) case 'p': pixelratio = 1; break; + case 'P': + loosePixelratio = 1; + break; case 'e': if( !strcasecmp( optarg, "ffmpeg" ) ) { |