📄 umc_mpeg2_enc_put.cpp
字号:
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 + -