最近在做voip相关的项目,上位机直接使用linphone进行二次开发,下位机下位机使用的是利用osip、ffmpeg开发的sip客户端。测试时ffmpeg解码时打印出如下警告信息:
Too many slices (17 >= 16), increase MAX_SLICES and recompil
Too many slices (18 >= 16), increase MAX_SLICES and recompil
Too many slices (20 >= 16), increase MAX_SLICES and recompil
...
相关代码在h264.c中
...
h0->last_slice_type = slice_type;
h->slice_num = ++h0->current_slice;
if(h->slice_num >= MAX_SLICES){
av_log(s->avctx, AV_LOG_ERROR, "Too many slices (%d >= %d), increase MAX_SLICES and recompile\n", h->slice_num, MAX_SLICES);
}
...
显然slice数超过了定义的最大值,MAX_SLICES定义
/**
* The maximum number of slices supported by the decoder.
* must be a power of 2
*/
#define MAX_SLICES 16
尝试增加到32时,下位机解码出错了,没找到原因,所以从上位机入手。在x264的编码参数x264_param_t中有slice相关的几个成员
/* Slicing parameters */
int i_slice_max_size; /* Max size per slice in bytes; includes estimated NAL overhead. */
int i_slice_max_mbs; /* Max number of MBs per slice; overrides i_slice_count. */
int i_slice_count; /* Number of slices per frame: forces rectangular slices. */
这个i_slice_count就指定了分片数量,于是到msx264.c文件的enc_preprocess函数中,将编码参数中的i_slice_count设置为15。但是测试发现,这根本没用。后来在x264源码中,找到了问题所在
//x264/encoder.c 函数x264_validate_parameters
...
if( h->param.i_slice_max_mbs || h->param.i_slice_max_size )
h->param.i_slice_count = 0;
...
从上面的代码片断中可以看到,只要i_slice_max_mbs和i_slice_max_size两个值,i_slice_count就会被清0。而msx264.c的enc_preprocess函数就有下面一条语句
params.i_slice_max_size=ms_get_payload_max_size()-100; /*-100 security margin*/
现在真相大白,直接注释掉上面的语句,测试通过。