diff --git a/cfg/nonCTC-SliceConfigExamples/encoder_randomaccess_vtm_RasterScanSlice.cfg b/cfg/nonCTC-SliceConfigExamples/encoder_randomaccess_vtm_RasterScanSlice.cfg index ca7d109219c208df9b751082e07b0cc1f69c495f..1df2375bed19772df106d71c6e0e4ef50d98b18a 100644 --- a/cfg/nonCTC-SliceConfigExamples/encoder_randomaccess_vtm_RasterScanSlice.cfg +++ b/cfg/nonCTC-SliceConfigExamples/encoder_randomaccess_vtm_RasterScanSlice.cfg @@ -86,6 +86,9 @@ LFCrossSliceBoundaryFlag : 1 # In-loop filtering, including ALF a #============ Tiles ================ TileUniformSpacing : 0 # 0: the column boundaries are indicated by TileColumnWidth array, the row boundaries are indicated by TileRowHeight array # 1: the column and row boundaries are distributed uniformly +UniformTileColsWidthMinus1 : 0 # Width to use if TileUniformSpacing is equal to 1 +UniformTileRowHeightMinus1 : 0 # Height to use if TileUniformSpacing is equal to 1 + NumTileColumnsMinus1 : 1 # Number of tile columns in a picture minus 1 TileColumnWidthArray : 2 # Array containing tile column width values in units of CTU (from left to right in picture) NumTileRowsMinus1 : 1 # Number of tile rows in a picture minus 1 diff --git a/cfg/nonCTC-SliceConfigExamples/encoder_randomaccess_vtm_RectangularSlice.cfg b/cfg/nonCTC-SliceConfigExamples/encoder_randomaccess_vtm_RectangularSlice.cfg index 2e87582d1dab56980d890cf1bd90a5672f1c2a89..a69582afc09963d46dc9345b3885f5d723b8ea7f 100644 --- a/cfg/nonCTC-SliceConfigExamples/encoder_randomaccess_vtm_RectangularSlice.cfg +++ b/cfg/nonCTC-SliceConfigExamples/encoder_randomaccess_vtm_RectangularSlice.cfg @@ -86,6 +86,8 @@ LFCrossSliceBoundaryFlag : 1 # In-loop filtering, including ALF a #============ Tiles ================ TileUniformSpacing : 0 # 0: the column boundaries are indicated by TileColumnWidth array, the row boundaries are indicated by TileRowHeight array # 1: the column and row boundaries are distributed uniformly +UniformTileColsWidthMinus1 : 0 # Width to use if TileUniformSpacing is equal to 1 +UniformTileRowHeightMinus1 : 0 # Height to use if TileUniformSpacing is equal to 1 NumTileColumnsMinus1 : 3 # Number of tile columns in a picture minus 1 TileColumnWidthArray : 1 1 1 # Array containing tile column width values in units of CTU (from left to right in picture) NumTileRowsMinus1 : 1 # Number of tile rows in a picture minus 1 diff --git a/cfg/nonCTC-SliceConfigExamples/encoder_randomaccess_vtm_SingleTilePerSlice.cfg b/cfg/nonCTC-SliceConfigExamples/encoder_randomaccess_vtm_SingleTilePerSlice.cfg index 0fb70587452f2ec0434dcc6ef587d100c7920c32..0aeccf23b3c463346ba1f47c8233ef49f75b9658 100644 --- a/cfg/nonCTC-SliceConfigExamples/encoder_randomaccess_vtm_SingleTilePerSlice.cfg +++ b/cfg/nonCTC-SliceConfigExamples/encoder_randomaccess_vtm_SingleTilePerSlice.cfg @@ -84,8 +84,11 @@ LFCrossSliceBoundaryFlag : 1 # In-loop filtering, including ALF a # 0:not across, 1: across #============ Tiles ================ -TileUniformSpacing : 0 # 0: the column boundaries are indicated by TileColumnWidth array, the row boundaries are indicated by TileRowHeight array +TileUniformSpacing : 1 # 0: the column boundaries are indicated by TileColumnWidth array, the row boundaries are indicated by TileRowHeight array # 1: the column and row boundaries are distributed uniformly +UniformTileColsWidthMinus1 : 1 # Width to use if TileUniformSpacing is equal to 1 +UniformTileRowHeightMinus1 : 0 # Height to use if TileUniformSpacing is equal to 1 + NumTileColumnsMinus1 : 1 # Number of tile columns in a picture minus 1 TileColumnWidthArray : 2 # Array containing tile column width values in units of CTU (from left to right in picture) NumTileRowsMinus1 : 1 # Number of tile rows in a picture minus 1 diff --git a/doc/software-manual.tex b/doc/software-manual.tex index 2573b671a424763b48eb520eb9d2d44c5b1e3995..820df1b14e1df0497b45e0d89078b692af8037b6 100755 --- a/doc/software-manual.tex +++ b/doc/software-manual.tex @@ -1761,6 +1761,13 @@ Controls the mode used to determine per row and column tile sizes. \end{tabular} \\ +\Option{UniformTileColsWidthMinus1}% +\Option{UniformTileRowHeightMinus1} & +%\ShortOption{\None} & +\Default{-1} & +Specifies the tile width and height to use if TileUniformSpacing is set to 1. +\\ + \Option{NumTileColumnsMinus1}% \Option{NumTileRowsMinus1} & %\ShortOption{\None} & diff --git a/source/App/EncoderApp/EncApp.cpp b/source/App/EncoderApp/EncApp.cpp index e0bef48c13fbd2ea9ee23ee29013521997dbbe91..8646b6e48aebee4a43add86685dce75ede798091 100644 --- a/source/App/EncoderApp/EncApp.cpp +++ b/source/App/EncoderApp/EncApp.cpp @@ -554,6 +554,13 @@ void EncApp::xInitLibCfg() #endif m_cEncLib.setTileUniformSpacingFlag ( m_tileUniformSpacingFlag ); +#if JVET_O0143_BOTTOM_RIGHT_BRICK_IDX_DELTA + if (m_tileUniformSpacingFlag) + { + m_cEncLib.setUniformTileColsWidthMinus1 ( m_uniformTileColsWidthMinus1 ); + m_cEncLib.setUniformTileRowHeightMinus1 ( m_uniformTileRowHeightMinus1 ); + } +#endif m_cEncLib.setNumColumnsMinus1 ( m_numTileColumnsMinus1 ); m_cEncLib.setNumRowsMinus1 ( m_numTileRowsMinus1 ); if(!m_tileUniformSpacingFlag) diff --git a/source/App/EncoderApp/EncAppCfg.cpp b/source/App/EncoderApp/EncAppCfg.cpp index 91ba60a3ec5053d418ac291c9621c4b455d084d1..56a3813a0871afd3bd6f68222f68830c60b633f8 100644 --- a/source/App/EncoderApp/EncAppCfg.cpp +++ b/source/App/EncoderApp/EncAppCfg.cpp @@ -1180,6 +1180,10 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) ("TileUniformSpacing", m_tileUniformSpacingFlag, false, "Indicates that tile columns and rows are distributed uniformly") ("NumTileColumnsMinus1", m_numTileColumnsMinus1, 0, "Number of tile columns in a picture minus 1") ("NumTileRowsMinus1", m_numTileRowsMinus1, 0, "Number of rows in a picture minus 1") +#if JVET_O0143_BOTTOM_RIGHT_BRICK_IDX_DELTA + ("UniformTileColsWidthMinus1", m_uniformTileColsWidthMinus1, -1, "Tile width to use for uniform tiles minus 1") + ("UniformTileRowHeightMinus1", m_uniformTileRowHeightMinus1, -1, "Tile height to use for uniform tiles minus 1") +#endif ("TileColumnWidthArray", cfg_ColumnWidth, cfg_ColumnWidth, "Array containing tile column width values in units of CTU") ("TileRowHeightArray", cfg_RowHeight, cfg_RowHeight, "Array containing tile row height values in units of CTU") ("LFCrossTileBoundaryFlag", m_bLFCrossTileBoundaryFlag, true, "1: cross-tile-boundary loop filtering. 0:non-cross-tile-boundary loop filtering") @@ -1597,7 +1601,15 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) { m_tileRowHeight.clear(); } - +#if JVET_O0143_BOTTOM_RIGHT_BRICK_IDX_DELTA + if (m_tileUniformSpacingFlag) + { + int uniformTileHeight = ((m_uniformTileRowHeightMinus1 + 1) * m_uiCTUSize); + int uniformTileWidth = ((m_uniformTileColsWidthMinus1 + 1) * m_uiCTUSize); + m_numTileRowsMinus1 = ((m_iSourceHeight + uniformTileHeight - 1) / uniformTileHeight) - 1; + m_numTileColumnsMinus1 = ((m_iSourceWidth + uniformTileWidth - 1) / uniformTileWidth) - 1; + } +#endif /* rules for input, output and internal bitdepths as per help text */ if (m_MSBExtendedBitDepth[CHANNEL_TYPE_LUMA ] == 0) { diff --git a/source/App/EncoderApp/EncAppCfg.h b/source/App/EncoderApp/EncAppCfg.h index 913cfaeb39a6a38d2ec77d08b8b6e3e41bb2fe4e..4c67d85fade0bb654ffee889981ea7a14a0aa670 100644 --- a/source/App/EncoderApp/EncAppCfg.h +++ b/source/App/EncoderApp/EncAppCfg.h @@ -445,6 +445,10 @@ protected: bool m_tileUniformSpacingFlag; int m_numTileColumnsMinus1; int m_numTileRowsMinus1; +#if JVET_O0143_BOTTOM_RIGHT_BRICK_IDX_DELTA + int m_uniformTileColsWidthMinus1; + int m_uniformTileRowHeightMinus1; +#endif std::vector<int> m_tileColumnWidth; std::vector<int> m_tileRowHeight; bool m_entropyCodingSyncEnabledFlag; diff --git a/source/Lib/CommonLib/Picture.cpp b/source/Lib/CommonLib/Picture.cpp index f8689f672c830f1b98fb50fd0dbceb208808c850..0a7ded6a5d4d4a9731d4d02bb6c470df1b3d0ea6 100644 --- a/source/Lib/CommonLib/Picture.cpp +++ b/source/Lib/CommonLib/Picture.cpp @@ -519,6 +519,36 @@ void BrickMap::initBrickMap( const SPS& sps, const PPS& pps ) const uint32_t frameWidthInCtus = pcv->widthInCtus; const uint32_t frameHeightInCtus = pcv->heightInCtus; +#if JVET_O0143_BOTTOM_RIGHT_BRICK_IDX_DELTA + std::vector<uint32_t> tileRowHeight; + std::vector<uint32_t> tileColWidth; + if (pps.getUniformTileSpacingFlag()) + { + int tileWidthInCTUs = pps.getTileColsWidthMinus1() + 1; + int tileHeightInCTUs = pps.getTileRowsHeightMinus1() + 1; + int tileWidthInLumaSamples = tileWidthInCTUs * sps.getCTUSize(); + int tileHeightInLumaSamples = tileHeightInCTUs * sps.getCTUSize(); + + numTileColumns = (pps.getPicWidthInLumaSamples() + tileWidthInLumaSamples - 1) / tileWidthInLumaSamples; + numTileRows = (pps.getPicHeightInLumaSamples() + tileHeightInLumaSamples - 1) / tileHeightInLumaSamples; + numTiles = numTileColumns * numTileRows; + + int remainingHeightInCtbsY = frameHeightInCtus; + while (remainingHeightInCtbsY > tileHeightInCTUs) + { + tileRowHeight.push_back(tileHeightInCTUs); + remainingHeightInCtbsY -= tileHeightInCTUs; + } + tileRowHeight.push_back(remainingHeightInCtbsY); + + int remainingWidthInCtbsY = frameWidthInCtus; + while (remainingWidthInCtbsY > tileWidthInCTUs) + { + tileColWidth.push_back(tileWidthInCTUs); + remainingWidthInCtbsY -= tileWidthInCTUs; + } + tileColWidth.push_back(remainingWidthInCtbsY); +#else std::vector<uint32_t> tileRowHeight (numTileRows); std::vector<uint32_t> tileColWidth (numTileColumns); @@ -533,9 +563,14 @@ void BrickMap::initBrickMap( const SPS& sps, const PPS& pps ) { tileColWidth[col] = (col+1)*frameWidthInCtus/numTileColumns - (col*frameWidthInCtus)/numTileColumns; } +#endif } else { +#if JVET_O0143_BOTTOM_RIGHT_BRICK_IDX_DELTA + tileColWidth.resize(numTileColumns); + tileRowHeight.resize(numTileRows); +#endif tileColWidth[ numTileColumns - 1 ] = frameWidthInCtus; for( int i = 0; i < numTileColumns - 1; i++ ) { @@ -572,9 +607,13 @@ void BrickMap::initBrickMap( const SPS& sps, const PPS& pps ) int brickIdx = 0; for(int tileIdx=0; tileIdx< numTiles; tileIdx++) { +#if JVET_O0143_BOTTOM_RIGHT_BRICK_IDX_DELTA + int tileX = tileIdx % numTileColumns; + int tileY = tileIdx / numTileColumns; +#else int tileX = tileIdx % ( pps.getNumTileColumnsMinus1() + 1 ); int tileY = tileIdx / ( pps.getNumTileColumnsMinus1() + 1 ); - +#endif if ( !pps.getBrickSplittingPresentFlag() || !pps.getBrickSplitFlag(tileIdx)) { bricks.resize(bricks.size()+1); @@ -697,6 +736,49 @@ void BrickMap::initBrickMap( const SPS& sps, const PPS& pps ) } } } +#if JVET_O0143_BOTTOM_RIGHT_BRICK_IDX_DELTA + if (pps.getRectSliceFlag()) + { + int numSlicesInPic = (pps.getNumSlicesInPicMinus1() + 1); + int numBricksInPic = (int)bricks.size(); + + std::vector<int> bricksToSliceMap(numBricksInPic); + std::vector<int> numBricksInSlice(numSlicesInPic); + + m_topLeftBrickIdx.resize(numSlicesInPic); + m_bottomRightBrickIdx.resize(numSlicesInPic); + + if (numSlicesInPic == 1) + { + m_topLeftBrickIdx[0] = 0; + m_bottomRightBrickIdx[0] = numBricksInPic - 1; + } + else + { + for (int i = 0; i < numSlicesInPic; i++) + { + for (int j = 0; i == 0 && j < numBricksInPic; j++) + { + bricksToSliceMap[j] = -1; + } + numBricksInSlice[i] = 0; + m_bottomRightBrickIdx[i] = pps.getBottomRightBrickIdxDelta(i) + ((i == 0) ? 0 : m_bottomRightBrickIdx[i - 1]); + for (int j = m_bottomRightBrickIdx[i]; j >= 0; j--) + { + if (bricks[j].getColBd() <= bricks[m_bottomRightBrickIdx[i]].getColBd() && + bricks[j].getRowBd() <= bricks[m_bottomRightBrickIdx[i]].getRowBd() && + bricksToSliceMap[j] == -1) + { + m_topLeftBrickIdx[i] = j; + numBricksInSlice[i]++; + bricksToSliceMap[j] = i; + } + } + } + } + } +#endif + } diff --git a/source/Lib/CommonLib/Picture.h b/source/Lib/CommonLib/Picture.h index 7baba024b62ebcd5b166a6f598565ec145c8612e..afcbbe537d37544aad5f64382a3c4f4132d76f76 100644 --- a/source/Lib/CommonLib/Picture.h +++ b/source/Lib/CommonLib/Picture.h @@ -165,6 +165,13 @@ struct BrickMap uint32_t getSubstreamForCtuAddr(const uint32_t ctuAddr, const bool addressInRaster, Slice *slice) const; +#if JVET_O0143_BOTTOM_RIGHT_BRICK_IDX_DELTA + int getTopLeftBrickIdx(uint32_t val) const { return m_topLeftBrickIdx[val]; } + void setTopLeftBrickIdx(const std::vector<int>& val) { m_topLeftBrickIdx = val; } + int getBottomRightBrickIdx(uint32_t val) const { return m_bottomRightBrickIdx[val]; } + void setBottomRightBrickIdx(const std::vector<int>& val) { m_bottomRightBrickIdx = val; } +#endif + const PreCalcValues* pcv; std::vector<Brick> bricks; @@ -176,6 +183,11 @@ struct BrickMap uint32_t* ctuBsToRsAddrMap; uint32_t* ctuRsToBsAddrMap; +#if JVET_O0143_BOTTOM_RIGHT_BRICK_IDX_DELTA + std::vector<int> m_topLeftBrickIdx; + std::vector<int> m_bottomRightBrickIdx; +#endif + void initBrickMap( const SPS& sps, const PPS& pps ); void initCtuBsRsAddrMap(); }; diff --git a/source/Lib/CommonLib/Slice.h b/source/Lib/CommonLib/Slice.h index e5fc2804b985238ef628e5eb5c9f9ad8a5643bcb..ff7e27527e513d160d9bc4823fc609739d1060a0 100644 --- a/source/Lib/CommonLib/Slice.h +++ b/source/Lib/CommonLib/Slice.h @@ -1290,7 +1290,9 @@ private: int m_numSlicesInPicMinus1; std::vector<int> m_topLeftBrickIdx; std::vector<int> m_bottomRightBrickIdx; - +#if JVET_O0143_BOTTOM_RIGHT_BRICK_IDX_DELTA + std::vector<int> m_bottomRightBrickIdxDelta; +#endif int m_numTilesInPic; int m_numBricksInPic; bool m_signalledSliceIdFlag; @@ -1492,6 +1494,10 @@ public: void setTopLeftBrickIdx(const std::vector<int>& val) { m_topLeftBrickIdx = val; } int getBottomRightBrickIdx(uint32_t columnIdx) const { return m_bottomRightBrickIdx[columnIdx]; } void setBottomRightBrickIdx(const std::vector<int>& val) { m_bottomRightBrickIdx = val; } +#if JVET_O0143_BOTTOM_RIGHT_BRICK_IDX_DELTA + int getBottomRightBrickIdxDelta(uint32_t delta) const { return m_bottomRightBrickIdxDelta[delta]; } + void setBottomRightBrickIdxDelta(const std::vector<int>& val) { m_bottomRightBrickIdxDelta = val; } +#endif int getNumTilesInPic() const { return m_numTilesInPic; } void setNumTilesInPic(int val) { m_numTilesInPic = val; } int getNumBricksInPic() const { return m_numBricksInPic; } diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index 260dccbcd4c1c58ce78a57a2bae2bc4024e14425..44aa44e3ec759f0f138a27e03a423f42c41b05f5 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -50,6 +50,10 @@ #include <assert.h> #include <cassert> +#define JVET_O0143_BOTTOM_RIGHT_BRICK_IDX_DELTA 1 // JVET-O0143: Remove signaling of top_right_brick_idx + +#define JVET_O0236_PPS_PARSING_DEPENDENCY 1 // JVET-O0236: Resolves a PPS parsing dependency + #define JVET_O0148_NUM_ACTIVE_REF_PIC_CHECK 1 // JVET-O0148: Constraint that num active entries in RPL 0 and RPL 1 for P and B pictures #define JVET_O0145_ENTRYPOINT_SIGNALLING 1 // JVET-O0145: Not signalling num_entry_point_offsets but derive it at decoder diff --git a/source/Lib/DecoderLib/DecLib.cpp b/source/Lib/DecoderLib/DecLib.cpp index 22225020e0d6ae58dbe694f4e30929d1c86142c5..6fefef22ff57d5ddedb723d87a3c1d53ee708df3 100644 --- a/source/Lib/DecoderLib/DecLib.cpp +++ b/source/Lib/DecoderLib/DecLib.cpp @@ -1395,6 +1395,19 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl m_pcPic->referenced = true; m_pcPic->layer = nalu.m_temporalId; +#if JVET_O0143_BOTTOM_RIGHT_BRICK_IDX_DELTA + if (pcSlice->getPPS()->getRectSliceFlag()) + { + int sliceIdx = pcSlice->getSliceIndex(); + int topLeft = pcSlice->getPic()->brickMap->getTopLeftBrickIdx(sliceIdx); + int bottomRight = pcSlice->getPic()->brickMap->getBottomRightBrickIdx(sliceIdx); + + pcSlice->setSliceCurStartBrickIdx(topLeft); + pcSlice->setSliceCurEndBrickIdx(bottomRight); + pcSlice->setSliceCurStartCtuTsAddr(pcSlice->getSliceCurStartBrickIdx()); + } +#endif + // When decoding the slice header, the stored start and end addresses were actually RS addresses, not TS addresses. // Now, having set up the maps, convert them to the correct form. const BrickMap& tileMap = *(m_pcPic->brickMap); diff --git a/source/Lib/DecoderLib/VLCReader.cpp b/source/Lib/DecoderLib/VLCReader.cpp index 5e43333627214d77975608bb6432a3027cb18529..1f5d45f2426705d9a86f90cd8d9e000e4ba0cb1d 100644 --- a/source/Lib/DecoderLib/VLCReader.cpp +++ b/source/Lib/DecoderLib/VLCReader.cpp @@ -576,7 +576,24 @@ void HLSyntaxReader::parsePPS( PPS* pcPPS, ParameterSetManager *parameterSetMana READ_FLAG( uiCode, "brick_splitting_present_flag" ); pcPPS->setBrickSplittingPresentFlag(uiCode == 1); +#if JVET_O0236_PPS_PARSING_DEPENDENCY + int numTilesInPic = 0; + if (pcPPS->getUniformTileSpacingFlag()) + { + if (pcPPS->getBrickSplittingPresentFlag()) + { + READ_UVLC(uiCode, "num_tiles_in_pic_minus1"); + numTilesInPic = uiCode + 1; + } + } + else + { + numTilesInPic = (pcPPS->getNumTileColumnsMinus1() + 1) * (pcPPS->getNumTileRowsMinus1() + 1); + } +#else int numTilesInPic = pcPPS->getUniformTileSpacingFlag() ? 0 : (pcPPS->getNumTileColumnsMinus1() + 1) * (pcPPS->getNumTileRowsMinus1() + 1); +#endif + pcPPS->setNumTilesInPic(numTilesInPic); if (pcPPS->getBrickSplittingPresentFlag()) @@ -651,19 +668,42 @@ void HLSyntaxReader::parsePPS( PPS* pcPPS, ParameterSetManager *parameterSetMana if(pcPPS->getRectSliceFlag() && !pcPPS->getSingleBrickPerSliceFlag()) { READ_UVLC (uiCode, "num_slices_in_pic_minus1" ); pcPPS->setNumSlicesInPicMinus1(uiCode); +#if JVET_O0236_PPS_PARSING_DEPENDENCY + const uint32_t numSlicesInPic = pcPPS->getNumSlicesInPicMinus1() + 1; +#else const uint32_t tileColumnsMinus1 = pcPPS->getNumTileColumnsMinus1(); const uint32_t tileRowsMinus1 = pcPPS->getNumTileRowsMinus1(); const uint32_t numSlicesInPic = pcPPS->getNumSlicesInPicMinus1() + 1; const uint32_t numTilesInPic = (tileColumnsMinus1 + 1) * (tileRowsMinus1 + 1); int codeLength = ceilLog2(numTilesInPic); int codeLength2 = codeLength; +#endif +#if JVET_O0143_BOTTOM_RIGHT_BRICK_IDX_DELTA + uint32_t codeLen; + READ_UVLC(codeLen, "bottom_right_brick_idx_length_minus1 "); +#endif if (numSlicesInPic > 0) { +#if JVET_O0143_BOTTOM_RIGHT_BRICK_IDX_DELTA + std::vector<int> bottomRightBrickIdxDelta(numSlicesInPic); +#else std::vector<int> topLeft(numSlicesInPic); std::vector<int> bottomRight(numSlicesInPic); topLeft[0] = 0; +#endif for (uint32_t i = 0; i < numSlicesInPic; i++) { +#if JVET_O0143_BOTTOM_RIGHT_BRICK_IDX_DELTA + READ_CODE(codeLen, uiCode, "bottom_right_brick_idx_delta"); + int delta = uiCode; + READ_FLAG(uiCode, "brick_idx_delta_sign_flag"); + int sign = uiCode; + if (sign == 0) + { + delta = -delta; + } + bottomRightBrickIdxDelta[i] = delta; +#else if (i > 0) { READ_CODE( codeLength, uiCode, "top_left_brick_idx" ); @@ -672,9 +712,14 @@ void HLSyntaxReader::parsePPS( PPS* pcPPS, ParameterSetManager *parameterSetMana } READ_CODE( codeLength2, uiCode, "bottom_right_brick_idx_delta"); bottomRight[i] = topLeft[i] + uiCode; +#endif } +#if JVET_O0143_BOTTOM_RIGHT_BRICK_IDX_DELTA + pcPPS->setBottomRightBrickIdxDelta(bottomRightBrickIdxDelta); +#else pcPPS->setTopLeftBrickIdx(topLeft); pcPPS->setBottomRightBrickIdx(bottomRight); +#endif } } if (pcPPS->getRectSliceFlag() && pcPPS->getSingleBrickPerSliceFlag()) @@ -1875,8 +1920,12 @@ void HLSyntaxReader::parseSliceHeader (Slice* pcSlice, ParameterSetManager *para { sliceIdx++; } +#if JVET_O0143_BOTTOM_RIGHT_BRICK_IDX_DELTA + pcSlice->setSliceIndex(sliceIdx); +#else pcSlice->setSliceCurStartBrickIdx(pps->getTopLeftBrickIdx(sliceIdx)); pcSlice->setSliceCurEndBrickIdx(pps->getBottomRightBrickIdx(sliceIdx)); +#endif } else { @@ -1895,6 +1944,16 @@ void HLSyntaxReader::parseSliceHeader (Slice* pcSlice, ParameterSetManager *para { pcSlice->setSliceNumBricks(1); } +#endif +#if JVET_O0143_BOTTOM_RIGHT_BRICK_IDX_DELTA + if (pps->getRectSliceFlag()) + { + if (pcSlice->getSliceIndex() != 0) + { + pcSlice->setSliceCurStartBrickIdx(pcSlice->getPic()->brickMap->getTopLeftBrickIdx(pcSlice->getSliceIndex())); + pcSlice->setSliceCurEndBrickIdx(pcSlice->getPic()->brickMap->getBottomRightBrickIdx(pcSlice->getSliceIndex())); + } + } #endif pcSlice->setSliceCurStartCtuTsAddr(pcSlice->getSliceCurStartBrickIdx()); diff --git a/source/Lib/EncoderLib/EncCfg.h b/source/Lib/EncoderLib/EncCfg.h index b541bd96aca6c05436d06c030f3d644d704bcf96..5a430caa73dff7e3217346ec695e7d710a90ace9 100644 --- a/source/Lib/EncoderLib/EncCfg.h +++ b/source/Lib/EncoderLib/EncCfg.h @@ -503,6 +503,10 @@ protected: bool m_tileUniformSpacingFlag; int m_iNumColumnsMinus1; int m_iNumRowsMinus1; +#if JVET_O0143_BOTTOM_RIGHT_BRICK_IDX_DELTA + int m_uniformTileColsWidthMinus1; + int m_uniformTileRowHeightMinus1; +#endif std::vector<int> m_tileColumnWidth; std::vector<int> m_tileRowHeight; @@ -1362,6 +1366,12 @@ public: bool getTileUniformSpacingFlag () { return m_tileUniformSpacingFlag; } void setNumColumnsMinus1 ( int i ) { m_iNumColumnsMinus1 = i; } int getNumColumnsMinus1 () { return m_iNumColumnsMinus1; } +#if JVET_O0143_BOTTOM_RIGHT_BRICK_IDX_DELTA + void setUniformTileColsWidthMinus1 (int i) { m_uniformTileColsWidthMinus1 = i; } + int getUniformTileColsWidthMinus1 () { return m_uniformTileColsWidthMinus1; } + void setUniformTileRowHeightMinus1 (int i) { m_uniformTileRowHeightMinus1 = i; } + int getUniformTileRowHeightMinus1 () { return m_uniformTileRowHeightMinus1; } +#endif void setColumnWidth ( const std::vector<int>& columnWidth ) { m_tileColumnWidth = columnWidth; } uint32_t getColumnWidth ( uint32_t columnIdx ) { return m_tileColumnWidth[columnIdx]; } void setNumRowsMinus1 ( int i ) { m_iNumRowsMinus1 = i; } diff --git a/source/Lib/EncoderLib/EncLib.cpp b/source/Lib/EncoderLib/EncLib.cpp index 92a19047fa13400f058917f5344b48748dc28629..35777c365bfd1d5f8d82d9a5bae41ea479eed1e4 100644 --- a/source/Lib/EncoderLib/EncLib.cpp +++ b/source/Lib/EncoderLib/EncLib.cpp @@ -1783,12 +1783,31 @@ void EncLib::xInitPPSforTiles(PPS &pps) pps.setTileColumnWidth( m_tileColumnWidth ); pps.setTileRowHeight( m_tileRowHeight ); } +#if JVET_O0143_BOTTOM_RIGHT_BRICK_IDX_DELTA + else + { + pps.setTileColsWidthMinus1(m_uniformTileColsWidthMinus1); + pps.setTileRowsHeightMinus1(m_uniformTileRowHeightMinus1); + } +#endif pps.setLoopFilterAcrossBricksEnabledFlag( m_loopFilterAcrossBricksEnabledFlag ); //pps.setRectSliceFlag( m_rectSliceFlag ); pps.setNumSlicesInPicMinus1( m_numSlicesInPicMinus1 ); pps.setTopLeftBrickIdx(m_topLeftBrickIdx); pps.setBottomRightBrickIdx(m_bottomRightBrickIdx); +#if JVET_O0143_BOTTOM_RIGHT_BRICK_IDX_DELTA + if (m_numSlicesInPicMinus1 > 0) + { + std::vector<int> bottomrightdelta(m_numSlicesInPicMinus1 + 1); + for (int i = 0; i < m_numSlicesInPicMinus1 + 1; i++) + { + bottomrightdelta[i] = (i == 0) ? m_bottomRightBrickIdx[i] : m_bottomRightBrickIdx[i] - m_bottomRightBrickIdx[i - 1]; + } + pps.setBottomRightBrickIdxDelta(bottomrightdelta); + } +#endif + pps.setLoopFilterAcrossBricksEnabledFlag( m_loopFilterAcrossBricksEnabledFlag ); pps.setLoopFilterAcrossSlicesEnabledFlag( m_loopFilterAcrossSlicesEnabledFlag ); pps.setSignalledSliceIdFlag( m_signalledSliceIdFlag ); @@ -1915,6 +1934,25 @@ void EncCfg::xCheckGSParameters() uint32_t uiCummulativeColumnWidth = 0; uint32_t uiCummulativeRowHeight = 0; +#if JVET_O0143_BOTTOM_RIGHT_BRICK_IDX_DELTA + if (m_tileUniformSpacingFlag && m_uniformTileColsWidthMinus1 == -1) + { + EXIT("Uniform tiles specified with unspecified or invalid UniformTileColsWidthMinus1 value"); + } + if (m_tileUniformSpacingFlag && m_uniformTileRowHeightMinus1 == -1) + { + EXIT("Uniform tiles specified with unspecified or invalid UniformTileRowHeightMinus1 value"); + } + if (m_tileUniformSpacingFlag && m_uniformTileColsWidthMinus1 >= iWidthInCU) + { + EXIT("UniformTileColsWidthMinus1 too large"); + } + if (m_tileUniformSpacingFlag && m_uniformTileRowHeightMinus1 >= iHeightInCU) + { + EXIT("UniformTileRowHeightMinus1 too large"); + } +#endif + //check the column relative parameters if( m_iNumColumnsMinus1 >= (1<<(LOG2_MAX_NUM_COLUMNS_MINUS1+1)) ) { diff --git a/source/Lib/EncoderLib/VLCWriter.cpp b/source/Lib/EncoderLib/VLCWriter.cpp index 3371ddb7f42a86228059303448e446f8e6dddef8..d8c607de5b6ea0871056190f7205c45b056e9918 100644 --- a/source/Lib/EncoderLib/VLCWriter.cpp +++ b/source/Lib/EncoderLib/VLCWriter.cpp @@ -343,7 +343,17 @@ void HLSWriter::codePPS( const PPS* pcPPS ) } #endif +#if JVET_O0143_BOTTOM_RIGHT_BRICK_IDX_DELTA + int numTilesInPic = (pcPPS->getNumTileColumnsMinus1() + 1) * (pcPPS->getNumTileRowsMinus1() + 1); +#else int numTilesInPic = pcPPS->getUniformTileSpacingFlag() ? 0 : (pcPPS->getNumTileColumnsMinus1() + 1) * (pcPPS->getNumTileRowsMinus1() + 1); +#endif +#if JVET_O0236_PPS_PARSING_DEPENDENCY + if (pcPPS->getUniformTileSpacingFlag() && pcPPS->getBrickSplittingPresentFlag()) + { + WRITE_UVLC(numTilesInPic - 1, "num_tiles_in_pic_minus1"); + } +#endif for( int i = 0; pcPPS->getBrickSplittingPresentFlag() && i < numTilesInPic; i++ ) { @@ -383,17 +393,30 @@ void HLSWriter::codePPS( const PPS* pcPPS ) { WRITE_UVLC( pcPPS->getNumSlicesInPicMinus1(), "num_slices_in_pic_minus1" ); int numSlicesInPic = pcPPS->getNumSlicesInPicMinus1() + 1; +#if !JVET_O0143_BOTTOM_RIGHT_BRICK_IDX_DELTA int numTilesInPic = (pcPPS->getNumTileColumnsMinus1() + 1) * (pcPPS->getNumTileRowsMinus1() + 1); +#endif int codeLength = ceilLog2(numTilesInPic); +#if JVET_O0143_BOTTOM_RIGHT_BRICK_IDX_DELTA + WRITE_UVLC(codeLength, "bottom_right_brick_idx_length_minus1 "); +#else int codeLength2 = codeLength; +#endif for (int i = 0; i < numSlicesInPic; ++i) { +#if JVET_O0143_BOTTOM_RIGHT_BRICK_IDX_DELTA + int delta = (i == 0) ? pcPPS->getBottomRightBrickIdx(i) : pcPPS->getBottomRightBrickIdx(i) - pcPPS->getBottomRightBrickIdx(i - 1); + int sign = (delta > 0) ? 1 : 0; + WRITE_CODE(delta, codeLength, "bottom_right_brick_idx_delta"); + WRITE_FLAG(sign, "brick_idx_delta_sign_flag"); +#else if (i > 0) { WRITE_CODE(pcPPS->getTopLeftBrickIdx(i), codeLength, "top_left_brick_idx "); codeLength2 = ceilLog2((numTilesInPic - pcPPS->getTopLeftBrickIdx(i) < 2) ? 2 : numTilesInPic - pcPPS->getTopLeftBrickIdx(i)); } WRITE_CODE(pcPPS->getBottomRightBrickIdx(i) - pcPPS->getTopLeftBrickIdx(i), codeLength2, "bottom_right_brick_idx_delta"); +#endif } }