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

📄 epzs.c

📁 H264视频编解码程序
💻 C
📖 第 1 页 / 共 5 页
字号:
  int searcharray = input->BiPredMotionEstimation? 2 * max (input->search_range, input->BiPredMESearchRange) + 1 : 2 * input->search_range + 1;
  int searchlevels = RoundLog2 (input->search_range) - 1;  
  
  //! In this implementation we keep threshold limits fixed.
  //! However one could adapt these limits based on lagrangian 
  //! optimization considerations (i.e. qp), while also allow 
  //! adaptation of the limits themselves based on content or complexity. 
  for (i=0;i<8;i++)
  {
    medthres[i] = input->EPZSMedThresScale * medthres_base[i] * pel_error_me;
    maxthres[i] = input->EPZSMaxThresScale * maxthres_base[i] * pel_error_me;
    minthres[i] = input->EPZSMinThresScale * minthres_base[i] * pel_error_me;
    subthres[i] = input->EPZSSubPelThresScale * medthres_base[i] * pel_error_me;
  }
  
  //! Definition of pottential EPZS patterns.
  //! It is possible to also define other patterns, or even use
  //! resizing patterns (such as the PMVFAST scheme. These patterns
  //! are only shown here as reference, while the same also holds
  //! for this implementation (i.e. new conditions could be added
  //! on adapting predictors, or thresholds etc. Note that search
  //! could also be performed on subpel positions directly while 
  //! pattern needs not be restricted on integer positions only.
  
  //! Allocate memory and assign search patterns
  sdiamond = allocEPZSpattern(4);
  assignEPZSpattern(sdiamond, SDIAMOND);
  square = allocEPZSpattern(8);
  assignEPZSpattern(square, SQUARE);
  ediamond = allocEPZSpattern(12);
  assignEPZSpattern(ediamond, EDIAMOND);
  ldiamond = allocEPZSpattern(8);  
  assignEPZSpattern(ldiamond, LDIAMOND);
  
  //! Allocate and assign window based predictors. 
  //! Other window types could also be used, while method could be 
  //! made a bit more adaptive (i.e. patterns could be assigned 
  //! based on neighborhood
  window_predictor = allocEPZSpattern(searchlevels * 8);
  window_predictor_extended = allocEPZSpattern(searchlevels * 20);  
  EPZSWindowPredictorInit ((short) input->search_range, window_predictor, 0);
  EPZSWindowPredictorInit ((short) input->search_range, window_predictor_extended, 1);
  //! Also assing search predictor memory
  // maxwindow + spatial + blocktype + temporal + memspatial
  predictor = allocEPZSpattern(searchlevels * 20 + 5 + 5 + 9 * (input->EPZSTemporal) + 3 * (input->EPZSSpatialMem));
  
  //! Finally assign memory for all other elements 
  //! (distortion, EPZSMap, and temporal predictors)
  
  memory_size += get_mem3Dint (&EPZSDistortion, 6, 7, img->width/BLOCK_SIZE);
  memory_size += get_mem2D (&EPZSMap, searcharray, searcharray );
  if (input->EPZSSpatialMem)
  {
#if EPZSREF
    memory_size += get_mem6Dshort (&EPZSMotion, 6, img->max_num_references, 7, 4, img->width/BLOCK_SIZE, 2);
#else
    memory_size += get_mem5Dshort (&EPZSMotion, 6, 7, 4, img->width/BLOCK_SIZE, 2);
#endif
  }
  
  if (input->EPZSTemporal)
    EPZSCo_located = allocEPZScolocated (img->width, img->height, 
    active_sps->mb_adaptive_frame_field_flag);
  
  switch (input->EPZSPattern)
  {
  case 3:
    searchPattern = ldiamond;
    break;
  case 2:
    searchPattern = ediamond;
    break;
  case 1:
    searchPattern = square;
    break;
  case 0:
  default:
    searchPattern = sdiamond;
    break;
  }
  
  switch (input->EPZSDual)
  {
  case 4:
    searchPatternD = ldiamond;
    break;
  case 3:
    searchPatternD = ediamond;
    break;
  case 2:
    searchPatternD = square;
    break;
  case 1:
  default:
    searchPatternD = sdiamond;
    break;
  }
  
  return memory_size;
}

/*!
************************************************************************
* \brief
*    Delete EPZS Alocated memory
************************************************************************
*/
void EPZSDelete (void)
{
  if (input->EPZSTemporal)
    freeEPZScolocated (EPZSCo_located);
  
  free_mem2D (EPZSMap);
  free_mem3Dint (EPZSDistortion, 6);
  freeEPZSpattern(window_predictor_extended);
  freeEPZSpattern(window_predictor);
  freeEPZSpattern(predictor);
  freeEPZSpattern(ldiamond);
  freeEPZSpattern(ediamond);
  freeEPZSpattern(sdiamond);
  freeEPZSpattern(square);
  if (input->EPZSSpatialMem)
  {
#if EPZSREF
    free_mem6Dshort (EPZSMotion, 6, img->max_num_references, 7, 4);
#else
    free_mem5Dshort (EPZSMotion, 6, 7, 4); 
#endif
  }
  
}

//! For ME purposes restricting the co-located partition is not necessary.
/*!
************************************************************************
* \brief
*    EPZS Slice Level Initialization 
************************************************************************
*/
void
EPZSSliceInit (EPZSColocParams * p, 
               StorablePicture ** listX[6])
{
  StorablePicture *fs, *fs_top, *fs_bottom;
  StorablePicture *fs1, *fs_top1, *fs_bottom1, *fsx;
  int i, j, k, jj, jdiv, loffset;
  int prescale, iTRb, iTRp;
  int list = img->type == B_SLICE ? LIST_1 : LIST_0;
  int tempmv_scale[2];
  int epzs_scale[2][6][MAX_LIST_SIZE];
  int iref; 
  
  // Lets compute scaling factoes between all references in lists.
  // Needed to scale spatial predictors.
  for (j = LIST_0; j < 2 + (img->MbaffFrameFlag * 4); j ++)
  {
    for (k = 0; k < listXsize[j]; k++)   
    {
      for (i = 0; i < listXsize[j]; i++)
      {
        if (j/2 == 0) 
        {
          iTRb = Clip3 (-128, 127, enc_picture->poc - listX[j][i]->poc);
          iTRp = Clip3 (-128, 127, enc_picture->poc - listX[j][k]->poc);
        }
        else if (j/2 == 1)
        {
          iTRb = Clip3 (-128, 127, enc_picture->top_poc - listX[j][i]->poc);
          iTRp = Clip3 (-128, 127, enc_picture->top_poc - listX[j][k]->poc);
        }
        else 
        {
          iTRb = Clip3 (-128, 127, enc_picture->bottom_poc - listX[j][i]->poc);
          iTRp = Clip3 (-128, 127, enc_picture->bottom_poc - listX[j][k]->poc);
        }
        
        if (iTRp != 0)
        {
          prescale = (16384 + abs (iTRp / 2)) / iTRp;
          mv_scale[j][i][k] = Clip3 (-2048, 2047, (iTRb * prescale + 32) >> 6);
        }
        else
          mv_scale[j][i][k] = 256;
      }
    }
  }      
  
  if (input->EPZSTemporal)
  {
    fs_top = fs_bottom = fs = listX[list][0];
    if (listXsize[0]> 1)
      fs_top1 = fs_bottom1 = fs1 = listX[list][1];
    else
      fs_top1 = fs_bottom1 = fs1 = listX[list][0];
    
    for (j = 0; j < 6; j++)
    {
      for (i = 0; i < 6; i++)
      {
        epzs_scale[0][j][i] = 256;
        epzs_scale[1][j][i] = 256;
      }
    }
    
    for (j = 0; j < 2 + (img->MbaffFrameFlag * 4); j += 2)
    {
      for (i = 0; i < listXsize[j]; i++)
      {      
        if (j == 0)
          iTRb = Clip3 (-128, 127, enc_picture->poc - listX[LIST_0 + j][i]->poc);
        else if (j == 2)
          iTRb = Clip3 (-128, 127, enc_picture->top_poc - listX[LIST_0 + j][i]->poc);
        else
          iTRb = Clip3 (-128, 127, enc_picture->bottom_poc - listX[LIST_0 + j][i]->poc);
        iTRp = Clip3 (-128, 127, listX[list + j][0]->poc - listX[LIST_0 + j][i]->poc);      
        if (iTRp != 0)
        {
          prescale = (16384 + abs (iTRp / 2)) / iTRp;
          prescale = Clip3 (-2048, 2047, (iTRb * prescale + 32) >> 6);        
          //prescale = (iTRb * prescale + 32) >> 6;
        }
        else			// This could not happen but lets use it in case that reference is removed.
          prescale = 256;      
        epzs_scale[0][j][i] = (mv_scale[j][0][i] * prescale + 128) >> 8;
        epzs_scale[0][j + 1][i] = prescale - 256;      
        if (listXsize[j]>1)
        {
          iTRp = Clip3 (-128, 127, listX[list + j][1]->poc - listX[LIST_0 + j][i]->poc);      
          if (iTRp != 0)
          {
            prescale = (16384 + abs (iTRp / 2)) / iTRp;
            prescale = Clip3 (-2048, 2047, (iTRb * prescale + 32) >> 6);        
            //prescale = (iTRb * prescale + 32) >> 6;
          }
          else			// This could not happen but lets use it for case that reference is removed.
            prescale = 256;      
          epzs_scale[1][j][i] = (mv_scale[j][1][i] * prescale + 128) >> 8;
          epzs_scale[1][j + 1][i] = prescale - 256;      
        }
        else
        {
          epzs_scale[1][j][i] = epzs_scale[0][j][i];
          epzs_scale[1][j + 1][i] = epzs_scale[0][j + 1][i];
        }
      }
    }  
    if (img->MbaffFrameFlag)
    {
      fs_top = listX[list + 2][0];
      fs_bottom = listX[list + 4][0];
      if (listXsize[0]> 1)
      {
        fs_top1 = listX[list + 2][1];
        fs_bottom = listX[list + 4][1];
      }
    }
    else
    {
      if (img->structure != FRAME)
      {
        if ((img->structure != fs->structure) && (fs->coded_frame))
        {
          if (img->structure == TOP_FIELD)
          {
            fs_top = fs_bottom = fs = listX[list][0]->top_field;
            fs_top1 = fs_bottom1 = fs1 = listX[list][0]->bottom_field;
          }
          else
          {
            fs_top = fs_bottom = fs = listX[list][0]->bottom_field;
            fs_top1 = fs_bottom1 = fs1 = listX[list][0]->top_field;
          }
        }
      }
    }
    
    //if (!active_sps->frame_mbs_only_flag || active_sps->direct_8x8_inference_flag)
    if (!active_sps->frame_mbs_only_flag)
    {
      for (j = 0; j < fs->size_y >> 2; j++)
      {
        jj = j / 2;
        jdiv = j / 2 + 4 * (j / 8);
        for (i = 0; i < fs->size_x >> 2; i++)
        {
          if (img->MbaffFrameFlag && fs->field_frame[j][i])
          {
            //! Assign frame buffers for field MBs   
            //! Check whether we should use top or bottom field mvs.
            //! Depending on the assigned poc values.                
            if (abs (enc_picture->poc - fs_bottom->poc) > abs (enc_picture->poc - fs_top->poc))
            {
              tempmv_scale[LIST_0] = 256;
              tempmv_scale[LIST_1] = 0;
              
              if (fs->ref_id [LIST_0][jdiv][i] < 0 && listXsize[LIST_0] > 1)
              {
                fsx = fs_top1;
                loffset = 1;
              }
              else 
              {
                fsx = fs_top;
                loffset = 0;
              }             
              
              if (fs->ref_id [LIST_0][jdiv][i] != -1)
              {
                for (iref=0;iref<min(img->num_ref_idx_l0_active,listXsize[LIST_0]);iref++)
                {
                  if (enc_picture->ref_pic_num[LIST_0][iref]==fs->ref_id [LIST_0][jdiv][i])
                  {
                    tempmv_scale[LIST_0] = epzs_scale[loffset][LIST_0][iref];
                    tempmv_scale[LIST_1] = epzs_scale[loffset][LIST_1][iref];
                    break;
                  }
                }
                p->mv[LIST_0][j][i][0] = (tempmv_scale[LIST_0] * fsx->mv[LIST_0][jj][i][0] + 32) >> 6;
                p->mv[LIST_0][j][i][1] = (tempmv_scale[LIST_0] * fsx->mv[LIST_0][jj][i][1] + 32) >> 6;
                p->mv[LIST_1][j][i][0] = (tempmv_scale[LIST_1] * fsx->mv[LIST_0][jj][i][0] + 32) >> 6;
                p->mv[LIST_1][j][i][1] = (tempmv_scale[LIST_1] * fsx->mv[LIST_0][jj][i][1] + 32) >> 6;
              }
              else
              {
                p->mv[LIST_0][j][i][0] = 0;
                p->mv[LIST_0][j][i][1] = 0;
                p->mv[LIST_1][j][i][0] = 0;
                p->mv[LIST_1][j][i][1] = 0;        
              }          
              
            }
            else
            {
              tempmv_scale[LIST_0] = 256;
              tempmv_scale[LIST_1] = 0;
              

⌨️ 快捷键说明

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