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

📄 macroblock.c

📁 G729、h263、h264、MPEG4四种最流行的音频和视频标准的压缩和解压算法的源代码.rar
💻 C
📖 第 1 页 / 共 5 页
字号:
      case 0:  //===== TOP LEFT =====
        if      (mb_available_up)       for (i=0;i<4;i++)  s0 += image[up.pos_y][up.pos_x + i];
        if      (mb_available_left[0])  for (i=1;i<5;i++)  s2 += image[left[i].pos_y][left[i].pos_x];
        if      (mb_available_up && mb_available_left[0])  s  = (s0+s2+4) >> 3;
        else if (mb_available_up)                          s  = (s0   +2) >> 2;
        else if (mb_available_left[0])                     s  = (s2   +2) >> 2;
        break;
      case 1: //===== TOP RIGHT =====
        if      (mb_available_up)       for (i=4;i<8;i++)  s1 += image[up.pos_y][up.pos_x + i];
        else if (mb_available_left[0])  for (i=1;i<5;i++)  s2 += image[left[i].pos_y][left[i].pos_x];
        if      (mb_available_up)                          s  = (s1   +2) >> 2;
        else if (mb_available_left[0])                     s  = (s2   +2) >> 2;
        break;
      case 2: //===== BOTTOM LEFT =====
        if      (mb_available_left[1])  for (i=5;i<9;i++)  s3 += image[left[i].pos_y][left[i].pos_x];
        else if (mb_available_up)       for (i=0;i<4;i++)  s0 += image[up.pos_y][up.pos_x + i];
        if      (mb_available_left[1])                     s  = (s3   +2) >> 2;
        else if (mb_available_up)                          s  = (s0   +2) >> 2;
        break;
      case 3: //===== BOTTOM RIGHT =====
        if      (mb_available_up)       for (i=4;i<8;i++)  s1 += image[up.pos_y][up.pos_x + i];
        if      (mb_available_left[1])  for (i=5;i<9;i++)  s3 += image[left[i].pos_y][left[i].pos_x];
        if      (mb_available_up && mb_available_left[1])  s  = (s1+s3+4) >> 3;
        else if (mb_available_up)                          s  = (s1   +2) >> 2;
        else if (mb_available_left[1])                     s  = (s3   +2) >> 2;
        break;
      }


      //===== prediction =====
      for (j=block_y; j<block_y+4; j++)
      for (i=block_x; i<block_x+4; i++)
      {
        img->mprr_c[uv][DC_PRED_8][i][j] = s;
      }
    }

    // vertical prediction
    if (mb_available_up)
    {
      for (i=0; i<8; i++)
        hline[i] = image[up.pos_y][up.pos_x + i];
      for (i=0; i<8; i++)
      for (j=0; j<8; j++)
        img->mprr_c[uv][VERT_PRED_8][i][j] = hline[i];
    }

    // horizontal prediction 
    if (mb_available_left[0] && mb_available_left[1])
    {
      for (i=1; i<9; i++)
        vline[i] = image[left[i].pos_y][left[i].pos_x];
      for (i=0; i<8; i++)
      for (j=0; j<8; j++)
        img->mprr_c[uv][HOR_PRED_8][i][j] = vline[j+1]; 
    }

    // plane prediction 
    if (mb_available_left[0] && mb_available_left[1] && mb_available_up && mb_available_up_left)
    {
      ih = 4*(hline[7] - image[left[0].pos_y][left[0].pos_x]);
      iv = 4*(vline[7+1] - image[left[0].pos_y][left[0].pos_x]);
      for (i=1;i<4;i++)
      {
        ih += i*(hline[3+i] - hline[3-i]);
        iv += i*(vline[3+i+1] - vline[3-i+1]);
      }
      ib=(17*ih+16)>>5;
      ic=(17*iv+16)>>5;

      iaa=16*(hline[7]+vline[7+1]);
      for (j=0; j<8; j++)
      for (i=0; i<8; i++)
        img->mprr_c[uv][PLANE_8][i][j]=max(0,min(255,(iaa+(i-3)*ib +(j-3)*ic + 16)/32));// store plane prediction
    }
  }

  if (!input->rdopt) // the rd-opt part does not work correctly (see encode_one_macroblock)
  {                       // since ipredmodes could be overwritten => encoder-decoder-mismatches
    // pick lowest cost prediction mode
    min_cost = 1<<20;
    for (i=0;i<8;i++)
    {
      getNeighbour(mb_nr, 0 ,  i , 0, &left[i]);
    }
    for (mode=DC_PRED_8; mode<=PLANE_8; mode++)
    {
      if ((mode==VERT_PRED_8 && !mb_available_up) ||
          (mode==HOR_PRED_8 && (!mb_available_left[0] || !mb_available_left[1])) ||
          (mode==PLANE_8 && (!mb_available_left[0] || !mb_available_left[1] || !mb_available_up || !mb_available_up_left)))
        continue;

      cost = 0;
      for (uv=0; uv<2; uv++)
      {
        image = imgUV_org[uv];
        for (block_y=0; block_y<8; block_y+=4)
        for (block_x=0; block_x<8; block_x+=4)
        {
          for (k=0,j=block_y; j<block_y+4; j++)
          for (i=block_x; i<block_x+4; i++,k++)
          {
            diff[k] = image[left[j].pos_y][left[j].pos_x+i] - img->mprr_c[uv][mode][i][j];
          }
          cost += SATD(diff, input->hadamard);
        }
      }
      if (cost < min_cost)
      {
        best_mode = mode;
        min_cost = cost;
      }
    }

    currMB->c_ipred_mode = best_mode;
  }
 
}


/*!
 ************************************************************************
 * \brief
 *    Check if all reference frames for a macroblock are zero
 ************************************************************************
 */
int
ZeroRef (Macroblock* currMB)
{
  int i,j;

  for (j=0; j<4; j++)
  for (i=0; i<4; i++)
  {
    if (enc_picture->ref_idx[LIST_0][img->block_x+i][img->block_y+j]!=0)
    {
        return 0;
    }
  }
  return 1;
}


/*!
 ************************************************************************
 * \brief
 *    Converts macroblock type to coding value
 ************************************************************************
 */
int
MBType2Value (Macroblock* currMB)
{
  static const int dir1offset[3]    =  { 1,  2, 3};
  static const int dir2offset[3][3] = {{ 0,  4,  8},   // 1. block forward
                                       { 6,  2, 10},   // 1. block backward
                                       {12, 14, 16}};  // 1. block bi-directional

  int mbtype, pdir0, pdir1;

  if (img->type!=B_SLICE)
  {
    if      (currMB->mb_type==I4MB)     return (img->type==I_SLICE ? 0 : 6);
    else if (currMB->mb_type==I16MB)    return (img->type==I_SLICE ? 0 : 6) + img->i16offset;
    else if (currMB->mb_type==P8x8)
    {
      if (input->symbol_mode==UVLC && ZeroRef (currMB))  return 5;
      else                                               return 4;
    }
    else                                return currMB->mb_type;
  }
  else
  {
    mbtype = currMB->mb_type;
    pdir0  = currMB->b8pdir[0];
    pdir1  = currMB->b8pdir[3];

    if      (mbtype==0)       return 0;
    else if (mbtype==I4MB)    return 23;
    else if (mbtype==I16MB)   return 23 + img->i16offset;
    else if (mbtype==P8x8)    return 22;
    else if (mbtype==1)       return dir1offset[pdir0];
    else if (mbtype==2)       return 4 + dir2offset[pdir0][pdir1];
    else                      return 5 + dir2offset[pdir0][pdir1];
  }
}



/*!
 ************************************************************************
 * \brief
 *    Writes intra prediction modes for an 8x8 block
 ************************************************************************
 */
int writeIntra4x4Modes(int only_this_block)
{
  int i,j,bs_x,bs_y,ii,jj;
  int block8x8;
  int rate;
  int ipred_array[16],cont_array[16],ipred_number;
  Macroblock    *currMB     = &img->mb_data[img->current_mb_nr];
  SyntaxElement *currSE     = &img->MB_SyntaxElements[currMB->currSEnr];
  int           *bitCount   = currMB->bitcounter;
  Slice         *currSlice  = img->currentSlice;
  DataPartition *dataPart;
  const int     *partMap    = assignSE2partition[input->partition_mode];

  ipred_number=0;
  for(block8x8=0;block8x8<4;block8x8++)
  {
    if( currMB->b8mode[block8x8]==IBLOCK && (only_this_block<0||only_this_block==block8x8) )
    {
      bs_x=bs_y=4;
      ii=(bs_x>>2); // bug fix for solaris. mwi 
      jj=(bs_y>>2); // bug fix for solaris. mwi
      
      for(j=0;j<2;j+=jj)
      {
        for(i=0;i<2;i+=ii)
        {
          ipred_array[ipred_number]=currMB->intra_pred_modes[(block8x8<<2)|(j<<1)|i];
          cont_array[ipred_number]=(block8x8<<2)+(j<<1)+i;
          ipred_number++;
        }
      }
    }
  }
  rate=0;

  for(i=0;i<ipred_number;i++)
  {
    currMB->IntraChromaPredModeFlag = 1;
    currSE->context = cont_array[i];
    currSE->value1  = ipred_array[i];
    currSE->value2  = 0;

#if TRACE
    snprintf(currSE->tracestring, TRACESTRING_SIZE, "Intra mode     = %3d %d",currSE->value1,currSE->context);
#endif

    /*--- set symbol type and function pointers ---*/
    if (input->symbol_mode != UVLC)    currSE->writing = writeIntraPredMode_CABAC;
    currSE->type = SE_INTRAPREDMODE;

    /*--- choose data partition ---*/
    dataPart = &(currSlice->partArr[partMap[SE_INTRAPREDMODE]]);   
    /*--- encode and update rate ---*/
    if (input->symbol_mode == UVLC)    writeSyntaxElement_Intra4x4PredictionMode(currSE, dataPart);
    else                               dataPart->writeSyntaxElement (currSE, dataPart);
    bitCount[BITS_COEFF_Y_MB]+=currSE->len;
    rate += currSE->len;
    currSE++;
    currMB->currSEnr++;
  }

  return rate;
}



/*!
 ************************************************************************
 * \brief
 *    Converts 8x8 block tyoe to coding value
 ************************************************************************
 */
int
B8Mode2Value (int b8mode, int b8pdir)
{
  static const int b8start[8] = {0,0,0,0, 1, 4, 5, 10};
  static const int b8inc  [8] = {0,0,0,0, 1, 2, 2, 1};

  if (img->type!=B_SLICE)
  {
    return (b8mode-4);
  }
  else
  {
    return b8start[b8mode] + b8inc[b8mode] * b8pdir;
  }
}



/*!
 ************************************************************************
 * \brief
 *    Codes macroblock header
 ************************************************************************
 */
int writeMBHeader (int rdopt)  // GB CHROMA !!!!!!!!
{
  int             i,j;
  int             mb_nr     = img->current_mb_nr;
  Macroblock*     currMB    = &img->mb_data[mb_nr];
  Macroblock*     prevMB    = mb_nr ? (&img->mb_data[mb_nr-1]) : NULL;
  SyntaxElement  *currSE    = &img->MB_SyntaxElements[currMB->currSEnr];
  int*            bitCount  = currMB->bitcounter;
  Slice*          currSlice = img->currentSlice;
  DataPartition*  dataPart;
  const int*      partMap   = assignSE2partition[input->partition_mode];
  int             no_bits   = 0;
  int             skip      = currMB->mb_type ? 0:((img->type == B_SLICE) ? !currMB->cbp:1);
  int             mb_type;
  int							prevMbSkipped = 0;
	int							mb_field_tmp;
  Macroblock			*topMB = NULL;
  
  int             WriteFrameFieldMBInHeader = 0;

  if (img->MbaffFrameFlag)
  {
    if (0==(mb_nr%2))
    {
      WriteFrameFieldMBInHeader = 1; // top field

      prevMbSkipped = 0;
    }
    else
    {
      if (prevMB->mb_type ? 0:((img->type == B_SLICE) ? !prevMB->cbp:1))
      {
        WriteFrameFieldMBInHeader = 1; // bottom, if top was skipped
      }

      topMB= &img->mb_data[img->current_mb_nr-1];
      if(!(img->type == B_SLICE))
        prevMbSkipped = (topMB->mb_type == 0);
      else 
        prevMbSkipped = (topMB->mb_type == 0 && topMB->cbp == 0);
    }
  }
  currMB->IntraChromaPredModeFlag = IS_INTRA(currMB);

  // choose the appropriate data partition
  dataPart = &(currSlice->partArr[partMap[SE_MBTYPE]]);
  
  //=====  BITS FOR MACROBLOCK MODE =====
  if(img->type == I_SLICE)//GB
  {
    // write mb_aff 
    if(img->MbaffFrameFlag && !skip) // check for copy mode, Krit
    {
      if(WriteFrameFieldMBInHeader)
      {
        currSE->value1 =  currMB->mb_field;
        currSE->value2 = 0;
        currSE->type   =  SE_MBTYPE;
        
        if (input->symbol_mode==UVLC)   currSE->mapping = ue_linfo;
        else                            currSE->writing = writeFieldModeInfo_CABAC;
          
#if TRACE
        snprintf(currSE->tracestring, TRACESTRING_SIZE, "Field mode = %3d",currMB->mb_field);
#endif
        if( input->symbol_mode==UVLC)
        {
          currSE->bitpattern = (currMB->mb_field ? 1 : 0);
          currSE->len = 1;
          writeSyntaxElement2Buf_Fixed(currSE, dataPart->bitstream);
        }
        else
        {
          dataPart->writeSyntaxElement(currSE, dataPart);
        }

        bitCount[BITS_MB_MODE] += currSE->len;
        no_bits                += currSE->len;
        currSE++;
        currMB->currSEnr++;
      }
    }
    
                        // write mb_type
    currSE->value1  = MBType2Value (currMB);
    currSE->value2  = 0;
    currSE->type    = SE_MBTYPE;
    
    if (input->symbol_mode == UVLC)  currSE->mapping = ue_linfo;
    else                             currSE->writing = writeMB_typeInfo_CABAC;
    
    dataPart->writeSyntaxElement( currSE, dataPart);
#if TRACE
    snprintf(currS

⌨️ 快捷键说明

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