📄 qualitylevelassigner.cpp
字号:
if( !bValid )
{
RNOK( pcReadBitStream->releasePacket( rpcBinData ) );
}
}
return Err::m_nOK;
}
ErrVal
QualityLevelAssigner::xGetDistortion( UInt& ruiDistortion,
const UChar* pucReconstruction,
const UChar* pucReference,
UInt uiHeight,
UInt uiWidth,
UInt uiStride )
{
ruiDistortion = 0;
for( UInt y = 0; y < uiHeight; y++ )
{
for( UInt x = 0; x < uiWidth; x++ )
{
Int iDiff = ( pucReconstruction[x] - pucReference[x] );
ruiDistortion += (UInt)( iDiff * iDiff );
}
pucReconstruction += uiStride;
pucReference += uiStride;
}
return Err::m_nOK;
}
ErrVal
QualityLevelAssigner::xInitDistortion( UInt* auiDistortion,
UInt uiTopLayer,
UInt uiLayer,
UInt uiFGSLayer,
UInt uiLevel,
Bool bIndependent )
{
ROT( m_pcParameter->getOriginalFileName( uiTopLayer ).empty() );
if( uiLevel == MSYS_UINT_MAX )
printf( "determine distortion (layer %d - FGS %d - base layer ) ...", uiLayer, uiFGSLayer );
else
printf( "determine distortion (layer %d - FGS %d - lev%2d - %s ) ...", uiLayer, uiFGSLayer, uiLevel, bIndependent?"ind":"dep" );
#if WIN32
Char tmp_file_name[] = "decout.tmp";
#endif
Bool bEOS = false;
Bool bToDecode = false;
UInt uiFrame = 0;
UInt uiNalUnitType = 0;
UInt uiMbX = 0;
UInt uiMbY = 0;
UInt uiSize = 0;
Bool SuffixEnable; //bug-fix suffix
// UInt uiNonRequiredPic = 0; //NonRequired JVT-Q066
UInt uiLumOffset = 0;
UInt uiCbOffset = 0;
UInt uiCrOffset = 0;
Bool bYuvDimSet = false;
PicBuffer* pcPicBuffer = 0;
PicBuffer* pcPicBufferOrig = 0;
WriteYuvIf* pcWriteYuv = 0;
PicBufferList cPicBufferOutputList;
PicBufferList cPicBufferUnusedList;
PicBufferList cPicBufferReleaseList;
UInt auiFrameNumAnalysis[MAX_LAYERS] = { MSYS_UINT_MAX, MSYS_UINT_MAX, MSYS_UINT_MAX, MSYS_UINT_MAX, MSYS_UINT_MAX, MSYS_UINT_MAX, MSYS_UINT_MAX, MSYS_UINT_MAX };
UInt auiFrameNumDecoding[MAX_LAYERS] = { MSYS_UINT_MAX, MSYS_UINT_MAX, MSYS_UINT_MAX, MSYS_UINT_MAX, MSYS_UINT_MAX, MSYS_UINT_MAX, MSYS_UINT_MAX, MSYS_UINT_MAX };
//===== init =====
RNOK( m_pcH264AVCPacketAnalyzer->init() );
RNOK( m_pcH264AVCDecoder ->init( true ) );
ReadBitstreamFile* pcReadBitStream = 0;
ReadYuvFile* pcReadYuv = 0;
RNOK( ReadBitstreamFile ::create( pcReadBitStream ) );
RNOK( ReadYuvFile ::create( pcReadYuv ) );
RNOK( pcReadBitStream ->init( m_pcParameter->getInputBitStreamName() ) );
RNOK( pcReadYuv ->init( m_pcParameter->getOriginalFileName ( uiTopLayer ), m_auiFrameHeight[uiTopLayer], m_auiFrameWidth[uiTopLayer] ) );
if( m_bOutputReconstructions )
{
Char acName[1024];
sprintf( acName, "rec_Layer%d_FGS%d_Level%d_Mode%d", uiLayer, uiFGSLayer, uiLevel, (bIndependent?0:1) );
RNOK( WriteYuvToFile::create( pcWriteYuv, std::string( acName ) ) );
}
//===== loop over packets =====
while( ! bEOS )
{
Int iPos;
Bool bFinishChecking;
BinData* pcBinData;
BinDataAccessor cBinDataAccessor;
//----- analyse access unit -----
RNOK( pcReadBitStream->getPosition( iPos ) );
do
{
RNOK( xGetNextValidPacket( pcBinData, pcReadBitStream, uiTopLayer, uiLayer, uiFGSLayer, uiLevel, bIndependent, bEOS, auiFrameNumAnalysis ) );
pcBinData->setMemAccessor( cBinDataAccessor );
bFinishChecking = false;
RNOK( m_pcH264AVCDecoder->checkSliceLayerDependency( &cBinDataAccessor, bFinishChecking ) );
RNOK( pcReadBitStream->releasePacket( pcBinData ) );
} while( !bFinishChecking );
#define MAX_FRAGMENTS 10 // see H264AVCDecoderTest::go()
Bool bFragmented = false;
Bool bDiscardable = false;
Bool bStart = false;
Bool bFirst = true;
Bool bConcatenated = false;
UInt uiTotalLength = 0;
UInt uiFragmentNumber = 0;
BinData* apcBinDataTmp [MAX_FRAGMENTS];
BinDataAccessor acBinDataAccessorTmp[MAX_FRAGMENTS];
UInt auiStartPos [MAX_FRAGMENTS];
UInt auiEndPos [MAX_FRAGMENTS];
for( pcBinData = 0, bEOS = false; !bStart && !bEOS; )
{
if( bFirst )
{
RNOK( pcReadBitStream->setPosition( iPos ) );
bFirst = false;
}
RNOK( xGetNextValidPacket( apcBinDataTmp[uiFragmentNumber], pcReadBitStream, uiTopLayer, uiLayer, uiFGSLayer, uiLevel, bIndependent, bEOS, auiFrameNumDecoding ) );
::memcpy( auiFrameNumAnalysis, auiFrameNumDecoding, MAX_LAYERS*sizeof(UInt) );
apcBinDataTmp[uiFragmentNumber]->setMemAccessor( acBinDataAccessorTmp[uiFragmentNumber] );
RNOK( m_pcH264AVCDecoder->initPacket( &acBinDataAccessorTmp[uiFragmentNumber],
uiNalUnitType, uiMbX, uiMbY, uiSize,
//uiNonRequiredPic, //NonRequired JVT-Q066
true, false, //FRAG_FIX_3
bStart, auiStartPos[uiFragmentNumber], auiEndPos[uiFragmentNumber],
bFragmented, bDiscardable ) );
//prefix unit{{
if(uiNalUnitType == 14)
{
m_pcH264AVCDecoder->decreaseNumOfNALInAU();
RNOK( pcReadBitStream->releasePacket( apcBinDataTmp[uiFragmentNumber] ) );
break;
}
//prefix unit}}
//NonRequired JVT-Q066
/*
if( uiNonRequiredPic )
{
continue;
}
*/
//NonRequired JVT-Q066
uiTotalLength += ( auiEndPos[uiFragmentNumber] - auiStartPos[uiFragmentNumber] );
if( !bStart )
{
uiFragmentNumber++;
}
else
{
if( apcBinDataTmp[0]->size() != 0 )
{
pcBinData = new BinData();
pcBinData->set( new UChar[uiTotalLength], uiTotalLength );
UInt uiOffset = 0;
for( UInt uiFragment = 0; uiFragment <= uiFragmentNumber; uiFragment++ )
{
::memcpy ( pcBinData->data()+uiOffset,
apcBinDataTmp[uiFragment]->data() + auiStartPos[uiFragment],
auiEndPos[uiFragment] - auiStartPos[uiFragment] );
uiOffset += auiEndPos[uiFragment] - auiStartPos[uiFragment];
RNOK( pcReadBitStream->releasePacket( apcBinDataTmp[uiFragment] ) );
apcBinDataTmp[uiFragment] = 0;
m_pcH264AVCDecoder->decreaseNumOfNALInAU();
if( uiFragment > 0 )
{
bConcatenated = true;
}
}
pcBinData->setMemAccessor( cBinDataAccessor );
bToDecode = false;
if( ( uiTotalLength != 0 ) && ( !bDiscardable || bFragmented ) )
{
if( ( uiNalUnitType == 20 ) || ( uiNalUnitType == 21 ) || ( uiNalUnitType == 1 ) || ( uiNalUnitType == 5 ) )
{
RNOK( m_pcH264AVCDecoder->initPacket( &cBinDataAccessor, uiNalUnitType,
uiMbX, uiMbY, uiSize,
//uiNonRequiredPic, //NonRequired JVT-Q066
false, bConcatenated, bStart,
auiStartPos[uiFragmentNumber+1], auiEndPos[uiFragmentNumber+1],
bFragmented, bDiscardable ) );
}
else
{
RNOK( m_pcH264AVCDecoder->initPacket( &cBinDataAccessor ) );
}
bToDecode = true;
}
}
//manu.mathew@samsung : memory leak fix
else
{
RNOK( pcReadBitStream->releasePacket( apcBinDataTmp[0] ) );
apcBinDataTmp[0] = NULL;
}
//--
}
}
//prefix unit{{
if(uiNalUnitType == 14)
{
continue;
}
//prefix unit}}
Bool bWasAVCNALUnit = ( uiNalUnitType == 1 || uiNalUnitType == 5 );
//NonRequired JVT-Q066{
if(m_pcH264AVCDecoder->isNonRequiredPic())
continue;
//NonRequired JVT-Q066}
if( bToDecode )
{
//----- get pic buffer -----
pcPicBuffer = 0;
if( uiNalUnitType == 1 || uiNalUnitType == 5 || uiNalUnitType == 20 || uiNalUnitType == 21 )
{
RNOK( xGetNewPicBuffer( pcPicBuffer, uiSize ) );
if( !bYuvDimSet )
{
RNOK( xGetNewPicBuffer( pcPicBufferOrig, uiSize ) );
UInt uiLumSize = ((uiMbX<<3)+ YUV_X_MARGIN) * ((uiMbY<<3) + YUV_Y_MARGIN ) * 4;
uiLumOffset = ((uiMbX<<4)+2*YUV_X_MARGIN) * YUV_Y_MARGIN + YUV_X_MARGIN;
uiCbOffset = ((uiMbX<<3)+ YUV_X_MARGIN) * YUV_Y_MARGIN/2 + YUV_X_MARGIN/2 + uiLumSize;
uiCrOffset = ((uiMbX<<3)+ YUV_X_MARGIN) * YUV_Y_MARGIN/2 + YUV_X_MARGIN/2 + 5*uiLumSize/4;
bYuvDimSet = true;
}
}
//----- decode packet -----
{
//----- re-direct stdout -----
#if WIN32 // for linux, this have to be slightly re-formulated
Int orig_stdout = _dup(1);
FILE* stdout_copy = freopen( tmp_file_name, "wt", stdout );
#endif
//bug-fix suffix{{
if(uiNalUnitType == 1 || uiNalUnitType == 5)
{
SuffixEnable = true;
RNOK(m_pcH264AVCDecoderSuffix->init( false ));
RNOK( pcReadBitStream->getPosition( iPos ) );
RNOK( pcReadBitStream->extractPacket( pcBinData, bEOS ) );
pcBinData->setMemAccessor( cBinDataAccessor );
RNOK( m_pcH264AVCDecoderSuffix->initPacketSuffix( &cBinDataAccessor, uiNalUnitType, true,
false, //FRAG_FIX_3
bStart, m_pcH264AVCDecoder,SuffixEnable
)
);
RNOK( m_pcH264AVCDecoderSuffix->uninit( false ));
if( !SuffixEnable )
{
RNOK( pcReadBitStream->setPosition( iPos ) );
bEOS = false;
}
else
{
// m_pcH264AVCDecoder->decreaseNumOfNALInAU(); //{suffix TL read
}
}
//bug-fix suffix}}
//----- decode -----
RNOK( m_pcH264AVCDecoder->process( pcPicBuffer,
cPicBufferOutputList,
cPicBufferUnusedList,
cPicBufferReleaseList ) );
if( bWasAVCNALUnit && m_pcH264AVCDecoder->getBaseSVCActive() )
{
RNOK( xGetNewPicBuffer( pcPicBuffer, uiSize ) );
RNOK( m_pcH264AVCDecoder->process( pcPicBuffer, cPicBufferOutputList, cPicBufferUnusedList, cPicBufferReleaseList ) );
}
//---- restore stdout -----
#if WIN32 // for linux, this have to be slightly re-formulated
fclose( stdout );
_dup2( orig_stdout, 1 );
_iob[1] = *fdopen( 1, "wt" );
fclose( fdopen( orig_stdout, "w" ) );
#endif
}
//----- determine distortion (and output for debugging) -----
while( ! cPicBufferOutputList.empty() )
{
PicBuffer* pcPicBufferTmp = cPicBufferOutputList.front();
cPicBufferOutputList.pop_front();
if( pcPicBufferTmp )
{
//----- output (for debugging) -----
if( pcWriteYuv )
{
RNOK( pcWriteYuv->writeFrame( *pcPicBufferTmp + uiLumOffset,
*pcPicBufferTmp + uiCbOffset,
*pcPicBufferTmp + uiCrOffset,
uiMbY << 4,
uiMbX << 4,
(uiMbX << 4) + YUV_X_MARGIN*2 ) );
}
//----- read in reference picture ------
RNOK( pcReadYuv->readFrame ( *pcPicBufferOrig + uiLumOffset,
*pcPicBufferOrig + uiCbOffset,
*pcPicBufferOrig + uiCrOffset,
uiMbY << 4,
uiMbX << 4,
(uiMbX << 4) + YUV_X_MARGIN*2 ) );
//----- get distortion -----
RNOK( xGetDistortion ( auiDistortion[uiFrame],
*pcPicBufferTmp + uiLumOffset,
*pcPicBufferOrig + uiLumOffset,
uiMbY << 4,
uiMbX << 4,
(uiMbX << 4) + YUV_X_MARGIN*2 ) );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -