diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index 57b25b615ceb8d23b69142881eee6e9f902c9e52..9f4077909042c944f2b4065a5f96f58d83fe0890 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -78,6 +78,8 @@ #define JVET_L0265_AFF_MINIMUM4X4 1 //Affine 4x4 chroma subblock #define JVET_L0111 1 // Max Tx size for skip +#define JVET_L0209_PCM 1 // PCM mode + #define JVET_L0553_FIX_INITQP 1 #define JVET_L0053_L0272_DM 1 // use center position of luma block to derive DM diff --git a/source/Lib/DecoderLib/CABACReader.cpp b/source/Lib/DecoderLib/CABACReader.cpp index 03806e69585b6f61bd05a6842f2d6d0aab178223..d29fa7b34ba292ecc4d635c24303b7cb11c125e3 100644 --- a/source/Lib/DecoderLib/CABACReader.cpp +++ b/source/Lib/DecoderLib/CABACReader.cpp @@ -705,10 +705,25 @@ bool CABACReader::coding_unit( CodingUnit &cu, Partitioner &partitioner, CUCtx& // --> create PUs CU::addPUs( cu ); +#if JVET_L0209_PCM + // pcm samples + if( CU::isIntra(cu) && cu.partSize == SIZE_2Nx2N ) + { + pcm_flag( cu, partitioner ); + if( cu.ipcm ) + { + TransformUnit& tu = cs.addTU( cu, partitioner.chType ); + pcm_samples( tu ); + return end_of_ctu( cu, cuCtx ); + } + } +#endif + #if JVET_L0283_MULTI_REF_LINE extend_ref_line( cu ); #endif +#if !JVET_L0209_PCM // pcm samples if( CU::isIntra(cu) ) { @@ -720,6 +735,7 @@ bool CABACReader::coding_unit( CodingUnit &cu, Partitioner &partitioner, CUCtx& return end_of_ctu( cu, cuCtx ); } } +#endif // prediction data ( intra prediction modes / reference indexes + motion vectors ) cu_pred_data( cu ); @@ -814,11 +830,19 @@ void CABACReader::pred_mode( CodingUnit& cu ) } } - +#if JVET_L0209_PCM +void CABACReader::pcm_flag( CodingUnit& cu, Partitioner &partitioner ) +#else void CABACReader::pcm_flag( CodingUnit& cu ) +#endif { const SPS& sps = *cu.cs->sps; +#if JVET_L0209_PCM + if( !sps.getUsePCM() || partitioner.currArea().lwidth() > (1 << sps.getPCMLog2MaxSize()) || partitioner.currArea().lwidth() < (1 << sps.getPCMLog2MinSize()) + || partitioner.currArea().lheight() > (1 << sps.getPCMLog2MaxSize()) || partitioner.currArea().lheight() < (1 << sps.getPCMLog2MinSize()) ) +#else if( !sps.getUsePCM() || cu.lumaSize().width > (1 << sps.getPCMLog2MaxSize()) || cu.lumaSize().width < (1 << sps.getPCMLog2MinSize()) ) +#endif { cu.ipcm = false; return; @@ -1882,10 +1906,24 @@ void CABACReader::pcm_samples( TransformUnit& tu ) { CHECK( !tu.cu->ipcm, "pcm mode expected" ); +#if JVET_L0209_PCM + const CodingStructure *cs = tu.cs; + const ChannelType chType = tu.chType; +#endif + const SPS& sps = *tu.cu->cs->sps; +#if !JVET_L0209_PCM const ComponentID maxCompId = ( tu.chromaFormat == CHROMA_400 ? COMPONENT_Y : COMPONENT_Cr ); +#endif tu.depth = 0; + +#if JVET_L0209_PCM + ComponentID compStr = (CS::isDualITree(*cs) && !isLuma(chType)) ? COMPONENT_Cb: COMPONENT_Y; + ComponentID compEnd = (CS::isDualITree(*cs) && isLuma(chType)) ? COMPONENT_Y : COMPONENT_Cr; + for( ComponentID compID = compStr; compID <= compEnd; compID = ComponentID(compID+1) ) +#else for( ComponentID compID = COMPONENT_Y; compID <= maxCompId; compID = ComponentID(compID+1) ) +#endif { PelBuf samples = tu.getPcmbuf( compID ); const unsigned sampleBits = sps.getPCMBitDepth( toChannelType(compID) ); diff --git a/source/Lib/DecoderLib/CABACReader.h b/source/Lib/DecoderLib/CABACReader.h index 4332968b2e99f916c91d5d6ab9949fd806c8cec3..58f3802cebf60573851487ed3961f99174d249b0 100644 --- a/source/Lib/DecoderLib/CABACReader.h +++ b/source/Lib/DecoderLib/CABACReader.h @@ -78,7 +78,11 @@ public: void cu_transquant_bypass_flag ( CodingUnit& cu ); void cu_skip_flag ( CodingUnit& cu ); void pred_mode ( CodingUnit& cu ); +#if JVET_L0209_PCM + void pcm_flag ( CodingUnit& cu, Partitioner& pm ); +#else void pcm_flag ( CodingUnit& cu ); +#endif void cu_pred_data ( CodingUnit& cu ); #if JVET_L0646_GBI void cu_gbi_flag ( CodingUnit& cu ); diff --git a/source/Lib/DecoderLib/DecCu.cpp b/source/Lib/DecoderLib/DecCu.cpp index 019da17a898c0510c128091c736a62013728b2cd..c90d2b52b3bfddb465cd6519439af6196d8a905c 100644 --- a/source/Lib/DecoderLib/DecCu.cpp +++ b/source/Lib/DecoderLib/DecCu.cpp @@ -260,9 +260,20 @@ void DecCu::xDecodePCMTexture(TransformUnit &tu, const ComponentID compID) */ void DecCu::xReconPCM(TransformUnit &tu) { +#if JVET_L0209_PCM + const CodingStructure *cs = tu.cs; + const ChannelType chType = tu.chType; + + ComponentID compStr = (CS::isDualITree(*cs) && !isLuma(chType)) ? COMPONENT_Cb: COMPONENT_Y; + ComponentID compEnd = (CS::isDualITree(*cs) && isLuma(chType)) ? COMPONENT_Y : COMPONENT_Cr; + for( ComponentID compID = compStr; compID <= compEnd; compID = ComponentID(compID+1) ) +#else for (uint32_t ch = 0; ch < tu.blocks.size(); ch++) +#endif { +#if !JVET_L0209_PCM ComponentID compID = ComponentID(ch); +#endif xDecodePCMTexture(tu, compID); } diff --git a/source/Lib/EncoderLib/CABACWriter.cpp b/source/Lib/EncoderLib/CABACWriter.cpp index 18b823c7247d1c96c3121bffed668175fba488b1..fbe47cdfed25dfc44255d76c1046e885818ea759 100644 --- a/source/Lib/EncoderLib/CABACWriter.cpp +++ b/source/Lib/EncoderLib/CABACWriter.cpp @@ -629,6 +629,19 @@ void CABACWriter::coding_unit( const CodingUnit& cu, Partitioner& partitioner, C return; } +#if JVET_L0209_PCM + // pcm samples + if( CU::isIntra(cu) && cu.partSize == SIZE_2Nx2N ) + { + pcm_data( cu, partitioner ); + if( cu.ipcm ) + { + end_of_ctu( cu, cuCtx ); + return; + } + } +#endif + // prediction mode and partitioning data pred_mode ( cu ); @@ -636,6 +649,7 @@ void CABACWriter::coding_unit( const CodingUnit& cu, Partitioner& partitioner, C extend_ref_line(cu); #endif +#if !JVET_L0209_PCM // pcm samples if( CU::isIntra(cu) ) { @@ -646,6 +660,7 @@ void CABACWriter::coding_unit( const CodingUnit& cu, Partitioner& partitioner, C return; } } +#endif // prediction data ( intra prediction modes / reference indexes + motion vectors ) cu_pred_data( cu ); @@ -689,9 +704,17 @@ void CABACWriter::pred_mode( const CodingUnit& cu ) m_BinEncoder.encodeBin( ( CU::isIntra( cu ) ), Ctx::PredMode() ); } +#if JVET_L0209_PCM +void CABACWriter::pcm_data( const CodingUnit& cu, Partitioner& partitioner ) +#else void CABACWriter::pcm_data( const CodingUnit& cu ) +#endif { +#if JVET_L0209_PCM + pcm_flag( cu, partitioner ); +#else pcm_flag( cu ); +#endif if( cu.ipcm ) { m_BinEncoder.pcmAlignBits(); @@ -699,11 +722,19 @@ void CABACWriter::pcm_data( const CodingUnit& cu ) } } - +#if JVET_L0209_PCM +void CABACWriter::pcm_flag( const CodingUnit& cu, Partitioner& partitioner ) +#else void CABACWriter::pcm_flag( const CodingUnit& cu ) +#endif { const SPS& sps = *cu.cs->sps; + #if JVET_L0209_PCM + if( !sps.getUsePCM() || partitioner.currArea().lwidth() > (1 << sps.getPCMLog2MaxSize()) || partitioner.currArea().lwidth() < (1 << sps.getPCMLog2MinSize()) + || partitioner.currArea().lheight() > (1 << sps.getPCMLog2MaxSize()) || partitioner.currArea().lheight() < (1 << sps.getPCMLog2MinSize()) ) +#else if( !sps.getUsePCM() || cu.lumaSize().width > (1 << sps.getPCMLog2MaxSize()) || cu.lumaSize().width < (1 << sps.getPCMLog2MinSize()) ) +#endif { return; } @@ -1833,8 +1864,18 @@ void CABACWriter::pcm_samples( const TransformUnit& tu ) CHECK( !tu.cu->ipcm, "pcm mode expected" ); const SPS& sps = *tu.cu->cs->sps; + +#if JVET_L0209_PCM + const CodingStructure *cs = tu.cs; + const ChannelType chType = tu.chType; + + ComponentID compStr = (CS::isDualITree(*cs) && !isLuma(chType)) ? COMPONENT_Cb: COMPONENT_Y; + ComponentID compEnd = (CS::isDualITree(*cs) && isLuma(chType)) ? COMPONENT_Y : COMPONENT_Cr; + for( ComponentID compID = compStr; compID <= compEnd; compID = ComponentID(compID+1) ) +#else const ComponentID maxCompId = ( tu.chromaFormat == CHROMA_400 ? COMPONENT_Y : COMPONENT_Cr ); for( ComponentID compID = COMPONENT_Y; compID <= maxCompId; compID = ComponentID(compID+1) ) +#endif { const CPelBuf samples = tu.getPcmbuf( compID ); const unsigned sampleBits = sps.getPCMBitDepth( toChannelType(compID) ); diff --git a/source/Lib/EncoderLib/CABACWriter.h b/source/Lib/EncoderLib/CABACWriter.h index addb673f2877e74e707290805c2b717220d3fda2..58297747435e287a5a21cfa2f234920df392a308 100644 --- a/source/Lib/EncoderLib/CABACWriter.h +++ b/source/Lib/EncoderLib/CABACWriter.h @@ -90,8 +90,13 @@ public: void cu_transquant_bypass_flag ( const CodingUnit& cu ); void cu_skip_flag ( const CodingUnit& cu ); void pred_mode ( const CodingUnit& cu ); +#if JVET_L0209_PCM + void pcm_data ( const CodingUnit& cu, Partitioner& pm ); + void pcm_flag ( const CodingUnit& cu, Partitioner& pm ); +#else void pcm_data ( const CodingUnit& cu ); void pcm_flag ( const CodingUnit& cu ); +#endif void cu_pred_data ( const CodingUnit& cu ); #if JVET_L0646_GBI void cu_gbi_flag ( const CodingUnit& cu ); diff --git a/source/Lib/EncoderLib/EncCu.cpp b/source/Lib/EncoderLib/EncCu.cpp index 88733b4a5295e9c2dc21c3eb49cbe83fda651cc5..e7fc099713941cfd145e80c9c4d010a97e70b73e 100644 --- a/source/Lib/EncoderLib/EncCu.cpp +++ b/source/Lib/EncoderLib/EncCu.cpp @@ -1453,8 +1453,11 @@ void EncCu::xCheckRDCostIntra( CodingStructure *&tempCS, CodingStructure *&bestC m_CABACEstimator->extend_ref_line( cu ); #endif m_CABACEstimator->cu_pred_data ( cu ); +#if JVET_L0209_PCM + m_CABACEstimator->pcm_data ( cu, partitioner ); +#else m_CABACEstimator->pcm_data ( cu ); - +#endif // Encode Coefficients CUCtx cuCtx; @@ -1500,7 +1503,11 @@ void EncCu::xCheckIntraPCM(CodingStructure *&tempCS, CodingStructure *&bestCS, P { tempCS->initStructData( encTestMode.qp, encTestMode.lossless ); +#if JVET_L0209_PCM + CodingUnit &cu = tempCS->addCU( CS::getArea( *tempCS, tempCS->area, partitioner.chType ), partitioner.chType ); +#else CodingUnit &cu = tempCS->addCU( tempCS->area, partitioner.chType ); +#endif partitioner.setCUData( cu ); cu.slice = tempCS->slice; @@ -1517,9 +1524,15 @@ void EncCu::xCheckIntraPCM(CodingStructure *&tempCS, CodingStructure *&bestCS, P cu.qp = encTestMode.qp; cu.ipcm = true; +#if JVET_L0209_PCM + tempCS->addPU( CS::getArea( *tempCS, tempCS->area, partitioner.chType ), partitioner.chType ); + + tempCS->addTU( CS::getArea( *tempCS, tempCS->area, partitioner.chType ), partitioner.chType ); +#else tempCS->addPU(tempCS->area, partitioner.chType); tempCS->addTU( tempCS->area, partitioner.chType ); +#endif m_pcIntraSearch->IPCMSearch(*tempCS, partitioner); @@ -1541,7 +1554,11 @@ void EncCu::xCheckIntraPCM(CodingStructure *&tempCS, CodingStructure *&bestCS, P m_CABACEstimator->cu_skip_flag ( cu ); } m_CABACEstimator->pred_mode ( cu ); +#if JVET_L0209_PCM + m_CABACEstimator->pcm_data ( cu, partitioner ); +#else m_CABACEstimator->pcm_data ( cu ); +#endif tempCS->fracBits = m_CABACEstimator->getEstFracBits(); diff --git a/source/Lib/EncoderLib/IntraSearch.cpp b/source/Lib/EncoderLib/IntraSearch.cpp index b33510910c9fa9e8203ac9f0e2433aba25c0e4ee..e8d76cfb09fe6c18b135eb85820b9db144fa085c 100644 --- a/source/Lib/EncoderLib/IntraSearch.cpp +++ b/source/Lib/EncoderLib/IntraSearch.cpp @@ -1000,9 +1000,17 @@ void IntraSearch::estIntraPredChromaQT(CodingUnit &cu, Partitioner &partitioner) void IntraSearch::IPCMSearch(CodingStructure &cs, Partitioner& partitioner) { +#if JVET_L0209_PCM + ComponentID compStr = (CS::isDualITree(cs) && !isLuma(partitioner.chType)) ? COMPONENT_Cb: COMPONENT_Y; + ComponentID compEnd = (CS::isDualITree(cs) && isLuma(partitioner.chType)) ? COMPONENT_Y : COMPONENT_Cr; + for( ComponentID compID = compStr; compID <= compEnd; compID = ComponentID(compID+1) ) +#else for (uint32_t ch = 0; ch < getNumberValidTBlocks( *cs.pcv ); ch++) +#endif { +#if !JVET_L0209_PCM const ComponentID compID = ComponentID(ch); +#endif xEncPCM(cs, partitioner, compID); } @@ -1016,7 +1024,9 @@ void IntraSearch::IPCMSearch(CodingStructure &cs, Partitioner& partitioner) cs.cost = 0; cs.setDecomp(cs.area); +#if !JVET_L0209_PCM cs.picture->getRecoBuf(cs.area).copyFrom(cs.getRecoBuf()); +#endif } void IntraSearch::xEncPCM(CodingStructure &cs, Partitioner& partitioner, const ComponentID &compID) @@ -1080,7 +1090,11 @@ void IntraSearch::xEncIntraHeader(CodingStructure &cs, Partitioner &partitioner, #endif if( CU::isIntra(cu) ) { +#if JVET_L0209_PCM + m_CABACEstimator->pcm_data( cu, partitioner ); +#else m_CABACEstimator->pcm_data( cu ); +#endif if( cu.ipcm ) { return;