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