From f8eb63aed0df0e9c99b5d652728ccb01a2d4eb68 Mon Sep 17 00:00:00 2001 From: van Date: Fri, 8 Aug 2008 06:19:54 +0000 Subject: - change aspect from a scaled int to a double so we can handle the wider range of aspect ratios we get from ffmpeg files. - add container_aspect to title struct (always zero except for DVDs when it's the aspect from the VTSI). To handle broken French DVDs, make HB complain & use the container aspect if it's different from the aspect computed from the video PAR. - fix ScanFunc's job template init so that it doesn't think the only legal aspect ratios are 16:9 & 4:3. - hb_reduce wouldn't reduce any fraction where both terms were equal and prime (e.g., 2/2, 3/3, 5/5, etc. would not become 1/1). Recoded it using Euclid's Algorithm so it always works and is faster. git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@1616 b64f7644-9d1e-0410-96f1-a4d463321fa5 --- libhb/common.c | 46 +++++++++++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 21 deletions(-) (limited to 'libhb/common.c') diff --git a/libhb/common.c b/libhb/common.c index c625bec9b..c8cc8dddc 100644 --- a/libhb/common.c +++ b/libhb/common.c @@ -82,18 +82,26 @@ const char * hb_mixdown_get_short_name_from_mixdown( int amixdown ) *********************************************************************/ void hb_reduce( int *x, int *y, int num, int den ) { - int lower = MIN( num, den ); - int i; - *x = num; - *y = den; - for( i = lower - 1; i > 1; --i ) + // find the greatest common divisor of num & den by Euclid's algorithm + int n = num, d = den; + while ( d ) { - if( ( num % i == 0 ) && ( den % i == 0 ) ) - { - *x = num / i; - *y = den / i; - break; - } + int t = d; + d = n % d; + n = t; + } + + // at this point n is the gcd. if it's non-zero remove it from num + // and den. Otherwise just return the original values. + if ( n ) + { + *x = num / n; + *y = den / n; + } + else + { + *x = num; + *y = den; } } @@ -143,22 +151,18 @@ void hb_fix_aspect( hb_job_t * job, int keep ) } } + double par = (double)title->width / ( (double)title->height * title->aspect ); + double cropped_sar = (double)( title->height - job->crop[0] - job->crop[1] ) / + (double)(title->width - job->crop[2] - job->crop[3] ); + double ar = par * cropped_sar; if( keep == HB_KEEP_WIDTH ) { - job->height = MULTIPLE_16( - (uint64_t) job->width * title->width * HB_ASPECT_BASE * - ( title->height - job->crop[0] - job->crop[1] ) / - ( (uint64_t) title->height * title->aspect * - ( title->width - job->crop[2] - job->crop[3] ) ) ); + job->height = MULTIPLE_16( (uint64_t)( (double)job->width * ar ) ); job->height = MAX( 16, job->height ); } else { - job->width = MULTIPLE_16( - (uint64_t) job->height * title->height * title->aspect * - ( title->width - job->crop[2] - job->crop[3] ) / - ( (uint64_t) title->width * HB_ASPECT_BASE * - ( title->height - job->crop[0] - job->crop[1] ) ) ); + job->width = MULTIPLE_16( (uint64_t)( (double)job->height / ar ) ); job->width = MAX( 16, job->width ); } } -- cgit v1.2.3