mirror of
https://github.com/aler9/gortsplib
synced 2025-10-12 10:30:15 +08:00
rtpaac: support ADTS-encoded, fragmented AUs
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
Reference in New Issue
Block a user