// texture
/** encode coefficients
* \param pcCU
* \param uiAbsPartIdx
* \param uiDepth
* \param uiWidth
* \param uiHeight
*/
Void TEncEntropy::encodeCoeff( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth, UInt uiWidth, UInt uiHeight, Bool& bCodeDQP )
{
UInt uiMinCoeffSize = pcCU->getPic()->getMinCUWidth()*pcCU->getPic()->getMinCUHeight();
UInt uiLumaOffset = uiMinCoeffSize*uiAbsPartIdx;
UInt uiChromaOffset = uiLumaOffset>>2;
if( pcCU->isIntra(uiAbsPartIdx) )
{
DTRACE_CABAC_VL( g_nSymbolCounter++ )
DTRACE_CABAC_T( "\tdecodeTransformIdx()\tCUDepth=" )
DTRACE_CABAC_V( uiDepth )
DTRACE_CABAC_T( "\n" )
}
else
{
if( !(pcCU->getMergeFlag( uiAbsPartIdx ) && pcCU->getPartitionSize(uiAbsPartIdx) == SIZE_2Nx2N ) )
{
m_pcEntropyCoderIf->codeQtRootCbf( pcCU, uiAbsPartIdx );
}
if ( !pcCU->getQtRootCbf( uiAbsPartIdx ) )
{
return;
}
}
xEncodeTransform( pcCU, uiLumaOffset, uiChromaOffset, uiAbsPartIdx, uiDepth, uiWidth, uiHeight, 0, bCodeDQP);
}
Void TEncEntropy::xEncodeTransform( TComDataCU* pcCU,UInt offsetLuma, UInt offsetChroma, UInt uiAbsPartIdx, UInt uiDepth, UInt width, UInt height, UInt uiTrIdx, Bool& bCodeDQP )
{
const UInt uiSubdiv = pcCU->getTransformIdx( uiAbsPartIdx ) + pcCU->getDepth( uiAbsPartIdx ) > uiDepth;
const UInt uiLog2TrafoSize = g_aucConvertToBit[pcCU->getSlice()->getSPS()->getMaxCUWidth()]+2 - uiDepth;
UInt cbfY = pcCU->getCbf( uiAbsPartIdx, TEXT_LUMA , uiTrIdx );
UInt cbfU = pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_U, uiTrIdx );
UInt cbfV = pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_V, uiTrIdx );
if(uiTrIdx==0)
{
m_bakAbsPartIdxCU = uiAbsPartIdx;
}
if( uiLog2TrafoSize == 2 )
{
UInt partNum = pcCU->getPic()->getNumPartInCU() >> ( ( uiDepth - 1 ) << 1 );
if( ( uiAbsPartIdx % partNum ) == 0 )
{
m_uiBakAbsPartIdx = uiAbsPartIdx;
m_uiBakChromaOffset = offsetChroma;
}
else if( ( uiAbsPartIdx % partNum ) == (partNum - 1) )
{
cbfU = pcCU->getCbf( m_uiBakAbsPartIdx, TEXT_CHROMA_U, uiTrIdx );
cbfV = pcCU->getCbf( m_uiBakAbsPartIdx, TEXT_CHROMA_V, uiTrIdx );
}
}
if( pcCU->getPredictionMode(uiAbsPartIdx) == MODE_INTRA && pcCU->getPartitionSize(uiAbsPartIdx) == SIZE_NxN && uiDepth == pcCU->getDepth(uiAbsPartIdx) )
{
assert( uiSubdiv );
}
else if( pcCU->getPredictionMode(uiAbsPartIdx) == MODE_INTER && (pcCU->getPartitionSize(uiAbsPartIdx) != SIZE_2Nx2N) && uiDepth == pcCU->getDepth(uiAbsPartIdx) && (pcCU->getSlice()->getSPS()->getQuadtreeTUMaxDepthInter() == 1) )
{
if ( uiLog2TrafoSize > pcCU->getQuadtreeTULog2MinSizeInCU(uiAbsPartIdx) )
{
assert( uiSubdiv );
}
else
{
assert(!uiSubdiv );
}
}
else if( uiLog2TrafoSize > pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() )
{
assert( uiSubdiv );
}
else if( uiLog2TrafoSize == pcCU->getSlice()->getSPS()->getQuadtreeTULog2MinSize() )
{
assert( !uiSubdiv );
}
else if( uiLog2TrafoSize == pcCU->getQuadtreeTULog2MinSizeInCU(uiAbsPartIdx) )
{
assert( !uiSubdiv );
}
else
{
assert( uiLog2TrafoSize > pcCU->getQuadtreeTULog2MinSizeInCU(uiAbsPartIdx) );
m_pcEntropyCoderIf->codeTransformSubdivFlag( uiSubdiv, 5 - uiLog2TrafoSize );
}
const UInt uiTrDepthCurr = uiDepth - pcCU->getDepth( uiAbsPartIdx );
const Bool bFirstCbfOfCU = uiTrDepthCurr == 0;
if( bFirstCbfOfCU || uiLog2TrafoSize > 2 )
{
if( bFirstCbfOfCU || pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_U, uiTrDepthCurr - 1 ) )
{
m_pcEntropyCoderIf->codeQtCbf( pcCU, uiAbsPartIdx, TEXT_CHROMA_U, uiTrDepthCurr );
}
if( bFirstCbfOfCU || pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_V, uiTrDepthCurr - 1 ) )
{
m_pcEntropyCoderIf->codeQtCbf( pcCU, uiAbsPartIdx, TEXT_CHROMA_V, uiTrDepthCurr );
}
}
else if( uiLog2TrafoSize == 2 )
{
assert( pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_U, uiTrDepthCurr ) == pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_U, uiTrDepthCurr - 1 ) );
assert( pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_V, uiTrDepthCurr ) == pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_V, uiTrDepthCurr - 1 ) );
}
if( uiSubdiv )
{
UInt size;
width >>= 1;
height >>= 1;
size = width*height;
uiTrIdx++;
++uiDepth;
const UInt partNum = pcCU->getPic()->getNumPartInCU() >> (uiDepth << 1);
xEncodeTransform( pcCU, offsetLuma, offsetChroma, uiAbsPartIdx, uiDepth, width, height, uiTrIdx, bCodeDQP );
uiAbsPartIdx += partNum; offsetLuma += size; offsetChroma += (size>>2);
xEncodeTransform( pcCU, offsetLuma, offsetChroma, uiAbsPartIdx, uiDepth, width, height, uiTrIdx, bCodeDQP );
uiAbsPartIdx += partNum; offsetLuma += size; offsetChroma += (size>>2);
xEncodeTransform( pcCU, offsetLuma, offsetChroma, uiAbsPartIdx, uiDepth, width, height, uiTrIdx, bCodeDQP );
uiAbsPartIdx += partNum; offsetLuma += size; offsetChroma += (size>>2);
xEncodeTransform( pcCU, offsetLuma, offsetChroma, uiAbsPartIdx, uiDepth, width, height, uiTrIdx, bCodeDQP );
}
else
{
{
DTRACE_CABAC_VL( g_nSymbolCounter++ );
DTRACE_CABAC_T( "\tTrIdx: abspart=" );
DTRACE_CABAC_V( uiAbsPartIdx );
DTRACE_CABAC_T( "\tdepth=" );
DTRACE_CABAC_V( uiDepth );
DTRACE_CABAC_T( "\ttrdepth=" );
DTRACE_CABAC_V( pcCU->getTransformIdx( uiAbsPartIdx ) );
DTRACE_CABAC_T( "\n" );
}
if( pcCU->getPredictionMode(uiAbsPartIdx) != MODE_INTRA && uiDepth == pcCU->getDepth( uiAbsPartIdx ) && !pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_U, 0 ) && !pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_V, 0 ) )
{
assert( pcCU->getCbf( uiAbsPartIdx, TEXT_LUMA, 0 ) );
// printf( "saved one bin! " );
}
else
{
m_pcEntropyCoderIf->codeQtCbf( pcCU, uiAbsPartIdx, TEXT_LUMA, pcCU->getTransformIdx( uiAbsPartIdx ) );
}
if ( cbfY || cbfU || cbfV )
{
// dQP: only for LCU once
if ( pcCU->getSlice()->getPPS()->getUseDQP() )
{
if ( bCodeDQP )
{
encodeQP( pcCU, m_bakAbsPartIdxCU );
bCodeDQP = false;
}
}
}
if( cbfY )
{
Int trWidth = width;
Int trHeight = height;
m_pcEntropyCoderIf->codeCoeffNxN( pcCU, (pcCU->getCoeffY()+offsetLuma), uiAbsPartIdx, trWidth, trHeight, uiDepth, TEXT_LUMA );
}
if( uiLog2TrafoSize > 2 )
{
Int trWidth = width >> 1;
Int trHeight = height >> 1;
if( cbfU )
{
m_pcEntropyCoderIf->codeCoeffNxN( pcCU, (pcCU->getCoeffCb()+offsetChroma), uiAbsPartIdx, trWidth, trHeight, uiDepth, TEXT_CHROMA_U );
}
if( cbfV )
{
m_pcEntropyCoderIf->codeCoeffNxN( pcCU, (pcCU->getCoeffCr()+offsetChroma), uiAbsPartIdx, trWidth, trHeight, uiDepth, TEXT_CHROMA_V );
}
}
else
{
UInt partNum = pcCU->getPic()->getNumPartInCU() >> ( ( uiDepth - 1 ) << 1 );
if( ( uiAbsPartIdx % partNum ) == (partNum - 1) )
{
Int trWidth = width;
Int trHeight = height;
if( cbfU )
{
m_pcEntropyCoderIf->codeCoeffNxN( pcCU, (pcCU->getCoeffCb()+m_uiBakChromaOffset), m_uiBakAbsPartIdx, trWidth, trHeight, uiDepth, TEXT_CHROMA_U );
}
if( cbfV )
{
m_pcEntropyCoderIf->codeCoeffNxN( pcCU, (pcCU->getCoeffCr()+m_uiBakChromaOffset), m_uiBakAbsPartIdx, trWidth, trHeight, uiDepth, TEXT_CHROMA_V );
}
}
}
}
}
版权声明:本文为FRD2009041510原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。