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

📄 switched_filters.c

📁 JM 11.0 KTA 2.1 Source Code
💻 C
📖 第 1 页 / 共 4 页
字号:

  if(img->type == P_SLICE)
  {
    ResetAll(img->type);
    ScanMacroblocksAndApplyFunction(AccumulateError_P);       // Accumulate squared error for filter decision and offsets
    ComputeFiltersAndOffsets_P();
  }
  else if(img->type == B_SLICE)
  {
    ResetAll(img->type);

    ScanMacroblocksAndApplyFunction(AccumulateError_B);       // Accumulate squared error for frame and sequence
    ComputeFilterCombination_B();                             // Compute filter combination (unique filter per encoded frame)

    ScanMacroblocksAndApplyFunction(AccumulateOffset0_B);     // Accumulate offset data for F reference frame
    ComputeOffset0();                                         // Compute offsets for F (one offset per REFERENCE frame)

    ScanMacroblocksAndApplyFunction(AccumulateOffset1_B);     // Accumulate offset data for B reference frame
    ComputeOffset1();                                         // Compute offsets for B (one offset per REFERENCE frame)

    // Copy filter settings
    for(i = 0; i < 16; ++i)
      img->filterFrame[i] = BestCombFilterB[i];

    // Copy offsets
    for(i = 0; i < 16; ++i)
    {
      img->subpelOffset_list0[i] = SubPelOffsetF[i];
      img->subpelOffset_list1[i] = SubPelOffsetB[i];
    }

    for(i = 0; i < listXsize[LIST_0]; ++i)
      img->imgOffset_list0[i] = FrameOffsetF[i];

    for(i = 0; i < listXsize[LIST_1]; ++i)
      img->imgOffset_list1[i] = FrameOffsetB[i];
  }

  return 1; 
}

//
//
//
void initSIFOFilters()
{
  static int first = 1;

  if(first == 1)
  {  
    int i, j;
    first = 0;

    memset(img->filterSequence, 0, 16 * sizeof(int));
    memset(img->filterFrame, 0, 16 * sizeof(int));
    memset(img->subpelOffset_list0, 0, 16 * sizeof(int));
    memset(img->subpelOffset_list1, 0, 16 * sizeof(int));
    memset(img->imgOffset_list0, 0, MAX_REFERENCE_PICTURES * sizeof(int));
    memset(img->imgOffset_list0, 0, MAX_REFERENCE_PICTURES * sizeof(int));

    // Assign filters
    for(i = 0; i < 15; ++i)
      for(j = 0; j < SQR_FILTER; ++j)
      {
        SIFO_FILTER[0][i][j] = STANDARD_2D_FILTER[i][j];
        SIFO_FILTER[1][i][j] = SYMMETRIC_1[i][j];
        SIFO_FILTER[2][i][j] = SYMMETRIC_2[i][j];
      }
  }
}


//
//
//
static void UnifiedOneForthPixSwitchedFilters(int *filter, int *subpelOffset, int *imgOffset, int list)
{
  int i, j, offset;
  int frame;
  imgpel **out4Y;
  int img_width, img_height;
  int sub_pos, x_sub, y_sub;
  int icoord, jcoord;
  unsigned short ** imgY;

  for(frame = 0; frame < listXsize[list]; ++frame)
  {
    img_width  = listX[list][frame]->size_x;
    img_height = listX[list][frame]->size_y;

    out4Y  = listX[list][frame]->imgY_ups;
    imgY = listX[list][frame]->imgY;

    for(i = -4 * IMG_PAD_SIZE; i < (IMG_PAD_SIZE + img_height) * 4; ++i)
    {
      for(j = -4 * IMG_PAD_SIZE; j < (IMG_PAD_SIZE + img_width) * 4; ++j)
      {
        icoord = i + 4 * IMG_PAD_SIZE;
        jcoord = j + 4 * IMG_PAD_SIZE;

        x_sub = jcoord % 4;             // x-sub-coordinate in a 4x4block
        y_sub = icoord % 4;             // y-sub-coordinate in a 4x4block

        sub_pos = x_sub + 4 * y_sub;    // pos 0..15 in a 4x4 block

        offset = (frame == 0)? subpelOffset[sub_pos]: imgOffset[frame];

        assert(filter[sub_pos] < NUM_SIFO);
        out4Y[icoord][jcoord] = (int) Clip3Fun(0, 255, offset + 
          GetInterpolatedPixel(imgY, icoord, jcoord, img_width, img_height, sub_pos, filter[sub_pos]));
      }
    }

    offset = (frame == 0)? subpelOffset[0]: imgOffset[frame];

    for(i = 0; i < img_height; ++i)
      for(j = 0; j < img_width; ++j)
        listX[list][frame]->imgY_filt[i][j] = (int)Clip3(0, 255, listX[list][frame]->imgY[i][j] + offset);

    GenerateFullPelRepresentation(out4Y, listX[list][frame]->imgY_11_filt, img_width, img_height);  
  }
}


//
//
//
void UnifiedOneForthPixFiltSel(int filterParam)
{
  int zeroSubpelOffsets[16] = {0};
  int zeroImgOffset[MAX_REFERENCE_PICTURES] = {0};

  if(img->type == P_SLICE)
  {
    if(filterParam == SIFO_FIRST_PASS)
    {
      UnifiedOneForthPixSwitchedFilters(img->filterSequence, zeroSubpelOffsets, zeroImgOffset, LIST_0);
    }
    else
    {
      UnifiedOneForthPixSwitchedFilters(img->filterFrame, img->subpelOffset_list0, img->imgOffset_list0, LIST_0);
    }
  }
  else if(img->type == B_SLICE)
  {
    if((filterParam == SIFO_FIRST_PASS) || (filterParam == SIFO_SEQ_FILTER))
    {
      UnifiedOneForthPixSwitchedFilters(img->filterSequence, zeroSubpelOffsets, zeroImgOffset, LIST_0);
      UnifiedOneForthPixSwitchedFilters(img->filterSequence, zeroSubpelOffsets, zeroImgOffset, LIST_1);
    }
    else
    {
      UnifiedOneForthPixSwitchedFilters(img->filterFrame, img->subpelOffset_list0, img->imgOffset_list0, LIST_0);
      UnifiedOneForthPixSwitchedFilters(img->filterFrame, img->subpelOffset_list1, img->imgOffset_list1, LIST_1);
    }
  }
  else
  {
    assert(0);    // Called on a I-slice?
  }
}

//
//
//
void rdPictureCodingFilterP(void)
{
  int rd_qp = img->qp;
  int previntras = intras;
  int skip_encode = 0;
   
  active_pps = PicParSet[0];

  // Compute frame filters
  ComputeFiltersAndOffsets();

  img->write_macroblock = 0;    
  skip_encode = 0;
  if(skip_encode)
  {
    img->rd_pass = 0;
    enc_frame_picture2 = NULL;
  }
  else
  {
    img->filterParam = SIFO_FRAME_FILTER_WITH_OFFSET;
    frame_picture (frame_pic_2, 1);
    img->rd_pass=picture_coding_decision(frame_pic_1, frame_pic_2, rd_qp);
  }
  
  if(img->rd_pass == 0)
  {
    enc_picture = enc_frame_picture;
    intras = previntras;
    frame_pic = frame_pic_1;
  }
  else
  {
    enc_picture = enc_frame_picture2;
    frame_pic = frame_pic_2;
  }

  // Update sequence filters
  UpdateSequenceFilters_P();
} 


//
//
//
static int TryImplicitWP(void)
{
  int td, tb;
  float b_scaling = 0.5;

  if(listXsize[LIST_0] && listXsize[LIST_1])
  {
    td = Clip3(-128, 127, (listX[LIST_1][0]->poc - listX[LIST_0][0]->poc));
    tb = Clip3(-128, 127, (enc_picture->poc - listX[LIST_0][0]->poc));
    if (td != 0)
      b_scaling = (float) tb / (float) td;

    if(b_scaling == 0.5)
      return 0;
    else
      return 1;
  }
  else
  {
    return 0;
  }
}

//
//
//
void rdPictureCodingFilterB(void)
{
  int rd_qp = img->qp;
  int previntras = intras;

  img->write_macroblock = 0;
  if(input->GenerateMultiplePPS && TryImplicitWP())
  {    
    // Implicit WP (POC) with sequence filters
    active_pps = PicParSet[2];
    img->filterParam = SIFO_SEQ_FILTER;
    frame_picture(frame_pic_2, 1);
    img->rd_pass = picture_coding_decision(frame_pic_1, frame_pic_2, rd_qp);
  }
  else
  {
    active_pps = PicParSet[0];
    img->rd_pass = 0;
    enc_frame_picture2 = NULL;
  }

  if(img->rd_pass == 0)
  {
    enc_picture = enc_frame_picture;
    intras = previntras;
    active_pps = PicParSet[0];
  }
  else
  {
    enc_picture = enc_frame_picture2;
    previntras = intras;
  }

  // Compute filters on Pass 0 or Pass 1
  ComputeFiltersAndOffsets();

  // Frame filters and sub-pel offsets
  img->write_macroblock = 0;
  img->filterParam = SIFO_FRAME_FILTER_WITH_OFFSET;
  frame_picture(frame_pic_3, 2);

  if(img->rd_pass == 0)
    img->rd_pass = 2 * picture_coding_decision(frame_pic_1, frame_pic_3, rd_qp);  // 0 or 2
  else
    img->rd_pass += picture_coding_decision(frame_pic_2, frame_pic_3, rd_qp);     // 1 or 2

  if(img->rd_pass == 0)
  {
    enc_picture = enc_frame_picture;
  }
  else if(img->rd_pass == 1)
  {
    enc_picture = enc_frame_picture2;
  }   
  else
  {
    enc_picture = enc_frame_picture3;
    previntras = intras;
  }

  // Filters and sub-pel offsets with QP+1
  img->write_macroblock = 0;
  img->qp = rd_qp + 1;
  img->filterParam = SIFO_FRAME_FILTER_WITH_OFFSET;

  if((img->rd_pass == 0) || (img->rd_pass == 1))
  {
    img->filterParam = SIFO_SEQ_FILTER;                 // Try sequence filters with QP+1
    frame_picture(frame_pic_3, 2);                      // Reuse frame_pic_3
  }
  else if(img->rd_pass == 2)
  {
    img->filterParam = SIFO_FRAME_FILTER_WITH_OFFSET;   // Try frame filters and offsets with QP+1
    frame_picture(frame_pic_2, 1);                      // Reuse frame_pic_2
  }   

  if(img->rd_pass == 0)
  {
    img->rd_pass = picture_coding_decision(frame_pic_1, frame_pic_3, rd_qp);
    if(img->rd_pass == 0)
    {
      enc_picture = enc_frame_picture;
      intras = previntras;
      img->qp = rd_qp;
      img->rd_pass = 0;
    }
    else
    {
      enc_picture = enc_frame_picture3;
      img->qp = rd_qp + 1;
      img->rd_pass = 2;
    }   
  }
  else if(img->rd_pass == 1)
  {
    img->rd_pass = picture_coding_decision(frame_pic_2, frame_pic_3, rd_qp);
    if(img->rd_pass == 0)
    {
      enc_picture = enc_frame_picture2;
      intras = previntras;
      img->qp = rd_qp;
      img->rd_pass = 1;
    }
    else
    {
      enc_picture = enc_frame_picture3;
      img->qp = rd_qp + 1;
      img->rd_pass = 2;
    }   
  }
  else
  {
    img->rd_pass = picture_coding_decision(frame_pic_3, frame_pic_2, rd_qp);
    if(img->rd_pass == 0)
    {
      enc_picture = enc_frame_picture3;
      intras = previntras;
      img->qp = rd_qp;
      img->rd_pass = 2;
    }
    else
    {
      enc_picture = enc_frame_picture2;
      img->qp = rd_qp + 1;      
      img->rd_pass = 1;
    }
  } 

  // Update sequence filters
  UpdateSequenceFilters_B();
}
#endif




⌨️ 快捷键说明

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