mirror of
https://github.com/aler9/gortsplib
synced 2025-10-06 07:37:07 +08:00
improve performance
This commit is contained in:
@@ -72,7 +72,7 @@ type ConnClient struct {
|
||||
udpLastFrameTimes map[int]*int64
|
||||
udpRtpListeners map[int]*connClientUDPListener
|
||||
udpRtcpListeners map[int]*connClientUDPListener
|
||||
tcpFrameReadBuf *MultiBuffer
|
||||
tcpFrames *multiFrame
|
||||
playing bool
|
||||
|
||||
receiverReportTerminate chan struct{}
|
||||
@@ -150,9 +150,7 @@ func (c *ConnClient) NetConn() net.Conn {
|
||||
// ReadFrame reads an InterleavedFrame.
|
||||
func (c *ConnClient) ReadFrame() (*InterleavedFrame, error) {
|
||||
c.nconn.SetReadDeadline(time.Now().Add(c.conf.ReadTimeout))
|
||||
frame := &InterleavedFrame{
|
||||
Content: c.tcpFrameReadBuf.Next(),
|
||||
}
|
||||
frame := c.tcpFrames.next()
|
||||
err := frame.Read(c.br)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -172,9 +170,7 @@ func (c *ConnClient) readFrameOrResponse() (interface{}, error) {
|
||||
c.br.UnreadByte()
|
||||
|
||||
if b == interleavedFrameMagicByte {
|
||||
frame := &InterleavedFrame{
|
||||
Content: c.tcpFrameReadBuf.Next(),
|
||||
}
|
||||
frame := c.tcpFrames.next()
|
||||
err := frame.Read(c.br)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -610,7 +606,7 @@ func (c *ConnClient) Play(u *url.URL) (*Response, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
c.tcpFrameReadBuf = NewMultiBuffer(c.conf.ReadBufferCount, clientTCPFrameReadBufferSize)
|
||||
c.tcpFrames = newMultiFrame(c.conf.ReadBufferCount, clientTCPFrameReadBufferSize)
|
||||
|
||||
// v4lrtspserver sends frames before the response.
|
||||
// ignore them and wait for the response.
|
||||
|
@@ -33,10 +33,10 @@ type ConnServerConf struct {
|
||||
|
||||
// ConnServer is a server-side RTSP connection.
|
||||
type ConnServer struct {
|
||||
conf ConnServerConf
|
||||
br *bufio.Reader
|
||||
bw *bufio.Writer
|
||||
tcpFrameReadBuf *MultiBuffer
|
||||
conf ConnServerConf
|
||||
br *bufio.Reader
|
||||
bw *bufio.Writer
|
||||
tcpFrames *multiFrame
|
||||
}
|
||||
|
||||
// NewConnServer allocates a ConnServer.
|
||||
@@ -52,10 +52,10 @@ func NewConnServer(conf ConnServerConf) *ConnServer {
|
||||
}
|
||||
|
||||
return &ConnServer{
|
||||
conf: conf,
|
||||
br: bufio.NewReaderSize(conf.Conn, serverReadBufferSize),
|
||||
bw: bufio.NewWriterSize(conf.Conn, serverWriteBufferSize),
|
||||
tcpFrameReadBuf: NewMultiBuffer(conf.ReadBufferCount, clientTCPFrameReadBufferSize),
|
||||
conf: conf,
|
||||
br: bufio.NewReaderSize(conf.Conn, serverReadBufferSize),
|
||||
bw: bufio.NewWriterSize(conf.Conn, serverWriteBufferSize),
|
||||
tcpFrames: newMultiFrame(conf.ReadBufferCount, clientTCPFrameReadBufferSize),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,9 +88,7 @@ func (s *ConnServer) ReadFrameOrRequest(timeout bool) (interface{}, error) {
|
||||
s.br.UnreadByte()
|
||||
|
||||
if b == interleavedFrameMagicByte {
|
||||
frame := &InterleavedFrame{
|
||||
Content: s.tcpFrameReadBuf.Next(),
|
||||
}
|
||||
frame := s.tcpFrames.next()
|
||||
err := frame.Read(s.br)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@@ -3,8 +3,9 @@ package gortsplib
|
||||
// MultiBuffer implements software multi buffering, that allows to reuse
|
||||
// existing buffers without creating new ones, increasing performance.
|
||||
type MultiBuffer struct {
|
||||
count int
|
||||
buffers [][]byte
|
||||
curBuf int
|
||||
cur int
|
||||
}
|
||||
|
||||
// NewMultiBuffer allocates a MultiBuffer.
|
||||
@@ -15,16 +16,49 @@ func NewMultiBuffer(count int, size int) *MultiBuffer {
|
||||
}
|
||||
|
||||
return &MultiBuffer{
|
||||
count: count,
|
||||
buffers: buffers,
|
||||
}
|
||||
}
|
||||
|
||||
// Next gets the current buffer and sets the next buffer as the current one.
|
||||
func (mb *MultiBuffer) Next() []byte {
|
||||
ret := mb.buffers[mb.curBuf]
|
||||
mb.curBuf += 1
|
||||
if mb.curBuf >= len(mb.buffers) {
|
||||
mb.curBuf = 0
|
||||
ret := mb.buffers[mb.cur]
|
||||
mb.cur += 1
|
||||
if mb.cur >= mb.count {
|
||||
mb.cur = 0
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
type multiFrame struct {
|
||||
count int
|
||||
frames []*InterleavedFrame
|
||||
cur int
|
||||
}
|
||||
|
||||
func newMultiFrame(count int, bufsize int) *multiFrame {
|
||||
frames := make([]*InterleavedFrame, count)
|
||||
for i := 0; i < count; i++ {
|
||||
frames[i] = &InterleavedFrame{
|
||||
Content: make([]byte, 0, bufsize),
|
||||
}
|
||||
}
|
||||
|
||||
return &multiFrame{
|
||||
count: count,
|
||||
frames: frames,
|
||||
}
|
||||
}
|
||||
|
||||
func (mf *multiFrame) next() *InterleavedFrame {
|
||||
ret := mf.frames[mf.cur]
|
||||
mf.cur += 1
|
||||
if mf.cur >= mf.count {
|
||||
mf.cur = 0
|
||||
}
|
||||
|
||||
ret.Content = ret.Content[:cap(ret.Content)]
|
||||
|
||||
return ret
|
||||
}
|
||||
|
@@ -56,7 +56,7 @@ func (rr *RtcpReceiver) OnFrame(streamType StreamType, buf []byte) {
|
||||
|
||||
} else {
|
||||
// we can afford to unmarshal all RTCP frames
|
||||
// since they are sent with a frequency much lower than the one of the RTP frames
|
||||
// since they are sent with a frequency much lower than the one of RTP frames
|
||||
frames, err := rtcp.Unmarshal(buf)
|
||||
if err == nil {
|
||||
for _, frame := range frames {
|
||||
|
Reference in New Issue
Block a user