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
**********************************************************************
#ifndef HB_COMMON_H
#define HB_COMMON_H
+#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
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 );
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
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;
/* 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)
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;
/* 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;