diff --git a/source/App/EncoderApp/EncApp.cpp b/source/App/EncoderApp/EncApp.cpp index 49bdad2c4452833e4cdb41a90687df8355493f26..ad40955451cad60555deb02d34d6bc26e59b6de8 100644 --- a/source/App/EncoderApp/EncApp.cpp +++ b/source/App/EncoderApp/EncApp.cpp @@ -388,6 +388,32 @@ void EncApp::xInitLibCfg() #endif m_cEncLib.setRDpenalty ( m_rdPenalty ); m_cEncLib.setCTUSize ( m_uiCTUSize ); +#if JVET_P0171_SUBPICTURE_LAYOUT + m_cEncLib.setSubPicPresentFlag ( m_subPicPresentFlag ); + if(m_subPicPresentFlag){ + m_cEncLib.setNumSubPics ( m_numSubPics ); + for (int i = 0; i < m_numSubPics; i++) + { + m_cEncLib.setSubPicCtuTopLeftX ( m_subPicCtuTopLeftX[i], i ); + m_cEncLib.setSubPicCtuTopLeftY ( m_subPicCtuTopLeftY[i], i ); + m_cEncLib.setSubPicWidth ( m_subPicWidth[i], i ); + m_cEncLib.setSubPicHeight ( m_subPicHeight[i], i ); + m_cEncLib.setSubPicTreatedAsPicFlag ( m_subPicTreatedAsPicFlag[i], i ); + m_cEncLib.setLoopFilterAcrossSubpicEnabledFlag ( m_loopFilterAcrossSubpicEnabledFlag[i], i ); + } + } + m_cEncLib.setSubPicIdPresentFlag ( m_subPicIdPresentFlag ); + if (m_subPicIdPresentFlag) { + m_cEncLib.setSubPicIdSignallingPresentFlag ( m_subPicIdSignallingPresentFlag ); + if(m_subPicIdSignallingPresentFlag){ + m_cEncLib.setSubPicIdLen ( m_subPicIdLen ); + for (int i = 0; i < m_numSubPics; i++) + { + m_cEncLib.setSubPicId ( m_subPicId[i], i ); + } + } + } +#endif m_cEncLib.setUseSplitConsOverride ( m_SplitConsOverrideEnabledFlag ); m_cEncLib.setMinQTSizes ( m_uiMinQT ); m_cEncLib.setMaxMTTHierarchyDepth ( m_uiMaxMTTHierarchyDepth, m_uiMaxMTTHierarchyDepthI, m_uiMaxMTTHierarchyDepthIChroma ); diff --git a/source/App/EncoderApp/EncAppCfg.cpp b/source/App/EncoderApp/EncAppCfg.cpp index 3c90bde664c6c0580953828033fdf571063a7ead..4d5fad73751798026a0fcbc04e07e1eb1a43e9bc 100644 --- a/source/App/EncoderApp/EncAppCfg.cpp +++ b/source/App/EncoderApp/EncAppCfg.cpp @@ -923,7 +923,15 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) SMultiValueInput<unsigned> cfg_virtualBoundariesPosY (0, std::numeric_limits<uint32_t>::max(), 0, 3); SMultiValueInput<uint8_t> cfg_SubProfile(0, std::numeric_limits<uint8_t>::max(), 0, std::numeric_limits<uint8_t>::max()); - +#if JVET_P0171_SUBPICTURE_LAYOUT + SMultiValueInput<uint32_t> cfg_subPicCtuTopLeftX(0, std::numeric_limits<uint32_t>::max(), 0, MAX_NUM_SUB_PICS); + SMultiValueInput<uint32_t> cfg_subPicCtuTopLeftY(0, std::numeric_limits<uint32_t>::max(), 0, MAX_NUM_SUB_PICS); + SMultiValueInput<uint32_t> cfg_subPicWidth(1, std::numeric_limits<uint32_t>::max(), 0, MAX_NUM_SUB_PICS); + SMultiValueInput<uint32_t> cfg_subPicHeight(1, std::numeric_limits<uint32_t>::max(), 0, MAX_NUM_SUB_PICS); + SMultiValueInput<uint32_t> cfg_subPicTreatedAsPicFlag(0, 1, 0, MAX_NUM_SUB_PICS); + SMultiValueInput<uint32_t> cfg_loopFilterAcrossSubpicEnabledFlag(0, 1, 0, MAX_NUM_SUB_PICS); + SMultiValueInput<uint32_t> cfg_subPicId(0, std::numeric_limits<uint32_t>::max(), 0, MAX_NUM_SUB_PICS); +#endif int warnUnknowParameter = 0; #if ENABLE_TRACING @@ -1044,6 +1052,20 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) ("NonPackedSource", m_nonPackedConstraintFlag, false, "Indicate that source does not contain frame packing") ("FrameOnly", m_frameOnlyConstraintFlag, false, "Indicate that the bitstream contains only frames") ("CTUSize", m_uiCTUSize, 128u, "CTUSize (specifies the CTU size if QTBT is on) [default: 128]") +#if JVET_P0171_SUBPICTURE_LAYOUT + ("SubPicPresentFlag", m_subPicPresentFlag, false, "equal to 1 specifies that subpicture parameters are present in in the SPS RBSP syntax") + ("NumSubPics", m_numSubPics, 0u, "specifies the number of subpictures") + ("SubPicCtuTopLeftX", cfg_subPicCtuTopLeftX, cfg_subPicCtuTopLeftX, "specifies horizontal position of top left CTU of i-th subpicture in unit of CtbSizeY") + ("SubPicCtuTopLeftY", cfg_subPicCtuTopLeftY, cfg_subPicCtuTopLeftY, "specifies vertical position of top left CTU of i-th subpicture in unit of CtbSizeY") + ("SubPicWidth", cfg_subPicWidth, cfg_subPicWidth, "specifies the width of the i-th subpicture in units of CtbSizeY") + ("SubPicHeight", cfg_subPicHeight, cfg_subPicHeight, "specifies the height of the i-th subpicture in units of CtbSizeY") + ("SubPicTreatedAsPicFlag", cfg_subPicTreatedAsPicFlag, cfg_subPicTreatedAsPicFlag, "equal to 1 specifies that the i-th subpicture of each coded picture in the CLVS is treated as a picture in the decoding process excluding in-loop filtering operations") + ("LoopFilterAcrossSubpicEnabledFlag", cfg_loopFilterAcrossSubpicEnabledFlag, cfg_loopFilterAcrossSubpicEnabledFlag, "equal to 1 specifies that in-loop filtering operations may be performed across the boundaries of the i-th subpicture in each coded picture in the CLVS") + ("SubPicIdPresentFlag", m_subPicIdPresentFlag, false, "equal to 1 specifies that subpicture ID mapping is present in the SPS") + ("SubPicIdSignallingPresentFlag", m_subPicIdSignallingPresentFlag, false, "equal to 1 specifies that subpicture ID mapping is signalled in the SPS") + ("SubPicIdLen", m_subPicIdLen, 0u, "specifies the number of bits used to represent the syntax element sps_subpic_id[ i ]. ") + ("SubPicId", cfg_subPicId, cfg_subPicId, "specifies that subpicture ID of the i-th subpicture") +#endif ("EnablePartitionConstraintsOverride", m_SplitConsOverrideEnabledFlag, true, "Enable partition constraints override") ("MinQTISlice", m_uiMinQT[0], 8u, "MinQTISlice") ("MinQTLumaISlice", m_uiMinQT[0], 8u, "MinQTLumaISlice") @@ -1894,7 +1916,28 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) //number of fields to encode m_framesToBeEncoded *= 2; } - +#if JVET_P0171_SUBPICTURE_LAYOUT + if ( m_subPicPresentFlag ) + { + CHECK( m_numSubPics > 255 || m_numSubPics < 1, "Number of subpicture must be within 1 to 255" ); + m_subPicCtuTopLeftX = cfg_subPicCtuTopLeftX.values; + m_subPicCtuTopLeftY = cfg_subPicCtuTopLeftY.values; + m_subPicWidth = cfg_subPicWidth.values; + m_subPicHeight = cfg_subPicHeight.values; + m_subPicTreatedAsPicFlag = cfg_subPicTreatedAsPicFlag.values; + m_loopFilterAcrossSubpicEnabledFlag = cfg_loopFilterAcrossSubpicEnabledFlag.values; + m_subPicId = cfg_subPicId.values; + for(int i = 0; i < m_numSubPics; i++){ + CHECK(m_subPicCtuTopLeftX[i] + m_subPicWidth[i] > (m_iSourceWidth + m_uiCTUSize - 1) / m_uiCTUSize, "subpicture must not exceed picture boundary"); + CHECK(m_subPicCtuTopLeftY[i] + m_subPicHeight[i] > (m_iSourceHeight + m_uiCTUSize - 1) / m_uiCTUSize, "subpicture must not exceed picture boundary"); + } + if (m_subPicIdPresentFlag) { + if (m_subPicIdSignallingPresentFlag) { + CHECK( m_subPicIdLen > 16, "sibpic ID length must not exceed 16 bits" ); + } + } + } +#endif #if JVET_P1004_REMOVE_BRICKS if( m_picPartitionFlag ) { @@ -4329,6 +4372,28 @@ void EncAppCfg::xPrintParameter() msg( DETAILS, "Profile : %s\n", profileToString(m_profile) ); } msg( DETAILS, "CU size / depth / total-depth : %d / %d / %d\n", m_uiMaxCUWidth, m_uiMaxCUDepth, m_uiMaxCodingDepth ); +#if JVET_P0171_SUBPICTURE_LAYOUT + msg(DETAILS, "subpicture present flag : %d\n", m_subPicPresentFlag); + if (m_subPicPresentFlag) { + msg(DETAILS, "number of subpictures : %d\n", m_numSubPics); + for (int i = 0; i < m_numSubPics; i++) { + msg(DETAILS, "[%d]th subpictures location :[%d %d]\n", i, m_subPicCtuTopLeftX[i], m_subPicCtuTopLeftY[i]); + msg(DETAILS, "[%d]th subpictures size :[%d %d]\n", i, m_subPicWidth[i], m_subPicHeight[i]); + msg(DETAILS, "[%d]th subpictures treated as picture flag :%d\n", i, m_subPicTreatedAsPicFlag); + msg(DETAILS, "loop filter cross [%d]th subpictures enabled flag :%d\n", i, m_loopFilterAcrossSubpicEnabledFlag); + + } + } + msg(DETAILS, "subpicture ID present flag : %d\n", m_subPicIdPresentFlag); + if (m_subPicIdPresentFlag) { + msg(DETAILS, "subpicture ID signalling present flag : %d\n", m_subPicIdSignallingPresentFlag); + for (int i = 0; i < m_numSubPics; i++) { + msg(DETAILS, "[%d]th subpictures ID length :%d\n", i, m_subPicIdLen); + msg(DETAILS, "[%d]th subpictures ID :%d\n", i, m_subPicId); + + } + } +#endif msg( DETAILS, "Max TB size : %d \n", 1 << m_log2MaxTbSize ); msg( DETAILS, "Motion search range : %d\n", m_iSearchRange ); msg( DETAILS, "Intra period : %d\n", m_iIntraPeriod ); diff --git a/source/App/EncoderApp/EncAppCfg.h b/source/App/EncoderApp/EncAppCfg.h index 132fcb6640e7c4caeddcba5a31c5f42892aeb3e9..8f227d1d99144dc5d1198b6f28ddc12c5c23233f 100644 --- a/source/App/EncoderApp/EncAppCfg.h +++ b/source/App/EncoderApp/EncAppCfg.h @@ -276,6 +276,20 @@ protected: // coding unit (CU) definition unsigned m_uiCTUSize; +#if JVET_P0171_SUBPICTURE_LAYOUT + bool m_subPicPresentFlag; + unsigned m_numSubPics; + std::vector<uint32_t> m_subPicCtuTopLeftX; + std::vector<uint32_t> m_subPicCtuTopLeftY; + std::vector<uint32_t> m_subPicWidth; + std::vector<uint32_t> m_subPicHeight; + std::vector<uint32_t> m_subPicTreatedAsPicFlag; + std::vector<uint32_t> m_loopFilterAcrossSubpicEnabledFlag; + bool m_subPicIdPresentFlag; + bool m_subPicIdSignallingPresentFlag; + unsigned m_subPicIdLen; + std::vector<uint32_t> m_subPicId; +#endif bool m_SplitConsOverrideEnabledFlag; unsigned m_uiMinQT[3]; // 0: I slice luma; 1: P/B slice; 2: I slice chroma unsigned m_uiMaxMTTHierarchyDepth; diff --git a/source/Lib/DecoderLib/VLCReader.cpp b/source/Lib/DecoderLib/VLCReader.cpp index 237656a419f4d09f15cdd4e18fb036b083ad0e62..28ee3fb204511db918bca3d11d7c8cfb5bb97a22 100644 --- a/source/Lib/DecoderLib/VLCReader.cpp +++ b/source/Lib/DecoderLib/VLCReader.cpp @@ -1528,13 +1528,13 @@ void HLSyntaxReader::parseSPS(SPS* pcSPS) READ_CODE(8, uiCode, "sps_num_subpics_minus1"); pcSPS->setNumSubPics(uiCode + 1); for (int picIdx = 0; picIdx < pcSPS->getNumSubPics(); picIdx++) { - READ_CODE(ceilLog2(((pcSPS->getMaxPicWidthInLumaSamples() + pcSPS->getCTUSize() - 1) >> floorLog2(pcSPS->getCTUSize()))), uiCode, "subpic_ctu_top_left_x[ i ]"); + READ_CODE(std::max(1, ceilLog2(((pcSPS->getMaxPicWidthInLumaSamples() + pcSPS->getCTUSize() - 1) >> floorLog2(pcSPS->getCTUSize())))), uiCode, "subpic_ctu_top_left_x[ i ]"); pcSPS->setSubPicCtuTopLeftX(picIdx, uiCode); - READ_CODE(ceilLog2(((pcSPS->getMaxPicHeightInLumaSamples() + pcSPS->getCTUSize() - 1) >> floorLog2(pcSPS->getCTUSize()))), uiCode, "subpic_ctu_top_left_y[ i ]"); + READ_CODE(std::max(1, ceilLog2(((pcSPS->getMaxPicHeightInLumaSamples() + pcSPS->getCTUSize() - 1) >> floorLog2(pcSPS->getCTUSize())))), uiCode, "subpic_ctu_top_left_y[ i ]"); pcSPS->setSubPicCtuTopLeftY(picIdx, uiCode); - READ_CODE(ceilLog2(((pcSPS->getMaxPicWidthInLumaSamples() + pcSPS->getCTUSize() - 1) >> floorLog2(pcSPS->getCTUSize()))), uiCode, "subpic_width_minus1[ i ]"); + READ_CODE(std::max(1, ceilLog2(((pcSPS->getMaxPicWidthInLumaSamples() + pcSPS->getCTUSize() - 1) >> floorLog2(pcSPS->getCTUSize())))), uiCode, "subpic_width_minus1[ i ]"); pcSPS->setSubPicWidth(picIdx, uiCode + 1); - READ_CODE(ceilLog2(((pcSPS->getMaxPicHeightInLumaSamples() + pcSPS->getCTUSize() - 1) >> floorLog2(pcSPS->getCTUSize()))), uiCode, "subpic_height_minus1[ i ]"); + READ_CODE(std::max(1, ceilLog2(((pcSPS->getMaxPicHeightInLumaSamples() + pcSPS->getCTUSize() - 1) >> floorLog2(pcSPS->getCTUSize())))), uiCode, "subpic_height_minus1[ i ]"); pcSPS->setSubPicHeight(picIdx, uiCode + 1); READ_FLAG(uiCode, "subpic_treated_as_pic_flag[ i ]"); pcSPS->setSubPicTreatedAsPicFlag(picIdx, uiCode); diff --git a/source/Lib/EncoderLib/EncCfg.h b/source/Lib/EncoderLib/EncCfg.h index a73aabaad7e1a706bac77846dde4c536466df621..1fddc05e28a9b8538989f06706ebc786eee21a79 100644 --- a/source/Lib/EncoderLib/EncCfg.h +++ b/source/Lib/EncoderLib/EncCfg.h @@ -273,6 +273,20 @@ protected: int m_maxTempLayer; ///< Max temporal layer unsigned m_CTUSize; +#if JVET_P0171_SUBPICTURE_LAYOUT + bool m_subPicPresentFlag; + unsigned m_numSubPics; + uint32_t m_subPicCtuTopLeftX[MAX_NUM_SUB_PICS]; + uint32_t m_subPicCtuTopLeftY[MAX_NUM_SUB_PICS]; + uint32_t m_subPicWidth[MAX_NUM_SUB_PICS]; + uint32_t m_subPicHeight[MAX_NUM_SUB_PICS]; + uint32_t m_subPicTreatedAsPicFlag[MAX_NUM_SUB_PICS]; + uint32_t m_loopFilterAcrossSubpicEnabledFlag[MAX_NUM_SUB_PICS]; + bool m_subPicIdPresentFlag; + bool m_subPicIdSignallingPresentFlag; + unsigned m_subPicIdLen; + uint32_t m_subPicId[MAX_NUM_SUB_PICS]; +#endif bool m_useSplitConsOverride; unsigned m_uiMinQT[3]; //0: I slice; 1: P/B slice, 2: I slice chroma unsigned m_uiMaxMTTHierarchyDepth; @@ -1040,7 +1054,33 @@ public: bool getUseSplitConsOverride () const { return m_useSplitConsOverride; } void setDualITree ( bool b ) { m_dualITree = b; } bool getDualITree () const { return m_dualITree; } - +#if JVET_P0171_SUBPICTURE_LAYOUT + void setSubPicPresentFlag (bool b) { m_subPicPresentFlag = b; } + void setNumSubPics (uint32_t u) { m_numSubPics = u; } + void setSubPicCtuTopLeftX (uint32_t u, int i) { m_subPicCtuTopLeftX[i] = u; } + void setSubPicCtuTopLeftY (uint32_t u, int i) { m_subPicCtuTopLeftY[i] = u; } + void setSubPicWidth (uint32_t u, int i) { m_subPicWidth[i] = u; } + void setSubPicHeight (uint32_t u, int i) { m_subPicHeight[i] = u; } + void setSubPicTreatedAsPicFlag (bool b, int i) { m_subPicTreatedAsPicFlag[i] = b; } + void setLoopFilterAcrossSubpicEnabledFlag (uint32_t u, int i) { m_loopFilterAcrossSubpicEnabledFlag[i] = u; } + void setSubPicIdPresentFlag (bool b) { m_subPicIdPresentFlag = b; } + void setSubPicIdSignallingPresentFlag (bool b) { m_subPicIdSignallingPresentFlag = b; } + void setSubPicIdLen (uint32_t u) { m_subPicIdLen = u; } + void setSubPicId (uint32_t b, int i) { m_subPicId[i] = b; } + + bool getSubPicPresentFlag () { return m_subPicPresentFlag; } + uint32_t getNumSubPics () { return m_numSubPics; } + uint32_t getSubPicCtuTopLeftX (int i) { return m_subPicCtuTopLeftX[i]; } + uint32_t getSubPicCtuTopLeftY (int i) { return m_subPicCtuTopLeftY[i]; } + uint32_t getSubPicWidth (int i) { return m_subPicWidth[i]; } + uint32_t getSubPicHeight (int i) { return m_subPicHeight[i]; } + bool getSubPicTreatedAsPicFlag (int i) { return m_subPicTreatedAsPicFlag[i]; } + uint32_t getLoopFilterAcrossSubpicEnabledFlag (int i) { return m_loopFilterAcrossSubpicEnabledFlag[i]; } + bool getSubPicIdPresentFlag () { return m_subPicIdPresentFlag; } + bool getSubPicIdSignallingPresentFlag () { return m_subPicIdSignallingPresentFlag; } + uint32_t getSubPicIdLen () { return m_subPicIdLen; } + uint32_t getSubPicId (int i) { return m_subPicId[i]; } +#endif void setLFNST ( bool b ) { m_LFNST = b; } bool getLFNST() const { return m_LFNST; } void setUseFastLFNST ( bool b ) { m_useFastLFNST = b; } diff --git a/source/Lib/EncoderLib/EncLib.cpp b/source/Lib/EncoderLib/EncLib.cpp index 53c734c219f9122192aea730515251e92bcffd54..eb203b40cce89649c7bc81f49a8584f01fd1841b 100644 --- a/source/Lib/EncoderLib/EncLib.cpp +++ b/source/Lib/EncoderLib/EncLib.cpp @@ -1686,20 +1686,29 @@ void EncLib::xInitSPS(SPS &sps) #if JVET_P1006_PICTURE_HEADER #if JVET_P0171_SUBPICTURE_LAYOUT - for (int picIdx = 0; picIdx < MAX_NUM_SUB_PICS; picIdx++) { - sps.setSubPicCtuTopLeftX(picIdx, 0); - sps.setSubPicCtuTopLeftY(picIdx, 0); - sps.setSubPicWidth(picIdx, ((sps.getMaxPicWidthInLumaSamples() + sps.getCTUSize() - 1) >> floorLog2(sps.getCTUSize()))); - sps.setSubPicHeight(picIdx, ((sps.getMaxPicHeightInLumaSamples() + sps.getCTUSize() - 1) >> floorLog2(sps.getCTUSize()))); - sps.setSubPicTreatedAsPicFlag(picIdx, 0); - sps.setLoopFilterAcrossSubpicEnabledFlag(picIdx, 1); - } -#endif - sps.setSubPicIdSignallingPresentFlag(false); - sps.setSubPicIdLen(16); - for(int picIdx=0; picIdx<MAX_NUM_SUB_PICS; picIdx++) - { - sps.setSubPicId(picIdx, picIdx); + sps.setSubPicPresentFlag(m_subPicPresentFlag); + if (m_subPicPresentFlag) { + sps.setNumSubPics(m_numSubPics); + for (int i = 0; i < m_numSubPics; i++) { + sps.setSubPicCtuTopLeftX(i, m_subPicCtuTopLeftX[i] ); + sps.setSubPicCtuTopLeftY(i, m_subPicCtuTopLeftY[i]); + sps.setSubPicWidth(i, m_subPicWidth[i]); + sps.setSubPicHeight(i, m_subPicHeight[i]); + sps.setSubPicTreatedAsPicFlag(i, m_subPicTreatedAsPicFlag[i]); + sps.setLoopFilterAcrossSubpicEnabledFlag(i, m_loopFilterAcrossSubpicEnabledFlag[i]); + } + } +#endif + sps.setSubPicIdPresentFlag(m_subPicIdPresentFlag); + if (m_subPicIdPresentFlag) { + sps.setSubPicIdSignallingPresentFlag(m_subPicIdSignallingPresentFlag); + if (m_subPicIdSignallingPresentFlag){ + sps.setSubPicIdLen(m_subPicIdLen); + for (int i = 0; i < m_numSubPics; i++) + { + sps.setSubPicId(i, m_subPicId[i]); + } + } } sps.setLoopFilterAcrossVirtualBoundariesDisabledFlag( m_loopFilterAcrossVirtualBoundariesDisabledFlag ); diff --git a/source/Lib/EncoderLib/VLCWriter.cpp b/source/Lib/EncoderLib/VLCWriter.cpp index 128572dec6bba59dbb1350506ce15c50eff55640..93b1e95af4f70425a78ebb45af01e06036b12077 100644 --- a/source/Lib/EncoderLib/VLCWriter.cpp +++ b/source/Lib/EncoderLib/VLCWriter.cpp @@ -969,10 +969,10 @@ void HLSWriter::codeSPS( const SPS* pcSPS ) WRITE_CODE(pcSPS->getNumSubPics() - 1, 8, "sps_num_subpics_minus1"); for (int picIdx = 0; picIdx < pcSPS->getNumSubPics(); picIdx++) { - WRITE_CODE( pcSPS->getSubPicCtuTopLeftX(picIdx), ceilLog2((( pcSPS->getMaxPicWidthInLumaSamples() + pcSPS->getCTUSize() - 1) >> floorLog2( pcSPS->getCTUSize()))), "subpic_ctu_top_left_x[ i ]" ); - WRITE_CODE( pcSPS->getSubPicCtuTopLeftY(picIdx), ceilLog2((( pcSPS->getMaxPicHeightInLumaSamples() + pcSPS->getCTUSize() - 1) >> floorLog2( pcSPS->getCTUSize()))), "subpic_ctu_top_left_y[ i ]" ); - WRITE_CODE( pcSPS->getSubPicWidth(picIdx) - 1, ceilLog2((( pcSPS->getMaxPicWidthInLumaSamples() + pcSPS->getCTUSize() - 1) >> floorLog2( pcSPS->getCTUSize()))), "subpic_width_minus1[ i ]" ); - WRITE_CODE( pcSPS->getSubPicHeight(picIdx) - 1, ceilLog2((( pcSPS->getMaxPicHeightInLumaSamples() + pcSPS->getCTUSize() - 1) >> floorLog2( pcSPS->getCTUSize()))), "subpic_height_minus1[ i ]" ); + WRITE_CODE( pcSPS->getSubPicCtuTopLeftX(picIdx), std::max(1, ceilLog2((( pcSPS->getMaxPicWidthInLumaSamples() + pcSPS->getCTUSize() - 1) >> floorLog2( pcSPS->getCTUSize())))), "subpic_ctu_top_left_x[ i ]" ); + WRITE_CODE( pcSPS->getSubPicCtuTopLeftY(picIdx), std::max(1, ceilLog2((( pcSPS->getMaxPicHeightInLumaSamples() + pcSPS->getCTUSize() - 1) >> floorLog2( pcSPS->getCTUSize())))), "subpic_ctu_top_left_y[ i ]" ); + WRITE_CODE( pcSPS->getSubPicWidth(picIdx) - 1, std::max(1, ceilLog2((( pcSPS->getMaxPicWidthInLumaSamples() + pcSPS->getCTUSize() - 1) >> floorLog2( pcSPS->getCTUSize())))), "subpic_width_minus1[ i ]" ); + WRITE_CODE( pcSPS->getSubPicHeight(picIdx) - 1, std::max(1, ceilLog2((( pcSPS->getMaxPicHeightInLumaSamples() + pcSPS->getCTUSize() - 1) >> floorLog2( pcSPS->getCTUSize())))), "subpic_height_minus1[ i ]" ); WRITE_FLAG( pcSPS->getSubPicTreatedAsPicFlag(picIdx), "subpic_treated_as_pic_flag[ i ]" ); WRITE_FLAG( pcSPS->getLoopFilterAcrossSubpicEnabledFlag(picIdx), "loop_filter_across_subpic_enabled_flag[ i ]" ); }