mirror of
https://github.com/aler9/gortsplib
synced 2025-10-06 23:52:46 +08:00
reuse interleaved frame buffer to minimize ram and cpu
This commit is contained in:
@@ -144,7 +144,7 @@ func (c *ConnClient) WriteRequestNoResponse(req *Request) error {
|
||||
}
|
||||
|
||||
// ReadInterleavedFrameOrResponse reads an InterleavedFrame or a Response.
|
||||
func (c *ConnClient) ReadInterleavedFrameOrResponse() (interface{}, error) {
|
||||
func (c *ConnClient) ReadInterleavedFrameOrResponse(frame *InterleavedFrame) (interface{}, error) {
|
||||
c.conf.NConn.SetReadDeadline(time.Now().Add(c.conf.ReadTimeout))
|
||||
b, err := c.br.ReadByte()
|
||||
if err != nil {
|
||||
@@ -153,16 +153,20 @@ func (c *ConnClient) ReadInterleavedFrameOrResponse() (interface{}, error) {
|
||||
c.br.UnreadByte()
|
||||
|
||||
if b == _INTERLEAVED_FRAME_MAGIC {
|
||||
return interleavedFrameRead(c.br)
|
||||
err := frame.read(c.br)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return frame, err
|
||||
}
|
||||
|
||||
return readResponse(c.br)
|
||||
}
|
||||
|
||||
// ReadInterleavedFrame reads an InterleavedFrame.
|
||||
func (c *ConnClient) ReadInterleavedFrame() (*InterleavedFrame, error) {
|
||||
func (c *ConnClient) ReadInterleavedFrame(frame *InterleavedFrame) error {
|
||||
c.conf.NConn.SetReadDeadline(time.Now().Add(c.conf.ReadTimeout))
|
||||
return interleavedFrameRead(c.br)
|
||||
return frame.read(c.br)
|
||||
}
|
||||
|
||||
// WriteInterleavedFrame writes an InterleavedFrame.
|
||||
|
@@ -75,9 +75,9 @@ func (s *ConnServer) WriteResponse(res *Response) error {
|
||||
}
|
||||
|
||||
// ReadInterleavedFrame reads an InterleavedFrame.
|
||||
func (s *ConnServer) ReadInterleavedFrame() (*InterleavedFrame, error) {
|
||||
func (s *ConnServer) ReadInterleavedFrame(frame *InterleavedFrame) error {
|
||||
s.conf.NConn.SetReadDeadline(time.Now().Add(s.conf.ReadTimeout))
|
||||
return interleavedFrameRead(s.br)
|
||||
return frame.read(s.br)
|
||||
}
|
||||
|
||||
// WriteInterleavedFrame writes an InterleavedFrame.
|
||||
|
@@ -8,9 +8,7 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
_INTERLEAVED_FRAME_MAGIC = 0x24
|
||||
_INTERLEAVED_FRAME_MAX_SIZE = 512 * 1024
|
||||
_INTERLEAVED_FRAME_MAX_CONTENT_SIZE = (_INTERLEAVED_FRAME_MAX_SIZE - 4)
|
||||
_INTERLEAVED_FRAME_MAGIC = 0x24
|
||||
)
|
||||
|
||||
// InterleavedFrame is a structure that allows to send and receive binary data
|
||||
@@ -21,34 +19,32 @@ type InterleavedFrame struct {
|
||||
Content []byte
|
||||
}
|
||||
|
||||
func interleavedFrameRead(r io.Reader) (*InterleavedFrame, error) {
|
||||
func (f *InterleavedFrame) read(r io.Reader) error {
|
||||
var header [4]byte
|
||||
_, err := io.ReadFull(r, header[:])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
|
||||
if header[0] != _INTERLEAVED_FRAME_MAGIC {
|
||||
return nil, fmt.Errorf("wrong magic byte (0x%.2x)", header[0])
|
||||
return fmt.Errorf("wrong magic byte (0x%.2x)", header[0])
|
||||
}
|
||||
|
||||
framelen := int(binary.BigEndian.Uint16(header[2:]))
|
||||
if framelen > _INTERLEAVED_FRAME_MAX_SIZE {
|
||||
return nil, fmt.Errorf("frame length greater than maximum allowed (%d vs %d)",
|
||||
framelen, _INTERLEAVED_FRAME_MAX_SIZE)
|
||||
if framelen > len(f.Content) {
|
||||
return fmt.Errorf("frame length greater than maximum allowed (%d vs %d)",
|
||||
framelen, len(f.Content))
|
||||
}
|
||||
|
||||
f := &InterleavedFrame{
|
||||
Channel: header[1],
|
||||
Content: make([]byte, framelen),
|
||||
}
|
||||
f.Channel = header[1]
|
||||
f.Content = f.Content[:framelen]
|
||||
|
||||
_, err = io.ReadFull(r, f.Content)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
|
||||
return f, nil
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *InterleavedFrame) write(bw *bufio.Writer) error {
|
||||
|
Reference in New Issue
Block a user