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