feat: create capture subscription api to support more transports (#699)

* feat: introduce encoded media subscriptions

* chore: preserve sample field comments

* perf: reduce encoded sample dispatch copies

* docs: define encoded sample buffer ownership

* fix: avoid pipeline recreation errors

Reuse pipelines started by a new subscription during resize.

* fix: synchronize stream bitrate state

Protect bitrate updates, reads, and resets with one mutex.

* simplify

* group stream sink fields

* fix: remove unnecessary blank line in removeSubscription method

* remove defensive check

* remove noop

---------

Co-authored-by: Miroslav Šedivý <sedivy.miro@gmail.com>
This commit is contained in:
a
2026-09-24 03:58:39 -05:00
committed by GitHub
parent 6bc8350213
commit f4d632df2c
10 changed files with 505 additions and 175 deletions
+28 -21
View File
@@ -20,19 +20,37 @@ var (
type Sample struct {
// timing information
Timestamp time.Time
Duration time.Duration
// PTS, DTS, and Duration use -1 for GST_CLOCK_TIME_NONE.
PTS time.Duration
DTS time.Duration
Duration time.Duration
// metadata
DeltaUnit bool // this unit cannot be decoded independently.
// buffer length
Length int
// buffer with encoded media
// Data is immutable and remains valid while referenced. Consumers may retain
// it after WriteSample returns.
Data []byte
}
type SampleListener interface {
type SampleConsumer interface {
WriteSample(Sample)
}
type EncodedStream interface {
ID() string
Codec() codec.RTPCodec
Bitrate() uint64
Subscribe(SampleConsumer) (StreamSubscription, error)
}
type StreamSubscription interface {
Stream() EncodedStream
Switch(EncodedStream) error
Close() error
}
type BroadcastManager interface {
Start(url string) error
Stop()
@@ -103,27 +121,16 @@ type StreamSelector struct {
Bitrate uint64 `json:"bitrate"`
}
type StreamSelectorManager interface {
type EncodedStreamSelector interface {
IDs() []string
Codec() codec.RTPCodec
GetStream(selector StreamSelector) (StreamSinkManager, bool)
GetStream(selector StreamSelector) (EncodedStream, bool)
}
type StreamSinkManager interface {
ID() string
Codec() codec.RTPCodec
Bitrate() uint64
AddListener(listener SampleListener) error
RemoveListener(listener SampleListener) error
MoveListenerTo(listener SampleListener, targetStream StreamSinkManager) error
ListenersCount() int
Started() bool
CreatePipeline() error
DestroyPipeline()
type EncodedMediaSource interface {
Audio() EncodedStream
Video() EncodedStreamSelector
}
type StreamSrcManager interface {
@@ -137,13 +144,13 @@ type StreamSrcManager interface {
}
type CaptureManager interface {
EncodedMediaSource
Start()
Shutdown() error
Broadcast() BroadcastManager
Screencast() ScreencastManager
Audio() StreamSinkManager
Video() StreamSelectorManager
Webcam() StreamSrcManager
Microphone() StreamSrcManager