Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: allow media engine to register custom payloader on mimetype #2931

Merged
merged 1 commit into from
Oct 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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)
}
Loading