以P帧为例:
void alloc_ref_pic_list_reordering_buffer(Slice *currSlice)
{
int size = currSlice->num_ref_idx_active[LIST_0] + 1;
if ((currSlice->modification_of_pic_nums_idc[LIST_0] = calloc(size ,sizeof(int)))==NULL)
no_mem_exit("alloc_ref_pic_list_reordering_buffer: modification_of_pic_nums_idc_l0");
if ((currSlice->abs_diff_pic_num_minus1[LIST_0] = calloc(size,sizeof(int)))==NULL)
no_mem_exit("alloc_ref_pic_list_reordering_buffer: abs_diff_pic_num_minus1_l0");
if ((currSlice->long_term_pic_idx[LIST_0] = calloc(size,sizeof(int)))==NULL)
no_mem_exit("alloc_ref_pic_list_reordering_buffer: long_term_pic_idx_l0");
if ((currSlice->abs_diff_view_idx_minus1[LIST_0] = calloc(size,sizeof(int)))==NULL)
no_mem_exit("alloc_ref_pic_list_reordering_buffer: abs_diff_view_idx_minus1_l0");
currSlice->modification_of_pic_nums_idc[LIST_1] = NULL;
currSlice->abs_diff_pic_num_minus1[LIST_1] = NULL;
currSlice->long_term_pic_idx[LIST_1] = NULL;
currSlice->abs_diff_view_idx_minus1[LIST_1] = NULL;
}
num_ref_idx_active: 表示当前帧有几个参考帧
modification_of_pic_nums_idc:传输帧改变的方式:0,1,2分别是 短期的加 短期的减 长期
abs_diff_pic_num_minus1: 短期参考帧,传输和当前帧差值
long_term_pic_idx: 长期参考帧,传输POC
static void ref_pic_list_reordering(Slice *currSlice)
{
//VideoParameters *p_Vid = currSlice->p_Vid;
byte dP_nr = assignSE2partition[currSlice->dp_mode][SE_HEADER];
DataPartition *partition = &(currSlice->partArr[dP_nr]);
Bitstream *currStream = partition->bitstream;
int i, val;
alloc_ref_pic_list_reordering_buffer(currSlice);
// 根据 num_ref_idx_active 分配内存空间
if (currSlice->slice_type != I_SLICE && currSlice->slice_type != SI_SLICE)
{
val = currSlice->ref_pic_list_reordering_flag[LIST_0] = read_u_1 ("SH: ref_pic_list_reordering_flag_l0", currStream, &p_Dec->UsedBits);
// 调整 RefList0
if (val)
{
i=0;
do
{
// 先读一个修改模式
// 0||1 是修改短期参考帧
// 2 是修改长期参考帧
// 紧接着就是修改内容
val = currSlice->modification_of_pic_nums_idc[LIST_0][i] = read_ue_v("SH: modification_of_pic_nums_idc_l0", currStream, &p_Dec->UsedBits);
if (val==0 || val==1)
{
// 短期参考帧的帧偏移
currSlice->abs_diff_pic_num_minus1[LIST_0][i] = read_ue_v("SH: abs_diff_pic_num_minus1_l0", currStream, &p_Dec->UsedBits);
}
else
{
if (val==2)
{
// 长期参考帧的 idx
currSlice->long_term_pic_idx[LIST_0][i] = read_ue_v("SH: long_term_pic_idx_l0", currStream, &p_Dec->UsedBits);
}
}
i++;
// assert (i>currSlice->num_ref_idx_active[LIST_0]);
} while (val != 3);
// 3 是列表调整的循环停止标志
}
}
// set reference index of redundant slices.
if(currSlice->redundant_pic_cnt && (currSlice->slice_type != I_SLICE) )
{
currSlice->redundant_slice_ref_idx = currSlice->abs_diff_pic_num_minus1[LIST_0][0] + 1;
}
}
void dec_ref_pic_marking(VideoParameters *p_Vid, Bitstream *currStream, Slice *pSlice)
{
int val;
DecRefPicMarking_t *tmp_drpm,*tmp_drpm2;
// free old buffer content
while (pSlice->dec_ref_pic_marking_buffer)
{
tmp_drpm=pSlice->dec_ref_pic_marking_buffer;
pSlice->dec_ref_pic_marking_buffer=tmp_drpm->Next;
free (tmp_drpm);
}
#if (MVC_EXTENSION_ENABLE)
if ( pSlice->idr_flag || (pSlice->svc_extension_flag == 0 && pSlice->NaluHeaderMVCExt.non_idr_flag == 0) )
#else
if (pSlice->idr_flag)
#endif
{
pSlice->no_output_of_prior_pics_flag = read_u_1("SH: no_output_of_prior_pics_flag", currStream, &p_Dec->UsedBits);
p_Vid->no_output_of_prior_pics_flag = pSlice->no_output_of_prior_pics_flag;
pSlice->long_term_reference_flag = read_u_1("SH: long_term_reference_flag", currStream, &p_Dec->UsedBits);
}
else
{
pSlice->adaptive_ref_pic_buffering_flag = read_u_1("SH: adaptive_ref_pic_buffering_flag", currStream, &p_Dec->UsedBits);
if (pSlice->adaptive_ref_pic_buffering_flag)
{
// read Memory Management Control Operation
do
{
tmp_drpm=(DecRefPicMarking_t*)calloc (1,sizeof (DecRefPicMarking_t));
tmp_drpm->Next=NULL;
val = tmp_drpm->memory_management_control_operation = read_ue_v("SH: memory_management_control_operation", currStream, &p_Dec->UsedBits);
if ((val==1)||(val==3))
{
tmp_drpm->difference_of_pic_nums_minus1 = read_ue_v("SH: difference_of_pic_nums_minus1", currStream, &p_Dec->UsedBits);
}
if (val==2)
{
tmp_drpm->long_term_pic_num = read_ue_v("SH: long_term_pic_num", currStream, &p_Dec->UsedBits);
}
if ((val==3)||(val==6))
{
tmp_drpm->long_term_frame_idx = read_ue_v("SH: long_term_frame_idx", currStream, &p_Dec->UsedBits);
}
if (val==4)
{
tmp_drpm->max_long_term_frame_idx_plus1 = read_ue_v("SH: max_long_term_pic_idx_plus1", currStream, &p_Dec->UsedBits);
}
// add command
if (pSlice->dec_ref_pic_marking_buffer==NULL)
{
pSlice->dec_ref_pic_marking_buffer=tmp_drpm;
}
else
{
tmp_drpm2=pSlice->dec_ref_pic_marking_buffer;
while (tmp_drpm2->Next!=NULL) tmp_drpm2=tmp_drpm2->Next;
tmp_drpm2->Next=tmp_drpm;
}
}
while (val != 0);
}
}
}