From 6be53619ab5c255c36857a78d57ea988ebe363dc Mon Sep 17 00:00:00 2001 From: prigaux Date: Mon, 15 Jan 2007 08:56:54 +0000 Subject: [PATCH] Add PixelRatio support, when used, HB use the same pixel ratio than the source DVD so the widescreen is preserved, this controled bay the preferences sheet. git-svn-id: svn://svn.handbrake.fr/HandBrake/branches/0.7.3@116 b64f7644-9d1e-0410-96f1-a4d463321fa5 --- libhb/common.c | 23 +++++++++++++++++++++++ libhb/common.h | 20 +++++++++++++++----- libhb/encavcodec.c | 9 +++++++++ libhb/encx264.c | 10 ++++++++++ libhb/encxvid.c | 7 +++++++ libhb/scan.c | 17 ++++++++++++----- 6 files changed, 76 insertions(+), 10 deletions(-) diff --git a/libhb/common.c b/libhb/common.c index e9d366f75..7b41a93fb 100644 --- a/libhb/common.c +++ b/libhb/common.c @@ -36,6 +36,29 @@ int hb_audio_bitrates_count = sizeof( hb_audio_bitrates ) / sizeof( hb_rate_t ); int hb_audio_bitrates_default = 8; /* 128 kbps */ +/********************************************************************** + * hb_reduce + ********************************************************************** + * Given a numerator (num) and a denominator (den), reduce them to an + * equivalent fraction and store the result in x and y. + *********************************************************************/ +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 ) + { + if( ( num % i == 0 ) && ( den % i == 0 ) ) + { + *x = num / i; + *y = den / i; + break; + } + } +} + /********************************************************************** * hb_fix_aspect ********************************************************************** diff --git a/libhb/common.h b/libhb/common.h index 859711f81..be56d1a3c 100644 --- a/libhb/common.h +++ b/libhb/common.h @@ -7,6 +7,7 @@ #ifndef HB_COMMON_H #define HB_COMMON_H +#include #include #include #include @@ -55,6 +56,8 @@ void hb_list_rem( hb_list_t *, void * ); void * hb_list_item( hb_list_t *, int ); void hb_list_close( hb_list_t ** ); +void hb_reduce( int *x, int *y, int num, int den ); + #define HB_KEEP_WIDTH 0 #define HB_KEEP_HEIGHT 1 void hb_fix_aspect( hb_job_t * job, int keep ); @@ -92,17 +95,24 @@ struct hb_job_s int chapter_end; /* Picture settings: - crop: must be multiples of 2 (top/bottom/left/right) - deinterlace: 0 or 1 - width: must be a multiple of 16 - height: must be a multiple of 16 - keep_ratio: used by UIs */ + crop: must be multiples of 2 (top/bottom/left/right) + deinterlace: 0 or 1 + width: must be a multiple of 16 + height: must be a multiple of 16 + keep_ratio: used by UIs + pixel_ratio: store pixel aspect ratio in the video + pixel_aspect_width: numerator for pixel aspect ratio + pixel_aspect_height: denominator for pixel aspect ratio */ + int crop[4]; int deinterlace; int width; int height; int keep_ratio; int grayscale; + int pixel_ratio; + int pixel_aspect_width; + int pixel_aspect_height; /* Video settings: vcodec: output codec diff --git a/libhb/encavcodec.c b/libhb/encavcodec.c index f04606906..c71c8384e 100644 --- a/libhb/encavcodec.c +++ b/libhb/encavcodec.c @@ -65,6 +65,15 @@ int encavcodecInit( hb_work_object_t * w, hb_job_t * job ) context->gop_size = 10 * job->vrate / job->vrate_base; context->pix_fmt = PIX_FMT_YUV420P; + if( job->pixel_ratio ) + { + context->sample_aspect_ratio.num = job->pixel_aspect_width; + context->sample_aspect_ratio.den = job->pixel_aspect_height; + + hb_log( "encavcodec: encoding with stored aspect %d/%d", + job->pixel_aspect_width, job->pixel_aspect_height ); + } + if( job->mux & ( HB_MUX_MP4 | HB_MUX_PSP ) ) { context->flags |= CODEC_FLAG_GLOBAL_HEADER; diff --git a/libhb/encx264.c b/libhb/encx264.c index 1bc24866c..044b6fecd 100644 --- a/libhb/encx264.c +++ b/libhb/encx264.c @@ -75,6 +75,16 @@ int encx264Init( hb_work_object_t * w, hb_job_t * job ) /* Slightly faster with minimal quality lost */ param.analyse.i_subpel_refine = 4; + if( job->pixel_ratio ) + { + param.vui.i_sar_width = job->pixel_aspect_width; + param.vui.i_sar_height = job->pixel_aspect_height; + + hb_log( "encx264: encoding with stored aspect %d/%d", + param.vui.i_sar_width, param.vui.i_sar_height ); + } + + if( job->vquality >= 0.0 && job->vquality <= 1.0 ) { switch(job->crf) diff --git a/libhb/encxvid.c b/libhb/encxvid.c index 87c42b0a4..7768f8e12 100644 --- a/libhb/encxvid.c +++ b/libhb/encxvid.c @@ -162,6 +162,13 @@ int encxvidWork( hb_work_object_t * w, hb_buffer_t ** buf_in, frame.vol_flags = 0; frame.vop_flags = XVID_VOP_HALFPEL | XVID_VOP_INTER4V | XVID_VOP_TRELLISQUANT | XVID_VOP_HQACPRED; + if( job->pixel_ratio ) + { + frame.par = XVID_PAR_EXT; + frame.par_width = job->pixel_aspect_width; + frame.par_height = job->pixel_aspect_height; + } + if( job->grayscale ) { frame.vop_flags |= XVID_VOP_GREYSCALE; diff --git a/libhb/scan.c b/libhb/scan.c index 097f11638..101b954ec 100644 --- a/libhb/scan.c +++ b/libhb/scan.c @@ -177,13 +177,20 @@ static void ScanFunc( void * _data ) /* Autocrop by default. Gnark gnark */ memcpy( job->crop, title->crop, 4 * sizeof( int ) ); - job->width = title->width - job->crop[2] - job->crop[3]; - hb_fix_aspect( job, HB_KEEP_WIDTH ); - if( job->height > title->height - job->crop[0] - job->crop[1] ) + if( title->aspect == 16 ) + { + hb_reduce( &job->pixel_aspect_width, &job->pixel_aspect_height, + 16 * title->height, 9 * title->width ); + } + else { - job->height = title->height - job->crop[0] - job->crop[1]; - hb_fix_aspect( job, HB_KEEP_HEIGHT ); + hb_reduce( &job->pixel_aspect_width, &job->pixel_aspect_height, + 4 * title->height, 3 * title->width ); } + + job->width = title->width - job->crop[2] - job->crop[3]; + job->height = title->height - job->crop[0] - job->crop[1]; + job->keep_ratio = 1; job->vcodec = HB_VCODEC_FFMPEG; -- 2.40.0