diff --git a/source/App/EncoderApp/EncApp.cpp b/source/App/EncoderApp/EncApp.cpp index a920d46aebed3501a62700e1bdb746a049064fcc..a7037d42555b7f40066df63ec9f0f43a3b0c8780 100644 --- a/source/App/EncoderApp/EncApp.cpp +++ b/source/App/EncoderApp/EncApp.cpp @@ -220,10 +220,19 @@ void EncApp::xInitLibCfg() ptls[0].setTierFlag ( m_levelTier ); ptls[0].setFrameOnlyConstraintFlag ( m_frameOnlyConstraintFlag); ptls[0].setMultiLayerEnabledFlag ( m_multiLayerEnabledFlag); +#if JVET_W2005_RANGE_EXTENSION_PROFILES + CHECK((m_profile == Profile::MAIN_10 || m_profile == Profile::MAIN_10_444 || \ + m_profile == Profile::MAIN_10_STILL_PICTURE || m_profile == Profile::MAIN_10_444_STILL_PICTURE || \ + m_profile == Profile::MAIN_12 || m_profile == Profile::MAIN_12_INTRA || m_profile == Profile::MAIN_12_STILL_PICTURE || \ + m_profile == Profile::MAIN_12_444 || m_profile == Profile::MAIN_12_444_INTRA || m_profile == Profile::MAIN_12_444_STILL_PICTURE || \ + m_profile == Profile::MAIN_16_444 || m_profile == Profile::MAIN_16_444_INTRA || m_profile == Profile::MAIN_16_444_STILL_PICTURE) \ + && m_multiLayerEnabledFlag, "ptl_multilayer_enabled_flag shall be equal to 0 for non-multilayer profiles"); +#else CHECK((m_profile == Profile::MAIN_10 || m_profile == Profile::MAIN_10_444 || m_profile == Profile::MAIN_10_STILL_PICTURE || m_profile == Profile::MAIN_10_444_STILL_PICTURE) && m_multiLayerEnabledFlag, "ptl_multilayer_enabled_flag shall be equal to 0 for non-multilayer profiles"); +#endif ptls[0].setNumSubProfile ( m_numSubProfile ); for (int i = 0; i < m_numSubProfile; i++) { @@ -450,6 +459,13 @@ void EncApp::xInitLibCfg() CHECK(m_noVirtualBoundaryConstraintFlag && m_virtualBoundariesEnabledFlag, "Virtuall boundaries shall be deactivated when m_noVirtualBoundaryConstraintFlag is equal to 1"); m_cEncLib.setNoChromaQpOffsetConstraintFlag(m_noChromaQpOffsetConstraintFlag); CHECK(m_noChromaQpOffsetConstraintFlag && m_cuChromaQpOffsetSubdiv, "Chroma Qp offset shall be 0 when m_noChromaQpOffsetConstraintFlag is equal to 1"); +#if JVET_W2005_RANGE_EXTENSION_PROFILES + m_cEncLib.setGeneralLowerBitRateConstraintFlag(m_generalLowerBitRateConstraintFlag); + if (m_profile == Profile::MAIN_12 || m_profile == Profile::MAIN_12_444 || m_profile == Profile::MAIN_16_444) + { + CHECK(m_generalLowerBitRateConstraintFlag==0, "generalLowerBitRateConstraintFlag shall be 1 when non-Intra/Still Picture operation range extension profiles are used"); + } +#endif } else { @@ -515,6 +531,9 @@ void EncApp::xInitLibCfg() m_cEncLib.setNoActConstraintFlag(false); m_cEncLib.setNoLmcsConstraintFlag(false); m_cEncLib.setNoChromaQpOffsetConstraintFlag(false); +#if JVET_W2005_RANGE_EXTENSION_PROFILES + m_cEncLib.setGeneralLowerBitRateConstraintFlag(false); +#endif } //====== Coding Structure ======== diff --git a/source/App/EncoderApp/EncAppCfg.cpp b/source/App/EncoderApp/EncAppCfg.cpp index 6f09d58b5ee59048e54f5f011c541d99df9455d4..c9d6697e974537dd8accc6c195c93ad84759d08a 100644 --- a/source/App/EncoderApp/EncAppCfg.cpp +++ b/source/App/EncoderApp/EncAppCfg.cpp @@ -69,6 +69,17 @@ enum ExtendedProfileName // this is used for determining profile strings, wher MULTILAYER_MAIN_10_STILL_PICTURE, MULTILAYER_MAIN_10_444, MULTILAYER_MAIN_10_444_STILL_PICTURE, +#if JVET_W2005_RANGE_EXTENSION_PROFILES + MAIN_12, + MAIN_12_444, + MAIN_16_444, + MAIN_12_INTRA, + MAIN_12_444_INTRA, + MAIN_16_444_INTRA, + MAIN_12_STILL_PICTURE, + MAIN_12_444_STILL_PICTURE, + MAIN_16_444_STILL_PICTURE, +#endif AUTO = -1 }; @@ -178,6 +189,17 @@ static const struct MapStrToProfile { "multilayer_main_10_444", Profile::MULTILAYER_MAIN_10_444 }, { "multilayer_main_10_still_picture", Profile::MULTILAYER_MAIN_10_STILL_PICTURE }, { "multilayer_main_10_444_still_picture", Profile::MULTILAYER_MAIN_10_444_STILL_PICTURE }, +#if JVET_W2005_RANGE_EXTENSION_PROFILES + { "main_12", Profile::MAIN_12 }, + { "main_12_444", Profile::MAIN_12_444 }, + { "main_16_444", Profile::MAIN_16_444 }, + { "main_12_intra", Profile::MAIN_12_INTRA }, + { "main_12_444_intra", Profile::MAIN_12_444_INTRA }, + { "main_16_444_intra", Profile::MAIN_16_444_INTRA }, + { "main_12_still_picture", Profile::MAIN_12_STILL_PICTURE }, + { "main_12_444_still_picture", Profile::MAIN_12_444_STILL_PICTURE }, + { "main_16_444_still_picture", Profile::MAIN_16_444_STILL_PICTURE }, +#endif }; static const struct MapStrToExtendedProfile @@ -194,6 +216,17 @@ static const struct MapStrToExtendedProfile { "multilayer_main_10_444", MULTILAYER_MAIN_10_444 }, { "multilayer_main_10_still_picture", MULTILAYER_MAIN_10_STILL_PICTURE }, { "multilayer_main_10_444_still_picture", MULTILAYER_MAIN_10_444_STILL_PICTURE }, +#if JVET_W2005_RANGE_EXTENSION_PROFILES + { "main_12", MAIN_12 }, + { "main_12_444", MAIN_12_444 }, + { "main_16_444", MAIN_16_444 }, + { "main_12_intra", MAIN_12_INTRA }, + { "main_12_444_intra", MAIN_12_444_INTRA }, + { "main_16_444_intra", MAIN_16_444_INTRA }, + { "main_12_still_picture", MAIN_12_STILL_PICTURE }, + { "main_12_444_still_picture", MAIN_12_444_STILL_PICTURE }, + { "main_16_444_still_picture", MAIN_16_444_STILL_PICTURE }, +#endif { "auto", AUTO }, }; @@ -894,6 +927,9 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) ("NoLmcsConstraintFlag", m_noLmcsConstraintFlag, false, "Indicate that LMCS is deactivated") ("NoLadfConstraintFlag", m_noLadfConstraintFlag, false, "Indicate that LADF is deactivated") ("NoVirtualBoundaryConstraintFlag", m_noVirtualBoundaryConstraintFlag, false, "Indicate that virtual boundary is deactivated") +#if JVET_W2005_RANGE_EXTENSION_PROFILES + ("GeneralLowerBitRateConstraintFlag", m_generalLowerBitRateConstraintFlag, false, "Indicate whether lower bitrate constraint is used") +#endif ("CTUSize", m_uiCTUSize, 128u, "CTUSize (specifies the CTU size if QTBT is on) [default: 128]") ("Log2MinCuSize", m_log2MinCuSize, 2u, "Log2 min CU size") @@ -2094,6 +2130,26 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) case ExtendedProfileName::MULTILAYER_MAIN_10_444_STILL_PICTURE: m_profile = Profile::MULTILAYER_MAIN_10_444_STILL_PICTURE; break; +#if JVET_W2005_RANGE_EXTENSION_PROFILES + case ExtendedProfileName::MAIN_12: + m_profile = Profile::MAIN_12; break; + case ExtendedProfileName::MAIN_12_444: + m_profile = Profile::MAIN_12_444; break; + case ExtendedProfileName::MAIN_16_444: + m_profile = Profile::MAIN_16_444; break; + case ExtendedProfileName::MAIN_12_INTRA: + m_profile = Profile::MAIN_12_INTRA; break; + case ExtendedProfileName::MAIN_12_444_INTRA: + m_profile = Profile::MAIN_12_444_INTRA; break; + case ExtendedProfileName::MAIN_16_444_INTRA: + m_profile = Profile::MAIN_16_444_INTRA; break; + case ExtendedProfileName::MAIN_12_STILL_PICTURE: + m_profile = Profile::MAIN_12_STILL_PICTURE; break; + case ExtendedProfileName::MAIN_12_444_STILL_PICTURE: + m_profile = Profile::MAIN_12_444_STILL_PICTURE; break; + case ExtendedProfileName::MAIN_16_444_STILL_PICTURE: + m_profile = Profile::MAIN_16_444_STILL_PICTURE; break; +#endif default: EXIT("Unable to determine profile from configured settings"); break; } } @@ -2122,6 +2178,27 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) m_inputColourSpaceConvert = stringToInputColourSpaceConvert(inputColourSpaceConvert, true); m_rgbFormat = (m_inputColourSpaceConvert == IPCOLOURSPACE_RGBtoGBR && m_chromaFormatIDC == CHROMA_444) ? true : false; +#if JVET_W2005_RANGE_EXTENSION_PROFILES + if (m_profile == Profile::MAIN_12 || m_profile == Profile::MAIN_12_INTRA || m_profile == Profile::MAIN_12_STILL_PICTURE || + m_profile == Profile::MAIN_12_444 || m_profile == Profile::MAIN_12_444_INTRA || m_profile == Profile::MAIN_12_444_STILL_PICTURE || + m_profile == Profile::MAIN_16_444 || m_profile == Profile::MAIN_16_444_INTRA || m_profile == Profile::MAIN_16_444_STILL_PICTURE) + { + m_gciPresentFlag = true; + if (m_profile == Profile::MAIN_12 || m_profile == Profile::MAIN_12_444 || m_profile == Profile::MAIN_16_444) + { + CHECK(m_generalLowerBitRateConstraintFlag == 0, "GeneralLowerBitRateConstraintFlag setting must be 1 for non-Intra/Still Picture operation range extension profiles.") + } + } + if (m_profile == Profile::MAIN_12_INTRA || m_profile == Profile::MAIN_12_444_INTRA || m_profile == Profile::MAIN_16_444_INTRA) + { + CHECK(m_iIntraPeriod != 1, "IntraPeriod setting must be 1 for Intra profiles") + } + if (m_profile == Profile::MULTILAYER_MAIN_10_STILL_PICTURE || m_profile == Profile::MAIN_10_STILL_PICTURE || + m_profile == Profile::MAIN_12_STILL_PICTURE || m_profile == Profile::MAIN_12_444_STILL_PICTURE || m_profile == Profile::MAIN_16_444_STILL_PICTURE) + { + CHECK(m_framesToBeEncoded != 1, "FramesToBeEncoded setting must be 1 for Still Picture profiles") + } +#endif // Picture width and height must be multiples of 8 and minCuSize const int minResolutionMultiple = std::max(8, 1 << m_log2MinCuSize); @@ -2862,6 +2939,17 @@ int EncAppCfg::xAutoDetermineProfile() m_profile = m_maxLayers > 1 ? Profile::MULTILAYER_MAIN_10 : Profile::MAIN_10; } } +#if JVET_W2005_RANGE_EXTENSION_PROFILES + else if (maxBitDepth <= 12) + { + m_profile = (m_level == Level::LEVEL15_5 && m_framesToBeEncoded == 1) ? Profile::MAIN_12_STILL_PICTURE : (m_iIntraPeriod == 1) ? Profile::MAIN_12_INTRA : Profile::MAIN_12; + } + else if (maxBitDepth <= 16) + { + // Since there's no 16bit 420 profiles in VVC, we use 444 profiles. + m_profile = (m_level == Level::LEVEL15_5 && m_framesToBeEncoded == 1) ? Profile::MAIN_16_444_STILL_PICTURE : (m_iIntraPeriod == 1) ? Profile::MAIN_16_444_INTRA : Profile::MAIN_16_444; + } +#endif break; case ChromaFormat::CHROMA_422: @@ -2878,11 +2966,26 @@ int EncAppCfg::xAutoDetermineProfile() m_profile = m_maxLayers > 1 ? Profile::MULTILAYER_MAIN_10_444 : Profile::MAIN_10_444; } } +#if JVET_W2005_RANGE_EXTENSION_PROFILES + else if (maxBitDepth <= 12) + { + m_profile = (m_level == Level::LEVEL15_5 && m_framesToBeEncoded == 1) ? Profile::MAIN_12_444_STILL_PICTURE : (m_iIntraPeriod == 1) ? Profile::MAIN_12_444_INTRA : Profile::MAIN_12_444; + } + else if (maxBitDepth <= 16) + { + m_profile = (m_level == Level::LEVEL15_5 && m_framesToBeEncoded == 1) ? Profile::MAIN_16_444_STILL_PICTURE : (m_iIntraPeriod == 1) ? Profile::MAIN_16_444_INTRA : Profile::MAIN_16_444; + } +#endif break; default: return 1; } - +#if JVET_W2005_RANGE_EXTENSION_PROFILES + if (m_profile == Profile::MAIN_12 || m_profile == Profile::MAIN_12_444 || m_profile == Profile::MAIN_16_444) + { + m_generalLowerBitRateConstraintFlag = 1; // GeneralLowerBitRateConstraintFlag setting must be 1 for non-Intra/Still Picture operation range extension profiles.") + } +#endif return 0; } @@ -2952,17 +3055,31 @@ bool EncAppCfg::xCheckParameter() xConfirmPara(m_log2MaxTransformSkipBlockSize>=6, "Transform Skip Log2 Max Size must be less or equal to 5 for given profile."); xConfirmPara(m_transformSkipRotationEnabledFlag==true, "UseResidualRotation must not be enabled for given profile."); xConfirmPara(m_transformSkipContextEnabledFlag==true, "UseSingleSignificanceMapContext must not be enabled for given profile."); +#if !JVET_W2005_RANGE_EXTENSION_PROFILES xConfirmPara(m_rrcRiceExtensionEnableFlag == true, "Extention of the Golomb-Rice parameter derivation for RRC must not be enabled for given profile."); xConfirmPara(m_persistentRiceAdaptationEnabledFlag==true, "GolombRiceParameterAdaption must not be enabled for given profile."); xConfirmPara(m_extendedPrecisionProcessingFlag==true, "UseExtendedPrecision must not be enabled for given profile."); xConfirmPara(m_tsrcRicePresentFlag == true, "TSRCRicePresent must not be enabled for given profile."); #if JVET_W0046_RLSCP xConfirmPara(m_reverseLastSigCoeffEnabledFlag == true, "ReverseLastSigCoeff must not be enabled for given profile."); +#endif #endif xConfirmPara(m_highPrecisionOffsetsEnabledFlag==true, "UseHighPrecisionPredictionWeighting must not be enabled for given profile."); xConfirmPara(m_enableIntraReferenceSmoothing==false, "EnableIntraReferenceSmoothing must be enabled for given profile."); xConfirmPara(m_cabacBypassAlignmentEnabledFlag, "AlignCABACBeforeBypass cannot be enabled for given profile."); } +#if JVET_W2005_RANGE_EXTENSION_PROFILES + if (m_profile != Profile::NONE && m_profile != Profile::MAIN_12_444 && m_profile != Profile::MAIN_16_444 && m_profile != Profile::MAIN_12_444_INTRA && m_profile != Profile::MAIN_16_444_INTRA && m_profile != Profile::MAIN_12_444_STILL_PICTURE && m_profile != Profile::MAIN_12_444_STILL_PICTURE && m_profile != Profile::MAIN_16_444_STILL_PICTURE) + { + xConfirmPara(m_rrcRiceExtensionEnableFlag == true, "Extention of the Golomb-Rice parameter derivation for RRC must not be enabled for given profile."); + xConfirmPara(m_persistentRiceAdaptationEnabledFlag==true, "GolombRiceParameterAdaption must not be enabled for given profile."); + xConfirmPara(m_extendedPrecisionProcessingFlag==true, "UseExtendedPrecision must not be enabled for given profile."); + xConfirmPara(m_tsrcRicePresentFlag == true, "TSRCRicePresent must not be enabled for given profile."); +#if JVET_W0046_RLSCP + xConfirmPara(m_reverseLastSigCoeffEnabledFlag == true, "ReverseLastSigCoeff must not be enabled for given profile."); +#endif + } +#endif // check range of parameters @@ -4217,6 +4334,9 @@ void EncAppCfg::xPrintParameter() { msg( DETAILS, "Profile : %s\n", profileToString(m_profile) ); } +#if JVET_W2005_RANGE_EXTENSION_PROFILES + msg( DETAILS,"GeneralLowerBitRateConstraintFlag : %d\n", m_generalLowerBitRateConstraintFlag ); +#endif msg(DETAILS, "CTU size / min CU size : %d / %d \n", m_uiMaxCUWidth, 1 << m_log2MinCuSize); msg(DETAILS, "subpicture info present flag : %s\n", m_subPicInfoPresentFlag ? "Enabled" : "Disabled"); diff --git a/source/App/EncoderApp/EncAppCfg.h b/source/App/EncoderApp/EncAppCfg.h index 363bbc5e9022e396f0c30fec99cd434efa1ae47d..76f858929f4ebe6c4f8be3beea4d4ebdc8029ffc 100644 --- a/source/App/EncoderApp/EncAppCfg.h +++ b/source/App/EncoderApp/EncAppCfg.h @@ -189,6 +189,9 @@ protected: bool m_noCraConstraintFlag; bool m_noGdrConstraintFlag; bool m_noApsConstraintFlag; +#if JVET_W2005_RANGE_EXTENSION_PROFILES + bool m_generalLowerBitRateConstraintFlag; +#endif // profile/level Profile::Name m_profile; diff --git a/source/Lib/CommonLib/ProfileLevelTier.cpp b/source/Lib/CommonLib/ProfileLevelTier.cpp index b8287a8be9352212e597045d2886f2bf7acdecd5..e3029ece4c3c868c44f44556fc15a12703b36951 100644 --- a/source/Lib/CommonLib/ProfileLevelTier.cpp +++ b/source/Lib/CommonLib/ProfileLevelTier.cpp @@ -92,6 +92,17 @@ static const ProfileFeatures validProfiles[] = { { Profile::MAIN_10_444, "Main_444_10", 10, CHROMA_444, false, 2500, 2750, 3750, 75, mainLevelTierInfo, false }, { Profile::MULTILAYER_MAIN_10_444, "Multilayer_Main_444_10", 10, CHROMA_444, false, 2500, 2750, 3750, 75, mainLevelTierInfo, false }, +#if JVET_W2005_RANGE_EXTENSION_PROFILES + { Profile::MAIN_12, "Main_12", 12, CHROMA_420, true, 1500, 1650, 2250, 100, mainLevelTierInfo, false }, + { Profile::MAIN_12_INTRA, "Main_12_Intra", 12, CHROMA_420, true, 1500, 1650, 2250, 100, mainLevelTierInfo, false }, + { Profile::MAIN_12_STILL_PICTURE, "Main_12_Still_Picture", 12, CHROMA_420, true, 1500, 1650, 2250, 100, mainLevelTierInfo, false }, + { Profile::MAIN_12_444, "Main_12_444", 12, CHROMA_444, true, 3000, 3300, 4500, 50, mainLevelTierInfo, false }, + { Profile::MAIN_12_444_INTRA, "Main_12_444_Intra", 12, CHROMA_444, true, 3000, 3300, 4500, 50, mainLevelTierInfo, false }, + { Profile::MAIN_12_444_STILL_PICTURE, "Main_12_444_Still_Picture", 12, CHROMA_444, true, 3000, 3300, 4500, 50, mainLevelTierInfo, false }, + { Profile::MAIN_16_444, "Main_16_444", 16, CHROMA_444, true, 4000, 4400, 6000, 50, mainLevelTierInfo, false }, + { Profile::MAIN_16_444_INTRA, "Main_16_444_Intra", 16, CHROMA_444, true, 4000, 4400, 6000, 50, mainLevelTierInfo, false }, + { Profile::MAIN_16_444_STILL_PICTURE, "Main_16_444_Still_Picture", 16, CHROMA_444, true, 4000, 4400, 6000, 50, mainLevelTierInfo, false }, +#endif { Profile::NONE, 0 }, }; @@ -144,16 +155,37 @@ ProfileLevelTierFeatures::extractPTLInformation(const SPS &sps) } } } +#if JVET_W2005_RANGE_EXTENSION_PROFILES + Profile::Name profile = m_pProfile->profile; + if (profile == Profile::MAIN_10 || profile == Profile::MAIN_10_444 || + profile == Profile::MULTILAYER_MAIN_10 || profile == Profile::MULTILAYER_MAIN_10_444 || + profile == Profile::MAIN_12 || profile == Profile::MAIN_12_444 || profile == Profile::MAIN_16_444) + { + m_hbrFactor = 1; + } + else + { + m_hbrFactor = 2 - sps.getProfileTierLevel()->getConstraintInfo()->getLowerBitRateConstraintFlag(); + } +#endif } double ProfileLevelTierFeatures::getMinCr() const { +#if JVET_W2005_RANGE_EXTENSION_PROFILES + return (m_pLevelTier!=0 && m_pProfile!=0) ? (m_pProfile->minCrScaleFactorx100 * m_pLevelTier->minCrBase[m_tier?1:0] / m_hbrFactor)/100.0 : 0.0 ; +#else return (m_pLevelTier!=0 && m_pProfile!=0) ? (m_pProfile->minCrScaleFactorx100 * m_pLevelTier->minCrBase[m_tier?1:0])/100.0 : 0.0 ; +#endif } uint64_t ProfileLevelTierFeatures::getCpbSizeInBits() const { +#if JVET_W2005_RANGE_EXTENSION_PROFILES + return (m_pLevelTier!=0 && m_pProfile!=0) ? uint64_t(m_pProfile->cpbVclFactor) * m_pLevelTier->maxCpb[m_tier?1:0] * m_hbrFactor : uint64_t(0); +#else return (m_pLevelTier!=0 && m_pProfile!=0) ? uint64_t(m_pProfile->cpbVclFactor) * m_pLevelTier->maxCpb[m_tier?1:0] : uint64_t(0); +#endif } uint32_t ProfileLevelTierFeatures::getMaxDpbSize( uint32_t picSizeMaxInSamplesY ) const diff --git a/source/Lib/CommonLib/ProfileLevelTier.h b/source/Lib/CommonLib/ProfileLevelTier.h index 5a33faec29c94c81e528f4fc976c687a0dab467e..ceffdf809383dbc51320a2f4c30cb8114292a90d 100644 --- a/source/Lib/CommonLib/ProfileLevelTier.h +++ b/source/Lib/CommonLib/ProfileLevelTier.h @@ -88,6 +88,9 @@ class ProfileLevelTierFeatures const ProfileFeatures *m_pProfile; const LevelTierFeatures *m_pLevelTier; Level::Tier m_tier; +#if JVET_W2005_RANGE_EXTENSION_PROFILES + int m_hbrFactor; +#endif public: ProfileLevelTierFeatures() : m_pProfile(nullptr), m_pLevelTier(nullptr), m_tier(Level::MAIN) {} diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index 7c8accff973d6e178eba12c5810d2d4ad40a7069..f0ba87118be0959f8c0ea7298b2484068a9fc244 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -65,6 +65,8 @@ #define JVET_W0046_RLSCP 1 // JVET-W0046: CE1.1 reverse last significant coefficient position +#define JVET_W2005_RANGE_EXTENSION_PROFILES 1 // JVET-W2005 (JVET-W0136 profile plus meeting decisions) + //########### place macros to be be kept below this line ############### #define GDR_ENABLED 1 @@ -684,6 +686,9 @@ namespace Profile enum Name { NONE = 0, +#if JVET_W2005_RANGE_EXTENSION_PROFILES + INTRA = 8, +#endif STILL_PICTURE = 64, MAIN_10 = 1, MAIN_10_STILL_PICTURE = MAIN_10 | STILL_PICTURE, @@ -693,6 +698,17 @@ namespace Profile MAIN_10_444_STILL_PICTURE = MAIN_10_444 | STILL_PICTURE, MULTILAYER_MAIN_10_444 = 49, MULTILAYER_MAIN_10_444_STILL_PICTURE = MULTILAYER_MAIN_10_444 | STILL_PICTURE, +#if JVET_W2005_RANGE_EXTENSION_PROFILES + MAIN_12 = 2, + MAIN_12_444 = 34, + MAIN_16_444 = 36, + MAIN_12_INTRA = MAIN_12 | INTRA, + MAIN_12_444_INTRA = MAIN_12_444 | INTRA, + MAIN_16_444_INTRA = MAIN_16_444 | INTRA, + MAIN_12_STILL_PICTURE = MAIN_12 | STILL_PICTURE, + MAIN_12_444_STILL_PICTURE = MAIN_12_444 | STILL_PICTURE, + MAIN_16_444_STILL_PICTURE = MAIN_16_444 | STILL_PICTURE, +#endif }; } diff --git a/source/Lib/DecoderLib/VLCReader.cpp b/source/Lib/DecoderLib/VLCReader.cpp index a736f6b42fc9b5a5d42915978047b2071e17b12e..743947e0b07817084fb62de9d7d54cdcc57b7e9f 100644 --- a/source/Lib/DecoderLib/VLCReader.cpp +++ b/source/Lib/DecoderLib/VLCReader.cpp @@ -1923,6 +1923,10 @@ void HLSyntaxReader::parseSPS(SPS* pcSPS) pcSPS->setVerCollocatedChromaFlag(true); } READ_FLAG( uiCode, "sps_palette_enabled_flag"); pcSPS->setPLTMode ( uiCode != 0 ); +#if JVET_W2005_RANGE_EXTENSION_PROFILES + CHECK((profile == Profile::MAIN_12 || profile == Profile::MAIN_12_INTRA || profile == Profile::MAIN_12_STILL_PICTURE) + && uiCode != 0, "sps_palette_enabled_flag shall be equal to 0 for Main 12 (420) profiles"); +#endif if (pcSPS->getChromaFormatIdc() == CHROMA_444 && pcSPS->getLog2MaxTbSize() != 6) { READ_FLAG(uiCode, "sps_act_enabled_flag"); pcSPS->setUseColorTrans(uiCode != 0); @@ -2115,8 +2119,10 @@ void HLSyntaxReader::parseSPS(SPS* pcSPS) CHECK(bSkipTrailingExtensionBits, "Skipping trailing extension bits not supported"); { SPSRExt &spsRangeExtension = pcSPS->getSpsRangeExtension(); +#if !JVET_W2005_RANGE_EXTENSION_PROFILES READ_FLAG( uiCode, "transform_skip_rotation_enabled_flag"); spsRangeExtension.setTransformSkipRotationEnabledFlag(uiCode != 0); READ_FLAG( uiCode, "transform_skip_context_enabled_flag"); spsRangeExtension.setTransformSkipContextEnabledFlag (uiCode != 0); +#endif READ_FLAG( uiCode, "extended_precision_processing_flag"); spsRangeExtension.setExtendedPrecisionProcessingFlag (uiCode != 0); #if JVET_W0070_W0121_SPSRE_CLEANUP if (pcSPS->getTransformSkipEnabledFlag()) @@ -2126,14 +2132,18 @@ void HLSyntaxReader::parseSPS(SPS* pcSPS) #else READ_FLAG( uiCode, "sps_ts_residual_coding_rice_present_in_sh_flag"); spsRangeExtension.setTSRCRicePresentFlag(uiCode != 0); #endif +#if !JVET_W2005_RANGE_EXTENSION_PROFILES READ_FLAG( uiCode, "intra_smoothing_disabled_flag"); spsRangeExtension.setIntraSmoothingDisabledFlag (uiCode != 0); READ_FLAG( uiCode, "high_precision_offsets_enabled_flag"); spsRangeExtension.setHighPrecisionOffsetsEnabledFlag (uiCode != 0); +#endif READ_FLAG(uiCode, "rrc_rice_extension_flag"); spsRangeExtension.setRrcRiceExtensionEnableFlag (uiCode != 0); READ_FLAG( uiCode, "persistent_rice_adaptation_enabled_flag"); spsRangeExtension.setPersistentRiceAdaptationEnabledFlag (uiCode != 0); #if JVET_W0046_RLSCP READ_FLAG( uiCode, "reverse_last_position_enabled_flag"); spsRangeExtension.setReverseLastSigCoeffEnabledFlag(uiCode != 0); #endif +#if !JVET_W2005_RANGE_EXTENSION_PROFILES READ_FLAG( uiCode, "cabac_bypass_alignment_enabled_flag"); spsRangeExtension.setCabacBypassAlignmentEnabledFlag (uiCode != 0); +#endif } break; default: @@ -4489,7 +4499,11 @@ void HLSyntaxReader::getSlicePoc(Slice* pcSlice, PicHeader* picHeader, Parameter DTRACE_UPDATE( g_trace_ctx, std::make_pair( "final", 1 ) ); } +#if JVET_W2005_RANGE_EXTENSION_PROFILES +void HLSyntaxReader::parseConstraintInfo(ConstraintInfo *cinfo, const ProfileTierLevel* ptl ) +#else void HLSyntaxReader::parseConstraintInfo(ConstraintInfo *cinfo) +#endif { uint32_t symbol; READ_FLAG(symbol, "gci_present_flag"); cinfo->setGciPresentFlag(symbol ? true : false); @@ -4581,7 +4595,24 @@ void HLSyntaxReader::parseConstraintInfo(ConstraintInfo *cinfo) READ_FLAG(symbol, "gci_no_virtual_boundaries_constraint_flag"); cinfo->setNoVirtualBoundaryConstraintFlag(symbol > 0 ? true : false); READ_CODE(8, symbol, "gci_num_reserved_bits"); uint32_t const numReservedBits = symbol; +#if JVET_W2005_RANGE_EXTENSION_PROFILES + int numReservedBitsUsed; + if (numReservedBits > 0) + { + READ_FLAG(symbol, "general_lower_bit_rate_constraint_flag"); cinfo->setLowerBitRateConstraintFlag(symbol > 0 ? true : false); + numReservedBitsUsed = 1; + Profile::Name profile = ptl->getProfileIdc(); + CHECK((profile == Profile::MAIN_12 || profile == Profile::MAIN_12_444 || profile == Profile::MAIN_16_444) && + symbol == 0, "general_lower_bitrate_constraint_flag shall be equal to 1 for non-Intra/Still Picture operation range extension profiles."); + } + else + { + numReservedBitsUsed = 0; + } + for (int i = 0; i < numReservedBits - numReservedBitsUsed; i++) +#else for (int i = 0; i < numReservedBits; i++) +#endif { READ_FLAG(symbol, "gci_reserved_zero_bit"); CHECK(symbol != 0, "gci_reserved_zero_bit not equal to zero"); } @@ -4614,7 +4645,11 @@ void HLSyntaxReader::parseProfileTierLevel(ProfileTierLevel *ptl, bool profileTi if(profileTierPresentFlag) { +#if JVET_W2005_RANGE_EXTENSION_PROFILES + parseConstraintInfo(ptl->getConstraintInfo(), ptl); +#else parseConstraintInfo(ptl->getConstraintInfo()); +#endif } for (int i = maxNumSubLayersMinus1 - 1; i >= 0; i--) diff --git a/source/Lib/DecoderLib/VLCReader.h b/source/Lib/DecoderLib/VLCReader.h index 446368aa58fa6f1b0c73291bce4fc0f075a9cf77..ae43701999aa80b29a5eaf1f9760525bbd2de02d 100644 --- a/source/Lib/DecoderLib/VLCReader.h +++ b/source/Lib/DecoderLib/VLCReader.h @@ -177,7 +177,11 @@ public: void parseLmcsAps ( APS* pcAPS ); void parseScalingListAps ( APS* pcAPS ); void parseVUI ( VUI* pcVUI, SPS* pcSPS ); +#if JVET_W2005_RANGE_EXTENSION_PROFILES + void parseConstraintInfo (ConstraintInfo *cinfo, const ProfileTierLevel* ptl ); +#else void parseConstraintInfo (ConstraintInfo *cinfo); +#endif void parseProfileTierLevel(ProfileTierLevel *ptl, bool profileTierPresentFlag, int maxNumSubLayersMinus1); void parseOlsHrdParameters(GeneralHrdParams* generalHrd, OlsHrdParams *olsHrd, uint32_t firstSubLayer, uint32_t tempLevelHigh); void parseGeneralHrdParameters(GeneralHrdParams *generalHrd); diff --git a/source/Lib/EncoderLib/EncCfg.h b/source/Lib/EncoderLib/EncCfg.h index bc2b7dfd2204feb86958d09f4fbc2d141b1681b7..988cea965852482e758780d7d039ba614aab729e 100644 --- a/source/Lib/EncoderLib/EncCfg.h +++ b/source/Lib/EncoderLib/EncCfg.h @@ -235,6 +235,9 @@ protected: bool m_noCraConstraintFlag; bool m_noGdrConstraintFlag; bool m_noApsConstraintFlag; +#if JVET_W2005_RANGE_EXTENSION_PROFILES + bool m_generalLowerBitRateConstraintFlag; +#endif /* profile & level */ Profile::Name m_profile; @@ -1017,7 +1020,10 @@ public: void setNoGdrConstraintFlag(bool val) { m_noGdrConstraintFlag = val; } bool getNoApsConstraintFlag() const { return m_noApsConstraintFlag; } void setNoApsConstraintFlag(bool val) { m_noApsConstraintFlag = val; } - +#if JVET_W2005_RANGE_EXTENSION_PROFILES + bool getGeneralLowerBitRateConstraintFlag() const { return m_generalLowerBitRateConstraintFlag; } + void setGeneralLowerBitRateConstraintFlag(bool val) { m_generalLowerBitRateConstraintFlag = val; } +#endif void setFrameRate ( int i ) { m_iFrameRate = i; } void setFrameSkip ( uint32_t i ) { m_FrameSkip = i; } diff --git a/source/Lib/EncoderLib/EncLib.cpp b/source/Lib/EncoderLib/EncLib.cpp index be8bb2a613a4d09fe7926b61c6266436de074aeb..c7ca3b1667c9af14de9ea2416549255469df5330 100644 --- a/source/Lib/EncoderLib/EncLib.cpp +++ b/source/Lib/EncoderLib/EncLib.cpp @@ -1113,6 +1113,9 @@ void EncLib::xInitSPS( SPS& sps ) cinfo->setNoCraConstraintFlag(m_noCraConstraintFlag); cinfo->setNoGdrConstraintFlag(m_noGdrConstraintFlag); cinfo->setNoApsConstraintFlag(m_noApsConstraintFlag); +#if JVET_W2005_RANGE_EXTENSION_PROFILES + cinfo->setLowerBitRateConstraintFlag(m_generalLowerBitRateConstraintFlag); +#endif profileTierLevel->setLevelIdc (m_level); profileTierLevel->setTierFlag (m_levelTier); diff --git a/source/Lib/EncoderLib/VLCWriter.cpp b/source/Lib/EncoderLib/VLCWriter.cpp index 2ed76be86beab8d9d29214fd6778f04bb3a48c02..7a0846f2bed096bfb2a2570513cdb20ca4c6cfc4 100644 --- a/source/Lib/EncoderLib/VLCWriter.cpp +++ b/source/Lib/EncoderLib/VLCWriter.cpp @@ -1264,6 +1264,15 @@ void HLSWriter::codeSPS( const SPS* pcSPS ) { #if ENABLE_TRACING /*|| RExt__DECODER_DEBUG_BIT_STATISTICS*/ static const char *syntaxStrings[]={ "sps_range_extension_flag", +#if JVET_W2005_RANGE_EXTENSION_PROFILES + "sps_extension_7bits[0]", + "sps_extension_7bits[1]", + "sps_extension_7bits[2]", + "sps_extension_7bits[3]", + "sps_extension_7bits[4]", + "sps_extension_7bits[5]", + "sps_extension_7bits[6]" }; +#else "sps_multilayer_extension_flag", "sps_extension_6bits[0]", "sps_extension_6bits[1]", @@ -1272,6 +1281,7 @@ void HLSWriter::codeSPS( const SPS* pcSPS ) "sps_extension_6bits[4]", "sps_extension_6bits[5]" }; #endif +#endif #if JVET_W0178_CONSTRAINTS_ON_REXT_TOOLS if (pcSPS->getBitDepth(CHANNEL_TYPE_LUMA) <= 10) @@ -1294,8 +1304,10 @@ void HLSWriter::codeSPS( const SPS* pcSPS ) { const SPSRExt &spsRangeExtension=pcSPS->getSpsRangeExtension(); +#if !JVET_W2005_RANGE_EXTENSION_PROFILES WRITE_FLAG( (spsRangeExtension.getTransformSkipRotationEnabledFlag() ? 1 : 0), "transform_skip_rotation_enabled_flag"); WRITE_FLAG( (spsRangeExtension.getTransformSkipContextEnabledFlag() ? 1 : 0), "transform_skip_context_enabled_flag"); +#endif WRITE_FLAG( (spsRangeExtension.getExtendedPrecisionProcessingFlag() ? 1 : 0), "extended_precision_processing_flag" ); #if JVET_W0070_W0121_SPSRE_CLEANUP if (pcSPS->getTransformSkipEnabledFlag()) @@ -1305,14 +1317,18 @@ void HLSWriter::codeSPS( const SPS* pcSPS ) #else WRITE_FLAG( (spsRangeExtension.getTSRCRicePresentFlag() ? 1 : 0), "sps_ts_residual_coding_rice_present_in_sh_flag"); #endif +#if !JVET_W2005_RANGE_EXTENSION_PROFILES WRITE_FLAG( (spsRangeExtension.getIntraSmoothingDisabledFlag() ? 1 : 0), "intra_smoothing_disabled_flag" ); WRITE_FLAG( (spsRangeExtension.getHighPrecisionOffsetsEnabledFlag() ? 1 : 0), "high_precision_offsets_enabled_flag" ); +#endif WRITE_FLAG( (spsRangeExtension.getRrcRiceExtensionEnableFlag() ? 1 : 0), "rrc_rice_extension_flag"); WRITE_FLAG( (spsRangeExtension.getPersistentRiceAdaptationEnabledFlag() ? 1 : 0), "persistent_rice_adaptation_enabled_flag" ); #if JVET_W0046_RLSCP WRITE_FLAG( (spsRangeExtension.getReverseLastSigCoeffEnabledFlag() ? 1 : 0), "reverse_last_sig_coeff_enabled_flag" ); #endif +#if !JVET_W2005_RANGE_EXTENSION_PROFILES WRITE_FLAG( (spsRangeExtension.getCabacBypassAlignmentEnabledFlag() ? 1 : 0), "cabac_bypass_alignment_enabled_flag" ); +#endif break; } default: @@ -2625,7 +2641,11 @@ void HLSWriter::codeSliceHeader ( Slice* pcSlice, PicHeader *picHeader ) } +#if JVET_W2005_RANGE_EXTENSION_PROFILES +void HLSWriter::codeConstraintInfo ( const ConstraintInfo* cinfo, const ProfileTierLevel* ptl ) +#else void HLSWriter::codeConstraintInfo ( const ConstraintInfo* cinfo ) +#endif { WRITE_FLAG(cinfo->getGciPresentFlag(), "gci_present_flag"); if (cinfo->getGciPresentFlag()) @@ -2714,9 +2734,25 @@ void HLSWriter::codeConstraintInfo ( const ConstraintInfo* cinfo ) WRITE_FLAG(cinfo->getNoLmcsConstraintFlag() ? 1 : 0, "gci_no_lmcs_constraint_flag"); WRITE_FLAG(cinfo->getNoLadfConstraintFlag() ? 1 : 0, "gci_no_ladf_constraint_flag"); WRITE_FLAG(cinfo->getNoVirtualBoundaryConstraintFlag() ? 1 : 0, "gci_no_virtual_boundaries_constraint_flag"); +#if JVET_W2005_RANGE_EXTENSION_PROFILES + Profile::Name profile = ptl->getProfileIdc(); + if (profile == Profile::MAIN_12 || profile == Profile::MAIN_12_INTRA || profile == Profile::MAIN_12_STILL_PICTURE || + profile == Profile::MAIN_12_444 || profile == Profile::MAIN_12_444_INTRA || profile == Profile::MAIN_12_444_STILL_PICTURE || + profile == Profile::MAIN_16_444 || profile == Profile::MAIN_16_444_INTRA || profile == Profile::MAIN_16_444_STILL_PICTURE) + { + int numReservedBits = 1; + WRITE_CODE(numReservedBits, 8, "gci_num_reserved_bits"); + WRITE_FLAG(cinfo->getLowerBitRateConstraintFlag() ? 1 : 0, "general_lower_bit_rate_constraint_flag"); + } + else + { + WRITE_CODE(0, 8, "gci_num_reserved_bits"); + } +#else //The value of gci_num_reserved_bits shall be equal to 0 in bitstreams conforming to this version of this Specification. //Other values of gci_num_reserved_bits are reserved for future use by ITU-T | ISO/IEC. WRITE_CODE(0, 8, "gci_num_reserved_bits"); +#endif } while (!isByteAligned()) @@ -2740,7 +2776,11 @@ void HLSWriter::codeProfileTierLevel ( const ProfileTierLevel* ptl, bool pro if(profileTierPresentFlag) { +#if JVET_W2005_RANGE_EXTENSION_PROFILES + codeConstraintInfo(ptl->getConstraintInfo(), ptl); +#else codeConstraintInfo(ptl->getConstraintInfo()); +#endif } for (int i = maxNumSubLayersMinus1 - 1; i >= 0; i--) diff --git a/source/Lib/EncoderLib/VLCWriter.h b/source/Lib/EncoderLib/VLCWriter.h index 8b95e8e2efb779bebf35d3f38eef216c1e7c9213..ed1ff32d38b1b528d5186b26107b734139025b71 100644 --- a/source/Lib/EncoderLib/VLCWriter.h +++ b/source/Lib/EncoderLib/VLCWriter.h @@ -142,7 +142,11 @@ public: void codePictureHeader ( PicHeader* picHeader, bool writeRbspTrailingBits, Slice *slice = 0 ); void codeSliceHeader ( Slice* pcSlice, PicHeader *picheader = 0 ); void codeOPI ( const OPI* opi ); +#if JVET_W2005_RANGE_EXTENSION_PROFILES + void codeConstraintInfo ( const ConstraintInfo* cinfo, const ProfileTierLevel* ptl ); +#else void codeConstraintInfo ( const ConstraintInfo* cinfo ); +#endif void codeProfileTierLevel ( const ProfileTierLevel* ptl, bool profileTierPresentFlag, int maxNumSubLayersMinus1 ); void codeOlsHrdParameters(const GeneralHrdParams * generalHrd, const OlsHrdParams *olsHrd , const uint32_t firstSubLayer, const uint32_t maxNumSubLayersMinus1);