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

📄 rdopt.c

📁 包含了从MPEG4的视频解码到H.264的视频编码部分的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
 *************************************************************************************
 * \brief
 *    Gets mode offset for intra16x16 mode
 *************************************************************************************
 */
int I16Offset (int cbp, int i16mode)
{
  return (cbp&15?13:1) + i16mode + ((cbp&0x30)>>2);
}


/*! 
 *************************************************************************************
 * \brief
 *    Sets modes and reference frames for an macroblock
 *************************************************************************************
 */
void SetModesAndRefframeForBlocks (int mode)
{
  int i,j,k,l;
  Macroblock *currMB = &img->mb_data[img->current_mb_nr];
  int  bframe  = (img->type==B_IMG || img->type==BS_IMG);
  int  **abp_type_arr = abp_type_FrArr;
  int    **fwrefarr = fw_refFrArr;
  int    **bwrefarr = bw_refFrArr;
  int        **frefarr = refFrArr;
  int        block_y = img->block_y;

  if(input->InterlaceCodingOption >= MB_CODING && mb_adaptive && img->field_mode)
  {
    block_y = img->field_block_y;
    if(img->top_field)
    {
      frefarr  = refFrArr_top;
      fwrefarr = fw_refFrArr_top;
      bwrefarr = bw_refFrArr_top;
      abp_type_arr = abp_type_FrArr_top;
    }
    else
    {
      frefarr = refFrArr_bot;
      fwrefarr = fw_refFrArr_bot;
      bwrefarr = bw_refFrArr_bot;
      abp_type_arr = abp_type_FrArr_bot;
    }
  }

  //--- macroblock type ---
  currMB->mb_type = mode;

  //--- block 8x8 mode and prediction direction ---
  switch (mode)
  {
    case 0:
      for(i=0;i<4;i++)
      {
        currMB->b8mode[i] = 0;
        currMB->b8pdir[i] = (bframe?2:0);
      }
      break;
    case 1:
    case 2:
    case 3:
      for(i=0;i<4;i++)
      {
        currMB->b8mode[i] = mode;
        currMB->b8pdir[i] = best8x8pdir[mode][i];
      }
      break;
    case P8x8:
      for(i=0;i<4;i++)
      {
        currMB->b8mode[i]   = best8x8mode[i];
        currMB->b8pdir[i]   = best8x8pdir[mode][i];
      }
      break;
    case I4MB:
      for(i=0;i<4;i++)
      {
        currMB->b8mode[i] = IBLOCK;
        currMB->b8pdir[i] = -1;
     }
      break;
    case I16MB:
      for(i=0;i<4;i++)
      {
        currMB->b8mode[i] = 0;
        currMB->b8pdir[i] = -1;
      }
      break;
    default:
      printf ("Unsupported mode in SetModesAndRefframeForBlocks!\n");
      exit (1);
  }

#define IS_FW ((best8x8pdir[mode][k]==0 || best8x8pdir[mode][k]==2) && (mode!=P8x8 || best8x8mode[k]!=0 || !bframe))
#define IS_BW ((best8x8pdir[mode][k]==1 || best8x8pdir[mode][k]==2) && (mode!=P8x8 || best8x8mode[k]!=0))
  //--- reference frame arrays ---
  if (mode==0 || mode==I4MB || mode==I16MB)
  {
    if (bframe)
    { 
      for (j=0;j<4;j++)
      for (i=0;i<4;i++)
      {
        if(!mode)
        {
          if (img->type==BS_IMG)
          {
            fwrefarr[block_y+j][img->block_x+i] = fwdir_refFrArr[block_y+j][img->block_x+i];
            bwrefarr[block_y+j][img->block_x+i] = bwdir_refFrArr[block_y+j][img->block_x+i];            
            frefarr [block_y+j][img->block_x+i] = fwdir_refFrArr[block_y+j][img->block_x+i];
            abp_type_arr[block_y+j][img->block_x+i] = best8x8abp_type[mode][2*(j/2)+(i/2)];
          }
          else 
          {
            if (input->direct_type)
            {
              fwrefarr[block_y+j][img->block_x+i] = fwdir_refFrArr[block_y+j][img->block_x+i];
              bwrefarr[block_y+j][img->block_x+i] = bwdir_refFrArr[block_y+j][img->block_x+i];            
            }
            else
            {
              fwrefarr[block_y+j][img->block_x+i] = frefarr[block_y+j][img->block_x+i];
              bwrefarr[block_y+j][img->block_x+i] = min(frefarr[block_y+j][img->block_x+i],0);
            }
          }
        }
        else
        {
          fwrefarr[block_y+j][img->block_x+i] = -1;
          bwrefarr[block_y+j][img->block_x+i] = -1;          
          if (img->type==BS_IMG)
          {
            frefarr [block_y+j][img->block_x+i] = -1;
            abp_type_arr[block_y+j][img->block_x+i] = best8x8abp_type[mode][2*(j/2)+(i/2)];
          }
        }
      }
    }
    else
    {
      for (j=0;j<4;j++)
      for (i=0;i<4;i++)
      {
        frefarr [block_y+j][img->block_x+i] = (mode==0?0:-1);
      }
    }
  }
  else
  {
    if (bframe)
    {
      for (j=0;j<4;j++)
      for (i=0;i<4;i++)
      {
        k = 2*(j/2)+(i/2);
        l = 2*(j%2)+(i%2);

        if (img->type==BS_IMG)
        {
          if(mode == P8x8 && best8x8mode[k]==0)
          {
            fwrefarr[block_y+j][img->block_x+i] = fwdir_refFrArr[block_y+j][img->block_x+i];
            bwrefarr[block_y+j][img->block_x+i] = bwdir_refFrArr[block_y+j][img->block_x+i];            
          }
          else
          {
            fwrefarr[block_y+j][img->block_x+i] = (IS_FW ? best8x8ref[mode][k]   : -1);
            bwrefarr[block_y+j][img->block_x+i] = (IS_BW ? best8x8bwref[mode][k] : -1);
          }
          frefarr [block_y+j][img->block_x+i] = fwrefarr[block_y+j][img->block_x+i];
          abp_type_arr[block_y+j][img->block_x+i] = (IS_BW ? best8x8abp_type[mode][k] : 0);
        }
        else
        {
          if(mode == P8x8 && best8x8mode[k]==0)
          {           
            if (input->direct_type)
            {
              fwrefarr[block_y+j][img->block_x+i] = fwdir_refFrArr[block_y+j][img->block_x+i];
              bwrefarr[block_y+j][img->block_x+i] = bwdir_refFrArr[block_y+j][img->block_x+i];            
            }
            else
            {
              fwrefarr[block_y+j][img->block_x+i] = frefarr[block_y+j][img->block_x+i];
              bwrefarr[block_y+j][img->block_x+i] = min(frefarr[block_y+j][img->block_x+i],0);
            }
          }
          else
          {
            fwrefarr[block_y+j][img->block_x+i] = (IS_FW ? best8x8ref[mode][k] : -1);
            bwrefarr[block_y+j][img->block_x+i] = (IS_BW ?                   0 : -1);
          }
        }
      }
    }
    else
    {
      for (j=0;j<4;j++)
      for (i=0;i<4;i++)
      {
        k = 2*(j/2)+(i/2);
        l = 2*(j%2)+(i%2);
        frefarr [block_y+j][img->block_x+i] = (IS_FW ? best8x8ref[mode][k] : -1);
      }
    }
  }
#undef IS_FW
#undef IS_BW
}


/*! 
 *************************************************************************************
 * \brief
 *    Intra 16x16 mode decision
 *************************************************************************************
 */
void
Intra16x16_Mode_Decision (Macroblock* currMB, int* i16mode)
{
  intrapred_luma_16x16 ();   /* make intra pred for all 4 new modes */
  find_sad_16x16 (i16mode);   /* get best new intra mode */
  currMB->cbp = dct_luma_16x16 (*i16mode);
}



/*! 
 *************************************************************************************
 * \brief
 *    Sets Coefficients and reconstruction for an 8x8 block
 *************************************************************************************
 */
void SetCoeffAndReconstruction8x8 (Macroblock* currMB)
{
  int block, k, j, i;
  int block_y = img->block_y;
  int **ipredmodes = img->ipredmode;
 
  if(input->InterlaceCodingOption >= MB_CODING && mb_adaptive && img->field_mode)
  {
    block_y   = img->field_block_y;
    ipredmodes  = img->top_field ? img->ipredmode_top:img->ipredmode_bot;
  }

  //--- restore coefficients ---
  for (block=0; block<6; block++)
  for (k=0; k<4; k++)
  for (j=0; j<2; j++)
  for (i=0; i<65; i++)
    img->cofAC[block][k][j][i] = cofAC8x8[block][k][j][i];

  if (cnt_nonz_8x8<=5 && img->types!=SP_IMG)
  {
    currMB->cbp     = 0;
    currMB->cbp_blk = 0;
    for (j=0; j<16; j++)
    for (i=0; i<16; i++)  imgY[img->pix_y+j][img->pix_x+i] = mpr8x8[j][i];
  }
  else
  {
    currMB->cbp     = cbp8x8;
    currMB->cbp_blk = cbp_blk8x8;
    for (j=0; j<16; j++)
    for (i=0; i<16; i++)  imgY[img->pix_y+j][img->pix_x+i] = rec_mbY8x8[j][i];
  }

  //===== restore intra prediction modes for 8x8+ macroblock mode =====
  for (k=0, j=block_y+1; j<block_y+5; j++)
  for (     i=img->block_x+1; i<img->block_x+5; i++, k++)
  {
    ipredmodes    [i][j] = b8_ipredmode       [k];
    currMB->intra_pred_modes[k] = b8_intra_pred_modes[k];
  }
}


/*! 
 *************************************************************************************
 * \brief
 *    Sets motion vectors for an macroblock
 *************************************************************************************
 */
void SetMotionVectorsMB (Macroblock* currMB, int bframe)
{
  int i, j, k, l, mode8, pdir8, ref, by, bx, bxr, dref;
  int ***mv = tmp_mv;
  int *****all_mv = img->all_mv;
  int *****all_bmv = img->all_bmv;
  int ***fwMV    = tmp_fwMV;
  int ***bwMV    = tmp_bwMV;
  int *****imgmv   = img->mv;
  int *****p_fwMV  = img->p_fwMV;
  int *****p_bwMV  = img->p_bwMV;
  int **refar    = refFrArr;
  int **frefar     = fw_refFrArr;
  int block_y    = img->block_y;
  int **brefar     = bw_refFrArr;
  int  bw_ref;

  if(input->InterlaceCodingOption >= MB_CODING && mb_adaptive && img->field_mode)
  {
    if(img->top_field)
    {
      mv=tmp_mv_top;
      all_mv = img->all_mv_top;
      all_bmv = img->all_bmv_top;
      fwMV = tmp_fwMV_top;
      bwMV = tmp_bwMV_top;
      imgmv = img->mv_top;
      p_fwMV = img->p_fwMV_top;
      p_bwMV = img->p_bwMV_top;
      block_y = img->block_y/2;
      refar    = refFrArr_top;
      frefar     = fw_refFrArr_top;
      brefar     = bw_refFrArr_top;
    }
    else
    {
      mv=tmp_mv_bot;
      all_mv = img->all_mv_bot;
      all_bmv = img->all_bmv_bot;
      fwMV = tmp_fwMV_bot;
      bwMV = tmp_bwMV_bot;
      imgmv = img->mv_bot;
      p_fwMV = img->p_fwMV_bot;
      p_bwMV = img->p_bwMV_bot;
      block_y = (img->block_y-4)/2;
      refar    = refFrArr_bot;
      frefar     = fw_refFrArr_bot;
      brefar     = bw_refFrArr_bot;
    }
  }
  for (j=0; j<4; j++)
  for (i=0; i<4; i++)
  {
    mode8 = currMB->b8mode[k=2*(j/2)+(i/2)];
    pdir8 = currMB->b8pdir[k];
    l     = 2*(j%2)+(i%2);
    by    = block_y+j;
    bxr   = img->block_x+i;
    bx    = img->block_x+i+4;
    ref   = (bframe?frefar:refar)[by][bxr];
    bw_ref = (bframe?brefar:refar)[by][bxr];

    if (!bframe)
    {
      if (mode8!=IBLOCK && ref != -1)
      {
        mv   [0][by][bx] = all_mv [i][j][ ref][mode8][0];
        mv   [1][by][bx] = all_mv [i][j][ ref][mode8][1];
      }
      else
      {
        mv   [0][by][bx] = 0;
        mv   [1][by][bx] = 0;
      }

    if(input->InterlaceCodingOption >= MB_CODING && mb_adaptive)
    {
      rdopt->tmp_mv[0][j][i]  = mv[0][by][bx];
      rdopt->tmp_mv[1][j][i]  = mv[1][by][bx];
    }

    }
    else
    {
      if (pdir8==-1) // intra
      {
        fwMV [0][by][bx] = 0;
        fwMV [1][by][bx] = 0;
        bwMV [0][by][bx] = 0;
        bwMV [1][by][bx] = 0;
        dfMV     [0][by][bx] = 0;
        dfMV     [1][by][bx] = 0;
        dbMV     [0][by][bx] = 0;
        dbMV     [1][by][bx] = 0;
        if (img->type==BS_IMG)
        {
          mv   [0][by][bx] = 0;
          mv   [1][by][bx] = 0;
        }
      }
      else if (pdir8==0) // forward
      {
        fwMV [0][by][bx] = all_mv [i][j][ ref][mode8][0];
        fwMV [1][by][bx] = all_mv [i][j][ ref][mode8][1];
        bwMV [0][by][bx] = 0;
        bwMV [1][by][bx] = 0;
        dfMV     [0][by][bx] = 0;
        dfMV     [1][by][bx] = 0;
        dbMV     [0][by][bx] = 0;
        dbMV     [1][by][bx] = 0;
        if (img->type==BS_IMG)
        {
          mv   [0][by][bx] = all_mv [i][j][ ref][mode8][0];
          mv   [1][by][bx] = all_mv [i][j][ ref][mode8][1];
        }
      }
      else if (pdir8==1) // backward
      {
        fwMV [0][by][bx] = 0;
        fwMV [1][by][bx] = 0;

⌨️ 快捷键说明

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