diff --git a/source/Lib/CommonLib/Slice.cpp b/source/Lib/CommonLib/Slice.cpp index 225770e990f4330869bc2d11d14baba67a206d5a..fe6c281f224f0fec1d9ad95d39660b6855f5cb94 100644 --- a/source/Lib/CommonLib/Slice.cpp +++ b/source/Lib/CommonLib/Slice.cpp @@ -1594,6 +1594,10 @@ VPS::VPS() { m_vpsLayerId[i] = 0; m_vpsIndependentLayerFlag[i] = 1; +#if JVET_Q0172_CHROMA_FORMAT_BITDEPTH_CONSTRAINT + m_vpsLayerChromaFormatIDC[i] = NOT_VALID; + m_vpsLayerBitDepth[i] = NOT_VALID; +#endif for (int j = 0; j < MAX_VPS_LAYERS; j++) { m_vpsDirectRefLayerFlag[i][j] = 0; diff --git a/source/Lib/CommonLib/Slice.h b/source/Lib/CommonLib/Slice.h index 9cb0525275fef70979228878066be42440dc94af..3284af0974a149feeb6a021ca761e17668fdcf60 100644 --- a/source/Lib/CommonLib/Slice.h +++ b/source/Lib/CommonLib/Slice.h @@ -796,6 +796,11 @@ private: uint32_t m_interLayerRefIdx[MAX_VPS_LAYERS][MAX_VPS_LAYERS]; bool m_vpsExtensionFlag; +#if JVET_Q0172_CHROMA_FORMAT_BITDEPTH_CONSTRAINT + int m_vpsLayerChromaFormatIDC[MAX_VPS_LAYERS]; + int m_vpsLayerBitDepth[MAX_VPS_LAYERS]; +#endif + public: VPS(); @@ -847,6 +852,15 @@ public: bool getVPSExtensionFlag() const { return m_vpsExtensionFlag; } void setVPSExtensionFlag(bool t) { m_vpsExtensionFlag = t; } + +#if JVET_Q0172_CHROMA_FORMAT_BITDEPTH_CONSTRAINT + int getLayerChromaFormatIDC(uint32_t layerIdx) const { return m_vpsLayerChromaFormatIDC[layerIdx]; } + void setLayerChromaFormatIDC(uint32_t layerIdx, int chromaFormatIDC) { m_vpsLayerChromaFormatIDC[layerIdx] = chromaFormatIDC; } + + int getLayerBitDepth(uint32_t layerIdx) const { return m_vpsLayerBitDepth[layerIdx]; } + void setLayerBitDepth(uint32_t layerIdx, int bitDepth) { m_vpsLayerBitDepth[layerIdx] = bitDepth; } +#endif + }; class Window diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index 648f914518f10fe199f8c765ed5e518f3a9529fb..1a64b82fe09446f62c3979e64c77bd848ada5748 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -50,6 +50,8 @@ #include <assert.h> #include <cassert> +#define JVET_Q0172_CHROMA_FORMAT_BITDEPTH_CONSTRAINT 1 //JVET-Q0172: Disallow differing chroma format and different bit depths for cross-layer prediction. + #define JVET_Q0413_SKIP_LAST_SUBPIC_SIG 1 //JVET-Q0413 modification 2: skip the width and height signaling of last subpicture #define JVET_Q0169_SUBPIC_LEN_CONFORM 1 // JVET-Q0169: add bitstream conformance check on subpic length diff --git a/source/Lib/EncoderLib/EncLib.cpp b/source/Lib/EncoderLib/EncLib.cpp index 6352d8b3ea492c3784397dbed59bfb8863767035..4d80a4ebb931640b04c072788bdc5c0616559260 100644 --- a/source/Lib/EncoderLib/EncLib.cpp +++ b/source/Lib/EncoderLib/EncLib.cpp @@ -96,6 +96,35 @@ EncLib::~EncLib() void EncLib::create( const int layerId ) { m_layerId = layerId; +#if JVET_Q0172_CHROMA_FORMAT_BITDEPTH_CONSTRAINT + if (getVPS()->getMaxLayers() > 1) + { + VPS* vps = getVPS(); + int curLayerChromaFormatIdcInVPS = vps->getLayerChromaFormatIDC(layerId); + if (curLayerChromaFormatIdcInVPS == NOT_VALID) + vps->setLayerChromaFormatIDC(layerId, m_chromaFormatIDC); + else + CHECK(curLayerChromaFormatIdcInVPS != m_chromaFormatIDC, "The chroma formats of different SPS are not the same in the same layer"); + + int curLayerBitDepthInVPS = vps->getLayerBitDepth(layerId); + if (curLayerBitDepthInVPS == NOT_VALID) + vps->setLayerBitDepth(layerId, m_bitDepth[0]); + else + CHECK(curLayerBitDepthInVPS != m_bitDepth[0], "The bit-depth of different SPS are not the same in the same layer"); + + //check chroma format and bit-depth for dependent layers + for (uint32_t i = 0; i < layerId; i++) + { + if (vps->getDirectRefLayerFlag(layerId, i)) + { + int refLayerChromaFormatIdcInVPS = vps->getLayerChromaFormatIDC(i); + CHECK(curLayerChromaFormatIdcInVPS != refLayerChromaFormatIdcInVPS, "The chroma formats of the current layer and the reference layer are different"); + int refLayerBitDepthInVPS = vps->getLayerBitDepth(layerId); + CHECK(curLayerBitDepthInVPS != refLayerBitDepthInVPS, "The bit-depth of the current layer and the reference layer are different"); + } + } + } +#endif m_iPOCLast = m_compositeRefEnabled ? -2 : -1; // create processing unit classes m_cGOPEncoder. create( );