本文解析與參考圖像標記過程相關的幾個函數。
[cpp]
/*!
************************************************************************
* \brief
* Perform Sliding window decoded reference picture marking process 參考圖像的滑窗標記過程
*
************************************************************************
*/
static void sliding_window_memory_management(StorablePicture* p)
{
unsigned i;
assert (!p->idr_flag);
// if this is a reference pic with sliding sliding window, unmark first ref frame
if (dpb.ref_frames_in_buffer==dpb.num_ref_frames - dpb.ltref_frames_in_buffer)//!< 減去dpb.ltref_frames_in_buffer因滑窗標記不能使用在長期參考幀上
{
for (i=0; i<dpb.used_size;i++) //!< 采取FIFO策略,將dpb中第一個短期參考幀移出參考幀列表,並更新參考幀列表
{
if (dpb.fs[i]->is_reference && (!(dpb.fs[i]->is_long_term)))
{
unmark_for_reference(dpb.fs[i]); //!< 標記該幀為非參考幀
update_ref_list(); //!< 更新參考幀列表
break;
}
}
}
p->is_long_term = 0;
}
[cpp]
<span style="font-size:12px;">/*!
************************************************************************
* \brief
* Perform Adaptive memory control decoded reference picture marking process 自適應標記過程
************************************************************************
*/
static void adaptive_memory_management(StorablePicture* p)
{
DecRefPicMarking_t *tmp_drpm;
img->last_has_mmco_5 = 0; //!< memory_management_control_operation
assert (!p->idr_flag);
assert (p->adaptive_ref_pic_buffering_flag);
while (p->dec_ref_pic_marking_buffer) //!< stores the memory management control operations
{
tmp_drpm = p->dec_ref_pic_marking_buffer; //!< 臨時保存操作,可用於在執行完該操作後釋放掉對應的內存
switch (tmp_drpm->memory_management_control_operation)
{
case 0: //!< 結束循環,退出標記操作
if (tmp_drpm->Next != NULL)
{
error ("memory_management_control_operation = 0 not last operation in buffer", 500);
}
break;
case 1: //!< 將一個短期參考圖像標記為非參考圖像
mm_unmark_short_term_for_reference(p, tmp_drpm->difference_of_pic_nums_minus1);
update_ref_list();
break;
case 2: //!< 將一個長期參考圖像標記為非參考圖像
mm_unmark_long_term_for_reference(p, tmp_drpm->long_term_pic_num);
update_ltref_list();
break;
case 3: //!< 將一個短期參考圖像轉為長期參考圖像
mm_assign_long_term_frame_idx(p, tmp_drpm->difference_of_pic_nums_minus1, tmp_drpm->long_term_frame_idx);
update_ref_list();
update_ltref_list();
break;
case 4: //!< 指明長期參考幀的最大數目
mm_update_max_long_term_frame_idx (tmp_drpm->max_long_term_frame_idx_plus1);
update_ltref_list();
break;
case 5: //!< 清空參考幀隊列,將所有參考圖像移出參考幀隊列,並禁用長期參考機制
mm_unmark_all_short_term_for_reference();
mm_unmark_all_long_term_for_reference();
img->last_has_mmco_5 = 1; //!< 此處作標記用於接下來對POC進行更新
break;
case 6: //!< 將當前圖像存為一個長期參考幀
mm_mark_current_picture_long_term(p, tmp_drpm->long_term_frame_idx);
check_num_ref();
break;
default:
error ("invalid memory_management_control_operation in buffer", 500);
}
p->dec_ref_pic_marking_buffer = tmp_drpm->Next; //!< 取下一個操作
free (tmp_drpm); //!< 釋放掉執行完的操作的內存
}
if ( img->last_has_mmco_5 )
{
p->pic_num = p->frame_num = 0; //!< 因參考幀列表清空,frame_num清零
switch (p->structure)
{
case TOP_FIELD:
{
p->poc = p->top_poc = img->toppoc =0;
break;
}
case BOTTOM_FIELD:
{
p->poc = p->bottom_poc = img->bottompoc = 0;
break;
}
case FRAME: //!< 幀模式
{ www.2cto.com
p->top_poc -= p->poc;
p->bottom_poc -= p->poc;
img->toppoc = p->top_poc;
img->bottompoc = p->bottom_poc;
p->poc = min (p->top_poc, p->bottom_poc);
img->framepoc = p->poc;
break;
}
}
img->ThisPOC = p->poc;
flush_dpb();
}
}</span>