[x264-devel] Problem with x264 multithreding enabled

Alessandro Ferrari alessandroferrari87 at gmail.com
Wed Sep 16 10:43:08 CEST 2009


Hi,
     i'm developing a program using x264 api starting by the source code of
x264.c, and I encurr in a problem that probably i miss any operations. I
need to minimize the frame delay, so for this reason initially i have
developed forcing using only one thread. The program in this case works
correctly. Then, for maximize the performance i simply set the i_threads=2
to enabling multi-threading, and I expect a frame delay of one frame, but
the result is very different. I test the encoder on a sequence of 100
frames, and for all 100 frames the encoder function return a zero value for
i_nal, at the end in the flush _delayed_frame loop  i  have again  2 encoder
function calling with i_nal null, and then at the third passing i have
i_nal=1 but i have this error:
test_x264_2thread: common/frame.c:971: x264_frame_push_unused: Assertion
`frame->i_reference_count > 0' failed.
The strange things is that with param.i_threads=1 always works without
problem.
If i force the settings of x264.c by specifying it before calling the
encoder function to be equal at the settings that i specify in my program i
haven't this error. What could be the problem?
I also include my encoding functions:

int  static Encode_frame( x264_t *h, x264_picture_t *pic )
{
    x264_picture_t pic_out;
    x264_nal_t *nal;
    int i_nal, i, i_nalu_size;
    int buffersize=0;

    i_nalu_size = 0;



    if( x264_encoder_encode( h, &nal, &i_nal, pic, &pic_out ) < 0 )
    {
        fprintf( stderr, "x264 [error]: x264_encoder_encode failed\n" );
        return -1;
    }

    printf("inal:%d\n",i_nal);

    for( i = 0; i < i_nal; i++ )
    {
        int i_size;

        if( mux_buffer_size < nal[i].i_payload * 3/2 + 4 )
        {
            mux_buffer_size = nal[i].i_payload * 2 + 4;
            free( mux_buffer );
            mux_buffer = (uint8_t*)malloc( mux_buffer_size );
            if( !mux_buffer )
                return -1;
        }

        i_size = mux_buffer_size;
        x264_nal_encode( mux_buffer, &i_size, 1, &nal[i] );
        i_nalu_size += write_nal_unit(  mux_buffer, i_size );
        printf("i_nalu_size: %d\n",i_nalu_size);
        if( i_nalu_size < 0 )
            return -1;
        buffersize += i_nalu_size;
    }

    return buffersize;
}

static int  Encode(FILE *f)
{
    x264_t *h;
    x264_picture_t pic;
    x264_param_t param;

    int     i_frame;
    int64_t i_file;
    int     i_frame_size;
    struct timeb t_ini,t_fin;
    double media=0.0;

    x264_param_default( &param );
    param.i_width=352;
    param.i_height=288;

    /*Modified*/
    param.rc.i_lookahead = 0;
    param.i_threads = 2;
    //Gop Size maximum 20
    param.i_keyint_max = 20;

    //only pass1 mode for low latency
    param.rc.b_stat_read = 0;
    param.rc.b_stat_write = 1;

    //We don't need bframe
    param.i_bframe = 0;
    param.i_bframe_adaptive = 0;
     //Setting CRF
    param.rc.i_rc_method = X264_RC_CRF;
    //Specify quality of encoding
    param.rc.f_rf_constant = 30;


    //Maximum dimension of the gop
    param.i_keyint_max = 20;

    /*end modify*/

    if( ( h = x264_encoder_open( &param ) ) == NULL )
    {
        fprintf( stderr, "x264 [error]: x264_encoder_open failed\n" );
        return -1;
    }

    /* Create a new pic */
    if( x264_picture_alloc( &pic, X264_CSP_I420, param.i_width,
param.i_height ) < 0 )
    {
        fprintf( stderr, "x264 [error]: malloc failed\n" );
        return -1;
    }
    /* Encode frames */
    for( i_frame = 0, i_file = 0; read_yuv_frame(f, &pic, 352,288); )
    {
        pic.i_pts = (int64_t)i_frame * param.i_fps_den;
        printf("%d\n",param.i_fps_den);


        /* Do not force any parameters */
        pic.i_type = X264_TYPE_AUTO;
        pic.i_qpplus1 = 0;

        ftime(&t_ini);
    i_frame_size = Encode_frame( h,  &pic );
        ftime(&t_fin);
        media = media + (t_fin.time-t_ini.time)*1000 + t_fin.millitm -
t_ini.millitm;
        printf("Encoding time frame
n°%d:%d\n",i_frame,(t_fin.time-t_ini.time)*1000 + t_fin.millitm -
t_ini.millitm);
    if( i_frame_size < 0 )
            return -1;
        i_frame++;
    }

    /*modified*/
    int z=0;
    media = media/i_frame;

    printf("Media tempo di encoding:%0.3f\n",media);

    /* Flush delayed frames */
    while( x264_encoder_delayed_frames( h ) )
    {
        z++;
        i_frame_size = Encode_frame( h, NULL );
        if( i_frame_size < 0 )
            return -1;
        i_file += i_frame_size;
    }


    x264_picture_clean( &pic );
    x264_encoder_close( h );
    free( mux_buffer );

    return 0;
}

Thanks for the attention.
Best regards.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/x264-devel/attachments/20090916/27bf524e/attachment.htm>


More information about the x264-devel mailing list