本文解析与参考图像标记过程相关的几个函数。
- /*!
- ************************************************************************
- * \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;
- }
- <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: //!< 帧模式
- {
- 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>