diff --git a/doc/software-manual.tex b/doc/software-manual.tex index 37399da94ca4334508f82c4929efbd01e81c4bfb..4fa74935d3adf4231daf789a6da3c2c2727030a8 100644 --- a/doc/software-manual.tex +++ b/doc/software-manual.tex @@ -2798,13 +2798,6 @@ When true, specifies the use of the cross component prediction tool (4:4:4 proce If true, then when determining the alpha value for cross-component prediction, use the reconstructed residual rather than the pre-transform encoder-side residual \\ -\Option{SaoLumaOffsetBitShift} -\Option{SaoChromaOffsetBitShift}& -\Default{0} -\Default{0} & -Specifies the shift to apply to the SAO parameters. If negative, an estimate will be calculated based upon the initial QP. Version 1 and some Version 2 (RExt) profiles require this to be 0. -\\ - \Option{TransformSkipLog2MaxSize} & \Default{2} & Specifies the maximum TU size for which transform-skip can be used; the minimum value is 2. Version 1 and some Version 2 (RExt) profiles require this to be 2. diff --git a/source/App/EncoderApp/EncApp.cpp b/source/App/EncoderApp/EncApp.cpp index 3fa5065a9ae66b35ba2365657c20b9e6b981412e..bd2cf130a933949d4ff411a673b5c992eaf08d14 100644 --- a/source/App/EncoderApp/EncApp.cpp +++ b/source/App/EncoderApp/EncApp.cpp @@ -536,8 +536,10 @@ void EncApp::xInitLibCfg() m_cEncLib.setFastLocalDualTreeMode ( m_fastLocalDualTreeMode ); m_cEncLib.setCrossComponentPredictionEnabledFlag ( m_crossComponentPredictionEnabledFlag ); m_cEncLib.setUseReconBasedCrossCPredictionEstimate ( m_reconBasedCrossCPredictionEstimate ); +#if !JVET_Q0441_SAO_MOD_12_BIT m_cEncLib.setLog2SaoOffsetScale ( CHANNEL_TYPE_LUMA , m_log2SaoOffsetScale[CHANNEL_TYPE_LUMA] ); m_cEncLib.setLog2SaoOffsetScale ( CHANNEL_TYPE_CHROMA, m_log2SaoOffsetScale[CHANNEL_TYPE_CHROMA] ); +#endif m_cEncLib.setUseTransformSkip ( m_useTransformSkip ); m_cEncLib.setUseTransformSkipFast ( m_useTransformSkipFast ); m_cEncLib.setUseChromaTS ( m_useChromaTS && m_useTransformSkip); diff --git a/source/App/EncoderApp/EncAppCfg.cpp b/source/App/EncoderApp/EncAppCfg.cpp index 929dcd0b5dd673f8f7699197b4591185a7e358d7..ef84f009f060fe337ea9e032b0653d4476ead5b5 100644 --- a/source/App/EncoderApp/EncAppCfg.cpp +++ b/source/App/EncoderApp/EncAppCfg.cpp @@ -658,7 +658,9 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) string inputColourSpaceConvert; string inputPathPrefix; ExtendedProfileName extendedProfile; +#if !JVET_Q0441_SAO_MOD_12_BIT int saoOffsetBitShift[MAX_NUM_CHANNEL_TYPE]; +#endif // Multi-value input fields: // minval, maxval (incl), min_entries, max_entries (incl) [, default values, number of default values] SMultiValueInput<uint32_t> cfgTileColumnWidth (0, std::numeric_limits<uint32_t>::max(), 0, std::numeric_limits<uint32_t>::max()); @@ -1141,8 +1143,10 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) // Coding tools ("CrossComponentPrediction", m_crossComponentPredictionEnabledFlag, false, "Enable the use of cross-component prediction (not valid in V1 profiles)") ("ReconBasedCrossCPredictionEstimate", m_reconBasedCrossCPredictionEstimate, false, "When determining the alpha value for cross-component prediction, use the decoded residual rather than the pre-transform encoder-side residual") +#if !JVET_Q0441_SAO_MOD_12_BIT ("SaoLumaOffsetBitShift", saoOffsetBitShift[CHANNEL_TYPE_LUMA], 0, "Specify the luma SAO bit-shift. If negative, automatically calculate a suitable value based upon bit depth and initial QP") ("SaoChromaOffsetBitShift", saoOffsetBitShift[CHANNEL_TYPE_CHROMA], 0, "Specify the chroma SAO bit-shift. If negative, automatically calculate a suitable value based upon bit depth and initial QP") +#endif ("TransformSkip", m_useTransformSkip, false, "Intra transform skipping") ("TransformSkipFast", m_useTransformSkipFast, false, "Fast encoder search for transform skipping, winner takes it all mode.") ("TransformSkipLog2MaxSize", m_log2MaxTransformSkipBlockSize, 5U, "Specify transform-skip maximum size. Minimum 2, Maximum 5. (not valid in V1 profiles)") @@ -1899,6 +1903,7 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) } #endif +#if !JVET_Q0441_SAO_MOD_12_BIT for(uint32_t ch=0; ch<MAX_NUM_CHANNEL_TYPE; ch++) { if (saoOffsetBitShift[ch]<0) @@ -1917,6 +1922,7 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) m_log2SaoOffsetScale[ch]=uint32_t(saoOffsetBitShift[ch]); } } +#endif #if SHARP_LUMA_DELTA_QP CHECK( lumaLevelToDeltaQPMode >= LUMALVL_TO_DQP_NUM_MODES, "Error in cfg" ); @@ -2425,8 +2431,10 @@ bool EncAppCfg::xCheckParameter() xConfirmPara( (m_MSBExtendedBitDepth[CHANNEL_TYPE_LUMA ] < m_inputBitDepth[CHANNEL_TYPE_LUMA ]), "MSB-extended bit depth for luma channel (--MSBExtendedBitDepth) must be greater than or equal to input bit depth for luma channel (--InputBitDepth)" ); xConfirmPara( (m_MSBExtendedBitDepth[CHANNEL_TYPE_CHROMA] < m_inputBitDepth[CHANNEL_TYPE_CHROMA]), "MSB-extended bit depth for chroma channel (--MSBExtendedBitDepthC) must be greater than or equal to input bit depth for chroma channel (--InputBitDepthC)" ); +#if !JVET_Q0441_SAO_MOD_12_BIT xConfirmPara( m_log2SaoOffsetScale[CHANNEL_TYPE_LUMA] > (m_internalBitDepth[CHANNEL_TYPE_LUMA ]<10?0:(m_internalBitDepth[CHANNEL_TYPE_LUMA ]-10)), "SaoLumaOffsetBitShift must be in the range of 0 to InternalBitDepth-10, inclusive"); xConfirmPara( m_log2SaoOffsetScale[CHANNEL_TYPE_CHROMA] > (m_internalBitDepth[CHANNEL_TYPE_CHROMA]<10?0:(m_internalBitDepth[CHANNEL_TYPE_CHROMA]-10)), "SaoChromaOffsetBitShift must be in the range of 0 to InternalBitDepth-10, inclusive"); +#endif xConfirmPara( m_chromaFormatIDC >= NUM_CHROMA_FORMAT, "ChromaFormatIDC must be either 400, 420, 422 or 444" ); std::string sTempIPCSC="InputColourSpaceConvert must be empty, "+getListOfColourSpaceConverts(true); @@ -3720,11 +3728,13 @@ void EncAppCfg::xPrintParameter() msg( DETAILS, "high_precision_offsets_enabled_flag : %s\n", (m_highPrecisionOffsetsEnabledFlag ? "Enabled" : "Disabled") ); msg( DETAILS, "persistent_rice_adaptation_enabled_flag: %s\n", (m_persistentRiceAdaptationEnabledFlag ? "Enabled" : "Disabled") ); msg( DETAILS, "cabac_bypass_alignment_enabled_flag : %s\n", (m_cabacBypassAlignmentEnabledFlag ? "Enabled" : "Disabled") ); +#if !JVET_Q0441_SAO_MOD_12_BIT if (m_bUseSAO) { msg( DETAILS, "log2_sao_offset_scale_luma : %d\n", m_log2SaoOffsetScale[CHANNEL_TYPE_LUMA] ); msg( DETAILS, "log2_sao_offset_scale_chroma : %d\n", m_log2SaoOffsetScale[CHANNEL_TYPE_CHROMA] ); } +#endif switch (m_costMode) { diff --git a/source/App/EncoderApp/EncAppCfg.h b/source/App/EncoderApp/EncAppCfg.h index 198a5bc67a08df9db5e868fb9127d383c69e66a6..aa70f7bde31d81ef063512f9b98db55f22ebce24 100644 --- a/source/App/EncoderApp/EncAppCfg.h +++ b/source/App/EncoderApp/EncAppCfg.h @@ -214,7 +214,9 @@ protected: int m_maxDecPicBuffering[MAX_TLAYER]; ///< total number of pictures in the decoded picture buffer bool m_crossComponentPredictionEnabledFlag; ///< flag enabling the use of cross-component prediction bool m_reconBasedCrossCPredictionEstimate; ///< causes the alpha calculation in encoder search to be based on the decoded residual rather than the pre-transform encoder-side residual +#if !JVET_Q0441_SAO_MOD_12_BIT uint32_t m_log2SaoOffsetScale[MAX_NUM_CHANNEL_TYPE]; ///< number of bits for the upward bit shift operation on the decoded SAO offsets +#endif bool m_useTransformSkip; ///< flag for enabling intra transform skipping bool m_useTransformSkipFast; ///< flag for enabling fast intra transform skipping #if JVET_Q0089_SLICE_LOSSLESS_CODING_CHROMA_BDPCM diff --git a/source/Lib/CommonLib/Slice.cpp b/source/Lib/CommonLib/Slice.cpp index a0c5ad62daf2eb12ba5b6c5984a393f4f321001d..d2a9a02f99c57995581ea48fbde0e7e15fdfa327 100644 --- a/source/Lib/CommonLib/Slice.cpp +++ b/source/Lib/CommonLib/Slice.cpp @@ -2313,12 +2313,16 @@ SubPic::~SubPic() PPSRExt::PPSRExt() : m_crossComponentPredictionEnabledFlag(false) +#if JVET_Q0441_SAO_MOD_12_BIT +{ +#else // m_log2SaoOffsetScale initialized below { for(int ch=0; ch<MAX_NUM_CHANNEL_TYPE; ch++) { m_log2SaoOffsetScale[ch] = 0; } +#endif } PPS::PPS() diff --git a/source/Lib/CommonLib/Slice.h b/source/Lib/CommonLib/Slice.h index 374d6be31194e0e722cf7c020970470e1db8b7be..59ce4d95e922bcd72b98ae33696c1443bf036ea7 100644 --- a/source/Lib/CommonLib/Slice.h +++ b/source/Lib/CommonLib/Slice.h @@ -1691,30 +1691,37 @@ void setCCALFEnabledFlag( bool b ) /// PPS RExt class -class PPSRExt // Names aligned to text specification +class PPSRExt // TODO: remove { private: bool m_crossComponentPredictionEnabledFlag; +#if !JVET_Q0441_SAO_MOD_12_BIT uint32_t m_log2SaoOffsetScale[MAX_NUM_CHANNEL_TYPE]; +#endif public: PPSRExt(); bool settingsDifferFromDefaults(const bool bTransformSkipEnabledFlag) const { +#if JVET_Q0441_SAO_MOD_12_BIT + return (getCrossComponentPredictionEnabledFlag() ); +#else return (getCrossComponentPredictionEnabledFlag() ) || (getLog2SaoOffsetScale(CHANNEL_TYPE_LUMA) !=0 ) || (getLog2SaoOffsetScale(CHANNEL_TYPE_CHROMA) !=0 ); +#endif } bool getCrossComponentPredictionEnabledFlag() const { return m_crossComponentPredictionEnabledFlag; } void setCrossComponentPredictionEnabledFlag(bool value) { m_crossComponentPredictionEnabledFlag = value; } +#if !JVET_Q0441_SAO_MOD_12_BIT // Now: getPpsRangeExtension().getLog2SaoOffsetScale and getPpsRangeExtension().setLog2SaoOffsetScale uint32_t getLog2SaoOffsetScale(ChannelType type) const { return m_log2SaoOffsetScale[type]; } void setLog2SaoOffsetScale(ChannelType type, uint32_t uiBitShift) { m_log2SaoOffsetScale[type] = uiBitShift; } - +#endif }; diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index fefa0ba8ec6f9fbf7b8e04ef8fe8e81ab65a8f82..7d2c35e88de35addc4118976f88184a6945d1a97 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -88,6 +88,8 @@ #define JVET_Q0438_MONOCHROME_BUGFIXES 1 // JVET-Q0438: Monochrome bug fixes +#define JVET_Q0441_SAO_MOD_12_BIT 1 // JVET-Q0441: SAO modification for 12 bit. Also removes old HEVC RExt SAO modification, which was broken. + #define JVET_Q0043_RPR_and_Subpics 1 // JVET-Q0043: Disallow for both RPR and subpics to be used together #define JVET_Q0818_PT_SEI 1 // JVET-Q0818: add display_elemental_periods_minus1 to picture timing SEI message diff --git a/source/Lib/DecoderLib/DecLib.cpp b/source/Lib/DecoderLib/DecLib.cpp index 2fc546880a9fc272cd9bf47cd92eb6393d54c50b..89c2df41e4a4be77709eaa78dd38dc566f21c06a 100644 --- a/source/Lib/DecoderLib/DecLib.cpp +++ b/source/Lib/DecoderLib/DecLib.cpp @@ -1119,7 +1119,17 @@ void DecLib::xActivateParameterSets( const int layerId ) m_pcPic->cs->pcv = pps->pcv; // Initialise the various objects for the new set of settings +#if JVET_Q0441_SAO_MOD_12_BIT + const uint32_t log2SaoOffsetScaleLuma = (uint32_t) std::max(0, sps->getBitDepth(CHANNEL_TYPE_LUMA ) - MAX_SAO_TRUNCATED_BITDEPTH); + const uint32_t log2SaoOffsetScaleChroma = (uint32_t) std::max(0, sps->getBitDepth(CHANNEL_TYPE_CHROMA) - MAX_SAO_TRUNCATED_BITDEPTH); + m_cSAO.create( pps->getPicWidthInLumaSamples(), pps->getPicHeightInLumaSamples(), + sps->getChromaFormatIdc(), + sps->getMaxCUWidth(), sps->getMaxCUHeight(), + sps->getMaxCodingDepth(), + log2SaoOffsetScaleLuma, log2SaoOffsetScaleChroma ); +#else m_cSAO.create( pps->getPicWidthInLumaSamples(), pps->getPicHeightInLumaSamples(), sps->getChromaFormatIdc(), sps->getMaxCUWidth(), sps->getMaxCUHeight(), sps->getMaxCodingDepth(), pps->getPpsRangeExtension().getLog2SaoOffsetScale( CHANNEL_TYPE_LUMA ), pps->getPpsRangeExtension().getLog2SaoOffsetScale( CHANNEL_TYPE_CHROMA ) ); +#endif m_cLoopFilter.create( sps->getMaxCodingDepth() ); m_cIntraPred.init( sps->getChromaFormatIdc(), sps->getBitDepth( CHANNEL_TYPE_LUMA ) ); m_cInterPred.init( &m_cRdCost, sps->getChromaFormatIdc(), sps->getMaxCUHeight() ); diff --git a/source/Lib/DecoderLib/VLCReader.cpp b/source/Lib/DecoderLib/VLCReader.cpp index 9521cf57cece5c52e8d374d7c0e4791a4a0fe06c..c3b6a087abfc3f13c5f416e724b153dc65997804 100644 --- a/source/Lib/DecoderLib/VLCReader.cpp +++ b/source/Lib/DecoderLib/VLCReader.cpp @@ -854,11 +854,12 @@ void HLSyntaxReader::parsePPS( PPS* pcPPS, ParameterSetManager *parameterSetMana READ_FLAG( uiCode, "cross_component_prediction_enabled_flag"); ppsRangeExtension.setCrossComponentPredictionEnabledFlag(uiCode != 0); - +#if !JVET_Q0441_SAO_MOD_12_BIT READ_UVLC( uiCode, "log2_sao_offset_scale_luma"); ppsRangeExtension.setLog2SaoOffsetScale(CHANNEL_TYPE_LUMA, uiCode); READ_UVLC( uiCode, "log2_sao_offset_scale_chroma"); ppsRangeExtension.setLog2SaoOffsetScale(CHANNEL_TYPE_CHROMA, uiCode); +#endif } break; default: diff --git a/source/Lib/EncoderLib/EncCfg.h b/source/Lib/EncoderLib/EncCfg.h index f38c05ff486cf3f98ffb08f81336be5eb06119b5..e1752c81ecc00ea5ef0ef708ab69f44bc7e1a061 100644 --- a/source/Lib/EncoderLib/EncCfg.h +++ b/source/Lib/EncoderLib/EncCfg.h @@ -476,7 +476,9 @@ protected: bool m_useEarlySkipDetection; bool m_crossComponentPredictionEnabledFlag; bool m_reconBasedCrossCPredictionEstimate; +#if !JVET_Q0441_SAO_MOD_12_BIT uint32_t m_log2SaoOffsetScale[MAX_NUM_CHANNEL_TYPE]; +#endif bool m_useTransformSkip; bool m_useTransformSkipFast; bool m_useChromaTS; @@ -1393,7 +1395,9 @@ public: void setCrossComponentPredictionEnabledFlag (const bool value) { m_crossComponentPredictionEnabledFlag = value; } bool getUseReconBasedCrossCPredictionEstimate () const { return m_reconBasedCrossCPredictionEstimate; } void setUseReconBasedCrossCPredictionEstimate (const bool value) { m_reconBasedCrossCPredictionEstimate = value; } +#if !JVET_Q0441_SAO_MOD_12_BIT void setLog2SaoOffsetScale(ChannelType type, uint32_t uiBitShift) { m_log2SaoOffsetScale[type] = uiBitShift; } +#endif bool getUseTransformSkip () { return m_useTransformSkip; } void setUseTransformSkip ( bool b ) { m_useTransformSkip = b; } diff --git a/source/Lib/EncoderLib/EncGOP.cpp b/source/Lib/EncoderLib/EncGOP.cpp index e415c7d6a883945e4c164f9ad7bb0caef966e66b..4cbfa532a8a12de66640441f4f3993f741ca9ea2 100644 --- a/source/Lib/EncoderLib/EncGOP.cpp +++ b/source/Lib/EncoderLib/EncGOP.cpp @@ -2834,9 +2834,13 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic, const uint32_t widthInCtus = ( picWidth + maxCUWidth - 1 ) / maxCUWidth; const uint32_t heightInCtus = ( picHeight + maxCUHeight - 1 ) / maxCUHeight; const uint32_t numCtuInFrame = widthInCtus * heightInCtus; - +#if JVET_Q0441_SAO_MOD_12_BIT + const uint32_t log2SaoOffsetScaleLuma = (uint32_t) std::max(0, pcSlice->getSPS()->getBitDepth(CHANNEL_TYPE_LUMA ) - MAX_SAO_TRUNCATED_BITDEPTH); + const uint32_t log2SaoOffsetScaleChroma = (uint32_t) std::max(0, pcSlice->getSPS()->getBitDepth(CHANNEL_TYPE_CHROMA) - MAX_SAO_TRUNCATED_BITDEPTH); +#else const uint32_t log2SaoOffsetScaleLuma = pcPic->cs->slice->getPPS()->getPpsRangeExtension().getLog2SaoOffsetScale( CHANNEL_TYPE_LUMA ); const uint32_t log2SaoOffsetScaleChroma = pcPic->cs->slice->getPPS()->getPpsRangeExtension().getLog2SaoOffsetScale( CHANNEL_TYPE_CHROMA ); +#endif m_pcSAO->create( picWidth, picHeight, chromaFormatIDC, maxCUWidth, maxCUHeight, maxTotalCUDepth, log2SaoOffsetScaleLuma, log2SaoOffsetScaleChroma ); m_pcSAO->destroyEncData(); diff --git a/source/Lib/EncoderLib/EncLib.cpp b/source/Lib/EncoderLib/EncLib.cpp index f5661cb03418b4d232f368e60bb9de417edb5245..88386782a47484d325bd26bf34c6f35a7a4db37c 100644 --- a/source/Lib/EncoderLib/EncLib.cpp +++ b/source/Lib/EncoderLib/EncLib.cpp @@ -1632,8 +1632,10 @@ void EncLib::xInitPPS(PPS &pps, const SPS &sps) pps.clearChromaQpOffsetList(); } pps.getPpsRangeExtension().setCrossComponentPredictionEnabledFlag(m_crossComponentPredictionEnabledFlag); +#if !JVET_Q0441_SAO_MOD_12_BIT pps.getPpsRangeExtension().setLog2SaoOffsetScale(CHANNEL_TYPE_LUMA, m_log2SaoOffsetScale[CHANNEL_TYPE_LUMA ]); pps.getPpsRangeExtension().setLog2SaoOffsetScale(CHANNEL_TYPE_CHROMA, m_log2SaoOffsetScale[CHANNEL_TYPE_CHROMA]); +#endif { int baseQp = 26; diff --git a/source/Lib/EncoderLib/VLCWriter.cpp b/source/Lib/EncoderLib/VLCWriter.cpp index 1f0f1b672f8f246bd7d4cd543f477c0374fc3d5f..d5a49a9108b829720e5cde545236b14fb5ec2e75 100644 --- a/source/Lib/EncoderLib/VLCWriter.cpp +++ b/source/Lib/EncoderLib/VLCWriter.cpp @@ -515,9 +515,10 @@ void HLSWriter::codePPS( const PPS* pcPPS, const SPS* pcSPS ) const PPSRExt &ppsRangeExtension = pcPPS->getPpsRangeExtension(); WRITE_FLAG((ppsRangeExtension.getCrossComponentPredictionEnabledFlag() ? 1 : 0), "cross_component_prediction_enabled_flag" ); - +#if !JVET_Q0441_SAO_MOD_12_BIT WRITE_UVLC( ppsRangeExtension.getLog2SaoOffsetScale(CHANNEL_TYPE_LUMA), "log2_sao_offset_scale_luma" ); WRITE_UVLC( ppsRangeExtension.getLog2SaoOffsetScale(CHANNEL_TYPE_CHROMA), "log2_sao_offset_scale_chroma" ); +#endif } break; default: