aacparser: adjust func ParseADTSHeader FillADTSHeader

This commit is contained in:
nareix 2016-07-03 22:46:28 +08:00
parent 929adb2829
commit 6536e6f784
4 changed files with 55 additions and 65 deletions

View File

@ -91,36 +91,40 @@ var chanConfigTable = []av.ChannelLayout{
av.CH_FRONT_CENTER|av.CH_FRONT_LEFT|av.CH_FRONT_RIGHT|av.CH_SIDE_LEFT|av.CH_SIDE_RIGHT|av.CH_BACK_LEFT|av.CH_BACK_RIGHT|av.CH_LOW_FREQ, av.CH_FRONT_CENTER|av.CH_FRONT_LEFT|av.CH_FRONT_RIGHT|av.CH_SIDE_LEFT|av.CH_SIDE_RIGHT|av.CH_BACK_LEFT|av.CH_BACK_RIGHT|av.CH_LOW_FREQ,
} }
func IsADTSFrame(frames []byte) bool { func ParseADTSHeader(frame []byte) (config MPEG4AudioConfig, hdrlen int, framelen int, samples int, err error) {
return len(frames) > 7 && frames[0] == 0xff && frames[1]&0xf0 == 0xf0 if frame[0] != 0xff || frame[1]&0xf6 != 0xf0 {
} err = fmt.Errorf("not adts header")
func ReadADTSFrame(frame []byte) (config MPEG4AudioConfig, payload []byte, samples int, framelen int, err error) {
if !IsADTSFrame(frame) {
err = fmt.Errorf("not adts frame")
return return
} }
config.ObjectType = uint(frame[2]>>6) + 1 config.ObjectType = uint(frame[2]>>6) + 1
config.SampleRateIndex = uint(frame[2] >> 2 & 0xf) config.SampleRateIndex = uint(frame[2] >> 2 & 0xf)
config.ChannelConfig = uint(frame[2]<<2&0x4 | frame[3]>>6&0x3) config.ChannelConfig = uint(frame[2]<<2&0x4 | frame[3]>>6&0x3)
config = config.Complete()
framelen = int(frame[3]&0x3)<<11 | int(frame[4])<<3 | int(frame[5]>>5) framelen = int(frame[3]&0x3)<<11 | int(frame[4])<<3 | int(frame[5]>>5)
samples = (int(frame[6]&0x3) + 1) * 1024 samples = (int(frame[6]&0x3) + 1) * 1024
hdrlen := 7 hdrlen = 7
if frame[1]&0x1 == 0 { if frame[1]&0x1 == 0 {
hdrlen = 9 hdrlen = 9
} }
if framelen < hdrlen || len(frame) < framelen { if framelen < hdrlen {
err = fmt.Errorf("invalid adts header length") err = fmt.Errorf("adts framelen < hdrlen")
return return
} }
payload = frame[hdrlen:framelen]
return return
} }
func MakeADTSHeader(config MPEG4AudioConfig, samples int, payloadLength int) (header []byte) { const ADTSHeaderLength = 7
func FillADTSHeader(header []byte, config MPEG4AudioConfig, samples int, payloadLength int) {
payloadLength += 7 payloadLength += 7
//AAAAAAAA AAAABCCD EEFFFFGH HHIJKLMM MMMMMMMM MMMOOOOO OOOOOOPP (QQQQQQQQ QQQQQQQQ) //AAAAAAAA AAAABCCD EEFFFFGH HHIJKLMM MMMMMMMM MMMOOOOO OOOOOOPP (QQQQQQQQ QQQQQQQQ)
header = []byte{0xff, 0xf1, 0x50, 0x80, 0x043, 0xff, 0xcd} header[0] = 0xff
header[1] = 0xf1
header[2] = 0x50
header[3] = 0x80
header[4] = 0x43
header[5] = 0xff
header[6] = 0xcd
//config.ObjectType = uint(frames[2]>>6)+1 //config.ObjectType = uint(frames[2]>>6)+1
//config.SampleRateIndex = uint(frames[2]>>2&0xf) //config.SampleRateIndex = uint(frames[2]>>2&0xf)
//config.ChannelConfig = uint(frames[2]<<2&0x4|frames[3]>>6&0x3) //config.ChannelConfig = uint(frames[2]<<2&0x4|frames[3]>>6&0x3)
@ -133,20 +137,6 @@ func MakeADTSHeader(config MPEG4AudioConfig, samples int, payloadLength int) (he
return return
} }
func SplitADTSFrames(frames []byte) (config MPEG4AudioConfig, payload [][]byte, samples int, err error) {
for len(frames) > 0 {
var n, framelen int
var _payload []byte
if config, _payload, n, framelen, err = ReadADTSFrame(frames); err != nil {
return
}
payload = append(payload, _payload)
frames = frames[framelen:]
samples += n
}
return
}
func readObjectType(r *bits.Reader) (objectType uint, err error) { func readObjectType(r *bits.Reader) (objectType uint, err error) {
if objectType, err = r.ReadBits(5); err != nil { if objectType, err = r.ReadBits(5); err != nil {
return return
@ -209,8 +199,7 @@ func (self MPEG4AudioConfig) IsValid() bool {
return self.ObjectType > 0 return self.ObjectType > 0
} }
func (self MPEG4AudioConfig) Complete() (config MPEG4AudioConfig) { func (self *MPEG4AudioConfig) Complete() (config MPEG4AudioConfig) {
config = self
if int(config.SampleRateIndex) < len(sampleRateTable) { if int(config.SampleRateIndex) < len(sampleRateTable) {
config.SampleRate = sampleRateTable[config.SampleRateIndex] config.SampleRate = sampleRateTable[config.SampleRateIndex]
} }
@ -220,20 +209,10 @@ func (self MPEG4AudioConfig) Complete() (config MPEG4AudioConfig) {
return return
} }
func ParseMPEG4AudioConfig(data []byte) (config MPEG4AudioConfig, err error) { func ParseMPEG4AudioConfigBytes(data []byte) (config MPEG4AudioConfig, err error) {
r := bytes.NewReader(data)
if config, err = ReadMPEG4AudioConfig(r); err != nil {
err = fmt.Errorf("CodecData invalid: parse MPEG4AudioConfig failed(%s)", err)
return
}
config = config.Complete()
return
}
func ReadMPEG4AudioConfig(r io.Reader) (config MPEG4AudioConfig, err error) {
// copied from libavcodec/mpeg4audio.c avpriv_mpeg4audio_get_config() // copied from libavcodec/mpeg4audio.c avpriv_mpeg4audio_get_config()
r := bytes.NewReader(data)
br := &bits.Reader{R: r} br := &bits.Reader{R: r}
if config.ObjectType, err = readObjectType(br); err != nil { if config.ObjectType, err = readObjectType(br); err != nil {
return return
} }
@ -243,12 +222,12 @@ func ReadMPEG4AudioConfig(r io.Reader) (config MPEG4AudioConfig, err error) {
if config.ChannelConfig, err = br.ReadBits(4); err != nil { if config.ChannelConfig, err = br.ReadBits(4); err != nil {
return return
} }
config = config.Complete()
return return
} }
func WriteMPEG4AudioConfig(w io.Writer, config MPEG4AudioConfig) (err error) { func WriteMPEG4AudioConfig(w io.Writer, config MPEG4AudioConfig) (err error) {
bw := &bits.Writer{W: w} bw := &bits.Writer{W: w}
if err = writeObjectType(bw, config.ObjectType); err != nil { if err = writeObjectType(bw, config.ObjectType); err != nil {
return return
} }
@ -311,9 +290,15 @@ func (self CodecData) PacketDuration(data []byte) (dur time.Duration, err error)
return return
} }
func NewCodecDataFromMPEG4AudioConfig(config MPEG4AudioConfig) (self CodecData, err error) {
b := &bytes.Buffer{}
WriteMPEG4AudioConfig(b, config)
return NewCodecDataFromMPEG4AudioConfigBytes(b.Bytes())
}
func NewCodecDataFromMPEG4AudioConfigBytes(config []byte) (self CodecData, err error) { func NewCodecDataFromMPEG4AudioConfigBytes(config []byte) (self CodecData, err error) {
self.ConfigBytes = config self.ConfigBytes = config
if self.Config, err = ParseMPEG4AudioConfig(config); err != nil { if self.Config, err = ParseMPEG4AudioConfigBytes(config); err != nil {
err = fmt.Errorf("parse MPEG4AudioConfig failed(%s)", err) err = fmt.Errorf("parse MPEG4AudioConfig failed(%s)", err)
return return
} }

View File

@ -1059,12 +1059,20 @@ func (self *Stream) handleRtpPacket(packet []byte) (err error) {
} }
case av.AAC: case av.AAC:
if len(payload) < 4 { if len(payload) < 4+7 {
err = fmt.Errorf("rtp: aac packet too short") err = fmt.Errorf("rtp: aac packet too short")
return return
} }
payload = payload[4:] // TODO: remove this hack
var hdrlen, framelen int
if _, hdrlen, framelen, _, err = aacparser.ParseADTSHeader(payload); err != nil {
err = fmt.Errorf("rtsp: aac invalid: %s", err)
return
}
self.gotpkt = true self.gotpkt = true
self.pkt.Data = payload[4+7:] // TODO: remove this hack self.pkt.Data = payload[hdrlen:framelen]
self.timestamp = timestamp self.timestamp = timestamp
default: default:

View File

@ -171,30 +171,26 @@ func (self *Stream) payloadEnd() (err error) {
switch self.streamType { switch self.streamType {
case ElementaryStreamTypeAdtsAAC: case ElementaryStreamTypeAdtsAAC:
var config aacparser.MPEG4AudioConfig var config aacparser.MPEG4AudioConfig
var packets [][]byte if config, _, _, _, err = aacparser.ParseADTSHeader(payload); err != nil {
var totsamples int err = fmt.Errorf("ts: aac invalid: %s", err)
if config, packets, totsamples, err = aacparser.SplitADTSFrames(payload); err != nil {
err = fmt.Errorf("ts: demuxer: SplitADTSFrames failed: %s", err)
return return
} }
config = config.Complete()
if self.CodecData == nil { if self.CodecData == nil {
bw := &bytes.Buffer{} if self.CodecData, err = aacparser.NewCodecDataFromMPEG4AudioConfig(config); err != nil {
if err = aacparser.WriteMPEG4AudioConfig(bw, config); err != nil {
err = fmt.Errorf("WriteMPEG4AudioConfig failed: %s", err)
return
}
if self.CodecData, err = aacparser.NewCodecDataFromMPEG4AudioConfigBytes(bw.Bytes()); err != nil {
return return
} }
} }
frametime := time.Duration(totsamples / len(packets)) * time.Second / time.Duration(config.SampleRate) delta := time.Duration(0)
timedelta := time.Duration(0) for len(payload) > 0 {
for _, packet := range packets { var hdrlen, framelen, samples int
self.addPacket(packet, timedelta) if _, hdrlen, framelen, samples, err = aacparser.ParseADTSHeader(payload); err != nil {
timedelta += frametime return
}
self.addPacket(payload[hdrlen:framelen], delta)
delta += time.Duration(samples) * time.Second / time.Duration(config.SampleRate)
payload = payload[:framelen]
} }
case ElementaryStreamTypeH264: case ElementaryStreamTypeH264:

View File

@ -145,16 +145,17 @@ func (self *Muxer) writePacket(pkt av.Packet) (err error) {
switch stream.Type() { switch stream.Type() {
case av.AAC: case av.AAC:
codec := stream.CodecData.(aacparser.CodecData) codec := stream.CodecData.(aacparser.CodecData)
data := pkt.Data adtshdr := make([]byte, aacparser.ADTSHeaderLength)
data = append(aacparser.MakeADTSHeader(codec.Config, 1024, len(data)), data...) aacparser.FillADTSHeader(adtshdr, codec.Config, 1024, len(pkt.Data))
buf := &bytes.Buffer{} buf := &bytes.Buffer{}
pes := PESHeader{ pes := PESHeader{
StreamId: StreamIdAAC, StreamId: StreamIdAAC,
PTS: timeToPesTs(pkt.Time), PTS: timeToPesTs(pkt.Time),
} }
WritePESHeader(buf, pes, len(data)) WritePESHeader(buf, pes, len(pkt.Data)+len(adtshdr))
buf.Write(data) buf.Write(adtshdr)
buf.Write(pkt.Data)
stream.tsw.RandomAccessIndicator = true stream.tsw.RandomAccessIndicator = true
stream.tsw.PCR = timeToPCR(pkt.Time) stream.tsw.PCR = timeToPCR(pkt.Time)