Index: macosx/PictureController.mm =================================================================== --- macosx/PictureController.mm (revision 1031) +++ macosx/PictureController.mm (working copy) @@ -116,8 +116,22 @@ /* Set deinterlaces level according to the integer in the main window */ [fDeinterlacePopUp selectItemAtIndex: fPictureFilterSettings.deinterlace]; - - [fPARCheck setState:(job->pixel_ratio ? NSOnState : NSOffState)]; + + /* we set the anamorphic checkbox according to the prefs + * job->pixel_ratio values can be as follows: + * 0 = No Anamorphic + * 1 = "Strict" Anamorphic (Handbrake's original anamorphic implementation + * 2 = "Loose" Anamorphic (implementation which allows for 640 xxxx anamorphic) + */ + if (job->pixel_ratio > 0) + { + /* must be either 1(strict) or 2 (loose) anamorphic*/ + [fPARCheck setState:NSOnState]; + } + else + { + [fPARCheck setState:NSOffState]; + } /* We initially set the previous state of keep ar to on */ keepAspectRatioPreviousState = 1; if (!autoCrop) @@ -149,8 +163,6 @@ /* Set denoises level according to the integer in the main window */ [fDenoisePopUp selectItemAtIndex: fPictureFilterSettings.denoise]; - MaxOutputWidth = job->width; - MaxOutputHeight = job->height; fPicture = 0; [self SettingsChanged: nil]; @@ -197,25 +209,52 @@ height: ( fTitle->height + 2 )]; /* Set the Output Display below the Preview Picture*/ - int titlewidth = fTitle->width-fTitle->job->crop[2]-fTitle->job->crop[3]; int arpwidth = fTitle->job->pixel_aspect_width; int arpheight = fTitle->job->pixel_aspect_height; - int displayparwidth = titlewidth * arpwidth / arpheight; + int displayparwidth = croppedWidth * arpwidth / arpheight; int displayparheight = fTitle->height-fTitle->job->crop[0]-fTitle->job->crop[1]; NSSize displaySize = NSMakeSize( (float)fTitle->width, (float)fTitle->height ); - if( fTitle->job->pixel_ratio == 1 ) + if( fTitle->job->pixel_ratio > 0) { - [fInfoField setStringValue:[NSString stringWithFormat: - @"Source: %dx%d, Output: %dx%d, Anamorphic: %dx%d", - fTitle->width, fTitle->height, titlewidth, - displayparheight, displayparwidth, displayparheight]]; - displaySize.width *= ((float)arpwidth) / ((float)arpheight); + if (fTitle->job->pixel_ratio == 1) // strict anamorphic + { + [fInfoField setStringValue:[NSString stringWithFormat: + @"Source: %dx%d, Output: %dx%d, Anamorphic: %dx%d", + fTitle->width, fTitle->height, croppedWidth, + displayparheight, displayparwidth, displayparheight]]; + displaySize.width *= ((float)arpwidth) / ((float)arpheight); + } + else // Loose Anamorphic + { + /* Not real sure if this is applicable to the gui */ + + + /* 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. */ + //fTitle->job->pixel_aspect_width = fTitle->job->height * source_display_width / croppedHeight; + //fTitle->job->pixel_aspect_height = fTitle->job->width; + + + //displayparwidth = croppedWidth * arpwidth / arpheight; + //displayparheight = fTitle->height-fTitle->job->crop[0]-fTitle->job->crop[1]; + + [fInfoField setStringValue:[NSString stringWithFormat: + @"Source: %dx%d, Output: %dx%d, Anamorphic: %dx%d", + croppedWidth, croppedHeight, fTitle->job->width, + fTitle->job->height, sourceDisplayWidth, fTitle->job->height]]; + + + displaySize.width *= ((float)arpwidth) / ((float)arpheight); + + + } } else { [fInfoField setStringValue: [NSString stringWithFormat: - @"Source: %dx%d, Output: %dx%d", fTitle->width, fTitle->height, + @"Source: %dx%d, Output: %dx%d", croppedWidth, croppedHeight, fTitle->job->width, fTitle->job->height]]; } @@ -242,54 +281,239 @@ [fPrevButton setEnabled: ( fPicture > 0 )]; [fNextButton setEnabled: ( fPicture < 9 )]; } - - (IBAction) SettingsChanged: (id) sender { hb_job_t * job = fTitle->job; - - if( [fPARCheck state] == NSOnState ) - { - [fWidthStepper setIntValue: MaxOutputWidth]; - [fWidthField setIntValue: MaxOutputWidth]; + +job->width = [fWidthStepper intValue]; +job->height = [fHeightStepper intValue]; + +/* We set the job->crop values here as they are needed for proper par calculation below */ + if( autoCrop ) + { + memcpy( job->crop, fTitle->crop, 4 * sizeof( int ) ); + } + else + { + job->crop[0] = [fCropTopStepper intValue]; + job->crop[1] = [fCropBottomStepper intValue]; + job->crop[2] = [fCropLeftStepper intValue]; + job->crop[3] = [fCropRightStepper intValue]; + } +/* we set the variables to keep the math easier */ +maxOutputWidth = job->width; +maxOutputHeight = job->height; +croppedWidth = fTitle->width - job->crop[2] - job->crop[3] ; +croppedHeight = fTitle->height - job->crop[0] - job->crop[1] ; +storageAspect = croppedWidth * 10000 / croppedHeight; +if( [fPARCheck state] == NSOnState ) +{ +/* if the sender is the Anamorphic checkbox, record the state + of KeepAspect Ratio so it can be reset if Anamorphic is unchecked again */ + if (sender == fPARCheck) + { + keepAspectRatioPreviousState = [fRatioCheck state]; + } + + + /* check to see if we are using strict anamorphic, or loose anamorphic in the prefs */ + if ( [[NSUserDefaults standardUserDefaults] boolForKey:@"UseStrictAnamorphic"] > 0) + { + /* We are using strict anamorphic */ + job->pixel_ratio = 1; + [fWidthStepper setIntValue: maxOutputWidth]; + [fWidthField setIntValue: maxOutputWidth]; /* This will show correct anamorphic height values, but show distorted preview picture ratio */ - [fHeightStepper setIntValue: fTitle->height-fTitle->job->crop[0]-fTitle->job->crop[1]]; - [fHeightField setIntValue: fTitle->height-fTitle->job->crop[0]-fTitle->job->crop[1]]; - - /* if the sender is the Anamorphic checkbox, record the state - of KeepAspect Ratio so it can be reset if Anamorphic is unchecked again */ - if (sender == fPARCheck) - { - keepAspectRatioPreviousState = [fRatioCheck state]; - } - [fRatioCheck setState:NSOffState]; - [fRatioCheck setEnabled: NO]; + [fHeightStepper setIntValue: croppedHeight]; + [fHeightField setIntValue: croppedHeight]; + + [fWidthStepper setEnabled: NO]; [fWidthField setEnabled: NO]; - [fHeightStepper setEnabled: NO]; - [fHeightField setEnabled: NO]; } - else - { + else // we use loose anamorphic + { + job->pixel_ratio = 2; + + [fRatioCheck setState:NSOffState]; + [fRatioCheck setEnabled: NO]; + [fWidthStepper setEnabled: YES]; [fWidthField setEnabled: YES]; - [fHeightStepper setEnabled: YES]; - [fHeightField setEnabled: YES]; - [fRatioCheck setEnabled: YES]; - /* if the sender is the Anamorphic checkbox, we return the - keep AR checkbox to its previous state */ - if (sender == fPARCheck) + + /* we have to set the new values appropriately */ + /* first, we handle width */ + if (job->maxWidth && (job->maxWidth < job->width)) { - [fRatioCheck setState:keepAspectRatioPreviousState]; + job->width = job->maxWidth; } + /* now, we handle height */ + if (job->maxHeight && (job->maxHeight < (job->width / storageAspect * 10000))) + { + job->height = job->maxHeight; + } + else + { + job->height = job->width * 10000 / storageAspect; + } - } - - job->width = [fWidthStepper intValue]; - job->height = [fHeightStepper intValue]; + + /* Time to get picture dimensions that divide cleanly. + These variables will store temporary dimensions as we iterate. */ + /* This is taken from hb.c and reworked to provide proper user feedback */ + int i, w, h, mod; + /* for our purposes, we will just use mod 16, but leave the code in here + * in case we want to be able to specify modulus (like mod 8) in the gui + * down the road + */ + /* 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 (croppedWidth <= 706) + { + /* Handle ITU PARs */ + if (fTitle->height == 480) + { + /* It's NTSC */ + if (fTitle->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 (fTitle->height == 576) + { + /* It's PAL */ + if(fTitle->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. */ + sourceDisplayWidth = croppedWidth * ((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 * sourceDisplayWidth / croppedHeight; + 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 ); + + /* Okay, since we are using loose anamorphic, + lets set the steppers and fields as per our job values here*/ + //[fWidthStepper setIntValue: job->width]; + //[fWidthField setIntValue: job->width]; + + } + + [fRatioCheck setState:NSOffState]; + [fRatioCheck setEnabled: NO]; + + [fHeightStepper setEnabled: NO]; + [fHeightField setEnabled: NO]; + + + +} +else // We arent using anamorphic at all. +{ + +/* if the sender is the Anamorphic checkbox, we return the + keep AR checkbox to its previous state */ + if (sender == fPARCheck) + { + [fRatioCheck setState:keepAspectRatioPreviousState]; + } + job->pixel_ratio = 0; + [fWidthStepper setEnabled: YES]; + [fWidthField setEnabled: YES]; + [fHeightStepper setEnabled: YES]; + [fHeightField setEnabled: YES]; + [fRatioCheck setEnabled: YES]; +} + + + job->keep_ratio = ( [fRatioCheck state] == NSOnState ); fPictureFilterSettings.deinterlace = [fDeinterlacePopUp indexOfSelectedItem]; @@ -306,7 +530,6 @@ } fPictureFilterSettings.denoise = [fDenoisePopUp indexOfSelectedItem]; fPictureFilterSettings.detelecine = [fDetelecineCheck state]; - job->pixel_ratio = ( [fPARCheck state] == NSOnState ); autoCrop = ( [fCropMatrix selectedRow] == 0 ); [fCropTopStepper setEnabled: !autoCrop]; @@ -314,18 +537,8 @@ [fCropLeftStepper setEnabled: !autoCrop]; [fCropRightStepper setEnabled: !autoCrop]; - if( autoCrop ) - { - memcpy( job->crop, fTitle->crop, 4 * sizeof( int ) ); - } - else - { - job->crop[0] = [fCropTopStepper intValue]; - job->crop[1] = [fCropBottomStepper intValue]; - job->crop[2] = [fCropLeftStepper intValue]; - job->crop[3] = [fCropRightStepper intValue]; - } + if( job->keep_ratio ) { if( sender == fWidthStepper || sender == fRatioCheck || @@ -365,7 +578,7 @@ crashing hb_get_preview. In fact, just for kicks lets getting previews at a min limit of 32, since no human can see any meaningful detail below that */ - if (job->width >= 64 && job->height >= 64) + if (job->width >= 64 || job->height >= 64) { [self Display: HB_ANIMATE_NONE]; } Index: macosx/Controller.mm =================================================================== --- macosx/Controller.mm (revision 1031) +++ macosx/Controller.mm (working copy) @@ -2714,7 +2714,7 @@ [fPicSettingWidth setStringValue: [NSString stringWithFormat:@"%d", fTitle->job->width]]; [fPicSettingHeight setStringValue: [NSString stringWithFormat:@"%d", fTitle->job->height]]; - if (fTitle->job->pixel_ratio == 1) + if (fTitle->job->pixel_ratio > 0) { int titlewidth = fTitle->width-fTitle->job->crop[2]-fTitle->job->crop[3]; int arpwidth = fTitle->job->pixel_aspect_width; @@ -2728,7 +2728,7 @@ [fPicSettingPARWidth setStringValue: [NSString stringWithFormat:@"%d", displayparwidth]]; [fPicSettingPARHeight setStringValue: [NSString stringWithFormat:@"%d", displayparheight]]; - fTitle->job->keep_ratio = 0; + //fTitle->job->keep_ratio = 0; } else { Index: macosx/English.lproj/Preferences.nib/info.nib =================================================================== --- macosx/English.lproj/Preferences.nib/info.nib (revision 1031) +++ macosx/English.lproj/Preferences.nib/info.nib (working copy) @@ -7,9 +7,9 @@ IBEditorPositions 233 - 480 459 520 251 0 0 1440 878 + 460 484 520 251 0 0 1440 878 234 - 480 510 520 150 0 0 1440 878 + 41 635 520 170 0 0 1440 878 235 480 522 520 125 0 0 1440 878 236 @@ -19,7 +19,7 @@ 446.1 IBOpenObjects - 233 + 234 IBSystem Version 8R2218 Index: macosx/English.lproj/Preferences.nib/keyedobjects.nib =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: macosx/PictureController.h =================================================================== --- macosx/PictureController.h (revision 1031) +++ macosx/PictureController.h (working copy) @@ -48,8 +48,12 @@ IBOutlet NSButton * fNextButton; IBOutlet NSTextField * fInfoField; - int MaxOutputWidth; - int MaxOutputHeight; + int maxOutputWidth; + int maxOutputHeight; + int croppedWidth; + int croppedHeight; + int storageAspect; + int sourceDisplayWidth; BOOL autoCrop; /* used to track the previous state of the keep aspect