Documentation
¶
Overview ¶
Package sender implements WebRTC sender functionality for bandwidth estimation tests.
Package sender implements WebRTC sender functionality for bandwidth estimation tests.
Package sender implements WebRTC sender functionality for bandwidth estimation tests.
Package sender implements WebRTC sender functionality for bandwidth estimation tests.
Index ¶
- Variables
- type AudioBuffer
- func (a *AudioBuffer) Close() error
- func (a *AudioBuffer) Closed() <-chan struct{}
- func (a *AudioBuffer) FrameReady() <-chan struct{}
- func (a *AudioBuffer) ID() string
- func (a *AudioBuffer) LastCaptureTSUs() int64
- func (a *AudioBuffer) LastDequeueWallUs() int64
- func (a *AudioBuffer) PushPCM(samples []int16, sampleRate, channels int) error
- func (a *AudioBuffer) PushPCMWithCaptureTS(samples []int16, sampleRate, channels int, captureTSUs int64) error
- func (a *AudioBuffer) Read() (wave.Audio, func(), error)
- func (a *AudioBuffer) SetInitialized()
- type ConfigurableWebRTCSender
- type EncodedFrameCallback
- type EncodedTrack
- type FrameBuffer
- func (f *FrameBuffer) Close() error
- func (f *FrameBuffer) Closed() <-chan struct{}
- func (f *FrameBuffer) FrameReady() <-chan struct{}
- func (f *FrameBuffer) ID() string
- func (f *FrameBuffer) LastCaptureTSUs() int64
- func (f *FrameBuffer) LastDequeueWallUs() int64
- func (f *FrameBuffer) Read() (image.Image, func(), error)
- func (f *FrameBuffer) ResetInitialized()
- func (f *FrameBuffer) SendFrame(frame image.Image) error
- func (f *FrameBuffer) SendFrameWithCaptureTS(frame image.Image, captureTSUs int64) (evicted bool, err error)
- func (f *FrameBuffer) SetInitialized()
- type FrameSentCallback
- type MediaSource
- type Option
- func CCLogWriter(w io.Writer) Option
- func DefaultInterceptors() Option
- func GCC(initialBitrate, maxBitrate int, extra ...gcc.Option) Option
- func PacketLogWriter(rtpWriter, rtcpWriter io.Writer) Option
- func SetLoggerFactory(loggerFactory plogging.LoggerFactory) Option
- func SetMediaSource(source MediaSource) Option
- func SetVnet(v *vnet.Net, publicIPs []string) Option
- type RTCSender
- func (s *RTCSender) AcceptAnswer(answer *webrtc.SessionDescription) error
- func (s *RTCSender) AddAudioTrack(trackID string) (*webrtc.TrackLocalStaticSample, error)
- func (s *RTCSender) AddEncodedAudioTrack(trackID string, params opus.Params) error
- func (s *RTCSender) AddVideoTrack(info VideoTrackInfo) error
- func (s *RTCSender) Close() error
- func (s *RTCSender) CreateOffer() (*webrtc.SessionDescription, error)
- func (s *RTCSender) ForceKeyFrame(trackID string) error
- func (s *RTCSender) GetEncodeFrameOk() bool
- func (s *RTCSender) GetEstimatorChan() chan cc.BandwidthEstimator
- func (s *RTCSender) GetMediaEngine() *webrtc.MediaEngine
- func (s *RTCSender) GetPeerConnection() *webrtc.PeerConnection
- func (s *RTCSender) GetRegistry() *interceptor.Registry
- func (s *RTCSender) GetSettingEngine() *webrtc.SettingEngine
- func (s *RTCSender) GetTrackStats(trackID string) *TrackStats
- func (s *RTCSender) GetWebRTCTrackLocal(trackID string) (*webrtc.TrackLocalStaticSample, error)
- func (s *RTCSender) LookupNetStatsBySSRC(ssrc webrtc.SSRC) *SenderNetStats
- func (s *RTCSender) SendAudioFrameWithCaptureTS(trackID string, pcm []int16, sampleRate, channels int, captureTSUs int64) error
- func (s *RTCSender) SendFrame(trackID string, frame image.Image) error
- func (s *RTCSender) SendFrameWithCaptureTS(trackID string, frame image.Image, captureTSUs int64) error
- func (s *RTCSender) SetBitrateAllocation(allocation map[string]float64) error
- func (s *RTCSender) SetCCLogWriter(w io.Writer)
- func (s *RTCSender) SetLogger(logger logging.LeveledLogger)
- func (s *RTCSender) SetOnEncodedFrame(cb EncodedFrameCallback)
- func (s *RTCSender) SetOnFrameSent(cb FrameSentCallback)
- func (s *RTCSender) SetPreEncodedCaptureTSUs(ssrc uint32, captureTSUs int64)
- func (s *RTCSender) SetupPeerConnection() error
- func (s *RTCSender) Start(ctx context.Context) error
- func (s *RTCSender) UpdateBitrate(targetBitrate int)
- type Sender
- func (s *Sender) AcceptAnswer(answer *webrtc.SessionDescription) error
- func (s *Sender) CreateOffer() (*webrtc.SessionDescription, error)
- func (s *Sender) GetEstimatorChan() chan cc.BandwidthEstimator
- func (s *Sender) GetMediaEngine() *webrtc.MediaEngine
- func (s *Sender) GetRegistry() *interceptor.Registry
- func (s *Sender) GetSettingEngine() *webrtc.SettingEngine
- func (s *Sender) GetSource() MediaSource
- func (s *Sender) SetCCLogWriter(w io.Writer)
- func (s *Sender) SetLogger(logger logging.LeveledLogger)
- func (s *Sender) SetupPeerConnection() error
- func (s *Sender) SignalHTTP(addr, route string) error
- func (s *Sender) Start(ctx context.Context) error
- type SenderNetStats
- type SimulcastFilesSource
- type StatisticalEncoderSource
- func (s *StatisticalEncoderSource) Close() error
- func (s *StatisticalEncoderSource) SetTargetBitrate(rate int)
- func (s *StatisticalEncoderSource) SetWriter(f func(sample media.Sample) error)
- func (s *StatisticalEncoderSource) Start(ctx context.Context) error
- func (s *StatisticalEncoderSource) WriteFrame(frame syncodec.Frame)
- type TrackStats
- type VideoSource
- type VideoTrackInfo
- type WebRTCSender
Constants ¶
This section is empty.
Variables ¶
var ( ErrBufferClosed = errors.New("buffer closed") ErrNoFrameAvailable = errors.New("no frame available") ErrFailedToAddFrameAfterDrop = errors.New("failed to add frame after dropping oldest") )
Static errors for err113 compliance.
var ( ErrTrackAlreadyExists = errors.New("track already exists") ErrTrackNotFound = errors.New("track not found") ErrTrackDoesNotSupportFrames = errors.New("track does not support frame injection") ErrInvalidNegativeValue = errors.New("invalid value: must be non-negative") ErrAllocationSumMustBePositive = errors.New("sum of allocation values must be greater than 0") ErrFailedToCastVideoTrack = errors.New("failed to cast media track to VideoTrack") ErrFailedToCastAudioTrack = errors.New("failed to cast media track to AudioTrack") ErrMissingEncoderConfig = errors.New("either EncoderBuilder or InitialBitrate must be provided") ErrForceKeyFrameNotSupported = errors.New("encoder does not support ForceKeyFrame") ErrInvalidPCMChunk = errors.New("invalid PCM chunk: length must be a positive multiple of channel count") ErrPCMFormatMismatch = errors.New("PCM sample rate / channel count does not match the track's encoder") ErrAudioTrackNotAllocatable = errors.New("audio track bitrate is GCC-managed, not allocatable") )
Static errors for err113 compliance.
Functions ¶
This section is empty.
Types ¶
type AudioBuffer ¶
type AudioBuffer struct {
// contains filtered or unexported fields
}
AudioBuffer is a simple in-memory PCM buffer that implements mediadevices.AudioSource (audio.Reader + Source). It is the audio counterpart of FrameBuffer: callers push raw interleaved PCM via PushPCM and the mediadevices Opus encoder reads chunks from it, letting GCC drive the audio bitrate just like video.
func NewAudioBuffer ¶
func NewAudioBuffer(sampleRate, channels int) *AudioBuffer
NewAudioBuffer creates a new audio buffer for the given declared format. sampleRate/channels describe the PCM that will be pushed (e.g. 48000, 2) and are used to synthesize a silence chunk for encoder property detection.
func (*AudioBuffer) Close ¶
func (a *AudioBuffer) Close() error
Close stops the audio buffer and releases resources.
func (*AudioBuffer) Closed ¶
func (a *AudioBuffer) Closed() <-chan struct{}
Closed returns a channel closed when the buffer is closed, so a consumer blocked on FrameReady can wake and observe ErrBufferClosed.
func (*AudioBuffer) FrameReady ¶
func (a *AudioBuffer) FrameReady() <-chan struct{}
FrameReady returns a channel that receives a value when a chunk is enqueued. It is buffered (cap 1) and edge-triggered: signal() drops the notification if one is already pending, so a consumer that drains all available chunks after each wake-up never misses one. This lets the encode loop block for a chunk instead of polling. Mirrors FrameBuffer.FrameReady.
func (*AudioBuffer) ID ¶
func (a *AudioBuffer) ID() string
ID returns the identifier for this audio source.
func (*AudioBuffer) LastCaptureTSUs ¶
func (a *AudioBuffer) LastCaptureTSUs() int64
LastCaptureTSUs returns the capture timestamp (unix microseconds) of the most recently dequeued chunk, or 0 if none carried one. The init silence chunk and legacy PushPCM leave it unchanged / zero.
func (*AudioBuffer) LastDequeueWallUs ¶
func (a *AudioBuffer) LastDequeueWallUs() int64
LastDequeueWallUs returns the wall-clock time (unix microseconds) at which the most recent real chunk was dequeued in Read.
func (*AudioBuffer) PushPCM ¶
func (a *AudioBuffer) PushPCM(samples []int16, sampleRate, channels int) error
PushPCM adds an interleaved PCM chunk to the buffer with no capture timestamp. Equivalent to PushPCMWithCaptureTS(samples, sampleRate, channels, 0).
func (*AudioBuffer) PushPCMWithCaptureTS ¶
func (a *AudioBuffer) PushPCMWithCaptureTS(samples []int16, sampleRate, channels int, captureTSUs int64) error
PushPCMWithCaptureTS adds an interleaved PCM chunk together with an opaque capture timestamp (unix microseconds; 0 = none). samples is interleaved 16-bit PCM (len must be a multiple of channels). sampleRate/channels must stay constant across pushes: the Opus encoder's internal accumulator discards partial data if the channel count changes. If the buffer is full, the oldest chunk is dropped to add the new one.
func (*AudioBuffer) Read ¶
func (a *AudioBuffer) Read() (wave.Audio, func(), error)
Read returns the next available PCM chunk from the buffer. When initialized (normal operation), returns immediately with ErrNoFrameAvailable if no chunk is ready — this must never block because the encode loop reads under the sender's write lock. When not initialized (encoder init), blocks up to 100ms and returns a silence chunk so mediadevices can detect the audio properties.
func (*AudioBuffer) SetInitialized ¶
func (a *AudioBuffer) SetInitialized()
SetInitialized marks the audio buffer as initialized.
type ConfigurableWebRTCSender ¶
type ConfigurableWebRTCSender interface {
GetSettingEngine() *webrtc.SettingEngine
GetMediaEngine() *webrtc.MediaEngine
GetRegistry() *interceptor.Registry
GetEstimatorChan() chan cc.BandwidthEstimator
SetLogger(plogging.LeveledLogger)
SetCCLogWriter(io.Writer) // For Sender compatibility
}
ConfigurableWebRTCSender defines the interface that both Sender and RTCSender implement to allow shared option configuration.
type EncodedFrameCallback ¶
EncodedFrameCallback is called after each VP8 frame is encoded with the track ID, encoded data, and whether it's a keyframe. Callers can use this to route encoded frames to a ring buffer or other sink without a second encode pass.
type EncodedTrack ¶
type EncodedTrack struct {
// contains filtered or unexported fields
}
EncodedTrack represents a GCC-managed encoded track (video or audio). videoTrack is the shared local track written via WriteSample for both kinds; encodedReader, bitrateTracker and mimeType are shared too. The video-only fields (info, mediaTrack, encoderBuilder, videoSource) are nil/zero for audio, and the audio-only fields (audioTrack, audioSource) are nil for video.
type FrameBuffer ¶
type FrameBuffer struct {
// contains filtered or unexported fields
}
FrameBuffer is a simple in-memory frame buffer that implements VideoSource It can be used as a virtual video driver for testing or programmatic frame injection.
func NewFrameBuffer ¶
func NewFrameBuffer(width, height int) *FrameBuffer
NewFrameBuffer creates a new frame buffer with the specified dimensions.
Capacity 1: a single-slot "latest frame" mailbox. At most one frame may be in-flight in the encoder while at most one newer frame waits staged; each new SendFrame overwrites the staged frame (drop-oldest in SendFrameWithCaptureTS), so the encoder always pulls the freshest image and stale frames are discarded under load. This minimizes per-frame buffer wait at the cost of dropping on any same-tick burst — intentional for low-latency teleoperation where a newer frame always supersedes an older one. Encoder throughput remains bounded by encoder CPU, not queue depth.
func (*FrameBuffer) Close ¶
func (f *FrameBuffer) Close() error
Close stops the frame buffer and releases resources.
func (*FrameBuffer) Closed ¶
func (f *FrameBuffer) Closed() <-chan struct{}
Closed returns a channel closed when the buffer is closed, so a consumer blocked on FrameReady can wake and observe ErrBufferClosed.
func (*FrameBuffer) FrameReady ¶
func (f *FrameBuffer) FrameReady() <-chan struct{}
FrameReady returns a channel that receives a value when a frame is enqueued. It is buffered (cap 1) and edge-triggered: signal() drops the notification if one is already pending, so a consumer that drains all available frames after each wake-up never misses a frame. This lets the encode loop block for a frame instead of polling, eliminating poll-induced buffer-wait latency.
func (*FrameBuffer) ID ¶
func (f *FrameBuffer) ID() string
ID returns the identifier for this video source.
func (*FrameBuffer) LastCaptureTSUs ¶
func (f *FrameBuffer) LastCaptureTSUs() int64
LastCaptureTSUs returns the captureTSUs of the most recently popped frame, or 0 if no real frame has been consumed yet. Intended for the encode loop to call right after encodedReader.Read.
func (*FrameBuffer) LastDequeueWallUs ¶
func (f *FrameBuffer) LastDequeueWallUs() int64
LastDequeueWallUs returns time.Now().UnixMicro() at the most recent real-frame Read (the queue-exit instant), or 0 if no real frame has been consumed yet. Intended for the encode loop to read right after encodedReader.Read.
func (*FrameBuffer) Read ¶
func (f *FrameBuffer) Read() (image.Image, func(), error)
Read returns the next available frame from the buffer. When initialized (normal operation), it returns immediately with ErrNoFrameAvailable if no frame is ready. The vpx encoder's Read holds its internal mutex across the inner Read call, so blocking here would also block concurrent DynamicQPControl bitrate updates that try to take the same mutex. runEncodeLoop handles ErrNoFrameAvailable by sleeping briefly before retrying. When not initialized (encoder init), it blocks up to 100ms and returns a black frame for codec property detection.
Side effect: stores the popped frame's captureTSUs for LastCaptureTSUs. Black-frame timeouts preserve the previous value so encoders with lookahead can still correlate the previously-read real frame.
func (*FrameBuffer) ResetInitialized ¶
func (f *FrameBuffer) ResetInitialized()
ResetInitialized temporarily marks the frame buffer as uninitialized. This causes Read() to return black frames on timeout instead of ErrNoFrameAvailable, which is needed when recreating an encoder (NewEncodedReader reads one frame for property detection during initialization).
func (*FrameBuffer) SendFrame ¶
func (f *FrameBuffer) SendFrame(frame image.Image) error
SendFrame adds a frame to the buffer with no capture timestamp. If the buffer is full, it drops the oldest frame and adds the new one.
func (*FrameBuffer) SendFrameWithCaptureTS ¶
func (f *FrameBuffer) SendFrameWithCaptureTS(frame image.Image, captureTSUs int64) (evicted bool, err error)
SendFrameWithCaptureTS adds a frame with an opaque capture timestamp (microseconds), retrievable via LastCaptureTSUs after the encode pipeline pops it. Pass 0 to opt out. evicted is true when the buffer was full and the oldest entry was discarded to make room.
func (*FrameBuffer) SetInitialized ¶
func (f *FrameBuffer) SetInitialized()
SetInitialized marks the frame buffer as initialized.
type FrameSentCallback ¶
type FrameSentCallback func(trackID string, captureTSUs, dequeuedAtWallUs, encodeDoneAtWallUs, sentAtWallUs int64, dropped bool)
FrameSentCallback fires per encoded frame (after WriteSample) and per frame evicted from a full buffer. captureTSUs echoes the value passed to SendFrameWithCaptureTS (0 = none). dequeuedAtWallUs / encodeDoneAtWallUs / sentAtWallUs are time.Now().UnixMicro() at FrameBuffer.Read return, encodedReader.Read return, and WriteSample return respectively. On dropped=true (WriteSample error or eviction), dequeuedAtWallUs and encodeDoneAtWallUs are 0. Runs on the encode goroutine for completed sends, on the SendFrame caller's goroutine for evictions; must not block.
type MediaSource ¶
type MediaSource interface {
SetTargetBitrate(int)
SetWriter(func(sample media.Sample) error)
Start(ctx context.Context) error
}
MediaSource represents a source of media samples that can be sent over WebRTC.
type Option ¶
type Option func(ConfigurableWebRTCSender) error
Option is a function that configures a ConfigurableWebRTCSender.
func CCLogWriter ¶
CCLogWriter returns an Option that configures congestion control logging.
func DefaultInterceptors ¶
func DefaultInterceptors() Option
DefaultInterceptors returns an Option that registers the default WebRTC interceptors.
func GCC ¶
GCC returns an Option that configures Google Congestion Control with the specified initial bitrate and max bitrate (in bps). A maxBitrate of 0 means no cap (uses GCC default of 50 Mbps). GCC configures send-side bandwidth estimation. extra is passed through to the estimator, so a caller can set options the two bitrate arguments do not cover.
func PacketLogWriter ¶
PacketLogWriter returns an Option that configures RTP and RTCP packet logging.
func SetLoggerFactory ¶
func SetLoggerFactory(loggerFactory plogging.LoggerFactory) Option
SetLoggerFactory returns an Option that configures the logger factory.
func SetMediaSource ¶
func SetMediaSource(source MediaSource) Option
SetMediaSource returns an Option that sets the media source for the sender. Note: This only works with the original Sender type, not RTCSender.
type RTCSender ¶
type RTCSender struct {
// contains filtered or unexported fields
}
RTCSender is a generic sender that can work with any frame source.
func NewRTCSender ¶
NewRTCSender creates a new generic sender with GCC bandwidth estimation by default.
func (*RTCSender) AcceptAnswer ¶
func (s *RTCSender) AcceptAnswer(answer *webrtc.SessionDescription) error
AcceptAnswer processes the WebRTC answer.
func (*RTCSender) AddAudioTrack ¶
func (s *RTCSender) AddAudioTrack(trackID string) (*webrtc.TrackLocalStaticSample, error)
AddAudioTrack adds a pre-encoded audio track (Opus). Audio tracks don't participate in bitrate allocation or encoding — they receive pre-encoded Opus frames via WriteSample on the returned track.
func (*RTCSender) AddEncodedAudioTrack ¶
AddEncodedAudioTrack adds a GCC-managed encoded audio track. Unlike AddAudioTrack (which expects pre-encoded Opus via WriteSample), this track owns the Opus encoder: callers push raw PCM via SendAudioFrameWithCaptureTS and the GCC control loop drives its bitrate alongside video, sharing the pool. It is driven by the same per-track runEncodeLoop goroutine as video.
func (*RTCSender) AddVideoTrack ¶
func (s *RTCSender) AddVideoTrack(info VideoTrackInfo) error
AddVideoTrack adds a new video track.
func (*RTCSender) CreateOffer ¶
func (s *RTCSender) CreateOffer() (*webrtc.SessionDescription, error)
CreateOffer creates a WebRTC offer.
func (*RTCSender) ForceKeyFrame ¶
ForceKeyFrame forces the next frame for the given track to be a keyframe.
func (*RTCSender) GetEncodeFrameOk ¶
GetEncodeFrameOk returns the current encode frame status.
func (*RTCSender) GetEstimatorChan ¶
func (s *RTCSender) GetEstimatorChan() chan cc.BandwidthEstimator
GetEstimatorChan returns the bandwidth estimator channel.
func (*RTCSender) GetMediaEngine ¶
func (s *RTCSender) GetMediaEngine() *webrtc.MediaEngine
GetMediaEngine returns the media engine.
func (*RTCSender) GetPeerConnection ¶
func (s *RTCSender) GetPeerConnection() *webrtc.PeerConnection
GetPeerConnection returns the WebRTC peer connection.
func (*RTCSender) GetRegistry ¶
func (s *RTCSender) GetRegistry() *interceptor.Registry
GetRegistry returns the interceptor registry.
func (*RTCSender) GetSettingEngine ¶
func (s *RTCSender) GetSettingEngine() *webrtc.SettingEngine
GetSettingEngine returns the setting engine.
func (*RTCSender) GetTrackStats ¶
func (s *RTCSender) GetTrackStats(trackID string) *TrackStats
GetTrackStats returns the latest cumulative TrackStats for the given video track. Returns nil when the track does not exist. Network fields are zero until the stats interceptor has observed traffic for the track's SSRC and (for RTT) at least one RTCP receiver report has arrived.
Pipeline counters approximate the W3C `outbound-rtp` framesEncoded / totalEncodeTime / totalPacketSendDelay fields. They are updated each time the encode loop produces a frame.
func (*RTCSender) GetWebRTCTrackLocal ¶
func (s *RTCSender) GetWebRTCTrackLocal(trackID string) (*webrtc.TrackLocalStaticSample, error)
GetWebRTCTrackLocal returns the WebRTC track for a specific track ID (video or audio).
func (*RTCSender) LookupNetStatsBySSRC ¶
func (s *RTCSender) LookupNetStatsBySSRC(ssrc webrtc.SSRC) *SenderNetStats
LookupNetStatsBySSRC returns the pion stats interceptor's network counters for any sender on the underlying PeerConnection, identified by its outbound SSRC. Use this for tracks added directly to the PC (e.g. via pc.AddTrack) rather than through AddVideoTrack — AddVideoTrack-managed tracks should keep using GetTrackStats, which also surfaces pipeline (encoder) counters.
Returns nil when the stats interceptor has not yet bound to a PeerConnection or has no entry for the SSRC (the latter being normal until the first RTP packet has been sent for that sender). RTT-bearing fields stay zero until at least one RTCP receiver report has arrived for the SSRC, matching GetTrackStats' contract.
func (*RTCSender) SendAudioFrameWithCaptureTS ¶
func (s *RTCSender) SendAudioFrameWithCaptureTS( trackID string, pcm []int16, sampleRate, channels int, captureTSUs int64, ) error
SendAudioFrameWithCaptureTS pushes raw interleaved PCM to an encoded audio track created via AddEncodedAudioTrack, along with an opaque capture timestamp (unix microseconds; 0 = none) that is encoded into the outgoing RTP timestamp. samples is interleaved 16-bit PCM; sampleRate and channels describe its format (expected 48000 / 1-2 to match the Opus track).
func (*RTCSender) SendFrame ¶
SendFrame sends a frame to a specific track with no associated capture timestamp. Equivalent to SendFrameWithCaptureTS(trackID, frame, 0).
func (*RTCSender) SendFrameWithCaptureTS ¶
func (s *RTCSender) SendFrameWithCaptureTS(trackID string, frame image.Image, captureTSUs int64) error
SendFrameWithCaptureTS sends a frame along with an opaque capture timestamp (microseconds) that is echoed to any registered FrameSentCallback. Pass 0 to opt out. When the buffer is full and the oldest frame is evicted to make room, the callback fires synchronously for the evicted frame with dropped=true so downstream SLO accounting catches the overload case.
func (*RTCSender) SetBitrateAllocation ¶
SetBitrateAllocation sets custom bitrate allocation for tracks. allocation is a map of track ID to arbitrary positive numbers representing relative weights The values will be normalized internally (each value divided by sum of all values) Pass nil to return to equal distribution.
func (*RTCSender) SetCCLogWriter ¶
SetCCLogWriter sets the congestion control log writer.
func (*RTCSender) SetLogger ¶
func (s *RTCSender) SetLogger(logger logging.LeveledLogger)
SetLogger sets the logger.
func (*RTCSender) SetOnEncodedFrame ¶
func (s *RTCSender) SetOnEncodedFrame(cb EncodedFrameCallback)
SetOnEncodedFrame registers a callback invoked after each VP8 frame is encoded and sent to the WebRTC track. Thread-safe (called under tracksMu).
func (*RTCSender) SetOnFrameSent ¶
func (s *RTCSender) SetOnFrameSent(cb FrameSentCallback)
SetOnFrameSent registers a per-frame send-completion callback. Thread-safe. See FrameSentCallback for the contract.
func (*RTCSender) SetPreEncodedCaptureTSUs ¶
SetPreEncodedCaptureTSUs records a capture timestamp (unix microseconds; 0 = none) on the capture-timestamp interceptor for a pre-encoded track's SSRC, so the interceptor encodes it into that track's next outgoing RTP timestamp (same abs-capture-time scheme as video).
Unlike encoded tracks (AddVideoTrack / AddEncodedAudioTrack), pre-encoded tracks added via AddAudioTrack produce RTP through WriteSample rather than an internal encode loop, so RTCSender never learns their SSRC. The caller supplies the SSRC (assigned when the track is added to the PeerConnection) and must call this immediately before the corresponding WriteSample, on the same goroutine, so the stored value applies to that frame's packets.
func (*RTCSender) SetupPeerConnection ¶
SetupPeerConnection initializes the WebRTC peer connection.
func (*RTCSender) UpdateBitrate ¶
UpdateBitrate applies a GCC target bitrate to the encoders this RTCSender manages. Start() calls the internal updateBitrate on its own 100ms tick; this exported entry point lets callers that own the estimator elsewhere (e.g. a hardware-encode deployment where Start() is not run) still drive the software-encoded tracks — notably the GCC-managed Opus audio track.
type Sender ¶
type Sender struct {
// contains filtered or unexported fields
}
Sender manages a WebRTC connection for sending media.
func NewSender ¶
func NewSender(source MediaSource, opts ...Option) (*Sender, error)
NewSender creates a new WebRTC sender with the given media source and options.
func (*Sender) AcceptAnswer ¶
func (s *Sender) AcceptAnswer(answer *webrtc.SessionDescription) error
AcceptAnswer processes a WebRTC answer from the remote peer.
func (*Sender) CreateOffer ¶
func (s *Sender) CreateOffer() (*webrtc.SessionDescription, error)
CreateOffer creates a WebRTC offer for signaling.
func (*Sender) GetEstimatorChan ¶
func (s *Sender) GetEstimatorChan() chan cc.BandwidthEstimator
GetEstimatorChan returns the bandwidth estimator channel.
func (*Sender) GetMediaEngine ¶
func (s *Sender) GetMediaEngine() *webrtc.MediaEngine
GetMediaEngine returns the media engine.
func (*Sender) GetRegistry ¶
func (s *Sender) GetRegistry() *interceptor.Registry
GetRegistry returns the interceptor registry.
func (*Sender) GetSettingEngine ¶
func (s *Sender) GetSettingEngine() *webrtc.SettingEngine
GetSettingEngine returns the setting engine.
func (*Sender) GetSource ¶
func (s *Sender) GetSource() MediaSource
GetSource returns the media source used by the sender.
func (*Sender) SetCCLogWriter ¶
SetCCLogWriter sets the congestion control log writer.
func (*Sender) SetLogger ¶
func (s *Sender) SetLogger(logger logging.LeveledLogger)
SetLogger sets the logger.
func (*Sender) SetupPeerConnection ¶
SetupPeerConnection initializes the WebRTC peer connection.
func (*Sender) SignalHTTP ¶
SignalHTTP performs WebRTC signaling over HTTP.
type SenderNetStats ¶
type SenderNetStats struct {
PacketsSent uint64
BytesSent uint64
HeaderBytesSent uint64
NACKCount uint32
PLICount uint32
PacketsReceived uint64
PacketsLost int64
Jitter float64
FractionLost float64
RoundTripTime time.Duration
TotalRoundTripTime time.Duration
RoundTripTimeMeasurements uint64
}
SenderNetStats is the per-SSRC network-side subset of TrackStats: counters the pion stats interceptor records from outbound RTP + remote RTCP, with no pipeline (encoder) fields. Returned by LookupNetStatsBySSRC for senders that were not added through AddVideoTrack (e.g. tracks added directly via pc.AddTrack on the same PeerConnection), where pipeline counters don't apply. Field semantics mirror the same-named fields on TrackStats.
type SimulcastFilesSource ¶
type SimulcastFilesSource struct {
WriteSample func(media.Sample) error
// contains filtered or unexported fields
}
SimulcastFilesSource is a media source that switches between different quality video files based on the target bitrate.
func NewSimulcastFilesSource ¶
func NewSimulcastFilesSource() *SimulcastFilesSource
NewSimulcastFilesSource returns a new SimulcastFilesSource.
func (*SimulcastFilesSource) Close ¶
func (s *SimulcastFilesSource) Close() error
Close stops the simulcast source and cleans up resources.
func (*SimulcastFilesSource) SetTargetBitrate ¶
func (s *SimulcastFilesSource) SetTargetBitrate(rate int)
SetTargetBitrate sets the target bitrate for the simulcast source.
type StatisticalEncoderSource ¶
type StatisticalEncoderSource struct {
// contains filtered or unexported fields
}
StatisticalEncoderSource is a source that fakes a media encoder using syncodec.StatisticalCodec.
func NewStatisticalEncoderSource ¶
func NewStatisticalEncoderSource() *StatisticalEncoderSource
NewStatisticalEncoderSource returns a new StatisticalEncoderSource.
func (*StatisticalEncoderSource) Close ¶
func (s *StatisticalEncoderSource) Close() error
Close stops the encoder and cleans up resources.
func (*StatisticalEncoderSource) SetTargetBitrate ¶
func (s *StatisticalEncoderSource) SetTargetBitrate(rate int)
SetTargetBitrate sets the target bitrate for the encoder.
func (*StatisticalEncoderSource) SetWriter ¶
func (s *StatisticalEncoderSource) SetWriter(f func(sample media.Sample) error)
SetWriter sets the sample writer function.
func (*StatisticalEncoderSource) Start ¶
func (s *StatisticalEncoderSource) Start(ctx context.Context) error
Start begins the encoding process and runs until context is done.
func (*StatisticalEncoderSource) WriteFrame ¶
func (s *StatisticalEncoderSource) WriteFrame(frame syncodec.Frame)
WriteFrame writes a frame to the encoder.
type TrackStats ¶
type TrackStats struct {
// Bandwidth (bps). AvailableOutgoingBitrate is the connection-level GCC
// estimate; TargetBitrate is this track's allocated share pushed to the
// encoder (W3C outbound-rtp `targetBitrate`).
AvailableOutgoingBitrate int
TargetBitrate int
// Pipeline counters from the local encode loop.
FramesEncoded uint64
TotalEncodeTimeNs uint64 // wall time spent inside encodedReader.Read
TotalSendQueueTimeNs uint64 // wall time between Read return and WriteSample return
// Synthesized quality-limitation durations (seconds), W3C outbound-rtp
// `qualityLimitationDurations` semantics. Bandwidth-limited is inferred from
// the GCC estimate sitting below the configured max bitrate; CPU-limited is
// inferred from the encode loop falling behind (buffer evictions). When GCC
// has no max cap, bandwidth-limited cannot be inferred and stays zero.
QualityLimitationCPUSeconds float64
QualityLimitationBandwidthSeconds float64
// Network counters from the Pion stats interceptor.
PacketsSent uint64
BytesSent uint64
HeaderBytesSent uint64
NACKCount uint32
PLICount uint32
FIRCount uint32
// Remote receiver counters (from RTCP RR).
PacketsReceived uint64
PacketsLost int64
Jitter float64
FractionLost float64
RoundTripTime time.Duration
TotalRoundTripTime time.Duration
RoundTripTimeMeasurements uint64
}
TrackStats summarizes per-track network and pipeline statistics for one outbound video track. Cumulative since track creation; callers that want per-window deltas should snapshot two reads and subtract.
type VideoSource ¶
VideoSource represents any source of video frames (camera, file, virtual buffer, etc.)
type VideoTrackInfo ¶
type VideoTrackInfo struct {
TrackID string
Width int
Height int
EncoderBuilder codec.VideoEncoderBuilder
InitialBitrate int // Optional: if EncoderBuilder is nil, a default VP8 encoder with this bitrate will be created
}
VideoTrackInfo holds information about a video track.
type WebRTCSender ¶
type WebRTCSender interface {
SetupPeerConnection() error
CreateOffer() (*webrtc.SessionDescription, error)
AcceptAnswer(answer *webrtc.SessionDescription) error
Start(ctx context.Context) error
}
WebRTCSender is a common interface for different sender implementations.