rtcp*: split ProcessFrame into ProcessPacketRTP and ProcessPacketRTCP

This commit is contained in:
aler9
2021-10-30 16:36:58 +02:00
committed by Alessandro Ros
parent 1f5dec4a02
commit 6d340cdf39
10 changed files with 163 additions and 139 deletions

View File

@@ -7,8 +7,6 @@ import (
"time"
"github.com/pion/rtcp"
"github.com/aler9/gortsplib/pkg/base"
)
func randUint32() uint32 {
@@ -53,83 +51,6 @@ func New(receiverSSRC *uint32, clockRate int) *RTCPReceiver {
}
}
// ProcessFrame extracts the needed data from RTP or RTCP packets.
func (rr *RTCPReceiver) ProcessFrame(ts time.Time, streamType base.StreamType, payload []byte) {
rr.mutex.Lock()
defer rr.mutex.Unlock()
if streamType == base.StreamTypeRTP {
// do not parse the entire packet, extract only the fields we need
if len(payload) >= 8 {
sequenceNumber := uint16(payload[2])<<8 | uint16(payload[3])
rtpTime := uint32(payload[4])<<24 | uint32(payload[5])<<16 | uint32(payload[6])<<8 | uint32(payload[7])
// first frame
if !rr.firstRTPReceived {
rr.firstRTPReceived = true
rr.totalSinceReport = 1
rr.lastSequenceNumber = sequenceNumber
rr.lastRTPTimeRTP = rtpTime
rr.lastRTPTimeTime = ts
// subsequent frames
} else {
diff := int32(sequenceNumber) - int32(rr.lastSequenceNumber)
// following frame or following frame after an overflow
if diff > 0 || diff < -0x0FFF {
// overflow
if diff < -0x0FFF {
rr.sequenceNumberCycles++
}
// detect lost frames
if sequenceNumber != (rr.lastSequenceNumber + 1) {
rr.totalLost += uint32(uint16(diff) - 1)
rr.totalLostSinceReport += uint32(uint16(diff) - 1)
// allow up to 24 bits
if rr.totalLost > 0xFFFFFF {
rr.totalLost = 0xFFFFFF
}
if rr.totalLostSinceReport > 0xFFFFFF {
rr.totalLostSinceReport = 0xFFFFFF
}
}
// compute jitter
// https://tools.ietf.org/html/rfc3550#page-39
D := ts.Sub(rr.lastRTPTimeTime).Seconds()*rr.clockRate -
(float64(rtpTime) - float64(rr.lastRTPTimeRTP))
if D < 0 {
D = -D
}
rr.jitter += (D - rr.jitter) / 16
rr.totalSinceReport += uint32(uint16(diff))
rr.lastSequenceNumber = sequenceNumber
rr.lastRTPTimeRTP = rtpTime
rr.lastRTPTimeTime = ts
}
// ignore invalid frames (diff = 0) or reordered frames (diff < 0)
}
}
} else {
// we can afford to unmarshal all RTCP packets
// since they are sent with a frequency much lower than the one of RTP packets
frames, err := rtcp.Unmarshal(payload)
if err == nil {
for _, frame := range frames {
if sr, ok := (frame).(*rtcp.SenderReport); ok {
rr.senderSSRC = sr.SSRC
rr.lastSenderReport = uint32(sr.NTPTime >> 16)
rr.lastSenderReportTime = ts
}
}
}
}
}
// Report generates a RTCP receiver report.
func (rr *RTCPReceiver) Report(ts time.Time) []byte {
rr.mutex.Lock()
@@ -165,3 +86,84 @@ func (rr *RTCPReceiver) Report(ts time.Time) []byte {
return byts
}
// ProcessPacketRTP extracts the needed data from RTP packets.
func (rr *RTCPReceiver) ProcessPacketRTP(ts time.Time, payload []byte) {
rr.mutex.Lock()
defer rr.mutex.Unlock()
// do not parse the entire packet, extract only the fields we need
if len(payload) >= 8 {
sequenceNumber := uint16(payload[2])<<8 | uint16(payload[3])
rtpTime := uint32(payload[4])<<24 | uint32(payload[5])<<16 | uint32(payload[6])<<8 | uint32(payload[7])
// first frame
if !rr.firstRTPReceived {
rr.firstRTPReceived = true
rr.totalSinceReport = 1
rr.lastSequenceNumber = sequenceNumber
rr.lastRTPTimeRTP = rtpTime
rr.lastRTPTimeTime = ts
// subsequent frames
} else {
diff := int32(sequenceNumber) - int32(rr.lastSequenceNumber)
// following frame or following frame after an overflow
if diff > 0 || diff < -0x0FFF {
// overflow
if diff < -0x0FFF {
rr.sequenceNumberCycles++
}
// detect lost frames
if sequenceNumber != (rr.lastSequenceNumber + 1) {
rr.totalLost += uint32(uint16(diff) - 1)
rr.totalLostSinceReport += uint32(uint16(diff) - 1)
// allow up to 24 bits
if rr.totalLost > 0xFFFFFF {
rr.totalLost = 0xFFFFFF
}
if rr.totalLostSinceReport > 0xFFFFFF {
rr.totalLostSinceReport = 0xFFFFFF
}
}
// compute jitter
// https://tools.ietf.org/html/rfc3550#page-39
D := ts.Sub(rr.lastRTPTimeTime).Seconds()*rr.clockRate -
(float64(rtpTime) - float64(rr.lastRTPTimeRTP))
if D < 0 {
D = -D
}
rr.jitter += (D - rr.jitter) / 16
rr.totalSinceReport += uint32(uint16(diff))
rr.lastSequenceNumber = sequenceNumber
rr.lastRTPTimeRTP = rtpTime
rr.lastRTPTimeTime = ts
}
// ignore invalid frames (diff = 0) or reordered frames (diff < 0)
}
}
}
// ProcessPacketRTCP extracts the needed data from RTCP packets.
func (rr *RTCPReceiver) ProcessPacketRTCP(ts time.Time, payload []byte) {
rr.mutex.Lock()
defer rr.mutex.Unlock()
// we can afford to unmarshal all RTCP packets
// since they are sent with a frequency much lower than the one of RTP packets
frames, err := rtcp.Unmarshal(payload)
if err == nil {
for _, frame := range frames {
if sr, ok := (frame).(*rtcp.SenderReport); ok {
rr.senderSSRC = sr.SSRC
rr.lastSenderReport = uint32(sr.NTPTime >> 16)
rr.lastSenderReportTime = ts
}
}
}
}