block.c

来自「the newest JM software by h.264 JVT offi」· C语言 代码 · 共 2,206 行 · 第 1/5 页

C
2,206
字号
  // AC inverse trans/quant for MB
  for (jj=0;jj<4;jj++)
  {
    for (ii=0;ii<4;ii++)
    {
      for (j=0;j<4;j++)
      {
        memcpy(M4[j],&M1[(jj<<2)+j][(ii<<2)], BLOCK_SIZE * sizeof(int));
      }

      //For residual DPCM
      if(new_intra_mode < 2)  //residual DPCM
      {
        Residual_DPCM_4x4_for_Intra16x16(M4, new_intra_mode);  
      }

      run      = -1;
      scan_pos =  0;
      b8       = 2*(jj >> 1) + (ii >> 1);
      b4       = 2*(jj & 0x01) + (ii & 0x01);
      ACLevel  = img->cofAC [b8+pl_off][b4][0];
      ACRun    = img->cofAC [b8+pl_off][b4][1];

      for (coeff_ctr=1;coeff_ctr<16;coeff_ctr++) // set in AC coeff
      {
        i=pos_scan[coeff_ctr][0];
        j=pos_scan[coeff_ctr][1];

        run++;
        m7 = &M4[j][i];

        if (*m7 != 0)
        {
          if (is_cavlc)
            *m7 = iClip3(-CAVLC_LEVEL_LIMIT, CAVLC_LEVEL_LIMIT, *m7);

          ac_coef = 15;
          ACLevel[scan_pos  ] = *m7;
          ACRun  [scan_pos++] = run;
          run=-1;
        }
        // set adaptive rounding params to 0 since process is not meaningful here.
      }
      ACLevel[scan_pos] = 0;

      ///For residual DPCM.  inv. residual DCPM
      if(new_intra_mode<2)  
      {
        Inv_Residual_DPCM_4x4_for_Intra16x16(M4, new_intra_mode);  
      }
      for (j=0;j<4;j++)
        memcpy(&M1[(jj<<2)+j][(ii<<2)],M4[j], BLOCK_SIZE * sizeof(int)); 
    }
  }

  for (j = 0; j < 16; j++)
  {
    img_Y = &img_enc[img->pix_y + j][img->pix_x];
    predY = curr_mpr_16x16[new_intra_mode][j];        
    for (i = 0; i < 16; i++)
      img_Y[i]=(imgpel)(M1[j][i] + predY[i]);
  }

  if(img->type == SP_SLICE)
  {
    for (j = img->pix_y; j < img->pix_y + 16;j++)
      for (i = img->pix_x; i < img->pix_x + 16;i++)
        lrec[j][i]=-16; //signals an I16 block in the SP frame
  }

  return ac_coef;
}

/*!
************************************************************************
* \brief
*    The routine performs transform,quantization,inverse transform, 
*    adds the diff to the prediction and writes the result to the 
*    decoded luma frame. 
*
* \par Input:
*    currMB:          Current macroblock.
*    pl:              Color plane for 4:4:4 coding.
*    block_x,block_y: Block position inside a macro block (0,4,8,12).
*    intra:           Intra block indicator.
*
* \par Output_
*    nonzero:         0 if no levels are nonzero. \n
*                     1 if there are nonzero levels.\n
*    coeff_cost:      Coeff coding cost for thresholding consideration.\n
************************************************************************
*/
int dct_4x4(Macroblock *currMB, ColorPlane pl, int block_x,int block_y, int *coeff_cost, int intra, int is_cavlc)
{
  int j;

  int nonzero = FALSE;

  int   pos_x   = block_x >> BLOCK_SHIFT;
  int   pos_y   = block_y >> BLOCK_SHIFT;
  int   b8      = 2*(pos_y >> 1) + (pos_x >> 1) + (pl<<2);
  int   b4      = 2*(pos_y & 0x01) + (pos_x & 0x01);
  int*  ACLevel = img->cofAC[b8][b4][0];
  int*  ACRun   = img->cofAC[b8][b4][1];

  imgpel **img_enc = enc_picture->p_curr_img;
  imgpel **mb_pred = img->mb_pred[pl];
  int    **mb_ores = img->mb_ores[pl];
  int    **mb_rres = img->mb_rres[pl]; 

  int   max_imgpel_value = img->max_imgpel_value;
  int   qp = currMB->qp_scaled[pl]; 
  const byte (*pos_scan)[2] = currMB->is_field_mode ? FIELD_SCAN : SNGL_SCAN;

  int qp_rem = qp_rem_matrix[qp];

  // select scaling parameters
  levelscale    = LevelScale4x4Comp[pl][intra][qp_rem];
  invlevelscale = InvLevelScale4x4Comp[pl][intra][qp_rem];
  leveloffset   = ptLevelOffset4x4[intra][qp];

  fadjust4x4    = img->AdaptiveRounding ? (&img->ARCofAdj4x4[pl][currMB->ar_mode][block_y]) : NULL;
  img->subblock_x = ((b8&0x1)==0) ? (((b4&0x1)==0)? 0: 1) : (((b4&0x1)==0)? 2: 3); // horiz. position for coeff_count context
  img->subblock_y = (b8<2)        ? ((b4<2)       ? 0: 1) : ((b4<2)       ? 2: 3); // vert.  position for coeff_count context

  //  Forward 4x4 transform
  forward4x4(mb_ores, M1, block_y, block_x);

  // Quantization process
  nonzero = quant_4x4(&M1[block_y], block_y, block_x, qp, ACLevel, ACRun, fadjust4x4, 
    levelscale, invlevelscale, leveloffset, coeff_cost, pos_scan, COEFF_COST4x4[params->disthres], is_cavlc);

  //  Decoded block moved to frame memory
  if (nonzero)
  {
    // Inverse 4x4 transform
    inverse4x4(M1, mb_rres, block_y, block_x);

    // generate final block
    SampleReconstruct (img_enc, mb_pred, mb_rres, block_y, block_x, img->pix_y, img->pix_x + block_x, BLOCK_SIZE, BLOCK_SIZE, max_imgpel_value, DQ_BITS);
  }
  else // if (nonzero) => No transformed residual. Just use prediction.
  {
    for (j=block_y; j < block_y + BLOCK_SIZE; j++)
    {
      memcpy(&(img_enc[img->pix_y + j][img->pix_x + block_x]),&(mb_pred[j][block_x]), BLOCK_SIZE * sizeof(imgpel));
    }
  }

  return nonzero;
}



/*!
************************************************************************
* \brief
*    Process for lossless coding of coefficients.
*    The routine performs transform, quantization,inverse transform, 
*    adds the diff to the prediction and writes the result to the 
*    decoded luma frame. 
*
* \par Input:
*    currMB:          Current macroblock.
*    pl:              Color plane for 4:4:4 coding.
*    block_x,block_y: Block position inside a macro block (0,4,8,12).
*    intra:           Intra block indicator.
*
* \par Output_
*    nonzero:         0 if no levels are nonzero. \n
*                     1 if there are nonzero levels.\n
*    coeff_cost:      Coeff coding cost for thresholding consideration.\n
************************************************************************
*/
int dct_4x4_ls(Macroblock *currMB, ColorPlane pl, int block_x,int block_y,int *coeff_cost, int intra, int is_cavlc)
{
  int i,j, coeff_ctr;
  int run = -1;
  int nonzero = FALSE;  

  int   pos_x   = block_x >> BLOCK_SHIFT;
  int   pos_y   = block_y >> BLOCK_SHIFT;
  int   b8      = 2*(pos_y >> 1) + (pos_x >> 1) + (pl<<2);
  int   b4      = 2*(pos_y & 0x01) + (pos_x & 0x01);

  int*  ACL = &img->cofAC[b8][b4][0][0];
  int*  ACR = &img->cofAC[b8][b4][1][0];

  int   pix_y, pix_x;
  imgpel **img_enc = enc_picture->p_curr_img;
  imgpel **mb_pred = img->mb_pred[pl];
  int    **mb_ores = img->mb_ores[pl];
  int    **mb_rres = img->mb_rres[pl]; 
  int   *m7;

  const byte *p_scan = currMB->is_field_mode ? &FIELD_SCAN[0][0] : &SNGL_SCAN[0][0];

  // select scaling parameters
  fadjust4x4    = img->AdaptiveRounding ? (&img->ARCofAdj4x4[pl][currMB->ar_mode][block_y]) : NULL;

  if( (ipmode_DPCM < 2) && (intra))
  {
    Residual_DPCM_4x4(ipmode_DPCM, mb_ores, mb_rres, block_y, block_x);
  }
  else
  {
    for (j=block_y; j < block_y + BLOCK_SIZE; j++)
      for (i=block_x; i < block_x + BLOCK_SIZE; i++)
        mb_rres[j][i] = mb_ores[j][i];
  }

  for (coeff_ctr=0;coeff_ctr < 16;coeff_ctr++)
  {
    i = *p_scan++;
    j = *p_scan++;

    run++;

    m7 = &mb_rres[block_y + j][block_x + i]; 

    if (img->AdaptiveRounding)
      fadjust4x4[j][block_x+i] = 0;

    if (*m7 != 0)
    {
      if (is_cavlc)
        *m7 = iClip3(-CAVLC_LEVEL_LIMIT, CAVLC_LEVEL_LIMIT, *m7);

      nonzero=TRUE;
      *coeff_cost += MAX_VALUE;
      *ACL++ = *m7;
      *ACR++ = run;
      run=-1;                     // reset zero level counter        
    }
  }
  *ACL = 0;

  if( (ipmode_DPCM < 2) && (intra))
  {
    Inv_Residual_DPCM_4x4(mb_rres, block_y, block_x);
  }

  for (j=0; j < BLOCK_SIZE; j++)
  {
    pix_y = img->pix_y + block_y + j;
    pix_x = img->pix_x+block_x;
    for (i=0; i < BLOCK_SIZE; i++)
    {
      img_enc[pix_y][pix_x+i] = mb_rres[j+block_y][i+block_x] + mb_pred[j+block_y][i+block_x];
    }
  }

  return nonzero;
}

/*!
************************************************************************
* \brief
*    Residual DPCM for Intra lossless coding
*
* \par Input:
*    block_x,block_y: Block position inside a macro block (0,4,8,12).
************************************************************************
*/
static int Residual_DPCM_4x4(int ipmode, int **mb_ores, int **mb_rres, int block_y, int block_x)
{
  int i;
  int temp[4][4];

  if(ipmode==VERT_PRED)
  {
    for (i=0; i<4; i++)
    {
      temp[0][i] = mb_ores[block_y + 0][block_x + i];
      temp[1][i] = mb_ores[block_y + 1][block_x + i] - mb_ores[block_y    ][block_x + i];
      temp[2][i] = mb_ores[block_y + 2][block_x + i] - mb_ores[block_y + 1][block_x + i];
      temp[3][i] = mb_ores[block_y + 3][block_x + i] - mb_ores[block_y + 2][block_x + i];
    }

    for (i = 0; i < 4; i++)
    {
      mb_rres[block_y + 0][block_x + i] = temp[0][i];
      mb_rres[block_y + 1][block_x + i] = temp[1][i];
      mb_rres[block_y + 2][block_x + i] = temp[2][i];
      mb_rres[block_y + 3][block_x + i] = temp[3][i];
    }
  }
  else  //HOR_PRED
  {
    for (i=0; i<4; i++)
    {
      temp[i][0] = mb_ores[block_y + i][block_x];
      temp[i][1] = mb_ores[block_y + i][block_x + 1] - mb_ores[block_y + i][block_x    ];
      temp[i][2] = mb_ores[block_y + i][block_x + 2] - mb_ores[block_y + i][block_x + 1];
      temp[i][3] = mb_ores[block_y + i][block_x + 3] - mb_ores[block_y + i][block_x + 2];
    }

    for (i=0; i<4; i++)
    {
      mb_rres[block_y + i][block_x + 0] = temp[i][0];
      mb_rres[block_y + i][block_x + 1] = temp[i][1];
      mb_rres[block_y + i][block_x + 2] = temp[i][2];
      mb_rres[block_y + i][block_x + 3] = temp[i][3];
    }
  }
  return 0;
}

/*!
************************************************************************
* \brief
*    Inverse residual DPCM for Intra lossless coding
*
* \par Input:
*    block_x,block_y: Block position inside a macro block (0,4,8,12).
************************************************************************
*/
//For residual DPCM
static int Inv_Residual_DPCM_4x4(int **m7, int block_y, int block_x)  
{
  int i;
  int temp[4][4];

  if(ipmode_DPCM==VERT_PRED)
  {
    for(i=0; i<4; i++)
    {
      temp[0][i] = m7[block_y + 0][block_x + i];
      temp[1][i] = m7[block_y + 1][block_x + i] + temp[0][i];
      temp[2][i] = m7[block_y + 2][block_x + i] + temp[1][i];
      temp[3][i] = m7[block_y + 3][block_x + i] + temp[2][i];
    }
    for(i=0; i<4; i++)
    {      
      m7[block_y + 0][block_x + i] = temp[0][i];
      m7[block_y + 1][block_x + i] = temp[1][i];
      m7[block_y + 2][block_x + i] = temp[2][i];
      m7[block_y + 3][block_x + i] = temp[3][i];
    }
  }
  else //HOR_PRED
  {
    for(i=0; i<4; i++)
    {
      temp[i][0] = m7[block_y + i][block_x + 0];
      temp[i][1] = m7[block_y + i][block_x + 1] + temp[i][0];
      temp[i][2] = m7[block_y + i][block_x + 2] + temp[i][1];
      temp[i][3] = m7[block_y + i][block_x + 3] + temp[i][2];    
    }
    for(i=0; i<4; i++)
    {
      m7[block_y+i][block_x  ] = temp[i][0];
      m7[block_y+i][block_x+1] = temp[i][1];
      m7[block_y+i][block_x+2] = temp[i][2];
      m7[block_y+i][block_x+3] = temp[i][3];
    }
  }
  return 0;
}

/*!
************************************************************************
* \brief
*    Residual DPCM for Intra lossless coding
************************************************************************
*/
//For residual DPCM
static int Residual_DPCM_4x4_for_Intra16x16(int **m7, int ipmode)  
{
  int i,j;
  int temp[4][4];

  if(ipmode==VERT_PRED)
  {   
    for (i=1; i<4; i++) 
      for (j=0; j<4; j++)
        temp[i][j] = m7[i][j] - m7[i-1][j];

    for (i=1; i<4; i++)
      for (j=0; j<4; j++)
        m7[i][j] = temp[i][j];
  }
  else  //HOR_PRED
  {
    for (i=0; i<4; i++)
      for (j=1; j<4; j++)
        temp[i][j] = m7[i][j] - m7[i][j-1];

    for (i=0; i<4; i++)
      for (j=1; j<4; j++)
        m7[i][j] = temp[i][j];
  }
  return 0;
}
/*!
************************************************************************
* \brief
*    Inverse residual DPCM for Intra lossless coding
************************************************************************
*/
//For residual DPCM
static int Inv_Residual_DPCM_4x4_for_Intra16x16(int **m7, int ipmode)  
{
  int i;
  int temp[4][4];

  if(ipmode==VERT_PRED)
  {
    for (i=0; i<4; i++) 
    {
      temp[0][i] = m7[0][i];
      temp[1][i] = m7[1][i] + temp[0][i];
      temp[2][i] = m7[2][i] + temp[1][i];
      temp[3][i] = m7[3][i] + temp[2][i];
    }
    // These could now just use a memcpy
    for (i=0; i<4; i++)
    {
      m7[1][i] = temp[1][i];
      m7[2][i] = temp[2][i];
      m7[3][i] = temp[3][i];
    }
  }
  else  //HOR_PRED
  {
    for(i=0; i<4; i++)
    {
      temp[i][0] = m7[i][0];
      temp[i][1] = m7[i][1] + temp[i][0];
      temp[i][2] = m7[i][2] + temp[i][1];
      temp[i][3] = m7[i][3] + temp[i][2];
    }
    for (i=0; i<4; i++)
    {
      m7[i][1] = temp[i][1];
      m7[i][2] = temp[i][2];
      m7[i][3] = temp[i][3];
    }    
  }
  return 0;
}

⌨️ 快捷键说明

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