From fbb98095a0a572e8c6de37fcb14f330e53785a2b Mon Sep 17 00:00:00 2001 From: Saxon Date: Mon, 9 Sep 2019 11:08:48 +0930 Subject: [PATCH] codec/h264/h264dec: embedded SliceHeader and SliceData into Slice type, and embedded SPS and PPS into VideoStream type --- codec/h264/h264dec/cabac.go | 10 +- codec/h264/h264dec/slice.go | 315 ++++++++++++++++++------------------ 2 files changed, 162 insertions(+), 163 deletions(-) diff --git a/codec/h264/h264dec/cabac.go b/codec/h264/h264dec/cabac.go index 7b28414e..25d3bec9 100644 --- a/codec/h264/h264dec/cabac.go +++ b/codec/h264/h264dec/cabac.go @@ -171,7 +171,7 @@ type CABAC struct { } // table 9-1 -func initCabac(binarization *Binarization, context *SliceContext) *CABAC { +func initCabac(binarization *Binarization, vid *VideoStream, ctx *SliceContext) *CABAC { var valMPS, pStateIdx int // TODO: When to use prefix, when to use suffix? ctxIdx := CtxIdx( @@ -180,7 +180,7 @@ func initCabac(binarization *Binarization, context *SliceContext) *CABAC { binarization.CtxIdxOffset.Prefix) mn := MNVars[ctxIdx] - preCtxState := PreCtxState(mn[0].M, mn[0].N, SliceQPy(context.PPS, context.Header)) + preCtxState := PreCtxState(mn[0].M, mn[0].N, SliceQPy(vid.PPS, ctx.SliceHeader)) if preCtxState <= 63 { pStateIdx = 63 - preCtxState valMPS = 0 @@ -195,7 +195,7 @@ func initCabac(binarization *Binarization, context *SliceContext) *CABAC { return &CABAC{ PStateIdx: pStateIdx, ValMPS: valMPS, - Context: context, + Context: ctx, } } @@ -457,7 +457,7 @@ func NewArithmeticDecoding(context *SliceContext, binarization *Binarization, ct if binarization.UseDecodeBypass == 1 { // TODO: 9.3.3.2.3 : DecodeBypass() var err error - codIOffset, a.BinVal, err = a.DecodeBypass(context.Slice.Data, codIRange, codIOffset) + codIOffset, a.BinVal, err = a.DecodeBypass(context.SliceData, codIRange, codIOffset) if err != nil { return ArithmeticDecoding{}, errors.Wrap(err, "error from DecodeBypass getting codIOffset and BinVal") } @@ -539,7 +539,7 @@ type ArithmeticDecoding struct { // returns: binVal, updated codIRange, updated codIOffset func (a ArithmeticDecoding) BinaryDecision(ctxIdx, codIRange, codIOffset int) (int, int, int, error) { var binVal int - cabac := initCabac(a.Binarization, a.Context) + cabac := initCabac(a.Binarization, nil, a.Context) // Derivce codIRangeLPS qCodIRangeIdx := (codIRange >> 6) & 3 pStateIdx := cabac.PStateIdx diff --git a/codec/h264/h264dec/slice.go b/codec/h264/h264dec/slice.go index 05fe33ea..4952cfd9 100644 --- a/codec/h264/h264dec/slice.go +++ b/codec/h264/h264dec/slice.go @@ -36,21 +36,21 @@ const ( ) type VideoStream struct { - SPS *SPS - PPS *PPS + *SPS + *PPS Slices []*SliceContext ChromaArrayType int } + type SliceContext struct { *NALUnit - *SPS - *PPS *Slice } + type Slice struct { - Header *SliceHeader - Data *SliceData + *SliceHeader + *SliceData } // RefPicListModification provides elements of a ref_pic_list_modification syntax @@ -526,12 +526,12 @@ func NumMbPart(nalUnit *NALUnit, sps *SPS, header *SliceHeader, data *SliceData) return numMbPart } -func MbPred(chromaArrayType int, sliceContext *SliceContext, br *bits.BitReader, rbsp []byte) error { +func MbPred(chromaArrayType int, vid *VideoStream, sliceContext *SliceContext, br *bits.BitReader, rbsp []byte) error { var cabac *CABAC r := newFieldReader(br) - sliceType := sliceTypeMap[sliceContext.Slice.Header.SliceType] - mbPartPredMode, err := MbPartPredMode(sliceContext.Slice.Data, sliceType, sliceContext.Slice.Data.MbType, 0) + sliceType := sliceTypeMap[sliceContext.Slice.SliceHeader.SliceType] + mbPartPredMode, err := MbPartPredMode(sliceContext.Slice.SliceData, sliceType, sliceContext.Slice.SliceData.MbType, 0) if err != nil { return errors.Wrap(err, "could not get mbPartPredMode") } @@ -539,14 +539,15 @@ func MbPred(chromaArrayType int, sliceContext *SliceContext, br *bits.BitReader, if mbPartPredMode == intra4x4 { for luma4x4BlkIdx := 0; luma4x4BlkIdx < 16; luma4x4BlkIdx++ { var v int - if sliceContext.PPS.EntropyCodingMode == 1 { + if vid.PPS.EntropyCodingMode == 1 { // TODO: 1 bit or ae(v) binarization := NewBinarization( "PrevIntra4x4PredModeFlag", - sliceContext.Slice.Data) + sliceContext.Slice.SliceData) binarization.Decode(sliceContext, br, rbsp) - cabac = initCabac(binarization, sliceContext) + // TODO: fix videostream should be nil. + cabac = initCabac(binarization, nil, sliceContext) _ = cabac logger.Printf("TODO: ae for PevIntra4x4PredModeFlag[%d]\n", luma4x4BlkIdx) } else { @@ -556,15 +557,15 @@ func MbPred(chromaArrayType int, sliceContext *SliceContext, br *bits.BitReader, } v = int(b) } - sliceContext.Slice.Data.PrevIntra4x4PredModeFlag = append( - sliceContext.Slice.Data.PrevIntra4x4PredModeFlag, + sliceContext.Slice.SliceData.PrevIntra4x4PredModeFlag = append( + sliceContext.Slice.SliceData.PrevIntra4x4PredModeFlag, v) - if sliceContext.Slice.Data.PrevIntra4x4PredModeFlag[luma4x4BlkIdx] == 0 { - if sliceContext.PPS.EntropyCodingMode == 1 { + if sliceContext.Slice.SliceData.PrevIntra4x4PredModeFlag[luma4x4BlkIdx] == 0 { + if vid.PPS.EntropyCodingMode == 1 { // TODO: 3 bits or ae(v) binarization := NewBinarization( "RemIntra4x4PredMode", - sliceContext.Slice.Data) + sliceContext.Slice.SliceData) binarization.Decode(sliceContext, br, rbsp) logger.Printf("TODO: ae for RemIntra4x4PredMode[%d]\n", luma4x4BlkIdx) @@ -575,22 +576,22 @@ func MbPred(chromaArrayType int, sliceContext *SliceContext, br *bits.BitReader, } v = int(b) } - if len(sliceContext.Slice.Data.RemIntra4x4PredMode) < luma4x4BlkIdx { - sliceContext.Slice.Data.RemIntra4x4PredMode = append( - sliceContext.Slice.Data.RemIntra4x4PredMode, - make([]int, luma4x4BlkIdx-len(sliceContext.Slice.Data.RemIntra4x4PredMode)+1)...) + if len(sliceContext.Slice.SliceData.RemIntra4x4PredMode) < luma4x4BlkIdx { + sliceContext.Slice.SliceData.RemIntra4x4PredMode = append( + sliceContext.Slice.SliceData.RemIntra4x4PredMode, + make([]int, luma4x4BlkIdx-len(sliceContext.Slice.SliceData.RemIntra4x4PredMode)+1)...) } - sliceContext.Slice.Data.RemIntra4x4PredMode[luma4x4BlkIdx] = v + sliceContext.Slice.SliceData.RemIntra4x4PredMode[luma4x4BlkIdx] = v } } } if mbPartPredMode == intra8x8 { for luma8x8BlkIdx := 0; luma8x8BlkIdx < 4; luma8x8BlkIdx++ { - sliceContext.Update(sliceContext.Slice.Header, sliceContext.Slice.Data) + sliceContext.Update(sliceContext.Slice.SliceHeader, sliceContext.Slice.SliceData) var v int - if sliceContext.PPS.EntropyCodingMode == 1 { + if vid.PPS.EntropyCodingMode == 1 { // TODO: 1 bit or ae(v) - binarization := NewBinarization("PrevIntra8x8PredModeFlag", sliceContext.Slice.Data) + binarization := NewBinarization("PrevIntra8x8PredModeFlag", sliceContext.Slice.SliceData) binarization.Decode(sliceContext, br, rbsp) logger.Printf("TODO: ae for PrevIntra8x8PredModeFlag[%d]\n", luma8x8BlkIdx) @@ -601,14 +602,14 @@ func MbPred(chromaArrayType int, sliceContext *SliceContext, br *bits.BitReader, } v = int(b) } - sliceContext.Slice.Data.PrevIntra8x8PredModeFlag = append( - sliceContext.Slice.Data.PrevIntra8x8PredModeFlag, v) - if sliceContext.Slice.Data.PrevIntra8x8PredModeFlag[luma8x8BlkIdx] == 0 { - if sliceContext.PPS.EntropyCodingMode == 1 { + sliceContext.Slice.SliceData.PrevIntra8x8PredModeFlag = append( + sliceContext.Slice.SliceData.PrevIntra8x8PredModeFlag, v) + if sliceContext.Slice.SliceData.PrevIntra8x8PredModeFlag[luma8x8BlkIdx] == 0 { + if vid.PPS.EntropyCodingMode == 1 { // TODO: 3 bits or ae(v) binarization := NewBinarization( "RemIntra8x8PredMode", - sliceContext.Slice.Data) + sliceContext.Slice.SliceData) binarization.Decode(sliceContext, br, rbsp) logger.Printf("TODO: ae for RemIntra8x8PredMode[%d]\n", luma8x8BlkIdx) @@ -619,138 +620,138 @@ func MbPred(chromaArrayType int, sliceContext *SliceContext, br *bits.BitReader, } v = int(b) } - if len(sliceContext.Slice.Data.RemIntra8x8PredMode) < luma8x8BlkIdx { - sliceContext.Slice.Data.RemIntra8x8PredMode = append( - sliceContext.Slice.Data.RemIntra8x8PredMode, - make([]int, luma8x8BlkIdx-len(sliceContext.Slice.Data.RemIntra8x8PredMode)+1)...) + if len(sliceContext.Slice.SliceData.RemIntra8x8PredMode) < luma8x8BlkIdx { + sliceContext.Slice.SliceData.RemIntra8x8PredMode = append( + sliceContext.Slice.SliceData.RemIntra8x8PredMode, + make([]int, luma8x8BlkIdx-len(sliceContext.Slice.SliceData.RemIntra8x8PredMode)+1)...) } - sliceContext.Slice.Data.RemIntra8x8PredMode[luma8x8BlkIdx] = v + sliceContext.Slice.SliceData.RemIntra8x8PredMode[luma8x8BlkIdx] = v } } } if chromaArrayType == 1 || chromaArrayType == 2 { - if sliceContext.PPS.EntropyCodingMode == 1 { + if vid.PPS.EntropyCodingMode == 1 { // TODO: ue(v) or ae(v) binarization := NewBinarization( "IntraChromaPredMode", - sliceContext.Slice.Data) + sliceContext.Slice.SliceData) binarization.Decode(sliceContext, br, rbsp) logger.Printf("TODO: ae for IntraChromaPredMode\n") } else { - sliceContext.Slice.Data.IntraChromaPredMode = int(r.readUe()) + sliceContext.Slice.SliceData.IntraChromaPredMode = int(r.readUe()) } } } else if mbPartPredMode != direct { - for mbPartIdx := 0; mbPartIdx < NumMbPart(sliceContext.NALUnit, sliceContext.SPS, sliceContext.Slice.Header, sliceContext.Slice.Data); mbPartIdx++ { - sliceContext.Update(sliceContext.Slice.Header, sliceContext.Slice.Data) - m, err := MbPartPredMode(sliceContext.Slice.Data, sliceType, sliceContext.Slice.Data.MbType, mbPartIdx) + for mbPartIdx := 0; mbPartIdx < NumMbPart(sliceContext.NALUnit, vid.SPS, sliceContext.Slice.SliceHeader, sliceContext.Slice.SliceData); mbPartIdx++ { + sliceContext.Update(sliceContext.Slice.SliceHeader, sliceContext.Slice.SliceData) + m, err := MbPartPredMode(sliceContext.Slice.SliceData, sliceType, sliceContext.Slice.SliceData.MbType, mbPartIdx) if err != nil { return errors.Wrap(err, fmt.Sprintf("could not get mbPartPredMode for loop 1 mbPartIdx: %d", mbPartIdx)) } - if (sliceContext.Slice.Header.NumRefIdxL0ActiveMinus1 > 0 || sliceContext.Slice.Data.MbFieldDecodingFlag != sliceContext.Slice.Header.FieldPic) && m != predL1 { + if (sliceContext.Slice.SliceHeader.NumRefIdxL0ActiveMinus1 > 0 || sliceContext.Slice.SliceData.MbFieldDecodingFlag != sliceContext.Slice.SliceHeader.FieldPic) && m != predL1 { logger.Printf("\tTODO: refIdxL0[%d] te or ae(v)\n", mbPartIdx) - if len(sliceContext.Slice.Data.RefIdxL0) < mbPartIdx { - sliceContext.Slice.Data.RefIdxL0 = append( - sliceContext.Slice.Data.RefIdxL0, make([]int, mbPartIdx-len(sliceContext.Slice.Data.RefIdxL0)+1)...) + if len(sliceContext.Slice.SliceData.RefIdxL0) < mbPartIdx { + sliceContext.Slice.SliceData.RefIdxL0 = append( + sliceContext.Slice.SliceData.RefIdxL0, make([]int, mbPartIdx-len(sliceContext.Slice.SliceData.RefIdxL0)+1)...) } - if sliceContext.PPS.EntropyCodingMode == 1 { + if vid.PPS.EntropyCodingMode == 1 { // TODO: te(v) or ae(v) binarization := NewBinarization( "RefIdxL0", - sliceContext.Slice.Data) + sliceContext.Slice.SliceData) binarization.Decode(sliceContext, br, rbsp) logger.Printf("TODO: ae for RefIdxL0[%d]\n", mbPartIdx) } else { // TODO: Only one reference picture is used for inter-prediction, // then the value should be 0 - if MbaffFrameFlag(sliceContext.SPS, sliceContext.Slice.Header) == 0 || !sliceContext.Slice.Data.MbFieldDecodingFlag { - sliceContext.Slice.Data.RefIdxL0[mbPartIdx] = int(r.readTe(uint(sliceContext.Slice.Header.NumRefIdxL0ActiveMinus1))) + if MbaffFrameFlag(vid.SPS, sliceContext.Slice.SliceHeader) == 0 || !sliceContext.Slice.SliceData.MbFieldDecodingFlag { + sliceContext.Slice.SliceData.RefIdxL0[mbPartIdx] = int(r.readTe(uint(sliceContext.Slice.SliceHeader.NumRefIdxL0ActiveMinus1))) } else { - rangeMax := 2*sliceContext.Slice.Header.NumRefIdxL0ActiveMinus1 + 1 - sliceContext.Slice.Data.RefIdxL0[mbPartIdx] = int(r.readTe(uint(rangeMax))) + rangeMax := 2*sliceContext.Slice.SliceHeader.NumRefIdxL0ActiveMinus1 + 1 + sliceContext.Slice.SliceData.RefIdxL0[mbPartIdx] = int(r.readTe(uint(rangeMax))) } } } } - for mbPartIdx := 0; mbPartIdx < NumMbPart(sliceContext.NALUnit, sliceContext.SPS, sliceContext.Slice.Header, sliceContext.Slice.Data); mbPartIdx++ { - m, err := MbPartPredMode(sliceContext.Slice.Data, sliceType, sliceContext.Slice.Data.MbType, mbPartIdx) + for mbPartIdx := 0; mbPartIdx < NumMbPart(sliceContext.NALUnit, vid.SPS, sliceContext.Slice.SliceHeader, sliceContext.Slice.SliceData); mbPartIdx++ { + m, err := MbPartPredMode(sliceContext.Slice.SliceData, sliceType, sliceContext.Slice.SliceData.MbType, mbPartIdx) if err != nil { return errors.Wrap(err, fmt.Sprintf("could not get mbPartPredMode for loop 2 mbPartIdx: %d", mbPartIdx)) } if m != predL1 { for compIdx := 0; compIdx < 2; compIdx++ { - if len(sliceContext.Slice.Data.MvdL0) < mbPartIdx { - sliceContext.Slice.Data.MvdL0 = append( - sliceContext.Slice.Data.MvdL0, - make([][][]int, mbPartIdx-len(sliceContext.Slice.Data.MvdL0)+1)...) + if len(sliceContext.Slice.SliceData.MvdL0) < mbPartIdx { + sliceContext.Slice.SliceData.MvdL0 = append( + sliceContext.Slice.SliceData.MvdL0, + make([][][]int, mbPartIdx-len(sliceContext.Slice.SliceData.MvdL0)+1)...) } - if len(sliceContext.Slice.Data.MvdL0[mbPartIdx][0]) < compIdx { - sliceContext.Slice.Data.MvdL0[mbPartIdx][0] = append( - sliceContext.Slice.Data.MvdL0[mbPartIdx][0], - make([]int, compIdx-len(sliceContext.Slice.Data.MvdL0[mbPartIdx][0])+1)...) + if len(sliceContext.Slice.SliceData.MvdL0[mbPartIdx][0]) < compIdx { + sliceContext.Slice.SliceData.MvdL0[mbPartIdx][0] = append( + sliceContext.Slice.SliceData.MvdL0[mbPartIdx][0], + make([]int, compIdx-len(sliceContext.Slice.SliceData.MvdL0[mbPartIdx][0])+1)...) } - if sliceContext.PPS.EntropyCodingMode == 1 { + if vid.PPS.EntropyCodingMode == 1 { // TODO: se(v) or ae(v) if compIdx == 0 { binarization := NewBinarization( "MvdLnEnd0", - sliceContext.Slice.Data) + sliceContext.Slice.SliceData) binarization.Decode(sliceContext, br, rbsp) } else if compIdx == 1 { binarization := NewBinarization( "MvdLnEnd1", - sliceContext.Slice.Data) + sliceContext.Slice.SliceData) binarization.Decode(sliceContext, br, rbsp) } logger.Printf("TODO: ae for MvdL0[%d][0][%d]\n", mbPartIdx, compIdx) } else { - sliceContext.Slice.Data.MvdL0[mbPartIdx][0][compIdx], _ = readSe(br) + sliceContext.Slice.SliceData.MvdL0[mbPartIdx][0][compIdx], _ = readSe(br) } } } } - for mbPartIdx := 0; mbPartIdx < NumMbPart(sliceContext.NALUnit, sliceContext.SPS, sliceContext.Slice.Header, sliceContext.Slice.Data); mbPartIdx++ { - sliceContext.Update(sliceContext.Slice.Header, sliceContext.Slice.Data) - m, err := MbPartPredMode(sliceContext.Slice.Data, sliceType, sliceContext.Slice.Data.MbType, mbPartIdx) + for mbPartIdx := 0; mbPartIdx < NumMbPart(sliceContext.NALUnit, vid.SPS, sliceContext.Slice.SliceHeader, sliceContext.Slice.SliceData); mbPartIdx++ { + sliceContext.Update(sliceContext.Slice.SliceHeader, sliceContext.Slice.SliceData) + m, err := MbPartPredMode(sliceContext.Slice.SliceData, sliceType, sliceContext.Slice.SliceData.MbType, mbPartIdx) if err != nil { return errors.Wrap(err, fmt.Sprintf("could not get mbPartPredMode for loop 3 mbPartIdx: %d", mbPartIdx)) } if m != predL0 { for compIdx := 0; compIdx < 2; compIdx++ { - if len(sliceContext.Slice.Data.MvdL1) < mbPartIdx { - sliceContext.Slice.Data.MvdL1 = append( - sliceContext.Slice.Data.MvdL1, - make([][][]int, mbPartIdx-len(sliceContext.Slice.Data.MvdL1)+1)...) + if len(sliceContext.Slice.SliceData.MvdL1) < mbPartIdx { + sliceContext.Slice.SliceData.MvdL1 = append( + sliceContext.Slice.SliceData.MvdL1, + make([][][]int, mbPartIdx-len(sliceContext.Slice.SliceData.MvdL1)+1)...) } - if len(sliceContext.Slice.Data.MvdL1[mbPartIdx][0]) < compIdx { - sliceContext.Slice.Data.MvdL1[mbPartIdx][0] = append( - sliceContext.Slice.Data.MvdL0[mbPartIdx][0], - make([]int, compIdx-len(sliceContext.Slice.Data.MvdL1[mbPartIdx][0])+1)...) + if len(sliceContext.Slice.SliceData.MvdL1[mbPartIdx][0]) < compIdx { + sliceContext.Slice.SliceData.MvdL1[mbPartIdx][0] = append( + sliceContext.Slice.SliceData.MvdL0[mbPartIdx][0], + make([]int, compIdx-len(sliceContext.Slice.SliceData.MvdL1[mbPartIdx][0])+1)...) } - if sliceContext.PPS.EntropyCodingMode == 1 { + if vid.PPS.EntropyCodingMode == 1 { if compIdx == 0 { binarization := NewBinarization( "MvdLnEnd0", - sliceContext.Slice.Data) + sliceContext.Slice.SliceData) binarization.Decode(sliceContext, br, rbsp) } else if compIdx == 1 { binarization := NewBinarization( "MvdLnEnd1", - sliceContext.Slice.Data) + sliceContext.Slice.SliceData) binarization.Decode(sliceContext, br, rbsp) } // TODO: se(v) or ae(v) logger.Printf("TODO: ae for MvdL1[%d][0][%d]\n", mbPartIdx, compIdx) } else { - sliceContext.Slice.Data.MvdL1[mbPartIdx][0][compIdx], _ = readSe(br) + sliceContext.Slice.SliceData.MvdL1[mbPartIdx][0][compIdx], _ = readSe(br) } } } @@ -873,47 +874,47 @@ func MbaffFrameFlag(sps *SPS, header *SliceHeader) int { return 0 } -func NewSliceData(chromaArrayType int, sliceContext *SliceContext, br *bits.BitReader) (*SliceData, error) { +func NewSliceData(chromaArrayType int, vid *VideoStream, sliceContext *SliceContext, br *bits.BitReader) (*SliceData, error) { r := newFieldReader(br) var cabac *CABAC - sliceContext.Slice.Data = &SliceData{BitReader: br} + sliceContext.Slice.SliceData = &SliceData{BitReader: br} // TODO: Why is this being initialized here? // initCabac(sliceContext) - if sliceContext.PPS.EntropyCodingMode == 1 { + if vid.PPS.EntropyCodingMode == 1 { for !br.ByteAligned() { b, err := br.ReadBits(1) if err != nil { return nil, errors.Wrap(err, "could not read CabacAlignmentOneBit") } - sliceContext.Slice.Data.CabacAlignmentOneBit = int(b) + sliceContext.Slice.SliceData.CabacAlignmentOneBit = int(b) } } mbaffFrameFlag := 0 - if sliceContext.SPS.MBAdaptiveFrameFieldFlag && !sliceContext.Slice.Header.FieldPic { + if vid.SPS.MBAdaptiveFrameFieldFlag && !sliceContext.Slice.SliceHeader.FieldPic { mbaffFrameFlag = 1 } - currMbAddr := sliceContext.Slice.Header.FirstMbInSlice * (1 * mbaffFrameFlag) + currMbAddr := sliceContext.Slice.SliceHeader.FirstMbInSlice * (1 * mbaffFrameFlag) moreDataFlag := true prevMbSkipped := 0 - sliceContext.Slice.Data.SliceTypeName = sliceTypeMap[sliceContext.Slice.Header.SliceType] - sliceContext.Slice.Data.MbTypeName = MbTypeName(sliceContext.Slice.Data.SliceTypeName, sliceContext.Slice.Data.MbType) + sliceContext.Slice.SliceData.SliceTypeName = sliceTypeMap[sliceContext.Slice.SliceHeader.SliceType] + sliceContext.Slice.SliceData.MbTypeName = MbTypeName(sliceContext.Slice.SliceData.SliceTypeName, sliceContext.Slice.SliceData.MbType) logger.Printf("debug: \tSliceData: Processing moreData: %v\n", moreDataFlag) for moreDataFlag { - logger.Printf("debug: \tLooking for more sliceContext.Slice.Data in slice type %s\n", sliceContext.Slice.Data.SliceTypeName) - if sliceContext.Slice.Data.SliceTypeName != "I" && sliceContext.Slice.Data.SliceTypeName != "SI" { + logger.Printf("debug: \tLooking for more sliceContext.Slice.SliceData in slice type %s\n", sliceContext.Slice.SliceData.SliceTypeName) + if sliceContext.Slice.SliceData.SliceTypeName != "I" && sliceContext.Slice.SliceData.SliceTypeName != "SI" { logger.Printf("debug: \tNonI/SI slice, processing moreData\n") - if sliceContext.PPS.EntropyCodingMode == 0 { - sliceContext.Slice.Data.MbSkipRun = int(r.readUe()) + if vid.PPS.EntropyCodingMode == 0 { + sliceContext.Slice.SliceData.MbSkipRun = int(r.readUe()) - if sliceContext.Slice.Data.MbSkipRun > 0 { + if sliceContext.Slice.SliceData.MbSkipRun > 0 { prevMbSkipped = 1 } - for i := 0; i < sliceContext.Slice.Data.MbSkipRun; i++ { + for i := 0; i < sliceContext.Slice.SliceData.MbSkipRun; i++ { // nextMbAddress(currMbAdd - currMbAddr = nextMbAddress(currMbAddr, sliceContext.SPS, sliceContext.PPS, sliceContext.Slice.Header) + currMbAddr = nextMbAddress(currMbAddr, vid.SPS, vid.PPS, sliceContext.Slice.SliceHeader) } - if sliceContext.Slice.Data.MbSkipRun > 0 { + if sliceContext.Slice.SliceData.MbSkipRun > 0 { moreDataFlag = moreRBSPData(br) } } else { @@ -921,16 +922,16 @@ func NewSliceData(chromaArrayType int, sliceContext *SliceContext, br *bits.BitR if err != nil { return nil, errors.Wrap(err, "could not read MbSkipFlag") } - sliceContext.Slice.Data.MbSkipFlag = b == 1 + sliceContext.Slice.SliceData.MbSkipFlag = b == 1 - moreDataFlag = !sliceContext.Slice.Data.MbSkipFlag + moreDataFlag = !sliceContext.Slice.SliceData.MbSkipFlag } } if moreDataFlag { if mbaffFrameFlag == 1 && (currMbAddr%2 == 0 || (currMbAddr%2 == 1 && prevMbSkipped == 1)) { - if sliceContext.PPS.EntropyCodingMode == 1 { + if vid.PPS.EntropyCodingMode == 1 { // TODO: ae implementation - binarization := NewBinarization("MbFieldDecodingFlag", sliceContext.Slice.Data) + binarization := NewBinarization("MbFieldDecodingFlag", sliceContext.Slice.SliceData) // TODO: this should take a BitReader where the nil is. binarization.Decode(sliceContext, br, nil) @@ -940,15 +941,15 @@ func NewSliceData(chromaArrayType int, sliceContext *SliceContext, br *bits.BitR if err != nil { return nil, errors.Wrap(err, "could not read MbFieldDecodingFlag") } - sliceContext.Slice.Data.MbFieldDecodingFlag = b == 1 + sliceContext.Slice.SliceData.MbFieldDecodingFlag = b == 1 } } // BEGIN: macroblockLayer() - if sliceContext.PPS.EntropyCodingMode == 1 { + if vid.PPS.EntropyCodingMode == 1 { // TODO: ae implementation - binarization := NewBinarization("MbType", sliceContext.Slice.Data) - cabac = initCabac(binarization, sliceContext) + binarization := NewBinarization("MbType", sliceContext.Slice.SliceData) + cabac = initCabac(binarization, nil, sliceContext) _ = cabac // TODO: remove bytes parameter from this function. binarization.Decode(sliceContext, br, nil) @@ -964,7 +965,7 @@ func NewSliceData(chromaArrayType int, sliceContext *SliceContext, br *bits.BitR if binarization.UseDecodeBypass == 1 { // DecodeBypass logger.Printf("TODO: decodeBypass is set: 9.3.3.2.3") - codIRange, codIOffset, err := initDecodingEngine(sliceContext.Slice.Data.BitReader) + codIRange, codIOffset, err := initDecodingEngine(sliceContext.Slice.SliceData.BitReader) if err != nil { return nil, errors.Wrap(err, "could not initialise decoding engine") } @@ -987,7 +988,7 @@ func NewSliceData(chromaArrayType int, sliceContext *SliceContext, br *bits.BitR } // Bypass decoding codIOffset, _, err = arithmeticDecoder.DecodeBypass( - sliceContext.Slice.Data, + sliceContext.Slice.SliceData, codIRange, codIOffset, ) @@ -1018,9 +1019,9 @@ func NewSliceData(chromaArrayType int, sliceContext *SliceContext, br *bits.BitR logger.Printf("TODO: ae for MBType\n") } else { - sliceContext.Slice.Data.MbType = int(r.readUe()) + sliceContext.Slice.SliceData.MbType = int(r.readUe()) } - if sliceContext.Slice.Data.MbTypeName == "I_PCM" { + if sliceContext.Slice.SliceData.MbTypeName == "I_PCM" { for !br.ByteAligned() { _, err := br.ReadBits(1) if err != nil { @@ -1028,35 +1029,35 @@ func NewSliceData(chromaArrayType int, sliceContext *SliceContext, br *bits.BitR } } // 7-3 p95 - bitDepthY := 8 + sliceContext.SPS.BitDepthLumaMinus8 + bitDepthY := 8 + vid.SPS.BitDepthLumaMinus8 for i := 0; i < 256; i++ { s, err := br.ReadBits(int(bitDepthY)) if err != nil { return nil, errors.Wrap(err, fmt.Sprintf("could not read PcmSampleLuma[%d]", i)) } - sliceContext.Slice.Data.PcmSampleLuma = append( - sliceContext.Slice.Data.PcmSampleLuma, + sliceContext.Slice.SliceData.PcmSampleLuma = append( + sliceContext.Slice.SliceData.PcmSampleLuma, int(s)) } // 9.3.1 p 246 // cabac = initCabac(binarization, sliceContext) // 6-1 p 47 - mbWidthC := 16 / SubWidthC(sliceContext.SPS) - mbHeightC := 16 / SubHeightC(sliceContext.SPS) + mbWidthC := 16 / SubWidthC(vid.SPS) + mbHeightC := 16 / SubHeightC(vid.SPS) // if monochrome - if sliceContext.SPS.ChromaFormatIDC == chromaMonochrome || sliceContext.SPS.SeparateColorPlaneFlag { + if vid.SPS.ChromaFormatIDC == chromaMonochrome || vid.SPS.SeparateColorPlaneFlag { mbWidthC = 0 mbHeightC = 0 } - bitDepthC := 8 + sliceContext.SPS.BitDepthChromaMinus8 + bitDepthC := 8 + vid.SPS.BitDepthChromaMinus8 for i := 0; i < 2*mbWidthC*mbHeightC; i++ { s, err := br.ReadBits(int(bitDepthC)) if err != nil { return nil, errors.Wrap(err, fmt.Sprintf("could not read PcmSampleChroma[%d]", i)) } - sliceContext.Slice.Data.PcmSampleChroma = append( - sliceContext.Slice.Data.PcmSampleChroma, + sliceContext.Slice.SliceData.PcmSampleChroma = append( + sliceContext.Slice.SliceData.PcmSampleChroma, int(s)) } // 9.3.1 p 246 @@ -1064,32 +1065,32 @@ func NewSliceData(chromaArrayType int, sliceContext *SliceContext, br *bits.BitR } else { noSubMbPartSizeLessThan8x8Flag := 1 - m, err := MbPartPredMode(sliceContext.Slice.Data, sliceContext.Slice.Data.SliceTypeName, sliceContext.Slice.Data.MbType, 0) + m, err := MbPartPredMode(sliceContext.Slice.SliceData, sliceContext.Slice.SliceData.SliceTypeName, sliceContext.Slice.SliceData.MbType, 0) if err != nil { return nil, errors.Wrap(err, "could not get mbPartPredMode") } - if sliceContext.Slice.Data.MbTypeName == "I_NxN" && m != intra16x16 && NumMbPart(sliceContext.NALUnit, sliceContext.SPS, sliceContext.Slice.Header, sliceContext.Slice.Data) == 4 { + if sliceContext.Slice.SliceData.MbTypeName == "I_NxN" && m != intra16x16 && NumMbPart(sliceContext.NALUnit, vid.SPS, sliceContext.Slice.SliceHeader, sliceContext.Slice.SliceData) == 4 { logger.Printf("\tTODO: subMbPred\n") /* - subMbType := SubMbPred(sliceContext.Slice.Data.MbType) + subMbType := SubMbPred(sliceContext.Slice.SliceData.MbType) for mbPartIdx := 0; mbPartIdx < 4; mbPartIdx++ { if subMbType[mbPartIdx] != "B_Direct_8x8" { if NumbSubMbPart(subMbType[mbPartIdx]) > 1 { noSubMbPartSizeLessThan8x8Flag = 0 } - } else if !sliceContext.SPS.Direct8x8InferenceFlag { + } else if !vid.SPS.Direct8x8InferenceFlag { noSubMbPartSizeLessThan8x8Flag = 0 } } */ } else { - if sliceContext.PPS.Transform8x8Mode == 1 && sliceContext.Slice.Data.MbTypeName == "I_NxN" { + if vid.PPS.Transform8x8Mode == 1 && sliceContext.Slice.SliceData.MbTypeName == "I_NxN" { // TODO // 1 bit or ae(v) - // If sliceContext.PPS.EntropyCodingMode == 1, use ae(v) - if sliceContext.PPS.EntropyCodingMode == 1 { - binarization := NewBinarization("TransformSize8x8Flag", sliceContext.Slice.Data) - cabac = initCabac(binarization, sliceContext) + // If vid.PPS.EntropyCodingMode == 1, use ae(v) + if vid.PPS.EntropyCodingMode == 1 { + binarization := NewBinarization("TransformSize8x8Flag", sliceContext.Slice.SliceData) + cabac = initCabac(binarization, nil, sliceContext) binarization.Decode(sliceContext, br, nil) logger.Println("TODO: ae(v) for TransformSize8x8Flag") @@ -1098,22 +1099,22 @@ func NewSliceData(chromaArrayType int, sliceContext *SliceContext, br *bits.BitR if err != nil { return nil, errors.Wrap(err, "could not read TransformSize8x8Flag") } - sliceContext.Slice.Data.TransformSize8x8Flag = b == 1 + sliceContext.Slice.SliceData.TransformSize8x8Flag = b == 1 } } // TODO: fix nil argument for. - MbPred(chromaArrayType, sliceContext, br, nil) + MbPred(chromaArrayType, nil, sliceContext, br, nil) } - m, err = MbPartPredMode(sliceContext.Slice.Data, sliceContext.Slice.Data.SliceTypeName, sliceContext.Slice.Data.MbType, 0) + m, err = MbPartPredMode(sliceContext.Slice.SliceData, sliceContext.Slice.SliceData.SliceTypeName, sliceContext.Slice.SliceData.MbType, 0) if err != nil { return nil, errors.Wrap(err, "could not get mbPartPredMode") } if m != intra16x16 { // TODO: me, ae logger.Printf("TODO: CodedBlockPattern pending me/ae implementation\n") - if sliceContext.PPS.EntropyCodingMode == 1 { - binarization := NewBinarization("CodedBlockPattern", sliceContext.Slice.Data) - cabac = initCabac(binarization, sliceContext) + if vid.PPS.EntropyCodingMode == 1 { + binarization := NewBinarization("CodedBlockPattern", sliceContext.Slice.SliceData) + cabac = initCabac(binarization, nil, sliceContext) // TODO: fix nil argument. binarization.Decode(sliceContext, br, nil) @@ -1123,17 +1124,17 @@ func NewSliceData(chromaArrayType int, sliceContext *SliceContext, br *bits.BitR br, uint(chromaArrayType), // TODO: fix this - //MbPartPredMode(sliceContext.Slice.Data, sliceContext.Slice.Data.SliceTypeName, sliceContext.Slice.Data.MbType, 0))) + //MbPartPredMode(sliceContext.Slice.SliceData, sliceContext.Slice.SliceData.SliceTypeName, sliceContext.Slice.SliceData.MbType, 0))) 0) - sliceContext.Slice.Data.CodedBlockPattern = int(me) + sliceContext.Slice.SliceData.CodedBlockPattern = int(me) } - // sliceContext.Slice.Data.CodedBlockPattern = me(v) | ae(v) - if CodedBlockPatternLuma(sliceContext.Slice.Data) > 0 && sliceContext.PPS.Transform8x8Mode == 1 && sliceContext.Slice.Data.MbTypeName != "I_NxN" && noSubMbPartSizeLessThan8x8Flag == 1 && (sliceContext.Slice.Data.MbTypeName != "B_Direct_16x16" || sliceContext.SPS.Direct8x8InferenceFlag) { + // sliceContext.Slice.SliceData.CodedBlockPattern = me(v) | ae(v) + if CodedBlockPatternLuma(sliceContext.Slice.SliceData) > 0 && vid.PPS.Transform8x8Mode == 1 && sliceContext.Slice.SliceData.MbTypeName != "I_NxN" && noSubMbPartSizeLessThan8x8Flag == 1 && (sliceContext.Slice.SliceData.MbTypeName != "B_Direct_16x16" || vid.SPS.Direct8x8InferenceFlag) { // TODO: 1 bit or ae(v) - if sliceContext.PPS.EntropyCodingMode == 1 { - binarization := NewBinarization("Transform8x8Flag", sliceContext.Slice.Data) - cabac = initCabac(binarization, sliceContext) + if vid.PPS.EntropyCodingMode == 1 { + binarization := NewBinarization("Transform8x8Flag", sliceContext.Slice.SliceData) + cabac = initCabac(binarization, nil, sliceContext) // TODO: fix nil argument. binarization.Decode(sliceContext, br, nil) @@ -1143,36 +1144,36 @@ func NewSliceData(chromaArrayType int, sliceContext *SliceContext, br *bits.BitR if err != nil { return nil, errors.Wrap(err, "coult not read TransformSize8x8Flag") } - sliceContext.Slice.Data.TransformSize8x8Flag = b == 1 + sliceContext.Slice.SliceData.TransformSize8x8Flag = b == 1 } } } - m, err = MbPartPredMode(sliceContext.Slice.Data, sliceContext.Slice.Data.SliceTypeName, sliceContext.Slice.Data.MbType, 0) + m, err = MbPartPredMode(sliceContext.Slice.SliceData, sliceContext.Slice.SliceData.SliceTypeName, sliceContext.Slice.SliceData.MbType, 0) if err != nil { return nil, errors.Wrap(err, "could not get mbPartPredMode") } - if CodedBlockPatternLuma(sliceContext.Slice.Data) > 0 || CodedBlockPatternChroma(sliceContext.Slice.Data) > 0 || m == intra16x16 { + if CodedBlockPatternLuma(sliceContext.Slice.SliceData) > 0 || CodedBlockPatternChroma(sliceContext.Slice.SliceData) > 0 || m == intra16x16 { // TODO: se or ae(v) - if sliceContext.PPS.EntropyCodingMode == 1 { - binarization := NewBinarization("MbQpDelta", sliceContext.Slice.Data) - cabac = initCabac(binarization, sliceContext) + if vid.PPS.EntropyCodingMode == 1 { + binarization := NewBinarization("MbQpDelta", sliceContext.Slice.SliceData) + cabac = initCabac(binarization, nil, sliceContext) // TODO; fix nil argument binarization.Decode(sliceContext, br, nil) logger.Printf("TODO: ae for MbQpDelta\n") } else { - sliceContext.Slice.Data.MbQpDelta, _ = readSe(br) + sliceContext.Slice.SliceData.MbQpDelta, _ = readSe(br) } } } } // END MacroblockLayer - if sliceContext.PPS.EntropyCodingMode == 0 { + if vid.PPS.EntropyCodingMode == 0 { moreDataFlag = moreRBSPData(br) } else { - if sliceContext.Slice.Data.SliceTypeName != "I" && sliceContext.Slice.Data.SliceTypeName != "SI" { - if sliceContext.Slice.Data.MbSkipFlag { + if sliceContext.Slice.SliceData.SliceTypeName != "I" && sliceContext.Slice.SliceData.SliceTypeName != "SI" { + if sliceContext.Slice.SliceData.MbSkipFlag { prevMbSkipped = 1 } else { prevMbSkipped = 0 @@ -1186,17 +1187,17 @@ func NewSliceData(chromaArrayType int, sliceContext *SliceContext, br *bits.BitR if err != nil { return nil, errors.Wrap(err, "could not read EndOfSliceFlag") } - sliceContext.Slice.Data.EndOfSliceFlag = b == 1 - moreDataFlag = !sliceContext.Slice.Data.EndOfSliceFlag + sliceContext.Slice.SliceData.EndOfSliceFlag = b == 1 + moreDataFlag = !sliceContext.Slice.SliceData.EndOfSliceFlag } } - currMbAddr = nextMbAddress(currMbAddr, sliceContext.SPS, sliceContext.PPS, sliceContext.Slice.Header) + currMbAddr = nextMbAddress(currMbAddr, vid.SPS, vid.PPS, sliceContext.Slice.SliceHeader) } // END while moreDataFlag - return sliceContext.Slice.Data, nil + return sliceContext.Slice.SliceData, nil } func (c *SliceContext) Update(header *SliceHeader, data *SliceData) { - c.Slice = &Slice{Header: header, Data: data} + c.Slice = &Slice{SliceHeader: header, SliceData: data} } func NewSliceContext(vid *VideoStream, nalUnit *NALUnit, rbsp []byte, showPacket bool) (*SliceContext, error) { var err error @@ -1360,13 +1361,11 @@ func NewSliceContext(vid *VideoStream, nalUnit *NALUnit, rbsp []byte, showPacket sliceContext := &SliceContext{ NALUnit: nalUnit, - SPS: sps, - PPS: pps, Slice: &Slice{ - Header: &header, + SliceHeader: &header, }, } - sliceContext.Slice.Data, err = NewSliceData(vid.ChromaArrayType, sliceContext, br) + sliceContext.Slice.SliceData, err = NewSliceData(vid.ChromaArrayType, nil, sliceContext, br) if err != nil { return nil, errors.Wrap(err, "could not create slice data") }