mirror of https://bitbucket.org/ausocean/av.git
125 lines
3.6 KiB
Go
125 lines
3.6 KiB
Go
|
package h264dec
|
||
|
|
||
|
import (
|
||
|
"math"
|
||
|
|
||
|
"bitbucket.org/ausocean/av/codec/h264/h264dec/bits"
|
||
|
)
|
||
|
|
||
|
// import "strings"
|
||
|
|
||
|
// Specification Page 46 7.3.2.2
|
||
|
|
||
|
type PPS struct {
|
||
|
ID, SPSID int
|
||
|
EntropyCodingMode int
|
||
|
BottomFieldPicOrderInFramePresent bool
|
||
|
NumSliceGroupsMinus1 int
|
||
|
SliceGroupMapType int
|
||
|
RunLengthMinus1 []int
|
||
|
TopLeft []int
|
||
|
BottomRight []int
|
||
|
SliceGroupChangeDirection bool
|
||
|
SliceGroupChangeRateMinus1 int
|
||
|
PicSizeInMapUnitsMinus1 int
|
||
|
SliceGroupId []int
|
||
|
NumRefIdxL0DefaultActiveMinus1 int
|
||
|
NumRefIdxL1DefaultActiveMinus1 int
|
||
|
WeightedPred bool
|
||
|
WeightedBipred int
|
||
|
PicInitQpMinus26 int
|
||
|
PicInitQsMinus26 int
|
||
|
ChromaQpIndexOffset int
|
||
|
DeblockingFilterControlPresent bool
|
||
|
ConstrainedIntraPred bool
|
||
|
RedundantPicCntPresent bool
|
||
|
Transform8x8Mode int
|
||
|
PicScalingMatrixPresent bool
|
||
|
PicScalingListPresent []bool
|
||
|
SecondChromaQpIndexOffset int
|
||
|
}
|
||
|
|
||
|
func NewPPS(br *bits.BitReader, chromaFormat int) (*PPS, error) {
|
||
|
pps := PPS{}
|
||
|
r := newFieldReader(br)
|
||
|
|
||
|
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 = int(r.readUe())
|
||
|
|
||
|
if pps.SliceGroupMapType == 0 {
|
||
|
for iGroup := 0; iGroup <= pps.NumSliceGroupsMinus1; iGroup++ {
|
||
|
pps.RunLengthMinus1 = append(pps.RunLengthMinus1, int(r.readUe()))
|
||
|
}
|
||
|
} else if pps.SliceGroupMapType == 2 {
|
||
|
for iGroup := 0; iGroup < pps.NumSliceGroupsMinus1; iGroup++ {
|
||
|
pps.TopLeft[iGroup] = int(r.readUe())
|
||
|
pps.BottomRight[iGroup] = int(r.readUe())
|
||
|
}
|
||
|
} else if pps.SliceGroupMapType > 2 && pps.SliceGroupMapType < 6 {
|
||
|
pps.SliceGroupChangeDirection = r.readBits(1) == 1
|
||
|
pps.SliceGroupChangeRateMinus1 = int(r.readUe())
|
||
|
} else if pps.SliceGroupMapType == 6 {
|
||
|
pps.PicSizeInMapUnitsMinus1 = int(r.readUe())
|
||
|
|
||
|
for i := 0; i <= pps.PicSizeInMapUnitsMinus1; i++ {
|
||
|
pps.SliceGroupId[i] = int(r.readBits(int(math.Ceil(math.Log2(float64(pps.NumSliceGroupsMinus1 + 1))))))
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
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")
|
||
|
pps.Transform8x8Mode = int(r.readBits(1))
|
||
|
pps.PicScalingMatrixPresent = r.readBits(1) == 1
|
||
|
|
||
|
if pps.PicScalingMatrixPresent {
|
||
|
v := 6
|
||
|
if chromaFormat != chroma444 {
|
||
|
v = 2
|
||
|
}
|
||
|
for i := 0; i < 6+(v*pps.Transform8x8Mode); i++ {
|
||
|
pps.PicScalingListPresent[i] = r.readBits(1) == 1
|
||
|
if pps.PicScalingListPresent[i] {
|
||
|
if i < 6 {
|
||
|
scalingList(
|
||
|
br,
|
||
|
ScalingList4x4[i],
|
||
|
16,
|
||
|
DefaultScalingMatrix4x4[i])
|
||
|
|
||
|
} else {
|
||
|
scalingList(
|
||
|
br,
|
||
|
ScalingList8x8[i],
|
||
|
64,
|
||
|
DefaultScalingMatrix8x8[i-6])
|
||
|
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
pps.SecondChromaQpIndexOffset = r.readSe()
|
||
|
moreRBSPData(br)
|
||
|
// rbspTrailingBits()
|
||
|
}
|
||
|
return &pps, nil
|
||
|
}
|