From 1d6c501bb8c970eaf369796a79d87d7815a0b74d Mon Sep 17 00:00:00 2001 From: Saxon Date: Tue, 30 Jul 2019 10:16:08 +0930 Subject: [PATCH] codec/h264/h264dec: fixed field types in sps.go and corrected code after merge of master into branch --- codec/h264/h264dec/parse.go | 21 +- codec/h264/h264dec/pps.go | 161 ++--------- codec/h264/h264dec/slice.go | 187 +++--------- codec/h264/h264dec/sps.go | 552 ++++++++++-------------------------- 4 files changed, 230 insertions(+), 691 deletions(-) diff --git a/codec/h264/h264dec/parse.go b/codec/h264/h264dec/parse.go index 0763be27..b2981958 100644 --- a/codec/h264/h264dec/parse.go +++ b/codec/h264/h264dec/parse.go @@ -64,11 +64,11 @@ func (r fieldReader) readBits(n int) uint64 { // Exp-Golomb-coded element using method as specified in section 9.1 of ITU-T // H.264 and return as an int. The read does not happen if the fieldReader // has a non-nil error. -func (r fieldReader) readUe() int { +func (r fieldReader) readUe() uint64 { if r.e != nil { return 0 } - var i int + var i uint64 i, r.e = readUe(r.br) return i } @@ -77,11 +77,11 @@ func (r fieldReader) readUe() int { // Exp-Golomb-coded syntax element using method as specified in section 9.1 // and returns as an int. The read does not happen if the fieldReader // has a non-nil error. -func (r fieldReader) readTe(x uint) int { +func (r fieldReader) readTe(x uint) int64 { if r.e != nil { return 0 } - var i int + var i int64 i, r.e = readTe(r.br, x) return i } @@ -122,7 +122,7 @@ func (r fieldReader) err() error { // // TODO: this should return uint, but rest of code needs to be changed for this // to happen. -func readUe(r *bits.BitReader) (int, error) { +func readUe(r *bits.BitReader) (uint64, error) { nZeros := -1 var err error for b := uint64(0); b == 0; nZeros++ { @@ -135,7 +135,7 @@ func readUe(r *bits.BitReader) (int, error) { if err != nil { return 0, err } - return int(math.Pow(float64(2), float64(nZeros)) - 1 + float64(rem)), nil + return uint64(math.Pow(float64(2), float64(nZeros)) - 1 + float64(rem)), nil } // readTe parses a syntax element of te(v) descriptor i.e, truncated @@ -143,9 +143,10 @@ func readUe(r *bits.BitReader) (int, error) { // Rec. ITU-T H.264 (04/2017). // // TODO: this should also return uint. -func readTe(r *bits.BitReader, x uint) (int, error) { +func readTe(r *bits.BitReader, x uint) (int64, error) { if x > 1 { - return readUe(r) + ue, err := readUe(r) + return int64(ue), err } if x == 1 { @@ -181,7 +182,7 @@ func readSe(r *bits.BitReader) (int, error) { // in Rec. ITU-T H.264 (04/2017). func readMe(r *bits.BitReader, chromaArrayType uint, mpm mbPartPredMode) (uint, error) { // Indexes to codedBlockPattern map. - var i1, i2, i3 int + var i1, i2, i3 uint64 // ChromaArrayType selects first index. switch chromaArrayType { @@ -200,7 +201,7 @@ func readMe(r *bits.BitReader, chromaArrayType uint, mpm mbPartPredMode) (uint, } // Need to check that we won't go out of bounds with this index. - if i2 >= len(codedBlockPattern[i1]) { + if int(i2) >= len(codedBlockPattern[i1]) { return 0, errInvalidCodeNum } diff --git a/codec/h264/h264dec/pps.go b/codec/h264/h264dec/pps.go index 1f618c2e..2467a550 100644 --- a/codec/h264/h264dec/pps.go +++ b/codec/h264/h264dec/pps.go @@ -4,7 +4,6 @@ import ( "math" "bitbucket.org/ausocean/av/codec/h264/h264dec/bits" - "github.com/pkg/errors" ) // import "strings" @@ -47,151 +46,54 @@ func NewPPS(sps *SPS, rbsp []byte, showPacket bool) (*PPS, error) { pps := PPS{} // TODO: give this io.Reader br := bits.NewBitReader(nil) + r := newFieldReader(br) - var err error - pps.ID, err = readUe(br) - if err != nil { - return nil, errors.Wrap(err, "could not parse ID") - } - - pps.SPSID, err = readUe(br) - if err != nil { - return nil, errors.Wrap(err, "could not parse SPS ID") - } - - b, err := br.ReadBits(1) - if err != nil { - return nil, errors.Wrap(err, "could not read EntropyCodingMode") - } - pps.EntropyCodingMode = int(b) - - b, err = br.ReadBits(1) - if err != nil { - return nil, errors.Wrap(err, "could not read BottomFieldPicOrderInFramePresent") - } - pps.BottomFieldPicOrderInFramePresent = b == 1 - - pps.NumSliceGroupsMinus1, err = readUe(br) - if err != nil { - return nil, errors.Wrap(err, "could not parse NumSliceGroupsMinus1") - } + pps.ID = int(r.readUe()) + pps.SPSID = int(r.readUe()) + pps.EntropyCodingMode = int(r.readBits(1)) + pps.BottomFieldPicOrderInFramePresent = r.readBits(1) == 1 + pps.NumSliceGroupsMinus1 = int(r.readUe()) if pps.NumSliceGroupsMinus1 > 0 { - pps.SliceGroupMapType, err = readUe(br) - if err != nil { - return nil, errors.Wrap(err, "could not parse SliceGroupMapType") - } + pps.SliceGroupMapType = int(r.readUe()) if pps.SliceGroupMapType == 0 { for iGroup := 0; iGroup <= pps.NumSliceGroupsMinus1; iGroup++ { - pps.RunLengthMinus1[iGroup], err = readUe(br) - if err != nil { - return nil, errors.Wrap(err, "could not parse RunLengthMinus1") - } + pps.RunLengthMinus1[iGroup] = int(r.readUe()) } } else if pps.SliceGroupMapType == 2 { for iGroup := 0; iGroup < pps.NumSliceGroupsMinus1; iGroup++ { - pps.TopLeft[iGroup], err = readUe(br) - if err != nil { - return nil, errors.Wrap(err, "could not parse TopLeft[iGroup]") - } - if err != nil { - return nil, errors.Wrap(err, "could not parse TopLeft[iGroup]") - } - - pps.BottomRight[iGroup], err = readUe(br) - if err != nil { - return nil, errors.Wrap(err, "could not parse BottomRight[iGroup]") - } + pps.TopLeft[iGroup] = int(r.readUe()) + pps.BottomRight[iGroup] = int(r.readUe()) } } else if pps.SliceGroupMapType > 2 && pps.SliceGroupMapType < 6 { - b, err = br.ReadBits(1) - if err != nil { - return nil, errors.Wrap(err, "could not read SliceGroupChangeDirection") - } - pps.SliceGroupChangeDirection = b == 1 - - pps.SliceGroupChangeRateMinus1, err = readUe(br) - if err != nil { - return nil, errors.Wrap(err, "could not parse SliceGroupChangeRateMinus1") - } + pps.SliceGroupChangeDirection = r.readBits(1) == 1 + pps.SliceGroupChangeRateMinus1 = int(r.readUe()) } else if pps.SliceGroupMapType == 6 { - pps.PicSizeInMapUnitsMinus1, err = readUe(br) - if err != nil { - return nil, errors.Wrap(err, "could not parse PicSizeInMapUnitsMinus1") - } + pps.PicSizeInMapUnitsMinus1 = int(r.readUe()) for i := 0; i <= pps.PicSizeInMapUnitsMinus1; i++ { - b, err = br.ReadBits(int(math.Ceil(math.Log2(float64(pps.NumSliceGroupsMinus1 + 1))))) - if err != nil { - return nil, errors.Wrap(err, "coult not read SliceGroupId") - } - pps.SliceGroupId[i] = int(b) + pps.SliceGroupId[i] = int(r.readBits(int(math.Ceil(math.Log2(float64(pps.NumSliceGroupsMinus1 + 1)))))) } } } - pps.NumRefIdxL0DefaultActiveMinus1, err = readUe(br) - if err != nil { - return nil, errors.New("could not parse NumRefIdxL0DefaultActiveMinus1") - } - - pps.NumRefIdxL1DefaultActiveMinus1, err = readUe(br) - if err != nil { - return nil, errors.New("could not parse NumRefIdxL1DefaultActiveMinus1") - } - - b, err = br.ReadBits(1) - if err != nil { - return nil, errors.Wrap(err, "could not read WeightedPred") - } - pps.WeightedPred = b == 1 - - b, err = br.ReadBits(2) - if err != nil { - return nil, errors.Wrap(err, "could not read WeightedBipred") - } - pps.WeightedBipred = int(b) - - pps.PicInitQpMinus26, err = readSe(br) - if err != nil { - return nil, errors.New("could not parse PicInitQpMinus26") - } - - pps.PicInitQsMinus26, err = readSe(br) - if err != nil { - return nil, errors.New("could not parse PicInitQsMinus26") - } - - pps.ChromaQpIndexOffset, err = readSe(br) - if err != nil { - return nil, errors.New("could not parse ChromaQpIndexOffset") - } - - err = readFlags(br, []flag{ - {&pps.DeblockingFilterControlPresent, "DeblockingFilterControlPresent"}, - {&pps.ConstrainedIntraPred, "ConstrainedIntraPred"}, - {&pps.RedundantPicCntPresent, "RedundantPicCntPresent"}, - }) - if err != nil { - return nil, err - } + pps.NumRefIdxL0DefaultActiveMinus1 = int(r.readUe()) + pps.NumRefIdxL1DefaultActiveMinus1 = int(r.readUe()) + pps.WeightedPred = r.readBits(1) == 1 + pps.WeightedBipred = int(r.readBits(2)) + pps.PicInitQpMinus26 = int(r.readSe()) + pps.PicInitQsMinus26 = int(r.readSe()) + pps.ChromaQpIndexOffset = int(r.readSe()) + pps.DeblockingFilterControlPresent = r.readBits(1) == 1 + pps.ConstrainedIntraPred = r.readBits(1) == 1 + pps.RedundantPicCntPresent = r.readBits(1) == 1 logger.Printf("debug: \tChecking for more PPS data") if moreRBSPData(br) { logger.Printf("debug: \tProcessing additional PPS data") - - b, err = br.ReadBits(1) - if err != nil { - return nil, errors.Wrap(err, "could not read Transform8x8Mode") - } - pps.Transform8x8Mode = int(b) - - b, err = br.ReadBits(1) - if err != nil { - return nil, errors.Wrap(err, "could not read PicScalingMatrixPresent") - } - pps.PicScalingMatrixPresent = b == 1 + pps.Transform8x8Mode = int(r.readBits(1)) + pps.PicScalingMatrixPresent = r.readBits(1) == 1 if pps.PicScalingMatrixPresent { v := 6 @@ -199,11 +101,7 @@ func NewPPS(sps *SPS, rbsp []byte, showPacket bool) (*PPS, error) { v = 2 } for i := 0; i < 6+(v*pps.Transform8x8Mode); i++ { - b, err = br.ReadBits(1) - if err != nil { - return nil, errors.Wrap(err, "could not read PicScalingListPresent") - } - pps.PicScalingListPresent[i] = b == 1 + pps.PicScalingListPresent[i] = r.readBits(1) == 1 if pps.PicScalingListPresent[i] { if i < 6 { scalingList( @@ -222,10 +120,7 @@ func NewPPS(sps *SPS, rbsp []byte, showPacket bool) (*PPS, error) { } } } - pps.SecondChromaQpIndexOffset, err = readSe(br) - if err != nil { - return nil, errors.New("could not parse SecondChromaQpIndexOffset") - } + pps.SecondChromaQpIndexOffset = r.readSe() } moreRBSPData(br) // rbspTrailingBits() diff --git a/codec/h264/h264dec/slice.go b/codec/h264/h264dec/slice.go index 0a20c781..4b620cad 100644 --- a/codec/h264/h264dec/slice.go +++ b/codec/h264/h264dec/slice.go @@ -169,22 +169,22 @@ func MbToSliceGroupMap(sps *SPS, pps *PPS, header *SliceHeader) []int { } func PicWidthInMbs(sps *SPS) int { - return sps.PicWidthInMBSMinus1 + 1 + return int(sps.PicWidthInMBSMinus1 + 1) } func PicHeightInMapUnits(sps *SPS) int { - return sps.PicHeightInMapUnitsMinus1 + 1 + return int(sps.PicHeightInMapUnitsMinus1 + 1) } func PicSizeInMapUnits(sps *SPS) int { - return PicWidthInMbs(sps) * PicHeightInMapUnits(sps) + return int(PicWidthInMbs(sps) * PicHeightInMapUnits(sps)) } func FrameHeightInMbs(sps *SPS) int { - return (2 - flagVal(sps.FrameMBSOnlyFlag)) * PicHeightInMapUnits(sps) + return int((2 - flagVal(sps.FrameMBSOnlyFlag)) * PicHeightInMapUnits(sps)) } func PicHeightInMbs(sps *SPS, header *SliceHeader) int { - return FrameHeightInMbs(sps) / (1 + flagVal(header.FieldPic)) + return int(FrameHeightInMbs(sps) / (1 + flagVal(header.FieldPic))) } func PicSizeInMbs(sps *SPS, header *SliceHeader) int { - return PicWidthInMbs(sps) * PicHeightInMbs(sps, header) + return int(PicWidthInMbs(sps) * PicHeightInMbs(sps, header)) } // table 6-1 @@ -262,6 +262,7 @@ func NumMbPart(nalUnit *NALUnit, sps *SPS, header *SliceHeader, data *SliceData) } func MbPred(sliceContext *SliceContext, br *bits.BitReader, rbsp []byte) error { + r := newFieldReader(br) var cabac *CABAC sliceType := sliceTypeMap[sliceContext.Slice.Header.SliceType] mbPartPredMode, err := MbPartPredMode(sliceContext.Slice.Data, sliceType, sliceContext.Slice.Data.MbType, 0) @@ -372,11 +373,7 @@ func MbPred(sliceContext *SliceContext, br *bits.BitReader, rbsp []byte) error { logger.Printf("TODO: ae for IntraChromaPredMode\n") } else { - var err error - sliceContext.Slice.Data.IntraChromaPredMode, err = readUe(br) - if err != nil { - return errors.Wrap(err, "could not parse IntraChromaPredMode") - } + sliceContext.Slice.Data.IntraChromaPredMode = int(r.readUe()) } } @@ -405,14 +402,10 @@ func MbPred(sliceContext *SliceContext, br *bits.BitReader, rbsp []byte) error { // 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], _ = readTe( - br, - uint(sliceContext.Slice.Header.NumRefIdxL0ActiveMinus1)) + sliceContext.Slice.Data.RefIdxL0[mbPartIdx] = int(r.readTe(uint(sliceContext.Slice.Header.NumRefIdxL0ActiveMinus1))) } else { rangeMax := 2*sliceContext.Slice.Header.NumRefIdxL0ActiveMinus1 + 1 - sliceContext.Slice.Data.RefIdxL0[mbPartIdx], _ = readTe( - br, - uint(rangeMax)) + sliceContext.Slice.Data.RefIdxL0[mbPartIdx] = int(r.readTe(uint(rangeMax))) } } } @@ -588,9 +581,9 @@ func nextMbAddress(n int, sps *SPS, pps *PPS, header *SliceHeader) int { // FrameHeightInMbs = (2 - ps.FrameMBSOnlyFlag) * PicHeightInMapUnits picWidthInMbs := sps.PicWidthInMBSMinus1 + 1 picHeightInMapUnits := sps.PicHeightInMapUnitsMinus1 + 1 - frameHeightInMbs := (2 - flagVal(sps.FrameMBSOnlyFlag)) * picHeightInMapUnits + frameHeightInMbs := (2 - flagVal(sps.FrameMBSOnlyFlag)) * int(picHeightInMapUnits) picHeightInMbs := frameHeightInMbs / (1 + flagVal(header.FieldPic)) - picSizeInMbs := picWidthInMbs * picHeightInMbs + picSizeInMbs := int(picWidthInMbs) * picHeightInMbs mbToSliceGroupMap := MbToSliceGroupMap(sps, pps, header) for i < picSizeInMbs && mbToSliceGroupMap[i] != mbToSliceGroupMap[i] { i++ @@ -615,8 +608,8 @@ func MbaffFrameFlag(sps *SPS, header *SliceHeader) int { } func NewSliceData(sliceContext *SliceContext, br *bits.BitReader) (*SliceData, error) { + r := newFieldReader(br) var cabac *CABAC - var err error sliceContext.Slice.Data = &SliceData{BitReader: br} // TODO: Why is this being initialized here? // initCabac(sliceContext) @@ -645,10 +638,7 @@ func NewSliceData(sliceContext *SliceContext, br *bits.BitReader) (*SliceData, e if sliceContext.Slice.Data.SliceTypeName != "I" && sliceContext.Slice.Data.SliceTypeName != "SI" { logger.Printf("debug: \tNonI/SI slice, processing moreData\n") if sliceContext.PPS.EntropyCodingMode == 0 { - sliceContext.Slice.Data.MbSkipRun, err = readUe(br) - if err != nil { - return nil, errors.Wrap(err, "could not parse MbSkipRun") - } + sliceContext.Slice.Data.MbSkipRun = int(r.readUe()) if sliceContext.Slice.Data.MbSkipRun > 0 { prevMbSkipped = 1 @@ -762,10 +752,7 @@ func NewSliceData(sliceContext *SliceContext, br *bits.BitReader) (*SliceData, e logger.Printf("TODO: ae for MBType\n") } else { - sliceContext.Slice.Data.MbType, err = readUe(br) - if err != nil { - return nil, errors.Wrap(err, "could not parse MbType") - } + sliceContext.Slice.Data.MbType = int(r.readUe()) } if sliceContext.Slice.Data.MbTypeName == "I_PCM" { for !br.ByteAligned() { @@ -777,7 +764,7 @@ func NewSliceData(sliceContext *SliceContext, br *bits.BitReader) (*SliceData, e // 7-3 p95 bitDepthY := 8 + sliceContext.SPS.BitDepthLumaMinus8 for i := 0; i < 256; i++ { - s, err := br.ReadBits(bitDepthY) + s, err := br.ReadBits(int(bitDepthY)) if err != nil { return nil, errors.Wrap(err, fmt.Sprintf("could not read PcmSampleLuma[%d]", i)) } @@ -798,7 +785,7 @@ func NewSliceData(sliceContext *SliceContext, br *bits.BitReader) (*SliceData, e bitDepthC := 8 + sliceContext.SPS.BitDepthChromaMinus8 for i := 0; i < 2*mbWidthC*mbHeightC; i++ { - s, err := br.ReadBits(bitDepthC) + s, err := br.ReadBits(int(bitDepthC)) if err != nil { return nil, errors.Wrap(err, fmt.Sprintf("could not read PcmSampleChroma[%d]", i)) } @@ -959,27 +946,17 @@ func NewSliceContext(videoStream *VideoStream, nalUnit *NALUnit, rbsp []byte, sh if sps.SeparateColorPlaneFlag { header.ChromaArrayType = 0 } else { - header.ChromaArrayType = sps.ChromaFormatIDC + header.ChromaArrayType = int(sps.ChromaFormatIDC) } br := bits.NewBitReader(bytes.NewReader(rbsp)) + r := newFieldReader(br) - header.FirstMbInSlice, err = readUe(br) - if err != nil { - return nil, errors.Wrap(err, "could not parse FirstMbInSlice") - } - - header.SliceType, err = readUe(br) - if err != nil { - return nil, errors.Wrap(err, "could not parse SliceType") - } + header.FirstMbInSlice = int(r.readUe()) + header.SliceType = int(r.readUe()) sliceType := sliceTypeMap[header.SliceType] logger.Printf("debug: %s (%s) slice of %d bytes\n", NALUnitType[int(nalUnit.Type)], sliceType, len(rbsp)) - header.PPSID, err = readUe(br) - if err != nil { - return nil, errors.Wrap(err, "could not parse PPSID") - } - + header.PPSID = int(r.readUe()) if sps.SeparateColorPlaneFlag { b, err := br.ReadBits(2) if err != nil { @@ -1004,13 +981,10 @@ func NewSliceContext(videoStream *VideoStream, nalUnit *NALUnit, rbsp []byte, sh } } if idrPic { - header.IDRPicID, err = readUe(br) - if err != nil { - return nil, errors.Wrap(err, "could not parse IDRPicID") - } + header.IDRPicID = int(r.readUe()) } if sps.PicOrderCountType == 0 { - b, err := br.ReadBits(sps.Log2MaxPicOrderCntLSBMin4 + 4) + b, err := br.ReadBits(int(sps.Log2MaxPicOrderCntLSBMin4 + 4)) if err != nil { return nil, errors.Wrap(err, "could not read PicOrderCntLsb") } @@ -1037,10 +1011,7 @@ func NewSliceContext(videoStream *VideoStream, nalUnit *NALUnit, rbsp []byte, sh } } if pps.RedundantPicCntPresent { - header.RedundantPicCnt, err = readUe(br) - if err != nil { - return nil, errors.Wrap(err, "could not parse RedundantPicCnt") - } + header.RedundantPicCnt = int(r.readUe()) } if sliceType == "B" { b, err := br.ReadBits(1) @@ -1057,15 +1028,9 @@ func NewSliceContext(videoStream *VideoStream, nalUnit *NALUnit, rbsp []byte, sh header.NumRefIdxActiveOverride = b == 1 if header.NumRefIdxActiveOverride { - header.NumRefIdxL0ActiveMinus1, err = readUe(br) - if err != nil { - return nil, errors.Wrap(err, "could not parse NumRefIdxL0ActiveMinus1") - } + header.NumRefIdxL0ActiveMinus1 = int(r.readUe()) if sliceType == "B" { - header.NumRefIdxL1ActiveMinus1, err = readUe(br) - if err != nil { - return nil, errors.Wrap(err, "could not parse NumRefIdxL1ActiveMinus1") - } + header.NumRefIdxL1ActiveMinus1 = int(r.readUe()) } } } @@ -1085,21 +1050,12 @@ func NewSliceContext(videoStream *VideoStream, nalUnit *NALUnit, rbsp []byte, sh if header.RefPicListModificationFlagL0 { for header.ModificationOfPicNums != 3 { - header.ModificationOfPicNums, err = readUe(br) - if err != nil { - return nil, errors.Wrap(err, "could not parse ModificationOfPicNums") - } + header.ModificationOfPicNums = int(r.readUe()) if header.ModificationOfPicNums == 0 || header.ModificationOfPicNums == 1 { - header.AbsDiffPicNumMinus1, err = readUe(br) - if err != nil { - return nil, errors.Wrap(err, "could not parse AbsDiffPicNumMinus1") - } + header.AbsDiffPicNumMinus1 = int(r.readUe()) } else if header.ModificationOfPicNums == 2 { - header.LongTermPicNum, err = readUe(br) - if err != nil { - return nil, errors.Wrap(err, "could not parse LongTermPicNum") - } + header.LongTermPicNum = int(r.readUe()) } } } @@ -1114,21 +1070,12 @@ func NewSliceContext(videoStream *VideoStream, nalUnit *NALUnit, rbsp []byte, sh if header.RefPicListModificationFlagL1 { for header.ModificationOfPicNums != 3 { - header.ModificationOfPicNums, err = readUe(br) - if err != nil { - return nil, errors.Wrap(err, "could not parse ModificationOfPicNums") - } + header.ModificationOfPicNums = int(r.readUe()) if header.ModificationOfPicNums == 0 || header.ModificationOfPicNums == 1 { - header.AbsDiffPicNumMinus1, err = readUe(br) - if err != nil { - return nil, errors.Wrap(err, "could not parse AbsDiffPicNumMinus1") - } + header.AbsDiffPicNumMinus1 = int(r.readUe()) } else if header.ModificationOfPicNums == 2 { - header.LongTermPicNum, err = readUe(br) - if err != nil { - return nil, errors.Wrap(err, "could not parse LongTermPicNum") - } + header.LongTermPicNum = int(r.readUe()) } } } @@ -1138,23 +1085,13 @@ func NewSliceContext(videoStream *VideoStream, nalUnit *NALUnit, rbsp []byte, sh if (pps.WeightedPred && (sliceType == "P" || sliceType == "SP")) || (pps.WeightedBipred == 1 && sliceType == "B") { // predWeightTable() - header.LumaLog2WeightDenom, err = readUe(br) - if err != nil { - return nil, errors.Wrap(err, "could not parse LumaLog2WeightDenom") - } + header.LumaLog2WeightDenom = int(r.readUe()) if header.ChromaArrayType != 0 { - header.ChromaLog2WeightDenom, err = readUe(br) - if err != nil { - return nil, errors.Wrap(err, "could not parse ChromaLog2WeightDenom") - } + header.ChromaLog2WeightDenom = int(r.readUe()) } for i := 0; i <= header.NumRefIdxL0ActiveMinus1; i++ { - b, err := br.ReadBits(1) - if err != nil { - return nil, errors.Wrap(err, "could not read LumaWeightL0Flag") - } - header.LumaWeightL0Flag = b == 1 + header.LumaWeightL0Flag = r.readBits(1) == 1 if header.LumaWeightL0Flag { se, err := readSe(br) @@ -1266,69 +1203,37 @@ func NewSliceContext(videoStream *VideoStream, nalUnit *NALUnit, rbsp []byte, sh header.AdaptiveRefPicMarkingModeFlag = b == 1 if header.AdaptiveRefPicMarkingModeFlag { - header.MemoryManagementControlOperation, err = readUe(br) - if err != nil { - return nil, errors.Wrap(err, "could not parse MemoryManagementControlOperation") - } + header.MemoryManagementControlOperation = int(r.readUe()) for header.MemoryManagementControlOperation != 0 { if header.MemoryManagementControlOperation == 1 || header.MemoryManagementControlOperation == 3 { - header.DifferenceOfPicNumsMinus1, err = readUe(br) - if err != nil { - return nil, errors.Wrap(err, "could not parse MemoryManagementControlOperation") - } + header.DifferenceOfPicNumsMinus1 = int(r.readUe()) } if header.MemoryManagementControlOperation == 2 { - header.LongTermPicNum, err = readUe(br) - if err != nil { - return nil, errors.Wrap(err, "could not parse LongTermPicNum") - } + header.LongTermPicNum = int(r.readUe()) } if header.MemoryManagementControlOperation == 3 || header.MemoryManagementControlOperation == 6 { - header.LongTermFrameIdx, err = readUe(br) - if err != nil { - return nil, errors.Wrap(err, "could not parse LongTermFrameIdx") - } + header.LongTermFrameIdx = int(r.readUe()) } if header.MemoryManagementControlOperation == 4 { - header.MaxLongTermFrameIdxPlus1, err = readUe(br) - if err != nil { - return nil, errors.Wrap(err, "could not parse MaxLongTermFrameIdxPlus1") - } + header.MaxLongTermFrameIdxPlus1 = int(r.readUe()) } } } } // end decRefPicMarking } if pps.EntropyCodingMode == 1 && sliceType != "I" && sliceType != "SI" { - header.CabacInit, err = readUe(br) - if err != nil { - return nil, errors.Wrap(err, "could not parse CabacInit") - } - } - header.SliceQpDelta, err = readSe(br) - if err != nil { - return nil, errors.Wrap(err, "could not parse SliceQpDelta") + header.CabacInit = int(r.readUe()) } + header.SliceQpDelta = int(r.readSe()) if sliceType == "SP" || sliceType == "SI" { if sliceType == "SP" { - b, err := br.ReadBits(1) - if err != nil { - return nil, errors.Wrap(err, "could not read SpForSwitch") - } - header.SpForSwitch = b == 1 - } - header.SliceQsDelta, err = readSe(br) - if err != nil { - return nil, errors.Wrap(err, "could not parse SliceQsDelta") + header.SpForSwitch = r.readBits(1) == 1 } + header.SliceQsDelta = int(r.readSe()) } if pps.DeblockingFilterControlPresent { - header.DisableDeblockingFilter, err = readUe(br) - if err != nil { - return nil, errors.Wrap(err, "could not parse DisableDeblockingFilter") - } - + header.DisableDeblockingFilter = int(r.readUe()) if header.DisableDeblockingFilter != 1 { header.SliceAlphaC0OffsetDiv2, err = readSe(br) if err != nil { diff --git a/codec/h264/h264dec/sps.go b/codec/h264/h264dec/sps.go index bd3e1184..2c37746b 100644 --- a/codec/h264/h264dec/sps.go +++ b/codec/h264/h264dec/sps.go @@ -2,6 +2,7 @@ package h264dec import ( "bytes" + "fmt" "bitbucket.org/ausocean/av/codec/h264/h264dec/bits" "github.com/pkg/errors" @@ -63,46 +64,46 @@ var ( // SPS describes a sequence parameter set as defined by section 7.3.2.1.1 in // the Specifications. type SPS struct { - Profile int - Constraint0 int - Constraint1 int - Constraint2 int - Constraint3 int - Constraint4 int - Constraint5 int - LevelIDC int - SPSID int - ChromaFormatIDC int + Profile uint8 + Constraint0 bool + Constraint1 bool + Constraint2 bool + Constraint3 bool + Constraint4 bool + Constraint5 bool + LevelIDC uint8 + SPSID uint64 + ChromaFormatIDC uint64 SeparateColorPlaneFlag bool - BitDepthLumaMinus8 int - BitDepthChromaMinus8 int + BitDepthLumaMinus8 uint64 + BitDepthChromaMinus8 uint64 QPPrimeYZeroTransformBypassFlag bool SeqScalingMatrixPresentFlag bool SeqScalingListPresentFlag []bool - ScalingList4x4 [][]int + ScalingList4x4 [][]uint64 UseDefaultScalingMatrix4x4Flag []bool - ScalingList8x8 [][]int + ScalingList8x8 [][]uint64 UseDefaultScalingMatrix8x8Flag []bool - Log2MaxFrameNumMinus4 int - PicOrderCountType int - Log2MaxPicOrderCntLSBMin4 int + Log2MaxFrameNumMinus4 uint64 + PicOrderCountType uint64 + Log2MaxPicOrderCntLSBMin4 uint64 DeltaPicOrderAlwaysZeroFlag bool - OffsetForNonRefPic int - OffsetForTopToBottomField int - NumRefFramesInPicOrderCntCycle int + OffsetForNonRefPic int64 + OffsetForTopToBottomField int64 + NumRefFramesInPicOrderCntCycle uint64 OffsetForRefFrameList []int - MaxNumRefFrames int + MaxNumRefFrames uint64 GapsInFrameNumValueAllowed bool - PicWidthInMBSMinus1 int - PicHeightInMapUnitsMinus1 int + PicWidthInMBSMinus1 uint64 + PicHeightInMapUnitsMinus1 uint64 FrameMBSOnlyFlag bool MBAdaptiveFrameFieldFlag bool Direct8x8InferenceFlag bool FrameCroppingFlag bool - FrameCropLeftOffset int - FrameCropRightOffset int - FrameCropTopOffset int - FrameCropBottomOffset int + FrameCropLeftOffset uint64 + FrameCropRightOffset uint64 + FrameCropTopOffset uint64 + FrameCropBottomOffset uint64 VUIParametersPresentFlag bool VUIParameters *VUIParameters } @@ -115,76 +116,33 @@ func NewSPS(rbsp []byte, showPacket bool) (*SPS, error) { logger.Printf("debug: \t%#v\n", rbsp[0:8]) sps := SPS{} br := bits.NewBitReader(bytes.NewReader(rbsp)) - var err error + r := newFieldReader(br) - err = readFields(br, - []field{ - {&sps.Profile, "ProfileIDC", 8}, - {&sps.Constraint0, "Constraint0", 1}, - {&sps.Constraint1, "Constraint1", 1}, - {&sps.Constraint2, "Constraint2", 1}, - {&sps.Constraint3, "Constraint3", 1}, - {&sps.Constraint4, "Constraint4", 1}, - {&sps.Constraint5, "Constraint5", 1}, - }, - ) - - _, err = br.ReadBits(2) - if err != nil { - return nil, errors.Wrap(err, "could not read ReservedZeroBits") - } - - b, err := br.ReadBits(8) - if err != nil { - return nil, errors.Wrap(err, "could not read Level") - } - sps.LevelIDC = int(b) - - // sps.ID = b.NextField("SPSID", 6) // proper - sps.SPSID, err = readUe(br) - if err != nil { - return nil, errors.Wrap(err, "could not parse ID") - } - - sps.ChromaFormatIDC, err = readUe(br) - if err != nil { - return nil, errors.Wrap(err, "could not parse ChromaFormatIDC") - } + sps.Profile = uint8(r.readBits(8)) + sps.Constraint0 = r.readBits(1) == 1 + sps.Constraint1 = r.readBits(1) == 1 + sps.Constraint2 = r.readBits(1) == 1 + sps.Constraint3 = r.readBits(1) == 1 + sps.Constraint4 = r.readBits(1) == 1 + sps.Constraint5 = r.readBits(1) == 1 + r.readBits(2) // 2 reserved bits. + sps.LevelIDC = uint8(r.readBits(8)) + sps.SPSID = r.readUe() + sps.ChromaFormatIDC = r.readUe() // This should be done only for certain ProfileIDC: isProfileIDC := []int{100, 110, 122, 244, 44, 83, 86, 118, 128, 138, 139, 134, 135} // SpecialProfileCase1 - if isInList(isProfileIDC, sps.Profile) { + if isInList(isProfileIDC, int(sps.Profile)) { if sps.ChromaFormatIDC == chroma444 { // TODO: should probably deal with error here. - b, err := br.ReadBits(1) - if err != nil { - return nil, errors.Wrap(err, "could not read UseSeparateColorPlaneFlag") - } - sps.SeparateColorPlaneFlag = b == 1 + sps.SeparateColorPlaneFlag = r.readBits(1) == 1 } - sps.BitDepthLumaMinus8, err = readUe(br) - if err != nil { - return nil, errors.Wrap(err, "could not parse BitDepthLumaMinus8") - } - - sps.BitDepthChromaMinus8, err = readUe(br) - if err != nil { - return nil, errors.Wrap(err, "could not parse BitDepthChromaMinus8") - } - - b, err := br.ReadBits(1) - if err != nil { - return nil, errors.Wrap(err, "could not read QPrimeYZeroTransformBypass") - } - sps.QPPrimeYZeroTransformBypassFlag = b == 1 - - b, err = br.ReadBits(1) - if err != nil { - return nil, errors.Wrap(err, "could not read SeqScalingMatrixPresent") - } - sps.SeqScalingMatrixPresentFlag = b == 1 + sps.BitDepthLumaMinus8 = r.readUe() + sps.BitDepthChromaMinus8 = r.readUe() + sps.QPPrimeYZeroTransformBypassFlag = r.readBits(1) == 1 + sps.SeqScalingMatrixPresentFlag = r.readBits(1) == 1 if sps.SeqScalingMatrixPresentFlag { max := 12 @@ -193,11 +151,7 @@ func NewSPS(rbsp []byte, showPacket bool) (*SPS, error) { } logger.Printf("debug: \tbuilding Scaling matrix for %d elements\n", max) for i := 0; i < max; i++ { - b, err := br.ReadBits(1) - if err != nil { - return nil, errors.Wrap(err, "could not read SeqScalingList") - } - sps.SeqScalingListPresentFlag = append(sps.SeqScalingListPresentFlag, b == 1) + sps.SeqScalingListPresentFlag = append(sps.SeqScalingListPresentFlag, r.readBits(1) == 1) if sps.SeqScalingListPresentFlag[i] { if i < 6 { @@ -223,125 +177,44 @@ func NewSPS(rbsp []byte, showPacket bool) (*SPS, error) { // showSPS() // return sps // Possibly wrong due to no scaling list being built - sps.Log2MaxFrameNumMinus4, err = readUe(br) - if err != nil { - return nil, errors.Wrap(err, "could not parse Log2MaxFrameNumMinus4") - } - - sps.PicOrderCountType, err = readUe(br) - if err != nil { - return nil, errors.Wrap(err, "could not parse PicOrderCountType") - } + sps.Log2MaxFrameNumMinus4 = r.readUe() + sps.PicOrderCountType = r.readUe() if sps.PicOrderCountType == 0 { - sps.Log2MaxPicOrderCntLSBMin4, err = readUe(br) - if err != nil { - return nil, errors.Wrap(err, "could not parse Log2MaxPicOrderCntLSBMin4") - } + sps.Log2MaxPicOrderCntLSBMin4 = r.readUe() } else if sps.PicOrderCountType == 1 { - b, err = br.ReadBits(1) - if err != nil { - return nil, errors.Wrap(err, "could not read DeltaPicOrderAlwaysZero") - } - sps.DeltaPicOrderAlwaysZeroFlag = b == 1 + sps.DeltaPicOrderAlwaysZeroFlag = r.readBits(1) == 1 + sps.OffsetForNonRefPic = int64(r.readSe()) + sps.OffsetForTopToBottomField = int64(r.readSe()) + sps.NumRefFramesInPicOrderCntCycle = r.readUe() - sps.OffsetForNonRefPic, err = readSe(br) - if err != nil { - return nil, errors.Wrap(err, "could not parse OffsetForNonRefPic") - } - - sps.OffsetForTopToBottomField, err = readSe(br) - if err != nil { - return nil, errors.Wrap(err, "could not parse OffsetForTopToBottomField") - } - - sps.NumRefFramesInPicOrderCntCycle, err = readUe(br) - if err != nil { - return nil, errors.Wrap(err, "could not parse NumRefFramesInPicOrderCntCycle") - } - - for i := 0; i < sps.NumRefFramesInPicOrderCntCycle; i++ { - se, err := readSe(br) - if err != nil { - return nil, errors.Wrap(err, "could not parse OffsetForRefFrameList") - } - sps.OffsetForRefFrameList = append( - sps.OffsetForRefFrameList, - se) + for i := 0; i < int(sps.NumRefFramesInPicOrderCntCycle); i++ { + sps.OffsetForRefFrameList = append(sps.OffsetForRefFrameList, r.readSe()) } } - sps.MaxNumRefFrames, err = readUe(br) - if err != nil { - return nil, errors.Wrap(err, "could not parse MaxNumRefFrames") - } - - b, err = br.ReadBits(1) - if err != nil { - return nil, errors.Wrap(err, "could not read GapsInFrameNumValueAllowed") - } - sps.GapsInFrameNumValueAllowed = b == 1 - - sps.PicWidthInMBSMinus1, err = readUe(br) - if err != nil { - return nil, errors.Wrap(err, "could not parse PicWidthInMbsMinus1") - } - - sps.PicHeightInMapUnitsMinus1, err = readUe(br) - if err != nil { - return nil, errors.Wrap(err, "could not parse PicHeightInMapUnitsMinus1") - } - - b, err = br.ReadBits(1) - if err != nil { - return nil, errors.Wrap(err, "could not read FrameMbsOnly") - } - sps.FrameMBSOnlyFlag = b == 1 + sps.MaxNumRefFrames = r.readUe() + sps.GapsInFrameNumValueAllowed = r.readBits(1) == 1 + sps.PicWidthInMBSMinus1 = r.readUe() + sps.PicHeightInMapUnitsMinus1 = r.readUe() + sps.FrameMBSOnlyFlag = r.readBits(1) == 1 if !sps.FrameMBSOnlyFlag { - b, err = br.ReadBits(1) - if err != nil { - return nil, errors.Wrap(err, "could not read MBAdaptiveFrameField") - } - sps.MBAdaptiveFrameFieldFlag = b == 1 + sps.MBAdaptiveFrameFieldFlag = r.readBits(1) == 1 } - err = readFlags(br, []flag{ - {&sps.Direct8x8InferenceFlag, "Direct8x8Inference"}, - {&sps.FrameCroppingFlag, "FrameCropping"}, - }) - if err != nil { - return nil, err - } + sps.Direct8x8InferenceFlag = r.readBits(1) == 1 + sps.FrameCroppingFlag = r.readBits(1) == 1 if sps.FrameCroppingFlag { - sps.FrameCropLeftOffset, err = readUe(br) - if err != nil { - return nil, errors.Wrap(err, "could not parse FrameCropLeftOffset") - } - - sps.FrameCropRightOffset, err = readUe(br) - if err != nil { - return nil, errors.Wrap(err, "could not parse FrameCropRightOffset") - } - - sps.FrameCropTopOffset, err = readUe(br) - if err != nil { - return nil, errors.Wrap(err, "could not parse FrameCropTopOffset") - } - - sps.FrameCropBottomOffset, err = readUe(br) - if err != nil { - return nil, errors.Wrap(err, "could not parse FrameCropBottomOffset") - } + sps.FrameCropLeftOffset = r.readUe() + sps.FrameCropRightOffset = r.readUe() + sps.FrameCropTopOffset = r.readUe() + sps.FrameCropBottomOffset = r.readUe() } - b, err = br.ReadBits(1) - if err != nil { - return nil, errors.Wrap(err, "could not read VuiParametersPresent") - } - sps.VUIParametersPresentFlag = b == 1 + sps.VUIParametersPresentFlag = r.readBits(1) == 1 if sps.VUIParametersPresentFlag { @@ -354,24 +227,24 @@ func NewSPS(rbsp []byte, showPacket bool) (*SPS, error) { // Specifications. type VUIParameters struct { AspectRatioInfoPresentFlag bool - AspectRatioIDC int - SARWidth int - SARHeight int + AspectRatioIDC uint8 + SARWidth uint32 + SARHeight uint32 OverscanInfoPresentFlag bool OverscanAppropriateFlag bool VideoSignalTypePresentFlag bool - VideoFormat int + VideoFormat uint8 VideoFullRangeFlag bool ColorDescriptionPresentFlag bool - ColorPrimaries int - TransferCharacteristics int - MatrixCoefficients int + ColorPrimaries uint8 + TransferCharacteristics uint8 + MatrixCoefficients uint8 ChromaLocInfoPresentFlag bool - ChromaSampleLocTypeTopField int - ChromaSampleLocTypeBottomField int + ChromaSampleLocTypeTopField uint64 + ChromaSampleLocTypeBottomField uint64 TimingInfoPresentFlag bool - NumUnitsInTick int - TimeScale int + NumUnitsInTick uint32 + TimeScale uint32 FixedFrameRateFlag bool NALHRDParametersPresentFlag bool NALHRDParameters *HRDParameters @@ -381,12 +254,12 @@ type VUIParameters struct { PicStructPresentFlag bool BitstreamRestrictionFlag bool MotionVectorsOverPicBoundariesFlag bool - MaxBytesPerPicDenom int - MaxBitsPerMBDenom int - Log2MaxMVLengthHorizontal int - Log2MaxMVLengthVertical int - MaxNumReorderFrames int - MaxDecFrameBuffering int + MaxBytesPerPicDenom uint64 + MaxBitsPerMBDenom uint64 + Log2MaxMVLengthHorizontal uint64 + Log2MaxMVLengthVertical uint64 + MaxNumReorderFrames uint64 + MaxDecFrameBuffering uint64 } // NewVUIParameters parses video usability information parameters from br @@ -394,137 +267,60 @@ type VUIParameters struct { // new VUIParameters. func NewVUIParameters(br *bits.BitReader) (*VUIParameters, error) { p := &VUIParameters{} + r := newFieldReader(br) - b, err := br.ReadBits(1) - if err != nil { - return nil, errors.Wrap(err, "could not read AspectRatioInfoPresent") - } - p.AspectRatioInfoPresentFlag = b == 1 + p.AspectRatioInfoPresentFlag = r.readBits(1) == 1 if p.AspectRatioInfoPresentFlag { - b, err = br.ReadBits(8) - if err != nil { - return nil, errors.Wrap(err, "could not read AspectRatio") - } - p.AspectRatioIDC = int(b) + p.AspectRatioIDC = uint8(r.readBits(8)) EXTENDED_SAR := 999 - if p.AspectRatioIDC == EXTENDED_SAR { - b, err = br.ReadBits(16) - if err != nil { - return nil, errors.Wrap(err, "could not read SarWidth") - } - p.SARWidth = int(b) - - b, err = br.ReadBits(16) - if err != nil { - return nil, errors.Wrap(err, "could not read SarHeight") - } - p.SARHeight = int(b) + if int(p.AspectRatioIDC) == EXTENDED_SAR { + p.SARWidth = uint32(r.readBits(16)) + p.SARHeight = uint32(r.readBits(16)) } } - b, err = br.ReadBits(1) - if err != nil { - return nil, errors.Wrap(err, "could not read OverscanInfoPresent") - } - p.OverscanInfoPresentFlag = b == 1 + p.OverscanInfoPresentFlag = r.readBits(1) == 1 if p.OverscanInfoPresentFlag { - b, err = br.ReadBits(1) - if err != nil { - return nil, errors.Wrap(err, "could not read OverscanAppropriate") - } - p.OverscanAppropriateFlag = b == 1 + p.OverscanAppropriateFlag = r.readBits(1) == 1 } - b, err = br.ReadBits(1) - if err != nil { - return nil, errors.Wrap(err, "could not read VideoSignalTypePresent") - } - p.VideoSignalTypePresentFlag = b == 1 + p.VideoSignalTypePresentFlag = r.readBits(1) == 1 if p.VideoSignalTypePresentFlag { - b, err = br.ReadBits(3) - if err != nil { - return nil, errors.Wrap(err, "could not read VideoFormat") - } - p.VideoFormat = int(b) + p.VideoFormat = uint8(r.readBits(3)) } if p.VideoSignalTypePresentFlag { - b, err = br.ReadBits(1) - if err != nil { - return nil, errors.Wrap(err, "could not read VideoFullRange") - } - p.VideoFullRangeFlag = b == 1 - - b, err = br.ReadBits(1) - if err != nil { - return nil, errors.Wrap(err, "could not read ColorDescriptionPresent") - } - p.ColorDescriptionPresentFlag = b == 1 + p.VideoFullRangeFlag = r.readBits(1) == 1 + p.ColorDescriptionPresentFlag = r.readBits(1) == 1 if p.ColorDescriptionPresentFlag { - err = readFields(br, - []field{ - {&p.ColorPrimaries, "ColorPrimaries", 8}, - {&p.TransferCharacteristics, "TransferCharacteristics", 8}, - {&p.MatrixCoefficients, "MatrixCoefficients", 8}, - }, - ) - if err != nil { - return nil, err - } + p.ColorPrimaries = uint8(r.readBits(8)) + p.TransferCharacteristics = uint8(r.readBits(8)) + p.MatrixCoefficients = uint8(r.readBits(8)) } } - - b, err = br.ReadBits(1) - if err != nil { - return nil, errors.Wrap(err, "could not read ChromaLocInfoPresent") - } - p.ChromaLocInfoPresentFlag = b == 1 + p.ChromaLocInfoPresentFlag = r.readBits(1) == 1 if p.ChromaLocInfoPresentFlag { - p.ChromaSampleLocTypeTopField, err = readUe(br) - if err != nil { - return nil, errors.Wrap(err, "could not parse ChromaSampleLocTypeTopField") - } - - p.ChromaSampleLocTypeBottomField, err = readUe(br) - if err != nil { - return nil, errors.Wrap(err, "could not parse ChromaSampleLocTypeBottomField") - } + p.ChromaSampleLocTypeTopField = uint64(r.readUe()) + p.ChromaSampleLocTypeBottomField = uint64(r.readUe()) } - b, err = br.ReadBits(1) - if err != nil { - return nil, errors.Wrap(err, "could not read TimingInfoPresent") - } - p.TimingInfoPresentFlag = b == 1 + p.TimingInfoPresentFlag = r.readBits(1) == 1 if p.TimingInfoPresentFlag { - err := readFields(br, []field{ - {&p.NumUnitsInTick, "NumUnitsInTick", 32}, - {&p.TimeScale, "TimeScale", 32}, - }) - if err != nil { - return nil, err - } - - b, err = br.ReadBits(1) - if err != nil { - return nil, errors.Wrap(err, "could not read FixedFrameRate") - } - p.FixedFrameRateFlag = b == 1 + p.NumUnitsInTick = uint32(r.readBits(32)) + p.TimeScale = uint32(r.readBits(32)) + p.FixedFrameRateFlag = r.readBits(1) == 1 } - b, err = br.ReadBits(1) - if err != nil { - return nil, errors.Wrap(err, "could not read NalHrdParametersPresent") - } - p.NALHRDParametersPresentFlag = b == 1 + p.NALHRDParametersPresentFlag = r.readBits(1) == 1 + var err error if p.NALHRDParametersPresentFlag { p.NALHRDParameters, err = NewHRDParameters(br) if err != nil { @@ -532,11 +328,7 @@ func NewVUIParameters(br *bits.BitReader) (*VUIParameters, error) { } } - b, err = br.ReadBits(1) - if err != nil { - return nil, errors.Wrap(err, "could not read VclHrdParametersPresent") - } - p.VCLHRDParametersPresentFlag = b == 1 + p.VCLHRDParametersPresentFlag = r.readBits(1) == 1 if p.VCLHRDParametersPresentFlag { p.VCLHRDParameters, err = NewHRDParameters(br) @@ -545,54 +337,20 @@ func NewVUIParameters(br *bits.BitReader) (*VUIParameters, error) { } } if p.NALHRDParametersPresentFlag || p.VCLHRDParametersPresentFlag { - b, err = br.ReadBits(1) - if err != nil { - return nil, errors.Wrap(err, "could not read LowHrdDelay") - } - p.LowDelayHRDFlag = b == 1 + p.LowDelayHRDFlag = r.readBits(1) == 1 } - err = readFlags(br, []flag{ - {&p.PicStructPresentFlag, "PicStructPresent"}, - {&p.BitstreamRestrictionFlag, "BitStreamRestriction"}, - }) + p.PicStructPresentFlag = r.readBits(1) == 1 + p.BitstreamRestrictionFlag = r.readBits(1) == 1 if p.BitstreamRestrictionFlag { - b, err = br.ReadBits(1) - if err != nil { - return nil, errors.Wrap(err, "could not read MotionVectorsOverPicBoundaries") - } - p.MotionVectorsOverPicBoundariesFlag = b == 1 - - p.MaxBytesPerPicDenom, err = readUe(br) - if err != nil { - return nil, errors.Wrap(err, "could not parse MaxBytesPerPicDenom") - } - - p.MaxBitsPerMBDenom, err = readUe(br) - if err != nil { - return nil, errors.Wrap(err, "could not parse MaxBitsPerMbDenom") - } - - p.Log2MaxMVLengthHorizontal, err = readUe(br) - if err != nil { - return nil, errors.Wrap(err, "could not parse Log2MaxMvLengthHorizontal") - } - - p.Log2MaxMVLengthVertical, err = readUe(br) - if err != nil { - return nil, errors.Wrap(err, "could not parse Log2MaxMvLengthVertical") - } - - p.MaxNumReorderFrames, err = readUe(br) - if err != nil { - return nil, errors.Wrap(err, "could not parse MaxNumReorderFrames") - } - - p.MaxDecFrameBuffering, err = readUe(br) - if err != nil { - return nil, errors.Wrap(err, "could not parse MaxDecFrameBuffering") - } + p.MotionVectorsOverPicBoundariesFlag = r.readBits(1) == 1 + p.MaxBytesPerPicDenom = r.readUe() + p.MaxBitsPerMBDenom = r.readUe() + p.Log2MaxMVLengthHorizontal = r.readUe() + p.Log2MaxMVLengthVertical = r.readUe() + p.MaxNumReorderFrames = r.readUe() + p.MaxDecFrameBuffering = r.readUe() } return p, nil } @@ -600,16 +358,16 @@ func NewVUIParameters(br *bits.BitReader) (*VUIParameters, error) { // HRDParameters describes hypothetical reference decoder parameters as defined // by section E.1.2 in the specifications. type HRDParameters struct { - CPBCntMinus1 int - BitRateScale int - CPBSizeScale int - BitRateValueMinus1 []int - CPBSizeValueMinus1 []int + CPBCntMinus1 uint64 + BitRateScale uint8 + CPBSizeScale uint8 + BitRateValueMinus1 []uint64 + CPBSizeValueMinus1 []uint64 CBRFlag []bool - InitialCPBRemovalDelayLenMinus1 int - CPBRemovalDelayLenMinus1 int - DPBOutputDelayLenMinus1 int - TimeOffsetLen int + InitialCPBRemovalDelayLenMinus1 uint8 + CPBRemovalDelayLenMinus1 uint8 + DPBOutputDelayLenMinus1 uint8 + TimeOffsetLen uint8 } // NewHRDParameters parses hypothetical reference decoder parameter from br @@ -617,33 +375,16 @@ type HRDParameters struct { // new HRDParameters. func NewHRDParameters(br *bits.BitReader) (*HRDParameters, error) { h := &HRDParameters{} - var err error - h.CPBCntMinus1, err = readUe(br) - if err != nil { - return nil, errors.Wrap(err, "could not parse CPBCntMinus1") - } + r := newFieldReader(br) - err = readFields(br, []field{ - {&h.BitRateScale, "BitRateScale", 4}, - {&h.CPBSizeScale, "CPBSizeScale", 4}, - }) - if err != nil { - return nil, err - } + h.CPBCntMinus1 = r.readUe() + h.BitRateScale = uint8(r.readBits(4)) + h.CPBSizeScale = uint8(r.readBits(4)) // SchedSelIdx E1.2 - for sseli := 0; sseli <= h.CPBCntMinus1; sseli++ { - ue, err := readUe(br) - if err != nil { - return nil, errors.Wrap(err, "could not parse BitRateValueMinus1") - } - h.BitRateValueMinus1 = append(h.BitRateValueMinus1, ue) - - ue, err = readUe(br) - if err != nil { - return nil, errors.Wrap(err, "could not parse CPBSizeValueMinus1") - } - h.CPBSizeValueMinus1 = append(h.CPBSizeValueMinus1, ue) + for sseli := 0; sseli <= int(h.CPBCntMinus1); sseli++ { + h.BitRateValueMinus1 = append(h.BitRateValueMinus1, r.readUe()) + h.CPBSizeValueMinus1 = append(h.CPBSizeValueMinus1, r.readUe()) if v, _ := br.ReadBits(1); v == 1 { h.CBRFlag = append(h.CBRFlag, true) @@ -651,17 +392,14 @@ func NewHRDParameters(br *bits.BitReader) (*HRDParameters, error) { h.CBRFlag = append(h.CBRFlag, false) } - err = readFields(br, - []field{ - {&h.InitialCPBRemovalDelayLenMinus1, "InitialCPBRemovalDelayLenMinus1", 5}, - {&h.CPBRemovalDelayLenMinus1, "CPBRemovalDelayLenMinus1", 5}, - {&h.DPBOutputDelayLenMinus1, "DpbOutputDelayLenMinus1", 5}, - {&h.TimeOffsetLen, "TimeOffsetLen", 5}, - }, - ) - if err != nil { - return nil, err - } + h.InitialCPBRemovalDelayLenMinus1 = uint8(r.readBits(5)) + h.CPBRemovalDelayLenMinus1 = uint8(r.readBits(5)) + h.DPBOutputDelayLenMinus1 = uint8(r.readBits(5)) + h.TimeOffsetLen = uint8(r.readBits(5)) + } + + if r.err() != nil { + return nil, fmt.Errorf("error from fieldReader: %v", r.err()) } return h, nil }