Improve RTCP for HomeKit

This commit is contained in:
Alexey Khit
2022-11-13 14:35:53 +03:00
parent 77888fe086
commit b617796941
2 changed files with 56 additions and 10 deletions
+3 -6
View File
@@ -3,7 +3,6 @@ package srtp
import ( import (
"github.com/AlexxIT/go2rtc/cmd/app" "github.com/AlexxIT/go2rtc/cmd/app"
"github.com/AlexxIT/go2rtc/pkg/srtp" "github.com/AlexxIT/go2rtc/pkg/srtp"
"github.com/rs/zerolog"
"net" "net"
) )
@@ -24,12 +23,12 @@ func Init() {
return return
} }
log = app.GetLogger("srtp") log := app.GetLogger("srtp")
// create SRTP server (endpoint) for receiving video from HomeKit camera // create SRTP server (endpoint) for receiving video from HomeKit camera
conn, err := net.ListenPacket("udp", cfg.Mod.Listen) conn, err := net.ListenPacket("udp", cfg.Mod.Listen)
if err != nil { if err != nil {
log.Warn().Err(err).Msg("[srtp] listen") log.Warn().Err(err).Caller().Send()
} }
log.Info().Str("addr", cfg.Mod.Listen).Msg("[srtp] listen") log.Info().Str("addr", cfg.Mod.Listen).Msg("[srtp] listen")
@@ -38,11 +37,9 @@ func Init() {
go func() { go func() {
Server = &srtp.Server{} Server = &srtp.Server{}
if err = Server.Serve(conn); err != nil { if err = Server.Serve(conn); err != nil {
log.Warn().Err(err).Msg("[srtp] serve") log.Warn().Err(err).Caller().Send()
} }
}() }()
} }
var Server *srtp.Server var Server *srtp.Server
var log zerolog.Logger
+53 -4
View File
@@ -5,6 +5,7 @@ import (
"github.com/pion/rtcp" "github.com/pion/rtcp"
"github.com/pion/rtp" "github.com/pion/rtp"
"github.com/pion/srtp/v2" "github.com/pion/srtp/v2"
"time"
) )
type Session struct { type Session struct {
@@ -16,6 +17,14 @@ type Session struct {
Write func(b []byte) (int, error) Write func(b []byte) (int, error)
Track *streamer.Track Track *streamer.Track
lastSequence uint32
lastTimestamp uint32
//lastPacket *rtp.Packet
lastTime time.Time
jitter float64
//sequenceCycle uint16
totalLost uint32
} }
func (s *Session) SetKeys( func (s *Session) SetKeys(
@@ -46,8 +55,33 @@ func (s *Session) HandleRTP(data []byte) (err error) {
return return
} }
now := time.Now()
// https://www.ietf.org/rfc/rfc3550.txt
if s.lastTimestamp != 0 {
delta := packet.SequenceNumber - uint16(s.lastSequence)
// lost packet
if delta > 1 {
s.totalLost += uint32(delta - 1)
}
// D(i,j) = (Rj - Ri) - (Sj - Si) = (Rj - Sj) - (Ri - Si)
dTime := now.Sub(s.lastTime).Seconds()*float64(s.Track.Codec.ClockRate) -
float64(packet.Timestamp-s.lastTimestamp)
if dTime < 0 {
dTime = -dTime
}
// J(i) = J(i-1) + (|D(i-1,i)| - J(i-1))/16
s.jitter += (dTime - s.jitter) / 16
}
// keeping cycles (overflow)
s.lastSequence = s.lastSequence&0xFFFF0000 | uint32(packet.SequenceNumber)
s.lastTimestamp = packet.Timestamp
s.lastTime = now
_ = s.Track.WriteRTP(packet) _ = s.Track.WriteRTP(packet)
//s.Output(core.RTP{Channel: s.Channel, Packet: packet})
return return
} }
@@ -64,7 +98,6 @@ func (s *Session) HandleRTCP(data []byte) (err error) {
} }
_ = packets _ = packets
//s.Output(core.RTCP{Channel: s.Channel + 1, Header: header, Packets: packets})
if header.Type == rtcp.TypeSenderReport { if header.Type == rtcp.TypeSenderReport {
err = s.KeepAlive() err = s.KeepAlive()
@@ -74,9 +107,25 @@ func (s *Session) HandleRTCP(data []byte) (err error) {
} }
func (s *Session) KeepAlive() (err error) { func (s *Session) KeepAlive() (err error) {
var data []byte
// we can send empty receiver response, but should send it to hold the connection
rep := rtcp.ReceiverReport{SSRC: s.LocalSSRC} rep := rtcp.ReceiverReport{SSRC: s.LocalSSRC}
if s.lastTimestamp > 0 {
//log.Printf("[RTCP] ssrc=%d seq=%d lost=%d jit=%.2f", s.RemoteSSRC, s.lastSequence, s.totalLost, s.jitter)
rep.Reports = []rtcp.ReceptionReport{{
SSRC: s.RemoteSSRC,
LastSequenceNumber: s.lastSequence,
LastSenderReport: s.lastTimestamp,
FractionLost: 0, // TODO
TotalLost: s.totalLost,
Delay: 0, // send just after receive
Jitter: uint32(s.jitter),
}}
}
// we can send empty receiver response, but should send it to hold the connection
var data []byte
if data, err = rep.Marshal(); err != nil { if data, err = rep.Marshal(); err != nil {
return return
} }