roq

package module
v0.4.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 28, 2026 License: MIT Imports: 15 Imported by: 3

README

RTP over QUIC (RoQ)

Go Reference

RTP over QUIC (RoQ) implementation in Go.

Example applications using the library can be found in the examples directory.

Documentation

Index

Constants

View Source
const (
	ErrRoQNoError = iota
	ErrRoQGeneralError
	ErrRoQInternalError
	ErrRoQPacketError
	ErrRoQStreamCreationError
	ErrRoQFrameCancelled
	ErrRoQUnknownFlowID
	ErrRoQExpectationUnmet
)

Variables

This section is empty.

Functions

This section is empty.

Types

type Connection

type Connection interface {
	SendDatagram(payload []byte) error
	ReceiveDatagram(context.Context) ([]byte, error)
	OpenUniStreamSync(context.Context) (SendStream, error)
	AcceptUniStream(context.Context) (ReceiveStream, error)
	CloseWithError(uint64, string) error
}

type Option added in v0.4.0

type Option func(*sessionConfig) error

Option configures a Session.

func WithLogger added in v0.4.0

func WithLogger(logger *slog.Logger) Option

WithLogger sets the logger the session and its flows write to.The session discards all log records unless the application passes one in. Pass slog.Default() to send them to the standard logger. The logger must not be nil.

func WithQlogPacketData added in v0.4.0

func WithQlogPacketData(maxBytes int) Option

WithQlogPacketData makes the session log the wire image of every RTP and RTCP packet it sends and receives as the data field of the raw info of its qlog events. maxBytes caps how many bytes of each packet are logged; zero logs the whole packet. The logged length is always that of the complete packet, even when the data is truncated.

Packet data makes qlog files considerably larger, and every logged packet is copied on the send and receive paths, so it is off unless this option is set.

func WithQlogTrace added in v0.4.0

func WithQlogTrace(t qlogwriter.Trace) Option

WithQlogTrace sets the qlog trace the session logs its RoQ events to. RoQ events are only logged if the trace was created with the RoQ event schema, see github.com/mengelbart/roq/qlog.DefaultConnectionTracer.

It is only needed for connections that do not implement QlogConnection: a session on a QUICGoConnection picks up the trace of the QUIC connection by itself. Setting it takes precedence over that.

func WithReceiveBufferSize added in v0.4.0

func WithReceiveBufferSize(packets int) Option

WithReceiveBufferSize sets the number of packets each ReceiveFlow of the session buffers for the application to read. Packets that arrive for a flow whose buffer is full are dropped. It defaults to 1024 packets and must be greater than zero.

func WithUnknownFlowBufferSize added in v0.4.0

func WithUnknownFlowBufferSize(flows int) Option

WithUnknownFlowBufferSize sets the number of receive flows the session buffers for flow IDs the application has not called NewReceiveFlow for yet. Once the buffer is full, the oldest of those flows is evicted and its streams are cancelled with ErrRoQUnknownFlowID. It defaults to 16 flows and must be greater than zero.

type PrioritySendStream added in v0.4.0

type PrioritySendStream interface {
	SetPriority(p uint32)
	SetIncremental(b bool)
}

type QUICGoConnection

type QUICGoConnection struct {
	// contains filtered or unexported fields
}

func NewQUICGoConnection

func NewQUICGoConnection(conn *quic.Conn) *QUICGoConnection

func (*QUICGoConnection) AcceptUniStream

func (c *QUICGoConnection) AcceptUniStream(ctx context.Context) (ReceiveStream, error)

func (*QUICGoConnection) CloseWithError

func (c *QUICGoConnection) CloseWithError(code uint64, reason string) error

func (*QUICGoConnection) OpenUniStreamSync

func (c *QUICGoConnection) OpenUniStreamSync(ctx context.Context) (SendStream, error)

func (*QUICGoConnection) QlogTrace added in v0.4.0

func (c *QUICGoConnection) QlogTrace() qlogwriter.Trace

QlogTrace returns the qlog trace of the QUIC connection. It is nil if qlog is not enabled.

func (*QUICGoConnection) ReceiveDatagram

func (c *QUICGoConnection) ReceiveDatagram(ctx context.Context) ([]byte, error)

func (*QUICGoConnection) SendDatagram

func (c *QUICGoConnection) SendDatagram(payload []byte) error

type QUICGoReceiveStream added in v0.4.0

type QUICGoReceiveStream struct {
	// contains filtered or unexported fields
}

func NewQUICGoReceiveStream added in v0.4.0

func NewQUICGoReceiveStream(stream *quic.ReceiveStream) *QUICGoReceiveStream

func (*QUICGoReceiveStream) CancelRead added in v0.4.0

func (s *QUICGoReceiveStream) CancelRead(c uint64)

func (*QUICGoReceiveStream) ID added in v0.4.0

func (s *QUICGoReceiveStream) ID() int64

func (*QUICGoReceiveStream) Read added in v0.4.0

func (s *QUICGoReceiveStream) Read(p []byte) (n int, err error)

type QUICGoSendStream added in v0.4.0

type QUICGoSendStream struct {
	// contains filtered or unexported fields
}

func NewQUICGoSendStream added in v0.4.0

func NewQUICGoSendStream(stream *quic.SendStream) *QUICGoSendStream

func (*QUICGoSendStream) CancelWrite added in v0.4.0

func (s *QUICGoSendStream) CancelWrite(c uint64)

func (*QUICGoSendStream) Close added in v0.4.0

func (s *QUICGoSendStream) Close() error

func (*QUICGoSendStream) ID added in v0.4.0

func (s *QUICGoSendStream) ID() int64

func (*QUICGoSendStream) Write added in v0.4.0

func (s *QUICGoSendStream) Write(b []byte) (int, error)

type QlogConnection added in v0.4.0

type QlogConnection interface {
	QlogTrace() qlogwriter.Trace
}

QlogConnection is implemented by Connections that can provide the qlog trace of the underlying QUIC connection. A Session whose Connection implements it logs its RoQ events into that trace, provided the trace was created with the RoQ event schema. QUICGoConnection implements it.

type RTPSendStream

type RTPSendStream struct {
	// contains filtered or unexported fields
}

func (*RTPSendStream) CancelStream

func (s *RTPSendStream) CancelStream(errorCode uint64)

CancelStream closes the stream with the given error code. It may be called concurrently with WriteRTPBytes, and is what unblocks a write that is blocked on flow control.

func (*RTPSendStream) Close

func (s *RTPSendStream) Close() error

Close closes the stream gracefully. It may be called concurrently with WriteRTPBytes. Close does not flush the tail of a partially written frame, so closing after a short write leaves the peer with a truncated final frame.

func (*RTPSendStream) WriteRTPBytes

func (s *RTPSendStream) WriteRTPBytes(packet []byte) (int, error)

WriteRTPBytes sends an RTP or RTCP packet on the stream. It usually doesn't make sense to call this method from multiple goroutines concurrently, but it is safe for concurrent use.

The returned count is the number of bytes of packet that reached the stream, which is len(packet) on success. A frame is length-prefixed, so a partial write is recoverable: the bytes the peer has not seen are written first on the next call, before the next packet. Callers must therefore not re-send a packet that was reported short, or the peer receives it twice.

type ReceiveFlow

type ReceiveFlow struct {
	// contains filtered or unexported fields
}

func (*ReceiveFlow) Close

func (f *ReceiveFlow) Close() error

Close closes the flow.

func (*ReceiveFlow) ID

func (f *ReceiveFlow) ID() uint64

func (*ReceiveFlow) Read

func (f *ReceiveFlow) Read(buf []byte) (int, error)

Read reads the next RTP packet of the flow into buf. Packets are not split across calls: if buf is too small to hold the complete packet, the packet is dropped and Read returns 0 and io.ErrShortBuffer. Callers should provide a buffer large enough for the largest packet they expect to receive.

Read blocks until a packet arrives, the flow is closed, or the deadline set with SetReadDeadline passes.

func (*ReceiveFlow) SetReadDeadline

func (f *ReceiveFlow) SetReadDeadline(t time.Time) error

SetReadDeadline sets the deadline for future Read calls and for any Read that is currently blocked. Once the deadline has passed, Read returns os.ErrDeadlineExceeded without waiting for a packet, even if packets are still buffered, until the deadline is extended or cleared. A zero value for t clears the deadline.

type ReceiveStream

type ReceiveStream interface {
	io.Reader
	ID() int64
	CancelRead(uint64)
}

type SendFlow

type SendFlow struct {
	// contains filtered or unexported fields
}

func (*SendFlow) Close

func (f *SendFlow) Close() error

Close closes the flow and all associated streams. Every stream is closed even if an earlier one failed to close; the errors are joined and returned. The flow is marked closed and removed from the session in either case.

func (*SendFlow) ID added in v0.4.0

func (f *SendFlow) ID() uint64

func (*SendFlow) NewSendStream

func (f *SendFlow) NewSendStream(ctx context.Context, priority uint32, incremantal bool) (*RTPSendStream, error)

NewSendStream creates a new Stream for sending outgoing RTP and RTCP packets over a QUIC stream.

func (*SendFlow) WriteRTPBytes

func (f *SendFlow) WriteRTPBytes(packet []byte) error

WriteRTPBytes sends an RTP or RTCP packet as a QUIC Datagram.

type SendStream

type SendStream interface {
	io.Writer
	io.Closer
	ID() int64
	CancelWrite(uint64)
}

type Session

type Session struct {
	// contains filtered or unexported fields
}

func NewSession

func NewSession(conn Connection, acceptDatagrams bool, opts ...Option) (*Session, error)

NewSession creates a new roq session. QUIC connection is handled by roq. It returns an error if conn is nil or if an option is invalid.

func NewSessionWithAppHandledConn added in v0.4.0

func NewSessionWithAppHandledConn(conn Connection, acceptDatagrams bool, opts ...Option) (*Session, error)

NewSessionWithAppHandledConn creates a new roq session. QUIC connection is handled by the application. HandleDatagram and HandleUniStreamWithFlowID have to be called for each datagram / new stream. It returns an error if conn is nil or if an option is invalid.

func (*Session) Close

func (s *Session) Close() error

Close closes the session and waits for its receive loops to return. It must not be called from a callback running on one of those loops.

Close returns the error from closing the underlying QUIC connection. It is idempotent: later calls close nothing and report the same error as the call that closed the session.

Close also releases the session's qlog producer, which is what finishes the qlog trace of the QUIC connection, so it has to be called for the trace to be written completely.

func (*Session) HandleDatagram added in v0.4.0

func (s *Session) HandleDatagram(datagram []byte)

HandleDatagram handles a datagram. If QUIC connection is handled by the application, this function has to be called by the application for each datagram that belongs to the roq connection.

func (*Session) HandleUniStreamWithFlowID added in v0.4.0

func (s *Session) HandleUniStreamWithFlowID(flowID uint64, rs ReceiveStream)

HandleUniStreamWithFlowID handles a new stream with the flow ID already parsed. If QUIC connection is handled by the application, this function has to be called by the application for each new QUIC stream containing a roq flow ID.

func (*Session) NewReceiveFlow

func (s *Session) NewReceiveFlow(id uint64) (*ReceiveFlow, error)

func (*Session) NewSendFlow

func (s *Session) NewSendFlow(id uint64) (*SendFlow, error)

type SessionError added in v0.3.0

type SessionError struct {
	// contains filtered or unexported fields
}

SessionError is the error returned by operations on a closed session. It carries the RoQ error code and reason the session was closed with, which callers can inspect with errors.As.

func (SessionError) Code added in v0.4.0

func (e SessionError) Code() uint64

Code returns the RoQ error code the session was closed with, e.g. ErrRoQPacketError.

func (SessionError) Error added in v0.3.0

func (e SessionError) Error() string

func (SessionError) Reason added in v0.4.0

func (e SessionError) Reason() string

Reason returns the reason phrase the session was closed with. It may be empty.

Directories

Path Synopsis
examples
interop command
playfromdisk command
savetodisk command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL