From 3884249d4b3c303f8376412466f3dd5b58e9edb2 Mon Sep 17 00:00:00 2001 From: Jonatan Samuelsson <jonatan.samuelsson@divideon.com> Date: Thu, 23 Jan 2020 10:54:46 +0100 Subject: [PATCH] Enable signalling of slice header in picture header --- source/App/DecoderApp/DecApp.cpp | 13 ++++++++++++- source/Lib/CommonLib/TypeDef.h | 4 ++++ source/Lib/DecoderLib/DecLib.cpp | 6 ++++++ source/Lib/DecoderLib/NALread.cpp | 8 ++++++++ source/Lib/DecoderLib/NALread.h | 4 +++- source/Lib/DecoderLib/VLCReader.cpp | 20 +++++++++++++++++++- source/Lib/DecoderLib/VLCReader.h | 4 ++++ source/Lib/EncoderLib/EncGOP.cpp | 11 +++++++++++ source/Lib/EncoderLib/VLCWriter.cpp | 23 ++++++++++++++++++++++- source/Lib/EncoderLib/VLCWriter.h | 4 ++++ 10 files changed, 93 insertions(+), 4 deletions(-) diff --git a/source/App/DecoderApp/DecApp.cpp b/source/App/DecoderApp/DecApp.cpp index 69d4b1f7c4..af088ce082 100644 --- a/source/App/DecoderApp/DecApp.cpp +++ b/source/App/DecoderApp/DecApp.cpp @@ -492,8 +492,12 @@ bool DecApp::isNewPicture(ifstream *bitstreamFile, class InputByteStream *bytest ret = true; finished = true; break; - + +#if JVET_Q0775_PH_IN_SH + // NUT that may be the start of a new picture - check first bit in slice header +#else // NUT that are not the start of a new picture +#endif case NAL_UNIT_CODED_SLICE_TRAIL: case NAL_UNIT_CODED_SLICE_STSA: case NAL_UNIT_CODED_SLICE_RASL: @@ -507,6 +511,13 @@ bool DecApp::isNewPicture(ifstream *bitstreamFile, class InputByteStream *bytest case NAL_UNIT_CODED_SLICE_GDR: case NAL_UNIT_RESERVED_IRAP_VCL_11: case NAL_UNIT_RESERVED_IRAP_VCL_12: +#if JVET_Q0775_PH_IN_SH + ret = checkPictureHeaderInSliceHeaderFlag(nalu); + finished = true; + break; + + // NUT that are not the start of a new picture +#endif case NAL_UNIT_EOS: case NAL_UNIT_EOB: case NAL_UNIT_SUFFIX_APS: diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index 6da12cd707..f4180e5be6 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -71,6 +71,10 @@ #define JVET_Q0055_MTS_SIGNALLING 1 // JVET-Q0055: Check for transform coefficients outside the 16x16 area #define JVET_Q0480_RASTER_RECT_SLICES 1 // JVET-Q0480: Eliminate redundant slice height syntax when in raster rectangular slice mode (tile_idx_delta_present_flag == 0) +<<<<<<< HEAD +======= +#define JVET_Q0775_PH_IN_SH 1 // JVET-Q0755: Allow picture header in slice header +>>>>>>> Enable signalling of slice header in picture header #define JVET_Q0433_MODIFIED_CHROMA_DIST_WEIGHT 1 // modification of chroma distortion weight (as agreed during presentation of JVET-Q0433) diff --git a/source/Lib/DecoderLib/DecLib.cpp b/source/Lib/DecoderLib/DecLib.cpp index 6b62da6341..1e31c73fe5 100644 --- a/source/Lib/DecoderLib/DecLib.cpp +++ b/source/Lib/DecoderLib/DecLib.cpp @@ -1205,15 +1205,21 @@ void DecLib::xParsePrefixSEImessages() void DecLib::xDecodePicHeader( InputNALUnit& nalu ) { m_HLSReader.setBitstream( &nalu.getBitstream() ); +#if JVET_Q0775_PH_IN_SH + m_HLSReader.parsePictureHeader( &m_picHeader, &m_parameterSetManager, true ); +#else m_HLSReader.parsePictureHeader( &m_picHeader, &m_parameterSetManager); +#endif m_picHeader.setValid(); } bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDisplay ) { +#if !JVET_Q0775_PH_IN_SH if(m_picHeader.isValid() == false) { return false; } +#endif m_apcSlicePilot->setPicHeader( &m_picHeader ); m_apcSlicePilot->initSlice(); // the slice pilot is an object to prepare for a new slice // it is not associated with picture, sps or pps structures. diff --git a/source/Lib/DecoderLib/NALread.cpp b/source/Lib/DecoderLib/NALread.cpp index 07dddd03f6..819bcc2518 100644 --- a/source/Lib/DecoderLib/NALread.cpp +++ b/source/Lib/DecoderLib/NALread.cpp @@ -167,4 +167,12 @@ void read(InputNALUnit& nalu) bitstream.resetToStart(); readNalUnitHeader(nalu); } +#if JVET_Q0775_PH_IN_SH +bool checkPictureHeaderInSliceHeaderFlag(InputNALUnit& nalu) +{ + InputBitstream& bitstream = nalu.getBitstream(); + CHECK(bitstream.getByteLocation() != 2, "The picture_header_in_slice_header_flag is the first bit after the NAL unit header"); + return (bool)bitstream.read(1); +} +#endif //! \} diff --git a/source/Lib/DecoderLib/NALread.h b/source/Lib/DecoderLib/NALread.h index 1778dc5055..f807fbed75 100644 --- a/source/Lib/DecoderLib/NALread.h +++ b/source/Lib/DecoderLib/NALread.h @@ -67,7 +67,9 @@ class InputNALUnit : public NALUnit void read(InputNALUnit& nalu); void readNalUnitHeader(InputNALUnit& nalu); - +#if JVET_Q0775_PH_IN_SH +bool checkPictureHeaderInSliceHeaderFlag(InputNALUnit & nalu); +#endif //! \} #endif diff --git a/source/Lib/DecoderLib/VLCReader.cpp b/source/Lib/DecoderLib/VLCReader.cpp index 09400e0168..f2af42e183 100644 --- a/source/Lib/DecoderLib/VLCReader.cpp +++ b/source/Lib/DecoderLib/VLCReader.cpp @@ -1715,7 +1715,11 @@ void HLSyntaxReader::parseVPS(VPS* pcVPS) xReadRbspTrailingBits(); } +#if JVET_Q0775_PH_IN_SH +void HLSyntaxReader::parsePictureHeader( PicHeader* picHeader, ParameterSetManager *parameterSetManager, bool readRbspTrailingBits ) +#else void HLSyntaxReader::parsePictureHeader( PicHeader* picHeader, ParameterSetManager *parameterSetManager ) +#endif { uint32_t uiCode; int iCode; @@ -2398,7 +2402,14 @@ void HLSyntaxReader::parsePictureHeader( PicHeader* picHeader, ParameterSetManag } } +#if JVET_Q0775_PH_IN_SH + if( readRbspTrailingBits ) + { + xReadRbspTrailingBits(); + } +#else xReadRbspTrailingBits(); +#endif } void HLSyntaxReader::parseSliceHeader (Slice* pcSlice, PicHeader* picHeader, ParameterSetManager *parameterSetManager, const int prevTid0POC) @@ -2411,7 +2422,14 @@ void HLSyntaxReader::parseSliceHeader (Slice* pcSlice, PicHeader* picHeader, Par #endif PPS* pps = NULL; SPS* sps = NULL; - +#if JVET_Q0775_PH_IN_SH + READ_FLAG(uiCode, "picture_header_in_slice_header_flag"); + if (uiCode) + { + parsePictureHeader(picHeader, parameterSetManager, false); + picHeader->setValid(); + } +#endif CHECK(picHeader==0, "Invalid Picture Header"); CHECK(picHeader->isValid()==false, "Invalid Picture Header"); pps = parameterSetManager->getPPS( picHeader->getPPSId() ); diff --git a/source/Lib/DecoderLib/VLCReader.h b/source/Lib/DecoderLib/VLCReader.h index 69e3f479ca..67933c02e3 100644 --- a/source/Lib/DecoderLib/VLCReader.h +++ b/source/Lib/DecoderLib/VLCReader.h @@ -167,7 +167,11 @@ public: void parseConstraintInfo (ConstraintInfo *cinfo); void parseProfileTierLevel ( ProfileTierLevel *ptl, int maxNumSubLayersMinus1); void parseHrdParameters ( HRDParameters *hrd, uint32_t firstSubLayer, uint32_t tempLevelHigh ); +#if JVET_Q0775_PH_IN_SH + void parsePictureHeader ( PicHeader* picHeader, ParameterSetManager *parameterSetManager, bool readRbspTrailingBits ); +#else void parsePictureHeader ( PicHeader* picHeader, ParameterSetManager *parameterSetManager ); +#endif void parseSliceHeader ( Slice* pcSlice, PicHeader* picHeader, ParameterSetManager *parameterSetManager, const int prevTid0POC ); void parseSliceHeaderToPoc ( Slice* pcSlice, PicHeader* picHeader, ParameterSetManager *parameterSetManager, const int prevTid0POC ); void parseTerminatingBit ( uint32_t& ruiBit ); diff --git a/source/Lib/EncoderLib/EncGOP.cpp b/source/Lib/EncoderLib/EncGOP.cpp index 0bc3ea911b..194ba90a46 100644 --- a/source/Lib/EncoderLib/EncGOP.cpp +++ b/source/Lib/EncoderLib/EncGOP.cpp @@ -401,7 +401,11 @@ int EncGOP::xWritePicHeader( AccessUnit &accessUnit, PicHeader *picHeader ) m_HLSWriter->setBitstream( &nalu.m_Bitstream ); nalu.m_temporalId = accessUnit.temporalId; nalu.m_nuhLayerId = m_pcEncLib->getLayerId(); +#if JVET_Q0775_PH_IN_SH + m_HLSWriter->codePictureHeader( picHeader, true ); +#else m_HLSWriter->codePictureHeader( picHeader ); +#endif accessUnit.push_back(new NALUnitEBSP(nalu)); return (int)(accessUnit.back()->m_nalUnitData.str().size()) * 8; } @@ -3074,7 +3078,14 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic, pcPic->cs->picHeader->setPic(pcPic); pcPic->cs->picHeader->setValid(); +#if JVET_Q0775_PH_IN_SH + if (pcPic->cs->pps->getNumSlicesInPic() > 1) + { + actualTotalBits += xWritePicHeader(accessUnit, pcPic->cs->picHeader); + } +#else actualTotalBits += xWritePicHeader(accessUnit, pcPic->cs->picHeader); +#endif } pcSlice->setPicHeader( pcPic->cs->picHeader ); diff --git a/source/Lib/EncoderLib/VLCWriter.cpp b/source/Lib/EncoderLib/VLCWriter.cpp index d00d64a669..728598cab2 100644 --- a/source/Lib/EncoderLib/VLCWriter.cpp +++ b/source/Lib/EncoderLib/VLCWriter.cpp @@ -1162,7 +1162,11 @@ void HLSWriter::codeVPS(const VPS* pcVPS) xWriteRbspTrailingBits(); } +#if JVET_Q0775_PH_IN_SH +void HLSWriter::codePictureHeader( PicHeader* picHeader, bool writeRbspTrailingBits ) +#else void HLSWriter::codePictureHeader( PicHeader* picHeader ) +#endif { const PPS* pps = NULL; const SPS* sps = NULL; @@ -1714,7 +1718,14 @@ void HLSWriter::codePictureHeader( PicHeader* picHeader ) WRITE_UVLC(0,"pic_segment_header_extension_length"); } +#if JVET_Q0775_PH_IN_SH + if ( writeRbspTrailingBits ) + { + xWriteRbspTrailingBits(); + } +#else xWriteRbspTrailingBits(); +#endif } void HLSWriter::codeSliceHeader ( Slice* pcSlice ) @@ -1724,11 +1735,21 @@ void HLSWriter::codeSliceHeader ( Slice* pcSlice ) #endif CodingStructure& cs = *pcSlice->getPic()->cs; +#if JVET_Q0775_PH_IN_SH + PicHeader *picHeader = cs.picHeader; +#else const PicHeader *picHeader = cs.picHeader; +#endif const ChromaFormat format = pcSlice->getSPS()->getChromaFormatIdc(); const uint32_t numberValidComponents = getNumberValidComponents(format); const bool chromaEnabled = isChromaEnabled(format); - +#if JVET_Q0775_PH_IN_SH + WRITE_FLAG(cs.pps->getNumSlicesInPic() == 1 ? 1 : 0, "picture_header_in_slice_header_flag"); + if (cs.pps->getNumSlicesInPic() == 1) + { + codePictureHeader(picHeader, false); + } +#endif int pocBits = pcSlice->getSPS()->getBitsForPOC(); int pocMask = (1 << pocBits) - 1; WRITE_CODE(pcSlice->getPOC() & pocMask, pocBits, "slice_pic_order_cnt_lsb"); diff --git a/source/Lib/EncoderLib/VLCWriter.h b/source/Lib/EncoderLib/VLCWriter.h index 7816710363..5fb0ad3909 100644 --- a/source/Lib/EncoderLib/VLCWriter.h +++ b/source/Lib/EncoderLib/VLCWriter.h @@ -129,7 +129,11 @@ public: void codeScalingListAps ( APS* pcAPS ); void codeVPS ( const VPS* pcVPS ); void codeDPS ( const DPS* dps ); +#if JVET_Q0775_PH_IN_SH + void codePictureHeader ( PicHeader* picHeader, bool writeRbspTrailingBits ); +#else void codePictureHeader ( PicHeader* picHeader ); +#endif void codeSliceHeader ( Slice* pcSlice ); void codeConstraintInfo ( const ConstraintInfo* cinfo ); void codeProfileTierLevel ( const ProfileTierLevel* ptl, int maxNumSubLayersMinus1 ); -- GitLab