rtpaac: support ADTS-encoded, fragmented AUs

This commit is contained in:
aler9
2022-07-23 23:58:31 +02:00
parent 5692796b4a
commit 570be5c520

View File

@@ -29,12 +29,12 @@ type Decoder struct {
// The number of bits on which the AU-Index-delta field is encoded in any non-first AU-header.
IndexDeltaLength int
timeDecoder *rtptimedec.Decoder
firstPacketParsed bool
adtsMode bool
fragmentedMode bool
fragmentedParts [][]byte
fragmentedSize int
timeDecoder *rtptimedec.Decoder
firstAUParsed bool
adtsMode bool
fragmentedMode bool
fragmentedParts [][]byte
fragmentedSize int
}
// Init initializes the decoder
@@ -70,30 +70,6 @@ func (d *Decoder) Decode(pkt *rtp.Packet) ([][]byte, time.Duration, error) {
}
payload = payload[pos:]
if d.adtsMode {
if len(dataLens) != 1 {
return nil, 0, fmt.Errorf("multiple AUs in ADTS mode are not supported")
}
if len(payload) < int(dataLens[0]) {
return nil, 0, fmt.Errorf("payload is too short")
}
au := payload[:dataLens[0]]
var pkts aac.ADTSPackets
err := pkts.Unmarshal(au)
if err != nil {
return nil, 0, fmt.Errorf("unable to decode ADTS: %s", err)
}
if len(pkts) != 1 {
return nil, 0, fmt.Errorf("multiple ADTS packets are not supported")
}
return [][]byte{pkts[0].AU}, d.timeDecoder.Decode(pkt.Timestamp), nil
}
if !d.fragmentedMode {
if pkt.Header.Marker {
// AUs
@@ -107,21 +83,11 @@ func (d *Decoder) Decode(pkt *rtp.Packet) ([][]byte, time.Duration, error) {
payload = payload[dataLen:]
}
// some cameras wrap AUs with ADTS.
if !d.firstPacketParsed {
if len(aus) == 1 && len(aus[0]) >= 2 {
if aus[0][0] == 0xFF && (aus[0][1]&0xF0) == 0xF0 {
var pkts aac.ADTSPackets
err := pkts.Unmarshal(aus[0])
if err == nil && len(pkts) == 1 {
d.adtsMode = true
aus[0] = pkts[0].AU
}
}
}
aus, err = d.finalize(aus)
if err != nil {
return nil, 0, err
}
d.firstPacketParsed = true
return aus, d.timeDecoder.Decode(pkt.Timestamp), nil
}
@@ -133,7 +99,6 @@ func (d *Decoder) Decode(pkt *rtp.Packet) ([][]byte, time.Duration, error) {
return nil, 0, fmt.Errorf("payload is too short")
}
d.firstPacketParsed = true
d.fragmentedSize = int(dataLens[0])
d.fragmentedParts = append(d.fragmentedParts, payload[:dataLens[0]])
d.fragmentedMode = true
@@ -170,11 +135,17 @@ func (d *Decoder) Decode(pkt *rtp.Packet) ([][]byte, time.Duration, error) {
for _, p := range d.fragmentedParts {
n += copy(ret[n:], p)
}
aus := [][]byte{ret}
d.firstPacketParsed = true
d.fragmentedParts = d.fragmentedParts[:0]
d.fragmentedMode = false
return [][]byte{ret}, d.timeDecoder.Decode(pkt.Timestamp), nil
aus, err = d.finalize(aus)
if err != nil {
return nil, 0, err
}
return aus, d.timeDecoder.Decode(pkt.Timestamp), nil
}
func (d *Decoder) readAUHeaders(buf []byte, headersLen int) ([]uint64, error) {
@@ -235,3 +206,39 @@ func (d *Decoder) readAUHeaders(buf []byte, headersLen int) ([]uint64, error) {
return dataLens, nil
}
func (d *Decoder) finalize(aus [][]byte) ([][]byte, error) {
// some cameras wrap AUs into ADTS
if !d.firstAUParsed {
d.firstAUParsed = true
if len(aus) == 1 && len(aus[0]) >= 2 {
if aus[0][0] == 0xFF && (aus[0][1]&0xF0) == 0xF0 {
var pkts aac.ADTSPackets
err := pkts.Unmarshal(aus[0])
if err == nil && len(pkts) == 1 {
d.adtsMode = true
aus[0] = pkts[0].AU
}
}
}
} else if d.adtsMode {
if len(aus) != 1 {
return nil, fmt.Errorf("multiple AUs in ADTS mode are not supported")
}
var pkts aac.ADTSPackets
err := pkts.Unmarshal(aus[0])
if err != nil {
return nil, fmt.Errorf("unable to decode ADTS: %s", err)
}
if len(pkts) != 1 {
return nil, fmt.Errorf("multiple ADTS packets are not supported")
}
aus[0] = pkts[0].AU
}
return aus, nil
}