From 59a8c8e7ffdf573dcebd6521d8f7415b475f9617 Mon Sep 17 00:00:00 2001
From: Karl Sharman <karl.sharman@sony.com>
Date: Mon, 22 Jun 2020 16:30:13 +0100
Subject: [PATCH] Patch for renumbering levels, JVET-R0245.

Renumbering level according to major*16+minor*3, with maximum level now
15.5 (not 8.3).
---
 doc/software-manual.tex                   |  2 +-
 source/App/EncoderApp/EncAppCfg.cpp       |  8 ++++++++
 source/Lib/CommonLib/ProfileLevelTier.cpp |  8 ++++++++
 source/Lib/CommonLib/ProfileLevelTier.h   |  4 ++++
 source/Lib/CommonLib/TypeDef.h            | 21 +++++++++++++++++++++
 source/Lib/EncoderLib/EncGOP.cpp          |  4 ++++
 6 files changed, 46 insertions(+), 1 deletion(-)

diff --git a/doc/software-manual.tex b/doc/software-manual.tex
index 2cd15f917..92d138e03 100644
--- a/doc/software-manual.tex
+++ b/doc/software-manual.tex
@@ -972,7 +972,7 @@ NB: There is currently only limited validation that the encoder configuration co
 %\ShortOption{\None} &
 \Default{none} &
 Specifies the level to which the encoded bitstream complies.
-Valid values are: none, 1, 2, 2.1, 3, 3.1, 4, 4.1, 5, 5.1, 5.2, 6, 6.1, 6.2, 8.5
+Valid values are: none, 1, 2, 2.1, 3, 3.1, 4, 4.1, 5, 5.1, 5.2, 6, 6.1, 6.2, 15.5
 
 NB: There is currently only limited validation that the encoder configuration complies with the profile, level and tier constraints.
 \\
diff --git a/source/App/EncoderApp/EncAppCfg.cpp b/source/App/EncoderApp/EncAppCfg.cpp
index 69c32de88..9fa5b1a7f 100644
--- a/source/App/EncoderApp/EncAppCfg.cpp
+++ b/source/App/EncoderApp/EncAppCfg.cpp
@@ -273,7 +273,11 @@ strToLevel[] =
   {"6",   Level::LEVEL6},
   {"6.1", Level::LEVEL6_1},
   {"6.2", Level::LEVEL6_2},
+#if JVET_R0245_LEVEL_CODING
+  {"15.5", Level::LEVEL15_5},
+#else
   {"8.5", Level::LEVEL8_5},
+#endif
 };
 
 #if U0132_TARGET_BITS_SATURATION
@@ -711,7 +715,11 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
   SMultiValueInput<uint32_t>  cfg_subPicId(0, std::numeric_limits<uint16_t>::max(), 0, MAX_NUM_SUB_PICS);
 
   SMultiValueInput<int>          cfg_sliFractions(0, 100, 0, std::numeric_limits<int>::max());
+#if JVET_R0245_LEVEL_CODING
+  SMultiValueInput<Level::Name>  cfg_sliRefLevels(Level::NONE, Level::LEVEL15_5,  0, 8);
+#else
   SMultiValueInput<Level::Name>  cfg_sliRefLevels(Level::NONE, Level::LEVEL8_5,  0, 8);
+#endif
 
   int warnUnknowParameter = 0;
 
diff --git a/source/Lib/CommonLib/ProfileLevelTier.cpp b/source/Lib/CommonLib/ProfileLevelTier.cpp
index 0d47501d5..2989180b5 100644
--- a/source/Lib/CommonLib/ProfileLevelTier.cpp
+++ b/source/Lib/CommonLib/ProfileLevelTier.cpp
@@ -70,7 +70,11 @@ static const LevelTierFeatures mainLevelTierInfo[] =
     { Level::LEVEL6  , 35651584, {    60000,   240000 },      600,       22,       20, 1069547520ULL, {   60000,   240000 }, { 8, 4} },
     { Level::LEVEL6_1, 35651584, {   120000,   480000 },      600,       22,       20, 2139095040ULL, {  120000,   480000 }, { 8, 4} },
     { Level::LEVEL6_2, 35651584, {   240000,   800000 },      600,       22,       20, 4278190080ULL, {  240000,   800000 }, { 6, 4} },
+#if JVET_R0245_LEVEL_CODING
+    { Level::LEVEL15_5, MAX_UINT, { MAX_UINT, MAX_UINT }, MAX_UINT, MAX_UINT, MAX_UINT, MAX_CNFUINT64, {MAX_UINT, MAX_UINT }, { 0, 0} },
+#else
     { Level::LEVEL8_5, MAX_UINT, { MAX_UINT, MAX_UINT }, MAX_UINT, MAX_UINT, MAX_UINT, MAX_CNFUINT64, {MAX_UINT, MAX_UINT }, { 0, 0} },
+#endif
     { Level::NONE    }
 };
 
@@ -103,7 +107,11 @@ ProfileLevelTierFeatures::extractPTLInformation(const SPS &sps)
     // Now identify the level:
     const LevelTierFeatures *pLTF = m_pProfile->pLevelTiersListInfo;
     const Level::Name spsLevelName = spsPtl.getLevelIdc();
+#if JVET_R0245_LEVEL_CODING
+    if (spsLevelName!=Level::LEVEL15_5 || m_pProfile->canUseLevel15p5)
+#else
     if (spsLevelName!=Level::LEVEL8_5 || m_pProfile->canUseLevel8p5)
+#endif
     {
       for(int i=0; pLTF[i].level!=Level::NONE; i++)
       {
diff --git a/source/Lib/CommonLib/ProfileLevelTier.h b/source/Lib/CommonLib/ProfileLevelTier.h
index 2d99c311f..df8215d0b 100644
--- a/source/Lib/CommonLib/ProfileLevelTier.h
+++ b/source/Lib/CommonLib/ProfileLevelTier.h
@@ -70,7 +70,11 @@ struct ProfileFeatures
   uint32_t                 maxBitDepth;
   ChromaFormat             maxChromaFormat;
 
+#if JVET_R0245_LEVEL_CODING
+  bool                     canUseLevel15p5;
+#else
   bool                     canUseLevel8p5;
+#endif
   uint32_t                 cpbVclFactor;
   uint32_t                 cpbNalFactor;
   uint32_t                 formatCapabilityFactorx1000;
diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h
index 2bd51eda2..6c8354baa 100644
--- a/source/Lib/CommonLib/TypeDef.h
+++ b/source/Lib/CommonLib/TypeDef.h
@@ -241,6 +241,8 @@
 
 #define JVET_R0101_PROPOSAL2                              1 // JVET-R0101 Proposal 2: Bug fix for signalling some syntax elements length
 
+#define JVET_R0245_LEVEL_CODING                           1 // JVET-R0245: level coding numbering scheme
+
 //########### 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
@@ -888,6 +890,24 @@ namespace Level
 
   enum Name
   {
+#if JVET_R0245_LEVEL_CODING
+    // code = (major_level * 16 + minor_level * 3)
+    NONE     = 0,
+    LEVEL1   = 16,
+    LEVEL2   = 32,
+    LEVEL2_1 = 35,
+    LEVEL3   = 48,
+    LEVEL3_1 = 51,
+    LEVEL4   = 64,
+    LEVEL4_1 = 67,
+    LEVEL5   = 80,
+    LEVEL5_1 = 83,
+    LEVEL5_2 = 86,
+    LEVEL6   = 96,
+    LEVEL6_1 = 99,
+    LEVEL6_2 = 102,
+    LEVEL15_5 = 255,
+#else
     // code = (level * 30)
     NONE     = 0,
     LEVEL1   = 30,
@@ -904,6 +924,7 @@ namespace Level
     LEVEL6_1 = 183,
     LEVEL6_2 = 186,
     LEVEL8_5 = 255,
+#endif
   };
 }
 
diff --git a/source/Lib/EncoderLib/EncGOP.cpp b/source/Lib/EncoderLib/EncGOP.cpp
index 77d7fba77..485599320 100644
--- a/source/Lib/EncoderLib/EncGOP.cpp
+++ b/source/Lib/EncoderLib/EncGOP.cpp
@@ -1206,7 +1206,11 @@ validateMinCrRequirements(const ProfileLevelTierFeatures &plt, std::size_t numBy
   //  numBytesInVclNalUnits shall be less than or equal to
   //     FormatCapabilityFactor * MaxLumaSr * framePeriod / MinCr,
   //     ( = FormatCapabilityFactor * MaxLumaSr / (MinCr * frameRate),
+#if JVET_R0245_LEVEL_CODING
+  if (plt.getLevelTierFeatures() && plt.getProfileFeatures() && plt.getLevelTierFeatures()->level!=Level::LEVEL15_5)
+#else
   if (plt.getLevelTierFeatures() && plt.getProfileFeatures() && plt.getLevelTierFeatures()->level!=Level::LEVEL8_5)
+#endif
   {
     const uint32_t formatCapabilityFactorx1000 = plt.getProfileFeatures()->formatCapabilityFactorx1000;
     const uint64_t maxLumaSr = plt.getLevelTierFeatures()->maxLumaSr;
-- 
GitLab