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

📄 macroblock.c

📁 h.264/avc 视频编码程序,实现分数像素匹配功能,非原创.
💻 C
📖 第 1 页 / 共 5 页
字号:
    snprintf(currSE.tracestring, TRACESTRING_SIZE, " Delta quant ");
#endif
    dP->readSyntaxElement(&currSE,img,inp,dP);
    currMB->delta_quant = currSE.value1;
    img->qp= (img->qp-MIN_QP+currMB->delta_quant+(MAX_QP-MIN_QP+1))%(MAX_QP-MIN_QP+1)+MIN_QP;

    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
  }

  qp_per    = (img->qp-MIN_QP)/6;
  qp_rem    = (img->qp-MIN_QP)%6;
  qp_per_uv = ((img->qp<0?img->qp:QP_SCALE_CR[img->qp])-MIN_QP)/6;
  qp_rem_uv = ((img->qp<0?img->qp:QP_SCALE_CR[img->qp])-MIN_QP)%6;
  currMB->qp = img->qp;

  // 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;
          b8 = 2*jj+ii;

          if (IS_NEWINTRA (currMB))   start_scan = 1; /* skip DC coeff */
          else                        start_scan = 0; /* take all coeffs */

          img->subblock_x = i; // position for coeff_count ctx
          img->subblock_y = j; // position for coeff_count ctx
          if (cbp & (1<<b8))  /* are there any coeff in current block at all */
          {
            if (currMB->b8mode[b8]!=IBLOCK || (inp->symbol_mode!=CABAC && img->qp>=24))
            {
              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 (currMB->b8mode[b8]==IBLOCK || IS_NEWINTRA (currMB))
                  {
                    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 (currMB->b8mode[b8]==IBLOCK)
                  {
                    currSE.context = 2; // for choosing context model
                    currSE.type  = SE_LUM_AC_INTRA;
                  }
                  else if (IS_NEWINTRA (currMB))
                  {
                    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
                sprintf(currSE.tracestring, " 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;
                  i0=SNGL_SCAN[coef_ctr][0];
                  j0=SNGL_SCAN[coef_ctr][1];
                  currMB->cbp_blk      |= 1 << ((j<<2) + i) ;
                  img->cof[i][j][i0][j0]= level*dequant_coef[qp_rem][i0][j0]<<qp_per;
                }
              }
            }
            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
                  sprintf(currSE.tracestring, "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*dequant_coef[qp_rem][i0][j0]<<qp_per;
                  }
                }
              }
            }
          }
        }
      }
    }
  }

  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 (IS_INTRA (currMB))
        {
          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;
        }
        currSE.k = ll; //coeff_count ctx
#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*dequant_coef[qp_rem_uv][0][0]<<qp_per_uv;
        }
      }

      if (((img->type==SP_IMG_1 || img->type==SP_IMG_MULT) && IS_INTER (currMB)))
      {
        img->cof[0+ll][4][0][0]=(img->cofu[0]>>qp_per_uv)/dequant_coef[qp_rem_uv][0][0];
        img->cof[1+ll][4][0][0]=(img->cofu[1]>>qp_per_uv)/dequant_coef[qp_rem_uv][0][0];
        img->cof[0+ll][5][0][0]=(img->cofu[2]>>qp_per_uv)/dequant_coef[qp_rem_uv][0][0];
        img->cof[1+ll][5][0][0]=(img->cofu[3]>>qp_per_uv)/dequant_coef[qp_rem_uv][0][0];
      }
      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;
      }
    }
  }

  // chroma AC coeff, all zero fram start_scan
  uv=-1;
  if (cbp>31)
  {
    block_y=4;
    for (block_x=0; block_x < 4; block_x += 2)
    {
      for (j=block_y; j < block_y+2; j++)
      {
        jj=j/2;
        j1=j-4;
        for (i=block_x; i < block_x+2; i++)
        {
          ii=i/2;
          i1=i%2;
          {
            coef_ctr=0;
            level=1;
            uv++;
            for(k=0;(k<16)&&(level!=0);k++)
            {
              currSE.k = uv;  //coeff_count ctx
              if (IS_INTRA (currMB))
              {
                currSE.context = 8; // for choosing context model
                currSE.type  = SE_CHR_AC_INTRA;
              }
              else
              {
                currSE.context = 7; // for choosing context model
                currSE.type  = SE_CHR_AC_INTER;
              }
#if TRACE
              snprintf(currSE.tracestring, TRACESTRING_SIZE, " AC 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_inter;
              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 |= 1 << (16 + (j1<<1) + i1 + (block_x<<1) ) ;
                coef_ctr=coef_ctr+run+1;
                i0=SNGL_SCAN[coef_ctr][0];
                j0=SNGL_SCAN[coef_ctr][1];
                img->cof[i][j][i0][j0]=level*dequant_coef[qp_rem_uv][i0][j0]<<qp_per_uv;
              }
            }
          }
        }
      }
    }
  }
}



/*!
 ************************************************************************
 * \brief
 *    copy current MB from last MB
 ************************************************************************
 */
void decode_one_CopyMB(struct img_par *img,struct inp_par *inp)
{
  int tmp_block[BLOCK_SIZE][BLOCK_SIZE];
  int i, j, ii, jj, uv;
  int ref_frame = 0; //currMB->ref_frame;
  int mv_mul;

  if(img->mv_res)
    mv_mul=8;
  else
    mv_mul=4;

  // get luma pixel *************************************************
  for(j=0;j<MB_BLOCK_SIZE;j+=BLOCK_SIZE)
  {
    for(i=0;i<MB_BLOCK_SIZE;i+=BLOCK_SIZE)
    {
      get_block(ref_frame,(img->pix_x+i)*mv_mul,(img->pix_y+j)*mv_mul,img,tmp_block);

      for(ii=0;ii<BLOCK_SIZE;ii++)
        for(jj=0;jj<BLOCK_SIZE;jj++)
          imgY[img->pix_y+j+jj][img->pix_x+i+ii]=tmp_block[ii][jj];
    }
  }
  if (img->type==SP_IMG_1 || img->type==SP_IMG_MULT)
  {
    for(j=0;j<MB_BLOCK_SIZE;j++)
    {
      jj=img->pix_y+j;
      for(i=0;i<MB_BLOCK_SIZE;i++)
      {
        ii=img->pix_x+i;
        img->mpr[i][j]=imgY[jj][ii];
      }
    }
    for (i=0; i < MB_BLOCK_SIZE; i+=BLOCK_SIZE)
      for (j=0; j < MB_BLOCK_SIZE; j+=BLOCK_SIZE)
        copyblock_sp(img,i,j);
  }
  // get chroma pixel **********************************************
  for(uv=0;uv<2;uv++)
  {
    for(j=0;j<MB_BLOCK_SIZE/2;j++)
    {
      jj=img->pix_c_y+j;
      for(i=0;i<MB_BLOCK_SIZE/2;i++)
      {

⌨️ 快捷键说明

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