H.264参考帧列表管理分析 —— JM中相关函数解析(中)

文章深入分析了H.264编码标准中的参考帧列表管理,特别是JM编码器中涉及的参考帧重排序相关函数,探讨了这些函数如何影响编码效率。

本文解析几个与参考帧重排序的相关函数。

/*!
 ************************************************************************
 * \brief
 *    Reordering process for short-term reference pictures 短期参考帧重排序
 *
 ************************************************************************
 */
static void reorder_short_term(StorablePicture **RefPicListX, int num_ref_idx_lX_active_minus1, int picNumLX, int *refIdxLX)
{
  int cIdx, nIdx;

  StorablePicture *picLX;

  picLX = get_short_term_pic(picNumLX);	//!< 根据给定的picNumLX获取相应的短期参考帧

  for( cIdx = num_ref_idx_lX_active_minus1+1; cIdx > *refIdxLX; cIdx-- )
    RefPicListX[ cIdx ] = RefPicListX[ cIdx - 1];	 //!< 将refIdxLX位置之后的参考帧依次后移
  
  RefPicListX[ (*refIdxLX)++ ] = picLX; //!< 将给定的picNumLX短期参考帧存至refIdxLX位置

  nIdx = *refIdxLX;

  for( cIdx = *refIdxLX; cIdx <= num_ref_idx_lX_active_minus1+1; cIdx++ )
    if (RefPicListX[ cIdx ])
      if( (RefPicListX[ cIdx ]->is_long_term ) ||  (RefPicListX[ cIdx ]->pic_num != picNumLX ))	 //!< 该操作可将参考帧列表中重复的序号为picNumLX的参考帧覆盖掉
        RefPicListX[ nIdx++ ] = RefPicListX[ cIdx ];

}

 

 /*!
 ************************************************************************
 * \brief
 *    Returns short term pic with given picNum 返回给定picNum序号的短期参考帧
 *
 ************************************************************************
 */
static StorablePicture*  get_short_term_pic(int picNum)
{
  unsigned i;

  for (i=0; i<dpb.ref_frames_in_buffer; i++) //!< 遍历dpb中的参考帧
  {
    if (img->structure==FRAME) //!< 帧模式
    {
      if (dpb.fs_ref[i]->is_reference == 3)
        if ((!dpb.fs_ref[i]->frame->is_long_term)&&(dpb.fs_ref[i]->frame->pic_num == picNum))
          return dpb.fs_ref[i]->frame; //!< 找到pic_num等于picNum且不是长期参考帧的短期参考帧,返回
    }
    else //!< 场模式(略过)
    {
      if (dpb.fs_ref[i]->is_reference & 1)
        if ((!dpb.fs_ref[i]->top_field->is_long_term)&&(dpb.fs_ref[i]->top_field->pic_num == picNum))
          return dpb.fs_ref[i]->top_field;
      if (dpb.fs_ref[i]->is_reference & 2)
        if ((!dpb.fs_ref[i]->bottom_field->is_long_term)&&(dpb.fs_ref[i]->bottom_field->pic_num == picNum))
          return dpb.fs_ref[i]->bottom_field;
    }
  }
//  return NULL;
  return no_reference_picture;
}


 

/*!
 ************************************************************************
 * \brief
 *    Reordering process for long-term reference pictures 长期参考帧重排序
 *
 ************************************************************************
 */
static void reorder_long_term(StorablePicture **RefPicListX, int num_ref_idx_lX_active_minus1, int LongTermPicNum, int *refIdxLX)
{
  int cIdx, nIdx;

  StorablePicture *picLX;

  picLX = get_long_term_pic(LongTermPicNum); //!< 获取给定LongTermPicNum的相应的长期参考帧

  for( cIdx = num_ref_idx_lX_active_minus1+1; cIdx > *refIdxLX; cIdx-- )
    RefPicListX[ cIdx ] = RefPicListX[ cIdx - 1]; //!< 将refIdxLX之后的参考帧依次右移
  
  RefPicListX[ (*refIdxLX)++ ] = picLX; //!< 将LongTermPicNum对应的长期参考帧存至refIdxLX位置

  nIdx = *refIdxLX;

  for( cIdx = *refIdxLX; cIdx <= num_ref_idx_lX_active_minus1+1; cIdx++ )
    if (RefPicListX[ cIdx ])
      if( (!RefPicListX[ cIdx ]->is_long_term ) ||  (RefPicListX[ cIdx ]->long_term_pic_num != LongTermPicNum )) //!< 可将序号为LongTermPicNum重复的参考帧覆盖掉
        RefPicListX[ nIdx++ ] = RefPicListX[ cIdx ];
}
/*!
 ************************************************************************
 * \brief
 *    Returns long term pic with given LongtermPicNum
 *
 ************************************************************************
 */
static StorablePicture*  get_long_term_pic(int LongtermPicNum)
{
  unsigned i;

  for (i=0; i<dpb.ltref_frames_in_buffer; i++) //!< 遍历dpb中所有的长期参考帧
  {
    if (img->structure==FRAME) //!< 帧模式
    {
      if (dpb.fs_ltref[i]->is_reference == 3)
        if ((dpb.fs_ltref[i]->frame->is_long_term)&&(dpb.fs_ltref[i]->frame->long_term_pic_num == LongtermPicNum))
          return dpb.fs_ltref[i]->frame; //!< 找到long_term_pic_num等于LongtermPicNum的长期参考帧,返回
    }
    else //!< 场模式(略过)
    {
      if (dpb.fs_ltref[i]->is_reference & 1)
        if ((dpb.fs_ltref[i]->top_field->is_long_term)&&(dpb.fs_ltref[i]->top_field->long_term_pic_num == LongtermPicNum))
          return dpb.fs_ltref[i]->top_field;
      if (dpb.fs_ltref[i]->is_reference & 2)
        if ((dpb.fs_ltref[i]->bottom_field->is_long_term)&&(dpb.fs_ltref[i]->bottom_field->long_term_pic_num == LongtermPicNum))
          return dpb.fs_ltref[i]->bottom_field;
    }
  }
  return NULL;
}
 


                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值