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

📄 conformance.c

📁 the newest JM software by h.264 JVT official reference model.
💻 C
📖 第 1 页 / 共 2 页
字号:
  {
    snprintf(errortext, ET_SIZE, "\nIntraProfile requires IDRPeriod >= 1.");
    error (errortext, 500);
  }

  if (params->IntraProfile && params->intra_period != 1) 
  {
    snprintf(errortext, ET_SIZE, "\nIntraProfile requires IntraPeriod equal 1.");
    error (errortext, 500);
  }

  if (params->IntraProfile && params->num_ref_frames) 
  {
    fprintf( stderr, "\nWarning: Setting NumberReferenceFrames to 0 in IntraProfile.");
    params->num_ref_frames = 0;
  }

  if (params->IntraProfile == 0 && params->num_ref_frames == 0) 
  {
    snprintf(errortext, ET_SIZE, "\nProfiles other than IntraProfile require NumberReferenceFrames > 0.");
    error (errortext, 500);
  }
}

/*!
 ***********************************************************************
 * \brief
 *    Check if Level constraints are satisfied
 ***********************************************************************
 */
void LevelCheck(void)
{
  unsigned int PicSizeInMbs = ( (params->output.width + img->auto_crop_right) * (params->output.height + img->auto_crop_bottom) ) >> 8;
  unsigned int MBProcessingRate = (unsigned int) (PicSizeInMbs * params->output.frame_rate + 0.5);

  if ( (params->LevelIDC>=30) && (params->directInferenceFlag==0))
  {
    fprintf( stderr, "\nWarning: LevelIDC 3.0 and above require direct_8x8_inference to be set to 1. Please check your settings.\n");
    params->directInferenceFlag=1;
  }
  if ( ((params->LevelIDC<21) || (params->LevelIDC>41)) && (params->PicInterlace > 0 || params->MbInterlace > 0) )
  {
    snprintf(errortext, ET_SIZE, "\nInterlace modes only supported for LevelIDC in the range of 21 and 41. Please check your settings.\n");
    error (errortext, 500);
  }

  if ( PicSizeInMbs > getMaxFs(params->LevelIDC) )
  {
    snprintf(errortext, ET_SIZE, "\nPicSizeInMbs exceeds maximum allowed size at specified LevelIdc %.1f\n", (float) params->LevelIDC / 10.0);
    error (errortext, 500);
  }
  
  if (params->IntraProfile && (PicSizeInMbs > 1620) && params->slice_mode != 1) 
  {
    error ("\nIntraProfile with PicSizeInMbs > 1620 requires SliceMode equal 1.", 500);
  }

  if (params->IntraProfile && (PicSizeInMbs > 1620) && ((unsigned int)params->slice_argument > (  getMaxFs(params->LevelIDC) >> 2 ) ) )
  {
    //when PicSizeInMbs is greater than 1620, the number of macroblocks in any coded slice shall not exceed MaxFS / 4
    snprintf(errortext, ET_SIZE, "\nIntraProfile requires SliceArgument smaller or equal to 1/4 MaxFs at specified LevelIdc %d.", params->LevelIDC);
    error (errortext, 500);
  }

  if ( MBProcessingRate > getMaxMBPS(params->LevelIDC) )
  {
    snprintf(errortext, ET_SIZE, "\nMB Processing Rate (%d) exceeds maximum allowed processing rate (%d) at specified LevelIdc %.1f\n", 
      MBProcessingRate, getMaxMBPS(params->LevelIDC), (float) params->LevelIDC / 10.0);
    error (errortext, 500);
  }
}

/*!
 ***********************************************************************
 * \brief
 *    Update Motion Vector Limits
 ***********************************************************************
 */
void update_mv_limits(ImageParameters *img, byte is_field)
{
  memcpy(img->MaxVmvR, LEVELVMVLIMIT[img->LevelIndex], 6 * sizeof(int));
  memcpy(img->MaxHmvR, LEVELHMVLIMIT, 6 * sizeof(int));
  if (is_field)
  {
    int i;
    for (i = 0; i < 6; i++)
      img->MaxVmvR[i] = rshift_rnd(img->MaxVmvR[i], 1);
  }
  if (params->UseMVLimits)
  {
    img->MaxVmvR[0] = imax(img->MaxVmvR[0], -(params->SetMVYLimit));
    img->MaxVmvR[1] = imin(img->MaxVmvR[1],  (params->SetMVYLimit));
    img->MaxVmvR[2] = imax(img->MaxVmvR[2], -(params->SetMVYLimit << 1));
    img->MaxVmvR[3] = imin(img->MaxVmvR[3],  (params->SetMVYLimit << 1));
    img->MaxVmvR[4] = imax(img->MaxVmvR[4], -(params->SetMVYLimit << 2));
    img->MaxVmvR[5] = imin(img->MaxVmvR[5],  (params->SetMVYLimit << 2));

    img->MaxHmvR[0] = imax(img->MaxHmvR[0], -(params->SetMVXLimit));
    img->MaxHmvR[1] = imin(img->MaxHmvR[1],  (params->SetMVXLimit));
    img->MaxHmvR[2] = imax(img->MaxHmvR[2], -(params->SetMVXLimit << 1));
    img->MaxHmvR[3] = imin(img->MaxHmvR[3],  (params->SetMVXLimit << 1));
    img->MaxHmvR[4] = imax(img->MaxHmvR[4], -(params->SetMVXLimit << 2));
    img->MaxHmvR[5] = imin(img->MaxHmvR[5],  (params->SetMVXLimit << 2));
  }
}


/*!
 ***********************************************************************
 * \brief
 *    Clip motion vector range given encoding level
 ***********************************************************************
 */
void clip_mv_range(ImageParameters *img, int search_range, MotionVector *mv, int res)
{
  search_range <<= res;
  res <<= 1;

  mv->mv_x = iClip3( img->MaxHmvR[0 + res] + search_range, img->MaxHmvR[1 + res] - search_range, mv->mv_x);
  mv->mv_y = iClip3( img->MaxVmvR[0 + res] + search_range, img->MaxVmvR[1 + res] - search_range, mv->mv_y);
}

/*!
 ***********************************************************************
 * \brief
 *    Clip motion vector range given encoding level
 ***********************************************************************
 */
void test_clip_mvs(ImageParameters *img, short mv[2], Boolean write_mb)
{
  if ((mv[0] < img->MaxHmvR[4]) || (mv[0] > img->MaxHmvR[5]) || (mv[1] < img->MaxVmvR[4]) || (mv[1] > img->MaxVmvR[5]))
  {
    if (write_mb == TRUE)
      printf("Warning MVs (%d %d) were out of range x(%d %d) y(%d %d). Clipping mvs before writing\n", mv[0], mv[1], img->MaxHmvR[4], img->MaxHmvR[5], img->MaxVmvR[4], img->MaxVmvR[5]);
    mv[0] = iClip3( img->MaxHmvR[4], img->MaxHmvR[5], mv[0]);
    mv[1] = iClip3( img->MaxVmvR[4], img->MaxVmvR[5], mv[1]);
  }
}
  
/*!
 ***********************************************************************
 * \brief
 *    Clip motion vector range given encoding level
 ***********************************************************************
 */
int out_of_bounds_mvs(ImageParameters *img, short mv[2])
{
  return ((mv[0] < img->MaxHmvR[4]) || (mv[0] > img->MaxHmvR[5]) || (mv[1] < img->MaxVmvR[4]) || (mv[1] > img->MaxVmvR[5]));
}

int InvalidWeightsForBiPrediction(Block8x8Info* b8x8info, int mode)
{
  int cur_blk, cur_comp;
  int best8x8l0ref, best8x8l1ref;
  int weight_sum = 0;
  int invalid_mode = 0;
  int *wbp0, *wbp1;
  for (cur_blk = 0; cur_blk < 4; cur_blk ++)
  {
    if (b8x8info->best8x8pdir[mode][cur_blk] == 2)
    { 
      best8x8l0ref = (int) b8x8info->best8x8l0ref[mode][cur_blk];
      best8x8l1ref = (int) b8x8info->best8x8l1ref[mode][cur_blk];
      wbp0 = &wbp_weight[LIST_0][best8x8l0ref][best8x8l1ref][0];
      wbp1 = &wbp_weight[LIST_1][best8x8l0ref][best8x8l1ref][0];

      for (cur_comp = 0; cur_comp < (active_sps->chroma_format_idc == YUV400 ? 1 : 3) ; cur_comp ++)
      {
        weight_sum = *wbp0++ + *wbp1++;

        if (weight_sum < -128 ||  weight_sum > 127) 
        {
          invalid_mode = 1;
          break;
        }
      }
      if (invalid_mode == 1)
        break;
    }
  }
  return invalid_mode;
}

int InvalidMotionVectors(Block8x8Info* b8x8info, int mode)
{
  int cur_blk;
  int l0ref, l1ref;
  int invalid_mode = 0;
  int i, j;

  if (mode > P8x8)
    return invalid_mode;

  // Brute force method. Note that this ignores currently subpartitions in 8x8 modes
  for (cur_blk = 0; cur_blk < 4; cur_blk ++)
  {
    i = (cur_blk & 0x01) << 1;
    j = (cur_blk >> 1) << 1;
    switch (b8x8info->best8x8pdir[mode][cur_blk])
    {
    case 0:
      l0ref = (int) b8x8info->best8x8l0ref[mode][cur_blk];
      if (out_of_bounds_mvs(img, img->all_mv [LIST_0][l0ref][mode][j][i]))
      {
        invalid_mode = 1;
        return invalid_mode;
      }
      break;
    case 1:
      l1ref = (int) b8x8info->best8x8l1ref[mode][cur_blk];
      if (out_of_bounds_mvs(img, img->all_mv [LIST_1][l1ref][mode][j][i]))
      {
        invalid_mode = 1;
        return invalid_mode;
      }
      break;
    case 2:
      l0ref = (int) b8x8info->best8x8l0ref[mode][cur_blk];
      l1ref = (int) b8x8info->best8x8l1ref[mode][cur_blk];
      if (out_of_bounds_mvs(img, img->all_mv [LIST_0][l0ref][mode][j][i]))
      {
        invalid_mode = 1;
        return invalid_mode;
      }
      if (out_of_bounds_mvs(img, img->all_mv [LIST_1][l1ref][mode][j][i]))
      {
        invalid_mode = 1;
        return invalid_mode;
      }
      break;
    default:
      break;
    }
  }

  return invalid_mode;
}

int CheckPredictionParams(pic_parameter_set_rbsp_t *active_pps, Block8x8Info *b8x8info, int mode, int bslice)
{
  // check if weights are in valid range for biprediction.
  if (bslice && active_pps->weighted_bipred_idc == 1 &&  mode < P8x8) 
  {
    if (InvalidWeightsForBiPrediction(b8x8info, mode))
      return 0;
  }

  if (InvalidMotionVectors(b8x8info, mode))
    return 0;
  
  return 1;
}

⌨️ 快捷键说明

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