mirror of
https://github.com/aler9/gortsplib
synced 2025-10-04 14:52:46 +08:00
149 lines
2.8 KiB
Go
149 lines
2.8 KiB
Go
package conn
|
|
|
|
import (
|
|
"bufio"
|
|
"io"
|
|
|
|
"github.com/aler9/gortsplib/pkg/base"
|
|
)
|
|
|
|
const (
|
|
readBufferSize = 4096
|
|
)
|
|
|
|
// Conn is a RTSP TCP connection.
|
|
type Conn struct {
|
|
w io.Writer
|
|
br *bufio.Reader
|
|
}
|
|
|
|
// NewConn allocates a Conn.
|
|
func NewConn(rw io.ReadWriter) *Conn {
|
|
return &Conn{
|
|
w: rw,
|
|
br: bufio.NewReaderSize(rw, readBufferSize),
|
|
}
|
|
}
|
|
|
|
// ReadResponse reads a Response.
|
|
func (c *Conn) ReadResponse(res *base.Response) error {
|
|
return res.Read(c.br)
|
|
}
|
|
|
|
// ReadRequest reads a Request.
|
|
func (c *Conn) ReadRequest(req *base.Request) error {
|
|
return req.Read(c.br)
|
|
}
|
|
|
|
// ReadInterleavedFrame reads a InterleavedFrame.
|
|
func (c *Conn) ReadInterleavedFrame(fr *base.InterleavedFrame) error {
|
|
return fr.Read(c.br)
|
|
}
|
|
|
|
// ReadInterleavedFrameOrRequest reads an InterleavedFrame or a Request.
|
|
func (c *Conn) ReadInterleavedFrameOrRequest(
|
|
frame *base.InterleavedFrame,
|
|
req *base.Request,
|
|
) (interface{}, error) {
|
|
b, err := c.br.ReadByte()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
c.br.UnreadByte()
|
|
|
|
if b == base.InterleavedFrameMagicByte {
|
|
err := frame.Read(c.br)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return frame, err
|
|
}
|
|
|
|
err = req.Read(c.br)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return req, nil
|
|
}
|
|
|
|
// ReadInterleavedFrameOrResponse reads an InterleavedFrame or a Response.
|
|
func (c *Conn) ReadInterleavedFrameOrResponse(
|
|
frame *base.InterleavedFrame,
|
|
res *base.Response,
|
|
) (interface{}, error) {
|
|
b, err := c.br.ReadByte()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
c.br.UnreadByte()
|
|
|
|
if b == base.InterleavedFrameMagicByte {
|
|
err := frame.Read(c.br)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return frame, err
|
|
}
|
|
|
|
err = res.Read(c.br)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return res, nil
|
|
}
|
|
|
|
// ReadRequestIgnoreFrames reads a Request and ignore frames in between.
|
|
func (c *Conn) ReadRequestIgnoreFrames(req *base.Request) error {
|
|
var f base.InterleavedFrame
|
|
|
|
for {
|
|
recv, err := c.ReadInterleavedFrameOrRequest(&f, req)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if _, ok := recv.(*base.Request); ok {
|
|
return nil
|
|
}
|
|
}
|
|
}
|
|
|
|
// ReadResponseIgnoreFrames reads a Response and ignore frames in between.
|
|
func (c *Conn) ReadResponseIgnoreFrames(res *base.Response) error {
|
|
var f base.InterleavedFrame
|
|
|
|
for {
|
|
recv, err := c.ReadInterleavedFrameOrResponse(&f, res)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if _, ok := recv.(*base.Response); ok {
|
|
return nil
|
|
}
|
|
}
|
|
}
|
|
|
|
// WriteRequest writes a request.
|
|
func (c *Conn) WriteRequest(req *base.Request) error {
|
|
buf, _ := req.Marshal()
|
|
_, err := c.w.Write(buf)
|
|
return err
|
|
}
|
|
|
|
// WriteResponse writes a response.
|
|
func (c *Conn) WriteResponse(res *base.Response) error {
|
|
buf, _ := res.Marshal()
|
|
_, err := c.w.Write(buf)
|
|
return err
|
|
}
|
|
|
|
// WriteInterleavedFrame writes an interleaved frame.
|
|
func (c *Conn) WriteInterleavedFrame(fr *base.InterleavedFrame, buf []byte) error {
|
|
n, _ := fr.MarshalTo(buf)
|
|
_, err := c.w.Write(buf[:n])
|
|
return err
|
|
}
|