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

📄 umc_mpeg2_enc_put.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 4 页
字号:
  chroma_420_type = (encodeInfo.info.color_format == YUV420 &&
                     encodeInfo.info.interlace_type == PROGRESSIVE) ? 1 : 0;
  PUT_BITS(chroma_420_type, 1);       // chroma_420_type
  PUT_BITS((encodeInfo.info.interlace_type == PROGRESSIVE ? 1 : 0), 1);  // progressive_frame
  PUT_BITS(0, 1);                     // composite_display_flag
  // composite display information not implemented yet
}

// generate sequence_end_code (6.2.2)
void MPEG2VideoEncoderBase::PutSequenceEnd()
{
  PUT_START_CODE(SEQ_END_CODE);
}

// slice header (6.2.4)
void MPEG2VideoEncoderBase::PutSliceHeader(Ipp32s RowNumber, Ipp32s numTh)
{
  if( encodeInfo.info.clip_info.height <= 2800 )
  {
    PUT_START_CODE_TH(numTh, SLICE_MIN_START + RowNumber); // slice_start_code
  }
  else
  {
    PUT_START_CODE_TH(numTh, SLICE_MIN_START + (RowNumber & 127)); // slice_start_code
    PUT_BITS_TH(RowNumber >> 7, 3); // slice_vertical_position_extension
  }

  PUT_BITS_TH((quantiser_scale_code<<1), (5+1)); // + extra_bit_slice
}

// put variable length code for macroblock_address_increment (6.3.17)
void MPEG2VideoEncoderBase::PutAddrIncrement(Ipp32s increment, Ipp32s numTh )
{
  while( increment > 33 )
  {
    PUT_BITS_TH(0x08, 11); // put macroblock_escape
    increment -= 33;
  }

  PUT_BITS_TH(AddrIncrementTbl[increment].code, AddrIncrementTbl[increment].len);
}

void MPEG2VideoEncoderBase::PutMV(Ipp32s delta, Ipp32s f_code, Ipp32s numTh)
{
  Ipp32s f, r_size, low, high, range , temp, motion_code, motion_residual;
  Ipp32s tpos; // LUT position

  r_size = f_code - 1;
  f = 1<<r_size;

  low   = -16*f;
  high  = 16*f - 1;
  range = 32*f;

  /* fold vector difference into [vmin...vmax] */
  if(delta > high)     delta -= range;
  else if(delta < low) delta += range;

  /* check value */
  mpeg2_assert(delta >= low);
  mpeg2_assert(delta <= high);

  if(f == 1 || delta == 0)
  {
    PUT_BITS_TH(MV_VLC_Tbl[16 + delta].code, MV_VLC_Tbl[16 + delta].len);
    return;
  }

  // present delta as motion_code and motion_residual
  if( delta < 0 )
  {
    temp = -delta + f - 1;
    motion_code = temp >> r_size;
    tpos = 16 - motion_code;
  }
  else // delta > 0
  {
    temp = delta + f - 1;
    motion_code = temp >> r_size;
    tpos = 16 + motion_code;
  }
  mpeg2_assert(motion_code > 0 && motion_code <= 16);
  // put variable length code for motion_code (6.3.16.3)
  // put fixed length code for motion_residual
  motion_residual = (MV_VLC_Tbl[tpos].code << r_size) + (temp & (f - 1));
  r_size += MV_VLC_Tbl[tpos].len;

  PUT_BITS_TH(motion_residual, r_size);
}

/* generate variable length code for other DCT coefficients (7.2.2)*/
static void mp2PutAC(Ipp32u **pBitStream,
                     Ipp32s *pOffset,
                     Ipp32s run,
                     Ipp32s signed_level,
                     IppVCHuffmanSpec_32s *ptab)
{
    Ipp32s level, code, len;
    Ipp32s maxRun = ptab[0] >> 20;
    Ipp32s addr;
    Ipp32s * table;
    Ipp32u val;

  if(run > maxRun)
  {
    /* no VLC for this (run, level) combination: use escape coding (7.2.2.3)*/
    /* ISO/IEC 13818-2 uses a 12 bit code, Table B-16*/
    signed_level &= (1 << 12) - 1;
    val = signed_level + (run<<12) + (1<<18);
    ippiPutBits(*pBitStream, *pOffset, val, 24 )
    return;
  }

  level = (signed_level < 0) ? -signed_level : signed_level;

  addr = ptab[run + 1];
  table = (Ipp32s*)((Ipp8s*)ptab + addr);
  if(level <= table[0])
  {
    len  = *(table + signed_level) & 0x1f;
    code = (*(table + signed_level) >> 16);
    ippiPutBits(*pBitStream, *pOffset,  code, len )
  }
  else
  {
    /* no VLC for this (run, level) combination: use escape coding (7.2.2.3)*/
    /* ISO/IEC 13818-2 uses a 12 bit code, Table B-16*/
    signed_level &= (1 << 12) - 1;
    val = signed_level + (run<<12) + (1<<18);
    ippiPutBits(*pBitStream, *pOffset, val, 24 )
  }
}

static Status mp2PutIntraBlock(Ipp32u **pBitStream,
                                  Ipp32s *pOffset,
                                  Ipp16s *block,
                                  Ipp32s *dc_dct_pred,
                                  IppVCHuffmanSpec_32u* DC_Tbl,
                                  IppVCHuffmanSpec_32s* AC_Tbl,
                                  Ipp32s *scan,
                                  Ipp32s EOBLen,
                                  Ipp32s EOBCode,
                                  Ipp32s count)
{
  Ipp32s n, m, dct_diff, run, signed_level;
  Ipp32s absval, size1;

  dct_diff = block[0] - *dc_dct_pred;
  *dc_dct_pred = block[0];

  /* generate variable length code for DC coefficient (7.2.1)*/
  if(dct_diff == 0) {
    ippiPutBits(*pBitStream, *pOffset, DC_Tbl[0].code, DC_Tbl[0].len )
  } else {
    m = dct_diff >> 31;
    absval = (dct_diff + m) ^ m;
    for (size1=1; absval >>= 1; size1++);

    /* generate VLC for dct_dc_size (Table B-12 or B-13)*/
    /* append fixed length code (dc_dct_differential)*/
    absval = ((DC_Tbl[size1].code - m) << size1) + (dct_diff + m);
    n  = DC_Tbl[size1].len + size1;
    ippiPutBits(*pBitStream, *pOffset,  absval, n )
  }

  run = 0;
  m = 0;

  for(n=1; m < count ; n++)
  {
    signed_level = block[scan[n]];
    if( signed_level )
    {
      mp2PutAC(pBitStream, pOffset, run, signed_level, AC_Tbl);
      m++;
      run = 0;
    }
    else
      run++;
  }
  ippiPutBits(*pBitStream, *pOffset, EOBCode, EOBLen )

  return UMC_OK;
}

static Status mp2PutNonIntraBlock(Ipp32u **pBitStream,
                                     Ipp32s *pOffset,
                                     Ipp16s *block,
                                     IppVCHuffmanSpec_32s *AC_Tbl,
                                     Ipp32s *scan,
                                     Ipp32s EOBLen,
                                     Ipp32s EOBCode,
                                     Ipp32s count)
{
  Ipp32s n, m, run, signed_level;

  run = 0;
  m = 0;

  signed_level = block[0];
  if( signed_level)
  {
    if (signed_level == 1 || signed_level == -1) {
      //Ipp32s tmp = (signed_level == 1) ? 2 : 3;
      Ipp32s tmp = 2 + (signed_level==-1);
      ippiPutBits(*pBitStream, *pOffset, tmp, 2 )
    } else {
      mp2PutAC(pBitStream, pOffset, 0, signed_level, AC_Tbl);
    }
    m++;
  }
  else run++;

  for(n=1; m < count ; n++)
  {
    signed_level = block[scan[n]];

    if( signed_level )
    {
      mp2PutAC(pBitStream, pOffset, run, signed_level, AC_Tbl);
      m++;
      run = 0;
    }
    else
      run++;
  }

  ippiPutBits(*pBitStream, *pOffset, EOBCode, EOBLen )// End of Block

  return UMC_OK;
}

void MPEG2VideoEncoderBase::PutIntraBlock(Ipp16s* block, Ipp32s* dc_dct_pred, const IppVCHuffmanSpec_32u* DC_Tbl,Ipp32s count, Ipp32s numTh)
{
  Ipp32s EOBLen, EOBCode;
  IppVCHuffmanSpec_32s* AC_Tbl;
  Ipp32s *scan = curr_scan ? AlternateScan : ZigZagScan;

  CHECK_BUFFER;

  if (curr_intra_vlc_format) {
    EOBCode = 6;
    EOBLen  = 4; // (Table B-15)
    AC_Tbl = vlcTableB15;
  } else {
    EOBCode = 2;
    EOBLen  = 2; // (Table B-14)
    AC_Tbl = vlcTableB5c_e;
  }

  mp2PutIntraBlock(&threadSpec[numTh].bBuf.current_pointer, &threadSpec[numTh].bBuf.bit_offset,
                   block, dc_dct_pred, (IppVCHuffmanSpec_32u*)DC_Tbl, AC_Tbl, scan, EOBLen, EOBCode, count);

  CHECK_BUFFER;
}

void MPEG2VideoEncoderBase::PutNonIntraBlock(Ipp16s* block, Ipp32s count, Ipp32s numTh)
{
  Ipp32s *scan = curr_scan ? AlternateScan : ZigZagScan;

  CHECK_BUFFER;

  mp2PutNonIntraBlock(&threadSpec[numTh].bBuf.current_pointer, &threadSpec[numTh].bBuf.bit_offset,
                      block, vlcTableB5c_e, scan, 2, 2, count);

  CHECK_BUFFER;
}

void MPEG2VideoEncoderBase::PutIntraMacroBlock(Ipp32s numTh, Ipp32s k, const Ipp8u *BlockSrc[3], Ipp8u *BlockRec[3], Ipp32s *dc_dct_pred)
{
  IppiSize roi = {8, 8};
  Ipp16s *pMBlock = threadSpec[numTh].pMBlock;
  Ipp32s Count[12];
  Ipp32s stride[3];

⌨️ 快捷键说明

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