mirror of
https://github.com/livekit/livekit.git
synced 2026-08-07 01:49:47 +00:00
fix: revert recent changes to determine simulcast from sdp (#3565)
* Revert "Audio uses signal SignalCid and SdpCid. (#3564)" This reverts commitcdfbb106d1. * Revert "Keep simulcast information tied to receiver. (#3563)" This reverts commited5e2f16b2. * Revert "chore(logs): log VLS type for VP9/AV1 (#3561)" This reverts commitad010cfc43. * Revert "fix(video): determine svc/simulcast from SDP for advanced codecs (#3549)" This reverts commit15f565510c. * chore(deps): update protocol
This commit is contained in:
@@ -23,7 +23,7 @@ require (
|
||||
github.com/jxskiss/base62 v1.1.0
|
||||
github.com/livekit/mageutil v0.0.0-20230125210925-54e8a70427c1
|
||||
github.com/livekit/mediatransportutil v0.0.0-20250310153736-45596af895b6
|
||||
github.com/livekit/protocol v1.36.2-0.20250331123911-67af9b92e4ac
|
||||
github.com/livekit/protocol v1.36.2-0.20250331173645-dbeeaa7e264b
|
||||
github.com/livekit/psrpc v0.6.1-0.20250205181828-a0beed2e4126
|
||||
github.com/mackerelio/go-osstat v0.2.5
|
||||
github.com/magefile/mage v1.15.0
|
||||
|
||||
@@ -170,8 +170,8 @@ github.com/livekit/mageutil v0.0.0-20230125210925-54e8a70427c1 h1:jm09419p0lqTkD
|
||||
github.com/livekit/mageutil v0.0.0-20230125210925-54e8a70427c1/go.mod h1:Rs3MhFwutWhGwmY1VQsygw28z5bWcnEYmS1OG9OxjOQ=
|
||||
github.com/livekit/mediatransportutil v0.0.0-20250310153736-45596af895b6 h1:6ZhtnY9I9knfm3ieIPpznQSEU2rDECO8yliW/ANLQ7U=
|
||||
github.com/livekit/mediatransportutil v0.0.0-20250310153736-45596af895b6/go.mod h1:36s+wwmU3O40IAhE+MjBWP3W71QRiEE9SfooSBvtBqY=
|
||||
github.com/livekit/protocol v1.36.2-0.20250331123911-67af9b92e4ac h1:mEb60UmuJdilpY9WbrdA7L1OgdfBKX9SlRa7GuKMYL8=
|
||||
github.com/livekit/protocol v1.36.2-0.20250331123911-67af9b92e4ac/go.mod h1:WrT/CYRxtMNOVUjnIPm5OjWtEkmreffTeE1PRZwlRg4=
|
||||
github.com/livekit/protocol v1.36.2-0.20250331173645-dbeeaa7e264b h1:RGti8X/Khmpt5MVVMiQBtzuTAeCHgPVCXr19lhLZXI8=
|
||||
github.com/livekit/protocol v1.36.2-0.20250331173645-dbeeaa7e264b/go.mod h1:WrT/CYRxtMNOVUjnIPm5OjWtEkmreffTeE1PRZwlRg4=
|
||||
github.com/livekit/psrpc v0.6.1-0.20250205181828-a0beed2e4126 h1:fzuYpAQbCid7ySPpQWWePfQOWUrs8x6dJ0T3Wl07n+Y=
|
||||
github.com/livekit/psrpc v0.6.1-0.20250205181828-a0beed2e4126/go.mod h1:X5WtEZ7OnEs72Fi5/J+i0on3964F1aynQpCalcgMqRo=
|
||||
github.com/mackerelio/go-osstat v0.2.5 h1:+MqTbZUhoIt4m8qzkVoXUJg1EuifwlAJSk4Yl2GXh+o=
|
||||
|
||||
+17
-26
@@ -42,6 +42,7 @@ import (
|
||||
// Implements MediaTrack and PublishedTrack interface
|
||||
type MediaTrack struct {
|
||||
params MediaTrackParams
|
||||
numUpTracks atomic.Uint32
|
||||
buffer *buffer.Buffer
|
||||
everSubscribed atomic.Bool
|
||||
|
||||
@@ -176,27 +177,8 @@ func (t *MediaTrack) NotifySubscriberNodeMaxQuality(nodeID livekit.NodeID, quali
|
||||
}
|
||||
}
|
||||
|
||||
func (t *MediaTrack) HasSignalCid(cid string) bool {
|
||||
if t.params.SignalCid == cid {
|
||||
return true
|
||||
}
|
||||
|
||||
for _, c := range t.MediaTrackReceiver.TrackInfo().Codecs {
|
||||
if c.SignalCid == cid {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (t *MediaTrack) SdpCids() []string {
|
||||
var sdpCids []string
|
||||
for _, c := range t.MediaTrackReceiver.TrackInfo().Codecs {
|
||||
if c.SdpCid != "" {
|
||||
sdpCids = append(sdpCids, c.SdpCid)
|
||||
}
|
||||
}
|
||||
return sdpCids
|
||||
func (t *MediaTrack) SignalCid() string {
|
||||
return t.params.SignalCid
|
||||
}
|
||||
|
||||
func (t *MediaTrack) HasSdpCid(cid string) bool {
|
||||
@@ -204,8 +186,9 @@ func (t *MediaTrack) HasSdpCid(cid string) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
for _, c := range t.MediaTrackReceiver.TrackInfo().Codecs {
|
||||
if c.SdpCid == cid {
|
||||
ti := t.MediaTrackReceiver.TrackInfoClone()
|
||||
for _, c := range ti.Codecs {
|
||||
if c.Cid == cid {
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -216,8 +199,12 @@ func (t *MediaTrack) ToProto() *livekit.TrackInfo {
|
||||
return t.MediaTrackReceiver.TrackInfoClone()
|
||||
}
|
||||
|
||||
func (t *MediaTrack) UpdateCodecCid(codecs []*livekit.SimulcastCodec) {
|
||||
t.MediaTrackReceiver.UpdateCodecCid(codecs)
|
||||
}
|
||||
|
||||
// AddReceiver adds a new RTP receiver to the track, returns true when receiver represents a new codec
|
||||
func (t *MediaTrack) AddReceiver(receiver *webrtc.RTPReceiver, track sfu.TrackRemote, mid string, isSimulcast bool) bool {
|
||||
func (t *MediaTrack) AddReceiver(receiver *webrtc.RTPReceiver, track sfu.TrackRemote, mid string) bool {
|
||||
var newCodec bool
|
||||
ssrc := uint32(track.SSRC())
|
||||
buff, rtcpReader := t.params.BufferFactory.GetBufferPair(ssrc)
|
||||
@@ -264,7 +251,6 @@ func (t *MediaTrack) AddReceiver(receiver *webrtc.RTPReceiver, track sfu.TrackRe
|
||||
}
|
||||
})
|
||||
|
||||
t.MediaTrackReceiver.UpdateCodecInfo(track.Codec().MimeType, track.ID(), isSimulcast)
|
||||
ti := t.MediaTrackReceiver.TrackInfoClone()
|
||||
t.lock.Lock()
|
||||
var regressCodec bool
|
||||
@@ -272,7 +258,6 @@ func (t *MediaTrack) AddReceiver(receiver *webrtc.RTPReceiver, track sfu.TrackRe
|
||||
layer := buffer.RidToSpatialLayer(track.RID(), ti)
|
||||
t.params.Logger.Debugw(
|
||||
"AddReceiver",
|
||||
"cid", track.ID(),
|
||||
"rid", track.RID(),
|
||||
"layer", layer,
|
||||
"ssrc", track.SSRC(),
|
||||
@@ -410,6 +395,12 @@ func (t *MediaTrack) AddReceiver(receiver *webrtc.RTPReceiver, track sfu.TrackRe
|
||||
return false
|
||||
}
|
||||
|
||||
// LK-TODO: can remove this completely when VideoLayers protocol becomes the default as it has info from client or if we decide to use TrackInfo.Simulcast
|
||||
if t.numUpTracks.Inc() > 1 || track.RID() != "" {
|
||||
// cannot only rely on numUpTracks since we fire metadata events immediately after the first layer
|
||||
t.SetSimulcast(true)
|
||||
}
|
||||
|
||||
var bitrates int
|
||||
if len(ti.Layers) > int(layer) {
|
||||
bitrates = int(ti.Layers[layer].GetBitrate())
|
||||
|
||||
@@ -498,15 +498,9 @@ func (t *MediaTrackReceiver) SetSimulcast(simulcast bool) {
|
||||
t.lock.Lock()
|
||||
defer t.lock.Unlock()
|
||||
|
||||
if t.IsSimulcast() != simulcast {
|
||||
trackInfo := t.TrackInfoClone()
|
||||
trackInfo.Simulcast = simulcast
|
||||
t.trackInfo.Store(trackInfo)
|
||||
}
|
||||
}
|
||||
|
||||
func (t *MediaTrackReceiver) HasMultipleSpatialLayers() bool {
|
||||
return len(t.TrackInfo().Layers) > 1
|
||||
trackInfo := t.TrackInfoClone()
|
||||
trackInfo.Simulcast = simulcast
|
||||
t.trackInfo.Store(trackInfo)
|
||||
}
|
||||
|
||||
func (t *MediaTrackReceiver) Name() string {
|
||||
@@ -713,13 +707,13 @@ func (t *MediaTrackReceiver) SetLayerSsrc(mimeType mime.MimeType, rid string, ss
|
||||
t.updateTrackInfoOfReceivers()
|
||||
}
|
||||
|
||||
func (t *MediaTrackReceiver) UpdateCodecSignalCid(codecs []*livekit.SimulcastCodec) {
|
||||
func (t *MediaTrackReceiver) UpdateCodecCid(codecs []*livekit.SimulcastCodec) {
|
||||
t.lock.Lock()
|
||||
trackInfo := t.TrackInfoClone()
|
||||
for _, c := range codecs {
|
||||
for _, origin := range trackInfo.Codecs {
|
||||
if mime.GetMimeTypeCodec(origin.MimeType) == mime.NormalizeMimeTypeCodec(c.Codec) {
|
||||
origin.SignalCid = c.Cid
|
||||
origin.Cid = c.Cid
|
||||
break
|
||||
}
|
||||
}
|
||||
@@ -730,32 +724,6 @@ func (t *MediaTrackReceiver) UpdateCodecSignalCid(codecs []*livekit.SimulcastCod
|
||||
t.updateTrackInfoOfReceivers()
|
||||
}
|
||||
|
||||
func (t *MediaTrackReceiver) UpdateCodecInfo(mimeType string, cid string, isSimulcast bool) {
|
||||
t.lock.Lock()
|
||||
trackInfo := t.TrackInfoClone()
|
||||
for _, origin := range trackInfo.Codecs {
|
||||
if mime.IsMimeTypeStringEqual(origin.MimeType, mimeType) {
|
||||
if origin.SdpCid != "" {
|
||||
if origin.SdpCid != cid || origin.IsSimulcast != isSimulcast {
|
||||
t.params.Logger.Warnw(
|
||||
"uexpected codec info change", nil,
|
||||
"oldCid", origin.SdpCid, "newCid", cid,
|
||||
"oldIsSimulcast", origin.IsSimulcast, "newIsSimulcast", isSimulcast,
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
origin.SdpCid = cid
|
||||
origin.IsSimulcast = isSimulcast
|
||||
break
|
||||
}
|
||||
}
|
||||
t.trackInfo.Store(trackInfo)
|
||||
t.lock.Unlock()
|
||||
|
||||
t.updateTrackInfoOfReceivers()
|
||||
}
|
||||
|
||||
func (t *MediaTrackReceiver) UpdateTrackInfo(ti *livekit.TrackInfo) {
|
||||
updateMute := false
|
||||
clonedInfo := utils.CloneProto(ti)
|
||||
|
||||
+11
-65
@@ -37,7 +37,6 @@ import (
|
||||
"github.com/livekit/protocol/auth"
|
||||
"github.com/livekit/protocol/livekit"
|
||||
"github.com/livekit/protocol/logger"
|
||||
sdpHelper "github.com/livekit/protocol/sdp"
|
||||
"github.com/livekit/protocol/utils"
|
||||
"github.com/livekit/protocol/utils/guid"
|
||||
|
||||
@@ -207,8 +206,6 @@ type ParticipantImpl struct {
|
||||
pendingPublishingTracks map[livekit.TrackID]*pendingTrackInfo
|
||||
pendingRemoteTracks []*pendingRemoteTrack
|
||||
|
||||
simulcastTrackIds sync.Map
|
||||
|
||||
// supported codecs
|
||||
enabledPublishCodecs []*livekit.Codec
|
||||
enabledSubscribeCodecs []*livekit.Codec
|
||||
@@ -873,29 +870,10 @@ func (p *ParticipantImpl) synthesizeAddTrackRequests(offer webrtc.SessionDescrip
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *ParticipantImpl) findAndStoreSimulcastTrackIds(offer webrtc.SessionDescription) {
|
||||
parsed, err := offer.Unmarshal()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
for _, m := range parsed.MediaDescriptions {
|
||||
if m.MediaName.Media != "video" {
|
||||
continue
|
||||
}
|
||||
if sdpHelper.IsMediaDescriptionSimulcast(m) {
|
||||
trackID := sdpHelper.GetTrackIDFromMediaDescription(m)
|
||||
p.simulcastTrackIds.LoadOrStore(trackID, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// HandleOffer an offer from remote participant, used when clients make the initial connection
|
||||
func (p *ParticipantImpl) HandleOffer(offer webrtc.SessionDescription) error {
|
||||
p.pubLogger.Debugw("received offer", "transport", livekit.SignalTarget_PUBLISHER, "offer", offer)
|
||||
|
||||
p.findAndStoreSimulcastTrackIds(offer)
|
||||
|
||||
if p.params.UseOneShotSignallingMode {
|
||||
if err := p.synthesizeAddTrackRequests(offer); err != nil {
|
||||
return err
|
||||
@@ -1081,7 +1059,6 @@ func (p *ParticipantImpl) Close(sendLeave bool, reason types.ParticipantCloseRea
|
||||
p.pendingTracksLock.Lock()
|
||||
p.pendingTracks = make(map[string]*pendingTrackInfo)
|
||||
p.pendingPublishingTracks = make(map[livekit.TrackID]*pendingTrackInfo)
|
||||
p.simulcastTrackIds.Clear()
|
||||
p.pendingTracksLock.Unlock()
|
||||
|
||||
p.UpTrackManager.Close(isExpectedToResume)
|
||||
@@ -1760,13 +1737,6 @@ func (p *ParticipantImpl) onSubscriberOffer(offer webrtc.SessionDescription) err
|
||||
|
||||
func (p *ParticipantImpl) removePublishedTrack(track types.MediaTrack) {
|
||||
p.RemovePublishedTrack(track, false, true)
|
||||
|
||||
if lmt, ok := track.(types.LocalMediaTrack); ok {
|
||||
for _, sdpCid := range lmt.SdpCids() {
|
||||
p.simulcastTrackIds.Delete(sdpCid)
|
||||
}
|
||||
}
|
||||
|
||||
if p.ProtocolVersion().SupportsUnpublish() {
|
||||
p.sendTrackUnpublished(track.ID())
|
||||
} else {
|
||||
@@ -1810,13 +1780,7 @@ func (p *ParticipantImpl) onMediaTrack(rtcTrack *webrtc.TrackRemote, rtpReceiver
|
||||
codec = codecs[0]
|
||||
fromSdp = true
|
||||
}
|
||||
p.params.Logger.Debugw(
|
||||
"onMediaTrack",
|
||||
"codec", codec,
|
||||
"payloadType", codec.PayloadType,
|
||||
"fromSdp", fromSdp,
|
||||
"parameters", rtpReceiver.GetParameters(),
|
||||
)
|
||||
p.params.Logger.Debugw("onMediaTrack", "codec", codec, "payloadType", codec.PayloadType, "fromSdp", fromSdp, "parameters", rtpReceiver.GetParameters())
|
||||
|
||||
var track sfu.TrackRemote = sfu.NewTrackRemoteFromSdp(rtcTrack, codec)
|
||||
publishedTrack, isNewTrack := p.mediaTrackReceived(track, rtpReceiver)
|
||||
@@ -2247,7 +2211,7 @@ func (p *ParticipantImpl) addPendingTrackLocked(req *livekit.AddTrackRequest) *l
|
||||
return nil
|
||||
}
|
||||
|
||||
track.(*MediaTrack).UpdateCodecSignalCid(req.SimulcastCodecs)
|
||||
track.(*MediaTrack).UpdateCodecCid(req.SimulcastCodecs)
|
||||
ti := track.ToProto()
|
||||
return ti
|
||||
}
|
||||
@@ -2287,8 +2251,8 @@ func (p *ParticipantImpl) addPendingTrackLocked(req *livekit.AddTrackRequest) *l
|
||||
if req.Type == livekit.TrackType_VIDEO {
|
||||
// clients not supporting simulcast codecs, synthesise a codec
|
||||
ti.Codecs = append(ti.Codecs, &livekit.SimulcastCodecInfo{
|
||||
SignalCid: req.Cid,
|
||||
Layers: req.Layers,
|
||||
Cid: req.Cid,
|
||||
Layers: req.Layers,
|
||||
})
|
||||
}
|
||||
} else {
|
||||
@@ -2323,9 +2287,9 @@ func (p *ParticipantImpl) addPendingTrackLocked(req *livekit.AddTrackRequest) *l
|
||||
clonedLayers = append(clonedLayers, utils.CloneProto(l))
|
||||
}
|
||||
ti.Codecs = append(ti.Codecs, &livekit.SimulcastCodecInfo{
|
||||
MimeType: mimeType,
|
||||
SignalCid: codec.Cid,
|
||||
Layers: clonedLayers,
|
||||
MimeType: mimeType,
|
||||
Cid: codec.Cid,
|
||||
Layers: clonedLayers,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -2449,20 +2413,10 @@ func (p *ParticipantImpl) mediaTrackReceived(track sfu.TrackRemote, rtpReceiver
|
||||
return nil, false
|
||||
}
|
||||
|
||||
receiverIsSimulcast := false
|
||||
cidIsSimulcast, ok := p.simulcastTrackIds.Load(track.ID())
|
||||
if ok {
|
||||
receiverIsSimulcast = cidIsSimulcast.(bool)
|
||||
}
|
||||
|
||||
// use existing media track to handle simulcast
|
||||
var pubTime time.Duration
|
||||
var isMigrated bool
|
||||
mt, ok := p.getPublishedTrackBySdpCid(track.ID()).(*MediaTrack)
|
||||
if !ok {
|
||||
// only works for clients using same cid in signal and SDP, so won't work for clients like Firefox
|
||||
mt, ok = p.getPublishedTrackBySignalCid(track.ID()).(*MediaTrack)
|
||||
}
|
||||
if !ok {
|
||||
signalCid, ti, migrated, createdAt := p.getPendingTrack(track.ID(), ToProtoTrackKind(track.Kind()), true)
|
||||
if ti == nil {
|
||||
@@ -2501,10 +2455,6 @@ func (p *ParticipantImpl) mediaTrackReceived(track sfu.TrackRemote, rtpReceiver
|
||||
// only assign version on a fresh publish, i. e. avoid updating version in scenarios like migration
|
||||
ti.Version = p.params.VersionGenerator.Next().ToProto()
|
||||
}
|
||||
// track level simulcast set up only for the primary codec
|
||||
// assumption: when a new track is created, it is the primary codec that causes that
|
||||
ti.Simulcast = receiverIsSimulcast
|
||||
|
||||
mt = p.addMediaTrack(signalCid, track.ID(), ti)
|
||||
newTrack = true
|
||||
|
||||
@@ -2517,9 +2467,10 @@ func (p *ParticipantImpl) mediaTrackReceived(track sfu.TrackRemote, rtpReceiver
|
||||
pubTime = time.Since(createdAt)
|
||||
p.dirty.Store(true)
|
||||
}
|
||||
|
||||
p.pendingTracksLock.Unlock()
|
||||
|
||||
mt.AddReceiver(rtpReceiver, track, mid, receiverIsSimulcast)
|
||||
mt.AddReceiver(rtpReceiver, track, mid)
|
||||
|
||||
if newTrack {
|
||||
go func() {
|
||||
@@ -2670,10 +2621,6 @@ func (p *ParticipantImpl) addMediaTrack(signalCid string, sdpCid string, ti *liv
|
||||
)
|
||||
}
|
||||
|
||||
for _, sdpCid := range mt.SdpCids() {
|
||||
p.simulcastTrackIds.Delete(sdpCid)
|
||||
}
|
||||
|
||||
p.pendingTracksLock.Lock()
|
||||
if pti := p.pendingTracks[signalCid]; pti != nil {
|
||||
p.sendTrackPublished(signalCid, pti.trackInfos[0])
|
||||
@@ -2746,7 +2693,7 @@ func (p *ParticipantImpl) getPendingTrack(clientId string, kind livekit.TrackTyp
|
||||
for cid, pti := range p.pendingTracks {
|
||||
ti := pti.trackInfos[0]
|
||||
for _, c := range ti.Codecs {
|
||||
if c.SignalCid == clientId {
|
||||
if c.Cid == clientId {
|
||||
pendingInfo = pti
|
||||
signalCid = cid
|
||||
break track_loop
|
||||
@@ -2813,8 +2760,7 @@ func (p *ParticipantImpl) setTrackID(cid string, info *livekit.TrackInfo) {
|
||||
|
||||
func (p *ParticipantImpl) getPublishedTrackBySignalCid(clientId string) types.MediaTrack {
|
||||
for _, publishedTrack := range p.GetPublishedTracks() {
|
||||
if publishedTrack.(types.LocalMediaTrack).HasSignalCid(clientId) {
|
||||
p.pubLogger.Debugw("found track by signal cid", "signalCid", clientId, "trackID", publishedTrack.ID())
|
||||
if publishedTrack.(types.LocalMediaTrack).SignalCid() == clientId {
|
||||
return publishedTrack
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,7 +137,7 @@ func TestTrackPublishing(t *testing.T) {
|
||||
sink := p.params.Sink.(*routingfakes.FakeMessageSink)
|
||||
|
||||
track := &typesfakes.FakeLocalMediaTrack{}
|
||||
track.HasSignalCidReturns(true)
|
||||
track.SignalCidReturns("cid")
|
||||
track.ToProtoReturns(&livekit.TrackInfo{})
|
||||
// directly add to publishedTracks without lock - for testing purpose only
|
||||
p.UpTrackManager.publishedTracks["cid"] = track
|
||||
|
||||
@@ -141,12 +141,7 @@ func (p *ParticipantImpl) setCodecPreferencesVideoForPublisher(offer webrtc.Sess
|
||||
}
|
||||
var mimeType string
|
||||
for _, c := range info.Codecs {
|
||||
// this is reading streamID from SDP which is technically SDP cid,
|
||||
// but it is not set in TrackInfo by the time this is checked,
|
||||
// hence the check on signal cid.
|
||||
// As a result, this will fail for clients that use different cid
|
||||
// while signalling and while doing negotiation (e. g. Firefox)
|
||||
if c.SignalCid == streamID {
|
||||
if c.Cid == streamID {
|
||||
mimeType = c.MimeType
|
||||
break
|
||||
}
|
||||
|
||||
@@ -242,7 +242,10 @@ func TestUnsubscribe(t *testing.T) {
|
||||
sm.lock.RLock()
|
||||
subLen := len(sm.subscriptions)
|
||||
sm.lock.RUnlock()
|
||||
return subLen == 0
|
||||
if subLen != 0 {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}, subSettleTimeout, subCheckInterval, "Track was not unsubscribed")
|
||||
|
||||
// no traces should be left
|
||||
|
||||
@@ -1322,7 +1322,7 @@ func (t *PCTransport) AddTrackToStreamAllocator(subTrack types.SubscribedTrack)
|
||||
|
||||
t.streamAllocator.AddTrack(subTrack.DownTrack(), streamallocator.AddTrackParams{
|
||||
Source: subTrack.MediaTrack().Source(),
|
||||
IsSimulcast: subTrack.MediaTrack().HasMultipleSpatialLayers(),
|
||||
IsSimulcast: subTrack.MediaTrack().IsSimulcast(),
|
||||
PublisherID: subTrack.MediaTrack().PublisherID(),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -506,7 +506,6 @@ type MediaTrack interface {
|
||||
SetMuted(muted bool)
|
||||
|
||||
IsSimulcast() bool
|
||||
HasMultipleSpatialLayers() bool
|
||||
|
||||
GetAudioLevel() (level float64, active bool)
|
||||
|
||||
@@ -543,8 +542,7 @@ type LocalMediaTrack interface {
|
||||
|
||||
Restart()
|
||||
|
||||
HasSignalCid(cid string) bool
|
||||
SdpCids() []string
|
||||
SignalCid() string
|
||||
HasSdpCid(cid string) bool
|
||||
|
||||
GetConnectionScoreAndQuality() (float32, livekit.ConnectionQuality)
|
||||
|
||||
@@ -118,16 +118,6 @@ type FakeLocalMediaTrack struct {
|
||||
getTrackStatsReturnsOnCall map[int]struct {
|
||||
result1 *livekit.RTPStats
|
||||
}
|
||||
HasMultipleSpatialLayersStub func() bool
|
||||
hasMultipleSpatialLayersMutex sync.RWMutex
|
||||
hasMultipleSpatialLayersArgsForCall []struct {
|
||||
}
|
||||
hasMultipleSpatialLayersReturns struct {
|
||||
result1 bool
|
||||
}
|
||||
hasMultipleSpatialLayersReturnsOnCall map[int]struct {
|
||||
result1 bool
|
||||
}
|
||||
HasSdpCidStub func(string) bool
|
||||
hasSdpCidMutex sync.RWMutex
|
||||
hasSdpCidArgsForCall []struct {
|
||||
@@ -139,17 +129,6 @@ type FakeLocalMediaTrack struct {
|
||||
hasSdpCidReturnsOnCall map[int]struct {
|
||||
result1 bool
|
||||
}
|
||||
HasSignalCidStub func(string) bool
|
||||
hasSignalCidMutex sync.RWMutex
|
||||
hasSignalCidArgsForCall []struct {
|
||||
arg1 string
|
||||
}
|
||||
hasSignalCidReturns struct {
|
||||
result1 bool
|
||||
}
|
||||
hasSignalCidReturnsOnCall map[int]struct {
|
||||
result1 bool
|
||||
}
|
||||
IDStub func() livekit.TrackID
|
||||
iDMutex sync.RWMutex
|
||||
iDArgsForCall []struct {
|
||||
@@ -308,16 +287,6 @@ type FakeLocalMediaTrack struct {
|
||||
revokeDisallowedSubscribersReturnsOnCall map[int]struct {
|
||||
result1 []livekit.ParticipantIdentity
|
||||
}
|
||||
SdpCidsStub func() []string
|
||||
sdpCidsMutex sync.RWMutex
|
||||
sdpCidsArgsForCall []struct {
|
||||
}
|
||||
sdpCidsReturns struct {
|
||||
result1 []string
|
||||
}
|
||||
sdpCidsReturnsOnCall map[int]struct {
|
||||
result1 []string
|
||||
}
|
||||
SetMutedStub func(bool)
|
||||
setMutedMutex sync.RWMutex
|
||||
setMutedArgsForCall []struct {
|
||||
@@ -328,6 +297,16 @@ type FakeLocalMediaTrack struct {
|
||||
setRTTArgsForCall []struct {
|
||||
arg1 uint32
|
||||
}
|
||||
SignalCidStub func() string
|
||||
signalCidMutex sync.RWMutex
|
||||
signalCidArgsForCall []struct {
|
||||
}
|
||||
signalCidReturns struct {
|
||||
result1 string
|
||||
}
|
||||
signalCidReturnsOnCall map[int]struct {
|
||||
result1 string
|
||||
}
|
||||
SourceStub func() livekit.TrackSource
|
||||
sourceMutex sync.RWMutex
|
||||
sourceArgsForCall []struct {
|
||||
@@ -933,59 +912,6 @@ func (fake *FakeLocalMediaTrack) GetTrackStatsReturnsOnCall(i int, result1 *live
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeLocalMediaTrack) HasMultipleSpatialLayers() bool {
|
||||
fake.hasMultipleSpatialLayersMutex.Lock()
|
||||
ret, specificReturn := fake.hasMultipleSpatialLayersReturnsOnCall[len(fake.hasMultipleSpatialLayersArgsForCall)]
|
||||
fake.hasMultipleSpatialLayersArgsForCall = append(fake.hasMultipleSpatialLayersArgsForCall, struct {
|
||||
}{})
|
||||
stub := fake.HasMultipleSpatialLayersStub
|
||||
fakeReturns := fake.hasMultipleSpatialLayersReturns
|
||||
fake.recordInvocation("HasMultipleSpatialLayers", []interface{}{})
|
||||
fake.hasMultipleSpatialLayersMutex.Unlock()
|
||||
if stub != nil {
|
||||
return stub()
|
||||
}
|
||||
if specificReturn {
|
||||
return ret.result1
|
||||
}
|
||||
return fakeReturns.result1
|
||||
}
|
||||
|
||||
func (fake *FakeLocalMediaTrack) HasMultipleSpatialLayersCallCount() int {
|
||||
fake.hasMultipleSpatialLayersMutex.RLock()
|
||||
defer fake.hasMultipleSpatialLayersMutex.RUnlock()
|
||||
return len(fake.hasMultipleSpatialLayersArgsForCall)
|
||||
}
|
||||
|
||||
func (fake *FakeLocalMediaTrack) HasMultipleSpatialLayersCalls(stub func() bool) {
|
||||
fake.hasMultipleSpatialLayersMutex.Lock()
|
||||
defer fake.hasMultipleSpatialLayersMutex.Unlock()
|
||||
fake.HasMultipleSpatialLayersStub = stub
|
||||
}
|
||||
|
||||
func (fake *FakeLocalMediaTrack) HasMultipleSpatialLayersReturns(result1 bool) {
|
||||
fake.hasMultipleSpatialLayersMutex.Lock()
|
||||
defer fake.hasMultipleSpatialLayersMutex.Unlock()
|
||||
fake.HasMultipleSpatialLayersStub = nil
|
||||
fake.hasMultipleSpatialLayersReturns = struct {
|
||||
result1 bool
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeLocalMediaTrack) HasMultipleSpatialLayersReturnsOnCall(i int, result1 bool) {
|
||||
fake.hasMultipleSpatialLayersMutex.Lock()
|
||||
defer fake.hasMultipleSpatialLayersMutex.Unlock()
|
||||
fake.HasMultipleSpatialLayersStub = nil
|
||||
if fake.hasMultipleSpatialLayersReturnsOnCall == nil {
|
||||
fake.hasMultipleSpatialLayersReturnsOnCall = make(map[int]struct {
|
||||
result1 bool
|
||||
})
|
||||
}
|
||||
fake.hasMultipleSpatialLayersReturnsOnCall[i] = struct {
|
||||
result1 bool
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeLocalMediaTrack) HasSdpCid(arg1 string) bool {
|
||||
fake.hasSdpCidMutex.Lock()
|
||||
ret, specificReturn := fake.hasSdpCidReturnsOnCall[len(fake.hasSdpCidArgsForCall)]
|
||||
@@ -1047,67 +973,6 @@ func (fake *FakeLocalMediaTrack) HasSdpCidReturnsOnCall(i int, result1 bool) {
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeLocalMediaTrack) HasSignalCid(arg1 string) bool {
|
||||
fake.hasSignalCidMutex.Lock()
|
||||
ret, specificReturn := fake.hasSignalCidReturnsOnCall[len(fake.hasSignalCidArgsForCall)]
|
||||
fake.hasSignalCidArgsForCall = append(fake.hasSignalCidArgsForCall, struct {
|
||||
arg1 string
|
||||
}{arg1})
|
||||
stub := fake.HasSignalCidStub
|
||||
fakeReturns := fake.hasSignalCidReturns
|
||||
fake.recordInvocation("HasSignalCid", []interface{}{arg1})
|
||||
fake.hasSignalCidMutex.Unlock()
|
||||
if stub != nil {
|
||||
return stub(arg1)
|
||||
}
|
||||
if specificReturn {
|
||||
return ret.result1
|
||||
}
|
||||
return fakeReturns.result1
|
||||
}
|
||||
|
||||
func (fake *FakeLocalMediaTrack) HasSignalCidCallCount() int {
|
||||
fake.hasSignalCidMutex.RLock()
|
||||
defer fake.hasSignalCidMutex.RUnlock()
|
||||
return len(fake.hasSignalCidArgsForCall)
|
||||
}
|
||||
|
||||
func (fake *FakeLocalMediaTrack) HasSignalCidCalls(stub func(string) bool) {
|
||||
fake.hasSignalCidMutex.Lock()
|
||||
defer fake.hasSignalCidMutex.Unlock()
|
||||
fake.HasSignalCidStub = stub
|
||||
}
|
||||
|
||||
func (fake *FakeLocalMediaTrack) HasSignalCidArgsForCall(i int) string {
|
||||
fake.hasSignalCidMutex.RLock()
|
||||
defer fake.hasSignalCidMutex.RUnlock()
|
||||
argsForCall := fake.hasSignalCidArgsForCall[i]
|
||||
return argsForCall.arg1
|
||||
}
|
||||
|
||||
func (fake *FakeLocalMediaTrack) HasSignalCidReturns(result1 bool) {
|
||||
fake.hasSignalCidMutex.Lock()
|
||||
defer fake.hasSignalCidMutex.Unlock()
|
||||
fake.HasSignalCidStub = nil
|
||||
fake.hasSignalCidReturns = struct {
|
||||
result1 bool
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeLocalMediaTrack) HasSignalCidReturnsOnCall(i int, result1 bool) {
|
||||
fake.hasSignalCidMutex.Lock()
|
||||
defer fake.hasSignalCidMutex.Unlock()
|
||||
fake.HasSignalCidStub = nil
|
||||
if fake.hasSignalCidReturnsOnCall == nil {
|
||||
fake.hasSignalCidReturnsOnCall = make(map[int]struct {
|
||||
result1 bool
|
||||
})
|
||||
}
|
||||
fake.hasSignalCidReturnsOnCall[i] = struct {
|
||||
result1 bool
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeLocalMediaTrack) ID() livekit.TrackID {
|
||||
fake.iDMutex.Lock()
|
||||
ret, specificReturn := fake.iDReturnsOnCall[len(fake.iDArgsForCall)]
|
||||
@@ -1970,59 +1835,6 @@ func (fake *FakeLocalMediaTrack) RevokeDisallowedSubscribersReturnsOnCall(i int,
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeLocalMediaTrack) SdpCids() []string {
|
||||
fake.sdpCidsMutex.Lock()
|
||||
ret, specificReturn := fake.sdpCidsReturnsOnCall[len(fake.sdpCidsArgsForCall)]
|
||||
fake.sdpCidsArgsForCall = append(fake.sdpCidsArgsForCall, struct {
|
||||
}{})
|
||||
stub := fake.SdpCidsStub
|
||||
fakeReturns := fake.sdpCidsReturns
|
||||
fake.recordInvocation("SdpCids", []interface{}{})
|
||||
fake.sdpCidsMutex.Unlock()
|
||||
if stub != nil {
|
||||
return stub()
|
||||
}
|
||||
if specificReturn {
|
||||
return ret.result1
|
||||
}
|
||||
return fakeReturns.result1
|
||||
}
|
||||
|
||||
func (fake *FakeLocalMediaTrack) SdpCidsCallCount() int {
|
||||
fake.sdpCidsMutex.RLock()
|
||||
defer fake.sdpCidsMutex.RUnlock()
|
||||
return len(fake.sdpCidsArgsForCall)
|
||||
}
|
||||
|
||||
func (fake *FakeLocalMediaTrack) SdpCidsCalls(stub func() []string) {
|
||||
fake.sdpCidsMutex.Lock()
|
||||
defer fake.sdpCidsMutex.Unlock()
|
||||
fake.SdpCidsStub = stub
|
||||
}
|
||||
|
||||
func (fake *FakeLocalMediaTrack) SdpCidsReturns(result1 []string) {
|
||||
fake.sdpCidsMutex.Lock()
|
||||
defer fake.sdpCidsMutex.Unlock()
|
||||
fake.SdpCidsStub = nil
|
||||
fake.sdpCidsReturns = struct {
|
||||
result1 []string
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeLocalMediaTrack) SdpCidsReturnsOnCall(i int, result1 []string) {
|
||||
fake.sdpCidsMutex.Lock()
|
||||
defer fake.sdpCidsMutex.Unlock()
|
||||
fake.SdpCidsStub = nil
|
||||
if fake.sdpCidsReturnsOnCall == nil {
|
||||
fake.sdpCidsReturnsOnCall = make(map[int]struct {
|
||||
result1 []string
|
||||
})
|
||||
}
|
||||
fake.sdpCidsReturnsOnCall[i] = struct {
|
||||
result1 []string
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeLocalMediaTrack) SetMuted(arg1 bool) {
|
||||
fake.setMutedMutex.Lock()
|
||||
fake.setMutedArgsForCall = append(fake.setMutedArgsForCall, struct {
|
||||
@@ -2087,6 +1899,59 @@ func (fake *FakeLocalMediaTrack) SetRTTArgsForCall(i int) uint32 {
|
||||
return argsForCall.arg1
|
||||
}
|
||||
|
||||
func (fake *FakeLocalMediaTrack) SignalCid() string {
|
||||
fake.signalCidMutex.Lock()
|
||||
ret, specificReturn := fake.signalCidReturnsOnCall[len(fake.signalCidArgsForCall)]
|
||||
fake.signalCidArgsForCall = append(fake.signalCidArgsForCall, struct {
|
||||
}{})
|
||||
stub := fake.SignalCidStub
|
||||
fakeReturns := fake.signalCidReturns
|
||||
fake.recordInvocation("SignalCid", []interface{}{})
|
||||
fake.signalCidMutex.Unlock()
|
||||
if stub != nil {
|
||||
return stub()
|
||||
}
|
||||
if specificReturn {
|
||||
return ret.result1
|
||||
}
|
||||
return fakeReturns.result1
|
||||
}
|
||||
|
||||
func (fake *FakeLocalMediaTrack) SignalCidCallCount() int {
|
||||
fake.signalCidMutex.RLock()
|
||||
defer fake.signalCidMutex.RUnlock()
|
||||
return len(fake.signalCidArgsForCall)
|
||||
}
|
||||
|
||||
func (fake *FakeLocalMediaTrack) SignalCidCalls(stub func() string) {
|
||||
fake.signalCidMutex.Lock()
|
||||
defer fake.signalCidMutex.Unlock()
|
||||
fake.SignalCidStub = stub
|
||||
}
|
||||
|
||||
func (fake *FakeLocalMediaTrack) SignalCidReturns(result1 string) {
|
||||
fake.signalCidMutex.Lock()
|
||||
defer fake.signalCidMutex.Unlock()
|
||||
fake.SignalCidStub = nil
|
||||
fake.signalCidReturns = struct {
|
||||
result1 string
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeLocalMediaTrack) SignalCidReturnsOnCall(i int, result1 string) {
|
||||
fake.signalCidMutex.Lock()
|
||||
defer fake.signalCidMutex.Unlock()
|
||||
fake.SignalCidStub = nil
|
||||
if fake.signalCidReturnsOnCall == nil {
|
||||
fake.signalCidReturnsOnCall = make(map[int]struct {
|
||||
result1 string
|
||||
})
|
||||
}
|
||||
fake.signalCidReturnsOnCall[i] = struct {
|
||||
result1 string
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeLocalMediaTrack) Source() livekit.TrackSource {
|
||||
fake.sourceMutex.Lock()
|
||||
ret, specificReturn := fake.sourceReturnsOnCall[len(fake.sourceArgsForCall)]
|
||||
@@ -2367,12 +2232,8 @@ func (fake *FakeLocalMediaTrack) Invocations() map[string][][]interface{} {
|
||||
defer fake.getTemporalLayerForSpatialFpsMutex.RUnlock()
|
||||
fake.getTrackStatsMutex.RLock()
|
||||
defer fake.getTrackStatsMutex.RUnlock()
|
||||
fake.hasMultipleSpatialLayersMutex.RLock()
|
||||
defer fake.hasMultipleSpatialLayersMutex.RUnlock()
|
||||
fake.hasSdpCidMutex.RLock()
|
||||
defer fake.hasSdpCidMutex.RUnlock()
|
||||
fake.hasSignalCidMutex.RLock()
|
||||
defer fake.hasSignalCidMutex.RUnlock()
|
||||
fake.iDMutex.RLock()
|
||||
defer fake.iDMutex.RUnlock()
|
||||
fake.isEncryptedMutex.RLock()
|
||||
@@ -2409,12 +2270,12 @@ func (fake *FakeLocalMediaTrack) Invocations() map[string][][]interface{} {
|
||||
defer fake.restartMutex.RUnlock()
|
||||
fake.revokeDisallowedSubscribersMutex.RLock()
|
||||
defer fake.revokeDisallowedSubscribersMutex.RUnlock()
|
||||
fake.sdpCidsMutex.RLock()
|
||||
defer fake.sdpCidsMutex.RUnlock()
|
||||
fake.setMutedMutex.RLock()
|
||||
defer fake.setMutedMutex.RUnlock()
|
||||
fake.setRTTMutex.RLock()
|
||||
defer fake.setRTTMutex.RUnlock()
|
||||
fake.signalCidMutex.RLock()
|
||||
defer fake.signalCidMutex.RUnlock()
|
||||
fake.sourceMutex.RLock()
|
||||
defer fake.sourceMutex.RUnlock()
|
||||
fake.streamMutex.RLock()
|
||||
|
||||
@@ -96,16 +96,6 @@ type FakeMediaTrack struct {
|
||||
getTemporalLayerForSpatialFpsReturnsOnCall map[int]struct {
|
||||
result1 int32
|
||||
}
|
||||
HasMultipleSpatialLayersStub func() bool
|
||||
hasMultipleSpatialLayersMutex sync.RWMutex
|
||||
hasMultipleSpatialLayersArgsForCall []struct {
|
||||
}
|
||||
hasMultipleSpatialLayersReturns struct {
|
||||
result1 bool
|
||||
}
|
||||
hasMultipleSpatialLayersReturnsOnCall map[int]struct {
|
||||
result1 bool
|
||||
}
|
||||
IDStub func() livekit.TrackID
|
||||
iDMutex sync.RWMutex
|
||||
iDArgsForCall []struct {
|
||||
@@ -749,59 +739,6 @@ func (fake *FakeMediaTrack) GetTemporalLayerForSpatialFpsReturnsOnCall(i int, re
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeMediaTrack) HasMultipleSpatialLayers() bool {
|
||||
fake.hasMultipleSpatialLayersMutex.Lock()
|
||||
ret, specificReturn := fake.hasMultipleSpatialLayersReturnsOnCall[len(fake.hasMultipleSpatialLayersArgsForCall)]
|
||||
fake.hasMultipleSpatialLayersArgsForCall = append(fake.hasMultipleSpatialLayersArgsForCall, struct {
|
||||
}{})
|
||||
stub := fake.HasMultipleSpatialLayersStub
|
||||
fakeReturns := fake.hasMultipleSpatialLayersReturns
|
||||
fake.recordInvocation("HasMultipleSpatialLayers", []interface{}{})
|
||||
fake.hasMultipleSpatialLayersMutex.Unlock()
|
||||
if stub != nil {
|
||||
return stub()
|
||||
}
|
||||
if specificReturn {
|
||||
return ret.result1
|
||||
}
|
||||
return fakeReturns.result1
|
||||
}
|
||||
|
||||
func (fake *FakeMediaTrack) HasMultipleSpatialLayersCallCount() int {
|
||||
fake.hasMultipleSpatialLayersMutex.RLock()
|
||||
defer fake.hasMultipleSpatialLayersMutex.RUnlock()
|
||||
return len(fake.hasMultipleSpatialLayersArgsForCall)
|
||||
}
|
||||
|
||||
func (fake *FakeMediaTrack) HasMultipleSpatialLayersCalls(stub func() bool) {
|
||||
fake.hasMultipleSpatialLayersMutex.Lock()
|
||||
defer fake.hasMultipleSpatialLayersMutex.Unlock()
|
||||
fake.HasMultipleSpatialLayersStub = stub
|
||||
}
|
||||
|
||||
func (fake *FakeMediaTrack) HasMultipleSpatialLayersReturns(result1 bool) {
|
||||
fake.hasMultipleSpatialLayersMutex.Lock()
|
||||
defer fake.hasMultipleSpatialLayersMutex.Unlock()
|
||||
fake.HasMultipleSpatialLayersStub = nil
|
||||
fake.hasMultipleSpatialLayersReturns = struct {
|
||||
result1 bool
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeMediaTrack) HasMultipleSpatialLayersReturnsOnCall(i int, result1 bool) {
|
||||
fake.hasMultipleSpatialLayersMutex.Lock()
|
||||
defer fake.hasMultipleSpatialLayersMutex.Unlock()
|
||||
fake.HasMultipleSpatialLayersStub = nil
|
||||
if fake.hasMultipleSpatialLayersReturnsOnCall == nil {
|
||||
fake.hasMultipleSpatialLayersReturnsOnCall = make(map[int]struct {
|
||||
result1 bool
|
||||
})
|
||||
}
|
||||
fake.hasMultipleSpatialLayersReturnsOnCall[i] = struct {
|
||||
result1 bool
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeMediaTrack) ID() livekit.TrackID {
|
||||
fake.iDMutex.Lock()
|
||||
ret, specificReturn := fake.iDReturnsOnCall[len(fake.iDArgsForCall)]
|
||||
@@ -1877,8 +1814,6 @@ func (fake *FakeMediaTrack) Invocations() map[string][][]interface{} {
|
||||
defer fake.getQualityForDimensionMutex.RUnlock()
|
||||
fake.getTemporalLayerForSpatialFpsMutex.RLock()
|
||||
defer fake.getTemporalLayerForSpatialFpsMutex.RUnlock()
|
||||
fake.hasMultipleSpatialLayersMutex.RLock()
|
||||
defer fake.hasMultipleSpatialLayersMutex.RUnlock()
|
||||
fake.iDMutex.RLock()
|
||||
defer fake.iDMutex.RUnlock()
|
||||
fake.isEncryptedMutex.RLock()
|
||||
|
||||
@@ -391,14 +391,6 @@ func (d *DummyReceiver) UpdateTrackInfo(ti *livekit.TrackInfo) {
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DummyReceiver) IsSimulcast() bool {
|
||||
if r, ok := d.receiver.Load().(sfu.TrackReceiver); ok {
|
||||
return r.IsSimulcast()
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (d *DummyReceiver) IsClosed() bool {
|
||||
if r, ok := d.receiver.Load().(sfu.TrackReceiver); ok {
|
||||
return r.IsClosed()
|
||||
|
||||
@@ -146,6 +146,34 @@ type FakeSIPStore struct {
|
||||
result1 *livekit.SIPTrunkInfo
|
||||
result2 error
|
||||
}
|
||||
SelectSIPDispatchRuleStub func(context.Context, string) ([]*livekit.SIPDispatchRuleInfo, error)
|
||||
selectSIPDispatchRuleMutex sync.RWMutex
|
||||
selectSIPDispatchRuleArgsForCall []struct {
|
||||
arg1 context.Context
|
||||
arg2 string
|
||||
}
|
||||
selectSIPDispatchRuleReturns struct {
|
||||
result1 []*livekit.SIPDispatchRuleInfo
|
||||
result2 error
|
||||
}
|
||||
selectSIPDispatchRuleReturnsOnCall map[int]struct {
|
||||
result1 []*livekit.SIPDispatchRuleInfo
|
||||
result2 error
|
||||
}
|
||||
SelectSIPInboundTrunkStub func(context.Context, string) ([]*livekit.SIPInboundTrunkInfo, error)
|
||||
selectSIPInboundTrunkMutex sync.RWMutex
|
||||
selectSIPInboundTrunkArgsForCall []struct {
|
||||
arg1 context.Context
|
||||
arg2 string
|
||||
}
|
||||
selectSIPInboundTrunkReturns struct {
|
||||
result1 []*livekit.SIPInboundTrunkInfo
|
||||
result2 error
|
||||
}
|
||||
selectSIPInboundTrunkReturnsOnCall map[int]struct {
|
||||
result1 []*livekit.SIPInboundTrunkInfo
|
||||
result2 error
|
||||
}
|
||||
StoreSIPDispatchRuleStub func(context.Context, *livekit.SIPDispatchRuleInfo) error
|
||||
storeSIPDispatchRuleMutex sync.RWMutex
|
||||
storeSIPDispatchRuleArgsForCall []struct {
|
||||
@@ -842,6 +870,136 @@ func (fake *FakeSIPStore) LoadSIPTrunkReturnsOnCall(i int, result1 *livekit.SIPT
|
||||
}{result1, result2}
|
||||
}
|
||||
|
||||
func (fake *FakeSIPStore) SelectSIPDispatchRule(arg1 context.Context, arg2 string) ([]*livekit.SIPDispatchRuleInfo, error) {
|
||||
fake.selectSIPDispatchRuleMutex.Lock()
|
||||
ret, specificReturn := fake.selectSIPDispatchRuleReturnsOnCall[len(fake.selectSIPDispatchRuleArgsForCall)]
|
||||
fake.selectSIPDispatchRuleArgsForCall = append(fake.selectSIPDispatchRuleArgsForCall, struct {
|
||||
arg1 context.Context
|
||||
arg2 string
|
||||
}{arg1, arg2})
|
||||
stub := fake.SelectSIPDispatchRuleStub
|
||||
fakeReturns := fake.selectSIPDispatchRuleReturns
|
||||
fake.recordInvocation("SelectSIPDispatchRule", []interface{}{arg1, arg2})
|
||||
fake.selectSIPDispatchRuleMutex.Unlock()
|
||||
if stub != nil {
|
||||
return stub(arg1, arg2)
|
||||
}
|
||||
if specificReturn {
|
||||
return ret.result1, ret.result2
|
||||
}
|
||||
return fakeReturns.result1, fakeReturns.result2
|
||||
}
|
||||
|
||||
func (fake *FakeSIPStore) SelectSIPDispatchRuleCallCount() int {
|
||||
fake.selectSIPDispatchRuleMutex.RLock()
|
||||
defer fake.selectSIPDispatchRuleMutex.RUnlock()
|
||||
return len(fake.selectSIPDispatchRuleArgsForCall)
|
||||
}
|
||||
|
||||
func (fake *FakeSIPStore) SelectSIPDispatchRuleCalls(stub func(context.Context, string) ([]*livekit.SIPDispatchRuleInfo, error)) {
|
||||
fake.selectSIPDispatchRuleMutex.Lock()
|
||||
defer fake.selectSIPDispatchRuleMutex.Unlock()
|
||||
fake.SelectSIPDispatchRuleStub = stub
|
||||
}
|
||||
|
||||
func (fake *FakeSIPStore) SelectSIPDispatchRuleArgsForCall(i int) (context.Context, string) {
|
||||
fake.selectSIPDispatchRuleMutex.RLock()
|
||||
defer fake.selectSIPDispatchRuleMutex.RUnlock()
|
||||
argsForCall := fake.selectSIPDispatchRuleArgsForCall[i]
|
||||
return argsForCall.arg1, argsForCall.arg2
|
||||
}
|
||||
|
||||
func (fake *FakeSIPStore) SelectSIPDispatchRuleReturns(result1 []*livekit.SIPDispatchRuleInfo, result2 error) {
|
||||
fake.selectSIPDispatchRuleMutex.Lock()
|
||||
defer fake.selectSIPDispatchRuleMutex.Unlock()
|
||||
fake.SelectSIPDispatchRuleStub = nil
|
||||
fake.selectSIPDispatchRuleReturns = struct {
|
||||
result1 []*livekit.SIPDispatchRuleInfo
|
||||
result2 error
|
||||
}{result1, result2}
|
||||
}
|
||||
|
||||
func (fake *FakeSIPStore) SelectSIPDispatchRuleReturnsOnCall(i int, result1 []*livekit.SIPDispatchRuleInfo, result2 error) {
|
||||
fake.selectSIPDispatchRuleMutex.Lock()
|
||||
defer fake.selectSIPDispatchRuleMutex.Unlock()
|
||||
fake.SelectSIPDispatchRuleStub = nil
|
||||
if fake.selectSIPDispatchRuleReturnsOnCall == nil {
|
||||
fake.selectSIPDispatchRuleReturnsOnCall = make(map[int]struct {
|
||||
result1 []*livekit.SIPDispatchRuleInfo
|
||||
result2 error
|
||||
})
|
||||
}
|
||||
fake.selectSIPDispatchRuleReturnsOnCall[i] = struct {
|
||||
result1 []*livekit.SIPDispatchRuleInfo
|
||||
result2 error
|
||||
}{result1, result2}
|
||||
}
|
||||
|
||||
func (fake *FakeSIPStore) SelectSIPInboundTrunk(arg1 context.Context, arg2 string) ([]*livekit.SIPInboundTrunkInfo, error) {
|
||||
fake.selectSIPInboundTrunkMutex.Lock()
|
||||
ret, specificReturn := fake.selectSIPInboundTrunkReturnsOnCall[len(fake.selectSIPInboundTrunkArgsForCall)]
|
||||
fake.selectSIPInboundTrunkArgsForCall = append(fake.selectSIPInboundTrunkArgsForCall, struct {
|
||||
arg1 context.Context
|
||||
arg2 string
|
||||
}{arg1, arg2})
|
||||
stub := fake.SelectSIPInboundTrunkStub
|
||||
fakeReturns := fake.selectSIPInboundTrunkReturns
|
||||
fake.recordInvocation("SelectSIPInboundTrunk", []interface{}{arg1, arg2})
|
||||
fake.selectSIPInboundTrunkMutex.Unlock()
|
||||
if stub != nil {
|
||||
return stub(arg1, arg2)
|
||||
}
|
||||
if specificReturn {
|
||||
return ret.result1, ret.result2
|
||||
}
|
||||
return fakeReturns.result1, fakeReturns.result2
|
||||
}
|
||||
|
||||
func (fake *FakeSIPStore) SelectSIPInboundTrunkCallCount() int {
|
||||
fake.selectSIPInboundTrunkMutex.RLock()
|
||||
defer fake.selectSIPInboundTrunkMutex.RUnlock()
|
||||
return len(fake.selectSIPInboundTrunkArgsForCall)
|
||||
}
|
||||
|
||||
func (fake *FakeSIPStore) SelectSIPInboundTrunkCalls(stub func(context.Context, string) ([]*livekit.SIPInboundTrunkInfo, error)) {
|
||||
fake.selectSIPInboundTrunkMutex.Lock()
|
||||
defer fake.selectSIPInboundTrunkMutex.Unlock()
|
||||
fake.SelectSIPInboundTrunkStub = stub
|
||||
}
|
||||
|
||||
func (fake *FakeSIPStore) SelectSIPInboundTrunkArgsForCall(i int) (context.Context, string) {
|
||||
fake.selectSIPInboundTrunkMutex.RLock()
|
||||
defer fake.selectSIPInboundTrunkMutex.RUnlock()
|
||||
argsForCall := fake.selectSIPInboundTrunkArgsForCall[i]
|
||||
return argsForCall.arg1, argsForCall.arg2
|
||||
}
|
||||
|
||||
func (fake *FakeSIPStore) SelectSIPInboundTrunkReturns(result1 []*livekit.SIPInboundTrunkInfo, result2 error) {
|
||||
fake.selectSIPInboundTrunkMutex.Lock()
|
||||
defer fake.selectSIPInboundTrunkMutex.Unlock()
|
||||
fake.SelectSIPInboundTrunkStub = nil
|
||||
fake.selectSIPInboundTrunkReturns = struct {
|
||||
result1 []*livekit.SIPInboundTrunkInfo
|
||||
result2 error
|
||||
}{result1, result2}
|
||||
}
|
||||
|
||||
func (fake *FakeSIPStore) SelectSIPInboundTrunkReturnsOnCall(i int, result1 []*livekit.SIPInboundTrunkInfo, result2 error) {
|
||||
fake.selectSIPInboundTrunkMutex.Lock()
|
||||
defer fake.selectSIPInboundTrunkMutex.Unlock()
|
||||
fake.SelectSIPInboundTrunkStub = nil
|
||||
if fake.selectSIPInboundTrunkReturnsOnCall == nil {
|
||||
fake.selectSIPInboundTrunkReturnsOnCall = make(map[int]struct {
|
||||
result1 []*livekit.SIPInboundTrunkInfo
|
||||
result2 error
|
||||
})
|
||||
}
|
||||
fake.selectSIPInboundTrunkReturnsOnCall[i] = struct {
|
||||
result1 []*livekit.SIPInboundTrunkInfo
|
||||
result2 error
|
||||
}{result1, result2}
|
||||
}
|
||||
|
||||
func (fake *FakeSIPStore) StoreSIPDispatchRule(arg1 context.Context, arg2 *livekit.SIPDispatchRuleInfo) error {
|
||||
fake.storeSIPDispatchRuleMutex.Lock()
|
||||
ret, specificReturn := fake.storeSIPDispatchRuleReturnsOnCall[len(fake.storeSIPDispatchRuleArgsForCall)]
|
||||
@@ -1113,6 +1271,10 @@ func (fake *FakeSIPStore) Invocations() map[string][][]interface{} {
|
||||
defer fake.loadSIPOutboundTrunkMutex.RUnlock()
|
||||
fake.loadSIPTrunkMutex.RLock()
|
||||
defer fake.loadSIPTrunkMutex.RUnlock()
|
||||
fake.selectSIPDispatchRuleMutex.RLock()
|
||||
defer fake.selectSIPDispatchRuleMutex.RUnlock()
|
||||
fake.selectSIPInboundTrunkMutex.RLock()
|
||||
defer fake.selectSIPInboundTrunkMutex.RUnlock()
|
||||
fake.storeSIPDispatchRuleMutex.RLock()
|
||||
defer fake.storeSIPDispatchRuleMutex.RUnlock()
|
||||
fake.storeSIPInboundTrunkMutex.RLock()
|
||||
|
||||
@@ -586,8 +586,7 @@ func (d *DownTrack) Bind(t webrtc.TrackLocalContext) (webrtc.RTPCodecParameters,
|
||||
d.setBindStateLocked(bindStateBound)
|
||||
d.bindLock.Unlock()
|
||||
|
||||
receiver := d.Receiver()
|
||||
d.forwarder.DetermineCodec(codec.RTPCodecCapability, receiver.HeaderExtensions(), receiver.IsSimulcast())
|
||||
d.forwarder.DetermineCodec(codec.RTPCodecCapability, d.Receiver().HeaderExtensions())
|
||||
d.connectionStats.Start(d.Mime(), isFECEnabled)
|
||||
d.params.Logger.Debugw("downtrack bound")
|
||||
}
|
||||
@@ -696,8 +695,7 @@ func (d *DownTrack) handleUpstreamCodecChange(mimeType string) {
|
||||
)
|
||||
|
||||
d.forwarder.Restart()
|
||||
receiver := d.Receiver()
|
||||
d.forwarder.DetermineCodec(codec.RTPCodecCapability, receiver.HeaderExtensions(), receiver.IsSimulcast())
|
||||
d.forwarder.DetermineCodec(codec.RTPCodecCapability, d.Receiver().HeaderExtensions())
|
||||
d.connectionStats.UpdateCodec(d.Mime(), isFECEnabled)
|
||||
}
|
||||
|
||||
|
||||
+28
-43
@@ -297,11 +297,7 @@ func (f *Forwarder) SetMaxTemporalLayerSeen(maxTemporalLayerSeen int32) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (f *Forwarder) DetermineCodec(
|
||||
codec webrtc.RTPCodecCapability,
|
||||
extensions []webrtc.RTPHeaderExtensionParameter,
|
||||
isReceiverSimulcast bool,
|
||||
) {
|
||||
func (f *Forwarder) DetermineCodec(codec webrtc.RTPCodecCapability, extensions []webrtc.RTPHeaderExtensionParameter) {
|
||||
f.lock.Lock()
|
||||
defer f.lock.Unlock()
|
||||
|
||||
@@ -344,51 +340,40 @@ func (f *Forwarder) DetermineCodec(
|
||||
}
|
||||
|
||||
case mime.MimeTypeVP9:
|
||||
if isReceiverSimulcast {
|
||||
f.logger.Debugw("selecting simulcast video layer selector for VP9")
|
||||
if f.vls != nil {
|
||||
f.vls = videolayerselector.NewSimulcastFromOther(f.vls)
|
||||
} else {
|
||||
f.vls = videolayerselector.NewSimulcast(f.logger)
|
||||
}
|
||||
// VP9-SIMULCAST-TODO: Add temporal layer selector for VP9
|
||||
} else {
|
||||
isDDAvailable := ddAvailable(extensions)
|
||||
if isDDAvailable {
|
||||
f.logger.Debugw("selecting dependency descriptor video layer selector for VP9")
|
||||
if f.vls != nil {
|
||||
f.vls = videolayerselector.NewDependencyDescriptorFromOther(f.vls)
|
||||
} else {
|
||||
f.vls = videolayerselector.NewDependencyDescriptor(f.logger)
|
||||
}
|
||||
} else {
|
||||
f.logger.Debugw("selecting VP9 SVC video layer selector")
|
||||
if f.vls != nil {
|
||||
f.vls = videolayerselector.NewVP9FromOther(f.vls)
|
||||
} else {
|
||||
f.vls = videolayerselector.NewVP9(f.logger)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
case mime.MimeTypeAV1:
|
||||
// DD-TODO : we only enable dd layer selector for av1/vp9 now, in the future we can enable it for vp8 too
|
||||
isDDAvailable := ddAvailable(extensions)
|
||||
if isReceiverSimulcast || !isDDAvailable {
|
||||
// AV1-SIMULCAST-TODO: Add temporal layer selector for AV1
|
||||
f.logger.Debugw("selecting simulcast video layer selector for AV1")
|
||||
if f.vls != nil {
|
||||
f.vls = videolayerselector.NewSimulcastFromOther(f.vls)
|
||||
} else {
|
||||
f.vls = videolayerselector.NewSimulcast(f.logger)
|
||||
}
|
||||
} else {
|
||||
f.logger.Debugw("selecting dependency descriptor video layer selector for AV1")
|
||||
if isDDAvailable {
|
||||
if f.vls != nil {
|
||||
f.vls = videolayerselector.NewDependencyDescriptorFromOther(f.vls)
|
||||
} else {
|
||||
f.vls = videolayerselector.NewDependencyDescriptor(f.logger)
|
||||
}
|
||||
} else {
|
||||
if f.vls != nil {
|
||||
f.vls = videolayerselector.NewVP9FromOther(f.vls)
|
||||
} else {
|
||||
f.vls = videolayerselector.NewVP9(f.logger)
|
||||
}
|
||||
}
|
||||
// SVC-TODO: Support for VP9 simulcast. When DD is not available, have to pick selector based on VP9 SVC or Simulcast
|
||||
|
||||
case mime.MimeTypeAV1:
|
||||
// DD-TODO : we only enable dd layer selector for av1/vp9 now, in the future we can enable it for vp8 too
|
||||
isDDAvailable := ddAvailable(extensions)
|
||||
if isDDAvailable {
|
||||
if f.vls != nil {
|
||||
f.vls = videolayerselector.NewDependencyDescriptorFromOther(f.vls)
|
||||
} else {
|
||||
f.vls = videolayerselector.NewDependencyDescriptor(f.logger)
|
||||
}
|
||||
} else {
|
||||
if f.vls != nil {
|
||||
f.vls = videolayerselector.NewSimulcastFromOther(f.vls)
|
||||
} else {
|
||||
f.vls = videolayerselector.NewSimulcast(f.logger)
|
||||
}
|
||||
}
|
||||
// SVC-TODO: Support for AV1 Simulcast
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ func disable(f *Forwarder) {
|
||||
|
||||
func newForwarder(codec webrtc.RTPCodecCapability, kind webrtc.RTPCodecType) *Forwarder {
|
||||
f := NewForwarder(kind, logger.GetLogger(), true, nil)
|
||||
f.DetermineCodec(codec, nil, false)
|
||||
f.DetermineCodec(codec, nil)
|
||||
return f
|
||||
}
|
||||
|
||||
|
||||
@@ -240,6 +240,10 @@ func IsMimeTypeVideo(mimeType MimeType) bool {
|
||||
return strings.HasPrefix(mimeType.String(), MimeTypePrefixVideo)
|
||||
}
|
||||
|
||||
// SVC-TODO: Have to use more conditions to differentiate between
|
||||
// SVC-TODO: SVC and non-SVC (could be single layer or simulcast).
|
||||
// SVC-TODO: May only need to differentiate between simulcast and non-simulcast
|
||||
// SVC-TODO: i. e. may be possible to treat single layer as SVC to get proper/intended functionality.
|
||||
func IsMimeTypeSVC(mimeType MimeType) bool {
|
||||
switch mimeType {
|
||||
case MimeTypeAV1, MimeTypeVP9:
|
||||
|
||||
+6
-18
@@ -123,7 +123,6 @@ type TrackReceiver interface {
|
||||
|
||||
TrackInfo() *livekit.TrackInfo
|
||||
UpdateTrackInfo(ti *livekit.TrackInfo)
|
||||
IsSimulcast() bool
|
||||
|
||||
// Get primary receiver if this receiver represents a RED codec; otherwise it will return itself
|
||||
GetPrimaryReceiverForRed() TrackReceiver
|
||||
@@ -266,6 +265,7 @@ func NewWebRTCReceiver(
|
||||
codecState: ReceiverCodecStateNormal,
|
||||
kind: track.Kind(),
|
||||
onRTCP: onRTCP,
|
||||
isSVC: mime.IsMimeTypeStringSVC(track.Codec().MimeType),
|
||||
isRED: mime.IsMimeTypeStringRED(track.Codec().MimeType),
|
||||
}
|
||||
|
||||
@@ -274,12 +274,6 @@ func NewWebRTCReceiver(
|
||||
}
|
||||
w.trackInfo.Store(utils.CloneProto(trackInfo))
|
||||
|
||||
isSVC := false
|
||||
if !w.IsSimulcast() {
|
||||
isSVC = mime.IsMimeTypeStringSVC(track.Codec().MimeType)
|
||||
}
|
||||
w.isSVC = isSVC
|
||||
|
||||
w.downTrackSpreader = NewDownTrackSpreader(DownTrackSpreaderParams{
|
||||
Threshold: w.lbThreshold,
|
||||
Logger: logger,
|
||||
@@ -324,16 +318,6 @@ func (w *WebRTCReceiver) UpdateTrackInfo(ti *livekit.TrackInfo) {
|
||||
w.streamTrackerManager.UpdateTrackInfo(ti)
|
||||
}
|
||||
|
||||
func (w *WebRTCReceiver) IsSimulcast() bool {
|
||||
for _, codec := range w.trackInfo.Load().Codecs {
|
||||
if mime.IsMimeTypeStringEqual(codec.MimeType, w.codec.MimeType) {
|
||||
return codec.IsSimulcast
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (w *WebRTCReceiver) OnStatsUpdate(fn func(w *WebRTCReceiver, stat *livekit.AnalyticsStat)) {
|
||||
w.onStatsUpdate = fn
|
||||
}
|
||||
@@ -871,9 +855,13 @@ func (w *WebRTCReceiver) closeTracks() {
|
||||
}
|
||||
|
||||
func (w *WebRTCReceiver) DebugInfo() map[string]interface{} {
|
||||
isSimulcast := !w.isSVC
|
||||
if ti := w.trackInfo.Load(); ti != nil {
|
||||
isSimulcast = isSimulcast && len(ti.Layers) > 1
|
||||
}
|
||||
info := map[string]interface{}{
|
||||
"SVC": w.isSVC,
|
||||
"Simulcast": w.IsSimulcast(),
|
||||
"Simulcast": isSimulcast,
|
||||
}
|
||||
|
||||
w.bufferMu.RLock()
|
||||
|
||||
Reference in New Issue
Block a user