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

📄 rdoq_cavlc.c

📁 H.264编码实现
💻 C
📖 第 1 页 / 共 2 页
字号:

      if (numcoef > 1 && zerosleft) 
      {
        vlcnum = imin(zerosleft - 1, RUNBEFORE_NUM_M1);
        se.len = vlcnum;
        no_bits += Run_lentab[se.len][se.value1];
        zerosleft -= run;
        numcoef --;
      }
    }
  }

  return no_bits;
}


/*!
****************************************************************************
* \brief
*    estimate run and level for CAVLC 
****************************************************************************
*/
void est_RunLevel_CAVLC(levelDataStruct *levelData, int *levelTrellis, int block_type, 
                        int b8, int b4, int coeff_num, double lambda)
{
  int k, lastnonzero = -1, coeff_ctr;
  int level_to_enc[16] = {0}, sign_to_enc[16] = {0};
  int cstat, bestcstat = 0; 
  int nz_coeff=0;
  double lagr, lagrAcc = 0, minlagr = 0;

  int subblock_x = ((b8&0x1)==0)?(((b4&0x1)==0)?0:1):(((b4&0x1)==0)?2:3); 
  // horiz. position for coeff_count context  
  int subblock_y = (b8<2)?((b4<2)?0:1):((b4<2)?2:3); 
  // vert.  position for coeff_count context      
  int nnz; 
  levelDataStruct *dataLevel = &levelData[0];

  if (block_type != CHROMA_AC)
    nnz = predict_nnz(&img->mb_data[img->current_mb_nr], LUMA, subblock_x,subblock_y); 
  else
    nnz = predict_nnz_chroma(&img->mb_data[img->current_mb_nr], img->subblock_x, img->subblock_y+4);

  for (coeff_ctr=0;coeff_ctr < coeff_num;coeff_ctr++)
  {	 
    levelTrellis[coeff_ctr] = 0;

    for(k=0; k < dataLevel->noLevels; k++)
    {
      dataLevel->errLevel[k] /= 32768;
    }

    lagrAcc += dataLevel->errLevel[dataLevel->noLevels - 1];

    level_to_enc[coeff_ctr] = dataLevel->pre_level;
    sign_to_enc[coeff_ctr] = dataLevel->sign;

    if(dataLevel->noLevels > 1)
    {
      dataLevel->coeff_ctr = coeff_ctr;
      lastnonzero = coeff_ctr;
    }
    else
      dataLevel->coeff_ctr = -1;
    dataLevel++;
  }

  if(lastnonzero != -1)
  {
    //sort the coefficients based on their absolute value
    qsort(levelData, lastnonzero + 1, sizeof(levelDataStruct), cmp);

    dataLevel = &levelData[lastnonzero];

    for(coeff_ctr = lastnonzero; coeff_ctr >= 0; coeff_ctr--) // go over all coeff
    {
      if(dataLevel->noLevels == 1)
      {
        dataLevel--;
        continue;
      }

      lagrAcc -= dataLevel->errLevel[dataLevel->noLevels-1];
      for(cstat=0; cstat<dataLevel->noLevels; cstat++) // go over all states of cur coeff k
      {		
        level_to_enc[dataLevel->coeff_ctr] = dataLevel->level[cstat];
        lagr = lagrAcc + dataLevel->errLevel[cstat];

        lagr += lambda * est_CAVLC_bits(levelData, level_to_enc, sign_to_enc, nnz, block_type);

        if(cstat==0 || lagr<minlagr)
        {		
          minlagr = lagr;		
          bestcstat = cstat;
        }
      }
      lagrAcc += dataLevel->errLevel[bestcstat];
      level_to_enc[dataLevel->coeff_ctr] = dataLevel->level[bestcstat];
      dataLevel--;
    }

    for(coeff_ctr = 0; coeff_ctr <= lastnonzero; coeff_ctr++)
    {
      levelTrellis[coeff_ctr] = level_to_enc[coeff_ctr];
      if (level_to_enc[coeff_ctr] != 0)
        nz_coeff++;
    }
  }

  img->nz_coeff [img->current_mb_nr ][subblock_x][subblock_y] = nz_coeff;
}

/*!
****************************************************************************
* \brief
*    Initialize levelData 
****************************************************************************
*/
void init_trellis_data_4x4_CAVLC(int (*tblock)[16], int block_x, int qp_per, int qp_rem, int **levelscale, int **leveloffset, 
                                 const byte *p_scan, Macroblock *currMB, levelDataStruct *dataLevel, int type)
{
  int i, j, coeff_ctr; 
  static int *m7;
  int end_coeff_ctr = ( ( type == LUMA_4x4 ) ? 16 : 15 );
  int q_bits = Q_BITS + qp_per; 
  int q_offset = ( 1 << (q_bits - 1) );
  int level, lowerInt, k;
  double err, estErr;


  for (coeff_ctr = 0; coeff_ctr < end_coeff_ctr; coeff_ctr++)
  {
    i = *p_scan++;  // horizontal position
    j = *p_scan++;  // vertical position

    m7 = &tblock[j][block_x + i];

    if (*m7 == 0)
    {
      dataLevel->levelDouble = 0;
      dataLevel->level[0] = 0;
      dataLevel->noLevels = 1;
      err = 0.0;
      dataLevel->errLevel[0] = 0.0;
      dataLevel->pre_level = 0;
      dataLevel->sign = 0;
    }
    else
    {
      estErr = ((double) estErr4x4[qp_rem][j][i]) / norm_factor_4x4;

      dataLevel->levelDouble = iabs(*m7 * levelscale[j][i]);
      level = (dataLevel->levelDouble >> q_bits);

      lowerInt = (((int)dataLevel->levelDouble - (level << q_bits)) < q_offset )? 1 : 0;
      
      dataLevel->level[0] = 0;
      if (level == 0 && lowerInt == 1)
      {
        dataLevel->noLevels = 1;
      }
      else if (level == 0 && lowerInt == 0)
      {
        dataLevel->level[1] = 1;
        dataLevel->noLevels = 2;
      }
      else if (level > 0 && lowerInt == 1)
      {
        dataLevel->level[1] = level;
        dataLevel->noLevels = 2;
      }
      else
      {
        dataLevel->level[1] = level;
        dataLevel->level[2] = level + 1;
        dataLevel->noLevels = 3;
      }

      for (k = 0; k < dataLevel->noLevels; k++)
      {
        err = (double)(dataLevel->level[k] << q_bits) - (double)dataLevel->levelDouble;
        dataLevel->errLevel[k] = (err * err * estErr); 
      }

      if(dataLevel->noLevels == 1)
        dataLevel->pre_level = 0;
      else
        dataLevel->pre_level = (iabs (*m7) * levelscale[j][i] + leveloffset[j][i]) >> q_bits;
      dataLevel->sign = isign(*m7);
    }
    dataLevel++;
  }
}

/*!
****************************************************************************
* \brief
*    Initialize levelData for Luma DC
****************************************************************************
*/
void init_trellis_data_DC_CAVLC(int (*tblock)[4], int qp_per, int qp_rem, 
                         int levelscale, int leveloffset, const byte *p_scan, Macroblock *currMB,  
                         levelDataStruct *dataLevel, int type)
{
  int i, j, coeff_ctr, end_coeff_ctr = 16;
  int q_bits   = Q_BITS + qp_per + 1; 
  int q_offset = ( 1 << (q_bits - 1) );
  int level, lowerInt, k;
  int *m7;
  double err, estErr = (double) estErr4x4[qp_rem][0][0] / norm_factor_4x4; // note that we could also use int64

  for (coeff_ctr = 0; coeff_ctr < end_coeff_ctr; coeff_ctr++)
  {
    i = *p_scan++;  // horizontal position
    j = *p_scan++;  // vertical position
    m7 = &tblock[j][i];

    if (*m7 == 0)
    {
      dataLevel->levelDouble = 0;
      dataLevel->level[0] = 0;
      dataLevel->noLevels = 1;
      err = 0.0;
      dataLevel->errLevel[0] = 0.0;
      dataLevel->pre_level = 0;
      dataLevel->sign = 0;
    }
    else
    {
      dataLevel->levelDouble = iabs(*m7 * levelscale);
      level = (dataLevel->levelDouble >> q_bits);

      lowerInt=( ((int)dataLevel->levelDouble - (level<<q_bits)) < q_offset )? 1 : 0;

      dataLevel->level[0] = 0;    
      if (level == 0 && lowerInt == 1)
      {
        dataLevel->noLevels = 1;
      }
      else if (level == 0 && lowerInt == 0)
      {
        dataLevel->level[1] = 1;
        dataLevel->noLevels = 2;
      }
      else if (level > 0 && lowerInt == 1)
      {
        dataLevel->level[1] = level;
        dataLevel->noLevels = 2;
      }
      else
      {
        dataLevel->level[1] = level;
        dataLevel->level[2] = level + 1;
        dataLevel->noLevels = 3;
      }

      for (k = 0; k < dataLevel->noLevels; k++)
      {
        err = (double)(dataLevel->level[k] << q_bits) - (double)dataLevel->levelDouble;
        dataLevel->errLevel[k] = (err * err * estErr); 
      }

      if(dataLevel->noLevels == 1)
        dataLevel->pre_level = 0;
      else
        dataLevel->pre_level = (iabs (*m7) * levelscale + leveloffset) >> q_bits;
      dataLevel->sign = isign(*m7);
    }
    dataLevel++;
  }
}

/*!
****************************************************************************
* \brief
*    Initialize levelData 
****************************************************************************
*/
void init_trellis_data_8x8_CAVLC(int (*tblock)[16], int block_x, int qp_per, int qp_rem, int **levelscale, int **leveloffset, 
                                 const byte *p_scan, Macroblock *currMB, levelDataStruct levelData[4][16])
{
  int i, j, block, coeff_ctr;
  static int *m7;
  int q_bits   = Q_BITS_8 + qp_per;
  int q_offset = ( 1 << (q_bits - 1) );
  double err, estErr;
  int level, lowerInt, k;
  
  levelDataStruct *dataLevel = &levelData[0][0];  

  for (coeff_ctr = 0; coeff_ctr < 16; coeff_ctr++)
  {
    for (block = 0; block < 4; block++)
    {
      i = *p_scan++;  // horizontal position
      j = *p_scan++;  // vertical position

      m7 = &tblock[j][block_x + i];

      dataLevel = &levelData[block][coeff_ctr];
      if (*m7 == 0)
      {
        dataLevel->levelDouble = 0;
        dataLevel->level[0] = 0;
        dataLevel->noLevels = 1;
        err = 0.0;
        dataLevel->errLevel[0] = 0.0;
        dataLevel->pre_level = 0;
        dataLevel->sign = 0;
      }
      else
      {
        estErr = (double) estErr8x8[qp_rem][j][i] / norm_factor_8x8;

        dataLevel->levelDouble = iabs(*m7 * levelscale[j][i]);
        level = (dataLevel->levelDouble >> q_bits);

        lowerInt = (((int)dataLevel->levelDouble - (level << q_bits)) < q_offset ) ? 1 : 0;

        dataLevel->level[0] = 0;
        if (level == 0 && lowerInt == 1)
        {
          dataLevel->noLevels = 1;
        }
        else if (level == 0 && lowerInt == 0)
        {
          dataLevel->level[1] = 1;
          dataLevel->noLevels = 2;
        }
        else if (level > 0 && lowerInt == 1)
        {
          if (level > 1)
          {
            dataLevel->level[1] = level - 1;
            dataLevel->level[2] = level;
            dataLevel->noLevels = 3;
          }
          else
          {
            dataLevel->level[1] = level;
            dataLevel->noLevels = 2;
          }
        }
        else
        {
          dataLevel->level[1] = level;
          dataLevel->level[2] = level + 1;
          dataLevel->noLevels = 3;
        }

        for (k = 0; k < dataLevel->noLevels; k++)
        {
          err = (double)(dataLevel->level[k] << q_bits) - (double)dataLevel->levelDouble;
          dataLevel->errLevel[k] = err * err * estErr; 
        }

        if(dataLevel->noLevels == 1)
          dataLevel->pre_level = 0;
        else
          dataLevel->pre_level = (iabs (*m7) * levelscale[j][i] + leveloffset[j][i]) >> q_bits;
        dataLevel->sign = isign(*m7);
      }
    }
  }
}


⌨️ 快捷键说明

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