📄 umc_dv_enc_encode_bit_stream.cpp
字号:
/*
// INTEL CORPORATION PROPRIETARY INFORMATION
// This software is supplied under the terms of a license agreement or
// nondisclosure agreement with Intel Corporation and may not be copied
// or disclosed except in accordance with the terms of that agreement.
// Copyright (c) 2006-2007 Intel Corporation. All Rights Reserved.
//
*/
#include "umc_defs.h"
#if defined (UMC_ENABLE_DV_VIDEO_ENCODER)
#include "umc_dv_enc_compressor_def.h"
#include "umc_dv_enc_encode_bit_stream.h"
#include "umc_dv_enc_huffman.h"
#include "umc_dv_enc_block.h"
#include "umc_dv_enc_segment_compressor.h"
namespace UMC
{
#define ELEMENTh(run, cod, dl) (cod<< 16) | dl
#define ELEMENThEnd(run, cod, dl) ((cod + run)<< 16) | dl
static Ipp32u EncodeTablesIntern[64] = {0, ELEMENTh(0, 0x07ce, 11),
ELEMENTh(1, 0x07cf, 11), ELEMENTh(2, 0x0fac, 12), ELEMENTh(3, 0x0fad, 12),
ELEMENTh(4, 0x0fae, 12), ELEMENTh(5, 0x0faf, 12), ELEMENTh(6, 0x1f86, 13),
ELEMENThEnd(7, 0x1f80, 13), ELEMENThEnd(8, 0x1f80, 13), ELEMENThEnd(9, 0x1f80, 13),
ELEMENThEnd(10, 0x1f80, 13), ELEMENThEnd(11, 0x1f80, 13), ELEMENThEnd(12, 0x1f80, 13),
ELEMENThEnd(13, 0x1f80, 13), ELEMENThEnd(14, 0x1f80, 13), ELEMENThEnd(15, 0x1f80, 13),
ELEMENThEnd(16, 0x1f80, 13), ELEMENThEnd(17, 0x1f80, 13), ELEMENThEnd(18, 0x1f80, 13),
ELEMENThEnd(19, 0x1f80, 13), ELEMENThEnd(20, 0x1f80, 13), ELEMENThEnd(21, 0x1f80, 13),
ELEMENThEnd(22, 0x1f80, 13), ELEMENThEnd(23, 0x1f80, 13), ELEMENThEnd(24, 0x1f80, 13),
ELEMENThEnd(25, 0x1f80, 13), ELEMENThEnd(26, 0x1f80, 13), ELEMENThEnd(27, 0x1f80, 13),
ELEMENThEnd(28, 0x1f80, 13), ELEMENThEnd(29, 0x1f80, 13), ELEMENThEnd(30, 0x1f80, 13),
ELEMENThEnd(31, 0x1f80, 13), ELEMENThEnd(32, 0x1f80, 13), ELEMENThEnd(33, 0x1f80, 13),
ELEMENThEnd(34, 0x1f80, 13), ELEMENThEnd(35, 0x1f80, 13),/////////////////////////////////, ELEMENThEnd(36, 0x1f80, 13),
ELEMENThEnd(36, 0x1f80, 13), ELEMENThEnd(37, 0x1f80, 13), ELEMENThEnd(38, 0x1f80, 13),
ELEMENThEnd(39, 0x1f80, 13), ELEMENThEnd(40, 0x1f80, 13), ELEMENThEnd(41, 0x1f80, 13),
ELEMENThEnd(42, 0x1f80, 13), ELEMENThEnd(43, 0x1f80, 13), ELEMENThEnd(44, 0x1f80, 13),
ELEMENThEnd(45, 0x1f80, 13), ELEMENThEnd(46, 0x1f80, 13), ELEMENThEnd(47, 0x1f80, 13),
ELEMENThEnd(48, 0x1f80, 13), ELEMENThEnd(49, 0x1f80, 13), ELEMENThEnd(50, 0x1f80, 13),
ELEMENThEnd(51, 0x1f80, 13), ELEMENThEnd(52, 0x1f80, 13),////////////////////////////////, ELEMENThEnd(53, 0x1f80, 13),
ELEMENThEnd(53, 0x1f80, 13), ELEMENThEnd(54, 0x1f80, 13), ELEMENThEnd(55, 0x1f80, 13),
ELEMENThEnd(56, 0x1f80, 13), ELEMENThEnd(57, 0x1f80, 13), ELEMENThEnd(58, 0x1f80, 13),
ELEMENThEnd(59, 0x1f80, 13), ELEMENThEnd(60, 0x1f80, 13), ELEMENThEnd(61, 0x1f80, 13),
ELEMENThEnd(62, 0x1f80, 13)
};
static Ipp32s LastElemenInAreaNum[] ={ 6<<8, 21<<8, 43<<8, 64<<8 };
void SegmentCompressor::QuantizeBlock(BLOCK *lpBlock, Ipp32u qno)
{
Ipp32u QuantStep;
Ipp32s curr_elem, run_len, quantized_amp, area_num, last_elem_in_area, signX;
Ipp32u *lpsSrc = lpBlock->m_lpsDataRL;
Ipp32u *lpsDest = lpBlock->m_lpsDataRL + 1;
QuantStep = TABLE_QS[qno * 4 + lpBlock->m_cC1C0].qu_step | 0x10101010;
// first element is never quantized
curr_elem = *(++lpsSrc);
run_len = 0;
for(area_num = 0; area_num < 4; area_num++)
{
last_elem_in_area = LastElemenInAreaNum[area_num];
while( (curr_elem & 0x7f00) < last_elem_in_area)
{
run_len += (curr_elem & 0xff);
quantized_amp = (curr_elem >> (QuantStep & 0xff));
if(quantized_amp != 0)
{
signX = (curr_elem & 0x8000) << 1;
// code as single element
if (quantized_amp <= TableMaxAmpOnRun[run_len])
*lpsDest++ = ((EncodeTables[run_len][quantized_amp]).code << 16) | signX | ((EncodeTables[run_len][quantized_amp]).length);
else // code as 2 element
*lpsDest++ = ((EncodeTables[0][quantized_amp]).code << 16) | signX | ((EncodeTables[0][quantized_amp]).length) | (run_len << 8);
run_len = 0;
}
else run_len++;
curr_elem = *(++lpsSrc);
}
QuantStep >>=8;
}
*lpsDest = 0x4000;
}
Ipp32s GetEncodedBlockSize(BLOCK *lpBlock, Ipp32u qno)
{
Ipp32u QuantStep;
Ipp32s EncodedBlockSize = 16;// DC + m0 + c1c0 + eob
Ipp32s curr_elem, run_len, quantized_amp, area_num, last_elem_in_area;
Ipp32u *lpsSrc = lpBlock->m_lpsDataRL;
QuantStep = TABLE_QS[qno * 4 + lpBlock->m_cC1C0].qu_step | 0x10101010;
// first element is never prequantized
curr_elem = *(++lpsSrc);
run_len = 0;
for(area_num = 0; area_num < 4; area_num++)
{
last_elem_in_area = LastElemenInAreaNum[area_num];
while( (curr_elem & 0x7f00) < last_elem_in_area)
{
run_len += (curr_elem & 0xff);
quantized_amp = (curr_elem >> (QuantStep & 0xff));
if(quantized_amp != 0)
{
// code as single element
if (quantized_amp <= TableMaxAmpOnRun[run_len])
EncodedBlockSize += (EncodeTables[run_len][quantized_amp]).length;
else // code as 2 element
{
EncodedBlockSize += (EncodeTables[run_len - 1][0x00]).length;
EncodedBlockSize += (EncodeTables[0x00][quantized_amp]).length;
}
run_len = 0;
}
else run_len++;
curr_elem = *(++lpsSrc);
}
QuantStep >>=8;
}
return EncodedBlockSize;
}
//inline
Ipp32u ByteSwap(Ipp32u i)
{
//return ((i << 24) | ((i & 0x0000ff00) << 8) | ((i & 0x00ff0000) >> 8) | (i >> 24));
//Ipp32u testVal = ((i << 24) | ((i & 0x0000ff00) << 8) | ((i & 0x00ff0000) >> 8) | (i >> 24));
Ipp8u *tempByte =(Ipp8u *) &i;
Ipp8u temp = tempByte[0];
tempByte[0] = tempByte[3];
tempByte[3] = temp;
temp = tempByte[1];
tempByte[1] = tempByte[2];
tempByte[2] = temp;
return i;
} // Ipp32u ByteSwap(Ipp32u i)
Ipp32u ByteSwap(Ipp8u *currPointer)
{
Ipp32u byteSwapValue;
Ipp8u *tempByte =(Ipp8u *) &byteSwapValue;
tempByte[0] = currPointer[3];
tempByte[1] = currPointer[2];
tempByte[2] = currPointer[1];
tempByte[3] = currPointer[0];
return byteSwapValue;
} // Ipp32u ByteSwap(Ipp32u i)
Ipp32s EncodeBitStream(ENCODE_BIT_STREAM *lpStream, BLOCK *lpBlock)
{
Ipp64u Reg = 0;
Ipp32s iFreeBits = 64 - 9 - 3;//free bits in register. Total 64 bits, 12 already used for DC, m1, c1,c0
Ipp32s iSize = 0 + 9 + 3;// 9 bits for DC, 3 bits for c1 c0 and m0
Ipp32s temp;
Ipp32u *lpsSrc = lpBlock->m_lpsDataRL;
Ipp32s *lpiDst = (Ipp32s *) lpStream->m_lpcDest;
Ipp32s iToReturn;
#ifdef _DEBUG
memset(lpiDst, 0, 128);
#endif //_DEBUG
// encode DC
Reg = ((Ipp64u) (lpsSrc[0] & 0x01ff)) << (64 - 9);
// encode m0 & c1c0
Reg |= ((Ipp64u) ((lpBlock->m_cM0 << 2) | (lpBlock->m_cC1C0))) << (64 - 9 - 3);
temp = *(++lpsSrc);
while (!(temp & 0x4000))
{
Ipp32s code_len;
code_len = temp & 0xff;
// temp1 += (temp & 0xff);
if (!(temp & 0xff00))
{// code as single element
iSize += code_len;
iFreeBits -= code_len;
Reg |= ((Ipp64u) (temp & 0xffff0000)) << (iFreeBits - 16);
}
else // code as 2 element
{
Ipp32u RunXAmp0 = (Ipp32u)EncodeTablesIntern[(temp & 0x7f00) >> 8];
Reg |= (( (Ipp64u) ( (RunXAmp0 & 0xffff0000) | ((temp & 0xffff0000) >> code_len) ) )
<< (iFreeBits - 16 - (RunXAmp0 & 0xffff)) );
code_len += (RunXAmp0 & 0xffff);
iSize += code_len;
iFreeBits -= code_len;
}
if (iFreeBits < 32)
{
iFreeBits += 32;
*lpiDst = ByteSwap((Ipp32s) (Reg >> 32));
lpiDst++;
Reg <<= 32;
}
temp = *(++lpsSrc);
}
// set eob
iSize += 4;
iFreeBits -= 4;
Reg |= ((Ipp64s) (0x06)) << iFreeBits;
if (iFreeBits < 32)
{
iFreeBits += 32;
*lpiDst = ByteSwap((Ipp32s) (Reg >> 32));
lpiDst++;
Reg <<= 32;
}
*lpiDst = ByteSwap((Ipp32s) (Reg >> 32));
if (iSize < lpStream->m_bBitsCanTake)
{
lpStream->m_lpcDest = (Ipp8u *) lpiDst;
lpStream->m_bFreeBits = iFreeBits;
lpStream->m_bBitsCanTake -= iSize;
lpStream->m_wExtraBits = 0;
lpStream->m_dwRegister = ((Ipp32s) (Reg >> 32));
iToReturn = STREAM_NOT_FULL;
}
else if (iSize > lpStream->m_bBitsCanTake)
{
lpStream->m_lpcDest += lpStream->m_bBitsCanTake / 8;
lpStream->m_bFreeBits = 64;
lpStream->m_wExtraBits = iSize - lpStream->m_bBitsCanTake;
lpStream->m_bBitsCanTake = 0;
lpStream->m_dwRegister = 0;
iToReturn = STREAM_OVER;
}
else // if (iSize == m_bBitsCanTake)
{
iToReturn = STREAM_FULL;
}
return iToReturn;
} // Ipp32s EncodeBitStream(ENCODE_BIT_STREAM *lpStream, BLOCK *lpBlock)
Ipp32s AddBits(ENCODE_BIT_STREAM *lpStreamDst, ENCODE_BIT_STREAM *lpStreamSrc)
{
Ipp64u RegIn, RegOut;
Ipp32s iFreeIn, iFreeOut;
Ipp32s iToReturn;
Ipp32s iBits;
RegIn = ((Ipp64u) lpStreamSrc->m_dwRegister) << 32;
RegOut = ((Ipp64u) lpStreamDst->m_dwRegister) << 32;
iFreeIn = lpStreamSrc->m_bFreeBits;
iFreeOut = lpStreamDst->m_bFreeBits;
if (lpStreamDst->m_bBitsCanTake > lpStreamSrc->m_wExtraBits)
{
iBits = lpStreamSrc->m_wExtraBits;
iToReturn = STREAM_NOT_FULL;
lpStreamDst->m_bBitsCanTake -= lpStreamSrc->m_wExtraBits;
}
else // if(m_bBitsCanTake <= lpStream->m_wExtraBits)
{
iBits = lpStreamDst->m_bBitsCanTake;
iToReturn = STREAM_FULL;
lpStreamSrc->m_wExtraBits -= lpStreamDst->m_bBitsCanTake;
}
while (iBits >= 32)
{
//Ipp32s temp
//RegIn |= ((Ipp64u) ByteSwap(*((Ipp32s *) lpStreamSrc->m_lpcDest))) << (iFreeIn - 32);
RegIn |= ((Ipp64u) ByteSwap( lpStreamSrc->m_lpcDest)) << (iFreeIn - 32);
RegOut |= RegIn >> (64 - iFreeOut);
lpStreamSrc->m_lpcDest += 4;
RegIn <<= 32;
*((Ipp32s *) lpStreamDst->m_lpcDest) = ByteSwap((Ipp32s) (RegOut >> 32));
RegOut <<= 32;
lpStreamDst->m_lpcDest += 4;
iBits -= 32;
}
//RegIn |= ((Ipp64u) ByteSwap(*((Ipp32s *) lpStreamSrc->m_lpcDest))) << (iFreeIn - 32);
RegIn |= ((Ipp64u) ByteSwap( lpStreamSrc->m_lpcDest)) << (iFreeIn - 32);
RegOut |= RegIn >> (64 - iFreeOut);
lpStreamSrc->m_lpcDest += 4;
iFreeIn -= (32 - iBits);
RegIn <<= iBits;
iFreeOut -= iBits;
RegOut &= ( (Ipp64s(-1)) << iFreeOut);
if (iFreeOut < 32)
{
iFreeOut += 32;
*((Ipp32s *) lpStreamDst->m_lpcDest) = ByteSwap((Ipp32s) (RegOut >> 32));
lpStreamDst->m_lpcDest += 4;
RegOut <<= 32;
}
if (iFreeIn < 32)
{
iFreeIn += 32;
lpStreamSrc->m_lpcDest -= 4;
}
// store data
lpStreamSrc->m_dwRegister = (Ipp32s) (RegIn >> 32);
lpStreamSrc->m_bFreeBits = iFreeIn;
lpStreamDst->m_dwRegister = (Ipp32s) (RegOut >> 32);
lpStreamDst->m_bFreeBits = iFreeOut;
// flash down
*((Ipp32s *) lpStreamDst->m_lpcDest) = ByteSwap((Ipp32s) (RegOut >> 32));
return iToReturn;
} // Ipp32s AddBits(ENCODE_BIT_STREAM *lpStreamDst, ENCODE_BIT_STREAM *lpStreamSrc)
}//namespace UMC
#endif //(UMC_ENABLE_DV_VIDEO_ENCODER)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -