add ParseSliceHeaderFromNALU()
This commit is contained in:
parent
6b554c9c52
commit
2eb65b8fac
@ -112,12 +112,14 @@ func MakeADTSHeader(config MPEG4AudioConfig, samples int, payloadLength int) (he
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func ExtractADTSFrames(frames []byte) (config MPEG4AudioConfig, payload []byte, samples int, err error) {
|
func ExtractADTSFrames(frames []byte) (config MPEG4AudioConfig, payload [][]byte, samples int, err error) {
|
||||||
for len(frames) > 0 {
|
for len(frames) > 0 {
|
||||||
var n, framelen int
|
var n, framelen int
|
||||||
if config, payload, n, framelen, err = ReadADTSFrame(frames); err != nil {
|
var _payload []byte
|
||||||
|
if config, _payload, n, framelen, err = ReadADTSFrame(frames); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
payload = append(payload, _payload)
|
||||||
frames = frames[framelen:]
|
frames = frames[framelen:]
|
||||||
samples += n
|
samples += n
|
||||||
}
|
}
|
||||||
|
@ -301,9 +301,7 @@ type SPSInfo struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ParseSPS(data []byte) (self SPSInfo, err error) {
|
func ParseSPS(data []byte) (self SPSInfo, err error) {
|
||||||
r := &bits.GolombBitReader{
|
r := &bits.GolombBitReader{R: bytes.NewReader(data)}
|
||||||
R: bytes.NewReader(data),
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err = r.ReadBits(8); err != nil {
|
if _, err = r.ReadBits(8); err != nil {
|
||||||
return
|
return
|
||||||
@ -662,3 +660,69 @@ func ParseAVCDecoderConfRecord(config []byte) (self AVCDecoderConfRecord, err er
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SliceType uint
|
||||||
|
|
||||||
|
func (self SliceType) String() string {
|
||||||
|
switch self {
|
||||||
|
case P:
|
||||||
|
return "P"
|
||||||
|
case B:
|
||||||
|
return "B"
|
||||||
|
case I:
|
||||||
|
return "I"
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
P = iota+1
|
||||||
|
B
|
||||||
|
I
|
||||||
|
)
|
||||||
|
|
||||||
|
func ParseSliceHeaderFromNALU(packet []byte) (sliceType SliceType, err error) {
|
||||||
|
|
||||||
|
if len(packet) <= 1 {
|
||||||
|
err = fmt.Errorf("packet too short to parse slice header")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
nal_unit_type := packet[0]&0x1f
|
||||||
|
switch nal_unit_type {
|
||||||
|
case 1,2,5,19:
|
||||||
|
// slice_layer_without_partitioning_rbsp
|
||||||
|
// slice_data_partition_a_layer_rbsp
|
||||||
|
|
||||||
|
default:
|
||||||
|
err = fmt.Errorf("nal_unit_type=%d has no slice header", nal_unit_type)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
r := &bits.GolombBitReader{R: bytes.NewReader(packet[1:])}
|
||||||
|
|
||||||
|
// first_mb_in_slice
|
||||||
|
if _, err = r.ReadExponentialGolombCode(); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// slice_type
|
||||||
|
var u uint
|
||||||
|
if u, err = r.ReadExponentialGolombCode(); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
switch u {
|
||||||
|
case 0,3,5,8:
|
||||||
|
sliceType = P
|
||||||
|
case 1,6:
|
||||||
|
sliceType = B
|
||||||
|
case 2,4,7,9:
|
||||||
|
sliceType = I
|
||||||
|
default:
|
||||||
|
err = fmt.Errorf("slice_type=%d invalid", u)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user