From e650821fb49a70ba998b8130ea443e5a45ac56d9 Mon Sep 17 00:00:00 2001 From: Karl Sharman <karl.sharman@sony.com> Date: Mon, 22 Jun 2020 22:07:50 +0100 Subject: [PATCH] Added support for still picture profiles. --- doc/software-manual.tex | 16 ++------- source/App/EncoderApp/EncApp.cpp | 7 ++-- source/App/EncoderApp/EncAppCfg.cpp | 42 +++++++++++++++++++++++ source/App/EncoderApp/EncAppCfg.h | 3 ++ source/Lib/CommonLib/ProfileLevelTier.cpp | 15 ++++++++ source/Lib/CommonLib/ProfileLevelTier.h | 3 ++ source/Lib/CommonLib/TypeDef.h | 2 ++ source/Lib/DecoderLib/VLCReader.cpp | 3 ++ source/Lib/EncoderLib/EncCfg.h | 9 +++++ source/Lib/EncoderLib/EncLib.cpp | 3 ++ source/Lib/EncoderLib/VLCWriter.cpp | 3 ++ 11 files changed, 91 insertions(+), 15 deletions(-) diff --git a/doc/software-manual.tex b/doc/software-manual.tex index 92d138e03..fd102af34 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 a0d08c1f7..d99205950 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 9fa5b1a7f..fd6929190 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 7d2f9bc60..a8ae374f1 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 d482eb656..2469621fd 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 68149beb4..596963f6a 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 fda661919..3efce71b4 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 a4d1a75d8..e35ef1bf6 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 05e943559..39080be66 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 9be7d2a03..dbeb05e88 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 c5ee7bac6..f43537092 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" ); -- GitLab