x264源码分析-threads参数

本文深入解析了x264编码器中多线程的实现原理及配置选项,包括threads参数的最大值设定、sliced-threads的工作方式、lookahead_threads的作用等,并探讨了线程数量对编码效率的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

sprintf( s, " threads=%d", p->i_threads );
最大值128 X264_THREAD_MAX。


如果没有设置threads参数,x264根据当前CPU核数以及slice_threads计算应该设置的编码线程个数
h->param.i_threads = x264_cpu_num_processors() * (h->param.b_sliced_threads?2:3)/2;


从代码看:x264_threadpool_run( h->threadpool, (void*)x264_slices_write, h );


void x264_threadpool_run( x264_threadpool_t *pool, void *(*func)(void *), void *arg )
{
    x264_threadpool_job_t *job = (void*)x264_sync_frame_list_pop( &pool->uninit );
    job->func = func;
    job->arg  = arg;
    x264_sync_frame_list_push( &pool->run, (void*)job );
}


void x264_sync_frame_list_push( x264_sync_frame_list_t *slist, x264_frame_t *frame )
{
    x264_pthread_mutex_lock( &slist->mutex );
    while( slist->i_size == slist->i_max_size )
        x264_pthread_cond_wait( &slist->cv_empty, &slist->mutex );
    slist->list[ slist->i_size++ ] = frame;
    x264_pthread_mutex_unlock( &slist->mutex );
    x264_pthread_cond_broadcast( &slist->cv_fill );
}


这里是以帧为单位的多线程编码,当线程数量过大,会导致线程之间相互参考等待,已经线程调度等问题,建议不要超过16.


sliced-threads 一帧是否分slice
默认值0,一帧一个slice

值为1表示一帧多个slice。


lookahead_threads:参考线程个数,按线程个数分块编码,块之间参考关系相互独立。

for( int i = 0; i < h->param.i_lookahead_threads; i++ )
                {
                    x264_t *t = h->lookahead_thread[i];


                    /* FIXME move this somewhere else  填充编码参数*/
                    t->mb.i_me_method = h->mb.i_me_method;
                    t->mb.i_subpel_refine = h->mb.i_subpel_refine;
                    t->mb.b_chroma_me = h->mb.b_chroma_me;


                    s[i] = (x264_slicetype_slice_t){ t, a, frames, p0, p1, b, dist_scale_factor, do_search, w,
                        output_inter[i], output_intra[i] };


                    t->i_threadslice_start = ((h->mb.i_mb_height *  i    + h->param.i_lookahead_threads/2) / h->param.i_lookahead_threads);
                    t->i_threadslice_end   = ((h->mb.i_mb_height * (i+1) + h->param.i_lookahead_threads/2) / h->param.i_lookahead_threads);
                           //起始到结束的宏块编码序号

                    int thread_height = t->i_threadslice_end - t->i_threadslice_start;
                    int thread_output_size = thread_height + NUM_INTS;
                    memset( output_inter[i], 0, thread_output_size * sizeof(int) );
                    memset( output_intra[i], 0, thread_output_size * sizeof(int) );
                    output_inter[i][NUM_ROWS] = output_intra[i][NUM_ROWS] = thread_height;
                    output_inter[i+1] = output_inter[i] + thread_output_size + PAD_SIZE;
                    output_intra[i+1] = output_intra[i] + thread_output_size + PAD_SIZE;
                    x264_threadpool_run( h->lookaheadpool, (void*)x264_slicetype_slice_cost, &s[i] );
                }
                for( int i = 0; i < h->param.i_lookahead_threads; i++ )

                    x264_threadpool_wait( h->lookaheadpool, &s[i] );

lookahead_threads值

if( h->param.b_sliced_threads )//slice_threads =1时
            h->param.i_lookahead_threads = h->param.i_threads; 

sync_lookahead 设置了这个值,意味着更低的线程优先级。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值