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 f319815e68ca2df29385a08400be8508c8e4998d..abbe4d719fb3b3769e018080837efe6fa4ce3880 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 unneccessary signaling of qp offset table for JCCR, when it is disabled. + #define JVET_P0298_DISABLE_LEVELMAPPING_IN_BYPASS 1 // JVET-P0298: Disable level mapping in bypass mode #define JVET_P0325_CHANGE_MERGE_CANDIDATE_ORDER 1 // JVET-P0325: reorder the spatial merge candidates diff --git a/source/Lib/DecoderLib/VLCReader.cpp b/source/Lib/DecoderLib/VLCReader.cpp index 09c625f2662a33307d7fd68813e92234e789587f..8b67b025c7aee3a5ec5eed1c30f685b1db685a19 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); @@ -1320,6 +1346,31 @@ 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); + + if (pcSPS->getChromaFormatIdc() != CHROMA_400) + { + ChromaQpMappingTableParams chromaQpMappingTableParams; + READ_FLAG(uiCode, "same_qp_table_for_chroma"); chromaQpMappingTableParams.setSameCQPTableForAllChromaFlag(uiCode); + int numQPTables = chromaQpMappingTableParams.getSameCQPTableForAllChromaFlag() ? 1 : (pcSPS->getJointCbCrEnabledFlag() ? 3 : 2); + for (int i = 0; i < numQPTables; i++) + { + READ_UVLC(uiCode, "num_points_in_qp_table_minus1"); chromaQpMappingTableParams.setNumPtsInCQPTableMinus1(i, uiCode); + std::vector<int> deltaQpInValMinus1(chromaQpMappingTableParams.getNumPtsInCQPTableMinus1(i) + 1); + std::vector<int> deltaQpOutVal(chromaQpMappingTableParams.getNumPtsInCQPTableMinus1(i) + 1); + for (int j = 0; j <= chromaQpMappingTableParams.getNumPtsInCQPTableMinus1(i); j++) + { + READ_UVLC(uiCode, "delta_qp_in_val_minus1"); deltaQpInValMinus1[j] = uiCode; + READ_UVLC(uiCode, "delta_qp_out_val"); deltaQpOutVal[j] = uiCode; + } + chromaQpMappingTableParams.setDeltaQpInValMinus1(i, deltaQpInValMinus1); + chromaQpMappingTableParams.setDeltaQpOutVal(i, deltaQpOutVal); + } + pcSPS->setChromaQpMappingTableFromParams(chromaQpMappingTableParams, pcSPS->getQpBDOffset(CHANNEL_TYPE_CHROMA)); + pcSPS->derivedChromaQPMappingTables(); + } +#else if (pcSPS->getChromaFormatIdc() != CHROMA_400) { ChromaQpMappingTableParams chromaQpMappingTableParams; @@ -1340,6 +1391,7 @@ void HLSyntaxReader::parseSPS(SPS* pcSPS) pcSPS->setChromaQpMappingTableFromParams(chromaQpMappingTableParams, pcSPS->getQpBDOffset(CHANNEL_TYPE_CHROMA)); pcSPS->derivedChromaQPMappingTables(); } +#endif READ_FLAG( uiCode, "sps_sao_enabled_flag" ); pcSPS->setSAOEnabledFlag ( uiCode ? true : false ); READ_FLAG( uiCode, "sps_alf_enabled_flag" ); pcSPS->setALFEnabledFlag ( uiCode ? true : false ); @@ -1349,7 +1401,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 cfd0e5e35a1ecd6ce2d4a70da830dd78329e5280..0b6c8923d3faf5ff2cb89cf870a0ba5f66b597fc 100644 --- a/source/Lib/EncoderLib/EncLib.cpp +++ b/source/Lib/EncoderLib/EncLib.cpp @@ -1226,6 +1226,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()) { @@ -1237,14 +1248,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..68c1e4f474ebc77943e5270112d664abaf5a6be4 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,6 +806,26 @@ 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"); + + if (pcSPS->getChromaFormatIdc() != CHROMA_400) + { + const ChromaQpMappingTable& chromaQpMappingTable = pcSPS->getChromaQpMappingTable(); + WRITE_FLAG(chromaQpMappingTable.getSameCQPTableForAllChromaFlag(), "same_qp_table_for_chroma"); + int numQPTables = chromaQpMappingTable.getSameCQPTableForAllChromaFlag() ? 1 : (pcSPS->getJointCbCrEnabledFlag() ? 3 : 2); + for (int i = 0; i < numQPTables; i++) + { + WRITE_UVLC(chromaQpMappingTable.getNumPtsInCQPTableMinus1(i), "num_points_in_qp_table_minus1"); + + for (int j = 0; j <= chromaQpMappingTable.getNumPtsInCQPTableMinus1(i); j++) + { + WRITE_UVLC(chromaQpMappingTable.getDeltaQpInValMinus1(i, j), "delta_qp_in_val_minus1"); + WRITE_UVLC(chromaQpMappingTable.getDeltaQpOutVal(i, j), "delta_qp_out_val"); + } + } + } +#else if (pcSPS->getChromaFormatIdc() != CHROMA_400) { const ChromaQpMappingTable& chromaQpMappingTable = pcSPS->getChromaQpMappingTable(); @@ -802,6 +841,7 @@ void HLSWriter::codeSPS( const SPS* pcSPS ) } } } +#endif WRITE_FLAG( pcSPS->getSAOEnabledFlag(), "sps_sao_enabled_flag"); WRITE_FLAG( pcSPS->getALFEnabledFlag(), "sps_alf_enabled_flag" ); @@ -815,7 +855,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() )