From f53c8e3833c7cd810d1c94ff2ff48ed7553a7697 Mon Sep 17 00:00:00 2001 From: prigaux Date: Thu, 18 Jan 2007 14:18:24 +0000 Subject: [PATCH] Implement PixelRatio in the hblib git-svn-id: svn://svn.handbrake.fr/HandBrake/branches/PixelRatioWorking@187 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 ++++++++++++----- libhb/work.c | 12 +++++++++++- 7 files changed, 87 insertions(+), 11 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..17a82aeaa 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; diff --git a/libhb/work.c b/libhb/work.c index 6529e2fbb..598511c57 100644 --- a/libhb/work.c +++ b/libhb/work.c @@ -103,6 +103,16 @@ static void do_job( hb_job_t * job, int cpu_count ) hb_log( " + device %s", title->dvd ); hb_log( " + title %d, chapter(s) %d to %d", title->index, job->chapter_start, job->chapter_end ); + if ( job->pixel_ratio == 1 ) + { + /* Correct the geometry of the output movie when using PixelRatio */ + job->height=title->height-job->crop[0]-job->crop[1]; + job->width=title->width-job->crop[2]-job->crop[3]; + } + else + { + hb_fix_aspect( job, HB_KEEP_WIDTH ); + } hb_log( " + %dx%d -> %dx%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] ); @@ -119,7 +129,7 @@ static void do_job( hb_job_t * job, int cpu_count ) (float) job->vrate / (float) job->vrate_base, job->vbitrate, job->pass ); } - + hb_log (" + PixelRatio: %d, width:%d, height: %d",job->pixel_ratio,job->width, job->height); job->fifo_mpeg2 = hb_fifo_init( 2048 ); job->fifo_raw = hb_fifo_init( 8 ); job->fifo_sync = hb_fifo_init( 8 ); -- 2.40.0