diff --git a/pkg/rtpaac/decoder.go b/pkg/rtpaac/decoder.go index 6d3d2863..064975bc 100644 --- a/pkg/rtpaac/decoder.go +++ b/pkg/rtpaac/decoder.go @@ -21,6 +21,10 @@ func NewDecoder(clockRate int) *Decoder { } } +func (d *Decoder) decodeTimestamp(ts uint32) time.Duration { + return (time.Duration(ts) - time.Duration(d.initialTs)) * time.Second / d.clockRate +} + // Decode decodes an AU from an RTP/AAC packet. func (d *Decoder) Decode(byts []byte) (*AUAndTimestamp, error) { pkt := rtp.Packet{} @@ -40,6 +44,6 @@ func (d *Decoder) Decode(byts []byte) (*AUAndTimestamp, error) { return &AUAndTimestamp{ AU: pkt.Payload[4:], - Timestamp: time.Duration(pkt.Timestamp-d.initialTs) * time.Second / d.clockRate, + Timestamp: d.decodeTimestamp(pkt.Timestamp), }, nil } diff --git a/pkg/rtph264/decoder.go b/pkg/rtph264/decoder.go index ac24fab6..0097a668 100644 --- a/pkg/rtph264/decoder.go +++ b/pkg/rtph264/decoder.go @@ -50,6 +50,10 @@ func NewDecoder() *Decoder { return &Decoder{} } +func (d *Decoder) decodeTimestamp(ts uint32) time.Duration { + return (time.Duration(ts) - time.Duration(d.initialTs)) * time.Second / rtpClockRate +} + // Decode decodes NALUs from RTP/H264 packets. // It can return: // * no NALUs and ErrMorePacketsNeeded @@ -82,7 +86,7 @@ func (d *Decoder) Decode(byts []byte) ([]*NALUAndTimestamp, error) { NALUTypeReserved23: return []*NALUAndTimestamp{{ NALU: pkt.Payload, - Timestamp: time.Duration(pkt.Timestamp-d.initialTs) * time.Second / rtpClockRate, + Timestamp: d.decodeTimestamp(pkt.Timestamp), }}, nil case NALUTypeStapA: @@ -108,7 +112,7 @@ func (d *Decoder) Decode(byts []byte) ([]*NALUAndTimestamp, error) { ret = append(ret, &NALUAndTimestamp{ NALU: pkt.Payload[:size], - Timestamp: time.Duration(pkt.Timestamp-d.initialTs) * time.Second / rtpClockRate, + Timestamp: d.decodeTimestamp(pkt.Timestamp), }) pkt.Payload = pkt.Payload[size:] } @@ -166,7 +170,7 @@ func (d *Decoder) Decode(byts []byte) ([]*NALUAndTimestamp, error) { d.state = decoderStateInitial return []*NALUAndTimestamp{{ NALU: d.fragmentedBuf, - Timestamp: time.Duration(pkt.Timestamp-d.initialTs) * time.Second / rtpClockRate, + Timestamp: d.decodeTimestamp(pkt.Timestamp), }}, nil } } diff --git a/pkg/rtph264/rtph264_test.go b/pkg/rtph264/rtph264_test.go index 62e8f0fd..820ecba9 100644 --- a/pkg/rtph264/rtph264_test.go +++ b/pkg/rtph264/rtph264_test.go @@ -55,6 +55,25 @@ var cases = []struct { ), }, }, + { + "negative timestamp", + &NALUAndTimestamp{ + Timestamp: -20 * time.Millisecond, + NALU: mergeBytes( + []byte{0x05}, + bytes.Repeat([]byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}, 8), + ), + }, + [][]byte{ + mergeBytes( + []byte{ + 0x80, 0xe0, 0x44, 0xed, 0x88, 0x77, 0x5f, 0x4d, + 0x9d, 0xbb, 0x78, 0x12, 0x05, + }, + bytes.Repeat([]byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}, 8), + ), + }, + }, { "fragmented", &NALUAndTimestamp{