test hls ll
This commit is contained in:
95
format/fmp4/esio/decoderconf.go
Normal file
95
format/fmp4/esio/decoderconf.go
Normal file
@@ -0,0 +1,95 @@
|
||||
package esio
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/deepch/vdk/av"
|
||||
"github.com/deepch/vdk/codec/aacparser"
|
||||
"github.com/deepch/vdk/utils/bits/pio"
|
||||
)
|
||||
|
||||
type DecoderConfigDescriptor struct {
|
||||
ObjectType ObjectType
|
||||
StreamType StreamType
|
||||
BufferSize uint32
|
||||
MaxBitrate uint32
|
||||
AvgBitrate uint32
|
||||
|
||||
AudioSpecific []byte
|
||||
}
|
||||
|
||||
type ObjectType uint8
|
||||
|
||||
// ISO/IEC 14496-1 7.2.6.6.2 Table 5
|
||||
const ObjectTypeAudio = ObjectType(0x40)
|
||||
|
||||
type StreamType uint8
|
||||
|
||||
// ISO/IEC 14496-1 7.2.6.6.2 Table 6
|
||||
const StreamTypeAudioStream = StreamType(0x05)
|
||||
|
||||
func parseDecoderConfig(d []byte) (*DecoderConfigDescriptor, error) {
|
||||
if len(d) < 13 {
|
||||
return nil, errors.New("DecoderConfigDescriptor short")
|
||||
}
|
||||
conf := &DecoderConfigDescriptor{
|
||||
ObjectType: ObjectType(d[0]),
|
||||
StreamType: StreamType(d[1] >> 2),
|
||||
BufferSize: pio.U24BE(d[2:]),
|
||||
MaxBitrate: pio.U32BE(d[5:]),
|
||||
AvgBitrate: pio.U32BE(d[9:]),
|
||||
}
|
||||
d = d[13:]
|
||||
for len(d) > 0 {
|
||||
tag, contents, remainder, err := parseHeader(d)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("DecoderConfigDescriptor: %w", err)
|
||||
}
|
||||
d = remainder
|
||||
switch tag {
|
||||
case TagDecoderSpecificInfo:
|
||||
switch conf.ObjectType {
|
||||
case ObjectTypeAudio:
|
||||
conf.AudioSpecific = contents
|
||||
}
|
||||
}
|
||||
}
|
||||
return conf, nil
|
||||
}
|
||||
|
||||
func (c *DecoderConfigDescriptor) appendTo(b *builder) error {
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
||||
cursor := b.Descriptor(TagDecoderConfigDescriptor)
|
||||
defer cursor.DescriptorDone(-1)
|
||||
b.WriteByte(byte(c.ObjectType))
|
||||
b.WriteByte(byte(c.StreamType<<2) | 1)
|
||||
b.WriteU24(c.BufferSize)
|
||||
b.WriteU32(c.MaxBitrate)
|
||||
b.WriteU32(c.AvgBitrate)
|
||||
switch {
|
||||
case c.AudioSpecific != nil:
|
||||
// ISO/IEC 14496-3
|
||||
// 1.6.2.1 - base AudioSpecificConfig
|
||||
// 4.4.1 - GASpecificConfig
|
||||
// but we don't actually need to inspect this right now so just preserve the bytes
|
||||
c2 := b.Descriptor(TagDecoderSpecificInfo)
|
||||
b.Write(c.AudioSpecific)
|
||||
c2.DescriptorDone(-1)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func DecoderConfigFromCodecData(stream av.CodecData) (*DecoderConfigDescriptor, error) {
|
||||
switch cd := stream.(type) {
|
||||
case aacparser.CodecData:
|
||||
return &DecoderConfigDescriptor{
|
||||
ObjectType: ObjectTypeAudio,
|
||||
StreamType: StreamTypeAudioStream,
|
||||
AudioSpecific: cd.MPEG4AudioConfigBytes(),
|
||||
}, nil
|
||||
}
|
||||
return nil, fmt.Errorf("can't marshal %T to DecoderConfigDescriptor", stream)
|
||||
}
|
||||
Reference in New Issue
Block a user