diff --git a/doc/software-manual.tex b/doc/software-manual.tex index 92d138e03c3a1a2f47b898361a2e45646984579b..fd102af34c2d32dec1527d9682835ed7cb857998 100644 --- a/doc/software-manual.tex +++ b/doc/software-manual.tex @@ -954,18 +954,8 @@ multiple matches. \Default{none} & Specifies the profile to which the encoded bitstream complies. -Valid HEVC Ver. 1 values are: none, main, main10, main-still-picture - -Valid HEVC Ver. 2 (RExt) values are: main-RExt, high-throughput-RExt, -monochrome, monochrome12, monochrome16, main12, main_422_10, -main_422_12, main_444, main_444_10, main_444_12, main_444_16, -main_intra, main_10_intra, main_12_intra, main_422_10_intra, main_422_12_intra, -main_444_intra, main_444_10_intra, main_444_12_intra, main_444_16_intra. - -When main-RExt is specified, the constraint flags are either manually specified, or calculated via the other supplied settings. - -Compatibility flags are automatically determined according to the profile. -NB: There is currently only limited validation that the encoder configuration complies with the profile, level and tier constraints. +Valid VVC Ver. 1 values are: none, main_10, main_10_still_picture, main_444_10, main_444_10_still_picture. +When one of the still picture profiles are selected, the OnePictureOnlyConstraintFlag setting will be forced to 1. \\ \Option{Level} & @@ -1019,7 +1009,7 @@ For --profile=main-RExt, specifies the value of general_intra_constraint_flag to \Option{OnePictureOnlyConstraintFlag} & %\ShortOption{\None} & \Default{false} & -For --profile=main-RExt, specifies the value of general_one_picture_only_constraint_flag to use for RExt profiles. +Specifies the value of general_one_picture_only_constraint_flag. \\ \Option{LowerBitRateConstraintFlag} & diff --git a/source/App/EncoderApp/EncApp.cpp b/source/App/EncoderApp/EncApp.cpp index a0d08c1f71b2a4611e78289272515864a0eb1de7..d992059502eee4d52a2a149dd97e2db76ecf2d74 100644 --- a/source/App/EncoderApp/EncApp.cpp +++ b/source/App/EncoderApp/EncApp.cpp @@ -264,10 +264,13 @@ void EncApp::xInitLibCfg() m_cEncLib.setFramesToBeEncoded ( m_framesToBeEncoded ); //====== SPS constraint flags ======= - m_cEncLib.setIntraOnlyConstraintFlag ( m_intraConstraintFlag ); +#if STILL_PICTURE_PROFILES + m_cEncLib.setOnePictureOnlyConstraintFlag ( m_onePictureOnlyConstraintFlag ); +#endif + m_cEncLib.setIntraOnlyConstraintFlag ( m_intraConstraintFlag ); // NOTE: This setting is not used, and is confused with setIntraConstraintFlag m_cEncLib.setMaxBitDepthConstraintIdc ( m_bitDepthConstraint - 8 ); m_cEncLib.setMaxChromaFormatConstraintIdc ( m_chromaFormatConstraint ); - m_cEncLib.setFrameConstraintFlag ( m_bFrameConstraintFlag ); + m_cEncLib.setFrameConstraintFlag ( m_bFrameConstraintFlag ); // NOTE: This setting is neither used nor setup, and is confused with setFrameOnlyConstraintFlag m_cEncLib.setNoQtbttDualTreeIntraConstraintFlag ( !m_dualTree ); m_cEncLib.setNoPartitionConstraintsOverrideConstraintFlag ( !m_SplitConsOverrideEnabledFlag ); m_cEncLib.setNoSaoConstraintFlag ( !m_bUseSAO ); diff --git a/source/App/EncoderApp/EncAppCfg.cpp b/source/App/EncoderApp/EncAppCfg.cpp index 9fa5b1a7f57342034f6746fdb01aa2a0fd63af62..fd69291907fbf11bebd93a8b73990eff2f7ce25f 100644 --- a/source/App/EncoderApp/EncAppCfg.cpp +++ b/source/App/EncoderApp/EncAppCfg.cpp @@ -60,9 +60,17 @@ namespace po = df::program_options_lite; enum ExtendedProfileName // this is used for determining profile strings, where multiple profiles map to a single profile idc with various constraint flag combinations { +#if STILL_PICTURE_PROFILES + NONE, + MAIN_10, + MAIN_10_STILL_PICTURE, + MAIN_444_10, + MAIN_444_10_STILL_PICTURE, +#else NONE = Profile::NONE, MAIN_10 = Profile::MAIN_10, MAIN_444_10 = Profile::MAIN_444_10, +#endif AUTO = -1 }; @@ -237,6 +245,10 @@ strToExtendedProfile[] = {"none", NONE }, {"main_10", MAIN_10 }, {"main_444_10", MAIN_444_10 }, +#if STILL_PICTURE_PROFILES + {"main_10_still_picture", MAIN_10_STILL_PICTURE }, + {"main_444_10_still_picture", MAIN_444_10_STILL_PICTURE }, +#endif {"auto", AUTO } }; @@ -819,14 +831,23 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) ("HarmonizeGopFirstFieldCoupleEnabled", m_bHarmonizeGopFirstFieldCoupleEnabled, true, "Enables harmonization of Gop first field couple") // Profile and level +#if STILL_PICTURE_PROFILES + ("Profile", extendedProfile, ExtendedProfileName::NONE, "Profile name to use for encoding. Use main_10, main_10_still_picture, main_444_10, main_444_10_still_picture, auto, or none") +#else ("Profile", extendedProfile, ExtendedProfileName::NONE, "Profile name to use for encoding. Use main_10, main_444_10, auto, or none") +#endif ("Level", m_level, Level::NONE, "Level limit to be used, eg 5.1, or none") ("Tier", m_levelTier, Level::MAIN, "Tier to use for interpretation of --Level (main or high only)") ("SubProfile", cfg_SubProfile, cfg_SubProfile, "Sub-profile idc") ("EnableDecodingCapabilityInformation", m_DCIEnabled, false, "Enables writing of Decoding Capability Information") ("MaxBitDepthConstraint", m_bitDepthConstraint, 0u, "Bit depth to use for profile-constraint for RExt profiles. 0=automatically choose based upon other parameters") ("MaxChromaFormatConstraint", tmpConstraintChromaFormat, 0, "Chroma-format to use for the profile-constraint for RExt profiles. 0=automatically choose based upon other parameters") +#if STILL_PICTURE_PROFILES + ("OnePictureOnlyConstraintFlag", m_onePictureOnlyConstraintFlag, false, "Value of general_intra_constraint_flag. Can only be used for single frame encodings. Will be set to true for still picture profiles") + ("IntraConstraintFlag", m_intraConstraintFlag, false, "Value of intra_only_constraint_flag") +#else ("IntraConstraintFlag", m_intraConstraintFlag, false, "Value of general_intra_constraint_flag to use for RExt profiles (not used if an explicit RExt sub-profile is specified)") +#endif #if !JVET_R0090_VUI ("ProgressiveSource", m_progressiveSourceFlag, false, "Indicate that source is progressive") @@ -1812,7 +1833,21 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) } else { +#if STILL_PICTURE_PROFILES + switch (extendedProfile) + { + case ExtendedProfileName::NONE: m_profile = Profile::NONE; break; + case ExtendedProfileName::MAIN_10: m_profile = Profile::MAIN_10; break; + case ExtendedProfileName::MAIN_444_10: m_profile = Profile::MAIN_444_10; break; + case ExtendedProfileName::MAIN_10_STILL_PICTURE: m_profile = Profile::MAIN_10; m_onePictureOnlyConstraintFlag = true; break; + case ExtendedProfileName::MAIN_444_10_STILL_PICTURE: m_profile = Profile::MAIN_444_10; m_onePictureOnlyConstraintFlag = true; break; + default: + EXIT( "Unable to determine profile from configured settings"); + break; + } +#else m_profile = Profile::Name(extendedProfile); +#endif } { @@ -2557,6 +2592,13 @@ bool EncAppCfg::xCheckParameter() xConfirmPara (m_log2MaxTransformSkipBlockSize < 2, "Transform Skip Log2 Max Size must be at least 2 (4x4)"); +#if STILL_PICTURE_PROFILES + xConfirmPara ( m_onePictureOnlyConstraintFlag && m_framesToBeEncoded!=1, "When onePictureOnlyConstraintFlag is true, the number of frames to be encoded must be 1" ); + if (m_profile == Profile::MAIN_10 || m_profile==Profile::MAIN_444_10) + { + xConfirmPara ( m_level==Level::LEVEL15_5 && !m_onePictureOnlyConstraintFlag, "Currently the only profiles that support level 15.5 are still pictures, which require onePictureOnlyConstraintFlag to be 1" ); + } +#endif if( m_SubPuMvpMode == 3 && m_maxNumMergeCand < 7 ) { diff --git a/source/App/EncoderApp/EncAppCfg.h b/source/App/EncoderApp/EncAppCfg.h index 7d2f9bc6052729ecfb26a947950afee06a211644..a8ae374f1f992633a2885b4c11cb00beb79b265a 100644 --- a/source/App/EncoderApp/EncAppCfg.h +++ b/source/App/EncoderApp/EncAppCfg.h @@ -196,6 +196,9 @@ protected: uint32_t m_bitDepthConstraint; ChromaFormat m_chromaFormatConstraint; +#if STILL_PICTURE_PROFILES + bool m_onePictureOnlyConstraintFlag; +#endif bool m_intraConstraintFlag; #if !JVET_R0090_VUI bool m_progressiveSourceFlag; diff --git a/source/Lib/CommonLib/ProfileLevelTier.cpp b/source/Lib/CommonLib/ProfileLevelTier.cpp index d482eb656a27baa69d1eb57cd6ae61e7c3bacf86..2469621fdcc443f9aa7525e44b6fe7558c7e05ad 100644 --- a/source/Lib/CommonLib/ProfileLevelTier.cpp +++ b/source/Lib/CommonLib/ProfileLevelTier.cpp @@ -87,8 +87,16 @@ static const LevelTierFeatures mainLevelTierInfo[] = static const ProfileFeatures validProfiles[] = #if JVET_R0244_CPB_AND_MINCR { // profile, pNameString, maxBitDepth, maxChrFmt, lvl15.5, cpbvcl, cpbnal, fcf*1000, mincr*100, levelInfo +#if STILL_PICTURE_PROFILES + // most constrained profiles must appear first. + { Profile::MAIN_10, "Main_10_Still_Picture", 10, CHROMA_420, true, 1000, 1100, 1875, 100 , mainLevelTierInfo, true }, + { Profile::MAIN_444_10, "Main_444_10_Still_Picture", 10, CHROMA_444, true, 2500, 2750, 3750, 75 , mainLevelTierInfo, true }, + { Profile::MAIN_10, "Main_10", 10, CHROMA_420, false, 1000, 1100, 1875, 100 , mainLevelTierInfo, false }, + { Profile::MAIN_444_10, "Main_444_10", 10, CHROMA_444, false, 2500, 2750, 3750, 75 , mainLevelTierInfo, false }, +#else { Profile::MAIN_10, "Main_10", 10, CHROMA_420, false, 1000, 1100, 1875, 100 , mainLevelTierInfo }, { Profile::MAIN_444_10, "Main_444_10", 10, CHROMA_444, false, 2500, 2750, 3750, 75 , mainLevelTierInfo }, +#endif #else { // profile, pNameString, maxBitDepth, maxChrFmt, lvl8.5, cpbvcl, cpbnal, fcf*1000, mincr*10, levelInfo { Profile::MAIN_10, "Main_10", 10, CHROMA_420, false, 1000, 1100, 1875, 10 , mainLevelTierInfo }, @@ -105,9 +113,16 @@ ProfileLevelTierFeatures::extractPTLInformation(const SPS &sps) m_tier = spsPtl.getTierFlag(); // Identify the profile from the profile Idc, and possibly other constraints. +#if STILL_PICTURE_PROFILES + bool onePictureOnlyConstraintFlag=spsPtl.getConstraintInfo()->getOnePictureOnlyConstraintFlag(); +#endif for(int32_t i=0; validProfiles[i].profile != Profile::NONE; i++) { +#if STILL_PICTURE_PROFILES + if (spsPtl.getProfileIdc() == validProfiles[i].profile && !(validProfiles[i].onePictureOnlyFlagMustBe1 && !onePictureOnlyConstraintFlag)) +#else if (spsPtl.getProfileIdc() == validProfiles[i].profile) +#endif { m_pProfile = &(validProfiles[i]); break; diff --git a/source/Lib/CommonLib/ProfileLevelTier.h b/source/Lib/CommonLib/ProfileLevelTier.h index 68149beb4fe6be49b834a6d41b82713c1725b2fa..596963f6a48c84515b7915fee09a11d59b766937 100644 --- a/source/Lib/CommonLib/ProfileLevelTier.h +++ b/source/Lib/CommonLib/ProfileLevelTier.h @@ -84,6 +84,9 @@ struct ProfileFeatures uint32_t minCrScaleFactorx10; #endif const LevelTierFeatures *pLevelTiersListInfo; +#if STILL_PICTURE_PROFILES + bool onePictureOnlyFlagMustBe1; +#endif }; diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index fda66191973cce660b3a6b2c2a499598c336c300..3efce71b4d33fc8be45a1eefcc8a96cc4fcd0e5a 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -245,6 +245,8 @@ #define JVET_R0245_LEVEL_CODING 1 // JVET-R0245: level coding numbering scheme +#define STILL_PICTURE_PROFILES 1 // Adds support for still picture profiles + //########### place macros to be be kept below this line ############### #define JVET_R0164_MEAN_SCALED_SATD 1 // JVET-R0164: Use a mean scaled version of SATD in encoder decisions diff --git a/source/Lib/DecoderLib/VLCReader.cpp b/source/Lib/DecoderLib/VLCReader.cpp index a4d1a75d8e298e06379bdaacb54a079212518966..e35ef1bf6114d940e2ed5df6f93dcab0014576a9 100644 --- a/source/Lib/DecoderLib/VLCReader.cpp +++ b/source/Lib/DecoderLib/VLCReader.cpp @@ -4978,6 +4978,9 @@ void HLSyntaxReader::parseConstraintInfo(ConstraintInfo *cinfo) READ_FLAG(symbol, "general_non_packed_constraint_flag" ); cinfo->setNonPackedConstraintFlag(symbol ? true : false); READ_FLAG(symbol, "general_frame_only_constraint_flag" ); cinfo->setFrameOnlyConstraintFlag(symbol ? true : false); READ_FLAG(symbol, "general_non_projected_constraint_flag" ); cinfo->setNonProjectedConstraintFlag(symbol ? true : false); +#if STILL_PICTURE_PROFILES + READ_FLAG(symbol, "general_one_picture_only_constraint_flag" ); cinfo->setOnePictureOnlyConstraintFlag(symbol ? true : false); +#endif READ_FLAG(symbol, "intra_only_constraint_flag" ); cinfo->setIntraOnlyConstraintFlag(symbol ? true : false); READ_CODE(4, symbol, "max_bitdepth_constraint_idc" ); cinfo->setMaxBitDepthConstraintIdc(symbol); diff --git a/source/Lib/EncoderLib/EncCfg.h b/source/Lib/EncoderLib/EncCfg.h index 05e943559878562d84217bb51e01807f0b46762b..39080be66953556c511cfa2249122ecd44a56965 100644 --- a/source/Lib/EncoderLib/EncCfg.h +++ b/source/Lib/EncoderLib/EncCfg.h @@ -175,6 +175,9 @@ protected: bool m_printSequenceMSE; bool m_cabacZeroWordPaddingEnabled; +#if STILL_PICTURE_PROFILES + bool m_onePictureOnlyConstraintFlag; +#endif bool m_bIntraOnlyConstraintFlag; uint32_t m_maxBitDepthConstraintIdc; uint32_t m_maxChromaFormatConstraintIdc; @@ -790,6 +793,12 @@ public: void setLevel(Level::Tier tier, Level::Name level) { m_levelTier = tier; m_level = level; } void setNumSubProfile( uint8_t numSubProfile) { m_numSubProfile = numSubProfile; m_subProfile.resize(m_numSubProfile); } void setSubProfile( int i, uint32_t subProfile) { m_subProfile[i] = subProfile; } + +#if STILL_PICTURE_PROFILES + bool getOnePictureOnlyConstraintFlag() const { return m_onePictureOnlyConstraintFlag; } + void setOnePictureOnlyConstraintFlag(bool b) { m_onePictureOnlyConstraintFlag=b; } +#endif + bool getIntraOnlyConstraintFlag() const { return m_bIntraOnlyConstraintFlag; } void setIntraOnlyConstraintFlag(bool bVal) { m_bIntraOnlyConstraintFlag = bVal; } uint32_t getMaxBitDepthConstraintIdc() const { return m_maxBitDepthConstraintIdc; } diff --git a/source/Lib/EncoderLib/EncLib.cpp b/source/Lib/EncoderLib/EncLib.cpp index 9be7d2a03a5dde64c39b4af6aa0c7128818ac286..dbeb05e88b6e2382c27952287feb6457e62a0ffb 100644 --- a/source/Lib/EncoderLib/EncLib.cpp +++ b/source/Lib/EncoderLib/EncLib.cpp @@ -1142,6 +1142,9 @@ void EncLib::xInitSPS( SPS& sps ) cinfo->setOneSlicePerPicConstraintFlag(m_oneSlicePerPicConstraintFlag); cinfo->setOneSubpicPerPicConstraintFlag(m_oneSubpicPerPicConstraintFlag); cinfo->setFrameOnlyConstraintFlag (m_frameOnlyConstraintFlag); +#if STILL_PICTURE_PROFILES + cinfo->setOnePictureOnlyConstraintFlag(m_onePictureOnlyConstraintFlag); +#endif cinfo->setIntraOnlyConstraintFlag (m_intraConstraintFlag); cinfo->setMaxBitDepthConstraintIdc (m_maxBitDepthConstraintIdc); cinfo->setMaxChromaFormatConstraintIdc((ChromaFormat)m_maxChromaFormatConstraintIdc); diff --git a/source/Lib/EncoderLib/VLCWriter.cpp b/source/Lib/EncoderLib/VLCWriter.cpp index c5ee7bac68a6bee83468b1d102125ed9bd7979ce..f4353709226a82a221b784765ce594b57a83f8aa 100644 --- a/source/Lib/EncoderLib/VLCWriter.cpp +++ b/source/Lib/EncoderLib/VLCWriter.cpp @@ -2887,6 +2887,9 @@ void HLSWriter::codeConstraintInfo ( const ConstraintInfo* cinfo ) WRITE_FLAG(cinfo->getNonPackedConstraintFlag(), "general_non_packed_constraint_flag" ); WRITE_FLAG(cinfo->getFrameOnlyConstraintFlag(), "general_frame_only_constraint_flag" ); WRITE_FLAG(cinfo->getNonProjectedConstraintFlag(), "general_non_projected_constraint_flag"); +#if STILL_PICTURE_PROFILES + WRITE_FLAG(cinfo->getOnePictureOnlyConstraintFlag(), "general_one_picture_only_constraint_flag" ); +#endif WRITE_FLAG(cinfo->getIntraOnlyConstraintFlag(), "intra_only_constraint_flag" ); WRITE_CODE(cinfo->getMaxBitDepthConstraintIdc(), 4, "max_bitdepth_constraint_idc" );