codec/h264/h264dec: fixed field types in sps.go and corrected code after merge of master into branch

This commit is contained in:
Saxon 2019-07-30 10:16:08 +09:30
parent 8e8dbbaec6
commit 1d6c501bb8
4 changed files with 230 additions and 691 deletions

View File

@ -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
}

View File

@ -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()

View File

@ -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 {

View File

@ -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.FrameCropLeftOffset = r.readUe()
sps.FrameCropRightOffset = r.readUe()
sps.FrameCropTopOffset = r.readUe()
sps.FrameCropBottomOffset = r.readUe()
}
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")
}
}
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.ChromaSampleLocTypeTopField = uint64(r.readUe())
p.ChromaSampleLocTypeBottomField = uint64(r.readUe())
}
p.ChromaSampleLocTypeBottomField, err = readUe(br)
if err != nil {
return nil, errors.Wrap(err, "could not parse ChromaSampleLocTypeBottomField")
}
}
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
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 FixedFrameRate")
}
p.FixedFrameRateFlag = b == 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
}