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

📄 macroblock.c

📁 the newest JM software by h.264 JVT official reference model.
💻 C
📖 第 1 页 / 共 5 页
字号:
}

/*!
************************************************************************
* \brief
*    Writes 8x8 intra prediction modes for a macroblock
************************************************************************
*/
int writeIntra8x8Modes(Slice *currSlice, Macroblock *currMB)
{
  int block8x8;
  SyntaxElement se;
  int           *bitCount   = currMB->bitcounter;    
  const int     *partMap    = assignSE2partition[params->partition_mode];
  DataPartition *dataPart   = &(currSlice->partArr[partMap[SE_INTRAPREDMODE]]);

  int rate = 0;

  currMB->IntraChromaPredModeFlag = 1;

  for(block8x8 = 0; block8x8 < 16; block8x8 += 4)
  {

    se.context = block8x8;
    se.value1  = currMB->intra_pred_modes8x8[block8x8];
    se.value2  = 0;

#if TRACE
    if (se.value1 < 0 )
      snprintf(se.tracestring, TRACESTRING_SIZE, "Intra 8x8 mode  = predicted (context: %d)",se.context);
    else
      snprintf(se.tracestring, TRACESTRING_SIZE, "Intra 8x8 mode  = %3d (context: %d)",se.value1,se.context);
#endif

    // set symbol type and function pointers
    se.type = SE_INTRAPREDMODE;

    // encode and update rate
    writeIntraPredMode (&se, dataPart);

    rate += se.len;
  }
  bitCount[BITS_COEFF_Y_MB] += rate;

  return rate;
}

int writeIntraModes(Slice *currSlice, Macroblock *currMB)
{
  switch (currMB->mb_type)
  {
  case I4MB:
    return writeIntra4x4Modes(currSlice, currMB);
    break;
  case I8MB:
    return writeIntra8x8Modes(currSlice, currMB);
    break;
  default:
    return 0;
    break;
  }
}

/*!
 ************************************************************************
 * \brief
 *    Converts 8x8 block type to coding value
 ************************************************************************
 */
int B8Mode2Value (short b8mode, short 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};

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


static int writeIPCMLuma (ImageParameters *img, imgpel **imgY, Bitstream *currStream, SyntaxElement *se, int *bitCount)
{
  int i, j;
  int bit_size = MB_BLOCK_SIZE * MB_BLOCK_SIZE * img->bitdepth_luma;
  bitCount[BITS_COEFF_Y_MB] += bit_size;
  se->len   = img->bitdepth_luma;
  se->type  = SE_MBTYPE;   

  for (j = img->pix_y; j < img->pix_y + MB_BLOCK_SIZE; j++)
  {      
    for (i = img->pix_x; i < img->pix_x + MB_BLOCK_SIZE; i++)
    {            
      se->bitpattern = imax(img->min_IPCM_value, imgY[j][i]);
      se->value1 = se->bitpattern;      
#if TRACE
      snprintf(se->tracestring, TRACESTRING_SIZE, "pcm_sample_luma (%d %d) = %d", j, i, se->bitpattern);
#endif
      writeSE_Fix(se, currStream);
    }
  }
  return bit_size;
}

static int writeIPCMChroma (ImageParameters *img, imgpel **imgUV, Bitstream *currStream, SyntaxElement *se, int *bitCount)
{
  int i, j;
  int bit_size = img->mb_cr_size_y * img->mb_cr_size_x * img->bitdepth_luma;
  bitCount[BITS_COEFF_UV_MB] += bit_size;
  se->len   = img->bitdepth_chroma;
  se->type  = SE_MBTYPE;

  for (j = img->pix_c_y; j < img->pix_c_y + img->mb_cr_size_y; j++)
  {
    for (i = img->pix_c_x; i < img->pix_c_x + img->mb_cr_size_x; i++)
    {
      se->bitpattern = imax(img->min_IPCM_value, imgUV[j][i]);
      se->value1 = se->bitpattern;
#if TRACE
      //snprintf(se.tracestring, TRACESTRING_SIZE, "pcm_sample_chroma (%s) (%d %d) = %d", uv?"v":"u", j,i,se->bitpattern);
      snprintf(se->tracestring, TRACESTRING_SIZE, "pcm_sample_chroma (%d %d) = %d", j, i, se->bitpattern);
#endif
      writeSE_Fix(se, currStream);
    }
  }
  return bit_size;
}

static int writeIPCMByteAlign(Bitstream *currStream, SyntaxElement *se, int *bitCount)
{
  if (currStream->bits_to_go < 8)
  {
    // This will only happen in the CAVLC case, CABAC is already padded
    se->type  = SE_MBTYPE;
    se->len   = currStream->bits_to_go;      
    bitCount[BITS_COEFF_Y_MB]+= se->len;
    se->bitpattern = 0;
#if TRACE
    snprintf(se->tracestring, TRACESTRING_SIZE, "pcm_alignment_zero_bits = %d", se->len);
#endif
    writeSE_Fix(se, currStream);

    return se->len;
  }
  else 
    return 0;
}

/*!
************************************************************************
* \brief
*    Codes macroblock header
* \param currSlice
*    current slice
* \param currMB
*    current macroblock
* \param rdopt
*    true for calls during RD-optimization
* \param coeff_rate
*    bitrate of Luma and Chroma coeff
************************************************************************
*/
int writeMBLayer (Slice* currSlice, Macroblock *currMB, int rdopt, int *coeff_rate)
{
  int             i;
  int             mb_nr      = currMB->mb_nr;
  int             prev_mb_nr = FmoGetPreviousMBNr(img->current_mb_nr);
  Macroblock     *prevMB     = currMB->PrevMB; 
  SyntaxElement   se;
  int*            bitCount   = currMB->bitcounter;
  DataPartition*  dataPart;
  const int*      partMap    = assignSE2partition[params->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 ((mb_nr & 0x01) == 0)
    {
      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[prev_mb_nr];
      prevMbSkipped = topMB->skip_flag;
    }
  }
  currMB->IntraChromaPredModeFlag = IS_INTRA(currMB);

  // choose the appropriate data partition
  dataPart = &(currSlice->partArr[partMap[SE_MBTYPE]]);

  if(img->type == I_SLICE)
  {
    //========= write mb_aff (I_SLICE) =========
    if(WriteFrameFieldMBInHeader)
    {
      se.value1 = currMB->mb_field;
      se.value2 = 0;
      se.type   = SE_MBTYPE;

      TRACE_SE (se.tracestring, "mb_field_decoding_flag");
      writeFieldModeInfo(&se, dataPart);

      bitCount[BITS_MB_MODE] += se.len;
      no_bits                += se.len;
    }

    //========= write mb_type (I_SLICE) =========
    se.value1  = MBType2Value (currMB);
    se.value2  = 0;
    se.type    = SE_MBTYPE;

#if TRACE
    snprintf(se.tracestring, TRACESTRING_SIZE,   "mb_type (I_SLICE) (%2d,%2d) = %3d",img->mb_x, img->mb_y, currMB->mb_type);
#endif

    writeMB_typeInfo (&se, dataPart);

    bitCount[BITS_MB_MODE] += se.len;
    no_bits                += se.len;
  }  // not I_SLICE, CABAC
  else if (currSlice->symbol_mode == CABAC)
  {
    if (img->MbaffFrameFlag && ((img->current_mb_nr & 0x01) == 0 || prevMbSkipped))
    {
      mb_field_tmp = currMB->mb_field;
      currMB->mb_field = field_flag_inference(currMB);
      CheckAvailabilityOfNeighborsCABAC(currMB);
      currMB->mb_field = mb_field_tmp;
    }

    //========= write mb_skip_flag (CABAC) =========
    mb_type    = MBType2Value (currMB);
    se.value1  = mb_type;
    se.value2  = currMB->cbp;
    se.type    = SE_MBTYPE;

    TRACE_SE (se.tracestring, "mb_skip_flag");
    writeMB_skip_flagInfo_CABAC(currMB, &se, dataPart);

    bitCount[BITS_MB_MODE] += se.len;
    no_bits                += se.len;

    CheckAvailabilityOfNeighborsCABAC(currMB);

    //========= write mb_aff (CABAC) =========
    if(img->MbaffFrameFlag && !skip) // check for copy mode
    {
      if(WriteFrameFieldMBInHeader)
      {
        se.value1 = currMB->mb_field;
        se.value2 = 0;
        se.type   =  SE_MBTYPE;

        TRACE_SE(se.tracestring, "mb_field_decoding_flag");
        writeFieldModeInfo(&se, dataPart);

        bitCount[BITS_MB_MODE] += se.len;
        no_bits                += se.len;
      }
    }

    //========= write mb_type (CABAC) =========
    if (currMB->mb_type != 0 || ((img->type == B_SLICE) && (currMB->cbp != 0 || cmp_cbp[1] !=0 || cmp_cbp[2]!=0 )))
    {
      se.value1  = mb_type;
      se.value2  = 0;
      se.type    = SE_MBTYPE;

#if TRACE
      if (img->type == B_SLICE)
        snprintf(se.tracestring, TRACESTRING_SIZE, "mb_type (B_SLICE) (%2d,%2d) = %3d",img->mb_x, img->mb_y, currMB->mb_type);
      else
        snprintf(se.tracestring, TRACESTRING_SIZE, "mb_type (P_SLICE) (%2d,%2d) = %3d",img->mb_x, img->mb_y, currMB->mb_type);
#endif
      writeMB_typeInfo( &se, dataPart);

      bitCount[BITS_MB_MODE] += se.len;
      no_bits                += se.len;
    }
  }
  // VLC not intra
  else if (currMB->mb_type != 0 || ((img->type == B_SLICE) && (currMB->cbp != 0 || cmp_cbp[1] != 0 || cmp_cbp[2]!=0 )))
  {
    //===== Run Length Coding: Non-Skipped macroblock =====
    se.value1  = img->cod_counter;
    se.value2  = 0;
    se.type    = SE_MBTYPE;

    TRACE_SE (se.tracestring, "mb_skip_run");
    writeSE_UVLC(&se, dataPart);

    bitCount[BITS_MB_MODE] += se.len;
    no_bits                += se.len;

    // Reset cod counter
    img->cod_counter = 0;

    // write mb_aff
    if(img->MbaffFrameFlag && !skip) // check for copy mode
    {
      if(WriteFrameFieldMBInHeader)
      {
        se.value1 = currMB->mb_field;
        se.type   =  SE_MBTYPE;

        TRACE_SE(se.tracestring, "mb_field_decoding_flag");
        writeSE_Flag (&se, dataPart);

        bitCount[BITS_MB_MODE] += se.len;
        no_bits                += se.len;
      }
    }
    // Put out mb mode
    se.value1  = MBType2Value (currMB);

    if (img->type != B_SLICE)
    {
      se.value1--;
    }
    se.type    = SE_MBTYPE;
    se.value2  = 0;

#if TRACE
    if (img->type == B_SLICE)
      snprintf(se.tracestring, TRACESTRING_SIZE, "mb_type (B_SLICE) (%2d,%2d) = %3d",img->mb_x, img->mb_y, currMB->mb_type);
    else
      snprintf(se.tracestring, TRACESTRING_SIZE, "mb_type (P_SLICE) (%2d,%2d) = %3d",img->mb_x, img->mb_y, currMB->mb_type);
#endif

    writeMB_typeInfo(&se, dataPart);

    bitCount[BITS_MB_MODE] += se.len;
    no_bits                += se.len;
  }
  else
  {
    //Run Length Coding: Skipped macroblock
    img->cod_counter++;

    currMB->skip_flag = 1;
    // CAVLC
    reset_mb_nz_coeff(img->current_mb_nr);

    if(FmoGetNextMBNr(img->current_mb_nr) == -1 && img->cod_counter > 0)
    {
      // Put out run
      se.value1  = img->cod_counter;
      se.value2  = 0;
      se.type    = SE_MBTYPE;

      TRACE_SE(se.tracestring, "mb_skip_run");
      writeSE_UVLC(&se, dataPart);

      bitCount[BITS_MB_MODE] += se.len;
      no_bits                += se.len;

      // Reset cod counter
      img->cod_counter = 0;
    }
  }

  //init NoMbPartLessThan8x8Flag
  currMB->NoMbPartLessThan8x8Flag = (IS_DIRECT(currMB) && !(active_sps->direct_8x8_inference_flag))? 0: 1;

  if (currMB->mb_type == IPCM)
  {
    dataPart = &(currSlice->partArr[partMap[SE_LUM_DC_INTRA]]);
    if (currSlice->symbol_mode == CABAC)
    {
      int len;
      EncodingEnvironmentPtr eep = &dataPart->ee_cabac;
      len = arienco_bits_written(eep);
      arienco_done_encoding(eep); // This pads to byte
      len = arienco_bits_written(eep) - len;
      no_bits += len;
      // Now restart the encoder
      arienco_start_encoding(eep, dataPart->bitstream->streamBuffer, &(dataPart->bitstream->byte_pos));
    }

    writeIPCMByteAlign(dataPart->bitstream, &se, bitCount);

    no_bits += writeIPCMLuma (img, enc_picture->imgY, dataPart->bitstream, &se, bitCount);

    if ((active_sps->chroma_format_idc != YUV400) && !IS_INDEPENDENT(params))
    {
      int uv;
      for (uv = 0; uv < 2; uv ++)
      {
        no_bits += writeIPCMChroma (img, enc_picture->imgUV[uv], dataPart->bit

⌨️ 快捷键说明

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