diff --git a/source/App/DecoderApp/DecApp.cpp b/source/App/DecoderApp/DecApp.cpp index 075911c5ced1f605dee121ff65b9e7124ea1052a..d744b5ed0d34e61b01b5c9fe4072d94e12742c75 100644 --- a/source/App/DecoderApp/DecApp.cpp +++ b/source/App/DecoderApp/DecApp.cpp @@ -289,13 +289,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 1d2fda3a2ac3de67d0cdb5c0a931475e3c8fe857..060b9a7c30ed56b544c1d6c83748e7d03cf559ed 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -57,6 +57,9 @@ #define JVET_R0122_PIC_OUTPUT_FLAG_CLEANUP 1 // JVET-R0122: pic_output_flag is not signalled in picture header and inferred to be equal to 1, when the value of non_reference_picture_flag is equal to 1. +#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_R0041 1 // JVET-R0041: Picture types related constraints #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. diff --git a/source/Lib/DecoderLib/DecLib.cpp b/source/Lib/DecoderLib/DecLib.cpp index 619cfb9f617b7aad0b1f7c805a087078a04a738d..8f82764edc6bdf5429f871af81e5e79e433e965f 100644 --- a/source/Lib/DecoderLib/DecLib.cpp +++ b/source/Lib/DecoderLib/DecLib.cpp @@ -892,6 +892,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; @@ -2685,7 +2719,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 ee9cc7d8db5093bf7a9ed8fe7a791be22058dd34..6a1c1f0d5f7007ffb32cd3bdb01ee64094583eb5 100644 --- a/source/Lib/DecoderLib/DecLib.h +++ b/source/Lib/DecoderLib/DecLib.h @@ -156,6 +156,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 @@ -233,6 +236,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 b41530618a5e97b57b3ed13a9b60b9b633caf6d3..a0c6901cf99d2c3920974fe6b728299258abecb8 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 c10645f5c0f0472b8d6a297f33db15ffc3fe0fd8..65b8cfab55905aba92b51b6f83c3e92b62eb2dbf 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; @@ -428,8 +431,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)); } @@ -3054,6 +3060,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) @@ -3065,11 +3080,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 97ace412087c07cd5bcda5ba10c9629d5eb7525c..8b119e0e12646cdf5ba3c89ba408a8f8c64d8ef8 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 5c69439dff053c25546fa7acb577678c5521e30c..f6400b221638b0587afe7576f3905e61ff09232f 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 };