mirror of
https://github.com/aler9/gortsplib
synced 2025-10-04 23:02:45 +08:00
improve performance
This commit is contained in:
@@ -214,6 +214,7 @@ type Client struct {
|
|||||||
tracksByChannel map[int]int
|
tracksByChannel map[int]int
|
||||||
lastRange *headers.Range
|
lastRange *headers.Range
|
||||||
tcpReadBuffer *multibuffer.MultiBuffer
|
tcpReadBuffer *multibuffer.MultiBuffer
|
||||||
|
tcpRTPPacketBuffer *rtpPacketMultiBuffer
|
||||||
writeMutex sync.RWMutex // publish
|
writeMutex sync.RWMutex // publish
|
||||||
writeFrameAllowed bool // publish
|
writeFrameAllowed bool // publish
|
||||||
udpReportTimer *time.Timer
|
udpReportTimer *time.Timer
|
||||||
@@ -760,14 +761,14 @@ func (c *Client) runReader() {
|
|||||||
atomic.StoreInt64(c.tcpLastFrameTime, now.Unix())
|
atomic.StoreInt64(c.tcpLastFrameTime, now.Unix())
|
||||||
|
|
||||||
if isRTP {
|
if isRTP {
|
||||||
var pkt rtp.Packet
|
pkt := c.tcpRTPPacketBuffer.next()
|
||||||
err := pkt.Unmarshal(payload)
|
err := pkt.Unmarshal(payload)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.tracks[trackID].rtcpReceiver.ProcessPacketRTP(now, &pkt)
|
c.tracks[trackID].rtcpReceiver.ProcessPacketRTP(now, pkt)
|
||||||
c.OnPacketRTP(trackID, &pkt)
|
c.OnPacketRTP(trackID, pkt)
|
||||||
} else {
|
} else {
|
||||||
packets, err := rtcp.Unmarshal(payload)
|
packets, err := rtcp.Unmarshal(payload)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -1536,6 +1537,7 @@ func (c *Client) doSetup(
|
|||||||
case TransportTCP:
|
case TransportTCP:
|
||||||
if c.tcpReadBuffer == nil {
|
if c.tcpReadBuffer == nil {
|
||||||
c.tcpReadBuffer = multibuffer.New(uint64(c.ReadBufferCount), uint64(c.ReadBufferSize))
|
c.tcpReadBuffer = multibuffer.New(uint64(c.ReadBufferCount), uint64(c.ReadBufferSize))
|
||||||
|
c.tcpRTPPacketBuffer = newRTPPacketMultiBuffer(uint64(c.ReadBufferCount))
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.tracksByChannel == nil {
|
if c.tracksByChannel == nil {
|
||||||
|
@@ -11,7 +11,6 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/pion/rtcp"
|
"github.com/pion/rtcp"
|
||||||
"github.com/pion/rtp"
|
|
||||||
|
|
||||||
"github.com/aler9/gortsplib/pkg/base"
|
"github.com/aler9/gortsplib/pkg/base"
|
||||||
"github.com/aler9/gortsplib/pkg/liberrors"
|
"github.com/aler9/gortsplib/pkg/liberrors"
|
||||||
@@ -35,17 +34,18 @@ type ServerConn struct {
|
|||||||
s *Server
|
s *Server
|
||||||
conn net.Conn
|
conn net.Conn
|
||||||
|
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
ctxCancel func()
|
ctxCancel func()
|
||||||
remoteAddr *net.TCPAddr
|
remoteAddr *net.TCPAddr
|
||||||
br *bufio.Reader
|
br *bufio.Reader
|
||||||
sessions map[string]*ServerSession
|
sessions map[string]*ServerSession
|
||||||
tcpFrameEnabled bool
|
tcpFrameEnabled bool
|
||||||
tcpSession *ServerSession
|
tcpSession *ServerSession
|
||||||
tcpFrameTimeout bool
|
tcpFrameTimeout bool
|
||||||
tcpReadBuffer *multibuffer.MultiBuffer
|
tcpReadBuffer *multibuffer.MultiBuffer
|
||||||
tcpProcessFunc func(int, bool, []byte)
|
tcpRTPPacketBuffer *rtpPacketMultiBuffer
|
||||||
tcpWriterRunning bool
|
tcpProcessFunc func(int, bool, []byte)
|
||||||
|
tcpWriterRunning bool
|
||||||
|
|
||||||
// in
|
// in
|
||||||
sessionRemove chan *ServerSession
|
sessionRemove chan *ServerSession
|
||||||
@@ -260,7 +260,7 @@ func (sc *ServerConn) tcpProcessPlay(trackID int, isRTP bool, payload []byte) {
|
|||||||
|
|
||||||
func (sc *ServerConn) tcpProcessRecord(trackID int, isRTP bool, payload []byte) {
|
func (sc *ServerConn) tcpProcessRecord(trackID int, isRTP bool, payload []byte) {
|
||||||
if isRTP {
|
if isRTP {
|
||||||
var pkt rtp.Packet
|
pkt := sc.tcpRTPPacketBuffer.next()
|
||||||
err := pkt.Unmarshal(payload)
|
err := pkt.Unmarshal(payload)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
@@ -270,7 +270,7 @@ func (sc *ServerConn) tcpProcessRecord(trackID int, isRTP bool, payload []byte)
|
|||||||
h.OnPacketRTP(&ServerHandlerOnPacketRTPCtx{
|
h.OnPacketRTP(&ServerHandlerOnPacketRTPCtx{
|
||||||
Session: sc.tcpSession,
|
Session: sc.tcpSession,
|
||||||
TrackID: trackID,
|
TrackID: trackID,
|
||||||
Packet: &pkt,
|
Packet: pkt,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@@ -1019,6 +1019,7 @@ func (ss *ServerSession) handleRequest(sc *ServerConn, req *base.Request) (*base
|
|||||||
ss.tcpConn.tcpFrameEnabled = true
|
ss.tcpConn.tcpFrameEnabled = true
|
||||||
ss.tcpConn.tcpFrameTimeout = true
|
ss.tcpConn.tcpFrameTimeout = true
|
||||||
ss.tcpConn.tcpReadBuffer = multibuffer.New(uint64(sc.s.ReadBufferCount), uint64(sc.s.ReadBufferSize))
|
ss.tcpConn.tcpReadBuffer = multibuffer.New(uint64(sc.s.ReadBufferCount), uint64(sc.s.ReadBufferSize))
|
||||||
|
ss.tcpConn.tcpRTPPacketBuffer = newRTPPacketMultiBuffer(uint64(sc.s.ReadBufferCount))
|
||||||
ss.tcpConn.tcpProcessFunc = sc.tcpProcessRecord
|
ss.tcpConn.tcpProcessFunc = sc.tcpProcessRecord
|
||||||
|
|
||||||
// when recording, writeBuffer is only used to send RTCP receiver reports,
|
// when recording, writeBuffer is only used to send RTCP receiver reports,
|
||||||
|
@@ -15,6 +15,26 @@ import (
|
|||||||
"github.com/aler9/gortsplib/pkg/multibuffer"
|
"github.com/aler9/gortsplib/pkg/multibuffer"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type rtpPacketMultiBuffer struct {
|
||||||
|
count uint64
|
||||||
|
buffers []rtp.Packet
|
||||||
|
cur uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
func newRTPPacketMultiBuffer(count uint64) *rtpPacketMultiBuffer {
|
||||||
|
buffers := make([]rtp.Packet, count)
|
||||||
|
return &rtpPacketMultiBuffer{
|
||||||
|
count: count,
|
||||||
|
buffers: buffers,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mb *rtpPacketMultiBuffer) next() *rtp.Packet {
|
||||||
|
ret := &mb.buffers[mb.cur%mb.count]
|
||||||
|
mb.cur++
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
type clientData struct {
|
type clientData struct {
|
||||||
ss *ServerSession
|
ss *ServerSession
|
||||||
trackID int
|
trackID int
|
||||||
@@ -40,14 +60,15 @@ func (p *clientAddr) fill(ip net.IP, port int) {
|
|||||||
type serverUDPListener struct {
|
type serverUDPListener struct {
|
||||||
s *Server
|
s *Server
|
||||||
|
|
||||||
pc *net.UDPConn
|
pc *net.UDPConn
|
||||||
listenIP net.IP
|
listenIP net.IP
|
||||||
isRTP bool
|
isRTP bool
|
||||||
writeTimeout time.Duration
|
writeTimeout time.Duration
|
||||||
readBuffer *multibuffer.MultiBuffer
|
readBuffer *multibuffer.MultiBuffer
|
||||||
clientsMutex sync.RWMutex
|
rtpPacketBuffer *rtpPacketMultiBuffer
|
||||||
clients map[clientAddr]*clientData
|
clientsMutex sync.RWMutex
|
||||||
processFunc func(*clientData, []byte)
|
clients map[clientAddr]*clientData
|
||||||
|
processFunc func(*clientData, []byte)
|
||||||
|
|
||||||
readerDone chan struct{}
|
readerDone chan struct{}
|
||||||
}
|
}
|
||||||
@@ -135,14 +156,15 @@ func newServerUDPListener(
|
|||||||
}
|
}
|
||||||
|
|
||||||
u := &serverUDPListener{
|
u := &serverUDPListener{
|
||||||
s: s,
|
s: s,
|
||||||
pc: pc,
|
pc: pc,
|
||||||
listenIP: listenIP,
|
listenIP: listenIP,
|
||||||
clients: make(map[clientAddr]*clientData),
|
clients: make(map[clientAddr]*clientData),
|
||||||
isRTP: isRTP,
|
isRTP: isRTP,
|
||||||
writeTimeout: s.WriteTimeout,
|
writeTimeout: s.WriteTimeout,
|
||||||
readBuffer: multibuffer.New(uint64(s.ReadBufferCount), uint64(s.ReadBufferSize)),
|
readBuffer: multibuffer.New(uint64(s.ReadBufferCount), uint64(s.ReadBufferSize)),
|
||||||
readerDone: make(chan struct{}),
|
rtpPacketBuffer: newRTPPacketMultiBuffer(uint64(s.ReadBufferCount)),
|
||||||
|
readerDone: make(chan struct{}),
|
||||||
}
|
}
|
||||||
|
|
||||||
if isRTP {
|
if isRTP {
|
||||||
@@ -196,7 +218,7 @@ func (u *serverUDPListener) runReader() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (u *serverUDPListener) processRTP(clientData *clientData, payload []byte) {
|
func (u *serverUDPListener) processRTP(clientData *clientData, payload []byte) {
|
||||||
var pkt rtp.Packet
|
pkt := u.rtpPacketBuffer.next()
|
||||||
err := pkt.Unmarshal(payload)
|
err := pkt.Unmarshal(payload)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
@@ -204,13 +226,13 @@ func (u *serverUDPListener) processRTP(clientData *clientData, payload []byte) {
|
|||||||
|
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
atomic.StoreInt64(clientData.ss.udpLastFrameTime, now.Unix())
|
atomic.StoreInt64(clientData.ss.udpLastFrameTime, now.Unix())
|
||||||
clientData.ss.announcedTracks[clientData.trackID].rtcpReceiver.ProcessPacketRTP(now, &pkt)
|
clientData.ss.announcedTracks[clientData.trackID].rtcpReceiver.ProcessPacketRTP(now, pkt)
|
||||||
|
|
||||||
if h, ok := u.s.Handler.(ServerHandlerOnPacketRTP); ok {
|
if h, ok := u.s.Handler.(ServerHandlerOnPacketRTP); ok {
|
||||||
h.OnPacketRTP(&ServerHandlerOnPacketRTPCtx{
|
h.OnPacketRTP(&ServerHandlerOnPacketRTPCtx{
|
||||||
Session: clientData.ss,
|
Session: clientData.ss,
|
||||||
TrackID: clientData.trackID,
|
TrackID: clientData.trackID,
|
||||||
Packet: &pkt,
|
Packet: pkt,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user