func (this *TDecEntropy) DecodeCoeff(pcCU *TLibCommon.TComDataCU, uiAbsPartIdx, uiDepth, uiWidth, uiHeight uint, bCodeDQP *bool) { uiMinCoeffSize := pcCU.GetPic().GetMinCUWidth() * pcCU.GetPic().GetMinCUHeight() uiLumaOffset := uiMinCoeffSize * uiAbsPartIdx uiChromaOffset := uiLumaOffset >> 2 if !pcCU.IsIntra(uiAbsPartIdx) { uiQtRootCbf := uint(1) if !(pcCU.GetPartitionSize1(uiAbsPartIdx) == TLibCommon.SIZE_2Nx2N && pcCU.GetMergeFlag1(uiAbsPartIdx)) { this.m_pcEntropyDecoderIf.ParseQtRootCbf(uiAbsPartIdx, &uiQtRootCbf) } if uiQtRootCbf == 0 { pcCU.SetCbfSubParts(0, 0, 0, uiAbsPartIdx, uiDepth) pcCU.SetTrIdxSubParts(0, uiAbsPartIdx, uiDepth) return } } this.xDecodeTransform(pcCU, uiLumaOffset, uiChromaOffset, uiAbsPartIdx, uiDepth, uiWidth, uiHeight, 0, bCodeDQP) }
//private: func (this *TDecEntropy) xDecodeTransform(pcCU *TLibCommon.TComDataCU, offsetLuma, offsetChroma, uiAbsPartIdx, uiDepth, width, height, uiTrIdx uint, bCodeDQP *bool) { var uiSubdiv uint uiLog2TrafoSize := uint(TLibCommon.G_aucConvertToBit[pcCU.GetSlice().GetSPS().GetMaxCUWidth()]) + 2 - uiDepth if uiTrIdx == 0 { this.m_bakAbsPartIdxCU = uiAbsPartIdx } if uiLog2TrafoSize == 2 { partNum := pcCU.GetPic().GetNumPartInCU() >> ((uiDepth - 1) << 1) if (uiAbsPartIdx % partNum) == 0 { this.m_uiBakAbsPartIdx = uiAbsPartIdx this.m_uiBakChromaOffset = offsetChroma } } if pcCU.GetPredictionMode1(uiAbsPartIdx) == TLibCommon.MODE_INTRA && pcCU.GetPartitionSize1(uiAbsPartIdx) == TLibCommon.SIZE_NxN && uiDepth == uint(pcCU.GetDepth1(uiAbsPartIdx)) { uiSubdiv = 1 } else if (pcCU.GetSlice().GetSPS().GetQuadtreeTUMaxDepthInter() == 1) && (pcCU.GetPredictionMode1(uiAbsPartIdx) == TLibCommon.MODE_INTER) && (pcCU.GetPartitionSize1(uiAbsPartIdx) != TLibCommon.SIZE_2Nx2N) && (uiDepth == uint(pcCU.GetDepth1(uiAbsPartIdx))) { uiSubdiv = uint(TLibCommon.B2U(uiLog2TrafoSize > pcCU.GetQuadtreeTULog2MinSizeInCU(uiAbsPartIdx))) } else if uiLog2TrafoSize > pcCU.GetSlice().GetSPS().GetQuadtreeTULog2MaxSize() { uiSubdiv = 1 } else if uiLog2TrafoSize == pcCU.GetSlice().GetSPS().GetQuadtreeTULog2MinSize() { uiSubdiv = 0 } else if uiLog2TrafoSize == pcCU.GetQuadtreeTULog2MinSizeInCU(uiAbsPartIdx) { uiSubdiv = 0 } else { //assert( uiLog2TrafoSize > pcCU.GetQuadtreeTULog2MinSizeInCU(uiAbsPartIdx) ); this.m_pcEntropyDecoderIf.ParseTransformSubdivFlag(&uiSubdiv, 5-uiLog2TrafoSize) } uiTrDepth := uiDepth - uint(pcCU.GetDepth1(uiAbsPartIdx)) { bFirstCbfOfCU := uiTrDepth == 0 if bFirstCbfOfCU { pcCU.SetCbfSubParts4(0, TLibCommon.TEXT_CHROMA_U, uiAbsPartIdx, uiDepth) pcCU.SetCbfSubParts4(0, TLibCommon.TEXT_CHROMA_V, uiAbsPartIdx, uiDepth) } if bFirstCbfOfCU || uiLog2TrafoSize > 2 { if bFirstCbfOfCU || pcCU.GetCbf3(uiAbsPartIdx, TLibCommon.TEXT_CHROMA_U, uiTrDepth-1) != 0 { this.m_pcEntropyDecoderIf.ParseQtCbf(pcCU, uiAbsPartIdx, TLibCommon.TEXT_CHROMA_U, uiTrDepth, uiDepth) } if bFirstCbfOfCU || pcCU.GetCbf3(uiAbsPartIdx, TLibCommon.TEXT_CHROMA_V, uiTrDepth-1) != 0 { this.m_pcEntropyDecoderIf.ParseQtCbf(pcCU, uiAbsPartIdx, TLibCommon.TEXT_CHROMA_V, uiTrDepth, uiDepth) } } else { pcCU.SetCbfSubParts4(byte(pcCU.GetCbf3(uiAbsPartIdx, TLibCommon.TEXT_CHROMA_U, uiTrDepth-1)<<uiTrDepth), TLibCommon.TEXT_CHROMA_U, uiAbsPartIdx, uiDepth) pcCU.SetCbfSubParts4(byte(pcCU.GetCbf3(uiAbsPartIdx, TLibCommon.TEXT_CHROMA_V, uiTrDepth-1)<<uiTrDepth), TLibCommon.TEXT_CHROMA_V, uiAbsPartIdx, uiDepth) } } if uiSubdiv != 0 { var size uint width >>= 1 height >>= 1 size = width * height uiTrIdx++ uiDepth++ uiQPartNum := pcCU.GetPic().GetNumPartInCU() >> (uiDepth << 1) uiStartAbsPartIdx := uiAbsPartIdx uiYCbf := uint(0) uiUCbf := uint(0) uiVCbf := uint(0) for i := uint(0); i < 4; i++ { this.xDecodeTransform(pcCU, offsetLuma, offsetChroma, uiAbsPartIdx, uiDepth, width, height, uiTrIdx, bCodeDQP) uiYCbf |= uint(pcCU.GetCbf3(uiAbsPartIdx, TLibCommon.TEXT_LUMA, uiTrDepth+1)) uiUCbf |= uint(pcCU.GetCbf3(uiAbsPartIdx, TLibCommon.TEXT_CHROMA_U, uiTrDepth+1)) uiVCbf |= uint(pcCU.GetCbf3(uiAbsPartIdx, TLibCommon.TEXT_CHROMA_V, uiTrDepth+1)) uiAbsPartIdx += uiQPartNum offsetLuma += size offsetChroma += (size >> 2) } for ui := uint(0); ui < 4*uiQPartNum; ui++ { pcCU.GetCbf1(TLibCommon.TEXT_LUMA)[uiStartAbsPartIdx+ui] |= byte(uiYCbf << uiTrDepth) pcCU.GetCbf1(TLibCommon.TEXT_CHROMA_U)[uiStartAbsPartIdx+ui] |= byte(uiUCbf << uiTrDepth) pcCU.GetCbf1(TLibCommon.TEXT_CHROMA_V)[uiStartAbsPartIdx+ui] |= byte(uiVCbf << uiTrDepth) } } else { //assert( uiDepth >= pcCU.GetDepth( uiAbsPartIdx ) ); pcCU.SetTrIdxSubParts(uiTrDepth, uiAbsPartIdx, uiDepth) { //DTRACE_CABAC_VL( TLibCommon.G_nSymbolCounter++ ); /*this.m_pcEntropyDecoderIf.DTRACE_CABAC_T("\tTrIdx: abspart=") this.m_pcEntropyDecoderIf.DTRACE_CABAC_V(uiAbsPartIdx) this.m_pcEntropyDecoderIf.DTRACE_CABAC_T("\tdepth=") this.m_pcEntropyDecoderIf.DTRACE_CABAC_V(uiDepth) this.m_pcEntropyDecoderIf.DTRACE_CABAC_T("\ttrdepth=") this.m_pcEntropyDecoderIf.DTRACE_CABAC_V(uiTrDepth) this.m_pcEntropyDecoderIf.DTRACE_CABAC_T("\n")*/ } pcCU.SetCbfSubParts4(0, TLibCommon.TEXT_LUMA, uiAbsPartIdx, uiDepth) if pcCU.GetPredictionMode1(uiAbsPartIdx) != TLibCommon.MODE_INTRA && uiDepth == uint(pcCU.GetDepth1(uiAbsPartIdx)) && pcCU.GetCbf3(uiAbsPartIdx, TLibCommon.TEXT_CHROMA_U, 0) == 0 && pcCU.GetCbf3(uiAbsPartIdx, TLibCommon.TEXT_CHROMA_V, 0) == 0 { pcCU.SetCbfSubParts4(1<<uiTrDepth, TLibCommon.TEXT_LUMA, uiAbsPartIdx, uiDepth) } else { this.m_pcEntropyDecoderIf.ParseQtCbf(pcCU, uiAbsPartIdx, TLibCommon.TEXT_LUMA, uiTrDepth, uiDepth) } // transforthis.m_unit begin cbfY := pcCU.GetCbf3(uiAbsPartIdx, TLibCommon.TEXT_LUMA, uiTrIdx) cbfU := pcCU.GetCbf3(uiAbsPartIdx, TLibCommon.TEXT_CHROMA_U, uiTrIdx) cbfV := pcCU.GetCbf3(uiAbsPartIdx, TLibCommon.TEXT_CHROMA_V, uiTrIdx) if uiLog2TrafoSize == 2 { partNum := pcCU.GetPic().GetNumPartInCU() >> ((uiDepth - 1) << 1) if (uiAbsPartIdx % partNum) == (partNum - 1) { cbfU = pcCU.GetCbf3(this.m_uiBakAbsPartIdx, TLibCommon.TEXT_CHROMA_U, uiTrIdx) cbfV = pcCU.GetCbf3(this.m_uiBakAbsPartIdx, TLibCommon.TEXT_CHROMA_V, uiTrIdx) } } if cbfY != 0 || cbfU != 0 || cbfV != 0 { // dQP: only for LCU if pcCU.GetSlice().GetPPS().GetUseDQP() { if *bCodeDQP { this.DecodeQP(pcCU, this.m_bakAbsPartIdxCU) *bCodeDQP = false } } } if cbfY != 0 { trWidth := width trHeight := height this.m_pcEntropyDecoderIf.ParseCoeffNxN(pcCU, pcCU.GetCoeffY()[offsetLuma:], uiAbsPartIdx, trWidth, trHeight, uiDepth, TLibCommon.TEXT_LUMA) } if uiLog2TrafoSize > 2 { trWidth := width >> 1 trHeight := height >> 1 if cbfU != 0 { this.m_pcEntropyDecoderIf.ParseCoeffNxN(pcCU, pcCU.GetCoeffCb()[offsetChroma:], uiAbsPartIdx, trWidth, trHeight, uiDepth, TLibCommon.TEXT_CHROMA_U) } if cbfV != 0 { this.m_pcEntropyDecoderIf.ParseCoeffNxN(pcCU, pcCU.GetCoeffCr()[offsetChroma:], uiAbsPartIdx, trWidth, trHeight, uiDepth, TLibCommon.TEXT_CHROMA_V) } } else { partNum := pcCU.GetPic().GetNumPartInCU() >> ((uiDepth - 1) << 1) if (uiAbsPartIdx % partNum) == (partNum - 1) { trWidth := width trHeight := height if cbfU != 0 { this.m_pcEntropyDecoderIf.ParseCoeffNxN(pcCU, pcCU.GetCoeffCb()[this.m_uiBakChromaOffset:], this.m_uiBakAbsPartIdx, trWidth, trHeight, uiDepth, TLibCommon.TEXT_CHROMA_U) } if cbfV != 0 { this.m_pcEntropyDecoderIf.ParseCoeffNxN(pcCU, pcCU.GetCoeffCr()[this.m_uiBakChromaOffset:], this.m_uiBakAbsPartIdx, trWidth, trHeight, uiDepth, TLibCommon.TEXT_CHROMA_V) } } } // transform_unit end } }