diff options
Diffstat (limited to 'libhb/hb.c')
-rw-r--r-- | libhb/hb.c | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/libhb/hb.c b/libhb/hb.c index a53bd1f4a..6b108bdf0 100644 --- a/libhb/hb.c +++ b/libhb/hb.c @@ -427,6 +427,156 @@ void hb_get_preview( hb_handle_t * h, hb_title_t * title, int picture, } /** + * Calculates job width and height for anamorphic content. + * @param job Handle to hb_job_t. + */ +void hb_set_anamorphic_size( hb_job_t * job) +{ + hb_title_t * title = job->title; + + /* "Loose" anamorphic. + - Uses mod16-compliant dimensions, + - Allows users to set the width + - Handles ITU pixel aspects + */ + + /* 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 * 10000 / cropped_height; + + /* Gotta handle bounding dimensions differently + than for non-anamorphic encodes: + If the width is too big, just reset it with no rescaling. + Instead of using the aspect-scaled job height, + we need to see if the job width divided by the storage aspect + is bigger than the max. If so, set it to the max (this is sloppy). + If not, set job height to job width divided by storage aspect. + */ + if ( job->maxWidth && (job->maxWidth < job->width) ) + job->width = job->maxWidth; + + if ( job->maxHeight && (job->maxHeight < (job->width / storage_aspect * 10000)) ) + { + job->height = job->maxHeight; + } + else + { + job->height = job->width * 10000 / storage_aspect; + } + + /* Time to get picture dimensions that divide cleanly. + These variables will store temporary dimensions as we iterate. */ + int i, w, h, mod; + + /* In case the user specified a modulus, use it */ + if (job->modulus) + mod = job->modulus; + else + mod = 16; + + /* Iterate through multiples of mod to find one close to job->width. */ + for( i = 1;; i++ ) + { + w = mod * i; + + if (w < job->width) + { + if ( ( job->width - w ) <= ( mod / 2 ) ) + /* We'll take a width that's + smaller, but close enough. */ + break; + } + if (w == job->width) + /* Mod 16 dimensions, how nice! */ + break; + if( w > job->width ) + { + if ( ( w - job->width ) < (mod/2) ) + /* We'll take a width that's bigger, if we have to. */ + break; + } + } + job->width = mod * (i); + + /* Now do the same for a mod-friendly value near job->height. */ + for( i = 1;; i++) + { + h = i * mod; + + if (h < job->height) + { + if ( ( job->height - h ) <= ( mod / 2 )) + /* Go with a smaller height, + if it's close enough. */ + break; + } + if (h == job->height) + /* Mod 16 dimensions, how nice! */ + break; + + if ( h > job->height) + { + if ( ( h - job->height ) < ( mod / 2 )) + /* Use a taller height if necessary */ + break; + } + } + job->height = mod * (i); + + 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; + + /* While x264 is smart enough to reduce fractions on its own, libavcodec + needs some help with the math, so lose superfluous factors. */ + hb_reduce( &job->pixel_aspect_width, &job->pixel_aspect_height, + job->pixel_aspect_width, job->pixel_aspect_height ); +} + +/** * Calculates job width, height, and cropping parameters. * @param job Handle to hb_job_t. * @param aspect Desired aspect ratio. Value of -1 uses title aspect. |