Skip to content

Commit

Permalink
Support multi-variant HLS streams
Browse files Browse the repository at this point in the history
  • Loading branch information
olafal0 committed Oct 22, 2024
1 parent 23809f3 commit 82e4efa
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 4 deletions.
21 changes: 18 additions & 3 deletions pkg/media/pipeline.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,10 @@ type Pipeline struct {
sink *WebRTCSink
input *Input

closed core.Fuse
cancel atomic.Pointer[context.CancelFunc]
audioSinkCreated atomic.Bool
videoSinkCreated atomic.Bool
closed core.Fuse
cancel atomic.Pointer[context.CancelFunc]

pipelineErr chan error
}
Expand Down Expand Up @@ -119,6 +121,19 @@ func (p *Pipeline) onOutputReady(pad *gst.Pad, kind types.StreamKind) {
}

func (p *Pipeline) onParamsReady(kind types.StreamKind, gPad *gst.GhostPad, param *glib.ParamSpec) {
// Keep track of whether we've already created audio/video outputs, and skip
// adding more if so
switch kind {
case types.Audio:
if !p.audioSinkCreated.CompareAndSwap(false, true) {
return
}
case types.Video:
if !p.videoSinkCreated.CompareAndSwap(false, true) {
return
}
}

var err error

// TODO fix go-gst to not create non nil gst.Caps for a NULL native caps pointer?
Expand All @@ -139,7 +154,7 @@ func (p *Pipeline) onParamsReady(kind types.StreamKind, gPad *gst.GhostPad, para
p.SendStateUpdate(context.Background())
}()

bin, err := p.sink.AddTrack(kind, caps.(*gst.Caps))
bin, err := p.sink.AddTrack(kind, caps.(*gst.Caps), p.Params)
if err != nil {
return
}
Expand Down
16 changes: 15 additions & 1 deletion pkg/media/webrtc_sink.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ func (s *WebRTCSink) addVideoTrack(w, h int) ([]*Output, error) {
return outputs, nil
}

func (s *WebRTCSink) AddTrack(kind types.StreamKind, caps *gst.Caps) (*gst.Bin, error) {
func (s *WebRTCSink) AddTrack(kind types.StreamKind, caps *gst.Caps, p *params.Params) (*gst.Bin, error) {
var bin *gst.Bin

switch kind {
Expand All @@ -218,6 +218,20 @@ func (s *WebRTCSink) AddTrack(kind types.StreamKind, caps *gst.Caps) (*gst.Bin,
}

logger.Infow("source resolution parsed", "width", w, "height", h)
// In cases like multi-variant HLS, the initial source resolution may be very low
// (e.g. 320x180). Since the input capsfilter element in the output bin will maintain this
// resolution, upscale to the highest layer's dimensions to prevent downscaling if we
// get a higher resolution variant later.
if len(p.VideoEncodingOptions.GetLayers()) > 0 {
layerHigh := p.VideoEncodingOptions.GetLayers()[0]
lw := int(layerHigh.GetWidth())
lh := int(layerHigh.GetHeight())
if lw > w || lh > h {
w = lw
h = lh
logger.Infow("max layer resolution greater than source, sizing up", "width", w, "height", h)
}
}

outputs, err := s.addVideoTrack(w, h)
if err != nil {
Expand Down

0 comments on commit 82e4efa

Please sign in to comment.