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