// Copyright Epic Games, Inc. All Rights Reserved. #include "MediaSampleCache.h" #include "MediaUtilsPrivate.h" #include "IMediaAudioSample.h" #include "IMediaBinarySample.h" #include "IMediaControls.h" #include "IMediaOverlaySample.h" #include "IMediaPlayer.h" #include "IMediaSamples.h" #include "IMediaTextureSample.h" #include "Math/Range.h" #include "Misc/ScopeLock.h" /* FMediaSampleCache structors *****************************************************************************/ FMediaSampleCache::FMediaSampleCache() : CacheAhead(FTimespan::Zero()) , CacheBehind(FTimespan::Zero()) { } /* FMediaSampleCache interface *****************************************************************************/ void FMediaSampleCache::Empty() { FScopeLock Lock(&CriticalSection); AudioSamples.Empty(); MetadataSamples.Empty(); OverlaySamples.Empty(); VideoSamples.Empty(); } TSharedPtr FMediaSampleCache::GetAudioSample(FTimespan /*Time*/) { return nullptr; /* FScopeLock Lock(&CriticalSection); FetchAudioSamples(Player->GetSamples()); for (const TSharedPtr& Sample : AudioSamples) { const FTimespan SampleTime = Sample->GetTime(); if ((Time >= SampleTime) && (Time < SampleTime + Sample->GetDuration())) { return Sample; } } #if 1 UE_LOG(LogMediaUtils, Log, TEXT("---------------------------------------------------------- %d"), Time.GetTicks()); for (const TSharedPtr& Sample : AudioSamples) { UE_LOG(LogMediaUtils, Log, TEXT("%d - %d (%d)"), Sample->GetTime().GetTicks(), (Sample->GetTime() + Sample->GetDuration()).GetTicks() - 1, Sample->GetFrames()); } UE_LOG(LogMediaUtils, Log, TEXT("----------------------------------------------------------")); #endif return nullptr;*/ } void FMediaSampleCache::GetCachedAudioSampleRanges(TRangeSet& OutTimeRanges) const { FScopeLock Lock(&CriticalSection); for (const TSharedPtr& Sample : AudioSamples) { const FTimespan SampleTime = Sample->GetTime().Time; OutTimeRanges.Add(TRange(SampleTime, SampleTime + Sample->GetDuration())); } } void FMediaSampleCache::GetCachedVideoSampleRanges(TRangeSet& OutTimeRanges) const { FScopeLock Lock(&CriticalSection); for (const TSharedPtr& Sample : VideoSamples) { const FTimespan SampleTime = Sample->GetTime().Time; OutTimeRanges.Add(TRange(SampleTime, SampleTime + Sample->GetDuration())); } } void FMediaSampleCache::GetOverlaySamples(FTimespan Time, TArray>& /*OutSamples*/) { /* FScopeLock Lock(&CriticalSection); FetchOverlaySamples(Player->GetSamples()); for (const TSharedPtr& Sample : OverlaySamples) { const FTimespan SampleTime = Sample->GetTime(); if ((Time >= SampleTime) && (Time <= SampleTime + Sample->GetDuration())) { OutSamples.Add(Sample); } }*/ } TSharedPtr FMediaSampleCache::GetVideoSample(FTimespan /*Time*/, bool /*Forward*/) { return nullptr; /* FScopeLock Lock(&CriticalSection); FetchVideoSamples(Player->GetSamples()); TSharedPtr BestMatch; if (Forward) { FTimespan BestTime = FTimespan::MinValue(); for (const TSharedPtr& Sample : VideoSamples) { FTimespan SampleTime = Sample->GetTime(); if ((SampleTime <= Time) && (SampleTime > BestTime)) { BestMatch = Sample; if (SampleTime == Time) { break; // exact match } BestTime = SampleTime; } } } else { FTimespan BestTime = FTimespan::MaxValue(); for (const TSharedPtr& Sample : VideoSamples) { FTimespan SampleTime = Sample->GetTime() + Sample->GetDuration(); if ((SampleTime >= Time) && (SampleTime < BestTime)) { BestMatch = Sample; if (SampleTime == Time) { break; // exact match } BestTime = SampleTime; } } } return BestMatch;*/ } void FMediaSampleCache::Tick(FTimespan /*DeltaTime*/, float /*Rate*/, FTimespan /*Time*/) {/* // determine cache window const float CurrentRate = Player->GetControls().GetRate(); const FTimespan CurrentTime = Player->GetControls().GetTime(); const FTimespan Duration = Player->GetControls().GetDuration(); TRange CacheWindow; if (CurrentRate > 0.0f) { CacheWindow = TRange(CurrentTime - CacheBehind - DeltaTime, CurrentTime + CacheAhead); } else if (CurrentRate < 0.0f) { CacheWindow = TRange(CurrentTime - CacheAhead, CurrentTime + CacheBehind + DeltaTime); } else { FTimespan CacheMax = FMath::Max(CacheAhead, CacheBehind); CacheWindow = TRange(CurrentTime - CacheMax, CurrentTime + CacheMax); } FScopeLock Lock(&CriticalSection); // fetch unconsumed samples IMediaSamples& Samples = Player->GetSamples(); FetchAudioSamples(Samples); FetchMetadataSamples(Samples); FetchOverlaySamples(Samples); FetchVideoSamples(Samples); // remove expired samples for (TSampleSet::TIterator It(AudioSamples); It; ++It) { const FTimespan SampleTime = (*It)->GetTime(); if (!CacheWindow.Contains(SampleTime) && !CacheWindow.Contains(SampleTime + Duration) && !CacheWindow.Contains(SampleTime - Duration)) { It.RemoveCurrent(); } } for (TSampleSet::TIterator It(MetadataSamples); It; ++It) { const FTimespan SampleTime = (*It)->GetTime(); if (!CacheWindow.Contains(SampleTime) && !CacheWindow.Contains(SampleTime + Duration) && !CacheWindow.Contains(SampleTime - Duration)) { It.RemoveCurrent(); } } for (TSampleSet::TIterator It(OverlaySamples); It; ++It) { const FTimespan SampleTime = (*It)->GetTime(); if (!CacheWindow.Contains(SampleTime) && !CacheWindow.Contains(SampleTime + Duration) && !CacheWindow.Contains(SampleTime - Duration)) { It.RemoveCurrent(); } } for (TSampleSet::TIterator It(VideoSamples); It; ++It) { const auto& Sample = *It; if (Sample->IsCacheable()) { const FTimespan SampleTime = Sample->GetTime(); if (CacheWindow.Contains(SampleTime) || CacheWindow.Contains(SampleTime + Duration) || CacheWindow.Contains(SampleTime - Duration)) { continue; } } It.RemoveCurrent(); }*/ }