[Libav-user] Race condition during executing x264_encoder_reconfig with multithreading
TuTu Yu
tutu.yu at hulu.com
Tue Oct 15 01:01:12 CEST 2013
Hi,
I found out a bug in x264 when running ffmpeg with x264 module.
When ffmpeg tried to execute x264_encoder_reconfig during run time, x264 will first initialize values in structure x264_param_t back to default.
And later, x264 will properly set variable in structure x264_param_t based on user configuration in function x264_validate_parameters.
However, if this happens during running multithreading, un-expected encoding process will be produced.
Here is my patch towards this change.
Please let me know if you need me to explain more on this issue.
Thanks
TuTu
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
diff --git a/encoder/encoder.c b/encoder/encoder.c
index 78ad56a..e7b0238 100644
--- a/encoder/encoder.c
+++ b/encoder/encoder.c
@@ -416,6 +416,8 @@ static void x264_encoder_thread_init( x264_t *h )
static int x264_validate_parameters( x264_t *h, int b_open )
{
+ unsigned int analyse_inter = h->param.analyse.inter;
+ unsigned int analyse_intra = h->param.analyse.intra;
#if HAVE_MMX
if( b_open )
{
@@ -1003,16 +1005,18 @@ static int x264_validate_parameters( x264_t *h, int b_open )
(h->mb.b_lossless || h->param.analyse.i_subpel_refine <= 1) )
h->param.analyse.i_me_method = X264_ME_ESA;
h->param.analyse.b_mixed_references = h->param.analyse.b_mixed_references && h->param.i_frame_reference > 1;
- h->param.analyse.inter &= X264_ANALYSE_PSUB16x16|X264_ANALYSE_PSUB8x8|X264_ANALYSE_BSUB16x16|
+ analyse_inter &= X264_ANALYSE_PSUB16x16|X264_ANALYSE_PSUB8x8|X264_ANALYSE_BSUB16x16|
X264_ANALYSE_I4x4|X264_ANALYSE_I8x8;
- h->param.analyse.intra &= X264_ANALYSE_I4x4|X264_ANALYSE_I8x8;
- if( !(h->param.analyse.inter & X264_ANALYSE_PSUB16x16) )
- h->param.analyse.inter &= ~X264_ANALYSE_PSUB8x8;
+ analyse_intra &= X264_ANALYSE_I4x4|X264_ANALYSE_I8x8;
+ if( !(analyse_inter & X264_ANALYSE_PSUB16x16) )
+ analyse_intra &= ~X264_ANALYSE_PSUB8x8;
if( !h->param.analyse.b_transform_8x8 )
{
- h->param.analyse.inter &= ~X264_ANALYSE_I8x8;
- h->param.analyse.intra &= ~X264_ANALYSE_I8x8;
+ analyse_inter &= ~X264_ANALYSE_I8x8;
+ analyse_intra &= ~X264_ANALYSE_I8x8;
}
+ h->param.analyse.intra = analyse_intra;
+ h->param.analyse.inter = analyse_inter;
h->param.analyse.i_trellis = x264_clip3( h->param.analyse.i_trellis, 0, 2 );
h->param.rc.i_aq_mode = x264_clip3( h->param.rc.i_aq_mode, 0, 2 );
h->param.rc.f_aq_strength = x264_clip3f( h->param.rc.f_aq_strength, 0, 3 );
@@ -1689,8 +1693,6 @@ int x264_encoder_reconfig( x264_t *h, x264_param_t *param )
COPY( i_deblocking_filter_alphac0 );
COPY( i_deblocking_filter_beta );
COPY( i_frame_packing );
- COPY( analyse.inter );
- COPY( analyse.intra );
COPY( analyse.i_direct_mv_pred );
/* Scratch buffer prevents me_range from being increased for esa/tesa */
if( h->param.analyse.i_me_method < X264_ME_ESA || param->analyse.i_me_range < h->param.analyse.i_me_range )
More information about the Libav-user
mailing list