From 3054f3eea3cc3b40271eff3b4455a0813c1a03d2 Mon Sep 17 00:00:00 2001 From: Raja Subramanian Date: Fri, 27 May 2022 13:32:45 +0530 Subject: [PATCH] Protect TrackInfo (#724) * Protext TrackInfo Also making a copy rather than changing params. * prevent recursive lock * Remove double lock * Rework early return a little bit --- pkg/rtc/mediatrackreceiver.go | 53 ++++++++++++++++++++++++++--------- 1 file changed, 39 insertions(+), 14 deletions(-) diff --git a/pkg/rtc/mediatrackreceiver.go b/pkg/rtc/mediatrackreceiver.go index a1cb074de..a1156f24d 100644 --- a/pkg/rtc/mediatrackreceiver.go +++ b/pkg/rtc/mediatrackreceiver.go @@ -31,6 +31,7 @@ type MediaTrackReceiver struct { simulcasted atomic.Bool lock sync.RWMutex + trackInfo *livekit.TrackInfo receiver sfu.TrackReceiver layerDimensions map[livekit.VideoQuality]*livekit.VideoLayer @@ -62,6 +63,7 @@ type MediaTrackReceiverParams struct { func NewMediaTrackReceiver(params MediaTrackReceiverParams) *MediaTrackReceiver { t := &MediaTrackReceiver{ params: params, + trackInfo: proto.Clone(params.TrackInfo).(*livekit.TrackInfo), layerDimensions: make(map[livekit.VideoQuality]*livekit.VideoLayer), } @@ -75,12 +77,12 @@ func NewMediaTrackReceiver(params MediaTrackReceiverParams) *MediaTrackReceiver Logger: params.Logger, }) - if params.TrackInfo.Muted { + if t.trackInfo.Muted { t.SetMuted(true) } - if params.TrackInfo != nil && t.Kind() == livekit.TrackType_VIDEO { - t.UpdateVideoLayers(params.TrackInfo.Layers) + if t.trackInfo != nil && t.Kind() == livekit.TrackType_VIDEO { + t.UpdateVideoLayers(t.trackInfo.Layers) // LK-TODO: maybe use this or simulcast flag in TrackInfo to set simulcasted here } @@ -135,15 +137,24 @@ func (t *MediaTrackReceiver) Close() { } func (t *MediaTrackReceiver) ID() livekit.TrackID { - return livekit.TrackID(t.params.TrackInfo.Sid) + t.lock.RLock() + defer t.lock.RUnlock() + + return livekit.TrackID(t.trackInfo.Sid) } func (t *MediaTrackReceiver) Kind() livekit.TrackType { - return t.params.TrackInfo.Type + t.lock.RLock() + defer t.lock.RUnlock() + + return t.trackInfo.Type } func (t *MediaTrackReceiver) Source() livekit.TrackSource { - return t.params.TrackInfo.Source + t.lock.RLock() + defer t.lock.RUnlock() + + return t.trackInfo.Source } func (t *MediaTrackReceiver) PublisherID() livekit.ParticipantID { @@ -163,7 +174,10 @@ func (t *MediaTrackReceiver) SetSimulcast(simulcast bool) { } func (t *MediaTrackReceiver) Name() string { - return t.params.TrackInfo.Name + t.lock.RLock() + defer t.lock.RUnlock() + + return t.trackInfo.Name } func (t *MediaTrackReceiver) IsMuted() bool { @@ -225,14 +239,20 @@ func (t *MediaTrackReceiver) AddSubscriber(sub types.LocalParticipant) error { } func (t *MediaTrackReceiver) UpdateTrackInfo(ti *livekit.TrackInfo) { + t.lock.Lock() t.params.TrackInfo = ti + t.lock.Unlock() + if ti != nil && t.Kind() == livekit.TrackType_VIDEO { t.UpdateVideoLayers(ti.Layers) } } func (t *MediaTrackReceiver) TrackInfo() *livekit.TrackInfo { - return t.params.TrackInfo + t.lock.RLock() + defer t.lock.RUnlock() + + return proto.Clone(t.params.TrackInfo).(*livekit.TrackInfo) } func (t *MediaTrackReceiver) UpdateVideoLayers(layers []*livekit.VideoLayer) { @@ -265,25 +285,30 @@ func (t *MediaTrackReceiver) GetVideoLayers() []*livekit.VideoLayer { // affords a 20% tolerance on dimension func (t *MediaTrackReceiver) GetQualityForDimension(width, height uint32) livekit.VideoQuality { quality := livekit.VideoQuality_HIGH - if t.Kind() == livekit.TrackType_AUDIO || t.params.TrackInfo.Height == 0 { + if t.Kind() == livekit.TrackType_AUDIO { return quality } - origSize := t.params.TrackInfo.Height + + t.lock.RLock() + defer t.lock.RUnlock() + + if t.trackInfo.Height == 0 { + return quality + } + origSize := t.trackInfo.Height requestedSize := height - if t.params.TrackInfo.Width < t.params.TrackInfo.Height { + if t.trackInfo.Width < t.trackInfo.Height { // for portrait videos - origSize = t.params.TrackInfo.Width + origSize = t.trackInfo.Width requestedSize = width } // default sizes representing qualities low - high layerSizes := []uint32{180, 360, origSize} var providedSizes []uint32 - t.lock.RLock() for _, layer := range t.layerDimensions { providedSizes = append(providedSizes, layer.Height) } - t.lock.RUnlock() if len(providedSizes) > 0 { layerSizes = providedSizes // comparing height always