diff --git a/source/App/DecoderApp/DecApp.cpp b/source/App/DecoderApp/DecApp.cpp index d288bb0206af302fdf06b9bf4f865cda125d0710..cd23a9db0f7e280c26ddea6e137cb11d6243f059 100644 --- a/source/App/DecoderApp/DecApp.cpp +++ b/source/App/DecoderApp/DecApp.cpp @@ -286,13 +286,16 @@ uint32_t DecApp::decode() #endif if(bNewAccessUnit) { +#if JVET_R0065 + m_cDecLib.isCvsStart(); +#endif m_cDecLib.checkTidLayerIdInAccessUnit(); m_cDecLib.resetAccessUnitSeiTids(); m_cDecLib.checkSEIInAccessUnit(); m_cDecLib.resetAccessUnitSeiPayLoadTypes(); - m_cDecLib.resetAccessUnitNals(); - m_cDecLib.resetAccessUnitApsNals(); - m_cDecLib.resetAccessUnitPicInfo(); + m_cDecLib.resetAccessUnitNals(); + m_cDecLib.resetAccessUnitApsNals(); + m_cDecLib.resetAccessUnitPicInfo(); } } diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index 1e61cb22d9aecabdddbefb9218d1bc8dd5f18351..49e94cc85d8477318590a40623eb1b7baa0809c9 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -51,6 +51,9 @@ #include <cassert> //########### place macros to be removed in next cycle below this line ############### +#define JVET_R0065 1 //JVET-R0065: Each picture in an AU in a CVS shall have nuh_layer_id equal to the nuh_layer_id of one of the pictures present in the first AU of the CVS + // Add a flag aud_irap_or_gdr_au_flag to the AUD, and mandate the presence of AUD in each IRAP or GDR AU when vps_max_layers_minus1 is greater than 0 + #define JVET_R0064 1 // JVET-R0064, aspect 2: Move the flag scaling_matrix_for_lfnst_disabled_flag from the scaling_list_data( ) syntax to the SPS. #define RETRAIN_CABAC 1 // CABAC initial values retrained on VTM-9.0rc1 diff --git a/source/Lib/DecoderLib/DecLib.cpp b/source/Lib/DecoderLib/DecLib.cpp index b58dfdfa82ad01f8b797e62e9c6f283d4b5996cb..5fa8132c1a836c3aac0531c614edf68e646a06b3 100644 --- a/source/Lib/DecoderLib/DecLib.cpp +++ b/source/Lib/DecoderLib/DecLib.cpp @@ -874,6 +874,40 @@ void DecLib::xCreateUnavailablePicture(int iUnavailablePoc, bool longTermFlag, c } } +#if JVET_R0065 +void DecLib::isCvsStart() +{ + for (auto pic = m_accessUnitPicInfo.begin(); pic != m_accessUnitPicInfo.end(); pic++) + { + if (pic->m_nalUnitType != NAL_UNIT_CODED_SLICE_IDR_N_LP && pic->m_nalUnitType != NAL_UNIT_CODED_SLICE_IDR_W_RADL) + { + checkIncludedInFirstAu(); + return; + } + } + //save the first AU info for a CVS start + m_firstAccessUnitPicInfo.assign(m_accessUnitPicInfo.begin(), m_accessUnitPicInfo.end()); +} + + +void DecLib::checkIncludedInFirstAu() +{ + for (auto pic = m_accessUnitPicInfo.begin(); pic != m_accessUnitPicInfo.end(); pic++) + { + bool isFind = 0; + for (auto picFirst = m_firstAccessUnitPicInfo.begin(); picFirst != m_firstAccessUnitPicInfo.end(); picFirst++) + { + if (pic->m_nuhLayerId == picFirst->m_nuhLayerId) + { + isFind = 1; + break; + } + } + CHECK(!isFind, "each picture in an AU in a CVS shall have nuh_layer_id equal to the nuh_layer_id of one of the pictures present in the first AU of the CVS"); + } +} +#endif + void DecLib::checkTidLayerIdInAccessUnit() { int firstPicTid = m_accessUnitPicInfo.begin()->m_temporalId; @@ -2604,7 +2638,12 @@ bool DecLib::decode(InputNALUnit& nalu, int& iSkipFrame, int& iPOCLastDisplay, i { AUDReader audReader; uint32_t picType; +#if JVET_R0065 + uint32_t audIrapOrGdrAuFlag; + audReader.parseAccessUnitDelimiter(&(nalu.getBitstream()), audIrapOrGdrAuFlag, picType); +#else audReader.parseAccessUnitDelimiter(&(nalu.getBitstream()),picType); +#endif return !m_bFirstSliceInPicture; } diff --git a/source/Lib/DecoderLib/DecLib.h b/source/Lib/DecoderLib/DecLib.h index f7a1b0cf268c4f6c69563f6a1ff7aee37ae57a9e..04005fa82770cf29cbcc77259958b159451ecb0a 100644 --- a/source/Lib/DecoderLib/DecLib.h +++ b/source/Lib/DecoderLib/DecLib.h @@ -143,6 +143,9 @@ private: int m_POC; }; std::vector<AccessUnitPicInfo> m_accessUnitPicInfo; +#if JVET_R0065 + std::vector<AccessUnitPicInfo> m_firstAccessUnitPicInfo; +#endif struct NalUnitInfo { NalUnitType m_nalUnitType; ///< nal_unit_type @@ -217,6 +220,10 @@ public: void checkTidLayerIdInAccessUnit(); void resetAccessUnitSeiPayLoadTypes() { m_accessUnitSeiPayLoadTypes.clear(); } void checkSEIInAccessUnit(); +#if JVET_R0065 + void isCvsStart(); + void checkIncludedInFirstAu(); +#endif #if JVET_Q0488_SEI_REPETITION_CONSTRAINT void checkSeiInPictureUnit(); void resetPictureSeiNalus(); diff --git a/source/Lib/DecoderLib/VLCReader.cpp b/source/Lib/DecoderLib/VLCReader.cpp index ddbdca7d0b7380f9d0614034dd67407b355c6012..b28c13f235452ee7254e42d746d91ac46fa4736f 100644 --- a/source/Lib/DecoderLib/VLCReader.cpp +++ b/source/Lib/DecoderLib/VLCReader.cpp @@ -248,7 +248,11 @@ void VLCReader::xReadRbspTrailingBits() CHECK(cnt >= 8, "Read more than '8' trailing bits"); } +#if JVET_R0065 +void AUDReader::parseAccessUnitDelimiter(InputBitstream* bs, uint32_t &audIrapOrGdrAuFlag, uint32_t &picType) +#else void AUDReader::parseAccessUnitDelimiter(InputBitstream* bs, uint32_t &picType) +#endif { setBitstream(bs); @@ -256,6 +260,9 @@ void AUDReader::parseAccessUnitDelimiter(InputBitstream* bs, uint32_t &picType) xTraceAccessUnitDelimiter(); #endif +#if JVET_R0065 + READ_FLAG (audIrapOrGdrAuFlag, "aud_irap_or_gdr_au_flag"); +#endif READ_CODE (3, picType, "pic_type"); xReadRbspTrailingBits(); } diff --git a/source/Lib/DecoderLib/VLCReader.h b/source/Lib/DecoderLib/VLCReader.h index 720e4dfe37c3b8c7e94fd9ac6395ec5e0460940e..5d6f97831f04329fa23499b7d28e574fdb1a540e 100644 --- a/source/Lib/DecoderLib/VLCReader.h +++ b/source/Lib/DecoderLib/VLCReader.h @@ -129,7 +129,11 @@ class AUDReader: public VLCReader public: AUDReader() {}; virtual ~AUDReader() {}; +#if JVET_R0065 + void parseAccessUnitDelimiter(InputBitstream* bs, uint32_t &audIrapOrGdrAuFlag, uint32_t &picType); +#else void parseAccessUnitDelimiter(InputBitstream* bs, uint32_t &picType); +#endif }; diff --git a/source/Lib/EncoderLib/EncGOP.cpp b/source/Lib/EncoderLib/EncGOP.cpp index e6ef5219d886923866c582a775a060d46c8e7aa7..7048cbe1e99abcf53ba4cc896a587c21fa892f7e 100644 --- a/source/Lib/EncoderLib/EncGOP.cpp +++ b/source/Lib/EncoderLib/EncGOP.cpp @@ -96,6 +96,9 @@ EncGOP::EncGOP() m_pcListPic = NULL; m_HLSWriter = NULL; m_bSeqFirst = true; +#if JVET_R0065 + m_audIrapOrGdrAuFlag = false; +#endif m_bRefreshPending = 0; m_pocCRA = 0; @@ -420,8 +423,11 @@ void EncGOP::xWriteAccessUnitDelimiter (AccessUnit &accessUnit, Slice *slice) } CHECK( nalu.m_temporalId != accessUnit.temporalId, "TemporalId shall be equal to the TemporalId of the AU containing the NAL unit" ); int picType = slice->isIntra() ? 0 : (slice->isInterP() ? 1 : 2); - +#if JVET_R0065 + audWriter.codeAUD(nalu.m_Bitstream, m_audIrapOrGdrAuFlag, picType); +#else audWriter.codeAUD(nalu.m_Bitstream, picType); +#endif accessUnit.push_front(new NALUnitEBSP(nalu)); } @@ -3026,6 +3032,15 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic, int layerIdx = m_pcEncLib->getVPS() == nullptr ? 0 : m_pcEncLib->getVPS()->getGeneralLayerIdx( m_pcEncLib->getLayerId() ); +#if JVET_R0065 + // it is assumed that layerIdx equal to 0 is always present + m_audIrapOrGdrAuFlag = pcSlice->getPicHeader()->getGdrPicFlag() || (pcSlice->isIRAP() && !pcSlice->getPPS()->getMixedNaluTypesInPicFlag()); + if ((( m_pcEncLib->getVPS()->getMaxLayers() > 1 && m_audIrapOrGdrAuFlag) || m_pcCfg->getAccessUnitDelimiter()) && !layerIdx ) + { + xWriteAccessUnitDelimiter(accessUnit, pcSlice); + } +#endif + // it is assumed that layerIdx equal to 0 is always present actualTotalBits += xWriteParameterSets(accessUnit, pcSlice, writePS, layerIdx); if (writePS) @@ -3037,11 +3052,13 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic, m_bSeqFirst = false; } +#if !JVET_R0065 // it is assumed that layerIdx equal to 0 is always present if( m_pcCfg->getAccessUnitDelimiter() && !layerIdx ) { xWriteAccessUnitDelimiter(accessUnit, pcSlice); } +#endif //send LMCS APS when LMCSModel is updated. It can be updated even current slice does not enable reshaper. //For example, in RA, update is on intra slice, but intra slice may not use reshaper diff --git a/source/Lib/EncoderLib/EncGOP.h b/source/Lib/EncoderLib/EncGOP.h index 26b890e196b12d55925a1b648131f2dfb15b021f..1e6944e08e1d34d52d3774a9915617fbf679952c 100644 --- a/source/Lib/EncoderLib/EncGOP.h +++ b/source/Lib/EncoderLib/EncGOP.h @@ -155,6 +155,9 @@ private: RateCtrl* m_pcRateCtrl; // indicate sequence first bool m_bSeqFirst; +#if JVET_R0065 + bool m_audIrapOrGdrAuFlag; +#endif EncHRD* m_HRD; diff --git a/source/Lib/EncoderLib/VLCWriter.cpp b/source/Lib/EncoderLib/VLCWriter.cpp index e07b734b6e7ce2ceeff2497e28d20b0b1de4abef..37908c5b0d33d6663bb7d43f7c440cd3def68598 100644 --- a/source/Lib/EncoderLib/VLCWriter.cpp +++ b/source/Lib/EncoderLib/VLCWriter.cpp @@ -167,7 +167,11 @@ void VLCWriter::xWriteRbspTrailingBits() CHECK(cnt>=8, "More than '8' alignment bytes read"); } +#if JVET_R0065 +void AUDWriter::codeAUD(OutputBitstream& bs, const bool audIrapOrGdrAuFlag, const int pictureType) +#else void AUDWriter::codeAUD(OutputBitstream& bs, const int pictureType) +#endif { #if ENABLE_TRACING xTraceAccessUnitDelimiter(); @@ -175,6 +179,9 @@ void AUDWriter::codeAUD(OutputBitstream& bs, const int pictureType) CHECK(pictureType >= 3, "Invalid picture type"); setBitstream(&bs); +#if JVET_R0065 + WRITE_FLAG(audIrapOrGdrAuFlag, "aud_irap_or_gdr_au_flag"); +#endif WRITE_CODE(pictureType, 3, "pic_type"); xWriteRbspTrailingBits(); } diff --git a/source/Lib/EncoderLib/VLCWriter.h b/source/Lib/EncoderLib/VLCWriter.h index dddc1dac5e8f842268f18b1056239cfc9b38beff..5de0b0d3a3f9cac9caa3f5d758f049183f58d757 100644 --- a/source/Lib/EncoderLib/VLCWriter.h +++ b/source/Lib/EncoderLib/VLCWriter.h @@ -101,7 +101,11 @@ public: AUDWriter() {}; virtual ~AUDWriter() {}; +#if JVET_R0065 + void codeAUD(OutputBitstream& bs, const bool audIrapOrGdrAuFlag, const int pictureType); +#else void codeAUD(OutputBitstream& bs, const int pictureType); +#endif };