[x265] [PATCH SCC 02/09] Add profiletier, sps, pps MainScc profile support for scc extension

patoo34 at free.fr patoo34 at free.fr
Wed Aug 7 20:56:25 UTC 2024



----- Mail original -----
> 
> STOP STOP STOP STOP STOP
> don't send me anything anymore
> 
> ----- Mail original -----
> > 
> > 
> > From 85c51ad5a99db52001e254296ae64335074e47a5 Mon Sep 17 00:00:00
> > 2001
> > From: AnusuyaKumarasamy < anusuya.kumarasamy at multicorewareinc.com >
> > Date: Thu, 18 Jul 2024 20:37:58 +0530
> > Subject: [PATCH 2/9] Add profiletier, sps, pps MainScc profile
> > support for scc
> > extension
> > 
> > ---
> > source/common/slice.h | 5 ++-
> > source/encoder/encoder.cpp | 8 ++++
> > source/encoder/entropy.cpp | 48 +++++++++++++++++---
> > source/encoder/level.cpp | 92
> > +++++++++++++++++++++++++++++++++++---
> > source/x265.h | 6 +++
> > 5 files changed, 147 insertions(+), 12 deletions(-)
> > 
> > diff --git a/source/common/slice.h b/source/common/slice.h
> > index 0d6807952..add5948f8 100644
> > --- a/source/common/slice.h
> > +++ b/source/common/slice.h
> > @@ -76,7 +76,8 @@ namespace Profile {
> > HIGHTHROUGHPUTREXT = 5,
> > MULTIVIEWMAIN = 6,
> > SCALABLEMAIN = 7,
> > - SCALABLEMAIN10 = 8
> > + SCALABLEMAIN10 = 8,
> > + MAINSCC = 9
> > };
> > }
> > 
> > @@ -324,6 +325,8 @@ struct PPS
> > 
> > bool pps_extension_flag;
> > int maxViews;
> > +
> > + int profileIdc;
> > };
> > 
> > struct WeightParam
> > diff --git a/source/encoder/encoder.cpp
> > b/source/encoder/encoder.cpp
> > index ff8f53883..095009200 100644
> > --- a/source/encoder/encoder.cpp
> > +++ b/source/encoder/encoder.cpp
> > @@ -3656,6 +3656,8 @@ void Encoder::initSPS(SPS *sps)
> > }
> > #endif
> > 
> > + sps->sps_extension_flag = m_param->bEnableSCC ? true : false;
> > +
> > }
> > 
> > void Encoder::initPPS(PPS *pps)
> > @@ -3710,6 +3712,12 @@ void Encoder::initPPS(PPS *pps)
> > pps->maxViews = m_param->numViews;
> > }
> > #endif
> > +
> > + if (m_param->bEnableSCC)
> > + {
> > + pps->profileIdc = Profile::MAINSCC;
> > + pps->pps_extension_flag = true;
> > + }
> > }
> > 
> > void Encoder::configureZone(x265_param *p, x265_param *zone)
> > diff --git a/source/encoder/entropy.cpp
> > b/source/encoder/entropy.cpp
> > index 0e45b4976..400a7dd8e 100644
> > --- a/source/encoder/entropy.cpp
> > +++ b/source/encoder/entropy.cpp
> > @@ -585,7 +585,7 @@ void Entropy::codeSPS(const SPS& sps, const
> > ScalingList& scalingList, const Prof
> > WRITE_FLAG(sps.sps_extension_flag, "sps_extension_flag");
> > 
> > #if ENABLE_MULTIVIEW
> > - if (sps.sps_extension_flag)
> > + if (sps.sps_extension_flag && sps.maxViews > 1)
> > {
> > WRITE_FLAG(0, "sps_range_extensions_flag");
> > WRITE_FLAG(sps.maxViews > 1, "sps_multilayer_extension_flag");
> > @@ -598,6 +598,18 @@ void Entropy::codeSPS(const SPS& sps, const
> > ScalingList& scalingList, const Prof
> > WRITE_FLAG(1, "inter_view_mv_vert_constraint_flag");
> > }
> > #endif
> > +
> > + if (ptl.profileIdc[0] == Profile::MAINSCC)
> > + {
> > + bool sps_extension_flags[NUM_EXTENSION_FLAGS] = { false };
> > + sps_extension_flags[SCC_EXT_IDX] = true;
> > + for (int i = 0; i < NUM_EXTENSION_FLAGS; i++)
> > + WRITE_FLAG(sps_extension_flags[i], "sps_extension_flag");
> > + WRITE_FLAG(1, "intra_block_copy_enabled_flag");
> > + WRITE_FLAG(0, "palette_mode_enabled_flag");
> > + WRITE_CODE(0, 2, "motion_vector_resolution_control_idc");
> > + WRITE_FLAG(0, "intra_boundary_filter_disabled_flag");
> > + }
> > }
> > 
> > void Entropy::codePPS( const PPS& pps, bool filerAcross, int
> > iPPSInitQpMinus26, int layer)
> > @@ -650,7 +662,7 @@ void Entropy::codePPS( const PPS& pps, bool
> > filerAcross, int iPPSInitQpMinus26,
> > WRITE_FLAG(pps.pps_extension_flag, "pps_extension_flag");
> > 
> > #if ENABLE_MULTIVIEW
> > - if (pps.pps_extension_flag)
> > + if (pps.pps_extension_flag && pps.maxViews > 1)
> > {
> > WRITE_FLAG(0, "pps_range_extensions_flag");
> > WRITE_FLAG(pps.maxViews > 1, "pps_multilayer_extension_flag");
> > @@ -666,6 +678,18 @@ void Entropy::codePPS( const PPS& pps, bool
> > filerAcross, int iPPSInitQpMinus26,
> > }
> > }
> > #endif
> > +
> > +
> > + if (pps.profileIdc == Profile::MAINSCC)
> > + {
> > + bool pps_extension_flags[NUM_EXTENSION_FLAGS] = { false };
> > + pps_extension_flags[SCC_EXT_IDX] = true;
> > + for (int i = 0; i < NUM_EXTENSION_FLAGS; i++)
> > + WRITE_FLAG(pps_extension_flags[i], "pps_extension_flag");
> > + WRITE_FLAG(1, "curr_pic_as_ref_enabled_pps_flag");
> > + WRITE_FLAG(0, "adaptive_colour_trans_flag");
> > + WRITE_FLAG(0, "palette_predictor_initializer_flag");
> > + }
> > }
> > 
> > void Entropy::codeProfileTier(const ProfileTierLevel& ptl, int
> > maxTempSubLayers, int layer)
> > @@ -686,7 +710,7 @@ void Entropy::codeProfileTier(const
> > ProfileTierLevel& ptl, int maxTempSubLayers,
> > WRITE_FLAG(ptl.nonPackedConstraintFlag,
> > "general_non_packed_constraint_flag");
> > WRITE_FLAG(ptl.frameOnlyConstraintFlag,
> > "general_frame_only_constraint_flag");
> > 
> > - if (ptl.profileIdc[layer] == Profile::MAINREXT ||
> > ptl.profileIdc[layer] == Profile::HIGHTHROUGHPUTREXT ||
> > ptl.profileIdc[layer] == Profile::SCALABLEMAIN ||
> > ptl.profileIdc[layer] == Profile::SCALABLEMAIN10 ||
> > ptl.profileIdc[layer] == Profile::MULTIVIEWMAIN)
> > + if (ptl.profileIdc[layer] == Profile::MAINREXT ||
> > ptl.profileIdc[layer] == Profile::HIGHTHROUGHPUTREXT ||
> > ptl.profileIdc[layer] == Profile::SCALABLEMAIN ||
> > ptl.profileIdc[layer] == Profile::SCALABLEMAIN10 ||
> > ptl.profileIdc[layer] == Profile::MULTIVIEWMAIN ||
> > ptl.profileIdc[layer] == Profile::MAINSCC)
> > {
> > uint32_t bitDepthConstraint = ptl.bitDepthConstraint;
> > int csp = ptl.chromaFormatConstraint;
> > @@ -699,9 +723,19 @@ void Entropy::codeProfileTier(const
> > ProfileTierLevel& ptl, int maxTempSubLayers,
> > WRITE_FLAG(ptl.intraConstraintFlag,
> > "general_intra_constraint_flag");
> > WRITE_FLAG(ptl.onePictureOnlyConstraintFlag,"general_one_picture_only_constraint_flag");
> > WRITE_FLAG(ptl.lowerBitRateConstraintFlag,
> > "general_lower_bit_rate_constraint_flag");
> > - WRITE_CODE(0 , 16, "XXX_reserved_zero_35bits[0..15]");
> > - WRITE_CODE(0 , 16, "XXX_reserved_zero_35bits[16..31]");
> > - WRITE_CODE(0 , 3, "XXX_reserved_zero_35bits[32..34]");
> > + if (ptl.profileIdc[layer] == Profile::MAINSCC)
> > + {
> > + WRITE_FLAG(bitDepthConstraint <= 14,
> > "max_14bit_constraint_flag");
> > + WRITE_CODE(0, 16, "reserved_zero_33bits[0..15]");
> > + WRITE_CODE(0, 16, "reserved_zero_33bits[16..31]");
> > + WRITE_FLAG(0, "reserved_zero_33bits[32]");
> > + }
> > + else
> > + {
> > + WRITE_CODE(0, 16, "XXX_reserved_zero_35bits[0..15]");
> > + WRITE_CODE(0, 16, "XXX_reserved_zero_35bits[16..31]");
> > + WRITE_CODE(0, 3, "XXX_reserved_zero_35bits[32..34]");
> > + }
> > }
> > else
> > {
> > @@ -709,6 +743,8 @@ void Entropy::codeProfileTier(const
> > ProfileTierLevel& ptl, int maxTempSubLayers,
> > WRITE_CODE(0, 16, "XXX_reserved_zero_44bits[16..31]");
> > WRITE_CODE(0, 12, "XXX_reserved_zero_44bits[32..43]");
> > }
> > + if (ptl.profileIdc[layer] == Profile::MAINSCC)
> > + WRITE_FLAG(false, "inbld_flag");
> > 
> > WRITE_CODE(ptl.levelIdc, 8, "general_level_idc");
> > 
> > diff --git a/source/encoder/level.cpp b/source/encoder/level.cpp
> > index 12803baff..b5af25b4f 100644
> > --- a/source/encoder/level.cpp
> > +++ b/source/encoder/level.cpp
> > @@ -60,6 +60,40 @@ LevelSpec levels[] =
> > { MAX_UINT, MAX_UINT, MAX_UINT, MAX_UINT, MAX_UINT, MAX_UINT, 1,
> > Level::LEVEL8_5, "8.5", 85 },
> > };
> > 
> > +enum SCCProfileName
> > +{
> > + NONE = 0,
> > + // The following are SCC profiles, which would map to the MAINSCC
> > profile idc.
> > + // The enumeration indicates the bit-depth constraint in the
> > bottom
> > 2 digits
> > + // the chroma format in the next digit
> > + // the intra constraint in the next digit
> > + // If it is a SCC profile there is a '2' for the next digit.
> > + // If it is a highthroughput , there is a '2' for the top digit
> > else '1' for the top digit
> > + SCC_MAIN = 121108,
> > + SCC_MAIN_10 = 121110,
> > + SCC_MAIN_444 = 121308,
> > + SCC_MAIN_444_10 = 121310,
> > +};
> > +
> > +static const SCCProfileName validSCCProfileNames[1][4/* bit depth
> > constraint 8=0, 10=1, 12=2, 14=3*/][4/*chroma format*/] =
> > +{
> > + {
> > + { NONE, SCC_MAIN, NONE, SCC_MAIN_444 }, // 8-bit intra for 400,
> > 420, 422 and 444
> > + { NONE, SCC_MAIN_10, NONE, SCC_MAIN_444_10 }, // 10-bit intra for
> > 400, 420, 422 and 444
> > + { NONE, NONE, NONE, NONE }, // 12-bit intra for 400, 420, 422 and
> > 444
> > + { NONE, NONE, NONE, NONE } // 16-bit intra for 400, 420, 422 and
> > 444
> > + },
> > +};
> > +
> > +static inline int _confirm(x265_param* param, bool bflag, const
> > char* message)
> > +{
> > + if (!bflag)
> > + return 0;
> > +
> > + x265_log(param, X265_LOG_ERROR, "%s\n", message);
> > + return 1;
> > +}
> > +
> > /* determine minimum decoder level required to decode the described
> > video */
> > void determineLevel(const x265_param &param, VPS& vps)
> > {
> > @@ -79,7 +113,9 @@ void determineLevel(const x265_param &param,
> > VPS&
> > vps)
> > /* Probably an HEVC v1 profile, but must check to be sure */
> > if (param.internalBitDepth <= 8)
> > {
> > - if (vps.ptl.onePictureOnlyConstraintFlag)
> > + if (param.bEnableSCC)
> > + vps.ptl.profileIdc[0] = Profile::MAINSCC;
> > + else if (vps.ptl.onePictureOnlyConstraintFlag)
> > vps.ptl.profileIdc[0] = Profile::MAINSTILLPICTURE;
> > else if (vps.ptl.intraConstraintFlag)
> > vps.ptl.profileIdc[0] = Profile::MAINREXT; /* Main Intra */
> > @@ -94,7 +130,9 @@ void determineLevel(const x265_param &param,
> > VPS&
> > vps)
> > else if (param.internalBitDepth <= 10)
> > {
> > /* note there is no 10bit still picture profile */
> > - if (vps.ptl.intraConstraintFlag)
> > + if (param.bEnableSCC)
> > + vps.ptl.profileIdc[0] = Profile::MAINSCC;
> > + else if (vps.ptl.intraConstraintFlag)
> > vps.ptl.profileIdc[0] = Profile::MAINREXT; /* Main10 Intra */
> > else
> > vps.ptl.profileIdc[0] = Profile::MAIN10;
> > @@ -114,6 +152,11 @@ void determineLevel(const x265_param &param,
> > VPS& vps)
> > #endif
> > 
> > /* determine which profiles are compatible with this stream */
> > + if (vps.ptl.profileIdc[0] == Profile::MAINSCC)
> > + {
> > + vps.ptl.onePictureOnlyConstraintFlag = false;
> > + vps.ptl.intraConstraintFlag = param.keyframeMax <= 1 ||
> > vps.ptl.onePictureOnlyConstraintFlag;
> > + }
> > 
> > memset(vps.ptl.profileCompatibilityFlag, 0,
> > sizeof(vps.ptl.profileCompatibilityFlag));
> > vps.ptl.profileCompatibilityFlag[vps.ptl.profileIdc[0]] = true;
> > @@ -128,6 +171,8 @@ void determineLevel(const x265_param &param,
> > VPS&
> > vps)
> > }
> > else if (vps.ptl.profileIdc[0] == Profile::MAINREXT)
> > vps.ptl.profileCompatibilityFlag[Profile::MAINREXT] = true;
> > + else if (vps.ptl.profileIdc[0] == Profile::MAINSCC)
> > + vps.ptl.profileCompatibilityFlag[Profile::MAINSCC] = true;
> > 
> > uint32_t lumaSamples = param.sourceWidth * param.sourceHeight;
> > uint32_t samplesPerSec = (uint32_t)(lumaSamples *
> > ((double)param.fpsNum / param.fpsDenom));
> > @@ -232,7 +277,23 @@ void determineLevel(const x265_param &param,
> > VPS& vps)
> > break;
> > }
> > 
> > - static const char *profiles[] = { "None", "Main", "Main 10",
> > "Main
> > Still Picture", "RExt" };
> > + x265_param m_param = param;
> > +#define CHECK(expr, msg) check_failed |= _confirm(&m_param, expr,
> > msg)
> > + int check_failed = 0; /* abort if there is a fatal configuration
> > problem */
> > +
> > + if (vps.ptl.profileIdc[0] == Profile::MAINSCC)
> > + {
> > + CHECK(vps.ptl.lowerBitRateConstraintFlag == false &&
> > vps.ptl.intraConstraintFlag == false, "The lowerBitRateConstraint
> > flag cannot be false when intraConstraintFlag is false");
> > + CHECK(param.bEnableSCC && !(vps.ptl.profileIdc[0] ==
> > Profile::MAINSCC), "UseIntraBlockCopy must not be enabled unless
> > the
> > SCC profile is being used.");
> > + CHECK(vps.ptl.intraConstraintFlag, "intra constraint flag must be
> > 0
> > for SCC profiles");
> > + CHECK(vps.ptl.onePictureOnlyConstraintFlag, "one-picture-only
> > constraint flag shall be 0 for SCC profiles");
> > + const uint32_t bitDepthIdx = (vps.ptl.bitDepthConstraint == 8 ? 0
> > :
> > (vps.ptl.bitDepthConstraint == 10 ? 1 : (vps.ptl.bitDepthConstraint
> > == 12 ? 2 : (vps.ptl.bitDepthConstraint == 16 ? 3 : 4))));
> > + const uint32_t chromaFormatIdx =
> > uint32_t(vps.ptl.chromaFormatConstraint);
> > + const bool bValidProfile = (bitDepthIdx > 2 || chromaFormatIdx >
> > 3)
> > ? false : (validSCCProfileNames[0][bitDepthIdx][chromaFormatIdx] !=
> > NONE);
> > + CHECK(!bValidProfile, "Invalid intra constraint flag, bit depth
> > constraint flag and chroma format constraint flag combination for a
> > RExt profile");
> > + }
> > +
> > + static const char* profiles[] = { "None", "Main", "Main 10",
> > "Main
> > Still Picture", "RExt", "", "", "", "", "Main Scc" };
> > static const char *tiers[] = { "Main", "High" };
> > 
> > char profbuf[64];
> > @@ -292,6 +353,25 @@ void determineLevel(const x265_param &param,
> > VPS& vps)
> > if (vps.ptl.intraConstraintFlag && !bStillPicture)
> > strcat(profbuf, " Intra");
> > }
> > +
> > + if (vps.ptl.profileIdc[0] == Profile::MAINSCC)
> > + {
> > + if (param.internalCsp == X265_CSP_I420)
> > + {
> > + if (vps.ptl.bitDepthConstraint <= 8)
> > + strcpy(profbuf, "Main Scc");
> > + else if (vps.ptl.bitDepthConstraint <= 10)
> > + strcpy(profbuf, "Main 10 Scc");
> > + }
> > + else if (param.internalCsp == X265_CSP_I444)
> > + {
> > + if (vps.ptl.bitDepthConstraint <= 8)
> > + strcpy(profbuf, "Main 4:4:4 Scc");
> > + else if (vps.ptl.bitDepthConstraint <= 10)
> > + strcpy(profbuf, "Main 4:4:4 10 Scc");
> > + }
> > + }
> > +
> > x265_log(&param, X265_LOG_INFO, "%s profile, Level-%s (%s tier)\n",
> > profbuf, levels[i].name, tiers[vps.ptl.tierFlag]);
> > }
> > @@ -535,7 +615,8 @@ int x265_param_apply_profile(x265_param *param,
> > const char *profile)
> > if (!strcmp(profile, "main") || !strcmp(profile, "main-intra") ||
> > !strcmp(profile, "main10") || !strcmp(profile, "main10-intra") ||
> > !strcmp(profile, "main12") || !strcmp(profile, "main12-intra") ||
> > - !strcmp(profile, "mainstillpicture") || !strcmp(profile, "msp"))
> > + !strcmp(profile, "mainstillpicture") || !strcmp(profile, "msp")
> > ||
> > + !strcmp(profile, "main-scc") || !strcmp(profile, "main10-scc"))
> > {
> > if (param->internalCsp != X265_CSP_I420)
> > {
> > @@ -558,7 +639,8 @@ int x265_param_apply_profile(x265_param *param,
> > const char *profile)
> > !strcmp(profile, "main444-intra") || !strcmp(profile,
> > "main444-stillpicture") ||
> > !strcmp(profile, "main444-10") || !strcmp(profile,
> > "main444-10-intra") ||
> > !strcmp(profile, "main444-12") || !strcmp(profile,
> > "main444-12-intra") ||
> > - !strcmp(profile, "main444-16-intra") || !strcmp(profile,
> > "main444-16-stillpicture"))
> > + !strcmp(profile, "main444-16-intra") || !strcmp(profile,
> > "main444-16-stillpicture") ||
> > + !strcmp(profile, "main444-scc") || !strcmp(profile,
> > "main444-10-scc"))
> > {
> > /* any color space allowed */
> > }
> > diff --git a/source/x265.h b/source/x265.h
> > index 530ae4d81..abe3f16f0 100644
> > --- a/source/x265.h
> > +++ b/source/x265.h
> > @@ -654,6 +654,10 @@ typedef enum
> > #define MAX_LAYERS 1
> > #endif
> > 
> > +/* SCC Extension Options */
> > +#define SCC_EXT_IDX 3
> > +#define NUM_EXTENSION_FLAGS 8
> > +
> > #define X265_IPRATIO_STRENGTH 1.43
> > 
> > typedef struct x265_cli_csp
> > @@ -2365,6 +2369,8 @@ static const char * const
> > x265_profile_names[]
> > = {
> > "main444-12", "main444-12-intra",
> > 
> > "main444-16-intra", "main444-16-stillpicture", /* Not Supported! */
> > +
> > + "main-scc", "main10-scc", "main444-scc", "main444-10-scc", /*
> > Screen content coding */
> > 0
> > };
> > 
> > --
> > 2.36.0.windows.1
> > 
> > 
> > _______________________________________________
> > x265-devel mailing list
> > x265-devel at videolan.org
> > https://mailman.videolan.org/listinfo/x265-devel
> > 
> 
> _______________________________________________
> x265-devel mailing list
> x265-devel at videolan.org
> https://mailman.videolan.org/listinfo/x265-devel
> 


More information about the x265-devel mailing list