⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 slice.c

📁 H.264编码实现
💻 C
📖 第 1 页 / 共 4 页
字号:
        ++i;
        break;
      }

      memcpy ( default_order, tmp_reorder, num_ref_idx_lX_active * sizeof(int));

    }
    reordering_of_pic_nums_idc[i] = 3;

    memcpy ( default_order, tmp_reorder, num_ref_idx_lX_active * sizeof(int));


    if (list_no==0)
    {
      img->currentSlice->ref_pic_list_reordering_flag_l0=1;
    }
    else
    {
      img->currentSlice->ref_pic_list_reordering_flag_l1=1;
    }
  }
}

/*!
************************************************************************
* \brief
*    decide reference picture reordering, Field only
************************************************************************
*/
void poc_ref_pic_reorder_field(StorablePicture **list, unsigned num_ref_idx_lX_active, int *reordering_of_pic_nums_idc, int *abs_diff_pic_num_minus1, int *long_term_pic_idx, int list_no)
{
  unsigned int i,j,k;

  int currPicNum, picNumLXPred;

  int default_order[32];
  int re_order[32];
  int tmp_reorder[32];
  int list_sign[32];  
  int poc_diff[32];
  int fld_type[32];

  int reorder_stop, no_reorder;
  int tmp_value, diff;

  int abs_poc_dist;
  int maxPicNum;
  unsigned int numRefs;

  int field_used[2] = {1, 2};
  int fld, idx, num_flds;

  unsigned int top_idx = 0;
  unsigned int bot_idx = 0;
  unsigned int list_size = 0;

  StorablePicture *pField[2]; // 0: TOP_FIELD, 1: BOTTOM_FIELD
  FrameStore      *pFrameStore; 

  maxPicNum  = 2 * max_frame_num;
  currPicNum = 2 * img->frame_num + 1;

  picNumLXPred = currPicNum;

  // First assign default list order.
  for (i=0; i<num_ref_idx_lX_active; i++)
  {
    default_order[i] = list[i]->pic_num;
  }

  // Now access all references in buffer and assign them
  // to a potential reordering list. For each one of these
  // references compute the poc distance compared to current
  // frame.  
  // look for eligible fields
  idx = 0;

  for (i=0; i<dpb.ref_frames_in_buffer; i++)
  {
    pFrameStore = dpb.fs_ref[i];
    pField[0]   = pFrameStore->top_field;
    pField[1]   = pFrameStore->bottom_field;
    num_flds    = (img->structure == BOTTOM_FIELD && (enc_picture->poc == (pField[0]->poc + 1) ) ) ? 1 : 2;

    poc_diff[2*i    ] = 0xFFFF;
    poc_diff[2*i + 1] = 0xFFFF;

    for ( fld = 0; fld < num_flds; fld++ )
    {
      if ( (pFrameStore->is_used & field_used[fld]) && pField[fld]->used_for_reference && !(pField[fld]->is_long_term) )
      {
        abs_poc_dist = iabs(pField[fld]->poc - enc_picture->poc) ;
        poc_diff[idx] = abs_poc_dist;
        re_order[idx] = pField[fld]->pic_num;
        fld_type[idx] = fld + 1;

        if (list_no == LIST_0)
        {
          list_sign[idx] = (enc_picture->poc < pField[fld]->poc) ? +1 : -1;
        }
        else
        {
          list_sign[idx] = (enc_picture->poc > pField[fld]->poc) ? +1 : -1;
        }
        idx++;
      }
    }
  }
  numRefs = idx;

  // now sort these references based on poc (temporal) distance
  for (i=0; i < numRefs-1; i++)
  {
    for (j = (i + 1); j < numRefs; j++)
    {
      if (poc_diff[i] > poc_diff[j] || (poc_diff[i] == poc_diff[j] && list_sign[j] > list_sign[i]))
      {
        // poc_diff
        tmp_value   = poc_diff[i];
        poc_diff[i] = poc_diff[j];
        poc_diff[j] = tmp_value;
        // re_order (PicNum)
        tmp_value   = re_order[i];
        re_order[i] = re_order[j];
        re_order[j] = tmp_value;
        // list_sign
        tmp_value    = list_sign[i];
        list_sign[i] = list_sign[j];
        list_sign[j] = tmp_value;
        // fld_type
        tmp_value   = fld_type[i];
        fld_type[i] = fld_type[j];
        fld_type[j] = tmp_value ;
      }
    }
  }

  if (img->structure == TOP_FIELD)
  {
    while ((top_idx < numRefs)||(bot_idx < numRefs))
    {
      for ( ; top_idx < numRefs; top_idx++)
      {
        if ( fld_type[top_idx] == TOP_FIELD )
        {
          tmp_reorder[list_size] = re_order[top_idx];
          list_size++;
          top_idx++;
          break;
        }
      }
      for ( ; bot_idx < numRefs; bot_idx++)
      {
        if ( fld_type[bot_idx] == BOTTOM_FIELD )
        {
          tmp_reorder[list_size] = re_order[bot_idx];
          list_size++;
          bot_idx++;
          break;
        }
      }
    }
  }
  if (img->structure == BOTTOM_FIELD)
  {
    while ((top_idx < numRefs)||(bot_idx < numRefs))
    {
      for ( ; bot_idx < numRefs; bot_idx++)
      {
        if ( fld_type[bot_idx] == BOTTOM_FIELD )
        {
          tmp_reorder[list_size] = re_order[bot_idx];
          list_size++;
          bot_idx++;
          break;
        }
      }
      for ( ; top_idx < numRefs; top_idx++)
      {
        if ( fld_type[top_idx] == TOP_FIELD )
        {
          tmp_reorder[list_size] = re_order[top_idx];
          list_size++;
          top_idx++;
          break;
        }
      }
    }
  }

  // copy to final matrix
  list_size = imin( list_size, 32 );
  for ( i = 0; i < list_size; i++ )
  {
    re_order[i] = tmp_reorder[i];
  }

  // Check versus default list to see if any
  // change has happened
  no_reorder = 1;
  for (i=0; i<num_ref_idx_lX_active; i++)
  {
    if (default_order[i] != re_order[i])
    {
      no_reorder = 0;
    }
  }

  // If different, then signal reordering
  if (no_reorder == 0)
  {
    for (i=0; i<num_ref_idx_lX_active; i++)
    {
      diff = re_order[i] - picNumLXPred;
      if (diff <= 0)
      {
        reordering_of_pic_nums_idc[i] = 0;
        abs_diff_pic_num_minus1[i] = iabs(diff)-1;
        if (abs_diff_pic_num_minus1[i] < 0)
          abs_diff_pic_num_minus1[i] = maxPicNum -1;
      }
      else
      {
        reordering_of_pic_nums_idc[i] = 1;
        abs_diff_pic_num_minus1[i] = iabs(diff)-1;
      }
      picNumLXPred = re_order[i];

      tmp_reorder[i] = re_order[i];

      k = i;
      for (j = i; j < num_ref_idx_lX_active; j++)
      {
        if (default_order[j] != re_order[i])
        {
          ++k;
          tmp_reorder[k] = default_order[j];
        }
      }
      reorder_stop = 1;
      for(j=i+1; j<num_ref_idx_lX_active; j++)
      {
        if (tmp_reorder[j] != re_order[j])
        {
          reorder_stop = 0;
          break;
        }
      }

      if (reorder_stop==1)
      {
        ++i;
        break;
      }

      memcpy ( default_order, tmp_reorder, num_ref_idx_lX_active * sizeof(int));
    }
    reordering_of_pic_nums_idc[i] = 3;

    memcpy ( default_order, tmp_reorder, num_ref_idx_lX_active * sizeof(int));

    if (list_no==0)
    {
      img->currentSlice->ref_pic_list_reordering_flag_l0 = 1;
    }
    else
    {
      img->currentSlice->ref_pic_list_reordering_flag_l1 = 1;
    }
  }
}

void UpdateMELambda(ImageParameters *img)
{
  int j, k, qp;
  if (params->UpdateLambdaChromaME)
  {
    for (j = 0; j < 6; j++)
    {
      for (qp = -img->bitdepth_luma_qp_scale; qp < 52; qp++)
      { 
        for (k = 0; k < 3; k++)
        {
          if ((params->MEErrorMetric[k] == ERROR_SAD) && (params->ChromaMEEnable))
          {
            switch(params->yuv_format)
            {
            case YUV420:
              img->lambda_mf[j][qp][k] = (3 * img->lambda_mf[j][qp][k] + 1) >> 1;
              img->lambda_me[j][qp][k] *= 1.5;
              break;
            case YUV422:
              img->lambda_mf[j][qp][k] *= 2;
              img->lambda_me[j][qp][k] *= 2.0;
              break;
            case YUV444:
              img->lambda_mf[j][qp][k] *= 3;
              img->lambda_me[j][qp][k] *= 3.0;
              break;
            default:
              break;
            }
          }
        }
      }
    }
  }
}

void SetLambda(int j, int qp, double lambda_scale)
{
  int k;
  img->lambda_md[j][qp] *= lambda_scale;

  for (k = F_PEL; k <= Q_PEL; k++)
  {
    img->lambda_me[j][qp][k] =  (params->MEErrorMetric[k] == ERROR_SSE) ? img->lambda_md[j][qp] : sqrt(img->lambda_md[j][qp]);
    img->lambda_mf[j][qp][k] = LAMBDA_FACTOR (img->lambda_me[j][qp][k]);
  }
}

void SetLagrangianMultipliersOn()
{
  int qp, j;
  double qp_temp;
  double lambda_scale = 1.0 - dClip3(0.0,0.5,0.05 * (double) params->jumpd);;

  if (params->UseExplicitLambdaParams == 1) // consideration of explicit lambda weights.
  {
    for (j = 0; j < 6; j++)
    {
      for (qp = -img->bitdepth_luma_qp_scale; qp < 52; qp++)
      {
        qp_temp = (double)qp + img->bitdepth_luma_qp_scale - SHIFT_QP;

        img->lambda_md[j][qp] = params->LambdaWeight[j] * pow (2, qp_temp/3.0);
        SetLambda(j, qp, ((params->MEErrorMetric[H_PEL] == ERROR_SATD && params->MEErrorMetric[Q_PEL] == ERROR_SATD) ? 1.00 : 0.95));
      }
    }
  }
  else if (params->UseExplicitLambdaParams == 2) // consideration of fixed lambda values.
  {
    for (j = 0; j < 6; j++)
    {
      for (qp = -img->bitdepth_luma_qp_scale; qp < 52; qp++)
      {
        qp_temp = (double)qp + img->bitdepth_luma_qp_scale - SHIFT_QP;

        img->lambda_md[j][qp] = params->FixedLambda[j];
        SetLambda(j, qp, ((params->MEErrorMetric[H_PEL] == ERROR_SATD && params->MEErrorMetric[Q_PEL] == ERROR_SATD) ? 1.00 : 0.95));
      }
    }
  }
  else
  {
    for (j = 0; j < 5; j++)
    {
      for (qp = -img->bitdepth_luma_qp_scale; qp < 52; qp++)
      {
        qp_temp = (double)qp + img->bitdepth_luma_qp_scale - SHIFT_QP;

        if (params->successive_Bframe > 0)
          img->lambda_md[j][qp] = 0.68 * pow (2, qp_temp/3.0)
          * (j == B_SLICE && img->b_frame_to_code != 0 ? dClip3(2.00, 4.00, (qp_temp / 6.0)) : (j == SP_SLICE) ? dClip3(1.4,3.0,(qp_temp / 12.0)) : 1.0);
        else
          img->lambda_md[j][qp] = 0.85 * pow (2, qp_temp/3.0) * ((j == SP_SLICE) ? dClip3(1.4, 3.0,(qp_temp / 12.0)) : 1.0);

        // Scale lambda due to hadamard qpel only consideration
        img->lambda_md[j][qp] = ((params->MEErrorMetric[H_PEL] == ERROR_SATD && params->MEErrorMetric[Q_PEL] == ERROR_SATD) ? 1.00 : 0.95) * img->lambda_md[j][qp];
        //img->lambda_md[j][qp] = (j == B_SLICE && params->BRefPictures == 2 && img->b_frame_to_code == 0 ? 0.50 : 1.00) * img->lambda_md[j][qp];

        if (j == B_SLICE)
        {
          img->lambda_md[5][qp] = img->lambda_md[j][qp];

          if (img->b_frame_to_code != 0)
          {
            if (params->HierarchicalCoding == 2)
              img->lambda_md[5][qp] *= (1.0 - dmin(0.4, 0.2 * (double) gop_structure[img->b_frame_to_code-1].hierarchy_layer));
            else
              img->lambda_md[5][qp] *= 0.80;

          }
          SetLambda(5, qp, lambda_scale);
        }
        else
          img->lambda_md[j][qp] *= lambda_scale;

        SetLambda(j, qp, 1.0);

        if (params->CtxAdptLagrangeMult == 1)
        {
          int lambda_qp = (qp >= 32 && !params->RCEnable) ? imax(0, qp - 4) : imax(0, qp - 6);
          img->lambda_mf_factor[j][qp] = log (img->lambda_me[j][lambda_qp][Q_PEL] + 1.0) / log (2.0);
        }
      }
    }
  }

  UpdateMELambda(img);
}


void SetLagrangianMultipliersOff()
{
  int qp, j, k;
  double qp_temp;

  for (j = 0; j < 6; j++)
  {
    for (qp = -img->bitdepth_luma_qp_scale; qp < 52; qp++)
    {
      qp_temp = (double)qp + img->bitdepth_luma_qp_scale - SHIFT_QP;

      switch (params->UseExplicitLambdaParams)
      {
      case 1:  // explicit lambda weights
        img->lambda_md[j][qp] = sqrt(params->LambdaWeight[j] * pow (2, qp_temp/3.0));
        break;
      case 2: // explicit lambda
        img->lambda_md[j][qp] = sqrt(params->FixedLambda[j]);
        break;
      default:
        img->lambda_md[j][qp] = QP2QUANT[imax(0,qp - SHIFT_QP)];
        break;
      }

      for (k = F_PEL; k <= Q_PEL; k++)
      {
        img->lambda_me[j][qp][k]  = (params->MEErrorMetric[k] == ERROR_SSE) ? (img->lambda_md[j][qp] * img->lambda_md[j][qp]) : img->lambda_md[j][qp];
        img->lambda_mf[j][qp][k]  = LAMBDA_FACTOR (img->lambda_me[j][qp][k]);
      }

      if (params->CtxAdptLagrangeMult == 1)
      {
        int lambda_qp = (qp >= 32 && !params->RCEnable) ? imax(0, qp-4) : imax(0, qp-6);
        img->lambda_mf_factor[j][qp] = log (img->lambda_me[j][lambda_qp][Q_PEL] + 1.0) / log (2.0);
      }
    }
  }
  UpdateMELambda(img);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -