diff=0;
for (j = 0; j< listXsize[0]; j++) //!< 检查listX[0]和listX[1]是否相同
{
if (listX[0][j]!=listX[1][j])
diff=1;
}
if (!diff) //!< 如果两个列表相同,则交换listX[1]前两个元素的位置
{
tmp_s = listX[1][0];
listX[1][0]=listX[1][1];
listX[1][1]=tmp_s;
}
}
// set max size
listXsize[0] = min (listXsize[0], img->num_ref_idx_l0_active);
listXsize[1] = min (listXsize[1], img->num_ref_idx_l1_active);
// set the unused list entries to NULL
for (i=listXsize[0]; i< (MAX_LIST_SIZE) ; i++)
{
listX[0][i] = NULL;
}
for (i=listXsize[1]; i< (MAX_LIST_SIZE) ; i++)
{
listX[1][i] = NULL;
}
}
上述代码中,有个函数qsort,关于它的用法,在我的另一篇博客qsort 函数的使用 有简单的介绍。
(2)参考帧列表的重排序
主要在函数reorder_ref_pic_list(StorablePicture **list, int *list_size, int num_ref_idx_lX_active_minus1, int *reordering_of_pic_nums_idc, int *abs_diff_pic_num_minus1, int *long_term_pic_idx)中实现,在编码端被 init_slice (int start_mb_addr)调用,在解码端被read_new_slice()中的子函数reorder_lists(int currSliceType, Slice * currSlice)调用。
[cpp]
/*!
************************************************************************
* \brief
* Reordering process for reference picture lists
*
************************************************************************
*/
void reorder_ref_pic_list(StorablePicture **list, int *list_size, int num_ref_idx_lX_active_minus1, int *reordering_of_pic_nums_idc, int *abs_diff_pic_num_minus1, int *long_term_pic_idx)
{
int i;
int maxPicNum, currPicNum, picNumLXNoWrap, picNumLXPred, picNumLX;
int refIdxLX = 0;
if (img->structure==FRAME) //!< 帧模式
{
maxPicNum = img->MaxFrameNum; //!< frame_num的最大值
currPicNum = img->frame_num; //!< 当前帧的frame_num
}
else
{
maxPicNum = 2 * img->MaxFrameNum;
currPicNum = 2 * img->frame_num + 1;
}
picNumLXPred = currPicNum; //!< 预测值变量
for (i=0; reordering_of_pic_nums_idc[i]!=3; i++) //!< 重排序操作循环
{
if (reordering_of_pic_nums_idc[i]>3) //!< 该句法元素取值范围为0~3,3表示结束循环,退出重排序操作
error ("Invalid remapping_of_pic_nums_idc command", 500);
if (reordering_of_pic_nums_idc[i] < 2) //!< 短期参考帧重排序
{
if (reordering_of_pic_nums_idc[i] == 0) //!< 当前帧的PicNum减去(abs_diff_pic_num_minus1[i] + 1)指明需要重排序的图像
{
if( picNumLXPred - ( abs_diff_pic_num_minus1[i] + 1 ) < 0 ) //!< 预测值小于实际值
picNumLXNoWrap = picNumLXPred - ( abs_diff_pic_num_minus1[i] + 1 ) + maxPicNum; //!< frame_num循环计数
else
picNumLXNoWrap = picNumLXPred - ( abs_diff_pic_num_minus1[i] + 1 );
}
else // (remapping_of_pic_nums_idc[i] == 1) //!< 当前帧的PicNum加上(abs_diff_pic_num_minus1[i] + 1)指明需要重排序的图像
{
if( picNumLXPred + ( abs_diff_pic_num_minus1[i] + 1 ) >= maxPicNum ) //!< 预测值大于实际值
picNumLXNoWrap = picNumLXPred + ( abs_diff_pic_num_minus1[i] + 1 ) - maxPicNum; //!< frame_num循环计数
else
picNumLXNoWrap = picNumLXPred + ( abs_diff_pic_num_minus1[i] + 1 );
}
picNumLXPred = picNumLXNoWrap;
if( picNumLXNoWrap > currPicNum )
picNumLX = picNumLXNoWrap - maxPicNum;
else
picNumLX = picNumLXNoWrap;
//!< picNumLX存放的是需要移至refIdxLX位置的短期参考图像的PicNum
reorder_short_term(list, num_ref_idx_lX_active_minus1, picNumLX, &refIdxLX); //!< 调用该函数实现短期参考帧的重排序
}
else //(remapping_of_pic_nums_idc[i] == 2) //!< 长期参考帧重排序
{//!< long_term_pic_idx[i]存放的是需要移至refIdxLX位置的短期参考图像的序号
reorder_long_term(list, num_ref_idx_lX_active_minus1, long_term_pic_idx[i], &refIdxLX); //!< 调用该函数实现长期参考帧的重排序
}
}
// that's a definition
*list_size = num_ref_idx_lX_active_minus1 + 1;
}
(3)参考图像的标记
主要由两种,一种是滑窗标记即FIFO,另一种是自适应标记。
前者由函数sliding_window_memory_management(StorablePicture* p)实现,后者由函数adapt