Files
TerracottaWarriors/Plugins/AndroidVulkanVideo_5.3/Source/AndroidVulkanVideo/Private/VideoMediaSampleHolder.h

156 lines
4.9 KiB
C
Raw Normal View History

2025-07-14 22:24:27 +08:00
// ------------------------------------------------
// Copyright Joe Marshall 2024- All Rights Reserved
// ------------------------------------------------
//
// An implementation of IMediaSamples for the new
// v2 video timing in Unreal media player.
//
// With new timing, whilst in theory IMediaSamples
// is a queue, in use only the most recent sample
// is ever read.
//
// Given we know that, this class dumps any
// previous samples immediately, which allows
// the underlying hardware image to be released as
// soon as possible, which makes video decoding
// work more efficiently.
// ------------------------------------------------
#pragma once
#include "AndroidVulkanTextureSample.h"
#include "IMediaSamples.h"
#include "UnrealLogging.h"
// for v2 video timing, the sample queue just
// holds a single image
class FVideoMediaSampleHolder : public IMediaSamples
{
public:
void AddVideo(TSharedRef<AndroidVulkanTextureSample, ESPMode::ThreadSafe> &InSample)
{
if (VideoSample.IsValid())
{
// force sample texture clear because
// we're not going to display it
VideoSample->Clear();
UE_LOGFMT(LogDirectVideo, VeryVerbose, "Clearing videoframe {0}",
VideoSample.GetSharedReferenceCount());
}
VideoSample = InSample;
UE_LOGFMT(LogDirectVideo, VeryVerbose, "CSet video frame {0}", VideoSample.IsValid());
}
virtual bool FetchVideo(
TRange<FTimespan> TimeRange,
TSharedPtr<IMediaTextureSample, ESPMode::ThreadSafe> &OutSample) override
{
UE_LOGFMT(LogDirectVideo, VeryVerbose, "BFetch video frame {0}", VideoSample.IsValid());
if (VideoSample.IsValid())
{
OutSample = VideoSample;
VideoSample.Reset();
return true;
}
return false; // override in child classes, if supported
}
virtual bool FetchVideo(
TRange<FMediaTimeStamp> TimeRange,
TSharedPtr<IMediaTextureSample, ESPMode::ThreadSafe> &OutSample) override
{
UE_LOGFMT(LogDirectVideo, VeryVerbose, "AFetch video frame {0}", VideoSample.IsValid());
if (VideoSample.IsValid())
{
OutSample = VideoSample;
VideoSample.Reset();
return true;
}
return false; // override in child classes, if supported
}
virtual EFetchBestSampleResult FetchBestVideoSampleForTimeRange(
const TRange<FMediaTimeStamp> &TimeRange,
TSharedPtr<IMediaTextureSample, ESPMode::ThreadSafe> &OutSample, bool bReverse)
{
UE_LOGFMT(LogDirectVideo, VeryVerbose, "Best sample {0}", VideoSample.IsValid());
if (VideoSample.IsValid())
{
OutSample = VideoSample;
VideoSample.Reset();
return EFetchBestSampleResult::Ok;
}
else
{
return EFetchBestSampleResult::NoSample;
}
}
virtual void FlushSamples() override
{
UE_LOGFMT(LogDirectVideo, VeryVerbose, "Flush samples {0}", VideoSample.IsValid());
// override in child classes, if supported
VideoSample.Reset();
FlushCount += 1;
}
virtual uint32 GetFlushCount()
{
return FlushCount;
}
virtual bool PeekVideoSampleTime(FMediaTimeStamp &TimeStamp) override
{
if (VideoSample.IsValid())
{
TimeStamp = VideoSample->GetTime();
UE_LOGFMT(LogDirectVideo, VeryVerbose, "Peek timestamp {0}",
TimeStamp.Time.GetTotalSeconds());
return true;
}
else
{
// UE_LOGFMT(LogDirectVideo, VeryVerbose, "Peek timestamp returning zero");
// TimeStamp =
// FMediaTimeStamp(FTimespan(0LL),FMediaTimeStamp::MakeSequenceIndex(0, 0));
// return true;
UE_LOGFMT(LogDirectVideo, VeryVerbose, "Peek timestamp returning false");
return false;
}
}
virtual int32 NumVideoSamples() const override
{
UE_LOGFMT(LogDirectVideo, VeryVerbose, "Query num samples {0}", VideoSample.IsValid());
if (VideoSample.IsValid())
{
return 1;
}
else
{
return 0;
}
}
bool DiscardVideoSamples(const TRange<FMediaTimeStamp> &TimeRange, bool bReverse) override
{
UE_LOGFMT(LogDirectVideo, VeryVerbose, "Discard video samples {0}", VideoSample.IsValid());
return false;
}
virtual uint32 PurgeOutdatedVideoSamples(const FMediaTimeStamp &ReferenceTime, bool bReversed,
FTimespan MaxAge) override
{
UE_LOGFMT(LogDirectVideo, VeryVerbose, "PurgeOutdatedVideoSamples {0} {1}",
VideoSample.IsValid(), ReferenceTime.Time.GetTicks() * 100);
return 0;
};
TSharedPtr<AndroidVulkanTextureSample, ESPMode::ThreadSafe> VideoSample;
uint32 FlushCount = 0;
};