func (this *TEncEntropy) encodeInterDirPU(pcCU *TLibCommon.TComDataCU, uiAbsPartIdx uint) { if !pcCU.GetSlice().IsInterB() { return } this.m_pcEntropyCoderIf.codeInterDir(pcCU, uiAbsPartIdx) return }
func (this *TDecEntropy) DecodeIPCMInfo(pcCU *TLibCommon.TComDataCU, uiAbsPartIdx, uiDepth uint) { if !pcCU.GetSlice().GetSPS().GetUsePCM() || pcCU.GetWidth1(uiAbsPartIdx) > (1<<pcCU.GetSlice().GetSPS().GetPCMLog2MaxSize()) || pcCU.GetWidth1(uiAbsPartIdx) < (1<<pcCU.GetSlice().GetSPS().GetPCMLog2MinSize()) { return } this.m_pcEntropyDecoderIf.ParseIPCMInfo(pcCU, uiAbsPartIdx, uiDepth) }
func (this *TEncEntropy) encodeQP(pcCU *TLibCommon.TComDataCU, uiAbsPartIdx uint, bRD bool) { //= false ); if bRD { uiAbsPartIdx = 0 } if pcCU.GetSlice().GetPPS().GetUseDQP() { this.m_pcEntropyCoderIf.codeDeltaQP(pcCU, uiAbsPartIdx) } }
func (this *TEncEntropy) encodeSkipFlag(pcCU *TLibCommon.TComDataCU, uiAbsPartIdx uint, bRD bool) { //= false ); if pcCU.GetSlice().IsIntra() { return } if bRD { uiAbsPartIdx = 0 } this.m_pcEntropyCoderIf.codeSkipFlag(pcCU, uiAbsPartIdx) }
func (this *TEncEntropy) encodeRefFrmIdxPU(pcCU *TLibCommon.TComDataCU, uiAbsPartIdx uint, eRefList TLibCommon.RefPicList) { if pcCU.GetSlice().GetNumRefIdx(eRefList) == 1 { return } if pcCU.GetInterDir1(uiAbsPartIdx)&(1<<eRefList) != 0 { this.m_pcEntropyCoderIf.codeRefFrmIdx(pcCU, uiAbsPartIdx, eRefList) } return }
func (this *TDecEntropy) DecodeInterDirPU(pcCU *TLibCommon.TComDataCU, uiAbsPartIdx, uiDepth, uiPartIdx uint) { var uiInterDir uint if pcCU.GetSlice().IsInterP() { uiInterDir = 1 } else { this.m_pcEntropyDecoderIf.ParseInterDir(pcCU, &uiInterDir, uiAbsPartIdx) } pcCU.SetInterDirSubParts(uiInterDir, uiAbsPartIdx, uiPartIdx, uiDepth) }
func (this *TEncEntropy) encodeIPCMInfo(pcCU *TLibCommon.TComDataCU, uiAbsPartIdx uint, bRD bool) { // = false ); if !pcCU.GetSlice().GetSPS().GetUsePCM() || pcCU.GetWidth1(uiAbsPartIdx) > (1<<pcCU.GetSlice().GetSPS().GetPCMLog2MaxSize()) || pcCU.GetWidth1(uiAbsPartIdx) < (1<<pcCU.GetSlice().GetSPS().GetPCMLog2MinSize()) { return } if bRD { uiAbsPartIdx = 0 } this.m_pcEntropyCoderIf.codeIPCMInfo(pcCU, uiAbsPartIdx) }
func (this *TDecEntropy) DecodeRefFrmIdxPU(pcCU *TLibCommon.TComDataCU, uiAbsPartIdx, uiDepth, uiPartIdx uint, eRefList TLibCommon.RefPicList) { iRefFrmIdx := 0 iParseRefFrmIdx := pcCU.GetInterDir1(uiAbsPartIdx) & (1 << uint(eRefList)) //fmt.Printf("iParseRefFrmIdx=%d\n", iParseRefFrmIdx); if pcCU.GetSlice().GetNumRefIdx(eRefList) > 1 && iParseRefFrmIdx != 0 { this.m_pcEntropyDecoderIf.ParseRefFrmIdx(pcCU, &iRefFrmIdx, eRefList) //fmt.Printf("0iRefFrmIdx=%d\n", iRefFrmIdx); } else if iParseRefFrmIdx == 0 { iRefFrmIdx = TLibCommon.NOT_VALID //fmt.Printf("1iRefFrmIdx=%d\n", iRefFrmIdx); } else { iRefFrmIdx = 0 //fmt.Printf("2iRefFrmIdx=%d\n", iRefFrmIdx); } ePartSize := pcCU.GetPartitionSize1(uiAbsPartIdx) pcCU.GetCUMvField(eRefList).SetAllRefIdx(int8(iRefFrmIdx), ePartSize, int(uiAbsPartIdx), uiDepth, int(uiPartIdx)) }
func (this *TEncEntropy) encodePUWise(pcCU *TLibCommon.TComDataCU, uiAbsPartIdx uint, bRD bool) { //= false ); if bRD { uiAbsPartIdx = 0 } ePartSize := pcCU.GetPartitionSize1(uiAbsPartIdx) var uiNumPU uint if ePartSize == TLibCommon.SIZE_2Nx2N { uiNumPU = 1 } else if ePartSize == TLibCommon.SIZE_NxN { uiNumPU = 4 } else { uiNumPU = 2 } uiDepth := uint(pcCU.GetDepth1(uiAbsPartIdx)) //fmt.Printf("ePartSize=%d\n",ePartSize); uiPUOffset := (TLibCommon.G_auiPUOffset[uint(ePartSize)] << ((pcCU.GetSlice().GetSPS().GetMaxCUDepth() - uiDepth) << 1)) >> 4 uiSubPartIdx := uiAbsPartIdx for uiPartIdx := uint(0); uiPartIdx < uiNumPU; uiPartIdx++ { this.encodeMergeFlag(pcCU, uiSubPartIdx) if pcCU.GetMergeFlag1(uiSubPartIdx) { this.encodeMergeIndex(pcCU, uiSubPartIdx, false) } else { this.encodeInterDirPU(pcCU, uiSubPartIdx) for uiRefListIdx := 0; uiRefListIdx < 2; uiRefListIdx++ { if pcCU.GetSlice().GetNumRefIdx(TLibCommon.RefPicList(uiRefListIdx)) > 0 { this.encodeRefFrmIdxPU(pcCU, uiSubPartIdx, TLibCommon.RefPicList(uiRefListIdx)) this.encodeMvdPU(pcCU, uiSubPartIdx, TLibCommon.RefPicList(uiRefListIdx)) this.encodeMVPIdxPU(pcCU, uiSubPartIdx, TLibCommon.RefPicList(uiRefListIdx)) } } } uiSubPartIdx += uiPUOffset } return }
//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 } }
func (this *TDecEntropy) DecodeQP(pcCU *TLibCommon.TComDataCU, uiAbsPartIdx uint) { if pcCU.GetSlice().GetPPS().GetUseDQP() { this.m_pcEntropyDecoderIf.ParseDeltaQP(pcCU, uiAbsPartIdx, uint(pcCU.GetDepth1(uiAbsPartIdx))) } }
func (this *TDecEntropy) DecodePUWise(pcCU *TLibCommon.TComDataCU, uiAbsPartIdx, uiDepth uint, pcSubCU *TLibCommon.TComDataCU) { ePartSize := pcCU.GetPartitionSize1(uiAbsPartIdx) var uiNumPU uint if ePartSize == TLibCommon.SIZE_2Nx2N { uiNumPU = 1 } else if ePartSize == TLibCommon.SIZE_NxN { uiNumPU = 4 } else { uiNumPU = 2 } uiPUOffset := (TLibCommon.G_auiPUOffset[uint(ePartSize)] << ((pcCU.GetSlice().GetSPS().GetMaxCUDepth() - uiDepth) << 1)) >> 4 var cMvFieldNeighbours [TLibCommon.MRG_MAX_NUM_CANDS << 1]TLibCommon.TComMvField // double length for mv of both lists var uhInterDirNeighbours [TLibCommon.MRG_MAX_NUM_CANDS]byte for ui := uint(0); ui < pcCU.GetSlice().GetMaxNumMergeCand(); ui++ { uhInterDirNeighbours[ui] = 0 } numValidMergeCand := 0 isMerged := false pcSubCU.CopyInterPredInfoFrom(pcCU, uiAbsPartIdx, TLibCommon.REF_PIC_LIST_0) pcSubCU.CopyInterPredInfoFrom(pcCU, uiAbsPartIdx, TLibCommon.REF_PIC_LIST_1) uiSubPartIdx := uiAbsPartIdx for uiPartIdx := uint(0); uiPartIdx < uiNumPU; uiPartIdx++ { this.DecodeMergeFlag(pcCU, uiSubPartIdx, uiDepth, uiPartIdx) if pcCU.GetMergeFlag1(uiSubPartIdx) { this.DecodeMergeIndex(pcCU, uiPartIdx, uiSubPartIdx, uiDepth) uiMergeIndex := pcCU.GetMergeIndex1(uiSubPartIdx) if pcCU.GetSlice().GetPPS().GetLog2ParallelMergeLevelMinus2() != 0 && ePartSize != TLibCommon.SIZE_2Nx2N && pcSubCU.GetWidth1(0) <= 8 { pcSubCU.SetPartSizeSubParts(TLibCommon.SIZE_2Nx2N, 0, uiDepth) if !isMerged { pcSubCU.GetInterMergeCandidates(0, 0, cMvFieldNeighbours[:], uhInterDirNeighbours[:], &numValidMergeCand, -1) isMerged = true } pcSubCU.SetPartSizeSubParts(ePartSize, 0, uiDepth) } else { uiMergeIndex = pcCU.GetMergeIndex1(uiSubPartIdx) pcSubCU.GetInterMergeCandidates(uiSubPartIdx-uiAbsPartIdx, uiPartIdx, cMvFieldNeighbours[:], uhInterDirNeighbours[:], &numValidMergeCand, int(uiMergeIndex)) } pcCU.SetInterDirSubParts(uint(uhInterDirNeighbours[uiMergeIndex]), uiSubPartIdx, uiPartIdx, uiDepth) cTmpMv := TLibCommon.NewTComMv(0, 0) for uiRefListIdx := 0; uiRefListIdx < 2; uiRefListIdx++ { if pcCU.GetSlice().GetNumRefIdx(TLibCommon.RefPicList(uiRefListIdx)) > 0 { pcCU.SetMVPIdxSubParts(0, TLibCommon.RefPicList(uiRefListIdx), uiSubPartIdx, uiPartIdx, uiDepth) pcCU.SetMVPNumSubParts(0, TLibCommon.RefPicList(uiRefListIdx), uiSubPartIdx, uiPartIdx, uiDepth) pcCU.GetCUMvField(TLibCommon.RefPicList(uiRefListIdx)).SetAllMvd(*cTmpMv, ePartSize, int(uiSubPartIdx), uiDepth, int(uiPartIdx)) pcCU.GetCUMvField(TLibCommon.RefPicList(uiRefListIdx)).SetAllMvField(&cMvFieldNeighbours[2*int(uiMergeIndex)+uiRefListIdx], ePartSize, int(uiSubPartIdx), uiDepth, int(uiPartIdx)) } } } else { this.DecodeInterDirPU(pcCU, uiSubPartIdx, uiDepth, uiPartIdx) for uiRefListIdx := 0; uiRefListIdx < 2; uiRefListIdx++ { if pcCU.GetSlice().GetNumRefIdx(TLibCommon.RefPicList(uiRefListIdx)) > 0 { //fmt.Printf("%d \n",uiRefListIdx); this.DecodeRefFrmIdxPU(pcCU, uiSubPartIdx, uiDepth, uiPartIdx, TLibCommon.RefPicList(uiRefListIdx)) this.DecodeMvdPU(pcCU, uiSubPartIdx, uiDepth, uiPartIdx, TLibCommon.RefPicList(uiRefListIdx)) this.DecodeMVPIdxPU(pcSubCU, uiSubPartIdx-uiAbsPartIdx, uiDepth, uiPartIdx, TLibCommon.RefPicList(uiRefListIdx)) } } } if (pcCU.GetInterDir1(uiSubPartIdx) == 3) && pcSubCU.IsBipredRestriction(uiPartIdx) { pcCU.GetCUMvField(TLibCommon.REF_PIC_LIST_1).SetAllMv(*TLibCommon.NewTComMv(0, 0), ePartSize, int(uiSubPartIdx), uiDepth, int(uiPartIdx)) pcCU.GetCUMvField(TLibCommon.REF_PIC_LIST_1).SetAllRefIdx(-1, ePartSize, int(uiSubPartIdx), uiDepth, int(uiPartIdx)) pcCU.SetInterDirSubParts(1, uiSubPartIdx, uiPartIdx, uiDepth) } uiSubPartIdx += uiPUOffset } return }
func (this *TDecSlice) DecompressSlice(ppcSubstreams []*TLibCommon.TComInputBitstream, rpcPic *TLibCommon.TComPic, pcSbacDecoder *TDecSbac, pcSbacDecoders []*TDecSbac) { //var pcCU *TLibCommon.TComDataCU; uiIsLast := uint(0) var iStartCUEncOrder uint if rpcPic.GetSlice(rpcPic.GetCurrSliceIdx()).GetSliceCurStartCUAddr()/rpcPic.GetNumPartInCU() > rpcPic.GetSlice(rpcPic.GetCurrSliceIdx()).GetSliceSegmentCurStartCUAddr()/rpcPic.GetNumPartInCU() { iStartCUEncOrder = rpcPic.GetSlice(rpcPic.GetCurrSliceIdx()).GetSliceCurStartCUAddr() / rpcPic.GetNumPartInCU() } else { iStartCUEncOrder = rpcPic.GetSlice(rpcPic.GetCurrSliceIdx()).GetSliceSegmentCurStartCUAddr() / rpcPic.GetNumPartInCU() } iStartCUAddr := int(rpcPic.GetPicSym().GetCUOrderMap(int(iStartCUEncOrder))) // decoder don't need prediction & residual frame buffer rpcPic.SetPicYuvPred(nil) rpcPic.SetPicYuvResi(nil) //#if ENC_DEC_TRACE // g_bJustDoIt = g_bEncDecTraceEnable; //#endif // DTRACE_CABAC_VL( g_nSymbolCounter++ ); // DTRACE_CABAC_T( "\tPOC: " ); // DTRACE_CABAC_V( rpcPic.GetPOC() ); // DTRACE_CABAC_T( "\n" ); //#if ENC_DEC_TRACE // g_bJustDoIt = g_bEncDecTraceDisable; //#endif uiTilesAcross := rpcPic.GetPicSym().GetNumColumnsMinus1() + 1 pcSlice := rpcPic.GetSlice(rpcPic.GetCurrSliceIdx()) iNumSubstreams := pcSlice.GetPPS().GetNumSubstreams() // delete decoders if already allocated in previous slice /*if (m_pcBufferSbacDecoders) { delete [] m_pcBufferSbacDecoders; } if (m_pcBufferBinCABACs) { delete [] m_pcBufferBinCABACs; }*/ // allocate new decoders based on tile numbaer this.m_pcBufferSbacDecoders = make([]*TDecSbac, uiTilesAcross) this.m_pcBufferBinCABACs = make([]*TDecBinCabac, uiTilesAcross) for ui := 0; ui < uiTilesAcross; ui++ { this.m_pcBufferBinCABACs[ui] = NewTDecBinCabac() this.m_pcBufferSbacDecoders[ui] = NewTDecSbac() this.m_pcBufferSbacDecoders[ui].Init(this.m_pcBufferBinCABACs[ui]) } //save init. state for ui := 0; ui < uiTilesAcross; ui++ { this.m_pcBufferSbacDecoders[ui].Load(pcSbacDecoder) } // free memory if already allocated in previous call /*if (this.m_pcBufferLowLatSbacDecoders) { delete [] this.m_pcBufferLowLatSbacDecoders; } if (this.m_pcBufferLowLatBinCABACs) { delete [] this.m_pcBufferLowLatBinCABACs; }*/ this.m_pcBufferLowLatSbacDecoders = make([]*TDecSbac, uiTilesAcross) this.m_pcBufferLowLatBinCABACs = make([]*TDecBinCabac, uiTilesAcross) for ui := 0; ui < uiTilesAcross; ui++ { this.m_pcBufferLowLatBinCABACs[ui] = NewTDecBinCabac() this.m_pcBufferLowLatSbacDecoders[ui] = NewTDecSbac() this.m_pcBufferLowLatSbacDecoders[ui].Init(this.m_pcBufferLowLatBinCABACs[ui]) } //save init. state for ui := 0; ui < uiTilesAcross; ui++ { this.m_pcBufferLowLatSbacDecoders[ui].Load(pcSbacDecoder) } uiWidthInLCUs := rpcPic.GetPicSym().GetFrameWidthInCU() //UInt uiHeightInLCUs = rpcPic.GetPicSym().GetFrameHeightInCU(); uiCol := uint(0) uiLin := uint(0) uiSubStrm := uint(0) var uiTileCol, uiTileStartLCU, uiTileLCUX uint iNumSubstreamsPerTile := 1 // if independent. depSliceSegmentsEnabled := rpcPic.GetSlice(rpcPic.GetCurrSliceIdx()).GetPPS().GetDependentSliceSegmentsEnabledFlag() uiTileStartLCU = rpcPic.GetPicSym().GetTComTile(rpcPic.GetPicSym().GetTileIdxMap(iStartCUAddr)).GetFirstCUAddr() if depSliceSegmentsEnabled { if (!rpcPic.GetSlice(rpcPic.GetCurrSliceIdx()).IsNextSlice()) && iStartCUAddr != int(rpcPic.GetPicSym().GetTComTile(rpcPic.GetPicSym().GetTileIdxMap(iStartCUAddr)).GetFirstCUAddr()) { if pcSlice.GetPPS().GetEntropyCodingSyncEnabledFlag() { uiTileCol = rpcPic.GetPicSym().GetTileIdxMap(iStartCUAddr) % uint(rpcPic.GetPicSym().GetNumColumnsMinus1()+1) this.m_pcBufferSbacDecoders[uiTileCol].LoadContexts(this.CTXMem[1]) //2.LCU if (uint(iStartCUAddr)%uiWidthInLCUs + 1) >= uiWidthInLCUs { uiTileLCUX = uiTileStartLCU % uiWidthInLCUs uiCol = uint(iStartCUAddr) % uiWidthInLCUs if uiCol == uiTileLCUX { this.CTXMem[0].LoadContexts(pcSbacDecoder) } } } pcSbacDecoder.LoadContexts(this.CTXMem[0]) //end of depSlice-1 pcSbacDecoders[uiSubStrm].LoadContexts(pcSbacDecoder) } else { if pcSlice.GetPPS().GetEntropyCodingSyncEnabledFlag() { this.CTXMem[1].LoadContexts(pcSbacDecoder) } this.CTXMem[0].LoadContexts(pcSbacDecoder) } } for iCUAddr := iStartCUAddr; uiIsLast == 0 && iCUAddr < int(rpcPic.GetNumCUsInFrame()); iCUAddr = int(rpcPic.GetPicSym().XCalculateNxtCUAddr(uint(iCUAddr))) { pcCU := rpcPic.GetCU(uint(iCUAddr)) pcCU.InitCU(rpcPic, uint(iCUAddr)) fmt.Printf("%d ", iCUAddr) //#ifdef ENC_DEC_TRACE pcSbacDecoder.XTraceLCUHeader(TLibCommon.TRACE_LCU) pcSbacDecoder.XReadAeTr(iCUAddr, "lcu_address", TLibCommon.TRACE_LCU) pcSbacDecoder.XReadAeTr(int(rpcPic.GetPicSym().GetTileIdxMap(iCUAddr)), "tile_id", TLibCommon.TRACE_LCU) //#endif uiTileCol = rpcPic.GetPicSym().GetTileIdxMap(int(iCUAddr)) % uint(rpcPic.GetPicSym().GetNumColumnsMinus1()+1) // what column of tiles are we in? uiTileStartLCU = rpcPic.GetPicSym().GetTComTile(rpcPic.GetPicSym().GetTileIdxMap(int(iCUAddr))).GetFirstCUAddr() uiTileLCUX = uiTileStartLCU % uiWidthInLCUs uiCol = uint(iCUAddr) % uiWidthInLCUs // The 'line' is now relative to the 1st line in the slice, not the 1st line in the picture. uiLin = (uint(iCUAddr) / uiWidthInLCUs) - (uint(iStartCUAddr) / uiWidthInLCUs) // inherit from TR if necessary, select substream to use. if (pcSlice.GetPPS().GetNumSubstreams() > 1) || (depSliceSegmentsEnabled && (uiCol == uiTileLCUX) && (pcSlice.GetPPS().GetEntropyCodingSyncEnabledFlag())) { // independent tiles => substreams are "per tile". iNumSubstreams has already been multiplied. iNumSubstreamsPerTile = iNumSubstreams / rpcPic.GetPicSym().GetNumTiles() uiSubStrm = rpcPic.GetPicSym().GetTileIdxMap(iCUAddr)*uint(iNumSubstreamsPerTile) + uiLin%uint(iNumSubstreamsPerTile) this.m_pcEntropyDecoder.SetBitstream(ppcSubstreams[uiSubStrm]) // Synchronize cabac probabilities with upper-right LCU if it's available and we're at the start of a line. if ((pcSlice.GetPPS().GetNumSubstreams() > 1) || depSliceSegmentsEnabled) && (uiCol == uiTileLCUX) && (pcSlice.GetPPS().GetEntropyCodingSyncEnabledFlag()) { // We'll sync if the TR is available. pcCUUp := pcCU.GetCUAbove() uiWidthInCU := rpcPic.GetFrameWidthInCU() var pcCUTR *TLibCommon.TComDataCU if pcCUUp != nil && ((uint(iCUAddr)%uiWidthInCU + 1) < uiWidthInCU) { pcCUTR = rpcPic.GetCU(uint(iCUAddr) - uiWidthInCU + 1) } uiMaxParts := uint(1 << (pcSlice.GetSPS().GetMaxCUDepth() << 1)) if true && //bEnforceSliceRestriction ((pcCUTR == nil) || (pcCUTR.GetSlice() == nil) || ((pcCUTR.GetSCUAddr() + uiMaxParts - 1) < pcSlice.GetSliceCurStartCUAddr()) || (rpcPic.GetPicSym().GetTileIdxMap(int(pcCUTR.GetAddr())) != rpcPic.GetPicSym().GetTileIdxMap(iCUAddr))) { // TR not available. } else { // TR is available, we use it. pcSbacDecoders[uiSubStrm].LoadContexts(this.m_pcBufferSbacDecoders[uiTileCol]) } } pcSbacDecoder.Load(pcSbacDecoders[uiSubStrm]) //this load is used to simplify the code (avoid to change all the call to pcSbacDecoders) } else if pcSlice.GetPPS().GetNumSubstreams() <= 1 { // Set variables to appropriate values to avoid later code change. iNumSubstreamsPerTile = 1 } if (uint(iCUAddr) == rpcPic.GetPicSym().GetTComTile(rpcPic.GetPicSym().GetTileIdxMap(iCUAddr)).GetFirstCUAddr()) && // 1st in tile. (iCUAddr != 0) && (uint(iCUAddr) != rpcPic.GetPicSym().GetPicSCUAddr(rpcPic.GetSlice(rpcPic.GetCurrSliceIdx()).GetSliceCurStartCUAddr())/rpcPic.GetNumPartInCU()) && (uint(iCUAddr) != rpcPic.GetPicSym().GetPicSCUAddr(rpcPic.GetSlice(rpcPic.GetCurrSliceIdx()).GetSliceSegmentCurStartCUAddr())/rpcPic.GetNumPartInCU()) { // !1st in frame && !1st in slice if pcSlice.GetPPS().GetNumSubstreams() > 1 { // We're crossing into another tile, tiles are independent. // When tiles are independent, we have "substreams per tile". Each substream has already been terminated, and we no longer // have to perform it here. // For TILES_DECODER, there can be a header at the start of the 1st substream in a tile. These are read when the substreams // are extracted, not here. } else { sliceType := pcSlice.GetSliceType() if pcSlice.GetCabacInitFlag() { switch sliceType { case TLibCommon.P_SLICE: // change initialization table to B_SLICE intialization sliceType = TLibCommon.B_SLICE //break; case TLibCommon.B_SLICE: // change initialization table to P_SLICE intialization sliceType = TLibCommon.P_SLICE //break; //default : // should not occur //assert(0); } } this.m_pcEntropyDecoder.UpdateContextTables(sliceType, pcSlice.GetSliceQp()) } } //#if ENC_DEC_TRACE // g_bJustDoIt = g_bEncDecTraceEnable; //#endif if pcSlice.GetSPS().GetUseSAO() && (pcSlice.GetSaoEnabledFlag() || pcSlice.GetSaoEnabledFlagChroma()) { saoParam := rpcPic.GetPicSym().GetSaoParam() saoParam.SaoFlag[0] = pcSlice.GetSaoEnabledFlag() if iCUAddr == iStartCUAddr { saoParam.SaoFlag[1] = pcSlice.GetSaoEnabledFlagChroma() } numCuInWidth := saoParam.NumCuInWidth cuAddrInSlice := iCUAddr - int(rpcPic.GetPicSym().GetCUOrderMap(int(pcSlice.GetSliceCurStartCUAddr()/rpcPic.GetNumPartInCU()))) cuAddrUpInSlice := cuAddrInSlice - numCuInWidth rx := iCUAddr % numCuInWidth ry := iCUAddr / numCuInWidth allowMergeLeft := true allowMergeUp := true if rx != 0 { if rpcPic.GetPicSym().GetTileIdxMap(iCUAddr-1) != rpcPic.GetPicSym().GetTileIdxMap(iCUAddr) { allowMergeLeft = false } } if ry != 0 { if rpcPic.GetPicSym().GetTileIdxMap(iCUAddr-numCuInWidth) != rpcPic.GetPicSym().GetTileIdxMap(iCUAddr) { allowMergeUp = false } } pcSbacDecoder.ParseSaoOneLcuInterleaving(rx, ry, saoParam, pcCU, cuAddrInSlice, cuAddrUpInSlice, allowMergeLeft, allowMergeUp) } else if pcSlice.GetSPS().GetUseSAO() { addr := pcCU.GetAddr() saoParam := rpcPic.GetPicSym().GetSaoParam() for cIdx := 0; cIdx < 3; cIdx++ { saoLcuParam := &(saoParam.SaoLcuParam[cIdx][addr]) if ((cIdx == 0) && !pcSlice.GetSaoEnabledFlag()) || ((cIdx == 1 || cIdx == 2) && !pcSlice.GetSaoEnabledFlagChroma()) { saoLcuParam.MergeUpFlag = false saoLcuParam.MergeLeftFlag = false saoLcuParam.SubTypeIdx = 0 saoLcuParam.TypeIdx = -1 saoLcuParam.Offset[0] = 0 saoLcuParam.Offset[1] = 0 saoLcuParam.Offset[2] = 0 saoLcuParam.Offset[3] = 0 } } } this.m_pcCuDecoder.DecodeCU(pcCU, &uiIsLast) this.m_pcCuDecoder.DecompressCU(pcCU) //#if ENC_DEC_TRACE // g_bJustDoIt = g_bEncDecTraceDisable; //#endif pcSbacDecoders[uiSubStrm].Load(pcSbacDecoder) //Store probabilities of second LCU in line into buffer if (uiCol == uiTileLCUX+1) && (depSliceSegmentsEnabled || (pcSlice.GetPPS().GetNumSubstreams() > 1)) && (pcSlice.GetPPS().GetEntropyCodingSyncEnabledFlag()) { this.m_pcBufferSbacDecoders[uiTileCol].LoadContexts(pcSbacDecoders[uiSubStrm]) } if uiIsLast != 0 && depSliceSegmentsEnabled { if pcSlice.GetPPS().GetEntropyCodingSyncEnabledFlag() { this.CTXMem[1].LoadContexts(this.m_pcBufferSbacDecoders[uiTileCol]) //ctx 2.LCU } this.CTXMem[0].LoadContexts(pcSbacDecoder) //ctx end of dep.slice return } } return }
func (this *TEncEntropy) xEncodeTransform(pcCU *TLibCommon.TComDataCU, offsetLuma, offsetChroma, uiAbsPartIdx, uiDepth, width, height, uiTrIdx uint, bCodeDQP *bool) { uiSubdiv := uint(TLibCommon.B2U(uint(pcCU.GetTransformIdx1(uiAbsPartIdx)+pcCU.GetDepth1(uiAbsPartIdx)) > uiDepth)) uiLog2TrafoSize := uint(TLibCommon.G_aucConvertToBit[pcCU.GetSlice().GetSPS().GetMaxCUWidth()]) + 2 - uiDepth 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) //fmt.Print("Enter xEncodeTransform\n");// with uiSubdiv=%d, uiAbsPartIdx=%d, uiDepth=%d\n", uiSubdiv, uiAbsPartIdx, 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 } else 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 pcCU.GetPredictionMode1(uiAbsPartIdx) == TLibCommon.MODE_INTRA && pcCU.GetPartitionSize1(uiAbsPartIdx) == TLibCommon.SIZE_NxN && uiDepth == uint(pcCU.GetDepth1(uiAbsPartIdx)) { //assert( uiSubdiv ); } else if pcCU.GetPredictionMode1(uiAbsPartIdx) == TLibCommon.MODE_INTER && (pcCU.GetPartitionSize1(uiAbsPartIdx) != TLibCommon.SIZE_2Nx2N) && uiDepth == uint(pcCU.GetDepth1(uiAbsPartIdx)) && (pcCU.GetSlice().GetSPS().GetQuadtreeTUMaxDepthInter() == 1) { if uiLog2TrafoSize > pcCU.GetQuadtreeTULog2MinSizeInCU(uiAbsPartIdx) { //assert( uiSubdiv ); } else { //assert(!uiSubdiv ); } } else if uiLog2TrafoSize > pcCU.GetSlice().GetSPS().GetQuadtreeTULog2MaxSize() { //assert( uiSubdiv ); } else if uiLog2TrafoSize == pcCU.GetSlice().GetSPS().GetQuadtreeTULog2MinSize() { //assert( !uiSubdiv ); } else if uiLog2TrafoSize == pcCU.GetQuadtreeTULog2MinSizeInCU(uiAbsPartIdx) { //assert( !uiSubdiv ); } else { //assert( uiLog2TrafoSize > pcCU.GetQuadtreeTULog2MinSizeInCU(uiAbsPartIdx) ); this.m_pcEntropyCoderIf.codeTransformSubdivFlag(uiSubdiv, 5-uiLog2TrafoSize) } uiTrDepthCurr := uiDepth - uint(pcCU.GetDepth1(uiAbsPartIdx)) bFirstCbfOfCU := uiTrDepthCurr == 0 if bFirstCbfOfCU || uiLog2TrafoSize > 2 { if bFirstCbfOfCU || pcCU.GetCbf3(uiAbsPartIdx, TLibCommon.TEXT_CHROMA_U, uiTrDepthCurr-1) != 0 { this.m_pcEntropyCoderIf.codeQtCbf(pcCU, uiAbsPartIdx, TLibCommon.TEXT_CHROMA_U, uiTrDepthCurr) } if bFirstCbfOfCU || pcCU.GetCbf3(uiAbsPartIdx, TLibCommon.TEXT_CHROMA_V, uiTrDepthCurr-1) != 0 { this.m_pcEntropyCoderIf.codeQtCbf(pcCU, uiAbsPartIdx, TLibCommon.TEXT_CHROMA_V, uiTrDepthCurr) } } else if uiLog2TrafoSize == 2 { //assert( pcCU.GetCbf( uiAbsPartIdx, TEXT_CHROMA_U, uiTrDepthCurr ) == pcCU.GetCbf( uiAbsPartIdx, TEXT_CHROMA_U, uiTrDepthCurr - 1 ) ); //assert( pcCU.GetCbf( uiAbsPartIdx, TEXT_CHROMA_V, uiTrDepthCurr ) == pcCU.GetCbf( uiAbsPartIdx, TEXT_CHROMA_V, uiTrDepthCurr - 1 ) ); } if uiSubdiv != 0 { var size uint width >>= 1 height >>= 1 size = width * height uiTrIdx++ uiDepth++ partNum := pcCU.GetPic().GetNumPartInCU() >> (uiDepth << 1) this.xEncodeTransform(pcCU, offsetLuma, offsetChroma, uiAbsPartIdx, uiDepth, width, height, uiTrIdx, bCodeDQP) uiAbsPartIdx += partNum offsetLuma += size offsetChroma += (size >> 2) this.xEncodeTransform(pcCU, offsetLuma, offsetChroma, uiAbsPartIdx, uiDepth, width, height, uiTrIdx, bCodeDQP) uiAbsPartIdx += partNum offsetLuma += size offsetChroma += (size >> 2) this.xEncodeTransform(pcCU, offsetLuma, offsetChroma, uiAbsPartIdx, uiDepth, width, height, uiTrIdx, bCodeDQP) uiAbsPartIdx += partNum offsetLuma += size offsetChroma += (size >> 2) this.xEncodeTransform(pcCU, offsetLuma, offsetChroma, uiAbsPartIdx, uiDepth, width, height, uiTrIdx, bCodeDQP) } else { /*DTRACE_CABAC_VL( g_nSymbolCounter++ );*/ this.m_pcEntropyCoderIf.DTRACE_CABAC_T("\tTrIdx: abspart=") this.m_pcEntropyCoderIf.DTRACE_CABAC_V(uiAbsPartIdx) this.m_pcEntropyCoderIf.DTRACE_CABAC_T("\tdepth=") this.m_pcEntropyCoderIf.DTRACE_CABAC_V(uiDepth) this.m_pcEntropyCoderIf.DTRACE_CABAC_T("\ttrdepth=") this.m_pcEntropyCoderIf.DTRACE_CABAC_V(uint(pcCU.GetTransformIdx1(uiAbsPartIdx))) this.m_pcEntropyCoderIf.DTRACE_CABAC_T("\n") 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 { //assert( pcCU.GetCbf( uiAbsPartIdx, TLibCommon.TEXT_LUMA, 0 ) ); } else { this.m_pcEntropyCoderIf.codeQtCbf(pcCU, uiAbsPartIdx, TLibCommon.TEXT_LUMA, uint(pcCU.GetTransformIdx1(uiAbsPartIdx))) } if cbfY != 0 || cbfU != 0 || cbfV != 0 { // dQP: only for LCU once if pcCU.GetSlice().GetPPS().GetUseDQP() { if *bCodeDQP { this.encodeQP(pcCU, this.m_bakAbsPartIdxCU, false) *bCodeDQP = false } } } if cbfY != 0 { trWidth := width trHeight := height this.m_pcEntropyCoderIf.codeCoeffNxN(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_pcEntropyCoderIf.codeCoeffNxN(pcCU, pcCU.GetCoeffCb()[offsetChroma:], uiAbsPartIdx, trWidth, trHeight, uiDepth, TLibCommon.TEXT_CHROMA_U) } if cbfV != 0 { this.m_pcEntropyCoderIf.codeCoeffNxN(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_pcEntropyCoderIf.codeCoeffNxN(pcCU, pcCU.GetCoeffCb()[this.m_uiBakChromaOffset:], this.m_uiBakAbsPartIdx, trWidth, trHeight, uiDepth, TLibCommon.TEXT_CHROMA_U) } if cbfV != 0 { this.m_pcEntropyCoderIf.codeCoeffNxN(pcCU, pcCU.GetCoeffCr()[this.m_uiBakChromaOffset:], this.m_uiBakAbsPartIdx, trWidth, trHeight, uiDepth, TLibCommon.TEXT_CHROMA_V) } } } } //fmt.Print("Exit xEncodeTransform\n"); }