From 9727e6a694f27f7642b9b4a60e59d82e6529ee45 Mon Sep 17 00:00:00 2001 From: Jakub Audykowicz Date: Sat, 9 Sep 2023 11:42:59 +0200 Subject: [PATCH] Wrap access to VideoSinks with a scope lock --- DolbyIO/Source/Private/DolbyIOSubsystem.cpp | 66 ++++++++++++++------- DolbyIO/Source/Public/DolbyIOSubsystem.h | 3 + 2 files changed, 46 insertions(+), 23 deletions(-) diff --git a/DolbyIO/Source/Private/DolbyIOSubsystem.cpp b/DolbyIO/Source/Private/DolbyIOSubsystem.cpp index 3f5468a7..417c3840 100644 --- a/DolbyIO/Source/Private/DolbyIOSubsystem.cpp +++ b/DolbyIO/Source/Private/DolbyIOSubsystem.cpp @@ -36,10 +36,13 @@ void UDolbyIOSubsystem::Initialize(FSubsystemCollectionBase& Collection) ConferenceStatus = conference_status::destroyed; - VideoSinks.Emplace(LocalCameraTrackID, std::make_shared(LocalCameraTrackID)); - VideoSinks.Emplace(LocalScreenshareTrackID, std::make_shared(LocalScreenshareTrackID)); - LocalCameraFrameHandler = std::make_shared(VideoSinks[LocalCameraTrackID]); - LocalScreenshareFrameHandler = std::make_shared(VideoSinks[LocalScreenshareTrackID]); + { + FScopeLock Lock{&VideoSinksLock}; + VideoSinks.Emplace(LocalCameraTrackID, std::make_shared(LocalCameraTrackID)); + VideoSinks.Emplace(LocalScreenshareTrackID, std::make_shared(LocalScreenshareTrackID)); + LocalCameraFrameHandler = std::make_shared(VideoSinks[LocalCameraTrackID]); + LocalScreenshareFrameHandler = std::make_shared(VideoSinks[LocalScreenshareTrackID]); + } FTimerManager& TimerManager = GetGameInstance()->GetTimerManager(); TimerManager.SetTimer(LocationTimerHandle, this, &UDolbyIOSubsystem::SetLocationUsingFirstPlayer, 0.1, true); @@ -186,13 +189,14 @@ void UDolbyIOSubsystem::Initialize(const FString& Token) { const FDolbyIOVideoTrack VideoTrack = ToFDolbyIOVideoTrack(Event.track); + FScopeLock Lock1{&VideoSinksLock}; VideoSinks.Emplace(VideoTrack.TrackID, std::make_shared(VideoTrack.TrackID)); Sdk->video() .remote() .set_video_sink(Event.track, VideoSinks[VideoTrack.TrackID]) .on_error(MAKE_DLB_ERROR_HANDLER); - FScopeLock Lock{&RemoteParticipantsLock}; + FScopeLock Lock2{&RemoteParticipantsLock}; if (RemoteParticipants.Contains(VideoTrack.ParticipantID)) { VideoSinks[VideoTrack.TrackID]->OnTextureCreated([this, VideoTrack] @@ -216,8 +220,17 @@ void UDolbyIOSubsystem::Initialize(const FString& Token) DLB_UE_LOG("Video track removed: TrackID=%s ParticipantID=%s", *VideoTrack.TrackID, *VideoTrack.ParticipantID); - VideoSinks[VideoTrack.TrackID]->UnbindAllMaterials(); - VideoSinks.Remove(VideoTrack.TrackID); + FScopeLock Lock{&VideoSinksLock}; + if (std::shared_ptr* Sink = VideoSinks.Find(VideoTrack.TrackID)) + { + (*Sink)->UnbindAllMaterials(); + VideoSinks.Remove(VideoTrack.TrackID); + } + else + { + DLB_UE_WARN("Non-existent video track removed"); + } + BroadcastEvent(OnVideoTrackRemoved, VideoTrack); }); }) @@ -632,31 +645,35 @@ void UDolbyIOSubsystem::ProcessBufferedVideoTracks(const FString& ParticipantID) { if (TArray* AddedTracks = BufferedAddedVideoTracks.Find(ParticipantID)) { + FScopeLock Lock{&VideoSinksLock}; for (const FDolbyIOVideoTrack& AddedTrack : *AddedTracks) { - VideoSinks[AddedTrack.TrackID]->OnTextureCreated( - [=] - { - BroadcastVideoTrackAdded(AddedTrack); - - if (TArray* EnabledTracks = BufferedEnabledVideoTracks.Find(ParticipantID)) + if (std::shared_ptr* Sink = VideoSinks.Find(AddedTrack.TrackID)) + { + (*Sink)->OnTextureCreated( + [=] { - TArray& EnabledTracksRef = *EnabledTracks; - for (int i = 0; i < EnabledTracksRef.Num(); ++i) + BroadcastVideoTrackAdded(AddedTrack); + + if (TArray* EnabledTracks = BufferedEnabledVideoTracks.Find(ParticipantID)) { - if (EnabledTracksRef[i].TrackID == AddedTrack.TrackID) + TArray& EnabledTracksRef = *EnabledTracks; + for (int i = 0; i < EnabledTracksRef.Num(); ++i) { - BroadcastVideoTrackEnabled(EnabledTracksRef[i]); - EnabledTracksRef.RemoveAt(i); - if (!EnabledTracksRef.Num()) + if (EnabledTracksRef[i].TrackID == AddedTrack.TrackID) { - BufferedEnabledVideoTracks.Remove(ParticipantID); + BroadcastVideoTrackEnabled(EnabledTracksRef[i]); + EnabledTracksRef.RemoveAt(i); + if (!EnabledTracksRef.Num()) + { + BufferedEnabledVideoTracks.Remove(ParticipantID); + } + return; } - return; } } - } - }); + }); + } } BufferedAddedVideoTracks.Remove(ParticipantID); } @@ -664,6 +681,7 @@ void UDolbyIOSubsystem::ProcessBufferedVideoTracks(const FString& ParticipantID) UTexture2D* UDolbyIOSubsystem::GetTexture(const FString& VideoTrackID) { + FScopeLock Lock{&VideoSinksLock}; if (const std::shared_ptr* Sink = VideoSinks.Find(VideoTrackID)) { return (*Sink)->GetTexture(); @@ -753,6 +771,7 @@ void UDolbyIOSubsystem::ChangeScreenshareParameters(EDolbyIOScreenshareEncoderHi void UDolbyIOSubsystem::BindMaterial(UMaterialInstanceDynamic* Material, const FString& VideoTrackID) { + FScopeLock Lock{&VideoSinksLock}; for (auto& Sink : VideoSinks) { if (Sink.Key != VideoTrackID) @@ -769,6 +788,7 @@ void UDolbyIOSubsystem::BindMaterial(UMaterialInstanceDynamic* Material, const F void UDolbyIOSubsystem::UnbindMaterial(UMaterialInstanceDynamic* Material, const FString& VideoTrackID) { + FScopeLock Lock{&VideoSinksLock}; if (const std::shared_ptr* Sink = VideoSinks.Find(VideoTrackID)) { (*Sink)->UnbindMaterial(Material); diff --git a/DolbyIO/Source/Public/DolbyIOSubsystem.h b/DolbyIO/Source/Public/DolbyIOSubsystem.h index 3d20823c..bbdd0d53 100644 --- a/DolbyIO/Source/Public/DolbyIOSubsystem.h +++ b/DolbyIO/Source/Public/DolbyIOSubsystem.h @@ -457,10 +457,13 @@ class DOLBYIO_API UDolbyIOSubsystem : public UGameInstanceSubsystem EDolbyIOSpatialAudioStyle SpatialAudioStyle; TMap> BufferedAddedVideoTracks; TMap> BufferedEnabledVideoTracks; + TMap RemoteParticipants; FCriticalSection RemoteParticipantsLock; TMap> VideoSinks; + FCriticalSection VideoSinksLock; + std::shared_ptr LocalCameraFrameHandler; std::shared_ptr LocalScreenshareFrameHandler; TSharedPtr Sdk;