mirror of
https://github.com/livekit/livekit.git
synced 2026-04-15 06:25:40 +00:00
* Handle multiple codecs in renegotiation update pion to v3.1.9 for answer same order of codec as publisher. register enable codecs in subscriber peerconnectin created. add codec parameter to buffer.bind buffer should use the codec of TrackRemote as it's codec mime. sent h264blankframe when DownTrack closing
122 lines
3.9 KiB
Go
122 lines
3.9 KiB
Go
package rtc
|
|
|
|
import (
|
|
"strings"
|
|
|
|
livekit "github.com/livekit/protocol/proto"
|
|
"github.com/pion/sdp/v3"
|
|
"github.com/pion/webrtc/v3"
|
|
)
|
|
|
|
const (
|
|
frameMarking = "urn:ietf:params:rtp-hdrext:framemarking"
|
|
)
|
|
|
|
func registerCodecs(me *webrtc.MediaEngine, codecs []*livekit.Codec) error {
|
|
opusCodec := webrtc.RTPCodecCapability{MimeType: webrtc.MimeTypeOpus, ClockRate: 48000, Channels: 2, SDPFmtpLine: "minptime=10;useinbandfec=1", RTCPFeedback: nil}
|
|
if isCodecEnabled(codecs, opusCodec) {
|
|
if err := me.RegisterCodec(webrtc.RTPCodecParameters{
|
|
RTPCodecCapability: opusCodec,
|
|
PayloadType: 111,
|
|
}, webrtc.RTPCodecTypeAudio); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
videoRTCPFeedback := []webrtc.RTCPFeedback{
|
|
{Type: webrtc.TypeRTCPFBGoogREMB, Parameter: ""},
|
|
{Type: webrtc.TypeRTCPFBCCM, Parameter: "fir"},
|
|
{Type: webrtc.TypeRTCPFBNACK, Parameter: ""},
|
|
{Type: webrtc.TypeRTCPFBNACK, Parameter: "pli"}}
|
|
for _, codec := range []webrtc.RTPCodecParameters{
|
|
{
|
|
RTPCodecCapability: webrtc.RTPCodecCapability{MimeType: webrtc.MimeTypeVP8, ClockRate: 90000, RTCPFeedback: videoRTCPFeedback},
|
|
PayloadType: 96,
|
|
},
|
|
{
|
|
RTPCodecCapability: webrtc.RTPCodecCapability{MimeType: webrtc.MimeTypeVP9, ClockRate: 90000, SDPFmtpLine: "profile-id=0", RTCPFeedback: videoRTCPFeedback},
|
|
PayloadType: 98,
|
|
},
|
|
{
|
|
RTPCodecCapability: webrtc.RTPCodecCapability{MimeType: webrtc.MimeTypeVP9, ClockRate: 90000, SDPFmtpLine: "profile-id=1", RTCPFeedback: videoRTCPFeedback},
|
|
PayloadType: 100,
|
|
},
|
|
{
|
|
RTPCodecCapability: webrtc.RTPCodecCapability{MimeType: webrtc.MimeTypeH264, ClockRate: 90000, SDPFmtpLine: "level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f", RTCPFeedback: videoRTCPFeedback},
|
|
PayloadType: 125,
|
|
},
|
|
{
|
|
RTPCodecCapability: webrtc.RTPCodecCapability{MimeType: webrtc.MimeTypeH264, ClockRate: 90000, SDPFmtpLine: "level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=42e01f", RTCPFeedback: videoRTCPFeedback},
|
|
PayloadType: 108,
|
|
},
|
|
{
|
|
RTPCodecCapability: webrtc.RTPCodecCapability{MimeType: webrtc.MimeTypeH264, ClockRate: 90000, SDPFmtpLine: "level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=640032", RTCPFeedback: videoRTCPFeedback},
|
|
PayloadType: 123,
|
|
},
|
|
} {
|
|
if isCodecEnabled(codecs, codec.RTPCodecCapability) {
|
|
if err := me.RegisterCodec(codec, webrtc.RTPCodecTypeVideo); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func createPubMediaEngine(codecs []*livekit.Codec) (*webrtc.MediaEngine, error) {
|
|
me := &webrtc.MediaEngine{}
|
|
if err := registerCodecs(me, codecs); err != nil {
|
|
return nil, err
|
|
}
|
|
for _, extension := range []string{
|
|
sdp.SDESMidURI,
|
|
sdp.SDESRTPStreamIDURI,
|
|
sdp.TransportCCURI,
|
|
frameMarking,
|
|
} {
|
|
if err := me.RegisterHeaderExtension(webrtc.RTPHeaderExtensionCapability{URI: extension}, webrtc.RTPCodecTypeVideo); err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
for _, extension := range []string{
|
|
sdp.SDESMidURI,
|
|
sdp.SDESRTPStreamIDURI,
|
|
sdp.AudioLevelURI,
|
|
} {
|
|
if err := me.RegisterHeaderExtension(webrtc.RTPHeaderExtensionCapability{URI: extension}, webrtc.RTPCodecTypeAudio); err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
return me, nil
|
|
}
|
|
|
|
func createSubMediaEngine(codecs []*livekit.Codec) (*webrtc.MediaEngine, error) {
|
|
me := &webrtc.MediaEngine{}
|
|
if err := registerCodecs(me, codecs); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
for _, extension := range []string{
|
|
sdp.ABSSendTimeURI,
|
|
} {
|
|
if err := me.RegisterHeaderExtension(webrtc.RTPHeaderExtensionCapability{URI: extension}, webrtc.RTPCodecTypeVideo); err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
return me, nil
|
|
}
|
|
|
|
func isCodecEnabled(codecs []*livekit.Codec, cap webrtc.RTPCodecCapability) bool {
|
|
for _, codec := range codecs {
|
|
if !strings.EqualFold(codec.Mime, cap.MimeType) {
|
|
continue
|
|
}
|
|
if codec.FmtpLine == "" || strings.EqualFold(codec.FmtpLine, cap.SDPFmtpLine) {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|