diff --git a/source/Lib/CommonLib/Slice.h b/source/Lib/CommonLib/Slice.h index ebc1aaed370b5188ee2286cc15e8d8fe83854095..646822421b4cb3d72295733c5b29ad5dd1aff855 100644 --- a/source/Lib/CommonLib/Slice.h +++ b/source/Lib/CommonLib/Slice.h @@ -1180,6 +1180,9 @@ private: int m_chromaCbQpOffset; int m_chromaCrQpOffset; +#if JVET_P0667_QP_OFFSET_TABLE_SIGNALING_JCCR + bool m_chromaJointCbCrQpOffsetPresentFlag; +#endif int m_chromaCbCrQpOffset; // Chroma QP Adjustments @@ -1293,6 +1296,11 @@ public: void setCuQpDeltaSubdiv( uint32_t u ) { m_cuQpDeltaSubdiv = u; } uint32_t getCuQpDeltaSubdiv() const { return m_cuQpDeltaSubdiv; } +#if JVET_P0667_QP_OFFSET_TABLE_SIGNALING_JCCR + bool getJointCbCrQpOffsetPresentFlag() const { return m_chromaJointCbCrQpOffsetPresentFlag; } + void setJointCbCrQpOffsetPresentFlag(bool b) { m_chromaJointCbCrQpOffsetPresentFlag = b; } +#endif + void setQpOffset(ComponentID compID, int i ) { if (compID==COMPONENT_Cb) diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index 99c4419c46216ba58ce02fe053f49f8cec6104d0..76b56798687c40f695eea4b255a5ee8853cfbbf7 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -50,6 +50,8 @@ #include <assert.h> #include <cassert> +#define JVET_P0667_QP_OFFSET_TABLE_SIGNALING_JCCR 1 // JVET-P0667: removing signaling of qp offset table for JCCR, at SPS and PPS, when JCCR is disabled. + #define JVET_P0298_DISABLE_LEVELMAPPING_IN_BYPASS 1 // JVET-P0298: Disable level mapping in bypass mode #define JVET_P0347_MAX_MTT_DEPTH_CONSTRAINT 1 // JVET-P0347: Max MTT Depth constraint diff --git a/source/Lib/DecoderLib/VLCReader.cpp b/source/Lib/DecoderLib/VLCReader.cpp index 364601e3b80b0c5c66fc405e0e14a4f7af535a99..d11de7ca177f051d117bfdf3105d7f034b6f9a79 100644 --- a/source/Lib/DecoderLib/VLCReader.cpp +++ b/source/Lib/DecoderLib/VLCReader.cpp @@ -453,8 +453,23 @@ void HLSyntaxReader::parsePPS( PPS* pcPPS, ParameterSetManager *parameterSetMana CHECK( pcPPS->getQpOffset(COMPONENT_Cr) < -12, "Invalid Cr QP offset" ); CHECK( pcPPS->getQpOffset(COMPONENT_Cr) > 12, "Invalid Cr QP offset" ); +#if JVET_P0667_QP_OFFSET_TABLE_SIGNALING_JCCR + READ_FLAG(uiCode, "pps_joint_cbcr_qp_offset_present_flag"); + pcPPS->setJointCbCrQpOffsetPresentFlag(uiCode ? true : false); + + if (pcPPS->getJointCbCrQpOffsetPresentFlag()) + { + READ_SVLC(iCode, "pps_joint_cbcr_qp_offset"); + } + else + { + iCode = 0; + } +#else READ_SVLC( iCode, "pps_joint_cbcr_qp_offset"); +#endif pcPPS->setQpOffset(JOINT_CbCr, iCode); + CHECK( pcPPS->getQpOffset(JOINT_CbCr) < -12, "Invalid CbCr QP offset" ); CHECK( pcPPS->getQpOffset(JOINT_CbCr) > 12, "Invalid CbCr QP offset" ); @@ -485,7 +500,18 @@ void HLSyntaxReader::parsePPS( PPS* pcPPS, ParameterSetManager *parameterSetMana CHECK(cbOffset < -12 || cbOffset > 12, "Invalid chroma QP offset"); READ_SVLC(crOffset, "cr_qp_offset_list[i]"); CHECK(crOffset < -12 || crOffset > 12, "Invalid chroma QP offset"); +#if JVET_P0667_QP_OFFSET_TABLE_SIGNALING_JCCR + if (pcPPS->getJointCbCrQpOffsetPresentFlag()) + { + READ_SVLC(jointCbCrOffset, "joint_cbcr_qp_offset_list[i]"); + } + else + { + jointCbCrOffset = 0; + } +#else READ_SVLC(jointCbCrOffset, "joint_cbcr_qp_offset_list[i]"); +#endif CHECK(jointCbCrOffset < -12 || jointCbCrOffset > 12, "Invalid chroma QP offset"); // table uses +1 for index (see comment inside the function) pcPPS->setChromaQpOffsetListEntry(cuChromaQpOffsetIdx + 1, cbOffset, crOffset, jointCbCrOffset); @@ -1329,11 +1355,19 @@ void HLSyntaxReader::parseSPS(SPS* pcSPS) READ_FLAG( uiCode, "sps_max_luma_transform_size_64_flag"); pcSPS->setLog2MaxTbSize( (uiCode ? 1 : 0) + 5 ); +#if JVET_P0667_QP_OFFSET_TABLE_SIGNALING_JCCR + READ_FLAG(uiCode, "sps_joint_cbcr_enabled_flag"); pcSPS->setJointCbCrEnabledFlag(uiCode ? true : false); +#endif if (pcSPS->getChromaFormatIdc() != CHROMA_400) { ChromaQpMappingTableParams chromaQpMappingTableParams; READ_FLAG(uiCode, "same_qp_table_for_chroma"); chromaQpMappingTableParams.setSameCQPTableForAllChromaFlag(uiCode); +#if JVET_P0667_QP_OFFSET_TABLE_SIGNALING_JCCR + int numQPTables = chromaQpMappingTableParams.getSameCQPTableForAllChromaFlag() ? 1 : (pcSPS->getJointCbCrEnabledFlag() ? 3 : 2); + for (int i = 0; i < numQPTables; i++) +#else for (int i = 0; i < (chromaQpMappingTableParams.getSameCQPTableForAllChromaFlag() ? 1 : 3); i++) +#endif { READ_UVLC(uiCode, "num_points_in_qp_table_minus1"); chromaQpMappingTableParams.setNumPtsInCQPTableMinus1(i,uiCode); std::vector<int> deltaQpInValMinus1(chromaQpMappingTableParams.getNumPtsInCQPTableMinus1(i) + 1); @@ -1350,6 +1384,7 @@ void HLSyntaxReader::parseSPS(SPS* pcSPS) pcSPS->derivedChromaQPMappingTables(); } + READ_FLAG( uiCode, "sps_sao_enabled_flag" ); pcSPS->setSAOEnabledFlag ( uiCode ? true : false ); READ_FLAG( uiCode, "sps_alf_enabled_flag" ); pcSPS->setALFEnabledFlag ( uiCode ? true : false ); @@ -1358,7 +1393,9 @@ void HLSyntaxReader::parseSPS(SPS* pcSPS) { READ_FLAG(uiCode, "sps_bdpcm_enabled_flag"); pcSPS->setBDPCMEnabledFlag(uiCode ? true : false); } +#if !JVET_P0667_QP_OFFSET_TABLE_SIGNALING_JCCR READ_FLAG( uiCode, "sps_joint_cbcr_enabled_flag"); pcSPS->setJointCbCrEnabledFlag (uiCode ? true : false); +#endif READ_FLAG(uiCode, "sps_ref_wraparound_enabled_flag"); pcSPS->setWrapAroundEnabledFlag( uiCode ? true : false ); diff --git a/source/Lib/EncoderLib/EncLib.cpp b/source/Lib/EncoderLib/EncLib.cpp index 15641661ff172cc95ab63e0459d02c75034dfea9..27c9b67906105105f88ffba91e4040d623f99cb9 100644 --- a/source/Lib/EncoderLib/EncLib.cpp +++ b/source/Lib/EncoderLib/EncLib.cpp @@ -1246,6 +1246,17 @@ void EncLib::xInitPPS(PPS &pps, const SPS &sps) pps.setPicInitQPMinus26( std::min( maxDQP, std::max( minDQP, baseQp ) )); } +#if JVET_P0667_QP_OFFSET_TABLE_SIGNALING_JCCR + if (sps.getJointCbCrEnabledFlag() == false || getChromaFormatIdc() == CHROMA_400) + { + pps.setJointCbCrQpOffsetPresentFlag(false); + } + else + { + pps.setJointCbCrQpOffsetPresentFlag(true); + } +#endif + #if ER_CHROMA_QP_WCG_PPS if (getWCGChromaQPControl().isEnabled()) { @@ -1257,14 +1268,28 @@ void EncLib::xInitPPS(PPS &pps, const SPS &sps) const int crQP =(int)(dcrQP + ( dcrQP < 0 ? -0.5 : 0.5) ); pps.setQpOffset(COMPONENT_Cb, Clip3( -12, 12, min(0, cbQP) + m_chromaCbQpOffset )); pps.setQpOffset(COMPONENT_Cr, Clip3( -12, 12, min(0, crQP) + m_chromaCrQpOffset)); +#if JVET_P0667_QP_OFFSET_TABLE_SIGNALING_JCCR + if(pps.getJointCbCrQpOffsetPresentFlag()) + pps.setQpOffset(JOINT_CbCr, Clip3(-12, 12, (min(0, cbQP) + min(0, crQP)) / 2 + m_chromaCbCrQpOffset)); + else + pps.setQpOffset(JOINT_CbCr, 0); +#else pps.setQpOffset(JOINT_CbCr, Clip3( -12, 12, ( min(0, cbQP) + min(0, crQP) ) / 2 + m_chromaCbCrQpOffset)); +#endif } else { #endif pps.setQpOffset(COMPONENT_Cb, m_chromaCbQpOffset ); pps.setQpOffset(COMPONENT_Cr, m_chromaCrQpOffset ); +#if JVET_P0667_QP_OFFSET_TABLE_SIGNALING_JCCR + if (pps.getJointCbCrQpOffsetPresentFlag()) + pps.setQpOffset(JOINT_CbCr, m_chromaCbCrQpOffset); + else + pps.setQpOffset(JOINT_CbCr, 0); +#else pps.setQpOffset(JOINT_CbCr, m_chromaCbCrQpOffset ); +#endif #if ER_CHROMA_QP_WCG_PPS } #endif diff --git a/source/Lib/EncoderLib/VLCWriter.cpp b/source/Lib/EncoderLib/VLCWriter.cpp index 280c6a9e6a770402cec0d44644e205af0166b815..05025487d24b1cc1cdd131c902ec0d1f042029b6 100644 --- a/source/Lib/EncoderLib/VLCWriter.cpp +++ b/source/Lib/EncoderLib/VLCWriter.cpp @@ -258,7 +258,19 @@ void HLSWriter::codePPS( const PPS* pcPPS, const SPS* pcSPS ) WRITE_SVLC( pcPPS->getQpOffset(COMPONENT_Cb), "pps_cb_qp_offset" ); WRITE_SVLC( pcPPS->getQpOffset(COMPONENT_Cr), "pps_cr_qp_offset" ); +#if JVET_P0667_QP_OFFSET_TABLE_SIGNALING_JCCR + if (pcSPS->getJointCbCrEnabledFlag() == false || pcSPS->getChromaFormatIdc() == CHROMA_400) + { + CHECK(pcPPS->getJointCbCrQpOffsetPresentFlag(), "pps_jcbcr_qp_offset_present_flag should be false"); + } + WRITE_FLAG(pcPPS->getJointCbCrQpOffsetPresentFlag() ? 1 : 0, "pps_joint_cbcr_qp_offset_present_flag"); + if (pcPPS->getJointCbCrQpOffsetPresentFlag()) + { + WRITE_SVLC(pcPPS->getQpOffset(JOINT_CbCr), "pps_joint_cbcr_qp_offset"); + } +#else WRITE_SVLC( pcPPS->getQpOffset(JOINT_CbCr), "pps_joint_cbcr_qp_offset" ); +#endif WRITE_FLAG( pcPPS->getSliceChromaQpFlag() ? 1 : 0, "pps_slice_chroma_qp_offsets_present_flag" ); @@ -272,7 +284,14 @@ void HLSWriter::codePPS( const PPS* pcPPS, const SPS* pcSPS ) { WRITE_SVLC(pcPPS->getChromaQpOffsetListEntry(cuChromaQpOffsetIdx+1).u.comp.CbOffset, "cb_qp_offset_list[i]"); WRITE_SVLC(pcPPS->getChromaQpOffsetListEntry(cuChromaQpOffsetIdx+1).u.comp.CrOffset, "cr_qp_offset_list[i]"); +#if JVET_P0667_QP_OFFSET_TABLE_SIGNALING_JCCR + if (pcPPS->getJointCbCrQpOffsetPresentFlag()) + { + WRITE_SVLC(pcPPS->getChromaQpOffsetListEntry(cuChromaQpOffsetIdx + 1).u.comp.JointCbCrOffset, "joint_cbcr_qp_offset_list[i]"); + } +#else WRITE_SVLC(pcPPS->getChromaQpOffsetListEntry(cuChromaQpOffsetIdx + 1).u.comp.JointCbCrOffset, "joint_cbcr_qp_offset_list[i]"); +#endif } } @@ -787,11 +806,19 @@ void HLSWriter::codeSPS( const SPS* pcSPS ) WRITE_FLAG( (pcSPS->getLog2MaxTbSize() - 5) ? 1 : 0, "sps_max_luma_transform_size_64_flag" ); +#if JVET_P0667_QP_OFFSET_TABLE_SIGNALING_JCCR + WRITE_FLAG(pcSPS->getJointCbCrEnabledFlag(), "sps_joint_cbcr_enabled_flag"); +#endif if (pcSPS->getChromaFormatIdc() != CHROMA_400) { const ChromaQpMappingTable& chromaQpMappingTable = pcSPS->getChromaQpMappingTable(); WRITE_FLAG(chromaQpMappingTable.getSameCQPTableForAllChromaFlag(), "same_qp_table_for_chroma"); +#if JVET_P0667_QP_OFFSET_TABLE_SIGNALING_JCCR + int numQPTables = chromaQpMappingTable.getSameCQPTableForAllChromaFlag() ? 1 : (pcSPS->getJointCbCrEnabledFlag() ? 3 : 2); + for (int i = 0; i < numQPTables; i++) +#else for (int i = 0; i < (chromaQpMappingTable.getSameCQPTableForAllChromaFlag() ? 1 : 3); i++) +#endif { WRITE_UVLC(chromaQpMappingTable.getNumPtsInCQPTableMinus1(i), "num_points_in_qp_table_minus1"); @@ -815,7 +842,9 @@ void HLSWriter::codeSPS( const SPS* pcSPS ) { CHECK(pcSPS->getBDPCMEnabledFlag(), "BDPCM cannot be used when transform skip is disabled"); } +#if !JVET_P0667_QP_OFFSET_TABLE_SIGNALING_JCCR WRITE_FLAG( pcSPS->getJointCbCrEnabledFlag(), "sps_joint_cbcr_enabled_flag"); +#endif WRITE_FLAG( pcSPS->getWrapAroundEnabledFlag() ? 1 : 0, "sps_ref_wraparound_enabled_flag" ); if( pcSPS->getWrapAroundEnabledFlag() )