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

📄 macroblock.c

📁 h.264/avc 视频编码程序,实现分数像素匹配功能,非原创.
💻 C
📖 第 1 页 / 共 5 页
字号:
    {
      if(rFrameL == ref_frame)
        mvPredType = MVPRED_L;
    }
    else
    {
      if(rFrameUR == ref_frame)
        mvPredType = MVPRED_UR;
    }
  }
  else if(blockshape_x == 16 && blockshape_y == 8)
  {
    if(mb_y == 0)
    {
      if(rFrameU == ref_frame)
        mvPredType = MVPRED_U;
    }
    else
    {
      if(rFrameL == ref_frame)
        mvPredType = MVPRED_L;
    }
  }

  for (hv=0; hv < 2; hv++)
  {
    mv_a = block_available_left    ? tmp_mv[4+pic_block_x-1             ][pic_block_y  ][hv] : 0;
    mv_b = block_available_up      ? tmp_mv[4+pic_block_x               ][pic_block_y-1][hv] : 0;
    mv_d = block_available_upleft  ? tmp_mv[4+pic_block_x-1             ][pic_block_y-1][hv] : 0;
    mv_c = block_available_upright ? tmp_mv[4+pic_block_x+blockshape_x/4][pic_block_y-1][hv] : mv_d;

    switch (mvPredType)
    {
    case MVPRED_MEDIAN:
      if(!(block_available_upleft || block_available_up || block_available_upright))
        pred_vec = mv_a;
      else
        pred_vec = mv_a+mv_b+mv_c-min(mv_a,min(mv_b,mv_c))-max(mv_a,max(mv_b,mv_c));
      break;
    case MVPRED_L:
      pred_vec = mv_a;
      break;
    case MVPRED_U:
      pred_vec = mv_b;
      break;
    case MVPRED_UR:
      pred_vec = mv_c;
      break;
    default:
      break;
    }

    if (hv==0)  *pmv_x = pred_vec;
    else        *pmv_y = pred_vec;
  }
}


/*!
 ************************************************************************
 * \brief
 *    Set context for reference frames
 ************************************************************************
 */
int
BType2CtxRef (int btype)
{
  if (btype<4)  return 0;
  else          return 1;
}

/*!
 ************************************************************************
 * \brief
 *    Read motion info
 ************************************************************************
 */
void readMotionInfoFromNAL (struct img_par *img, struct inp_par *inp)
{
  int i,j,k,l,m;
  int step_h,step_v;
  int curr_mvd;
  int mb_nr           = img->current_mb_nr;
  Macroblock *currMB  = &img->mb_data[mb_nr];
  SyntaxElement currSE;
  Slice *currSlice    = img->currentSlice;
  DataPartition *dP;
  int *partMap        = assignSE2partition[inp->partition_mode];
  int bframe          = (img->type==B_IMG_1 || img->type==B_IMG_MULT);
  int partmode        = (IS_P8x8(currMB)?4:currMB->mb_type);
  int step_h0         = BLOCK_STEP [partmode][0];
  int step_v0         = BLOCK_STEP [partmode][1];


  int mv_mode, i0, j0, refframe;
  int pmv[2];
  int j4, i4, ii,jj;
  int vec;

  //  If multiple ref. frames, read reference frame for the MB *********************************
  if(img->type==INTER_IMG_MULT || img->type == SP_IMG_MULT || img->type == B_IMG_MULT)
  {
    currSE.type = SE_REFFRAME;
    if (bframe)                                               dP = &(currSlice->partArr[partMap[SE_BFRAME]]);
    else                                                      dP = &(currSlice->partArr[partMap[SE_REFFRAME]]);
    if (inp->symbol_mode == UVLC || dP->bitstream->ei_flag)   currSE.mapping = linfo;
    else                                                      currSE.reading = readRefFrameFromBuffer_CABAC;

    for (j0=0; j0<4; j0+=step_v0)
    for (i0=0; i0<4; i0+=step_h0)
    {
      k=2*(j0/2)+(i0/2);
      if ((currMB->b8pdir[k]==0 || currMB->b8pdir[k]==2) && currMB->b8mode[k]!=0)
      {
#if TRACE
        strncpy(currSE.tracestring,  "Reference frame no ", TRACESTRING_SIZE);
#endif
        img->subblock_x = i0;
        img->subblock_y = j0;

        if (!IS_P8x8 (currMB) || bframe || (!bframe && !img->allrefzero))
        {
          currSE.context = BType2CtxRef (currMB->b8mode[k]);
          dP->readSyntaxElement (&currSE,img,inp,dP);
          refframe = currSE.value1;
        }
        else
        {
          refframe = 0;
        }

        if (bframe && refframe>img->buf_cycle) //??? copied from readMotionInfoFrameNAL
        {
          set_ec_flag(SE_REFFRAME);
          refframe = 1;
        }

        if (!bframe)
        {
          for (j=j0; j<j0+step_v0;j++)
          for (i=i0; i<i0+step_h0;i++)
            refFrArr[img->block_y+j][img->block_x+i] = refframe;
        }
        else
        {
          for (j=j0; j<j0+step_v0;j++)
          for (i=i0; i<i0+step_h0;i++)
            img->fw_refFrArr[img->block_y+j][img->block_x+i] = refframe;
        }
      }
    }
  }


  //=====  READ FORWARD MOTION VECTORS =====
  currSE.type = SE_MVD;
  if (bframe)   dP = &(currSlice->partArr[partMap[SE_BFRAME]]);
  else          dP = &(currSlice->partArr[partMap[SE_MVD]]);

  if (inp->symbol_mode == UVLC || dP->bitstream->ei_flag) currSE.mapping = linfo_mvd;
  else if (bframe)                                        currSE.reading = readBiMVD2Buffer_CABAC;
  else                                                    currSE.reading = readMVDFromBuffer_CABAC;

  for (j0=0; j0<4; j0+=step_v0)
  for (i0=0; i0<4; i0+=step_h0)
  {
    k=2*(j0/2)+(i0/2);
    if ((currMB->b8pdir[k]==0 || currMB->b8pdir[k]==2) && (currMB->b8mode[k] !=0))//has forward vector
    {
      mv_mode  = currMB->b8mode[k];
      step_h   = BLOCK_STEP [mv_mode][0];
      step_v   = BLOCK_STEP [mv_mode][1];

      if (!bframe)  refframe = refFrArr        [img->block_y+j0][img->block_x+i0];
      else          refframe = img->fw_refFrArr[img->block_y+j0][img->block_x+i0];

      for (j=j0; j<j0+step_v0; j+=step_v)
      for (i=i0; i<i0+step_h0; i+=step_h)
      {
        j4 = img->block_y+j;
        i4 = img->block_x+i;

        // first make mv-prediction
        if (!bframe)  SetMotionVectorPredictor (img, pmv, pmv+1, refframe, refFrArr,         img->mv,    i, j, 4*step_h, 4*step_v);
        else          SetMotionVectorPredictor (img, pmv, pmv+1, refframe, img->fw_refFrArr, img->fw_mv, i, j, 4*step_h, 4*step_v);

        for (k=0; k < 2; k++) 
        {
#if TRACE
          snprintf(currSE.tracestring, TRACESTRING_SIZE, " MVD");
#endif
          img->subblock_x = i; // position used for context determination
          img->subblock_y = j; // position used for context determination
          currSE.value2 = (!bframe ? k : 2*k); // identifies the component; only used for context determination
          dP->readSyntaxElement(&currSE,img,inp,dP);
          curr_mvd = currSE.value1; 
  
          vec=curr_mvd+pmv[k];           /* find motion vector */

          if (bframe)
          {
            for(ii=0;ii<step_h;ii++)
              for(jj=0;jj<step_v;jj++)
                img->fw_mv[i4+ii+BLOCK_SIZE][j4+jj][k]=vec;
          }
          else
          {
            for(ii=0;ii<step_h;ii++)
              for(jj=0;jj<step_v;jj++)
                img->mv[i4+ii+BLOCK_SIZE][j4+jj][k]=vec;
          }

          /* store (oversampled) mvd */
          for (l=0; l < step_v; l++) 
            for (m=0; m < step_h; m++)  
              currMB->mvd[0][j+l][i+m][k] =  curr_mvd;
        }
      }
    }
  }


  //=====  READ FORWARD MOTION VECTORS =====
  currSE.type = SE_MVD;
  dP          = &(currSlice->partArr[partMap[SE_BFRAME]]);

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

  for (j0=0; j0<4; j0+=step_v0)
  for (i0=0; i0<4; i0+=step_h0)
  {
    k=2*(j0/2)+(i0/2);
    if ((currMB->b8pdir[k]==1 || currMB->b8pdir[k]==2) && (currMB->b8mode[k]!=0))//has forward vector
    {
      mv_mode  = currMB->b8mode[k];
      step_h   = BLOCK_STEP [mv_mode][0];
      step_v   = BLOCK_STEP [mv_mode][1];

      refframe = img->bw_refFrArr[img->block_y+j0][img->block_x+i0]; // always 0

      for (j=j0; j<j0+step_v0; j+=step_v)
      for (i=i0; i<i0+step_h0; i+=step_h)
      {
        j4 = img->block_y+j;
        i4 = img->block_x+i;

        // first make mv-prediction
        SetMotionVectorPredictor (img, pmv, pmv+1, refframe, img->bw_refFrArr, img->bw_mv, i, j, 4*step_h, 4*step_v);

        for (k=0; k < 2; k++) 
        {
#if TRACE
          snprintf(currSE.tracestring, TRACESTRING_SIZE, " MVD");
#endif
          img->subblock_x = i; // position used for context determination
          img->subblock_y = j; // position used for context determination
          currSE.value2   = 2*k+1; // identifies the component; only used for context determination
          dP->readSyntaxElement(&currSE,img,inp,dP);
          curr_mvd = currSE.value1; 
  
          vec=curr_mvd+pmv[k];           /* find motion vector */

          for(ii=0;ii<step_h;ii++)
            for(jj=0;jj<step_v;jj++)
              img->bw_mv[i4+ii+BLOCK_SIZE][j4+jj][k]=vec;

          /* store (oversampled) mvd */
          for (l=0; l < step_v; l++) 
            for (m=0; m < step_h; m++)  
              currMB->mvd[1][j+l][i+m][k] =  curr_mvd;
        }
      }
    }
  }
}



/*!
 ************************************************************************
 * \brief
 *    Get coded block pattern and coefficients (run/level)
 *    from the NAL
 ************************************************************************
 */
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, b8;
  int ll;
  int scan_loop_ctr;
  int block_x,block_y;
  int start_scan;
  int uv;

  int qp_per;
  int qp_rem;
  int qp_per_uv;
  int qp_rem_uv;


  // read CBP if not new intra mode
  if (!IS_NEWINTRA (currMB))
  {
    if (IS_OLDINTRA (currMB))   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 (IS_OLDINTRA (currMB))  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 (IS_INTER (currMB))  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
      {
        if (IS_INTER (currMB))   currSE.reading= readDquant_inter_FromBuffer_CABAC;
        else                     currSE.reading= readDquant_intra_FromBuffer_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-MIN_QP+currMB->delta_quant+(MAX_QP-MIN_QP+1))%(MAX_QP-MIN_QP+1)+MIN_QP;
    }
  }
  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 (IS_NEWINTRA (currMB)) // read DC coeffs for new intra modes
  {
    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= readDquant_intra_FromBuffer_CABAC;
    }
#if TRACE

⌨️ 快捷键说明

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