mirror of https://bitbucket.org/ausocean/av.git
codec/h264/h264dec: fixed field types in sps.go and corrected code after merge of master into branch
This commit is contained in:
parent
8e8dbbaec6
commit
1d6c501bb8
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue