Index: test/test.c===================================================================--- test/test.c (revision 1018)+++ test/test.c (working copy)@@ -53,6 +53,8 @@ static int mux = 0; static int acodec = 0; static int pixelratio = 0;+static int loosePixelratio = 0;+static int modulus = 0; static int chapter_start = 0; static int chapter_end = 0; static int chapter_markers = 0;@@ -449,8 +451,18 @@ job->deinterlace = deinterlace; job->grayscale = grayscale;- job->pixel_ratio = pixelratio;-+ if (loosePixelratio)+ {+ job->pixel_ratio = 2;+ if (modulus)+ {+ job->modulus = modulus;+ }+ }+ else+ {+ job->pixel_ratio = pixelratio;+ } /* Add selected filters */ job->filters = hb_list_init(); if( detelecine )@@ -874,6 +886,10 @@ " <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"+ " <modulus> Takes as optional argument what number you want\n"+ " the dimensions to divide cleanly by (default 16)\n"+ "\n"@@ -949,6 +965,7 @@ { "detelecine", optional_argument, NULL, '9' }, { "grayscale", no_argument, NULL, 'g' }, { "pixelratio", no_argument, NULL, 'p' },+ { "loosePixelratio", optional_argument, NULL, 'P' }, { "width", required_argument, NULL, 'w' }, { "height", required_argument, NULL, 'l' }, { "crop", required_argument, NULL, 'n' },@@ -973,7 +990,7 @@ 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:2d789gpP::w:l:n:b:q:S:B:r:R:Qx:TY:X:", long_options, &option_index ); if( c < 0 ) {@@ -1115,6 +1132,13 @@ case 'p': pixelratio = 1; break;+ case 'P':+ loosePixelratio = 1;+ if( optarg != NULL )+ {+ modulus = atoi( optarg );+ }+ break; case 'e': if( !strcasecmp( optarg, "ffmpeg" ) ) {Index: libhb/hb.c===================================================================--- libhb/hb.c (revision 1018)+++ libhb/hb.c (working copy)@@ -427,6 +427,173 @@ } /**+ * 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; ++ if (title->aspect != 16)+ {+ /* Don't use anamorphic for 4:3 material */+ job->pixel_ratio = 0;+ hb_log("4:3 material detected, unsetting anamorphic mode.");+ goto end_anamorphic;+ }++ /* 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+ These won't be used in the workflow,+ but they're here just in case someone+ wants to enable them down the line. */+ 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+ These won't be used in the workflow,+ but they're here just in case someone+ wants to enable them down the line. */+ 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 );++ /* Poor 4:3 video. If only there was a way to use PAR to set a display height.*/+ end_anamorphic: ;+}++/** * 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.Index: libhb/hb.h===================================================================--- libhb/hb.h (revision 1018)+++ libhb/hb.h (working copy)@@ -78,6 +78,7 @@ 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_anamorphic_size( hb_job_t * ); /* Handling jobs */ int hb_count( hb_handle_t * );Index: libhb/work.c===================================================================--- libhb/work.c (revision 1018)+++ libhb/work.c (working copy)@@ -128,16 +128,27 @@ 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 )+ {- /* Keep width and height within these boundaries */- if (job->maxHeight && (job->height > job->maxHeight) )+ /* While keeping the DVD storage aspect, resize the job width and height+ so they fit into the user's specified dimensions. */+ hb_set_anamorphic_size(job);+ }+++ /* Keep width and height within these boundaries,+ but ignore for "loose" anamorphic encodes, for+ which this stuff is covered in the pixel_ratio+ section right above.*/+ if (job->maxHeight && (job->height > job->maxHeight) && (job->pixel_ratio != 2)) { job->height = job->maxHeight; hb_fix_aspect( job, HB_KEEP_HEIGHT ); hb_log("Height out of bounds, scaling down to %i", job->maxHeight); hb_log("New dimensions %i * %i", job->width, job->height); }- if (job->maxWidth && (job->width > job->maxWidth) )+ if (job->maxWidth && (job->width > job->maxWidth) && (job->pixel_ratio != 2)) { job->width = job->maxWidth; hb_fix_aspect( job, HB_KEEP_WIDTH ); Index: libhb/common.h===================================================================--- libhb/common.h (revision 1018)+++ libhb/common.h (working copy)@@ -27,6 +27,7 @@ #define EVEN( a ) ( (a) + ( (a) & 1 ) ) #define MULTIPLE_16( a ) ( 16 * ( ( (a) + 8 ) / 16 ) )+#define MULTIPLE_MOD( a, b ) ( b * ( ( (a) + (b / 2) ) / b ) ) #define HB_DVD_READ_BUFFER_SIZE 2048@@ -139,6 +140,7 @@ int pixel_ratio; int pixel_aspect_width; int pixel_aspect_height;+ int modulus; int maxWidth; int maxHeight;