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

📄 b_frame.c

📁 本源码是H.26L标准的Visual C++源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
    {
      block_available_up = mb_available_up || (j > 0);
      j4=img->block_y+j;
      for(i=0;i<4;i=i+BLOCK_STEP[blocktype][0]) // X position in 4-pel resolution
      {
        i4=img->block_x+i;
        block_available_left = mb_available_left || (i > 0);

        if (j > 0)
          block_available_upright = i != ie ? 1 : 0;
        else if (i != ie)
          block_available_upright = block_available_up;
        else
          block_available_upright = mb_available_upright;

        if (i > 0)
          block_available_upleft = j > 0 ? 1 : block_available_up;
        else if (j > 0)
          block_available_upleft = block_available_left;
        else
          block_available_upleft = mb_available_upleft;

        mvPredType = MVPRED_MEDIAN;

        rFrameL    = block_available_left    ? img->fw_refFrArr[j4][i4-1]   : -1;
        rFrameU    = block_available_up      ? img->fw_refFrArr[j4-1][i4]   : -1;
        rFrameUR   = block_available_upright ? img->fw_refFrArr[j4-1][i4+BLOCK_STEP[blocktype][0]] :
                     block_available_upleft  ? img->fw_refFrArr[j4-1][i4-1] : -1;

        // Prediction if only one of the neighbors uses the selected reference frame
        if(rFrameL == fw_predframe_no && rFrameU != fw_predframe_no && rFrameUR != fw_predframe_no)
          mvPredType = MVPRED_L;
        else if(rFrameL != fw_predframe_no && rFrameU == fw_predframe_no && rFrameUR != fw_predframe_no)
          mvPredType = MVPRED_U;
        else if(rFrameL != fw_predframe_no && rFrameU != fw_predframe_no && rFrameUR == fw_predframe_no)
          mvPredType = MVPRED_UR;

        // Directional predictions
        else if(blocktype == 3)
        {
          if(i == 0)
          {
            if(rFrameL == fw_predframe_no)
              mvPredType = MVPRED_L;
          }
          else
          {
            if(rFrameUR == fw_predframe_no)
              mvPredType = MVPRED_UR;
          }
        }
        else if(blocktype == 2)
        {
          if(j == 0)
          {
            if(rFrameU == fw_predframe_no)
              mvPredType = MVPRED_U;
          }
          else
          {
            if(rFrameL == fw_predframe_no)
              mvPredType = MVPRED_L;
          }
        }
        else if(blocktype == 5 && i == 2)
          mvPredType = MVPRED_L;
        else if(blocktype == 6 && j == 2)
          mvPredType = MVPRED_U;

        for (k=0;k<2;k++)                       // vector prediction. find first koordinate set for pred
        {
          mv_a = block_available_left ? img->fw_mv[i4-1+BLOCK_SIZE][j4][k] : 0;
          mv_b = block_available_up   ? img->fw_mv[i4+BLOCK_SIZE][j4-1][k]   : 0;
          mv_d = block_available_upleft  ? img->fw_mv[i4-1+BLOCK_SIZE][j4-1][k] : 0;
          mv_c = block_available_upright ? img->fw_mv[i4+BLOCK_STEP[blocktype][0]+BLOCK_SIZE][j4-1][k] : 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 TRACE
          snprintf(currSE->tracestring, TRACESTRING_SIZE, " MVD(%d) ",k);
#endif

          currSE->type = SE_MVD;
          dp = &(currSlice->partArr[partMap[SE_BFRAME]]);

          if (inp->symbol_mode == UVLC)
            currSE->mapping = linfo_mvd; // linfo_2
          else
          {
            img->subblock_x = i; // position used for context determination
            img->subblock_y = j; // position used for context determination
                currSE->value2 = 2*k; // identifies the component and the direction; only used for context determination
                        currSE->reading = readBiMVD2Buffer_CABAC;
          }

          dp->readSyntaxElement(  currSE, img, inp, dp);

          vec = currSE->value1;

          for (l=0; l < BLOCK_STEP[blocktype][1]; l++)
            for (m=0; m < BLOCK_STEP[blocktype][0]; m++)
              currMB->mvd[0][j+l][i+m][k] =  vec;

          vec=vec+pred_vec;

          for(ii=0;ii<BLOCK_STEP[blocktype][0];ii++)
          {
            for(jj=0;jj<BLOCK_STEP[blocktype][1];jj++)
            {
              img->fw_mv[i4+ii+BLOCK_SIZE][j4+jj][k]=vec;
            }
          }

        }
      }
    }
  }

  // /////////////////////////////////////////////////////////////
  // find MVDBW
  // /////////////////////////////////////////////////////////////
  if(img->imod==B_Backward || img->imod==B_Bidirect)
  {
    // backward : note realtion between blocktype and img->mb_mode
    // bidirect : after reading bw_blk_size, bw_pmv is obtained

    if(img->mb_mode==2)
            blocktype=1;
    else if(img->mb_mode>4)
            blocktype=(img->mb_mode-1)/2;
    else if(img->mb_mode==3)
            blocktype=bw_blocktype;

        img->bw_blc_size_h = BLOCK_STEP[blocktype][0]*4;
        img->bw_blc_size_v = BLOCK_STEP[blocktype][1]*4;

    ie=4-BLOCK_STEP[blocktype][0];
    for(j=0;j<4;j=j+BLOCK_STEP[blocktype][1])   // Y position in 4-pel resolution
    {
      block_available_up = mb_available_up || (j > 0);
      j4=img->block_y+j;
      for(i=0;i<4;i=i+BLOCK_STEP[blocktype][0]) // X position in 4-pel resolution
      {
        i4=img->block_x+i;
        block_available_left = mb_available_left || (i > 0);

        if (j > 0)
          block_available_upright = i != ie ? 1 : 0;
        else if (i != ie)
          block_available_upright = block_available_up;
        else
          block_available_upright = mb_available_upright;

        if (i > 0)
          block_available_upleft = j > 0 ? 1 : block_available_up;
        else if (j > 0)
          block_available_upleft = block_available_left;
        else
          block_available_upleft = mb_available_upleft;

        mvPredType = MVPRED_MEDIAN;

        rFrameL    = block_available_left    ? img->bw_refFrArr[j4][i4-1]   : -1;
        rFrameU    = block_available_up      ? img->bw_refFrArr[j4-1][i4]   : -1;
        rFrameUR   = block_available_upright ? img->bw_refFrArr[j4-1][i4+BLOCK_STEP[blocktype][0]] :
                     block_available_upleft  ? img->bw_refFrArr[j4-1][i4-1] : -1;

        // Prediction if only one of the neighbors uses the selected reference frame
        if(rFrameL == bw_predframe_no && rFrameU != bw_predframe_no && rFrameUR != bw_predframe_no)
          mvPredType = MVPRED_L;
        else if(rFrameL != bw_predframe_no && rFrameU == bw_predframe_no && rFrameUR != bw_predframe_no)
          mvPredType = MVPRED_U;
        else if(rFrameL != bw_predframe_no && rFrameU != bw_predframe_no && rFrameUR == bw_predframe_no)
          mvPredType = MVPRED_UR;

        // Directional predictions
        else if(blocktype == 3)
        {
          if(i == 0)
          {
            if(rFrameL == bw_predframe_no)
              mvPredType = MVPRED_L;
          }
          else
          {
            if(rFrameUR == bw_predframe_no)
              mvPredType = MVPRED_UR;
          }
        }
        else if(blocktype == 2)
        {
          if(j == 0)
          {
            if(rFrameU == bw_predframe_no)
              mvPredType = MVPRED_U;
          }
          else
          {
            if(rFrameL == bw_predframe_no)
              mvPredType = MVPRED_L;
          }
        }
        else if(blocktype == 5 && i == 2)
          mvPredType = MVPRED_L;
        else if(blocktype == 6 && j == 2)
          mvPredType = MVPRED_U;

        for (k=0;k<2;k++)                       // vector prediction. find first koordinate set for pred
        {
          mv_a = block_available_left ? img->bw_mv[i4-1+BLOCK_SIZE][j4][k] : 0;
          mv_b = block_available_up   ? img->bw_mv[i4+BLOCK_SIZE][j4-1][k]   : 0;
          mv_d = block_available_upleft  ? img->bw_mv[i4-1+BLOCK_SIZE][j4-1][k] : 0;
          mv_c = block_available_upright ? img->bw_mv[i4+BLOCK_STEP[blocktype][0]+BLOCK_SIZE][j4-1][k] : 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 TRACE
          snprintf(currSE->tracestring, TRACESTRING_SIZE, " MVD(%d) ",k);
#endif

          currSE->type = SE_MVD;
          dp = &(currSlice->partArr[partMap[SE_BFRAME]]);

          if (inp->symbol_mode == UVLC)
            currSE->mapping = linfo_mvd; // linfo_2
          else
          {
            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 and the direction; only used for context determination
                        currSE->reading = readBiMVD2Buffer_CABAC;
          }

          dp->readSyntaxElement(  currSE, img, inp, dp);

          vec = currSE->value1;

          for (l=0; l < BLOCK_STEP[blocktype][1]; l++)
            for (m=0; m < BLOCK_STEP[blocktype][0]; m++)
              currMB->mvd[1][j+l][i+m][k] =  vec;

          vec=vec+pred_vec;

          for(ii=0;ii<BLOCK_STEP[blocktype][0];ii++)
          {
            for(jj=0;jj<BLOCK_STEP[blocktype][1];jj++)
            {
              img->bw_mv[i4+ii+BLOCK_SIZE][j4+jj][k]=vec;
            }
          }

        }
      }
    }
  }
}

/*!
 ************************************************************************
 * \brief
 *    decode one macroblock for a B frame
 ************************************************************************
 */
int decode_one_macroblock_Bframe(struct img_par *img)
{
  int tmp_block[BLOCK_SIZE][BLOCK_SIZE];
  int tmp_blockbw[BLOCK_SIZE][BLOCK_SIZE];
  int js[2][2];
  int i,j,ii,jj,i1,j1,j4,i4;
  int js0,js1,js2,js3,jf,ifx;
  int uv;
  int vec1_x,vec1_y,vec2_x,vec2_y, vec1_xx, vec1_yy;
  int fw_pred, bw_pred;

  int ioff,joff;
  int ii0,jj0,ii1,jj1,if1,jf1,if0,jf0;

  int hv;
  byte refP_tr, TRb, TRp;
  // keep track of neighbouring macroblocks available for prediction

  int mb_nr = img->current_mb_nr;
  int mb_width = img->width/16;
  int mb_available_up = (img->mb_y == 0) ? 0 : (img->mb_data[mb_nr].slice_nr == img->mb_data[mb_nr-mb_width].slice_nr);
  int mb_available_left = (img->mb_x == 0) ? 0 : (img->mb_data[mb_nr].slice_nr == img->mb_data[mb_nr-1].slice_nr);
  Macroblock *currMB = &img->mb_data[img->current_mb_nr];

  int ref_frame_bw = 0;
  int ref_frame_fw = currMB->ref_frame+1;
  int ref_frame = ref_frame_fw;
  int mv_mul, f1, f2, f3, f4;



#ifdef _ADAPT_LAST_GROUP_
  extern int *last_P_no;
#endif

#if POS
  int color;
  if( mb_nr == 122)
    color = 0;
  else
    color = 0xff;
#endif

  // set variables depending on mv_res
  if(img->mv_res)
  {
    mv_mul=8;
    f1=16;
    f2=15;
  }
  else
  {
    mv_mul=4;
    f1=8;
    f2=7;
  }

  f3=f1*f1;
  f4=f3/2;

  // ////////////////////////////////////////////////////////////
  // start_scan decoding
  // ////////////////////////////////////////////////////////////
  /**********************************
   *    luma                        *
   *********************************/

  if (img->imod==INTRA_MB_NEW)
    intrapred_luma_2( img, currMB->intra_pred_modes[0]);

  for(j=0;j<MB_BLOCK_SIZE/BLOCK_SIZE;j++)
  {
    joff=j*4;
    j4=img->block_y+j;
    for(i=0;i<MB_BLOCK_SIZE/BLOCK_SIZE;i++)
    {
      ioff=i*4;
      i4=img->block_x+i;
      if(img->imod==INTRA_MB_OLD)
      {

⌨️ 快捷键说明

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