summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjbrjake <[email protected]>2009-06-05 16:39:32 +0000
committerjbrjake <[email protected]>2009-06-05 16:39:32 +0000
commit259bc9a5dd14e07b3fd6b5e7a6aa3cf06caf9b59 (patch)
tree16de7c84f4d107e3f45c7a935a9468b4175ecc5b
parentdfaa966ad3ef68c86db85eb47cddd7eec4a817a4 (diff)
CLI: Implements custom anamorphic. No more -p or -P. Choices are --strict-anamorphic, --loose-anamorphic, and the new --custom-anamorphic. The last of which also handles --pixel-aspect, --display-width, --itu-par, --modulus, and --keep-display-aspect options. Loose will also obey the pixel aspect and ITU PAR options.
Libhb: Fixed a small bug with custom anamorphic working off the source's display aspect even when dealing with a custom display aspect, and made the job config display aware that custom anamorphic exists. Scripts: Updated manicure to write the new anamorphic option names. git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@2487 b64f7644-9d1e-0410-96f1-a4d463321fa5
-rw-r--r--libhb/hb.c14
-rw-r--r--libhb/work.c2
-rwxr-xr-xscripts/manicure.rb16
-rw-r--r--test/test.c291
4 files changed, 239 insertions, 84 deletions
diff --git a/libhb/hb.c b/libhb/hb.c
index f5caa8cd6..f7e3c9dae 100644
--- a/libhb/hb.c
+++ b/libhb/hb.c
@@ -796,12 +796,14 @@ void hb_set_anamorphic_size( hb_job_t * job,
}
else
{
- /* We first need the display ar.
- That's the source display width divided by the source height after cropping.
- Then we multiple the output height by that to get the pixel aspect width,
- and the pixel aspect height is the storage width.*/
- pixel_aspect_width = height * source_display_width / cropped_height;
- pixel_aspect_height = width;
+ /* If we're doing ana 3 and not specifying a DAR, care needs to be taken.
+ This indicates a PAR is potentially being set by the interface. But
+ this is an output PAR, to correct a source, and it should not be assumed
+ that it properly creates a display aspect ratio when applied to the source,
+ which could easily be stored in a different resolution. */
+
+ int output_display_width = width * (double)pixel_aspect_width /
+ (double)pixel_aspect_height ;
}
/* Back to caller */
diff --git a/libhb/work.c b/libhb/work.c
index 92f04f483..e99feaa8c 100644
--- a/libhb/work.c
+++ b/libhb/work.c
@@ -204,7 +204,7 @@ void hb_display_job_info( hb_job_t * job )
if( job->anamorphic.mode )
{
- hb_log( " + %s anamorphic", job->anamorphic.mode == 1 ? "strict" : "loose" );
+ hb_log( " + %s anamorphic", job->anamorphic.mode == 1 ? "strict" : job->anamorphic.mode == 2? "loose" : "custom" );
hb_log( " + storage dimensions: %d * %d -> %d * %d, crop %d/%d/%d/%d",
title->width, title->height, job->width, job->height,
job->crop[0], job->crop[1], job->crop[2], job->crop[3] );
diff --git a/scripts/manicure.rb b/scripts/manicure.rb
index 982fe3f1c..32ea30e50 100755
--- a/scripts/manicure.rb
+++ b/scripts/manicure.rb
@@ -473,9 +473,9 @@ class Display
#Anamorphic
if hash["PicturePAR"] == 1
- commandString << " -p"
+ commandString << " --strict-anamorphic"
elsif hash["PicturePAR"] == 2
- commandString << " -P"
+ commandString << " --loose-anamorphic"
end
#Booleans
@@ -718,9 +718,9 @@ class Display
#Anamorphic
if hash["PicturePAR"] == 1
- commandString << " -p"
+ commandString << " --strict-anamorphic"
elsif hash["PicturePAR"] == 2
- commandString << " -P"
+ commandString << " --loose-anamorphic"
end
#Booleans
@@ -982,9 +982,9 @@ class Display
#Anamorphic
if hash["PicturePAR"] == 1
- commandString << "pixelratio = 1;\n "
+ commandString << "anamorphic_mode = 1;\n "
elsif hash["PicturePAR"] == 2
- commandString << "pixelratio = 2;\n "
+ commandString << "anamorphic_mode = 2;\n "
end
#Booleans
@@ -1228,9 +1228,9 @@ class Display
#Anamorphic
if hash["PicturePAR"] == 1
- commandString << " -p"
+ commandString << " --strict-anamorphic"
elsif hash["PicturePAR"] == 2
- commandString << " -P"
+ commandString << " --loose-anamorphic"
end
#Booleans
diff --git a/test/test.c b/test/test.c
index e88dbb143..a175168a3 100644
--- a/test/test.c
+++ b/test/test.c
@@ -71,11 +71,13 @@ static float vquality = -1.0;
static int vbitrate = 0;
static int size = 0;
static int mux = 0;
-static int pixelratio = 0;
-static int loosePixelratio = 0;
+static int anamorphic_mode = 0;
static int modulus = 0;
static int par_height = 0;
static int par_width = 0;
+static int display_width = 0;
+static int keep_display_aspect = 0;
+static int itu_par = 0;
static int angle = 0;
static int chapter_start = 0;
static int chapter_end = 0;
@@ -347,8 +349,10 @@ static void PrintTitleInfo( hb_title_t * title )
fprintf( stderr, " + angle(s) %d\n", title->angle_count );
fprintf( stderr, " + duration: %02d:%02d:%02d\n",
title->hours, title->minutes, title->seconds );
- fprintf( stderr, " + size: %dx%d, aspect: %.2f, %.3f fps\n",
+ fprintf( stderr, " + size: %dx%d, pixel aspect: %d/%d, display aspect: %.2f, %.3f fps\n",
title->width, title->height,
+ title->pixel_aspect_width,
+ title->pixel_aspect_height,
(float) title->aspect,
(float) title->rate / title->rate_base );
fprintf( stderr, " + autocrop: %d/%d/%d/%d\n", title->crop[0],
@@ -552,7 +556,7 @@ static int HandleEvents( hb_handle_t * h )
{
x264opts = strdup("cabac=0:ref=2:mixed-refs=1:me=umh");
}
- pixelratio = 2;
+ anamorphic_mode = 2;
job->chapter_markers = 1;
}
@@ -677,7 +681,7 @@ static int HandleEvents( hb_handle_t * h )
{
x264opts = strdup("cabac=0:ref=2:mixed-refs=1:bframes=3:me=umh:subme=7:b-adapt=2:8x8dct=1");
}
- pixelratio = 2;
+ anamorphic_mode = 2;
job->chapter_markers = 1;
}
@@ -718,7 +722,7 @@ static int HandleEvents( hb_handle_t * h )
{
x264opts = strdup("ref=2:bframes=2:me=umh");
}
- pixelratio = 1;
+ anamorphic_mode = 1;
job->chapter_markers = 1;
}
@@ -761,7 +765,7 @@ static int HandleEvents( hb_handle_t * h )
}
detelecine = 1;
decomb = 1;
- pixelratio = 2;
+ anamorphic_mode = 2;
job->chapter_markers = 1;
}
@@ -835,7 +839,7 @@ static int HandleEvents( hb_handle_t * h )
{
x264opts = strdup("bframes=3:ref=1:subme=5:me=umh:no-fast-pskip=1:cabac=0");
}
- pixelratio = 1;
+ anamorphic_mode = 1;
job->chapter_markers = 1;
}
@@ -997,25 +1001,7 @@ static int HandleEvents( hb_handle_t * h )
job->deinterlace = deinterlace;
job->grayscale = grayscale;
- if (loosePixelratio)
- {
- job->anamorphic.mode = 2;
- if (modulus)
- {
- job->anamorphic.modulus = modulus;
- }
- if( par_width && par_height )
- {
- job->anamorphic.mode = 3;
- job->anamorphic.par_width = par_width;
- job->anamorphic.par_height = par_height;
- }
- }
- else
- {
- job->anamorphic.mode = pixelratio;
- }
-
+
/* Add selected filters */
job->filters = hb_list_init();
if( detelecine )
@@ -1044,31 +1030,168 @@ static int HandleEvents( hb_handle_t * h )
hb_list_add( job->filters, &hb_filter_denoise );
}
- if( width && height )
- {
- job->width = width;
- job->height = height;
- }
- else if( width )
- {
- job->width = width;
- hb_fix_aspect( job, HB_KEEP_WIDTH );
- }
- else if( height && !loosePixelratio)
- {
- job->height = height;
- hb_fix_aspect( job, HB_KEEP_HEIGHT );
- }
- else if( !width && !height && !pixelratio && !loosePixelratio )
- {
- hb_fix_aspect( job, HB_KEEP_WIDTH );
- }
- else if (!width && loosePixelratio)
+ switch( anamorphic_mode )
{
- /* Default to full width when one isn't specified for loose anamorphic */
- job->width = title->width - job->crop[2] - job->crop[3];
- /* The height will be thrown away in hb.c but calculate it anyway */
- hb_fix_aspect( job, HB_KEEP_WIDTH );
+ case 0: // Non-anamorphic
+
+ if( width && height )
+ {
+ job->width = width;
+ job->height = height;
+ }
+ else if( width )
+ {
+ job->width = width;
+ hb_fix_aspect( job, HB_KEEP_WIDTH );
+ }
+ else if( height )
+ {
+ job->height = height;
+ hb_fix_aspect( job, HB_KEEP_HEIGHT );
+ }
+ else if( !width && !height )
+ {
+ hb_fix_aspect( job, HB_KEEP_WIDTH );
+ }
+
+ break;
+
+ case 1: // Strict anammorphic
+ job->anamorphic.mode = anamorphic_mode;
+ break;
+
+ case 2: // Loose anamorphic
+ job->anamorphic.mode = 2;
+
+ if (modulus)
+ {
+ job->anamorphic.modulus = modulus;
+ }
+
+ if( itu_par )
+ {
+ job->anamorphic.itu_par = itu_par;
+ }
+
+ if( width )
+ {
+ job->width = width;
+ }
+ else if( !width && !height )
+ {
+ /* Default to full width when one isn't specified for loose anamorphic */
+ job->width = title->width - job->crop[2] - job->crop[3];
+ }
+
+ break;
+
+ case 3: // Custom Anamorphic 3: Power User Jamboree
+ job->anamorphic.mode = 3;
+
+ if (modulus)
+ {
+ job->anamorphic.modulus = modulus;
+ }
+
+ if( itu_par )
+ {
+ job->anamorphic.itu_par = itu_par;
+ }
+
+ if( par_width && par_height )
+ {
+ job->anamorphic.par_width = par_width;
+ job->anamorphic.par_height = par_height;
+ }
+
+ if( keep_display_aspect )
+ {
+ /* First, what *is* the display aspect? */
+ int cropped_width = title->width - job->crop[2] - job->crop[3];
+ int cropped_height = title->height - job->crop[0] - job->crop[1];
+
+ /* XXX -- I'm assuming people want to keep the source
+ display AR even though they might have already
+ asked for ITU values instead. */
+ float source_display_width = (float)cropped_width *
+ (float)title->pixel_aspect_width / (float)title->pixel_aspect_height;
+ float display_aspect = source_display_width / cropped_height;
+
+ /* When keeping display aspect, we have to rank some values
+ by priority in order to consistently handle situations
+ when more than one might be specified by default.
+
+ * First off, PAR gets ignored. (err make this reality)
+ * Height will be respected over all other settings,
+ * If it isn't set, display_width will be followed.
+ * If it isn't set, width will be followed. */
+ if( height )
+ {
+ /* We scale the display width to the new height */
+ display_width = (int)( (double)height * display_aspect );
+ }
+ else if( display_width )
+ {
+ /* We scale the height to the new display width */
+ height = (int)( (double)display_width / display_aspect );
+ }
+ else if( width )
+ {
+ /* We assume the source height minus cropping, round
+ to a mod-friendly number, figure out the proper
+ display width at that height, and adjust the PAR
+ to create that display width from the new source width. */
+ int temp_height;
+ temp_height = title->height - job->crop[0] - job->crop[1];
+ int temp_modulus;
+ if( modulus )
+ temp_modulus = modulus;
+ else
+ temp_modulus = 16;
+
+ temp_height = MULTIPLE_MOD( temp_height, temp_modulus );
+ job->anamorphic.par_width = (int)( (double)temp_height * display_aspect );
+ job->anamorphic.par_height = width;
+ }
+ }
+
+ if( display_width )
+ {
+ /* Adjust the PAR to create the new display width
+ from the default job width. */
+ job->anamorphic.dar_width = display_width;
+
+ job->anamorphic.dar_height = height ?
+ height :
+ title->height - job->crop[0] - job->crop[1];
+ }
+
+ if( width && height )
+ {
+ /* Use these storage dimensions */
+ job->width = width;
+ job->height = height;
+ }
+ else if( width )
+ {
+ /* Use just this storage width */
+ job->width = width;
+ job->height = title->height - job->crop[0] - job->crop[1];
+ }
+ else if( height )
+ {
+ /* Use just this storage height. */
+ job->height = height;
+ job->width = title->width - job->crop[2] - job->crop[3];
+ }
+ else if( !width && !height )
+ {
+ /* Assume source dimensions after cropping. */
+ job->width = title->width - job->crop[2] - job->crop[3];
+ job->height = title->height - job->crop[0] - job->crop[1];
+ }
+
+ break;
}
if( vquality >= 0.0 && ( ( vquality <= 1.0 ) || ( vcodec == HB_VCODEC_X264 ) || (vcodec == HB_VCODEC_FFMPEG) ) )
@@ -1871,11 +1994,23 @@ static void ShowHelp()
" --crop <T:B:L:R> Set cropping values (default: autocrop)\n"
" -Y, --maxHeight <#> Set maximum height\n"
" -X, --maxWidth <#> Set maximum width\n"
- " -p, --pixelratio Store pixel aspect ratio in video stream\n"
- " -P, --loosePixelratio Store pixel aspect ratio with specified width\n"
- " <MOD:PARX:PARY> Takes as optional arguments what number you want\n"
- " the dimensions to divide cleanly by (default 16)\n"
- " and the pixel ratio to use (default autodetected)\n"
+ " --strict-anamorphic Store pixel aspect ratio in video stream\n"
+ " --loose-anamorphic Store pixel aspect ratio with specified width\n"
+ " --custom-anamorphic Store pixel aspect ratio in video stream and\n"
+ " directly control all parameters.\n"
+ " --display-width Set the width to scale the actual pixels to\n"
+ " <number> at playback, for custom anamorphic.\n"
+ " --keep-display-aspect Preserve the source's display aspect ratio\n"
+ " when using custom anamorphic\n"
+ " --pixel-aspect Set a custom pixel aspect for custom anamorphic\n"
+ " <PARX:PARY>\n"
+ " (--display-width and --pixel-aspect are mutually\n"
+ " exclusive and the former will override the latter)\n"
+ " --itu-par Use wider, ITU pixel aspect values for loose and\n"
+ " custom anamorphic, useful with underscanned sources\n"
+ " --modulus Set the number you want the scaled pixel dimensions\n"
+ " <number> to divide cleanly by, for loose and custom\n"
+ " anamorphic modes (default: 16)\n"
" -M --color-matrix Set the color space signaled by the output\n"
" <601 or 709> (Bt.601 is mostly for SD content, Bt.709 for HD,\n"
" default: set by resolution)\n"
@@ -1932,21 +2067,21 @@ static void ShowPresets()
{
printf("\n< Apple\n");
- printf("\n + Universal: -e x264 -q 20.0 -a 1,1 -E faac,ac3 -B 160,160 -6 dpl2,auto -R 48,Auto -D 0.0,0.0 -f mp4 -X 720 -P -m -x cabac=0:ref=2:mixed-refs=1:me=umh\n");
+ printf("\n + Universal: -e x264 -q 20.0 -a 1,1 -E faac,ac3 -B 160,160 -6 dpl2,auto -R 48,Auto -D 0.0,0.0 -f mp4 -X 720 --loose-anamorphic -m -x cabac=0:ref=2:mixed-refs=1:me=umh\n");
printf("\n + iPod: -e x264 -b 700 -a 1 -E faac -B 160 -6 dpl2 -R 48 -D 0.0 -f mp4 -I -X 320 -m -x level=30:bframes=0:cabac=0:ref=1:vbv-maxrate=768:vbv-bufsize=2000:analyse=all:me=umh:no-fast-pskip=1\n");
printf("\n + iPhone & iPod Touch: -e x264 -q 20.0 -a 1 -E faac -B 128 -6 dpl2 -R 48 -D 0.0 -f mp4 -X 480 -m -x cabac=0:ref=2:mixed-refs:me=umh\n");
- printf("\n + AppleTV: -e x264 -q 20.0 -a 1,1 -E faac,ac3 -B 160,160 -6 dpl2,auto -R 48,Auto -D 0.0,0.0 -f mp4 -4 -X 960 -P -m -x cabac=0:ref=2:mixed-refs=1:bframes=3:me=umh:subme=7:b-adapt=2:8x8dct=1\n");
+ printf("\n + AppleTV: -e x264 -q 20.0 -a 1,1 -E faac,ac3 -B 160,160 -6 dpl2,auto -R 48,Auto -D 0.0,0.0 -f mp4 -4 -X 960 --loose-anamorphic -m -x cabac=0:ref=2:mixed-refs=1:bframes=3:me=umh:subme=7:b-adapt=2:8x8dct=1\n");
printf("\n>\n");
printf("\n< Regular\n");
- printf("\n + Normal: -e x264 -q 20.0 -a 1 -E faac -B 160 -6 dpl2 -R 48 -D 0.0 -f mp4 -p -m -x ref=2:bframes=2:me=umh\n");
+ printf("\n + Normal: -e x264 -q 20.0 -a 1 -E faac -B 160 -6 dpl2 -R 48 -D 0.0 -f mp4 --strict-anamorphic -m -x ref=2:bframes=2:me=umh\n");
- printf("\n + High Profile: -e x264 -q 20.0 -a 1,1 -E faac,ac3 -B 160,160 -6 dpl2,auto -R 48,Auto -D 0.0,0.0 -f mp4 --detelecine --decomb -P -m -x ref=3:mixed-refs:bframes=3:weightb:b-pyramid:b-adapt=2:me=umh:subme=9:analyse=all:8x8dct\n");
+ printf("\n + High Profile: -e x264 -q 20.0 -a 1,1 -E faac,ac3 -B 160,160 -6 dpl2,auto -R 48,Auto -D 0.0,0.0 -f mp4 --detelecine --decomb --loose-anamorphic -m -x ref=3:mixed-refs:bframes=3:weightb:b-pyramid:b-adapt=2:me=umh:subme=9:analyse=all:8x8dct\n");
printf("\n>\n");
@@ -1954,7 +2089,7 @@ static void ShowPresets()
printf("\n + Classic: -b 1000 -a 1 -E faac -B 160 -6 dpl2 -R 48 -D 0.0 -f mp4\n");
- printf("\n + AppleTV Legacy: -e x264 -b 2500 -a 1,1 -E faac,ac3 -B 160,160 -6 dpl2,auto -R 48,Auto -D 0.0,0.0 -f mp4 -4 -p -m -x bframes=3:ref=1:subme=5:me=umh:no-fast-pskip=1:cabac=0\n");
+ printf("\n + AppleTV Legacy: -e x264 -b 2500 -a 1,1 -E faac,ac3 -B 160,160 -6 dpl2,auto -R 48,Auto -D 0.0,0.0 -f mp4 -4 --strict-anamorphic -m -x bframes=3:ref=1:subme=5:me=umh:no-fast-pskip=1:cabac=0\n");
printf("\n + iPhone Legacy: -e x264 -b 960 -a 1 -E faac -B 128 -6 dpl2 -R 48 -D 0.0 -f mp4 -I -X 480 -m -x level=30:cabac=0:ref=1:analyse=all:me=umh:no-fast-pskip=1:psy-rd=0,0\n");
@@ -1974,6 +2109,10 @@ static int ParseOptions( int argc, char ** argv )
#define STOP_AT 259
#define ANGLE 260
#define DVDNAV 261
+ #define DISPLAY_WIDTH 262
+ #define PIXEL_ASPECT 263
+ #define MODULUS 264
+ #define KEEP_DISPLAY_ASPECT 265
for( ;; )
{
@@ -2014,8 +2153,14 @@ static int ParseOptions( int argc, char ** argv )
{ "detelecine", optional_argument, NULL, '9' },
{ "decomb", optional_argument, NULL, '5' },
{ "grayscale", no_argument, NULL, 'g' },
- { "pixelratio", no_argument, NULL, 'p' },
- { "loosePixelratio", optional_argument, NULL, 'P' },
+ { "strict-anamorphic", no_argument, &anamorphic_mode, 1 },
+ { "loose-anamorphic", no_argument, &anamorphic_mode, 2 },
+ { "custom-anamorphic", no_argument, &anamorphic_mode, 3 },
+ { "display-width", required_argument, NULL, DISPLAY_WIDTH },
+ { "keep-display-aspect", no_argument, &keep_display_aspect, 1 },
+ { "pixel-aspect", required_argument, NULL, PIXEL_ASPECT },
+ { "modulus", required_argument, NULL, MODULUS },
+ { "itu-par", no_argument, &itu_par, 1 },
{ "width", required_argument, NULL, 'w' },
{ "height", required_argument, NULL, 'l' },
{ "crop", required_argument, NULL, 'n' },
@@ -2049,7 +2194,7 @@ static int ParseOptions( int argc, char ** argv )
int c;
c = getopt_long( argc, argv,
- "hv::uC:f:4i:Io:t:Lc:m::M:a:A:6:s:UFN:e:E:2dD:7895gpOP::w:l:n:b:q:S:B:r:R:Qx:TY:X:Z:z",
+ "hv::uC:f:4i:Io:t:Lc:m::M:a:A:6:s:UFN:e:E:2dD:7895gOw:l:n:b:q:S:B:r:R:Qx:TY:X:Z:z",
long_options, &option_index );
if( c < 0 )
{
@@ -2266,14 +2411,22 @@ static int ParseOptions( int argc, char ** argv )
case 'g':
grayscale = 1;
break;
- case 'p':
- pixelratio = 1;
+ case DISPLAY_WIDTH:
+ if( optarg != NULL )
+ {
+ sscanf( optarg, "%i", &display_width );
+ }
+ break;
+ case PIXEL_ASPECT:
+ if( optarg != NULL )
+ {
+ sscanf( optarg, "%i:%i", &par_width, &par_height );
+ }
break;
- case 'P':
- loosePixelratio = 1;
+ case MODULUS:
if( optarg != NULL )
{
- sscanf( optarg, "%i:%i:%i", &modulus, &par_width, &par_height );
+ sscanf( optarg, "%i", &modulus );
}
break;
case 'e':