diff --git a/source/App/DecoderApp/DecApp.cpp b/source/App/DecoderApp/DecApp.cpp index 7735309afc36ac6d4e62a2e33522f93f757c0f1a..3e15f4a720ad6c9650d9fea4d22620d19b8cac6f 100644 --- a/source/App/DecoderApp/DecApp.cpp +++ b/source/App/DecoderApp/DecApp.cpp @@ -252,10 +252,15 @@ uint32_t DecApp::decode() m_cDecLib.setFirstSliceInPicture (false); } // write reconstruction to file -- for additional bumping as defined in C.5.2.3 +#if JVET_N0067_NAL_Unit_Header + if (!bNewPicture && ((nalu.m_nalUnitType >= NAL_UNIT_CODED_SLICE_TRAIL && nalu.m_nalUnitType <= NAL_UNIT_RESERVED_VCL_15) + || (nalu.m_nalUnitType >= NAL_UNIT_CODED_SLICE_IDR_W_RADL && nalu.m_nalUnitType <= NAL_UNIT_CODED_SLICE_GRA))) +#else #if !JVET_M0101_HLS if(!bNewPicture && nalu.m_nalUnitType >= NAL_UNIT_CODED_SLICE_TRAIL_N && nalu.m_nalUnitType <= NAL_UNIT_RESERVED_VCL31) #else if (!bNewPicture && nalu.m_nalUnitType >= NAL_UNIT_CODED_SLICE_TRAIL && nalu.m_nalUnitType <= NAL_UNIT_RESERVED_VCL15) +#endif #endif { xWriteOutput( pcListPic, nalu.m_temporalId ); diff --git a/source/App/Parcat/parcat.cpp b/source/App/Parcat/parcat.cpp index d85c356d804143423a7cce3315fd047bfb3f5313..aadd68f64379175ca77168f7591a3a087e0467bb 100644 --- a/source/App/Parcat/parcat.cpp +++ b/source/App/Parcat/parcat.cpp @@ -102,6 +102,40 @@ const bool verbose = false; const char * NALU_TYPE[] = { +#if JVET_N0067_NAL_Unit_Header + "NAL_UNIT_PPS", + "NAL_UNIT_ACCESS_UNIT_DELIMITER", + "NAL_UNIT_PREFIX_SEI", + "NAL_UNIT_SUFFIX_SEI", + "NAL_UNIT_APS", + "NAL_UNIT_RESERVED_NVCL_5", + "NAL_UNIT_RESERVED_NVCL_6", + "NAL_UNIT_RESERVED_NVCL_7", + "NAL_UNIT_CODED_SLICE_TRAIL", + "NAL_UNIT_CODED_SLICE_STSA", + "NAL_UNIT_CODED_SLICE_RADL", + "NAL_UNIT_CODED_SLICE_RASL", + "NAL_UNIT_RESERVED_VCL_12", + "NAL_UNIT_RESERVED_VCL_13", + "NAL_UNIT_RESERVED_VCL_14", + "NAL_UNIT_RESERVED_VCL_15", + "NAL_UNIT_DPS", + "NAL_UNIT_SPS", + "NAL_UNIT_EOS", + "NAL_UNIT_EOB", + "NAL_UNIT_VPS", + "NAL_UNIT_RESERVED_NVCL_21", + "NAL_UNIT_RESERVED_NVCL_22", + "NAL_UNIT_RESERVED_NVCL_23", + "NAL_UNIT_CODED_SLICE_IDR_W_RADL", + "NAL_UNIT_CODED_SLICE_IDR_N_LP", + "NAL_UNIT_CODED_SLICE_CRA", + "NAL_UNIT_CODED_SLICE_GRA", + "NAL_UNIT_UNSPECIFIED_28", + "NAL_UNIT_UNSPECIFIED_29", + "NAL_UNIT_UNSPECIFIED_30", + "NAL_UNIT_UNSPECIFIED_31" +#else #if !JVET_M0101_HLS "TRAIL_N", "TRAIL_R", @@ -196,6 +230,7 @@ const char * NALU_TYPE[] = "NAL_UNIT_UNSPECIFIED_30", "NAL_UNIT_UNSPECIFIED_31" #endif +#endif }; int calc_poc(int iPOClsb, int prevTid0POC, int getBitsForPOC, int nalu_type) @@ -280,10 +315,14 @@ std::vector<uint8_t> filter_segment(const std::vector<uint8_t> & v, int idx, int int offset = 16; offset += 1; //first_slice_segment_in_pic_flag +#if JVET_N0067_NAL_Unit_Header + if (nalu_type >= NAL_UNIT_CODED_SLICE_IDR_W_RADL && nalu_type <= NAL_UNIT_CODED_SLICE_CRA) +#else #if !JVET_M0101_HLS if (nalu_type >= NAL_UNIT_CODED_SLICE_BLA_W_LP && nalu_type <= NAL_UNIT_RESERVED_IRAP_VCL23) #else if (nalu_type >= NAL_UNIT_CODED_SLICE_IDR_W_RADL && nalu_type <= NAL_UNIT_RESERVED_IRAP_VCL13) +#endif #endif { offset += 1; //no_output_of_prior_pics_flag diff --git a/source/App/SEIRemovalApp/SEIRemovalApp.cpp b/source/App/SEIRemovalApp/SEIRemovalApp.cpp index dd22baa5291c4d962591b8354e98a8e19be63843..c4d21a4bdaf3581267d8d9e8f55926e21d63b5f3 100644 --- a/source/App/SEIRemovalApp/SEIRemovalApp.cpp +++ b/source/App/SEIRemovalApp/SEIRemovalApp.cpp @@ -72,11 +72,33 @@ void read2(InputNALUnit& nalu) { InputBitstream& bs = nalu.getBitstream(); + #if JVET_N0067_NAL_Unit_Header + nalu.m_zeroTidRequiredFlag = bs.read(1); // zero_tid_required_flag + nalu.m_temporalId = bs.read(3) - 1; // nuh_temporal_id_plus1 + if(nalu.m_temporalId < 0) { + THROW( "Temporal ID is negative." ); + } + //When zero_tid_required_flag is equal to 1, the value of nuh_temporal_id_plus1 shall be equal to 1. + if((nalu.m_zeroTidRequiredFlag == 1) && (nalu.m_temporalId != 0)) { + THROW( "Temporal ID is not '0' when zero tid is required." ); + } + uint32_t m_nalUnitTypeLsb = bs.read(4); // nal_unit_type_lsb + nalu.m_nalUnitType = (NalUnitType) ((nalu.m_zeroTidRequiredFlag << 4) + m_nalUnitTypeLsb); + nalu.m_nuhLayerId = bs.read(7); // nuh_layer_id + if((nalu.m_nuhLayerId < 0) || (nalu.m_nuhLayerId > 126)) { + THROW( "Layer ID out of range" ); + } + uint32_t nuh_reserved_zero_bit = bs.read(1); // nuh_reserved_zero_bit + if(nuh_reserved_zero_bit != 0) { + THROW( "Reserved zero bit is not '0'" ); + } +#else bool forbidden_zero_bit = bs.read(1); // forbidden_zero_bit if(forbidden_zero_bit != 0) { THROW( "Forbidden zero-bit not '0'" );} nalu.m_nalUnitType = (NalUnitType) bs.read(6); // nal_unit_type nalu.m_nuhLayerId = bs.read(6); // nuh_layer_id nalu.m_temporalId = bs.read(3) - 1; // nuh_temporal_id_plus1 +#endif } uint32_t SEIRemovalApp::decode() diff --git a/source/Lib/CommonLib/NAL.h b/source/Lib/CommonLib/NAL.h index 57f98f7812e751f783c99c28c97d7bfbebfa5374..7d074fde87e5129779bddee4d51876e2f234fa91 100644 --- a/source/Lib/CommonLib/NAL.h +++ b/source/Lib/CommonLib/NAL.h @@ -48,20 +48,32 @@ class OutputBitstream; struct NALUnit { NalUnitType m_nalUnitType; ///< nal_unit_type +#if JVET_N0067_NAL_Unit_Header + uint32_t m_zeroTidRequiredFlag; ///< zero_tid_required_flag +#endif uint32_t m_temporalId; ///< temporal_id uint32_t m_nuhLayerId; ///< nuh_layer_id NALUnit(const NALUnit &src) :m_nalUnitType (src.m_nalUnitType) +#if JVET_N0067_NAL_Unit_Header + ,m_zeroTidRequiredFlag (src.m_zeroTidRequiredFlag) +#endif ,m_temporalId (src.m_temporalId) ,m_nuhLayerId (src.m_nuhLayerId) { } /** construct an NALunit structure with given header values. */ NALUnit( NalUnitType nalUnitType, +#if JVET_N0067_NAL_Unit_Header + int zeroTidRequiredFlag = 0, +#endif int temporalId = 0, int nuhLayerId = 0) :m_nalUnitType (nalUnitType) +#if JVET_N0067_NAL_Unit_Header + ,m_zeroTidRequiredFlag (zeroTidRequiredFlag) +#endif ,m_temporalId (temporalId) ,m_nuhLayerId (nuhLayerId) {} @@ -74,6 +86,16 @@ struct NALUnit /** returns true if the NALunit is a slice NALunit */ bool isSlice() { +#if JVET_N0067_NAL_Unit_Header + return m_nalUnitType == NAL_UNIT_CODED_SLICE_TRAIL + || m_nalUnitType == NAL_UNIT_CODED_SLICE_STSA + || m_nalUnitType == NAL_UNIT_CODED_SLICE_IDR_W_RADL + || m_nalUnitType == NAL_UNIT_CODED_SLICE_IDR_N_LP + || m_nalUnitType == NAL_UNIT_CODED_SLICE_CRA + || m_nalUnitType == NAL_UNIT_CODED_SLICE_GRA + || m_nalUnitType == NAL_UNIT_CODED_SLICE_RADL + || m_nalUnitType == NAL_UNIT_CODED_SLICE_RASL; +#else #if JVET_M0101_HLS return m_nalUnitType == NAL_UNIT_CODED_SLICE_TRAIL || m_nalUnitType == NAL_UNIT_CODED_SLICE_STSA @@ -99,6 +121,7 @@ struct NALUnit || m_nalUnitType == NAL_UNIT_CODED_SLICE_RADL_R || m_nalUnitType == NAL_UNIT_CODED_SLICE_RASL_N || m_nalUnitType == NAL_UNIT_CODED_SLICE_RASL_R; +#endif #endif } bool isSei() @@ -109,7 +132,19 @@ struct NALUnit bool isVcl() { +#if JVET_N0067_NAL_Unit_Header + return m_nalUnitType == NAL_UNIT_CODED_SLICE_TRAIL + || m_nalUnitType == NAL_UNIT_CODED_SLICE_STSA + || m_nalUnitType == NAL_UNIT_CODED_SLICE_RADL + || m_nalUnitType == NAL_UNIT_CODED_SLICE_RASL + || m_nalUnitType == NAL_UNIT_CODED_SLICE_IDR_W_RADL + || m_nalUnitType == NAL_UNIT_CODED_SLICE_IDR_N_LP + || m_nalUnitType == NAL_UNIT_CODED_SLICE_CRA + || m_nalUnitType == NAL_UNIT_CODED_SLICE_GRA; + +#else return ( (uint32_t)m_nalUnitType < 32 ); +#endif } }; diff --git a/source/Lib/CommonLib/Rom.cpp b/source/Lib/CommonLib/Rom.cpp index 93f56a94890a79d9aa64f29816f66e6462b25cf3..3caa639c9707cf5df8706057cf7a40d55a13fbce 100644 --- a/source/Lib/CommonLib/Rom.cpp +++ b/source/Lib/CommonLib/Rom.cpp @@ -63,6 +63,27 @@ const char* nalUnitTypeToString(NalUnitType type) { switch (type) { +#if JVET_N0067_NAL_Unit_Header + case NAL_UNIT_PPS: return "PPS"; + case NAL_UNIT_ACCESS_UNIT_DELIMITER: return "AUD"; + case NAL_UNIT_PREFIX_SEI: return "Prefix SEI"; + case NAL_UNIT_SUFFIX_SEI: return "Suffix SEI"; + case NAL_UNIT_APS: return "APS"; + case NAL_UNIT_CODED_SLICE_TRAIL: return "TRAIL"; + case NAL_UNIT_CODED_SLICE_STSA: return "STSA"; + case NAL_UNIT_CODED_SLICE_RADL: return "RADL"; + case NAL_UNIT_CODED_SLICE_RASL: return "RASL"; + case NAL_UNIT_DPS: return "DPS"; + case NAL_UNIT_SPS: return "SPS"; + case NAL_UNIT_EOS: return "EOS"; + case NAL_UNIT_EOB: return "EOB"; + case NAL_UNIT_VPS: return "VPS"; + case NAL_UNIT_CODED_SLICE_IDR_W_RADL: return "IDR_W_RADL"; + case NAL_UNIT_CODED_SLICE_IDR_N_LP: return "IDR_N_LP"; + case NAL_UNIT_CODED_SLICE_CRA: return "CRA"; + case NAL_UNIT_CODED_SLICE_GRA: return "GRA"; + default: return "UNK"; +#else #if JVET_M0101_HLS case NAL_UNIT_CODED_SLICE_TRAIL: return "TRAIL"; case NAL_UNIT_CODED_SLICE_STSA: return "STSA"; @@ -114,6 +135,7 @@ const char* nalUnitTypeToString(NalUnitType type) case NAL_UNIT_PREFIX_SEI: return "Prefix SEI"; case NAL_UNIT_SUFFIX_SEI: return "Suffix SEI"; default: return "UNK"; +#endif #endif } } diff --git a/source/Lib/CommonLib/Slice.cpp b/source/Lib/CommonLib/Slice.cpp index 2e3d9d158eee081ab7296c9e94defd8b59f0ff01..3a6589db60b6bd67da886ea1281c461ffe8aa12b 100644 --- a/source/Lib/CommonLib/Slice.cpp +++ b/source/Lib/CommonLib/Slice.cpp @@ -929,12 +929,17 @@ void Slice::checkLeadingPictureRestrictions(PicList& rcListPic) const if(this->getAssociatedIRAPPOC() > this->getPOC()) { // Do not check IRAP pictures since they may get a POC lower than their associated IRAP +#if JVET_N0067_NAL_Unit_Header + if (nalUnitType < NAL_UNIT_CODED_SLICE_IDR_W_RADL || + nalUnitType > NAL_UNIT_CODED_SLICE_CRA) +#else #if !JVET_M0101_HLS if(nalUnitType < NAL_UNIT_CODED_SLICE_BLA_W_LP || nalUnitType > NAL_UNIT_RESERVED_IRAP_VCL23) #else if (nalUnitType < NAL_UNIT_CODED_SLICE_IDR_W_RADL || nalUnitType > NAL_UNIT_RESERVED_IRAP_VCL13) +#endif #endif { #if !JVET_M0101_HLS diff --git a/source/Lib/CommonLib/Slice.h b/source/Lib/CommonLib/Slice.h index c69de4f1fa47b93e4ff014b177f45f2bb5cdb244..950be854457ac807a82da438e59080959928e127 100644 --- a/source/Lib/CommonLib/Slice.h +++ b/source/Lib/CommonLib/Slice.h @@ -1949,12 +1949,17 @@ public: NalUnitType getNalUnitType() const { return m_eNalUnitType; } bool getRapPicFlag() const; bool getIdrPicFlag() const { return getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_W_RADL || getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_N_LP; } +#if JVET_N0067_NAL_Unit_Header + bool isIRAP() const { return (getNalUnitType() >= NAL_UNIT_CODED_SLICE_IDR_W_RADL) && (getNalUnitType() <= NAL_UNIT_CODED_SLICE_CRA); } + bool isIDRorBLA() const { return (getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_W_RADL) || (getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_N_LP); } +#else #if !JVET_M0101_HLS bool isIRAP() const { return (getNalUnitType() >= 16) && (getNalUnitType() <= 23); } bool isIDRorBLA() const { return (getNalUnitType() >= 16) && (getNalUnitType() <= 20); } #else bool isIRAP() const { return (getNalUnitType() >= NAL_UNIT_CODED_SLICE_IDR_W_RADL) && (getNalUnitType() <= NAL_UNIT_RESERVED_IRAP_VCL13); } bool isIDRorBLA() const { return (getNalUnitType() >= NAL_UNIT_CODED_SLICE_IDR_W_RADL) && (getNalUnitType() <= NAL_UNIT_CODED_SLICE_IDR_N_LP); } +#endif #endif void checkCRA(const ReferencePictureSet *pReferencePictureSet, int& pocCRA, NalUnitType& associatedIRAPType, PicList& rcListPic); void decodingRefreshMarking(int& pocCRA, bool& bRefreshPending, PicList& rcListPic, const bool bEfficientFieldIRAPEnabled); diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index d9c1d8b03a1f2c8ccd08e05b918fef9ca79d0f79..c104ad0e4aded9441fe2f9a3ff0ddc2f4abd19cd 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -50,6 +50,9 @@ #include <assert.h> #include <cassert> +#define JVET_N0067_NAL_Unit_Header 1 // NAL Unit Header + + #define JVET_N0068_AFFINE_MEM_BW 1 // memory bandwidth reduction for affine mode #define JVET_N0308_MAX_CU_SIZE_FOR_ISP 1 @@ -58,6 +61,9 @@ #define JVET_N0103_CGSIZE_HARMONIZATION 1 // Chroma CG sizes aligned to luma CG sizes + + + #define JVET_N0146_DMVR_BDOF_CONDITION 1 // JVET-N146/N0162/N0442/N0153/N0262/N0440/N0086 applicable condition of DMVR and BDOF #define JVET_N0470_SMVD_FIX 1 // remove mvd_l1_zero_flag condition, align to spec text. @@ -887,6 +893,41 @@ enum PPSExtensionFlagIndex // effort can be done without use of macros to alter the names used to indicate the different NAL unit types. enum NalUnitType { + #if JVET_N0067_NAL_Unit_Header + NAL_UNIT_PPS = 0, // 0 + NAL_UNIT_ACCESS_UNIT_DELIMITER, // 1 + NAL_UNIT_PREFIX_SEI, // 2 + NAL_UNIT_SUFFIX_SEI, // 3 + NAL_UNIT_APS, // 4 + NAL_UNIT_RESERVED_NVCL_5, // 5 + NAL_UNIT_RESERVED_NVCL_6, // 6 + NAL_UNIT_RESERVED_NVCL_7, // 7 + NAL_UNIT_CODED_SLICE_TRAIL, // 8 + NAL_UNIT_CODED_SLICE_STSA, // 9 + NAL_UNIT_CODED_SLICE_RADL, // 10 + NAL_UNIT_CODED_SLICE_RASL, // 11 + NAL_UNIT_RESERVED_VCL_12, // 12 + NAL_UNIT_RESERVED_VCL_13, // 13 + NAL_UNIT_RESERVED_VCL_14, // 14 + NAL_UNIT_RESERVED_VCL_15, // 15 + NAL_UNIT_DPS, // 16 + NAL_UNIT_SPS, // 17 + NAL_UNIT_EOS, // 18 + NAL_UNIT_EOB, // 19 + NAL_UNIT_VPS, // 20 + NAL_UNIT_RESERVED_NVCL_21, // 21 + NAL_UNIT_RESERVED_NVCL_22, // 22 + NAL_UNIT_RESERVED_NVCL_23, // 23 + NAL_UNIT_CODED_SLICE_IDR_W_RADL, // 24 + NAL_UNIT_CODED_SLICE_IDR_N_LP, // 25 + NAL_UNIT_CODED_SLICE_CRA, // 26 + NAL_UNIT_CODED_SLICE_GRA, // 27 + NAL_UNIT_UNSPECIFIED_28, // 29 + NAL_UNIT_UNSPECIFIED_29, // 30 + NAL_UNIT_UNSPECIFIED_30, // 31 + NAL_UNIT_UNSPECIFIED_31, // 32 + NAL_UNIT_INVALID +#else #if JVET_M0101_HLS NAL_UNIT_CODED_SLICE_TRAIL = 0, // 0 NAL_UNIT_CODED_SLICE_STSA, // 1 @@ -1016,6 +1057,7 @@ enum NalUnitType NAL_UNIT_UNSPECIFIED_63, NAL_UNIT_INVALID, #endif +#endif }; #if SHARP_LUMA_DELTA_QP diff --git a/source/Lib/DecoderLib/DecLib.cpp b/source/Lib/DecoderLib/DecLib.cpp index 7bec8e65ebaa2ca0992475d23a0cbec2caf601bb..0d6c67733628eefe2581a5476cb8adca5654e197 100644 --- a/source/Lib/DecoderLib/DecLib.cpp +++ b/source/Lib/DecoderLib/DecLib.cpp @@ -1512,6 +1512,7 @@ bool DecLib::decode(InputNALUnit& nalu, int& iSkipFrame, int& iPOCLastDisplay) case NAL_UNIT_EOB: return false; +#if !JVET_N0067_NAL_Unit_Header case NAL_UNIT_FILLER_DATA: { FDReader fdReader; @@ -1520,6 +1521,13 @@ bool DecLib::decode(InputNALUnit& nalu, int& iSkipFrame, int& iPOCLastDisplay) msg( NOTICE, "Note: found NAL_UNIT_FILLER_DATA with %u bytes payload.\n", size); return false; } +#endif +#if JVET_N0067_NAL_Unit_Header + case NAL_UNIT_RESERVED_VCL_12: + case NAL_UNIT_RESERVED_VCL_13: + case NAL_UNIT_RESERVED_VCL_14: + case NAL_UNIT_RESERVED_VCL_15: +#else #if !JVET_M0101_HLS case NAL_UNIT_RESERVED_VCL_N10: case NAL_UNIT_RESERVED_VCL_R11: @@ -1556,10 +1564,19 @@ bool DecLib::decode(InputNALUnit& nalu, int& iSkipFrame, int& iPOCLastDisplay) #if !HEVC_VPS case NAL_UNIT_RESERVED_VCL15: #endif +#endif #endif msg( NOTICE, "Note: found reserved VCL NAL unit.\n"); xParsePrefixSEIsForUnknownVCLNal(); return false; +#if JVET_N0067_NAL_Unit_Header + case NAL_UNIT_RESERVED_NVCL_5: + case NAL_UNIT_RESERVED_NVCL_6: + case NAL_UNIT_RESERVED_NVCL_7: + case NAL_UNIT_RESERVED_NVCL_21: + case NAL_UNIT_RESERVED_NVCL_22: + case NAL_UNIT_RESERVED_NVCL_23: +#else #if !JVET_M0101_HLS case NAL_UNIT_RESERVED_NVCL41: case NAL_UNIT_RESERVED_NVCL42: @@ -1572,6 +1589,7 @@ bool DecLib::decode(InputNALUnit& nalu, int& iSkipFrame, int& iPOCLastDisplay) case NAL_UNIT_RESERVED_NVCL16: case NAL_UNIT_RESERVED_NVCL26: case NAL_UNIT_RESERVED_NVCL27: +#endif #endif msg( NOTICE, "Note: found reserved NAL unit.\n"); return false; diff --git a/source/Lib/DecoderLib/NALread.cpp b/source/Lib/DecoderLib/NALread.cpp index 7b507b99fbe67d13581ea4bdcf2b7bc48f749907..3f32f8cfba9e55e65fb8feb7dddbdbd4e412f929 100644 --- a/source/Lib/DecoderLib/NALread.cpp +++ b/source/Lib/DecoderLib/NALread.cpp @@ -110,11 +110,18 @@ static void convertPayloadToRBSP(vector<uint8_t>& nalUnitBuf, InputBitstream *bi static void xTraceNalUnitHeader(InputNALUnit& nalu) { DTRACE( g_trace_ctx, D_NALUNITHEADER, "*********** NAL UNIT (%s) ***********\n", nalUnitTypeToString(nalu.m_nalUnitType) ); - + #if JVET_N0067_NAL_Unit_Header + DTRACE( g_trace_ctx, D_NALUNITHEADER, "%-50s u(%d) : %u\n", "zero_tid_required_flag", 1, nalu.m_zeroTidRequiredFlag ); + DTRACE( g_trace_ctx, D_NALUNITHEADER, "%-50s u(%d) : %u\n", "nuh_temporal_id_plus1", 3, nalu.m_temporalId + 1 ); + DTRACE( g_trace_ctx, D_NALUNITHEADER, "%-50s u(%d) : %u\n", "nal_unit_type_lsb", 4, (nalu.m_nalUnitType) - (nalu.m_zeroTidRequiredFlag << 4)); + DTRACE( g_trace_ctx, D_NALUNITHEADER, "%-50s u(%d) : %u\n", "nuh_layer_id", 7, nalu.m_nuhLayerId ); + DTRACE( g_trace_ctx, D_NALUNITHEADER, "%-50s u(%d) : %u\n", "nuh_reserved_zero_bit", 1, 0 ); + #else DTRACE( g_trace_ctx, D_NALUNITHEADER, "%-50s u(%d) : %u\n", "forbidden_zero_bit", 1, 0 ); DTRACE( g_trace_ctx, D_NALUNITHEADER, "%-50s u(%d) : %u\n", "nal_unit_type", 6, nalu.m_nalUnitType ); DTRACE( g_trace_ctx, D_NALUNITHEADER, "%-50s u(%d) : %u\n", "nuh_layer_id", 6, nalu.m_nuhLayerId ); DTRACE( g_trace_ctx, D_NALUNITHEADER, "%-50s u(%d) : %u\n", "nuh_temporal_id_plus1", 3, nalu.m_temporalId + 1 ); + #endif } #endif @@ -122,14 +129,41 @@ void readNalUnitHeader(InputNALUnit& nalu) { InputBitstream& bs = nalu.getBitstream(); +#if JVET_N0067_NAL_Unit_Header + nalu.m_zeroTidRequiredFlag = bs.read(1); // zero_tid_required_flag + nalu.m_temporalId = bs.read(3) - 1; // nuh_temporal_id_plus1 + if(nalu.m_temporalId < 0) { + THROW( "Temporal ID is negative." ); + } + //When zero_tid_required_flag is equal to 1, the value of nuh_temporal_id_plus1 shall be equal to 1. + if((nalu.m_zeroTidRequiredFlag == 1) && (nalu.m_temporalId != 0)) { + THROW( "Temporal ID is not '0' when zero tid is required." ); + } + uint32_t m_nalUnitTypeLsb = bs.read(4); // nal_unit_type_lsb + nalu.m_nalUnitType = (NalUnitType) ((nalu.m_zeroTidRequiredFlag << 4) + m_nalUnitTypeLsb); + nalu.m_nuhLayerId = bs.read(7); // nuh_layer_id + if((nalu.m_nuhLayerId < 0) || (nalu.m_nuhLayerId > 126)) { + THROW( "Layer ID out of range" ); + } + uint32_t nuh_reserved_zero_bit = bs.read(1); // nuh_reserved_zero_bit + if(nuh_reserved_zero_bit != 0) { + THROW( "Reserved zero bit is not '0'" ); + } +#else bool forbidden_zero_bit = bs.read(1); // forbidden_zero_bit if(forbidden_zero_bit != 0) { THROW( "Forbidden zero-bit not '0'" );} nalu.m_nalUnitType = (NalUnitType) bs.read(6); // nal_unit_type nalu.m_nuhLayerId = bs.read(6); // nuh_layer_id nalu.m_temporalId = bs.read(3) - 1; // nuh_temporal_id_plus1 +#endif + #if RExt__DECODER_DEBUG_BIT_STATISTICS +#if JVET_N0067_NAL_Unit_Header + CodingStatistics::IncrementStatisticEP(STATS__NAL_UNIT_HEADER_BITS, 1+3+4+7+1, 0); +#else CodingStatistics::IncrementStatisticEP(STATS__NAL_UNIT_HEADER_BITS, 1+6+6+3, 0); #endif +#endif #if ENABLE_TRACING xTraceNalUnitHeader(nalu); @@ -140,6 +174,12 @@ void readNalUnitHeader(InputNALUnit& nalu) { if ( nalu.m_temporalId ) { +#if JVET_N0067_NAL_Unit_Header + CHECK( + (uint32_t)nalu.m_nalUnitType >= 16 + && (uint32_t)nalu.m_nalUnitType <= 31 + , "Invalid NAL type" ); +#else #if HEVC_VPS #if !JVET_M0101_HLS CHECK( nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_BLA_W_LP @@ -185,10 +225,14 @@ void readNalUnitHeader(InputNALUnit& nalu) , "Invalid NAL type"); #endif #endif - +#endif } else { +#if JVET_N0067_NAL_Unit_Header + CHECK(nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_STSA + , "Invalid NAL type"); +#else #if !JVET_M0101_HLS CHECK( nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_TSA_R || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_TSA_N @@ -198,6 +242,7 @@ void readNalUnitHeader(InputNALUnit& nalu) #else CHECK(nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_STSA , "Invalid NAL type"); +#endif #endif } } diff --git a/source/Lib/EncoderLib/NALwrite.cpp b/source/Lib/EncoderLib/NALwrite.cpp index 93b09b4d90535882605a4c272a0246dc76114690..1cf976ebed40fe036edf04a09aaa20fec691aca7 100644 --- a/source/Lib/EncoderLib/NALwrite.cpp +++ b/source/Lib/EncoderLib/NALwrite.cpp @@ -49,12 +49,23 @@ static const uint8_t emulation_prevention_three_byte = 3; void writeNalUnitHeader(ostream& out, OutputNALUnit& nalu) // nal_unit_header() { OutputBitstream bsNALUHeader; +#if JVET_N0067_NAL_Unit_Header + if((nalu.m_nalUnitType >= 16) && (nalu.m_nalUnitType <= 31)) { + nalu.m_zeroTidRequiredFlag = 1; + } + bsNALUHeader.write(nalu.m_zeroTidRequiredFlag, 1); // zero_tid_required_flag + bsNALUHeader.write(nalu.m_temporalId+1, 3); // nuh_temporal_id_plus1 + uint32_t m_nalUnitTypeLsb = (nalu.m_nalUnitType) - (nalu.m_zeroTidRequiredFlag << 4); + bsNALUHeader.write(m_nalUnitTypeLsb, 4); // nal_unit_type_lsb + bsNALUHeader.write(nalu.m_nuhLayerId, 7); // nuh_layer_id + bsNALUHeader.write(0, 1); // nuh_reserved_zero_bit +#else bsNALUHeader.write(0,1); // forbidden_zero_bit bsNALUHeader.write(nalu.m_nalUnitType, 6); // nal_unit_type bsNALUHeader.write(nalu.m_nuhLayerId, 6); // nuh_layer_id bsNALUHeader.write(nalu.m_temporalId+1, 3); // nuh_temporal_id_plus1 - +#endif out.write(reinterpret_cast<const char*>(bsNALUHeader.getByteStream()), bsNALUHeader.getByteStreamLength()); } /** diff --git a/source/Lib/EncoderLib/NALwrite.h b/source/Lib/EncoderLib/NALwrite.h index b107a2f4c3425e7d3d123c25372e7946bbc1140a..57d7770325b44a67210d0fcaf6308749ecc2fcad 100644 --- a/source/Lib/EncoderLib/NALwrite.h +++ b/source/Lib/EncoderLib/NALwrite.h @@ -58,9 +58,16 @@ struct OutputNALUnit : public NALUnit */ OutputNALUnit( NalUnitType nalUnitType, +#if JVET_N0067_NAL_Unit_Header + uint32_t zeroTidRequiredFlag = 0, + uint32_t temporalID = 0, + uint32_t nuhLayerId = 0) + : NALUnit(nalUnitType, zeroTidRequiredFlag, temporalID, nuhLayerId) +#else uint32_t temporalID = 0, uint32_t reserved_zero_6bits = 0) : NALUnit(nalUnitType, temporalID, reserved_zero_6bits) +#endif , m_Bitstream() {}