From a5b3492ef05e4ad836c3f82973714cb66eb614da Mon Sep 17 00:00:00 2001 From: biaowang <biao.wang@huawei.com> Date: Tue, 3 Mar 2020 22:27:51 +0100 Subject: [PATCH] JVET-P0124/P0095/P0222: mixed Nal Unit type within a picture --- source/Lib/CommonLib/Slice.h | 10 +++ source/Lib/CommonLib/TypeDef.h | 5 +- source/Lib/DecoderLib/DecLib.cpp | 125 ++++++++++++++++++++++++++++ source/Lib/DecoderLib/DecLib.h | 14 +++- source/Lib/DecoderLib/VLCReader.cpp | 3 + source/Lib/EncoderLib/VLCWriter.cpp | 3 + 6 files changed, 158 insertions(+), 2 deletions(-) diff --git a/source/Lib/CommonLib/Slice.h b/source/Lib/CommonLib/Slice.h index 0749dfce94..791e42d12b 100644 --- a/source/Lib/CommonLib/Slice.h +++ b/source/Lib/CommonLib/Slice.h @@ -293,6 +293,9 @@ class ConstraintInfo bool m_noQpDeltaConstraintFlag; bool m_noDepQuantConstraintFlag; bool m_noSignDataHidingConstraintFlag; +#if JVET_P0124_MIXED_NALU + bool m_noMixedNaluTypesInPicConstraintFlag; +#endif bool m_noTrailConstraintFlag; bool m_noStsaConstraintFlag; bool m_noRaslConstraintFlag; @@ -353,6 +356,9 @@ public: , m_noQpDeltaConstraintFlag (false) , m_noDepQuantConstraintFlag (false) , m_noSignDataHidingConstraintFlag(false) +#if JVET_P0124_MIXED_NALU + , m_noMixedNaluTypesInPicConstraintFlag(false) +#endif , m_noTrailConstraintFlag (false) , m_noStsaConstraintFlag (false) , m_noRaslConstraintFlag (false) @@ -468,6 +474,10 @@ public: void setNoDepQuantConstraintFlag(bool bVal) { m_noDepQuantConstraintFlag = bVal; } bool getNoSignDataHidingConstraintFlag() const { return m_noSignDataHidingConstraintFlag; } void setNoSignDataHidingConstraintFlag(bool bVal) { m_noSignDataHidingConstraintFlag = bVal; } +#if JVET_P0124_MIXED_NALU + bool getNoMixedNaluTypesInPicConstraintFlag() const { return m_noMixedNaluTypesInPicConstraintFlag; } + void setNoMixedNaluTypesInPicConstraintFlag(bool bVal) { m_noMixedNaluTypesInPicConstraintFlag = bVal; } +#endif bool getNoTrailConstraintFlag() const { return m_noTrailConstraintFlag; } void setNoTrailConstraintFlag(bool bVal) { m_noTrailConstraintFlag = bVal; } bool getNoStsaConstraintFlag() const { return m_noStsaConstraintFlag; } diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index 5340766aa9..2e9d499036 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -167,6 +167,7 @@ #define JVET_Q0814_DPB 1 // JVET-Q0814: DPB capacity is based on picture units regardless of the resoltuion #define ENABLING_MULTI_SPS 1 // Bug fix to enable multiple SPS #define SPS_ID_CHECK 1 // add SPS id check to be the same within CLVS, related to mixed_nalu_types_in_pic_flag +#define JVET_P0124_MIXED_NALU 1 // JVET-P0124/P0095/P0222: MIxed IRAP/non-IRAP VCL NAL units within a picture #define JVET_Q0117_PARAMETER_SETS_CLEANUP 1 // JVET-Q0117: cleanups on parameter sets @@ -991,7 +992,9 @@ enum NalUnitType NAL_UNIT_RESERVED_IRAP_VCL_11, NAL_UNIT_RESERVED_IRAP_VCL_12, - +#if JVET_P0124_MIXED_NALU + NAL_UNIT_RESERVED_VCL_15, +#endif #if JVET_Q0117_PARAMETER_SETS_CLEANUP NAL_UNIT_DCI, // 13 #else diff --git a/source/Lib/DecoderLib/DecLib.cpp b/source/Lib/DecoderLib/DecLib.cpp index d8ddbcc10b..02dc5f5b5a 100644 --- a/source/Lib/DecoderLib/DecLib.cpp +++ b/source/Lib/DecoderLib/DecLib.cpp @@ -2145,6 +2145,15 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl //--------------- pcSlice->setRefPOCList(); +#if JVET_P0124_MIXED_NALU + NalUnitInfo naluInfo; + naluInfo.m_nalUnitType = nalu.m_nalUnitType; + naluInfo.m_nuhLayerId = nalu.m_nuhLayerId; + naluInfo.m_firstCTUinSlice = pcSlice->getFirstCtuRsAddrInSlice(); + naluInfo.m_POC = pcSlice->getPOC(); + xCheckMixedNalUnit(pcSlice, sps, nalu); + m_nalUnitInfo.push_back(naluInfo); +#endif SEIMessages drapSEIs = getSeisByType(m_pcPic->SEIs, SEI::DEPENDENT_RAP_INDICATION ); if (!drapSEIs.empty()) { @@ -2559,5 +2568,121 @@ void DecLib::xCheckNalUnitConstraintFlags( const ConstraintInfo *cInfo, uint32_t "Non-conforming bitstream. no_aps_constraint_flag is equal to 1 but bitstream contains NAL unit of type APS_SUFFIX_NUT."); } } +#if JVET_P0124_MIXED_NALU +void DecLib::xCheckMixedNalUnit(Slice* pcSlice, SPS *sps, InputNALUnit &nalu) +{ + if (pcSlice->getPPS()->getMixedNaluTypesInPicFlag()) + { + CHECK(pcSlice->getPPS()->getNumSlicesInPic() < 2, "mixed nal unit type picture, but with less than 2 slices"); + + const unsigned ctuRsAddr = pcSlice->getCtuAddrInSlice(0); + const unsigned ctuXPosInCtus = ctuRsAddr % pcSlice->getPPS()->getPicWidthInCtu(); + const unsigned ctuYPosInCtus = ctuRsAddr / pcSlice->getPPS()->getPicWidthInCtu(); + const unsigned maxCUSize = sps->getMaxCUWidth(); + Position pos(ctuXPosInCtus*maxCUSize, ctuYPosInCtus*maxCUSize); + SubPic curSubPic = pcSlice->getPPS()->getSubPicFromPos(pos); + // check subpicture constraints + if ((pcSlice->getNalUnitType() >= NAL_UNIT_CODED_SLICE_IDR_W_RADL) && (pcSlice->getNalUnitType() <= NAL_UNIT_CODED_SLICE_CRA)) + { + CHECK(curSubPic.getTreatedAsPicFlag() != true, "a slice of IDR_W_RADL to CRA_NUT shall have its subpic's sub_pic_treated_as_pic_flag equal to 1"); + } + else + { + // check reference list constraint + if (!m_nalUnitInfo.empty()) + { + //find out the closest IRAP nal unit that are in the same layer and in the corresponding subpicture + NalUnitInfo *latestIRAPNalUnit = nullptr; + int size = (int)m_nalUnitInfo.size(); + int naluIdx; + for (naluIdx = size - 1; naluIdx >= 0; naluIdx--) + { + NalUnitInfo *iterNalu = &m_nalUnitInfo[naluIdx]; + bool isTheSameLayer = iterNalu->m_nuhLayerId == nalu.m_nuhLayerId; + bool isIRAPSlice = iterNalu->m_nalUnitType >= NAL_UNIT_CODED_SLICE_IDR_W_RADL && iterNalu->m_nalUnitType <= NAL_UNIT_CODED_SLICE_CRA; + if (isTheSameLayer && isIRAPSlice) + { + latestIRAPNalUnit = iterNalu; + break; + } + } + if (latestIRAPNalUnit != nullptr) + { + // only check the current slice, as previous slice have been checked + const unsigned ctuRsAddrIRAP = latestIRAPNalUnit->m_firstCTUinSlice; + const unsigned ctuXPosInCtusIRAP = ctuRsAddrIRAP % pcSlice->getPPS()->getPicWidthInCtu(); + const unsigned ctuYPosInCtusIRAP = ctuRsAddrIRAP / pcSlice->getPPS()->getPicWidthInCtu(); + Position posIRAP(ctuXPosInCtusIRAP*maxCUSize, ctuXPosInCtusIRAP*maxCUSize); + bool isInCorrespondingSubpic = curSubPic.isContainingPos(posIRAP); + if (isInCorrespondingSubpic) + { + // check RefPicList[0] + for (int refIdx = 0; refIdx < pcSlice->getNumRefIdx(REF_PIC_LIST_0); refIdx++) + { + int POC = pcSlice->getRefPOC(REF_PIC_LIST_0, refIdx); + for (int i = 0; i < naluIdx; i++) + { + NalUnitInfo *iterNalu = &m_nalUnitInfo[i]; + if (iterNalu->m_nuhLayerId == nalu.m_nuhLayerId) + { + CHECK(POC == iterNalu->m_POC, "preIRAP picture shall not be used as the reference picture of a slice after the IRAP picture"); + } + } + } + // check RefPicList[1] + for (int refIdx = 0; refIdx < pcSlice->getNumRefIdx(REF_PIC_LIST_1); refIdx++) + { + int POC = pcSlice->getRefPOC(REF_PIC_LIST_1, refIdx); + for (int i = 0; i < naluIdx; i++) + { + NalUnitInfo *iterNalu = &m_nalUnitInfo[i]; + if (iterNalu->m_nuhLayerId == nalu.m_nuhLayerId) + { + CHECK(POC == iterNalu->m_POC, "preIRAP picture shall not be used as the reference picture of a slice after the IRAP picture"); + } + } + } + } + } + } + } + // check whether the nalu type of slices meet the nal unit type constraints + if (pcSlice->getPPS()->getNumSlicesInPic() == (m_uiSliceSegmentIdx + 1)) + { + int num1stSetSlice = 0; + int num2ndSetSlice = 0; + int num3rdSetSlice = 0; + for (int i = 0; i < pcSlice->getPPS()->getNumSlicesInPic(); i++) + { + NalUnitType naluType = pcSlice->getNalUnitType(); + if (naluType >= NAL_UNIT_CODED_SLICE_IDR_W_RADL && naluType <= NAL_UNIT_CODED_SLICE_CRA) + { + num1stSetSlice++; + } + else if ((naluType >= NAL_UNIT_CODED_SLICE_TRAIL && naluType <= NAL_UNIT_RESERVED_VCL_15) || naluType == NAL_UNIT_CODED_SLICE_GDR) + { + num2ndSetSlice++; + } + else + { + num3rdSetSlice++; + } + } + CHECK((num1stSetSlice + num2ndSetSlice) != pcSlice->getPPS()->getNumSlicesInPic() || num3rdSetSlice != 0, "mixed nal unit picture contain more than two nal unit types"); + } + } + else // all slices shall have the same nal unit type + { + bool sameNalUnitType = true; + for (int i = 0; i < m_uiSliceSegmentIdx; i++) + { + Slice *PreSlice = m_pcPic->slices[i]; + if (PreSlice->getNalUnitType() != pcSlice->getNalUnitType()) + sameNalUnitType = false; + } + CHECK(!sameNalUnitType, "mixed_nalu_types_in_pic_flag is zero, but have different nal unit types"); + } +} +#endif //! \} diff --git a/source/Lib/DecoderLib/DecLib.h b/source/Lib/DecoderLib/DecLib.h index 1edbe9cc3a..160512cce1 100644 --- a/source/Lib/DecoderLib/DecLib.h +++ b/source/Lib/DecoderLib/DecLib.h @@ -145,6 +145,16 @@ private: }; std::vector<AccessUnitPicInfo> m_accessUnitPicInfo; #endif +#if JVET_P0124_MIXED_NALU + struct NalUnitInfo + { + NalUnitType m_nalUnitType; ///< nal_unit_type + uint32_t m_nuhLayerId; ///< nuh_layer_id + uint32_t m_firstCTUinSlice; /// the first CTU in slice, specified with raster scan order ctu address + int m_POC; /// the picture order + }; + std::vector<NalUnitInfo> m_nalUnitInfo; +#endif std::vector<int> m_accessUnitApsNals; #if JVET_P0125_ASPECT_TID_LAYER_ID_NUH std::vector<int> m_accessUnitSeiTids; @@ -261,7 +271,9 @@ protected: void xParsePrefixSEIsForUnknownVCLNal(); void xCheckNalUnitConstraintFlags( const ConstraintInfo *cInfo, uint32_t naluType ); - +#if JVET_P0124_MIXED_NALU + void xCheckMixedNalUnit(Slice* pcSlice, SPS *sps, InputNALUnit &nalu); +#endif };// END CLASS DEFINITION DecLib diff --git a/source/Lib/DecoderLib/VLCReader.cpp b/source/Lib/DecoderLib/VLCReader.cpp index 1da70efb16..609d5a7756 100644 --- a/source/Lib/DecoderLib/VLCReader.cpp +++ b/source/Lib/DecoderLib/VLCReader.cpp @@ -5075,6 +5075,9 @@ void HLSyntaxReader::parseConstraintInfo(ConstraintInfo *cinfo) READ_FLAG(symbol, "no_qp_delta_constraint_flag"); cinfo->setNoQpDeltaConstraintFlag(symbol > 0 ? true : false); READ_FLAG(symbol, "no_dep_quant_constraint_flag"); cinfo->setNoDepQuantConstraintFlag(symbol > 0 ? true : false); READ_FLAG(symbol, "no_sign_data_hiding_constraint_flag"); cinfo->setNoSignDataHidingConstraintFlag(symbol > 0 ? true : false); +#if JVET_P0124_MIXED_NALU + READ_FLAG(symbol, "no_mixed_nalu_types_in_pic_constraint_flag"); cinfo->setNoMixedNaluTypesInPicConstraintFlag(symbol > 0 ? true : false); +#endif READ_FLAG(symbol, "no_trail_constraint_flag"); cinfo->setNoTrailConstraintFlag(symbol > 0 ? true : false); READ_FLAG(symbol, "no_stsa_constraint_flag"); cinfo->setNoStsaConstraintFlag(symbol > 0 ? true : false); READ_FLAG(symbol, "no_rasl_constraint_flag"); cinfo->setNoRaslConstraintFlag(symbol > 0 ? true : false); diff --git a/source/Lib/EncoderLib/VLCWriter.cpp b/source/Lib/EncoderLib/VLCWriter.cpp index 5a7c67b246..77ae5ca50f 100644 --- a/source/Lib/EncoderLib/VLCWriter.cpp +++ b/source/Lib/EncoderLib/VLCWriter.cpp @@ -3310,6 +3310,9 @@ void HLSWriter::codeConstraintInfo ( const ConstraintInfo* cinfo ) WRITE_FLAG(cinfo->getNoQpDeltaConstraintFlag() ? 1 : 0, "no_qp_delta_constraint_flag"); WRITE_FLAG(cinfo->getNoDepQuantConstraintFlag() ? 1 : 0, "no_dep_quant_constraint_flag"); WRITE_FLAG(cinfo->getNoSignDataHidingConstraintFlag() ? 1 : 0, "no_sign_data_hiding_constraint_flag"); +#if JVET_P0124_MIXED_NALU + WRITE_FLAG(cinfo->getNoMixedNaluTypesInPicConstraintFlag() ? 1 : 0, "no_mixed_nalu_types_in_pic_constraint_flag"); +#endif WRITE_FLAG(cinfo->getNoTrailConstraintFlag() ? 1 : 0, "no_trail_constraint_flag"); WRITE_FLAG(cinfo->getNoStsaConstraintFlag() ? 1 : 0, "no_stsa_constraint_flag"); WRITE_FLAG(cinfo->getNoRaslConstraintFlag() ? 1 : 0, "no_rasl_constraint_flag"); -- GitLab