memcpy( h->pixf.fpelcmp_x4, satd ? h->pixf.satd_x4 : h->pixf.sad_x4, sizeof(h->pixf.fpelcmp_x4) );
}
+static void x264_set_aspect_ratio( x264_t *h, x264_param_t *param, int initial )
+{
+ /* VUI */
+ if( param->vui.i_sar_width > 0 && param->vui.i_sar_height > 0 )
+ {
+ int i_w = param->vui.i_sar_width;
+ int i_h = param->vui.i_sar_height;
+ int old_w = h->param.vui.i_sar_width;
+ int old_h = h->param.vui.i_sar_height;
+
+ x264_reduce_fraction( &i_w, &i_h );
+
+ while( i_w > 65535 || i_h > 65535 )
+ {
+ i_w /= 2;
+ i_h /= 2;
+ }
+
+ if( i_w != old_w || i_h != old_h || initial )
+ {
+ h->param.vui.i_sar_width = 0;
+ h->param.vui.i_sar_height = 0;
+ if( i_w == 0 || i_h == 0 )
+ x264_log( h, X264_LOG_WARNING, "cannot create valid sample aspect ratio\n" );
+ else
+ {
+ x264_log( h, initial?X264_LOG_INFO:X264_LOG_DEBUG, "using SAR=%d/%d\n", i_w, i_h );
+ h->param.vui.i_sar_width = i_w;
+ h->param.vui.i_sar_height = i_h;
+ }
+ }
+ }
+}
+
/****************************************************************************
* x264_encoder_open:
****************************************************************************/
/* Create a copy of param */
memcpy( &h->param, param, sizeof(x264_param_t) );
+ if( param->param_free )
+ param->param_free( param );
+
if( x264_validate_parameters( h ) < 0 )
goto fail;
if( h->param.rc.psz_stat_in )
h->param.rc.psz_stat_in = strdup( h->param.rc.psz_stat_in );
- /* VUI */
- if( h->param.vui.i_sar_width > 0 && h->param.vui.i_sar_height > 0 )
- {
- int i_w = param->vui.i_sar_width;
- int i_h = param->vui.i_sar_height;
-
- x264_reduce_fraction( &i_w, &i_h );
-
- while( i_w > 65535 || i_h > 65535 )
- {
- i_w /= 2;
- i_h /= 2;
- }
-
- h->param.vui.i_sar_width = 0;
- h->param.vui.i_sar_height = 0;
- if( i_w == 0 || i_h == 0 )
- {
- x264_log( h, X264_LOG_WARNING, "cannot create valid sample aspect ratio\n" );
- }
- else
- {
- x264_log( h, X264_LOG_INFO, "using SAR=%d/%d\n", i_w, i_h );
- h->param.vui.i_sar_width = i_w;
- h->param.vui.i_sar_height = i_h;
- }
- }
+ x264_set_aspect_ratio( h, param, 1 );
x264_reduce_fraction( &h->param.i_fps_num, &h->param.i_fps_den );
int x264_encoder_reconfig( x264_t *h, x264_param_t *param )
{
h = h->thread[h->i_thread_phase%h->param.i_threads];
+ x264_set_aspect_ratio( h, param, 0 );
#define COPY(var) h->param.var = param->var
COPY( i_frame_reference ); // but never uses more refs than initially specified
COPY( i_bframe_bias );
return 0;
}
+ if( h->fenc->param )
+ {
+ x264_encoder_reconfig( h, h->fenc->param );
+ if( h->fenc->param->param_free )
+ h->fenc->param->param_free( h->fenc->param );
+ }
+
if( h->fenc->i_type == X264_TYPE_IDR )
{
h->frames.i_last_idr = h->fenc->i_frame;
return 0;
CHECKED_MALLOC( z->param, sizeof(x264_param_t) );
memcpy( z->param, &h->param, sizeof(x264_param_t) );
+ z->param->param_free = x264_free;
while( (tok = strtok_r( p, ",", &saveptr )) )
{
char *val = strchr( tok, '=' );
if( rc->zones )
{
x264_free( rc->zones[0].param );
- if( h->param.rc.psz_zones )
- for( i=1; i<rc->i_zones; i++ )
- if( rc->zones[i].param != rc->zones[0].param )
- x264_free( rc->zones[i].param );
+ for( i=1; i<rc->i_zones; i++ )
+ if( rc->zones[i].param != rc->zones[0].param && rc->zones[i].param->param_free )
+ rc->zones[i].param->param_free( rc->zones[i].param );
x264_free( rc->zones );
}
x264_free( rc );
#include <stdarg.h>
-#define X264_BUILD 71
+#define X264_BUILD 72
/* x264_t:
* opaque handler for encoder */
int b_aud; /* generate access unit delimiters */
int b_repeat_headers; /* put SPS/PPS before each keyframe */
int i_sps_id; /* SPS and PPS id number */
+
+ /* Optional callback for freeing this x264_param_t when it is done being used.
+ * Only used when the x264_param_t sits in memory for an indefinite period of time,
+ * i.e. when an x264_param_t is passed to x264_t in an x264_picture_t or in zones.
+ * Not used when x264_encoder_reconfig is called directly. */
+ void (*param_free)( void* );
} x264_param_t;
typedef struct {
int i_qpplus1;
/* In: user pts, Out: pts of encoded picture (user)*/
int64_t i_pts;
+ /* In: custom encoding parameters to be set from this frame forwards
+ (in coded order, not display order). If NULL, continue using
+ parameters from the previous frame. Some parameters, such as
+ aspect ratio, can only be changed per-GOP due to the limitations
+ of H.264 itself; in this case, the caller must force an IDR frame
+ if it needs the changed parameter to apply immediately. */
+ x264_param_t *param;
/* In: raw data */
x264_image_t img;
* create a new encoder handler, all parameters from x264_param_t are copied */
x264_t *x264_encoder_open ( x264_param_t * );
/* x264_encoder_reconfig:
- * change encoder options while encoding,
- * analysis-related parameters from x264_param_t are copied */
+ * analysis-related parameters from x264_param_t are copied.
+ * this takes effect immediately, on whichever frame is encoded next;
+ * due to delay, this may not be the next frame passed to encoder_encode.
+ * if the change should apply to some particular frame, use x264_picture_t->param instead. */
int x264_encoder_reconfig( x264_t *, x264_param_t * );
/* x264_encoder_headers:
* return the SPS and PPS that will be used for the whole stream */