Skip to content

Commit

Permalink
Add WithPayloader to TrackLocalStatic
Browse files Browse the repository at this point in the history
Allow custom payloader depending on the mime type

Fixes #2928
  • Loading branch information
LeeTeng2001 authored and Sean-Der committed Oct 15, 2024
1 parent 76634b1 commit 271ab55
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 1 deletion.
15 changes: 14 additions & 1 deletion track_local_static.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ type TrackLocalStaticRTP struct {
mu sync.RWMutex
bindings []trackBinding
codec RTPCodecCapability
payloader func(RTPCodecCapability) (rtp.Payloader, error)
id, rid, streamID string
}

Expand All @@ -57,6 +58,13 @@ func WithRTPStreamID(rid string) func(*TrackLocalStaticRTP) {
}
}

// WithPayloader allows the user to override the Payloader
func WithPayloader(h func(RTPCodecCapability) (rtp.Payloader, error)) func(*TrackLocalStaticRTP) {
return func(s *TrackLocalStaticRTP) {
s.payloader = h
}
}

// Bind is called by the PeerConnection after negotiation is complete
// This asserts that the code requested is supported by the remote peer.
// If so it sets up all the state (SSRC and PayloadType) to have a call
Expand Down Expand Up @@ -250,7 +258,12 @@ func (s *TrackLocalStaticSample) Bind(t TrackLocalContext) (RTPCodecParameters,
return codec, nil
}

payloader, err := payloaderForCodec(codec.RTPCodecCapability)
payloadHandler := s.rtpTrack.payloader
if payloadHandler == nil {
payloadHandler = payloaderForCodec
}

payloader, err := payloadHandler(codec.RTPCodecCapability)
if err != nil {
return codec, err
}
Expand Down
48 changes: 48 additions & 0 deletions track_local_static_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@ package webrtc
import (
"context"
"errors"
"sync/atomic"
"testing"
"time"

"github.com/pion/rtp"
"github.com/pion/transport/v3/test"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

// If a remote doesn't support a Codec used by a `TrackLocalStatic`
Expand Down Expand Up @@ -336,3 +338,49 @@ func Test_TrackLocalStatic_RTX(t *testing.T) {

closePairNow(t, offerer, answerer)
}

type customCodecPayloader struct {
invokeCount atomic.Int32
}

func (c *customCodecPayloader) Payload(_ uint16, payload []byte) [][]byte {
c.invokeCount.Add(1)
return [][]byte{payload}
}

func Test_TrackLocalStatic_Payloader(t *testing.T) {
const mimeTypeCustomCodec = "video/custom-codec"

mediaEngine := &MediaEngine{}
assert.NoError(t, mediaEngine.RegisterCodec(RTPCodecParameters{
RTPCodecCapability: RTPCodecCapability{MimeType: mimeTypeCustomCodec, ClockRate: 90000, Channels: 0, SDPFmtpLine: "", RTCPFeedback: nil},
PayloadType: 96,
}, RTPCodecTypeVideo))

offerer, err := NewAPI(WithMediaEngine(mediaEngine)).NewPeerConnection(Configuration{})
assert.NoError(t, err)

answerer, err := NewAPI(WithMediaEngine(mediaEngine)).NewPeerConnection(Configuration{})
assert.NoError(t, err)

customPayloader := &customCodecPayloader{}
track, err := NewTrackLocalStaticSample(RTPCodecCapability{MimeType: mimeTypeCustomCodec}, "video", "pion", WithPayloader(func(c RTPCodecCapability) (rtp.Payloader, error) {
require.Equal(t, c.MimeType, mimeTypeCustomCodec)
return customPayloader, nil
}))
assert.NoError(t, err)

_, err = offerer.AddTrack(track)
assert.NoError(t, err)

assert.NoError(t, signalPair(offerer, answerer))

onTrackFired, onTrackFiredFunc := context.WithCancel(context.Background())
answerer.OnTrack(func(*TrackRemote, *RTPReceiver) {
onTrackFiredFunc()
})

sendVideoUntilDone(onTrackFired.Done(), t, []*TrackLocalStaticSample{track})

closePairNow(t, offerer, answerer)
}

0 comments on commit 271ab55

Please sign in to comment.