本文主要是介绍x264源码分析三:x264_slices_write和x264_slice_write函数分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
下面将分析x264编码的核心算法部分:
首先先了解一下x264中比特流的层次结构:每个比特都隶属于某个句法元素,句法元素被组织成有层次的结构,分别描述各个层次的信息。如下图所示:
x264分层结构由五层组成,分别是序列参数集、图像参数集、片(Slice)、和宏块和子块。参数集是一个独立的数据单位,不依赖于参数集外的其它句法元素。下图描述了参数集与参数集外的句法元素之间的关系。
而本文所要分析的就是对应的片编码。下面看源代码:
static void *x264_slices_write( x264_t *h )
{int i_slice_num = 0;int last_thread_mb = h->sh.i_last_mb;/* init stats *///初始化一些状态memset( &h->stat.frame, 0, sizeof(h->stat.frame) );h->mb.b_reencode_mb = 0;//循环每一个slicewhile( h->sh.i_first_mb + SLICE_MBAFF*h->mb.i_mb_stride <= last_thread_mb ){h->sh.i_last_mb = last_thread_mb;if( !i_slice_num || !x264_frame_new_slice( h, h->fdec ) ){if( h->param.i_slice_max_mbs ){if( SLICE_MBAFF ){// convert first to mbaff form, add slice-max-mbs, then convert back to normal formint last_mbaff = 2*(h->sh.i_first_mb % h->mb.i_mb_width)+ h->mb.i_mb_width*(h->sh.i_first_mb / h->mb.i_mb_width)+ h->param.i_slice_max_mbs - 1;int last_x = (last_mbaff % (2*h->mb.i_mb_width))/2;int last_y = (last_mbaff / (2*h->mb.i_mb_width))*2 + 1;h->sh.i_last_mb = last_x + h->mb.i_mb_stride*last_y;}else{h->sh.i_last_mb = h->sh.i_first_mb + h->param.i_slice_max_mbs - 1;if( h->sh.i_last_mb < last_thread_mb && last_thread_mb - h->sh.i_last_mb < h->param.i_slice_min_mbs )h->sh.i_last_mb = last_thread_mb - h->param.i_slice_min_mbs;}i_slice_num++;}else if( h->param.i_slice_count && !h->param.b_sliced_threads ){int height = h->mb.i_mb_height >> PARAM_INTERLACED;int width = h->mb.i_mb_width << PARAM_INTERLACED;i_slice_num++;h->sh.i_last_mb = (height * i_slice_num + h->param.i_slice_count/2) / h->param.i_slice_count * width - 1;}}h->sh.i_last_mb = X264_MIN( h->sh.i_last_mb, last_thread_mb );//利用函数指针进行具体的块编码操作if( x264_stack_align( x264_slice_write, h ) )goto fail;h->sh.i_first_mb = h->sh.i_last_mb + 1;// if i_first_mb is not the last mb in a row then go to the next mb in MBAFF orderif( SLICE_MBAFF && h->sh.i_first_mb % h->mb.i_mb_width )h->sh.i_first_mb -= h->mb.i_mb_stride;}return (void *)0;fail:/* Tell other threads we're done, so they wouldn't wait for it */if( h->param.b_sliced_threads )x264_threadslice_cond_broadcast( h, 2 );return (void *)-1;
}
下面分析具体的块编码函数源代码:
static intptr_t x264_slice_write( x264_t *h )
{int i_skip;int mb_xy, i_mb_x, i_mb_y;/* NALUs other than the first use a 3-byte startcode.* Add one extra byte for the rbsp, and one more for the final CABAC putbyt
这篇关于x264源码分析三:x264_slices_write和x264_slice_write函数分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!