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

📄 macroblock.c

📁 本源码是H.26L标准的Visual C++源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
 */
void readCBPandCoeffsFromNAL(struct img_par *img,struct inp_par *inp)
{
  int i,j,k;
  int level, run;
  int mb_nr = img->current_mb_nr;
  int ii,jj;
  int i1,j1, m2,jg2;
  Macroblock *currMB = &img->mb_data[mb_nr];
  int cbp;
  SyntaxElement currSE;
  Slice *currSlice = img->currentSlice;
  DataPartition *dP;
  int *partMap = assignSE2partition[currSlice->dp_mode];
  int iii,jjj;
  int coef_ctr, len, i0,j0;

  int ll;
  int scan_loop_ctr;

  int block_x,block_y;
  int scan_mode, start_scan;

  // read CBP if not new intra mode
  if (img->imod != INTRA_MB_NEW)
  {
    if (img->imod == INTRA_MB_OLD)
      currSE.type = SE_CBP_INTRA;
    else
      currSE.type = SE_CBP_INTER;

    if(img->type == B_IMG_1 || img->type == B_IMG_MULT)
      dP = &(currSlice->partArr[partMap[SE_BFRAME]]);
    else
      dP = &(currSlice->partArr[partMap[currSE.type]]);

    if (inp->symbol_mode == UVLC || dP->bitstream->ei_flag)
    {
      if (img->imod == INTRA_MB_OLD)
        currSE.mapping = linfo_cbp_intra;
      else
        currSE.mapping = linfo_cbp_inter;
    }
    else
      currSE.reading = readCBPFromBuffer_CABAC;

#if TRACE
    snprintf(currSE.tracestring, TRACESTRING_SIZE, " CBP ");
#endif
   

    dP->readSyntaxElement(&currSE,img,inp,dP);
    currMB->cbp = cbp = currSE.value1;
    // Delta quant only if nonzero coeffs
    if (cbp !=0)
    {
      if (currMB->intraOrInter == INTER_MB)
        currSE.type = SE_DELTA_QUANT_INTER;
      else
        currSE.type = SE_DELTA_QUANT_INTRA;

      if(img->type == B_IMG_1 || img->type == B_IMG_MULT)
        dP = &(currSlice->partArr[partMap[SE_BFRAME]]);
      else
        dP = &(currSlice->partArr[partMap[currSE.type]]);
  
      if (inp->symbol_mode == UVLC || dP->bitstream->ei_flag)
        currSE.mapping = linfo_dquant;
      else
        currSE.reading= readDquantFromBuffer_CABAC;

#if TRACE
      snprintf(currSE.tracestring, TRACESTRING_SIZE, " Delta quant ");
#endif

      dP->readSyntaxElement(&currSE,img,inp,dP);
      currMB->delta_quant = currSE.value1;
      img->qp= (img->qp+currMB->delta_quant+32)%32;
    }
  }
  else
    cbp = currMB->cbp;

  for (i=0;i<BLOCK_SIZE;i++)
    for (j=0;j<BLOCK_SIZE;j++)
      for(iii=0;iii<BLOCK_SIZE;iii++)
        for(jjj=0;jjj<BLOCK_SIZE;jjj++)
          img->cof[i][j][iii][jjj]=0;// reset luma coeffs

  if(img->imod==INTRA_MB_NEW) // read DC coeffs for new intra modes
  {

    if (currMB->intraOrInter == INTER_MB)
      currSE.type = SE_DELTA_QUANT_INTER;
    else
      currSE.type = SE_DELTA_QUANT_INTRA;

    if(img->type == B_IMG_1 || img->type == B_IMG_MULT)
      dP = &(currSlice->partArr[partMap[SE_BFRAME]]);
    else
      dP = &(currSlice->partArr[partMap[currSE.type]]);

    if (inp->symbol_mode == UVLC || dP->bitstream->ei_flag)
      currSE.mapping = linfo_dquant;
    else
      currSE.reading= readDquantFromBuffer_CABAC;

#if TRACE
      snprintf(currSE.tracestring, TRACESTRING_SIZE, " Delta quant ");
#endif

    dP->readSyntaxElement(&currSE,img,inp,dP);
    currMB->delta_quant = currSE.value1;
    img->qp= (img->qp+currMB->delta_quant+32)%32;

    for (i=0;i<BLOCK_SIZE;i++)
      for (j=0;j<BLOCK_SIZE;j++)
        img->ipredmode[img->block_x+i+1][img->block_y+j+1]=0;

            // //////

    currSE.type = SE_LUM_DC_INTRA;
    if(img->type == B_IMG_1 || img->type == B_IMG_MULT)
      dP = &(currSlice->partArr[partMap[SE_BFRAME]]);
    else
      dP = &(currSlice->partArr[partMap[currSE.type]]);

    if (inp->symbol_mode == UVLC || dP->bitstream->ei_flag)
      currSE.mapping = linfo_levrun_inter;
    else
    {
      currSE.reading = readRunLevelFromBuffer_CABAC;
      currSE.context = 3; // for choosing context model
    }

    // ////////////
    coef_ctr=-1;
    level = 1;                            // just to get inside the loop
    for(k=0;(k<17) && (level!=0);k++)
    {
#if TRACE
      snprintf(currSE.tracestring, TRACESTRING_SIZE, "DC luma 16x16 ");
#endif
      dP->readSyntaxElement(&currSE,img,inp,dP);
      level = currSE.value1;
      run = currSE.value2;
      len = currSE.len;

      if (level != 0)                     // leave if len=1
      {
        coef_ctr=coef_ctr+run+1;

        i0=SNGL_SCAN[coef_ctr][0];
        j0=SNGL_SCAN[coef_ctr][1];

        img->cof[i0][j0][0][0]=level;// add new intra DC coeff
      }
    }
    itrans_2(img);// transform new intra DC
  }


  if (img->imod == INTRA_MB_OLD && img->qp < 24)
    scan_mode=DOUBLE_SCAN;
  else
    scan_mode=SINGLE_SCAN;


  // luma coefficients
  for (block_y=0; block_y < 4; block_y += 2) // all modes
  {
    for (block_x=0; block_x < 4; block_x += 2)
    {
      for (j=block_y; j < block_y+2; j++)
      {
        jj=j/2;
        for (i=block_x; i < block_x+2; i++)
        {
          ii=i/2;
          if (img->imod == INTRA_MB_NEW)
            start_scan = 1; // skip DC coeff
          else
            start_scan = 0; // take all coeffs

          if((cbp & (int)pow(2,(ii+2*jj))) != 0)  // are there any coeff in current block at all
          {
            if (scan_mode==SINGLE_SCAN)
            {
              coef_ctr=start_scan-1;
              level = 1;
              for(k=start_scan;(k<17) && (level!=0);k++)
              {
                  /*
                  * make distinction between INTRA and INTER coded
                  * luminance coefficients
                */
                if (k == 0)
                {
                  if (img->imod == INTRA_MB_OLD || img->imod == INTRA_MB_NEW)
                  {
                    currSE.context = 2; // for choosing context model
                    currSE.type  = SE_LUM_DC_INTRA;
                  }
                  else
                  {
                    currSE.context = 1; // for choosing context model
                    currSE.type  = SE_LUM_DC_INTER;
                  }
                }
                else
                {
                  if (img->imod == INTRA_MB_OLD /*|| img->imod == INTRA_MB_NEW*/)
                  {
                    currSE.context = 2; // for choosing context model
                    currSE.type  = SE_LUM_AC_INTRA;
                  }
                  else if ( img->imod == INTRA_MB_NEW )
                  {
                    currSE.context = 4; // for choosing context model
                    currSE.type  = SE_LUM_AC_INTRA;
                  }
                  else
                  {
                    currSE.context = 1; // for choosing context model
                    currSE.type  = SE_LUM_AC_INTER;
                  }
                }

#if TRACE
                snprintf(currSE.tracestring, TRACESTRING_SIZE, " Luma sng ");
#endif
                
                if(img->type == B_IMG_1 || img->type == B_IMG_MULT)
                  dP = &(currSlice->partArr[partMap[SE_BFRAME]]);
                else
                  dP = &(currSlice->partArr[partMap[currSE.type]]);

                if (inp->symbol_mode == UVLC || dP->bitstream->ei_flag)
                  currSE.mapping = linfo_levrun_inter;
                else
                  currSE.reading = readRunLevelFromBuffer_CABAC;

                dP->readSyntaxElement(&currSE,img,inp,dP);
                level = currSE.value1;
                run =  currSE.value2;
                len = currSE.len;

                if (level != 0)   // leave if len=1
                {
                  coef_ctr += run+1;
                  currMB->cbp_blk |= 1 << ((j<<2) + i) ;
                  i0=SNGL_SCAN[coef_ctr][0];
                  j0=SNGL_SCAN[coef_ctr][1];


                  img->cof[i][j][i0][j0]=level*JQ1[img->qp];
                }
              }
            }
            else    // double scan (old intra with QP<24
            {
              for(scan_loop_ctr=0;scan_loop_ctr<2;scan_loop_ctr++)
              {
                coef_ctr=start_scan-1;
                level=1;                          // just to get inside the loop
                for(k=0; k<9 && level!=0;k++)
                {
                  if (k == 0)
                    currSE.type  = SE_LUM_DC_INTRA; // element is of type DC
                  else
                    currSE.type  = SE_LUM_AC_INTRA;   // element is of type AC
#if TRACE
                  snprintf(currSE.tracestring, TRACESTRING_SIZE, "Luma dbl(%2d,%2d)  ",scan_loop_ctr,k);
#endif
                  if(img->type == B_IMG_1 || img->type == B_IMG_MULT)
                    dP = &(currSlice->partArr[partMap[SE_BFRAME]]);
                  else
                    dP = &(currSlice->partArr[partMap[currSE.type]]);

                  if (inp->symbol_mode == UVLC || dP->bitstream->ei_flag)
                    currSE.mapping = linfo_levrun_intra;
                  else
                  {
                    currSE.context = 0; // for choosing context model
                    currSE.reading = readRunLevelFromBuffer_CABAC;
                  }

                  dP->readSyntaxElement(&currSE,img,inp,dP);
                  level = currSE.value1;
                  run = currSE.value2;
                  len = currSE.len;

                  if (level != 0)   // leave if len=1
                  {
                    coef_ctr=coef_ctr+run+1;
                    currMB->cbp_blk |= 1 << ((j<<2) + i) ;

                    i0=DBL_SCAN[coef_ctr][0][scan_loop_ctr];
                    j0=DBL_SCAN[coef_ctr][1][scan_loop_ctr];

                    img->cof[i][j][i0][j0]=level*JQ1[img->qp];
                  }
                }
              }
            }
          }
        }
      }
    }
  }

  for (j=4;j<6;j++) // reset all chroma coeffs before read
    for (i=0;i<4;i++)
      for (iii=0;iii<4;iii++)
        for (jjj=0;jjj<4;jjj++)
          img->cof[i][j][iii][jjj]=0;

  m2=img->mb_x*2;
  jg2=img->mb_y*2;

  // chroma 2x2 DC coeff
  if(cbp>15)
  {
    for (ll=0;ll<3;ll+=2)
    {
      for (i=0;i<4;i++)
        img->cofu[i]=0;

      coef_ctr=-1;
      level=1;
      for(k=0;(k<5)&&(level!=0);k++)
      {
        if ( img->imod == INTRA_MB_OLD || img->imod == INTRA_MB_NEW)
        {
          currSE.context = 6; // for choosing context model
          currSE.type  = SE_CHR_DC_INTRA;
        }
        else
        {
          currSE.context = 5; // for choosing context model
          currSE.type  = SE_CHR_DC_INTER;
        }

#if TRACE
        snprintf(currSE.tracestring, TRACESTRING_SIZE, " 2x2 DC Chroma ");
#endif
        if(img->type == B_IMG_1 || img->type == B_IMG_MULT)
          dP = &(currSlice->partArr[partMap[SE_BFRAME]]);
        else
          dP = &(currSlice->partArr[partMap[currSE.type]]);

        if (inp->symbol_mode == UVLC || dP->bitstream->ei_flag)
          currSE.mapping = linfo_levrun_c2x2;
        else
          currSE.reading = readRunLevelFromBuffer_CABAC;

        dP->readSyntaxElement(&currSE,img,inp,dP);
        level = currSE.value1;
        run = currSE.value2;
        len = currSE.len;
        if (level != 0)
        {
          currMB->cbp_blk |= 0xf0000 << (ll<<1) ;
          coef_ctr=coef_ctr+run+1;
          // Bug: img->cofu has only 4 entries, hence coef_ctr MUST be <4 (which is
          // caught by the assert().  If it is bigger than 4, it starts patching the
          // img->predmode pointer, which leads to bugs later on.
          //
          // This assert() should be left in the code, because it captures a very likely
          // bug early when testing in error prone environments (or when testing NAL
          // functionality).
          assert (coef_ctr < 4);
          img->cofu[coef_ctr]=level*JQ1[QP_SCALE_CR[img->qp]];
        }
      }

      if ((img->type==SP_IMG_1 || img->type==SP_IMG_MULT) && (currMB->mb_imode == INTRA_MB_INTER))
      {
        img->cof[0+ll][4][0][0]=img->cofu[0]/JQ1[QP_SCALE_CR[img->qp]];
        img->cof[1+ll][4][0][0]=img->cofu[1]/JQ1[QP_SCALE_CR[img->qp]];
        img->cof[0+ll][5][0][0]=img->cofu[2]/JQ1[QP_SCALE_CR[img->qp]];
        img->cof[1+ll][5][0][0]=img->cofu[3]/JQ1[QP_SCALE_CR[img->qp]];
      }
      else
      {
        img->cof[0+ll][4][0][0]=(img->cofu[0]+img->cofu[1]+img->cofu[2]+img->cofu[3])/2;
        img->cof[1+ll][4][0][0]=(img->cofu[0]-img->cofu[1]+img->cofu[2]-img->cofu[3])/2;
        img->cof[0+ll][5][0][0]=(img->cofu[0]+img->cofu[1]-img->cofu[2]-img->cofu[3])/2;
        img->cof[1+ll][5][0][0]=(img->cofu[0]-img->cofu[1]-img->cofu[2]+img->cofu[3])/2;
      }
    }
  }

⌨️ 快捷键说明

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