Commit eb1390ec authored by Karsten Suehring's avatar Karsten Suehring

Merge branch 'crhelmrich/VVCSoftware_BMS-K0206-Integration'

parents 5050b4d0 b05e50cb
Pipeline #48 passed with stage
......@@ -214,6 +214,11 @@ uint32_t DecApp::decode()
}
}
if (m_packedYUVMode && (m_outputBitDepth[CH_L] != 10 && m_outputBitDepth[CH_L] != 12))
{
EXIT ("Invalid output bit-depth for packed YUV output, aborting\n");
}
m_cVideoIOYuvReconFile.open( m_reconFileName, true, m_outputBitDepth, m_outputBitDepth, bitDepths.recon ); // write mode
openedReconFile = true;
}
......@@ -283,9 +288,9 @@ void DecApp::xCreateDecLib()
m_cDecLib.create();
// initialize decoder class
m_cDecLib.init(
m_cDecLib.init(
#if JVET_J0090_MEMORY_BANDWITH_MEASURE
m_cacheCfgFile
m_cacheCfgFile
#endif
);
m_cDecLib.setDecodedPictureHashSEIEnabled(m_decodedPictureHashSEIEnabled);
......@@ -398,11 +403,13 @@ void DecApp::xWriteOutput( PicList* pcListPic, uint32_t tId )
if (display)
{
m_cVideoIOYuvReconFile.write( pcPicTop->getRecoBuf(), pcPicBottom->getRecoBuf(),
m_outputColourSpaceConvert,
conf.getWindowLeftOffset() + defDisp.getWindowLeftOffset(),
conf.getWindowRightOffset() + defDisp.getWindowRightOffset(),
conf.getWindowTopOffset() + defDisp.getWindowTopOffset(),
conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset(), NUM_CHROMA_FORMAT, isTff );
m_outputColourSpaceConvert,
false, // TODO: m_packedYUVMode,
conf.getWindowLeftOffset() + defDisp.getWindowLeftOffset(),
conf.getWindowRightOffset() + defDisp.getWindowRightOffset(),
conf.getWindowTopOffset() + defDisp.getWindowTopOffset(),
conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset(),
NUM_CHROMA_FORMAT, isTff );
}
}
......@@ -449,6 +456,7 @@ void DecApp::xWriteOutput( PicList* pcListPic, uint32_t tId )
m_cVideoIOYuvReconFile.write( pcPic->getRecoBuf(),
m_outputColourSpaceConvert,
m_packedYUVMode,
conf.getWindowLeftOffset() + defDisp.getWindowLeftOffset(),
conf.getWindowRightOffset() + defDisp.getWindowRightOffset(),
conf.getWindowTopOffset() + defDisp.getWindowTopOffset(),
......@@ -506,15 +514,18 @@ void DecApp::xFlushOutput( PicList* pcListPic )
// write to file
if ( !m_reconFileName.empty() )
{
const Window &conf = pcPicTop->cs->sps->getConformanceWindow();
const Window &conf = pcPicTop->cs->sps->getConformanceWindow();
const Window defDisp = (m_respectDefDispWindow && pcPicTop->cs->sps->getVuiParametersPresentFlag()) ? pcPicTop->cs->sps->getVuiParameters()->getDefaultDisplayWindow() : Window();
const bool isTff = pcPicTop->topField;
const bool isTff = pcPicTop->topField;
m_cVideoIOYuvReconFile.write( pcPicTop->getRecoBuf(), pcPicBottom->getRecoBuf(),
m_outputColourSpaceConvert,
conf.getWindowLeftOffset() + defDisp.getWindowLeftOffset(),
conf.getWindowRightOffset() + defDisp.getWindowRightOffset(),
conf.getWindowTopOffset() + defDisp.getWindowTopOffset(),
conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset(), NUM_CHROMA_FORMAT, isTff );
m_outputColourSpaceConvert,
false, // TODO: m_packedYUVMode,
conf.getWindowLeftOffset() + defDisp.getWindowLeftOffset(),
conf.getWindowRightOffset() + defDisp.getWindowRightOffset(),
conf.getWindowTopOffset() + defDisp.getWindowTopOffset(),
conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset(),
NUM_CHROMA_FORMAT, isTff );
}
// update POC of display order
......@@ -564,6 +575,7 @@ void DecApp::xFlushOutput( PicList* pcListPic )
m_cVideoIOYuvReconFile.write( pcPic->getRecoBuf(),
m_outputColourSpaceConvert,
m_packedYUVMode,
conf.getWindowLeftOffset() + defDisp.getWindowLeftOffset(),
conf.getWindowRightOffset() + defDisp.getWindowRightOffset(),
conf.getWindowTopOffset() + defDisp.getWindowTopOffset(),
......
......@@ -96,6 +96,7 @@ bool DecAppCfg::parseCfg( int argc, char* argv[] )
("SEIColourRemappingInfoFilename", m_colourRemapSEIFileName, string(""), "Colour Remapping YUV output file name. If empty, no remapping is applied (ignore SEI message)\n")
("OutputDecodedSEIMessagesFilename", m_outputDecodedSEIMessagesFilename, string(""), "When non empty, output decoded SEI messages to the indicated file. If file is '-', then output to stdout\n")
("ClipOutputVideoToRec709Range", m_bClipOutputVideoToRec709Range, false, "If true then clip output video to the Rec. 709 Range on saving")
("PYUV", m_packedYUVMode, false, "If true then output 10-bit and 12-bit YUV data as 5-byte and 3-byte (respectively) packed YUV data. Ignored for interlaced output.")
#if ENABLE_TRACING
("TraceChannelsList", bTracingChannelsList, false, "List all available tracing channels" )
("TraceRule", sTracingRule, string( "" ), "Tracing rule (ex: \"D_CABAC:poc==8\" or \"D_REC_CB_LUMA:poc==8\")" )
......@@ -227,6 +228,7 @@ DecAppCfg::DecAppCfg()
, m_respectDefDispWindow(0)
, m_outputDecodedSEIMessagesFilename()
, m_bClipOutputVideoToRec709Range(false)
, m_packedYUVMode(false)
, m_statMode(0)
{
for (uint32_t channelTypeIndex = 0; channelTypeIndex < MAX_NUM_CHANNEL_TYPE; channelTypeIndex++)
......
......@@ -70,6 +70,7 @@ protected:
int m_respectDefDispWindow; ///< Only output content inside the default display window
std::string m_outputDecodedSEIMessagesFilename; ///< filename to output decoded SEI messages to. If '-', then use stdout. If empty, do not output details.
bool m_bClipOutputVideoToRec709Range; ///< If true, clip the output video to the Rec 709 range on saving.
bool m_packedYUVMode; ///< If true, output 10-bit and 12-bit YUV data as 5-byte and 3-byte (respectively) packed YUV data
std::string m_cacheCfgFile; ///< Config file of cache model
int m_statMode; ///< Config statistic mode (0 - bit stat, 1 - tool stat, 3 - both)
......
......@@ -602,6 +602,17 @@ void EncApp::xCreateLib( std::list<PelUnitBuf*>& recBufList
#endif
if (!m_reconFileName.empty())
{
if (m_packedYUVMode && ((m_outputBitDepth[CH_L] != 10 && m_outputBitDepth[CH_L] != 12)
|| ((m_iSourceWidth & (1 + (m_outputBitDepth[CH_L] & 3))) != 0)))
{
EXIT ("Invalid output bit-depth or image width for packed YUV output, aborting\n");
}
if (m_packedYUVMode && (m_chromaFormatIDC != CHROMA_400) && ((m_outputBitDepth[CH_C] != 10 && m_outputBitDepth[CH_C] != 12)
|| (((m_iSourceWidth / SPS::getWinUnitX (m_chromaFormatIDC)) & (1 + (m_outputBitDepth[CH_C] & 3))) != 0)))
{
EXIT ("Invalid chroma output bit-depth or image width for packed YUV output, aborting\n");
}
m_cVideoIOYuvReconFile.open(m_reconFileName, true, m_outputBitDepth, m_outputBitDepth, m_internalBitDepth); // write mode
}
......@@ -790,7 +801,10 @@ void EncApp::xWriteOutput( int iNumEncoded, std::list<PelUnitBuf*>& recBufList
if (!m_reconFileName.empty())
{
m_cVideoIOYuvReconFile.write( *pcPicYuvRecTop, *pcPicYuvRecBottom, ipCSC, m_confWinLeft, m_confWinRight, m_confWinTop, m_confWinBottom, NUM_CHROMA_FORMAT, m_isTopFieldFirst );
m_cVideoIOYuvReconFile.write( *pcPicYuvRecTop, *pcPicYuvRecBottom,
ipCSC,
false, // TODO: m_packedYUVMode,
m_confWinLeft, m_confWinRight, m_confWinTop, m_confWinBottom, NUM_CHROMA_FORMAT, m_isTopFieldFirst );
}
}
}
......@@ -802,7 +816,9 @@ void EncApp::xWriteOutput( int iNumEncoded, std::list<PelUnitBuf*>& recBufList
if (!m_reconFileName.empty())
{
m_cVideoIOYuvReconFile.write( *pcPicYuvRec,
ipCSC, m_confWinLeft, m_confWinRight, m_confWinTop, m_confWinBottom, NUM_CHROMA_FORMAT, m_bClipOutputVideoToRec709Range );
ipCSC,
m_packedYUVMode,
m_confWinLeft, m_confWinRight, m_confWinTop, m_confWinBottom, NUM_CHROMA_FORMAT, m_bClipOutputVideoToRec709Range );
}
}
}
......
......@@ -107,6 +107,7 @@ EncAppCfg::EncAppCfg()
: m_inputColourSpaceConvert(IPCOLOURSPACE_UNCHANGED)
, m_snrInternalColourSpace(false)
, m_outputInternalColourSpace(false)
, m_packedYUVMode(false)
#if EXTENSION_360_VIDEO
, m_ext360(*this)
#endif
......@@ -766,6 +767,7 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
("FramesToBeEncoded,f", m_framesToBeEncoded, 0, "Number of frames to be encoded (default=all)")
("ClipInputVideoToRec709Range", m_bClipInputVideoToRec709Range, false, "If true then clip input video to the Rec. 709 Range on loading when InternalBitDepth is less than MSBExtendedBitDepth")
("ClipOutputVideoToRec709Range", m_bClipOutputVideoToRec709Range, false, "If true then clip output video to the Rec. 709 Range on saving when OutputBitDepth is less than InternalBitDepth")
("PYUV", m_packedYUVMode, false, "If true then output 10-bit and 12-bit YUV data as 5-byte and 3-byte (respectively) packed YUV data. Ignored for interlaced output.")
("SummaryOutFilename", m_summaryOutFilename, string(), "Filename to use for producing summary output file. If empty, do not produce a file.")
("SummaryPicFilenameBase", m_summaryPicFilenameBase, string(), "Base filename to use for producing summary picture output files. The actual filenames used will have I.txt, P.txt and B.txt appended. If empty, do not produce a file.")
("SummaryVerboseness", m_summaryVerboseness, 0u, "Specifies the level of the verboseness of the text output")
......@@ -973,7 +975,7 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
/* Quantization parameters */
#if QP_SWITCHING_FOR_PARALLEL
("QP,q", m_iQP, 30, "Qp value")
("QPIncrementFrame,-qpif", m_qpIncrementAtSourceFrame, OptionalValue<uint32_t>(), "If a source file frame number is specified, the internal QP will be incremented for all POCs associated with source frames >= frame number. If empty, do not increment.")
("QPIncrementFrame,-qpif", m_qpIncrementAtSourceFrame, OptionalValue<uint32_t>(), "If a source file frame number is specified, the internal QP will be incremented for all POCs associated with source frames >= frame number. If empty, do not increment.")
#else
("QP,q", m_fQP, 30.0, "Qp value, if value is float, QP is switched once during encoding")
#endif
......@@ -1858,14 +1860,25 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
#endif
#if ENABLE_QPA
if( m_LargeCTU && m_bUsePerceptQPA && !m_bUseAdaptiveQP && ( m_iSourceHeight <= 1280 ) && ( m_iSourceWidth <= 2048 ) )
if (m_bUsePerceptQPA && !m_bUseAdaptiveQP && m_dualTree && (m_cbQpOffsetDualTree != 0 || m_crQpOffsetDualTree != 0))
{
msg( WARNING, "*************************************************************************\n" );
msg( WARNING, "* WARNING: chroma QPA on, ignoring nonzero dual-tree chroma QP offsets! *\n" );
msg( WARNING, "*************************************************************************\n" );
}
#if QP_SWITCHING_FOR_PARALLEL
if( m_LargeCTU && ( m_iQP < 38 ) && ( m_iGOPSize > 4 ) && m_bUsePerceptQPA && !m_bUseAdaptiveQP && ( m_iSourceHeight <= 1280 ) && ( m_iSourceWidth <= 2048 ) )
#else
if( m_LargeCTU && ( ( int ) m_fQP < 38 ) && ( m_iGOPSize > 4 ) && m_bUsePerceptQPA && !m_bUseAdaptiveQP && ( m_iSourceHeight <= 1280 ) && ( m_iSourceWidth <= 2048 ) )
#endif
#else
if( false )
#endif
{
msg( WARNING, "***************************************************************************\n" );
msg( WARNING, "* WARNING: QPA on with LargeCTU for incompatible size, limiting CTU size! *\n" );
msg( WARNING, "***************************************************************************\n" );
msg( WARNING, "*************************************************************************\n" );
msg( WARNING, "* WARNING: QPA on with large CTU for <=HD sequences, limiting CTU size! *\n" );
msg( WARNING, "*************************************************************************\n" );
m_uiCTUSize = m_uiMaxCUWidth;
if( ( 1u << m_quadtreeTULog2MaxSize ) > m_uiCTUSize ) m_quadtreeTULog2MaxSize--;
......@@ -2363,6 +2376,9 @@ bool EncAppCfg::xCheckParameter()
xConfirmPara( m_bipredSearchRange < 0 , "Bi-prediction refinement search range must be more than 0" );
xConfirmPara( m_minSearchWindow < 0, "Minimum motion search window size for the adaptive window ME must be greater than or equal to 0" );
xConfirmPara( m_iMaxDeltaQP > MAX_DELTA_QP, "Absolute Delta QP exceeds supported range (0 to 7)" );
#if ENABLE_QPA
xConfirmPara( m_bUsePerceptQPA && m_uiDeltaQpRD > 0, "Perceptual QPA cannot be used together with slice-level multiple-QP optimization" );
#endif
#if SHARP_LUMA_DELTA_QP
xConfirmPara( m_lumaLevelToDeltaQPMapping.mode && m_uiDeltaQpRD > 0, "Luma-level-based Delta QP cannot be used together with slice level multiple-QP optimization\n" );
#endif
......@@ -3075,7 +3091,7 @@ void EncAppCfg::xPrintParameter()
msg( DETAILS, "Real Format : %dx%d %gHz\n", m_iSourceWidth - m_confWinLeft - m_confWinRight, m_iSourceHeight - m_confWinTop - m_confWinBottom, (double)m_iFrameRate / m_temporalSubsampleRatio );
msg( DETAILS, "Internal Format : %dx%d %gHz\n", m_iSourceWidth, m_iSourceHeight, (double)m_iFrameRate / m_temporalSubsampleRatio );
msg( DETAILS, "Sequence PSNR output : %s\n", ( m_printMSEBasedSequencePSNR ? "Linear average, MSE-based" : "Linear average only" ) );
msg(DETAILS, "Hexadecimal PSNR output : %s\n", ( m_printHexPsnr ? "Enabled" : "Disabled" ) );
msg( DETAILS, "Hexadecimal PSNR output : %s\n", ( m_printHexPsnr ? "Enabled" : "Disabled" ) );
msg( DETAILS, "Sequence MSE output : %s\n", ( m_printSequenceMSE ? "Enabled" : "Disabled" ) );
msg( DETAILS, "Frame MSE output : %s\n", ( m_printFrameMSE ? "Enabled" : "Disabled" ) );
msg( DETAILS, "Cabac-zero-word-padding : %s\n", ( m_cabacZeroWordPaddingEnabled ? "Enabled" : "Disabled" ) );
......
......@@ -115,6 +115,7 @@ protected:
bool m_cabacZeroWordPaddingEnabled;
bool m_bClipInputVideoToRec709Range;
bool m_bClipOutputVideoToRec709Range;
bool m_packedYUVMode; ///< If true, output 10-bit and 12-bit YUV data as 5-byte and 3-byte (respectively) packed YUV data
// profile/level
Profile::Name m_profile;
......@@ -338,7 +339,7 @@ protected:
int m_maxNumOffsetsPerPic; ///< SAO maximun number of offset per picture
bool m_saoCtuBoundary; ///< SAO parameter estimation using non-deblocked pixels for CTU bottom and right boundary areas
#if K0238_SAO_GREEDY_MERGE_ENCODING
bool m_saoGreedyMergeEnc; ///< SAO greedy merge encoding algorithm
bool m_saoGreedyMergeEnc; ///< SAO greedy merge encoding algorithm
#endif
// coding tools (loop filter)
bool m_bLoopFilterDisable; ///< flag for using deblocking filter
......
......@@ -1493,7 +1493,7 @@ void CtxStore<BinProbModel>::init( int qp, int initId )
const std::vector<uint8_t>& initTable = ContextSetCfg::getInitTable( initId );
CHECK( m_CtxBuffer.size() != initTable.size(),
"Size of init table (" << initTable.size() << ") does not match size of context buffer (" << m_CtxBuffer.size() << ")." );
int clippedQP = std::min( std::max( 0, qp ), MAX_QP );
int clippedQP = Clip3( 0, MAX_QP, qp );
for( std::size_t k = 0; k < m_CtxBuffer.size(); k++ )
{
m_CtxBuffer[k].init( clippedQP, initTable[k] );
......
......@@ -89,7 +89,7 @@
#define JVET_K0351_LESS_CONSTRAINT 1 // Only disallow binary split with same orientation in center partition of the ternary split and release the other constraints in K0351.
#define JVET_K0251_QP_EXT 1 // Extending the QP parameter value range for coarse quantization
#define JVET_K0251_QP_EXT 1 // Extending the QP parameter value range for coarse quantization
#define JVET_K_AFFINE 1
#if JVET_K_AFFINE
......@@ -178,7 +178,7 @@
#endif // ! ENABLE_TRACING
#define WCG_EXT 0 // part of JEM sharp Luma qp
#define WCG_WPSNR WCG_EXT
#define WCG_WPSNR WCG_EXT
#if HEVC_TOOLS
#define HEVC_USE_INTRA_SMOOTHING_T32 1
......@@ -321,8 +321,7 @@
#define SHARP_LUMA_DELTA_QP 1 ///< include non-normative LCU deltaQP and normative chromaQP change
#define ER_CHROMA_QP_WCG_PPS 1 ///< Chroma QP model for WCG used in Anchor 3.2
#define ENABLE_QPA 0
#define ENABLE_QPA 1 ///< Non-normative perceptual QP adaptation according to JVET-H0047 and JVET-K0206. Deactivated by default, activated using encoder arguments --PerceptQPA=1 --SliceChromaQPOffsetPeriodicity=1
#if JEM_TOOLS && !JVET_K0371_ALF
#define COM16_C806_ALF_TEMPPRED_NUM 6 //tbd
......@@ -1553,8 +1552,8 @@ enum AlfFilterType
struct AlfFilterShape
{
AlfFilterShape( int size )
: filterLength( size ),
numCoeff( size * size / 4 + 1 ),
: filterLength( size ),
numCoeff( size * size / 4 + 1 ),
filterSize( size * size / 2 + 1 )
{
if( size == 5 )
......@@ -1597,7 +1596,7 @@ struct AlfFilterShape
2,
2, 2, 2,
2, 2, 2, 2, 2,
2, 2, 2, 1, 1
2, 2, 2, 1, 1
};
golombIdx = {
......
......@@ -795,9 +795,9 @@ void EncCu::updateLambda( Slice* slice, double dQP )
#endif
#endif
double qp_temp = (double) dQP + bitdepth_luma_qp_scale - SHIFT_QP;
double dQPFactor = m_pcEncCfg->getGOPEntry( m_pcSliceEncoder->getGopId() ).m_QPFactor;
if( slice->getSliceType() == I_SLICE )
{
if( m_pcEncCfg->getIntraQpFactor() >= 0.0 /*&& m_pcEncCfg->getGOPEntry( m_pcSliceEncoder->getGopId() ).m_sliceType != I_SLICE*/ )
......@@ -848,7 +848,7 @@ void EncCu::updateLambda( Slice* slice, double dQP )
dLambda *= lambdaModifier;
int qpBDoffset = slice->getSPS()->getQpBDOffset(CHANNEL_TYPE_LUMA);
int iQP = max( -qpBDoffset, min( MAX_QP, (int) floor( dQP + 0.5 ) ) );
int iQP = Clip3(-qpBDoffset, MAX_QP, (int)floor(dQP + 0.5));
m_pcSliceEncoder->setUpLambda(slice, dLambda, iQP);
#else
......@@ -1469,7 +1469,7 @@ void EncCu::xCheckIntraPCM(CodingStructure *&tempCS, CodingStructure *&bestCS, P
cu.ipcm = true;
tempCS->addPU(tempCS->area, partitioner.chType);
tempCS->addTU( tempCS->area, partitioner.chType );
m_pcIntraSearch->IPCMSearch(*tempCS, partitioner);
......@@ -2508,7 +2508,7 @@ void EncCu::xEncodeInterResidual( CodingStructure *&tempCS, CodingStructure *&be
}
}
#endif
}//end emt loop
} //end emt loop
}
......
......@@ -359,7 +359,7 @@ void EncGOP::init ( EncLib* pcEncLib )
m_totalCoded = 0;
m_AUWriterIf = pcEncLib->getAUWriterIf();
#if WCG_EXT
pcEncLib->getRdCost()->initLumaLevelToWeightTable();
#endif
......@@ -1756,8 +1756,8 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
RefPicListModification* refPicListModification = pcSlice->getRefPicListModification();
refPicListModification->setRefPicListModificationFlagL0(0);
refPicListModification->setRefPicListModificationFlagL1(0);
pcSlice->setNumRefIdx(REF_PIC_LIST_0,min(m_pcCfg->getGOPEntry(iGOPid).m_numRefPicsActive,pcSlice->getRPS()->getNumberOfPictures()));
pcSlice->setNumRefIdx(REF_PIC_LIST_1,min(m_pcCfg->getGOPEntry(iGOPid).m_numRefPicsActive,pcSlice->getRPS()->getNumberOfPictures()));
pcSlice->setNumRefIdx(REF_PIC_LIST_0, std::min(m_pcCfg->getGOPEntry(iGOPid).m_numRefPicsActive, pcSlice->getRPS()->getNumberOfPictures()));
pcSlice->setNumRefIdx(REF_PIC_LIST_1, std::min(m_pcCfg->getGOPEntry(iGOPid).m_numRefPicsActive, pcSlice->getRPS()->getNumberOfPictures()));
// Set reference list
pcSlice->setRefPicList ( rcListPic );
......@@ -1994,12 +1994,12 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
#if V0078_ADAPTIVE_LOWER_BOUND
if (estimatedCpbFullness - estimatedBits < m_pcRateCtrl->getRCPic()->getLowerBound())
{
estimatedBits = max(200, estimatedCpbFullness - m_pcRateCtrl->getRCPic()->getLowerBound());
estimatedBits = std::max(200, estimatedCpbFullness - m_pcRateCtrl->getRCPic()->getLowerBound());
}
#else
if (estimatedCpbFullness - estimatedBits < (int)(m_pcRateCtrl->getCpbSize()*0.1f))
{
estimatedBits = max(200, estimatedCpbFullness - (int)(m_pcRateCtrl->getCpbSize()*0.1f));
estimatedBits = std::max(200, estimatedCpbFullness - (int)(m_pcRateCtrl->getCpbSize()*0.1f));
}
#endif
......@@ -2153,7 +2153,11 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
trySkipOrDecodePicture( decPic, encPic, *m_pcCfg, pcPic );
pcPic->cs->slice = pcSlice; // please keep this
if (pcSlice->getPPS()->getSliceChromaQpFlag() && CS::isDualITree(*pcSlice->getPic()->cs))
#if ENABLE_QPA
if (pcSlice->getPPS()->getSliceChromaQpFlag() && CS::isDualITree (*pcSlice->getPic()->cs) && !m_pcCfg->getUsePerceptQPA() && (m_pcCfg->getSliceChromaOffsetQpPeriodicity() == 0))
#else
if (pcSlice->getPPS()->getSliceChromaQpFlag() && CS::isDualITree (*pcSlice->getPic()->cs))
#endif
{
// overwrite chroma qp offset for dual tree
pcSlice->setSliceChromaQpDelta(COMPONENT_Cb, m_pcCfg->getChromaCbQpOffsetDualTree());
......@@ -2661,7 +2665,7 @@ void EncGOP::printOutSummary(uint32_t uiNumAllPicCoded, bool isField, const bool
m_gcAnalyzeWPSNR.setFrmRate(m_pcCfg->getFrameRate()*rateMultiplier / (double)m_pcCfg->getTemporalSubsampleRatio());
}
#endif
const ChromaFormat chFmt = m_pcCfg->getChromaFormatIdc();
//-- all
......@@ -2680,7 +2684,7 @@ void EncGOP::printOutSummary(uint32_t uiNumAllPicCoded, bool isField, const bool
msg( DETAILS,"\n\nB Slices--------------------------------------------------------\n" );
m_gcAnalyzeB.printOut('b', chFmt, printMSEBasedSNR, printSequenceMSE, bitDepths);
#if WCG_WPSNR
if (useLumaWPSNR)
{
......@@ -2828,15 +2832,18 @@ void EncGOP::xGetBuffer( PicList& rcListPic,
#if ENABLE_QPA
#ifndef BETA
#define BETA (2.0 / 3.0) // value between 0 and 1; use 0.0 for traditional PSNR
#define BETA 0.5 // value between 0.0 and 1; use 0.0 to obtain traditional PSNR
#endif
#define GLOBAL_AVERAGING 1 // "global" averaging of a_k across a set instead of one picture
#if FRAME_WEIGHTING
static const uint32_t DQP[16] = { 4, 12, 11, 12, 9, 12, 11, 12, 6, 12, 11, 12, 9, 12, 11, 12 };
#endif
static inline double calcWeightedSquaredError(const CPelBuf& org, const CPelBuf& rec, double &sumAct,
const uint32_t imageWidth, const uint32_t imageHeight, const uint32_t offsetX, const uint32_t offsetY, int blockWidth, int blockHeight)
static inline double calcWeightedSquaredError(const CPelBuf& org, const CPelBuf& rec,
double &sumAct, const uint32_t bitDepth,
const uint32_t imageWidth, const uint32_t imageHeight,
const uint32_t offsetX, const uint32_t offsetY,
int blockWidth, int blockHeight)
{
const int O = org.stride;
const int R = rec.stride;
......@@ -2850,8 +2857,8 @@ static inline double calcWeightedSquaredError(const CPelBuf& org, const CPelB
const int hAct = offsetY + (uint32_t)blockHeight < imageHeight ? blockHeight : blockHeight - 1;
const int wAct = offsetX + (uint32_t)blockWidth < imageWidth ? blockWidth : blockWidth - 1;
uint64_t ssErr = 0; // sum of squared diffs
uint64_t saAct = 0; // sum of abs. activity
uint64_t ssErr = 0; // sum of squared diffs
uint64_t saAct = 0; // sum of abs. activity
double msAct;
int x, y;
......@@ -2860,7 +2867,7 @@ static inline double calcWeightedSquaredError(const CPelBuf& org, const CPelB
{
for (x = 0; x < blockWidth; x++)
{
register int64_t iDiff = (int64_t)o[y*O + x] - (int64_t)r[y*R + x];
const int64_t iDiff = (int64_t)o[y*O + x] - (int64_t)r[y*R + x];
ssErr += uint64_t(iDiff * iDiff);
}
}
......@@ -2870,13 +2877,18 @@ static inline double calcWeightedSquaredError(const CPelBuf& org, const CPelB
{
for (x = xAct; x < wAct; x++)
{
saAct += uint64_t(abs(4 * (int64_t)o[y*O + x] - (int64_t)o[y*O + x-1] - (int64_t)o[y*O + x+1] - (int64_t)o[(y-1)*O + x] - (int64_t)o[(y+1)*O + x]));
const int f = 12 * (int)o[y*O + x] - 2 * ((int)o[y*O + x-1] + (int)o[y*O + x+1] + (int)o[(y-1)*O + x] + (int)o[(y+1)*O + x])
- (int)o[(y-1)*O + x-1] - (int)o[(y-1)*O + x+1] - (int)o[(y+1)*O + x-1] - (int)o[(y+1)*O + x+1];
saAct += abs(f);
}
}
// calculate weight (mean squared activity)
msAct = (double)saAct / (double(wAct - xAct) * double(hAct - yAct));
if (msAct < 8.0) msAct = 8.0;
// lower limit, accounts for high-pass gain
if (msAct < double(1 << (bitDepth - 4))) msAct = double(1 << (bitDepth - 4));
msAct *= msAct; // because ssErr is squared
sumAct += msAct; // includes high-pass gain
......@@ -2888,9 +2900,9 @@ static inline double calcWeightedSquaredError(const CPelBuf& org, const CPelB
uint64_t EncGOP::xFindDistortionPlane(const CPelBuf& pic0, const CPelBuf& pic1, const uint32_t rshift
#if ENABLE_QPA
, const uint32_t chromaShift /*= 0*/
, const uint32_t chromaShift /*= 0*/
#endif
)
)
{
uint64_t uiTotalDiff;
const Pel* pSrc0 = pic0.bufAt(0, 0);
......@@ -2907,7 +2919,7 @@ uint64_t EncGOP::xFindDistortionPlane(const CPelBuf& pic0, const CPelBuf& pic1,
{
const uint32_t W = pic0.width; // image width
const uint32_t H = pic0.height; // image height
const double R = double(W * H) / (1920.0 * 1080.0);
const double R = double(W * H) / (1920.0 * 1080.0);
const uint32_t B = Clip3<uint32_t>(0, 128 >> chromaShift, 4 * uint32_t(16.0 * sqrt(R) + 0.5)); // WPSNR block size in integer multiple of 4 (for SIMD, = 64 at full-HD)
uint32_t x, y;
......@@ -2919,7 +2931,7 @@ uint64_t EncGOP::xFindDistortionPlane(const CPelBuf& pic0, const CPelBuf& pic1,
{
for (x = 0; x < W; x++)
{
register int64_t iDiff = (int64_t)pSrc0[x] - (int64_t)pSrc1[x];
const int64_t iDiff = (int64_t)pSrc0[x] - (int64_t)pSrc1[x];
uiTotalDiff += uint64_t(iDiff * iDiff);
}
pSrc0 += pic0.stride;
......@@ -2936,7 +2948,11 @@ uint64_t EncGOP::xFindDistortionPlane(const CPelBuf& pic0, const CPelBuf& pic1,
{
for (x = 0; x < W; x += B)
{
wmse += calcWeightedSquaredError(pic1, pic0, sumAct, W, H, x, y, B, B);
wmse += calcWeightedSquaredError(pic1, pic0,
sumAct, BD,
W, H,
x, y,
B, B);
#if !GLOBAL_AVERAGING
numAct += 1.0;
#endif
......@@ -2945,11 +2961,17 @@ uint64_t EncGOP::xFindDistortionPlane(const CPelBuf& pic0, const CPelBuf& pic1,
// integer weighted distortion
#if GLOBAL_AVERAGING
sumAct = 1.5 * double(1 << BD);
if ((W << chromaShift) > 2048 && (H << chromaShift) > 1280) // UHD luma
sumAct = 32.0 * double(1 << BD);
if ((W << chromaShift) > 2048 && (H << chromaShift) > 1280) // for UHD/4K
{
sumAct /= 1.5;
sumAct *= 0.5;
}
else if ((W << chromaShift) <= 1024 || (H << chromaShift) <= 640) // 480p
{
sumAct *= 2.0;
}
return (wmse <= 0.0) ? 0 : uint64_t(wmse * pow(sumAct, BETA) + 0.5);
#else
return (wmse <= 0.0 || numAct <= 0.0) ? 0 : uint64_t(wmse * pow(sumAct / numAct, BETA) + 0.5);
......@@ -2986,7 +3008,7 @@ uint64_t EncGOP::xFindDistortionPlane(const CPelBuf& pic0, const CPelBuf& pic1,
return uiTotalDiff;
}
#if WCG_WPSNR
double EncGOP::xFindDistortionPlaneWPSNR(const CPelBuf& pic0, const CPelBuf& pic1, const uint32_t rshift, const CPelBuf& picLuma0,
double EncGOP::xFindDistortionPlaneWPSNR(const CPelBuf& pic0, const CPelBuf& pic1, const uint32_t rshift, const CPelBuf& picLuma0,
ComponentID compID, const ChromaFormat chfmt )
{
const bool useLumaWPSNR = m_pcEncLib->getLumaLevelToDeltaQPMapping().isEnabled();
......@@ -3176,7 +3198,7 @@ void EncGOP::xCalculateAddPSNR( Picture* pcPic, PelUnitBuf cPicD, const AccessUn
#else
const uint64_t uiSSDtemp = xFindDistortionPlane(recPB, orgPB, 0);
#if WCG_WPSNR
const double uiSSDtempWeighted = xFindDistortionPlaneWPSNR(recPB, orgPB, 0, org.get(COMPONENT_Y), compID, format);
const double uiSSDtempWeighted = xFindDistortionPlaneWPSNR(recPB, orgPB, 0, org.get(COMPONENT_Y), compID, format);
#endif
const uint32_t maxval = 255 << (bitDepth - 8);
#endif
......
......@@ -975,7 +975,7 @@ void EncLib::xInitSPS(SPS &sps)
sps.setMaxTLayers( m_maxTempLayer );
sps.setTemporalIdNestingFlag( ( m_maxTempLayer == 1 ) ? true : false );
for (int i = 0; i < min(sps.getMaxTLayers(),(uint32_t) MAX_TLAYER); i++ )
for (int i = 0; i < std::min(sps.getMaxTLayers(), (uint32_t) MAX_TLAYER); i++ )
{
sps.setMaxDecPicBuffering(m_maxDecPicBuffering[i], i);
sps.setNumReorderPics(m_numReorderPics[i], i);
......@@ -1265,7 +1265,7 @@ void EncLib::xInitPPS(PPS &pps, const SPS &sps)
if (getUsePerceptQPA() && !bUseDQP)
{
CHECK( m_iMaxCuDQPDepth != 0, "max. delta-QP depth must be zero!" );
bUseDQP = true;
bUseDQP = (getBaseQP() < 38) && (getSourceWidth() > 512 || getSourceHeight() > 320);
}
#endif
......@@ -1359,9 +1359,15 @@ void EncLib::xInitPPS(PPS &pps, const SPS &sps)
}
}
}
#if ENABLE_QPA
if ((getUsePerceptQPA() || getSliceChromaOffsetQpPeriodicity() > 0) && (getChromaFormatIdc() != CHROMA_400))
{
bChromaDeltaQPEnabled = true;
}
#endif
pps.setSliceChromaQpFlag(bChromaDeltaQPEnabled);
#endif
if (!pps.getSliceChromaQpFlag() && sps.getSpsNext().getUseDualITree())
if (!pps.getSliceChromaQpFlag() && sps.getSpsNext().getUseDualITree() && (getChromaFormatIdc() != CHROMA_400))
{
pps.setSliceChromaQpFlag(m_chromaCbQpOffsetDualTree != 0 || m_chromaCrQpOffsetDualTree != 0);
}
......
This diff is collapsed.
......@@ -109,7 +109,7 @@ public:
int getGopId() const { return m_gopID; }
double calculateLambda( const Slice* slice, const int GOPid, const int depth, const double refQP, const double dQP, int &iQP );
void setUpLambda( Slice* slice, const double dLambda, int iQP );
private:
#endif
#if HEVC_TILES_WPP
......@@ -120,6 +120,10 @@ private:
public:
#if ENABLE_QPA
int m_adaptedLumaQP;
#endif
EncSlice();
virtual ~EncSlice();
......
......@@ -413,24 +413,25 @@ static bool readPlane(Pel* dst,
* @param fileBitDepth component bit depth in file
* @return true for success, false in case of error
*/
static bool writePlane(ostream& fd, const Pel* src, bool is16bit,
static bool writePlane(ostream& fd, const Pel* src,
const bool is16bit,
const uint32_t stride_src,
uint32_t width444, uint32_t height444,
const ComponentID compID,
const ChromaFormat srcFormat,
const ChromaFormat fileFormat,
const int fileBitDepth)
const uint32_t fileBitDepth,
const uint32_t packedYUVOutputMode = 0</