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

📄 macroblock.c

📁 h.264/avc 视频编码程序,实现分数像素匹配功能,非原创.
💻 C
📖 第 1 页 / 共 5 页
字号:
        ii=img->pix_c_x+i;
        imgUV[uv][jj][ii]=mcef[ref_frame][uv][jj][ii];
      }
    }
    if(img->type==SP_IMG_1 || img->type==SP_IMG_MULT)
    {
      for(j=0;j<MB_BLOCK_SIZE/2;j++)
      {
        jj=img->pix_c_y+j;
        for(i=0;i<MB_BLOCK_SIZE/2;i++)
        {
          ii=img->pix_c_x+i;
          img->mpr[i][j]=imgUV[uv][jj][ii];
        }
      }
      for (j=4;j<6;j++)
        for(i=0;i<4;i++)
          for(ii=0;ii<4;ii++)
            for(jj=0;jj<4;jj++)
              img->cof[i][j][ii][jj]=0;

      itrans_sp_chroma(img,2*uv);

      for (j=4;j<6;j++)
      {
        for(i=0;i<2;i++)
        {
          itrans(img,i*4,(j-4)*4,2*uv+i,j);

          for(ii=0;ii<4;ii++)
            for(jj=0;jj<4;jj++)
            {
              imgUV[uv][img->pix_c_y+(j-4)*4+jj][img->pix_c_x+i*4+ii]=img->m7[ii][jj];
            }
        }
      }
    }
  }
}

/*!
 ************************************************************************
 * \brief
 *    decode one macroblock
 ************************************************************************
 */

int decode_one_macroblock(struct img_par *img,struct inp_par *inp)
{
  int tmp_block[BLOCK_SIZE][BLOCK_SIZE];
  int tmp_blockbw[BLOCK_SIZE][BLOCK_SIZE];
  int js[2][2];
  int i=0,j=0,k,ii=0,jj=0,i1=0,j1=0,j4=0,i4=0;
  int js0=0,js1=0,js2=0,js3=0,jf=0;
  int uv, hv;
  int vec1_x=0,vec1_y=0,vec2_x=0,vec2_y=0;
  int ioff,joff;

  int bw_pred, fw_pred, ifx;
  int ii0,jj0,ii1,jj1,if1,jf1,if0,jf0;
  int mv_mul,f1,f2,f3,f4;

  const byte decode_block_scan[16] = {0,1,4,5,2,3,6,7,8,9,12,13,10,11,14,15};

  Macroblock *currMB   = &img->mb_data[img->current_mb_nr];
  int refframe, fw_refframe, bw_refframe, mv_mode, pred_dir, intra_prediction; // = currMB->ref_frame;
  int*** mv_array, ***fw_mv_array, ***bw_mv_array;
  int bframe = (img->type==B_IMG_1 || img->type==B_IMG_MULT);
  byte refP_tr, TRb, TRp;

#ifdef _ADAPT_LAST_GROUP_
  extern int *last_P_no;
#endif

  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);

  if(img->UseConstrainedIntraPred)
  {
    if (mb_available_up   && (img->intra_block[mb_nr-mb_width][2]==0 || img->intra_block[mb_nr-mb_width][3]==0))
      mb_available_up   = 0;
    if (mb_available_left && (img->intra_block[mb_nr-       1][1]==0 || img->intra_block[mb_nr       -1][3]==0))
      mb_available_left = 0;
  }


  // 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;

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

  // get prediction for INTRA_MB_16x16
  if (IS_NEWINTRA (currMB))
  {
    intrapred_luma_2(img, currMB->i16mode);
  }

  for (k = 0; k < (MB_BLOCK_SIZE/BLOCK_SIZE)*(MB_BLOCK_SIZE/BLOCK_SIZE); k ++)
  {
    i = (decode_block_scan[k] & 3);
    j = ((decode_block_scan[k] >> 2) & 3);

    ioff=i*4;
    i4=img->block_x+i;

    joff=j*4;
    j4=img->block_y+j;

    mv_mode  = currMB->b8mode[2*(j/2)+(i/2)];
    pred_dir = currMB->b8pdir[2*(j/2)+(i/2)];
          
    // PREDICTION
    if (mv_mode==IBLOCK)
    {
      //===== INTRA PREDICTION =====
      if (intrapred(img,ioff,joff,i4,j4)==SEARCH_SYNC)  /* make 4x4 prediction block mpr from given prediction img->mb_mode */
        return SEARCH_SYNC;                   /* bit error */
    }
    else if (!IS_NEWINTRA (currMB))
    {
      if (pred_dir != 2)
      {
        //===== FORWARD/BACKWARD PREDICTION =====
        if (!bframe)
        {
          //refframe = (img->frame_cycle + img->buf_cycle - refFrArr[j4][i4]) % img->buf_cycle;
          refframe = refFrArr[j4][i4];
          mv_array = img->mv;
        }
        else if (!pred_dir)
        {
          //refframe = (img->number - 1 - img->fw_refFrArr[j4][i4] + img->buf_cycle) % img->buf_cycle;
          refframe = img->fw_refFrArr[j4][i4]+1;
          mv_array = img->fw_mv;
        }
        else
        {
          //refframe = (img->frame_cycle + img->buf_cycle) % img->buf_cycle;
          refframe = 0;
          mv_array = img->bw_mv;
        }

        vec1_x = i4*4*mv_mul + mv_array[i4+BLOCK_SIZE][j4][0];
        vec1_y = j4*4*mv_mul + mv_array[i4+BLOCK_SIZE][j4][1];

        get_block (refframe, vec1_x, vec1_y, img, tmp_block);

        for(ii=0;ii<BLOCK_SIZE;ii++)
        for(jj=0;jj<BLOCK_SIZE;jj++)  img->mpr[ii+ioff][jj+joff] = tmp_block[ii][jj];
      }
      else
      {
        if (mv_mode != 0)
        {
          //===== BI-DIRECTIONAL PREDICTION =====
          fw_mv_array = img->fw_mv;
          bw_mv_array = img->bw_mv;
          fw_refframe = img->fw_refFrArr[j4][i4]+1;
          bw_refframe = 0;
        }
        else
        {
          //===== DIRECT PREDICTION =====
          fw_mv_array = img->dfMV;
          bw_mv_array = img->dbMV;
          bw_refframe = 0;

          if(refFrArr[j4][i4]==-1) // next P is intra mode
          {
            for(hv=0; hv<2; hv++)   img->dfMV[i4+BLOCK_SIZE][j4][hv]=img->dbMV[i4+BLOCK_SIZE][j4][hv]=0;
            fw_refframe = 1;
          }
          else // next P is skip or inter mode
          {
#ifdef _ADAPT_LAST_GROUP_
            refP_tr = last_P_no[refFrArr[j4][i4]];
#else
            refP_tr = nextP_tr-((refFrArr[j4][i4]+1)*P_interval);
#endif
            TRb = img->tr-refP_tr;
            TRp = nextP_tr-refP_tr;

            img->dfMV[i4+BLOCK_SIZE][j4][0]=TRb*img->mv[i4+BLOCK_SIZE][j4][0]/TRp;
            img->dfMV[i4+BLOCK_SIZE][j4][1]=TRb*img->mv[i4+BLOCK_SIZE][j4][1]/TRp;
            img->dbMV[i4+BLOCK_SIZE][j4][0]=(TRb-TRp)*img->mv[i4+BLOCK_SIZE][j4][0]/TRp;
            img->dbMV[i4+BLOCK_SIZE][j4][1]=(TRb-TRp)*img->mv[i4+BLOCK_SIZE][j4][1]/TRp;
            //fw_refframe = (img->number - 1 - refFrArr[j4][i4] + img->buf_cycle) % img->buf_cycle;
            fw_refframe = refFrArr[j4][i4]+1;
          }
        }

        vec1_x = i4*4*mv_mul + fw_mv_array[i4+BLOCK_SIZE][j4][0];
        vec1_y = j4*4*mv_mul + fw_mv_array[i4+BLOCK_SIZE][j4][1];
        vec2_x = i4*4*mv_mul + bw_mv_array[i4+BLOCK_SIZE][j4][0];
        vec2_y = j4*4*mv_mul + bw_mv_array[i4+BLOCK_SIZE][j4][1];

        get_block(fw_refframe, vec1_x, vec1_y, img, tmp_block);
        get_block(bw_refframe, vec2_x, vec2_y, img, tmp_blockbw);

        for(ii=0;ii<BLOCK_SIZE;ii++)
        for(jj=0;jj<BLOCK_SIZE;jj++)  img->mpr[ii+ioff][jj+joff] = (tmp_block[ii][jj]+tmp_blockbw[ii][jj]+1)/2;
      }
    }

    if ((img->type==SP_IMG_1 || img->type==SP_IMG_MULT) && (IS_INTER (currMB) && mv_mode!=IBLOCK))
    {
      itrans_sp(img,ioff,joff,i,j);
    }
    else
    {
      itrans   (img,ioff,joff,i,j);      // use DCT transform and make 4x4 block m7 from prediction block mpr
    }

    for(ii=0;ii<BLOCK_SIZE;ii++)
    {
      for(jj=0;jj<BLOCK_SIZE;jj++)
      {
        imgY[j4*BLOCK_SIZE+jj][i4*BLOCK_SIZE+ii]=img->m7[ii][jj]; // contruct picture from 4x4 blocks
      }
    }
  }


  // chroma decoding *******************************************************
  for(uv=0;uv<2;uv++)
  {
    intra_prediction = (IS_NEWINTRA (currMB)        ||
                        currMB->b8mode[0] == IBLOCK ||
                        currMB->b8mode[1] == IBLOCK ||
                        currMB->b8mode[2] == IBLOCK ||
                        currMB->b8mode[3] == IBLOCK);

    if (intra_prediction)
    {
      js0=0;
      js1=0;
      js2=0;
      js3=0;
      for(i=0;i<4;i++)
      {
        if(mb_available_up)
        {
          js0=js0+imgUV[uv][img->pix_c_y-1][img->pix_c_x+i];
          js1=js1+imgUV[uv][img->pix_c_y-1][img->pix_c_x+i+4];
        }
        if(mb_available_left)
        {
          js2=js2+imgUV[uv][img->pix_c_y+i][img->pix_c_x-1];
          js3=js3+imgUV[uv][img->pix_c_y+i+4][img->pix_c_x-1];
        }
      }
      if(mb_available_up && mb_available_left)
      {
        js[0][0]=(js0+js2+4)/8;
        js[1][0]=(js1+2)/4;
        js[0][1]=(js3+2)/4;
        js[1][1]=(js1+js3+4)/8;
      }
      if(mb_available_up && !mb_available_left)
      {
        js[0][0]=(js0+2)/4;
        js[1][0]=(js1+2)/4;
        js[0][1]=(js0+2)/4;
        js[1][1]=(js1+2)/4;
      }
      if(mb_available_left && !mb_available_up)
      {
        js[0][0]=(js2+2)/4;
        js[1][0]=(js2+2)/4;
        js[0][1]=(js3+2)/4;
        js[1][1]=(js3+2)/4;
      }
      if(!mb_available_up && !mb_available_left)
      {
        js[0][0]=128;
        js[1][0]=128;
        js[0][1]=128;
        js[1][1]=128;
      }
    }

    for (j=4;j<6;j++)
    {
      joff=(j-4)*4;
      j4=img->pix_c_y+joff;
      for(i=0;i<2;i++)
      {
        ioff=i*4;
        i4=img->pix_c_x+ioff;

        mv_mode  = currMB->b8mode[2*(j-4)+i];
        pred_dir = currMB->b8pdir[2*(j-4)+i];

        // PREDICTION
        if (mv_mode==IBLOCK || IS_NEWINTRA (currMB))
        {
          //--- INTRA PREDICTION ---
          for (ii=0; ii<4; ii++)
          for (jj=0; jj<4; jj++)
          {
            img->mpr[ii+ioff][jj+joff]=js[i][j-4];
          }
        }
        else if (pred_dir != 2)
        {
          //--- FORWARD/BACKWARD PREDICTION ---
          if (!bframe)        mv_array = img->mv;
          else if (!pred_dir) mv_array = img->fw_mv;
          else                mv_array = img->bw_mv;

          for(jj=0;jj<4;jj++)
          {
            jf=(j4+jj)/2;
            for(ii=0;ii<4;ii++)
            {
              if1=(i4+ii)/2;

              if (!bframe)        refframe =           refFrArr[jf][if1];
              else if (!pred_dir) refframe = 1+img->fw_refFrArr[jf][if1];
              else                refframe = 0;

              i1=(img->pix_c_x+ii+ioff)*f1+mv_array[if1+4][jf][0];
              j1=(img->pix_c_y+jj+joff)*f1+mv_array[if1+4][jf][1];

              ii0=max (0, min (i1/f1, img->width_cr-1));
              jj0=max (0, min (j1/f1, img->height_cr-1));
              ii1=max (0, min ((i1+f2)/f1, img->width_cr-1));
              jj1=max (0, min ((j1+f2)/f1, img->height_cr-1));

              if1=(i1 & f2);
              jf1=(j1 & f2);
              if0=f1-if1;
              jf0=f1-jf1;
              img->mpr[ii+ioff][jj+joff]=(if0*jf0*mcef[refframe][uv][jj0][ii0]+
                                          if1*jf0*mcef[refframe][uv][jj0][ii1]+
                                          if0*jf1*mcef[refframe][uv][jj1][ii0]+
                                          if1*jf1*mcef[refframe][uv][jj1][ii1]+f4)/f3;
            }
          }
        }
        else
        {
          if (mv_mode != 0)
          {
            //===== BI-DIRECTIONAL PREDICTION =====
            fw_mv_array = img->fw_mv;
            bw_mv_array = img->bw_mv;
          }
          else
          {
            //===== DIRECT PREDICTION =====
            fw_mv_array = img->dfMV;
            bw_mv_array = img->dbMV;
          }

          for(jj=0;jj<4;jj++)
          {
            jf=(j4+jj)/2;
            for(ii=0;ii<4;ii++)
            {
              ifx=(i4+ii)/2;

              if (mv_mode != 0)
              {
                fw_refframe = 1+img->fw_refFrArr[jf][ifx];
                bw_refframe = 0;
              }
              else
              {
                bw_refframe = 0;
                if(refFrArr[jf][ifx]==-1)  fw_refframe = 1;
                else               

⌨️ 快捷键说明

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