Merged in nal-extension-types (pull request #216)

codec/h264/h264dec: NAL unit extension types and clean up
This commit is contained in:
Saxon Milton 2019-07-29 04:41:00 +00:00
commit 939fd4853e
4 changed files with 282 additions and 150 deletions

View File

@ -19,6 +19,8 @@ const (
naluTypePrefixNALU naluTypePrefixNALU
naluTypeSubsetSPS naluTypeSubsetSPS
naluTypeDepthParamSet naluTypeDepthParamSet
naluTypeSliceLayerExtRBSP = 20
naluTypeSliceLayerExtRBSP2 = 21
) )
var ( var (

View File

@ -1,161 +1,291 @@
/*
DESCRIPTION
nalunit.go provides structures for a NAL unit as well as it's extensions.
AUTHORS
Saxon Nelson-Milton <saxon@ausocean.org>, The Australian Ocean Laboratory (AusOcean)
mrmod <mcmoranbjr@gmail.com>
*/
package h264dec package h264dec
import ( import (
"bitbucket.org/ausocean/av/codec/h264/h264dec/bits" "fmt"
"io"
"github.com/pkg/errors" "github.com/pkg/errors"
"bitbucket.org/ausocean/av/codec/h264/h264dec/bits"
) )
type NalUnit struct { // MVCExtension describes a NAL unit header multiview video coding extension, as
NumBytes int // defined in section H.7.3.1.1 of the specifications.
ForbiddenZeroBit int // Semantics of fields are specified in section H.7.4.1.1.
RefIdc int type MVCExtension struct {
Type int // non_idr_flag, if true indicates that access unit is not IDR.
SvcExtensionFlag int NonIdrFlag bool
Avc3dExtensionFlag int
IdrFlag int // priority_id, indicates priority of NAL unit. A lower value => higher priority.
PriorityId int PriorityID uint8
NoInterLayerPredFlag int
DependencyId int // view_id, specifies a view identifier for the unit. Units with identical
QualityId int // view_id are in the same view.
TemporalId int ViewID uint32
UseRefBasePicFlag int
DiscardableFlag int // temporal_id, temporal identifier for the unit.
OutputFlag int TemporalID uint8
ReservedThree2Bits int
HeaderBytes int // anchor_pic_flag, if true access unit is an anchor access unit.
NonIdrFlag int AnchorPicFlag bool
ViewId int
AnchorPicFlag int // inter_view_flag, if false current view component not used for inter-view
InterViewFlag int // prediction elsewhere in access unit.
ReservedOneBit int InterViewFlag bool
ViewIdx int
DepthFlag int // reserved_one_bit, always 1 (ignored by decoders)
ReservedOneBit uint8
}
// NewMVCExtension parses a NAL unit header multiview video coding extension
// from br following the syntax structure specified in section H.7.3.1.1, and
// returns as a new MVCExtension.
func NewMVCExtension(br *bits.BitReader) (*MVCExtension, error) {
e := &MVCExtension{}
r := newFieldReader(br)
e.NonIdrFlag = r.readBits(1) == 1
e.PriorityID = uint8(r.readBits(6))
e.ViewID = uint32(r.readBits(10))
e.TemporalID = uint8(r.readBits(3))
e.AnchorPicFlag = r.readBits(1) == 1
e.InterViewFlag = r.readBits(1) == 1
e.ReservedOneBit = uint8(r.readBits(1))
if r.err() != nil {
return nil, fmt.Errorf("error from fieldReader: %v", r.err())
}
return e, nil
}
// ThreeDAVCExtension describes a NAL unit header 3D advanced video coding
// extension, as defined in section J.7.3.1.1 of the specifications.
// For field semantics see section J.7.4.1.1.
type ThreeDAVCExtension struct {
// view_idx, specifies the order index for the NAL i.e. view_id = view_id[view_idx].
ViewIdx uint8
// dpeth_flag, if true indicates NAL part of a depth view component, otherwise
// a texture view component.
DepthFlag bool
// non_idr_flag, if true indicates that access unit is not IDR.
NonIdrFlag bool
// temporal_id, temporal identifier for the unit.
TemporalID uint8
// anchor_pic_flag, if true access unit is an anchor access unit.
AnchorPicFlag bool
// inter_view_flag, if false current view component not used for inter-view
// prediction elsewhere in access unit.
InterViewFlag bool
}
// NewThreeDAVCExtension parses a NAL unit header 3D advanced video coding
// extension from br following the syntax structure specified in section
// J.7.3.1.1, and returns as a new ThreeDAVCExtension.
func NewThreeDAVCExtension(br *bits.BitReader) (*ThreeDAVCExtension, error) {
e := &ThreeDAVCExtension{}
r := newFieldReader(br)
e.ViewIdx = uint8(r.readBits(8))
e.DepthFlag = r.readBits(1) == 1
e.NonIdrFlag = r.readBits(1) == 1
e.TemporalID = uint8(r.readBits(3))
e.AnchorPicFlag = r.readBits(1) == 1
e.InterViewFlag = r.readBits(1) == 1
if r.err() != nil {
return nil, fmt.Errorf("error from fieldReader: %v", r.err())
}
return e, nil
}
// SVCExtension describes a NAL unit header scalable video coding extension, as
// defined in section G.7.3.1.1 of the specifications.
// For field semantics see section G.7.4.1.1.
type SVCExtension struct {
// idr_flag, if true the current coded picture is an IDR picture when
// dependency_id == max(dependency_id) in the coded picture.
IdrFlag bool
// priority_id, specifies priority identifier for unit.
PriorityID uint8
// no_inter_layer_pred_flag, if true inter-layer prediction can't be used for
// decoding slice.
NoInterLayerPredFlag bool
// dependency_id, specifies a dependency identifier for the NAL.
DependencyID uint8
// quality_id, specifies a quality identifier for the NAL.
QualityID uint8
// temporal_id, specifiesa temporal identifier for the NAL.
TemporalID uint8
// use_ref_base_pic_flag, if true indicates reference base pictures and
// decoded pictures are used as references for inter prediction.
UseRefBasePicFlag bool
// discardable_flag, if true, indicates current NAL is not used for decoding
// dependency representations that are part of the current coded picture or
// any subsequent coded picture in decoding order and have a greater
// dependency_id value than current NAL.
DiscardableFlag bool
// output_flag, affects the decoded picture output and removal processes as
// specified in Annex C.
OutputFlag bool
// reserved_three_2bits, equal to 3. Decoders ignore.
ReservedThree2Bits uint8
}
// NewSVCExtension parses a NAL unit header scalable video coding extension from
// br following the syntax structure specified in section G.7.3.1.1, and returns
// as a new SVCExtension.
func NewSVCExtension(br *bits.BitReader) (*SVCExtension, error) {
e := &SVCExtension{}
r := newFieldReader(br)
e.IdrFlag = r.readBits(1) == 1
e.PriorityID = uint8(r.readBits(6))
e.NoInterLayerPredFlag = r.readBits(1) == 1
e.DependencyID = uint8(r.readBits(3))
e.QualityID = uint8(r.readBits(4))
e.TemporalID = uint8(r.readBits(3))
e.UseRefBasePicFlag = r.readBits(1) == 1
e.DiscardableFlag = r.readBits(1) == 1
e.OutputFlag = r.readBits(1) == 1
e.ReservedThree2Bits = uint8(r.readBits(2))
if r.err() != nil {
return nil, fmt.Errorf("error from fieldReader: %v", r.err())
}
return e, nil
}
// NALUnit describes a network abstraction layer unit, as defined in section
// 7.3.1 of the specifications.
// Field semantics are defined in section 7.4.1.
type NALUnit struct {
// forbidden_zero_bit, always 0.
ForbiddenZeroBit uint8
// nal_ref_idc, if not 0 indicates content of NAL contains a sequence parameter
// set, a sequence parameter set extension, a subset sequence parameter set,
// a picture parameter set, a slice of a reference picture, a slice data
// partition of a reference picture, or a prefix NAL preceding a slice of
// a reference picture.
RefIdc uint8
// nal_unit_type, specifies the type of RBSP data contained in the NAL as
// defined in Table 7-1.
Type uint8
// svc_extension_flag, indicates whether a nal_unit_header_svc_extension()
// (G.7.3.1.1) or nal_unit_header_mvc_extension() (H.7.3.1.1) will follow next
// in the syntax structure.
SVCExtensionFlag bool
// avc_3d_extension_flag, for nal_unit_type = 21, indicates that a
// nal_unit_header_mvc_extension() (H.7.3.1.1) or
// nal_unit_header_3davc_extension() (J.7.3.1.1) will follow next in syntax
// structure.
AVC3DExtensionFlag bool
// nal_unit_header_svc_extension() as defined in section G.7.3.1.1.
SVCExtension *SVCExtension
// nal_unit_header_3davc_extension() as defined in section J.7.3.1.1
ThreeDAVCExtension *ThreeDAVCExtension
// nal_unit_header_mvc_extension() as defined in section H.7.3.1.1).
MVCExtension *MVCExtension
// emulation_prevention_three_byte, equal to 0x03 and is discarded by decoder.
EmulationPreventionThreeByte byte EmulationPreventionThreeByte byte
rbsp []byte
// rbsp_byte, the raw byte sequence payload data for the NAL.
RBSP []byte
} }
func NalUnitHeaderSvcExtension(nalUnit *NalUnit, br *bits.BitReader) error { // NewNALUnit parses a network abstraction layer unit from br following the
return readFields(br, []field{ // syntax structure specified in section 7.3.1, and returns as a new NALUnit.
{&nalUnit.IdrFlag, "IdrFlag", 1}, func NewNALUnit(br *bits.BitReader) (*NALUnit, error) {
{&nalUnit.PriorityId, "PriorityId", 6}, n := &NALUnit{}
{&nalUnit.NoInterLayerPredFlag, "NoInterLayerPredFlag", 1}, r := newFieldReader(br)
{&nalUnit.DependencyId, "DependencyId", 3},
{&nalUnit.QualityId, "QualityId", 4},
{&nalUnit.TemporalId, "TemporalId", 3},
{&nalUnit.UseRefBasePicFlag, "UseRefBasePicFlag", 1},
{&nalUnit.DiscardableFlag, "DiscardableFlag", 1},
{&nalUnit.OutputFlag, "OutputFlag", 1},
{&nalUnit.ReservedThree2Bits, "ReservedThree2Bits", 2},
})
}
func NalUnitHeader3davcExtension(nalUnit *NalUnit, br *bits.BitReader) error { n.ForbiddenZeroBit = uint8(r.readBits(1))
return readFields(br, []field{ n.RefIdc = uint8(r.readBits(2))
{&nalUnit.ViewIdx, "ViewIdx", 8}, n.Type = uint8(r.readBits(5))
{&nalUnit.DepthFlag, "DepthFlag", 1},
{&nalUnit.NonIdrFlag, "NonIdrFlag", 1},
{&nalUnit.TemporalId, "TemporalId", 3},
{&nalUnit.AnchorPicFlag, "AnchorPicFlag", 1},
{&nalUnit.InterViewFlag, "InterViewFlag", 1},
})
}
func NalUnitHeaderMvcExtension(nalUnit *NalUnit, br *bits.BitReader) error { var err error
return readFields(br, []field{ if n.Type == naluTypePrefixNALU || n.Type == naluTypeSliceLayerExtRBSP || n.Type == naluTypeSliceLayerExtRBSP2 {
{&nalUnit.NonIdrFlag, "NonIdrFlag", 1}, if n.Type != naluTypeSliceLayerExtRBSP2 {
{&nalUnit.PriorityId, "PriorityId", 6}, n.SVCExtensionFlag = r.readBits(1) == 1
{&nalUnit.ViewId, "ViewId", 10},
{&nalUnit.TemporalId, "TemporalId", 3},
{&nalUnit.AnchorPicFlag, "AnchorPicFlag", 1},
{&nalUnit.InterViewFlag, "InterViewFlag", 1},
{&nalUnit.ReservedOneBit, "ReservedOneBit", 1},
})
}
func (n *NalUnit) RBSP() []byte {
return n.rbsp
}
func NewNalUnit(frame []byte, numBytesInNal int) (*NalUnit, error) {
logger.Printf("debug: reading %d byte NAL\n", numBytesInNal)
nalUnit := NalUnit{
NumBytes: numBytesInNal,
HeaderBytes: 1,
}
// TODO: pass in actual io.Reader to NewBitReader
br := bits.NewBitReader(nil)
err := readFields(br, []field{
{&nalUnit.ForbiddenZeroBit, "ForbiddenZeroBit", 1},
{&nalUnit.RefIdc, "NalRefIdc", 2},
{&nalUnit.Type, "NalUnitType", 5},
})
if err != nil {
return nil, err
}
if nalUnit.Type == 14 || nalUnit.Type == 20 || nalUnit.Type == 21 {
if nalUnit.Type != 21 {
b, err := br.ReadBits(1)
if err != nil {
return nil, errors.Wrap(err, "could not read SvcExtensionFlag")
}
nalUnit.SvcExtensionFlag = int(b)
} else { } else {
b, err := br.ReadBits(1) n.AVC3DExtensionFlag = r.readBits(1) == 1
}
if n.SVCExtensionFlag {
n.SVCExtension, err = NewSVCExtension(br)
if err != nil { if err != nil {
return nil, errors.Wrap(err, "could not read Avc3dExtensionFlag") return nil, errors.Wrap(err, "could not parse SVCExtension")
} }
nalUnit.Avc3dExtensionFlag = int(b) } else if n.AVC3DExtensionFlag {
n.ThreeDAVCExtension, err = NewThreeDAVCExtension(br)
if err != nil {
return nil, errors.Wrap(err, "could not parse ThreeDAVCExtension")
} }
if nalUnit.SvcExtensionFlag == 1 {
NalUnitHeaderSvcExtension(&nalUnit, br)
nalUnit.HeaderBytes += 3
} else if nalUnit.Avc3dExtensionFlag == 1 {
NalUnitHeader3davcExtension(&nalUnit, br)
nalUnit.HeaderBytes += 2
} else { } else {
NalUnitHeaderMvcExtension(&nalUnit, br) n.MVCExtension, err = NewMVCExtension(br)
nalUnit.HeaderBytes += 3 if err != nil {
return nil, errors.Wrap(err, "could not parse MVCExtension")
}
} }
} }
logger.Printf("debug: found %d byte header. Reading body\n", nalUnit.HeaderBytes) for moreRBSPData(br) {
for i := nalUnit.HeaderBytes; i < nalUnit.NumBytes; i++ {
next3Bytes, err := br.PeekBits(24) next3Bytes, err := br.PeekBits(24)
if err != nil {
logger.Printf("error: while reading next 3 NAL bytes: %v\n", err) // If PeekBits cannot get 3 bytes, but there still might be 2 bytes left in
break // the source, we will get an io.EOF; we wish to ignore this and continue.
// The call to moreRBSPData will determine when we have reached the end of
// the NAL unit.
if err != nil && errors.Cause(err) != io.EOF {
return nil, errors.Wrap(err, "could not Peek next 3 bytes")
} }
// Little odd, the err above and the i+2 check might be synonyms
if i+2 < nalUnit.NumBytes && next3Bytes == 0x000003 { if next3Bytes == 0x000003 {
for j := 0; j < 2; j++ { for j := 0; j < 2; j++ {
rbspByte, err := br.ReadBits(8) rbspByte := byte(r.readBits(8))
if err != nil { n.RBSP = append(n.RBSP, byte(rbspByte))
return nil, errors.Wrap(err, "could not read rbspByte")
} }
nalUnit.rbsp = append(nalUnit.rbsp, byte(rbspByte))
}
i += 2
// Read Emulation prevention three byte. // Read Emulation prevention three byte.
eptByte, err := br.ReadBits(8) n.EmulationPreventionThreeByte = byte(r.readBits(8))
if err != nil {
return nil, errors.Wrap(err, "could not read eptByte")
}
nalUnit.EmulationPreventionThreeByte = byte(eptByte)
} else { } else {
if b, err := br.ReadBits(8); err == nil { n.RBSP = append(n.RBSP, byte(r.readBits(8)))
nalUnit.rbsp = append(nalUnit.rbsp, byte(b))
} else {
logger.Printf("error: while reading byte %d of %d nal bytes: %v\n", i, nalUnit.NumBytes, err)
break
}
} }
} }
// nalUnit.rbsp = frame[nalUnit.HeaderBytes:] if r.err() != nil {
logger.Printf("info: decoded %s NAL with %d RBSP bytes\n", NALUnitType[nalUnit.Type], len(nalUnit.rbsp)) return nil, fmt.Errorf("fieldReader error: %v", r.err())
return &nalUnit, nil }
return n, nil
} }

View File

@ -63,7 +63,7 @@ func (h *H264Reader) Start() {
switch nalUnit.Type { switch nalUnit.Type {
case naluTypeSPS: case naluTypeSPS:
// TODO: handle this error // TODO: handle this error
sps, _ := NewSPS(nalUnit.rbsp, false) sps, _ := NewSPS(nalUnit.RBSP, false)
h.VideoStreams = append( h.VideoStreams = append(
h.VideoStreams, h.VideoStreams,
&VideoStream{SPS: sps}, &VideoStream{SPS: sps},
@ -71,20 +71,20 @@ func (h *H264Reader) Start() {
case naluTypePPS: case naluTypePPS:
videoStream := h.VideoStreams[len(h.VideoStreams)-1] videoStream := h.VideoStreams[len(h.VideoStreams)-1]
// TODO: handle this error // TODO: handle this error
videoStream.PPS, _ = NewPPS(videoStream.SPS, nalUnit.RBSP(), false) videoStream.PPS, _ = NewPPS(videoStream.SPS, nalUnit.RBSP, false)
case naluTypeSliceIDRPicture: case naluTypeSliceIDRPicture:
fallthrough fallthrough
case naluTypeSliceNonIDRPicture: case naluTypeSliceNonIDRPicture:
videoStream := h.VideoStreams[len(h.VideoStreams)-1] videoStream := h.VideoStreams[len(h.VideoStreams)-1]
logger.Printf("info: frame number %d\n", len(videoStream.Slices)) logger.Printf("info: frame number %d\n", len(videoStream.Slices))
// TODO: handle this error // TODO: handle this error
sliceContext, _ := NewSliceContext(videoStream, nalUnit, nalUnit.RBSP(), true) sliceContext, _ := NewSliceContext(videoStream, nalUnit, nalUnit.RBSP, true)
videoStream.Slices = append(videoStream.Slices, sliceContext) videoStream.Slices = append(videoStream.Slices, sliceContext)
} }
} }
} }
func (r *H264Reader) readNalUnit() (*NalUnit, *bits.BitReader, error) { func (r *H264Reader) readNalUnit() (*NALUnit, *bits.BitReader, error) {
// Read to start of NAL // Read to start of NAL
logger.Printf("debug: Seeking NAL %d start\n", len(r.NalUnits)) logger.Printf("debug: Seeking NAL %d start\n", len(r.NalUnits))
@ -131,7 +131,7 @@ func (r *H264Reader) readNalUnit() (*NalUnit, *bits.BitReader, error) {
r.NalUnits = append(r.NalUnits, nalUnitReader) r.NalUnits = append(r.NalUnits, nalUnitReader)
// TODO: this should really take an io.Reader rather than []byte. Need to fix nil // TODO: this should really take an io.Reader rather than []byte. Need to fix nil
// once this is fixed. // once this is fixed.
nalUnit, err := NewNalUnit(nil, 0) nalUnit, err := NewNALUnit(nil)
if err != nil { if err != nil {
return nil, nil, errors.Wrap(err, "cannot create new nal unit") return nil, nil, errors.Wrap(err, "cannot create new nal unit")
} }

View File

@ -23,7 +23,7 @@ type VideoStream struct {
Slices []*SliceContext Slices []*SliceContext
} }
type SliceContext struct { type SliceContext struct {
*NalUnit *NALUnit
*SPS *SPS
*PPS *PPS
*Slice *Slice
@ -240,12 +240,12 @@ func CodedBlockPatternChroma(data *SliceData) int {
// dependencyId see Annex G.8.8.1 // dependencyId see Annex G.8.8.1
// Also G7.3.1.1 nal_unit_header_svc_extension // Also G7.3.1.1 nal_unit_header_svc_extension
func DQId(nalUnit *NalUnit) int { func DQId(nalUnit *NALUnit) int {
return (nalUnit.DependencyId << 4) + nalUnit.QualityId return int((nalUnit.SVCExtension.DependencyID << 4)) + int(nalUnit.SVCExtension.QualityID)
} }
// Annex G p527 // Annex G p527
func NumMbPart(nalUnit *NalUnit, sps *SPS, header *SliceHeader, data *SliceData) int { func NumMbPart(nalUnit *NALUnit, sps *SPS, header *SliceHeader, data *SliceData) int {
sliceType := sliceTypeMap[header.SliceType] sliceType := sliceTypeMap[header.SliceType]
numMbPart := 0 numMbPart := 0
if MbTypeName(sliceType, CurrMbAddr(sps, header)) == "B_SKIP" || MbTypeName(sliceType, CurrMbAddr(sps, header)) == "B_Direct_16x16" { if MbTypeName(sliceType, CurrMbAddr(sps, header)) == "B_SKIP" || MbTypeName(sliceType, CurrMbAddr(sps, header)) == "B_Direct_16x16" {
@ -381,7 +381,7 @@ func MbPred(sliceContext *SliceContext, br *bits.BitReader, rbsp []byte) error {
} }
} else if mbPartPredMode != direct { } else if mbPartPredMode != direct {
for mbPartIdx := 0; mbPartIdx < NumMbPart(sliceContext.NalUnit, sliceContext.SPS, sliceContext.Slice.Header, sliceContext.Slice.Data); mbPartIdx++ { for mbPartIdx := 0; mbPartIdx < NumMbPart(sliceContext.NALUnit, sliceContext.SPS, sliceContext.Slice.Header, sliceContext.Slice.Data); mbPartIdx++ {
sliceContext.Update(sliceContext.Slice.Header, sliceContext.Slice.Data) sliceContext.Update(sliceContext.Slice.Header, sliceContext.Slice.Data)
m, err := MbPartPredMode(sliceContext.Slice.Data, sliceType, sliceContext.Slice.Data.MbType, mbPartIdx) m, err := MbPartPredMode(sliceContext.Slice.Data, sliceType, sliceContext.Slice.Data.MbType, mbPartIdx)
if err != nil { if err != nil {
@ -417,7 +417,7 @@ func MbPred(sliceContext *SliceContext, br *bits.BitReader, rbsp []byte) error {
} }
} }
} }
for mbPartIdx := 0; mbPartIdx < NumMbPart(sliceContext.NalUnit, sliceContext.SPS, sliceContext.Slice.Header, sliceContext.Slice.Data); mbPartIdx++ { for mbPartIdx := 0; mbPartIdx < NumMbPart(sliceContext.NALUnit, sliceContext.SPS, sliceContext.Slice.Header, sliceContext.Slice.Data); mbPartIdx++ {
m, err := MbPartPredMode(sliceContext.Slice.Data, sliceType, sliceContext.Slice.Data.MbType, mbPartIdx) m, err := MbPartPredMode(sliceContext.Slice.Data, sliceType, sliceContext.Slice.Data.MbType, mbPartIdx)
if err != nil { if err != nil {
return errors.Wrap(err, fmt.Sprintf("could not get mbPartPredMode for loop 2 mbPartIdx: %d", mbPartIdx)) return errors.Wrap(err, fmt.Sprintf("could not get mbPartPredMode for loop 2 mbPartIdx: %d", mbPartIdx))
@ -456,7 +456,7 @@ func MbPred(sliceContext *SliceContext, br *bits.BitReader, rbsp []byte) error {
} }
} }
} }
for mbPartIdx := 0; mbPartIdx < NumMbPart(sliceContext.NalUnit, sliceContext.SPS, sliceContext.Slice.Header, sliceContext.Slice.Data); mbPartIdx++ { for mbPartIdx := 0; mbPartIdx < NumMbPart(sliceContext.NALUnit, sliceContext.SPS, sliceContext.Slice.Header, sliceContext.Slice.Data); mbPartIdx++ {
sliceContext.Update(sliceContext.Slice.Header, sliceContext.Slice.Data) sliceContext.Update(sliceContext.Slice.Header, sliceContext.Slice.Data)
m, err := MbPartPredMode(sliceContext.Slice.Data, sliceType, sliceContext.Slice.Data.MbType, mbPartIdx) m, err := MbPartPredMode(sliceContext.Slice.Data, sliceType, sliceContext.Slice.Data.MbType, mbPartIdx)
if err != nil { if err != nil {
@ -815,7 +815,7 @@ func NewSliceData(sliceContext *SliceContext, br *bits.BitReader) (*SliceData, e
if err != nil { if err != nil {
return nil, errors.Wrap(err, "could not get mbPartPredMode") return nil, errors.Wrap(err, "could not get mbPartPredMode")
} }
if sliceContext.Slice.Data.MbTypeName == "I_NxN" && m != intra16x16 && NumMbPart(sliceContext.NalUnit, sliceContext.SPS, sliceContext.Slice.Header, sliceContext.Slice.Data) == 4 { if sliceContext.Slice.Data.MbTypeName == "I_NxN" && m != intra16x16 && NumMbPart(sliceContext.NALUnit, sliceContext.SPS, sliceContext.Slice.Header, sliceContext.Slice.Data) == 4 {
logger.Printf("\tTODO: subMbPred\n") logger.Printf("\tTODO: subMbPred\n")
/* /*
subMbType := SubMbPred(sliceContext.Slice.Data.MbType) subMbType := SubMbPred(sliceContext.Slice.Data.MbType)
@ -945,11 +945,11 @@ func NewSliceData(sliceContext *SliceContext, br *bits.BitReader) (*SliceData, e
func (c *SliceContext) Update(header *SliceHeader, data *SliceData) { func (c *SliceContext) Update(header *SliceHeader, data *SliceData) {
c.Slice = &Slice{Header: header, Data: data} c.Slice = &Slice{Header: header, Data: data}
} }
func NewSliceContext(videoStream *VideoStream, nalUnit *NalUnit, rbsp []byte, showPacket bool) (*SliceContext, error) { func NewSliceContext(videoStream *VideoStream, nalUnit *NALUnit, rbsp []byte, showPacket bool) (*SliceContext, error) {
var err error var err error
sps := videoStream.SPS sps := videoStream.SPS
pps := videoStream.PPS pps := videoStream.PPS
logger.Printf("debug: %s RBSP %d bytes %d bits == \n", NALUnitType[nalUnit.Type], len(rbsp), len(rbsp)*8) logger.Printf("debug: %s RBSP %d bytes %d bits == \n", NALUnitType[int(nalUnit.Type)], len(rbsp), len(rbsp)*8)
logger.Printf("debug: \t%#v\n", rbsp[0:8]) logger.Printf("debug: \t%#v\n", rbsp[0:8])
var idrPic bool var idrPic bool
if nalUnit.Type == 5 { if nalUnit.Type == 5 {
@ -974,7 +974,7 @@ func NewSliceContext(videoStream *VideoStream, nalUnit *NalUnit, rbsp []byte, sh
} }
sliceType := sliceTypeMap[header.SliceType] sliceType := sliceTypeMap[header.SliceType]
logger.Printf("debug: %s (%s) slice of %d bytes\n", NALUnitType[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, err = readUe(br)
if err != nil { if err != nil {
return nil, errors.Wrap(err, "could not parse PPSID") return nil, errors.Wrap(err, "could not parse PPSID")
@ -1350,7 +1350,7 @@ func NewSliceContext(videoStream *VideoStream, nalUnit *NalUnit, rbsp []byte, sh
} }
sliceContext := &SliceContext{ sliceContext := &SliceContext{
NalUnit: nalUnit, NALUnit: nalUnit,
SPS: sps, SPS: sps,
PPS: pps, PPS: pps,
Slice: &Slice{ Slice: &Slice{