code
This commit is contained in:
@ -0,0 +1,155 @@
|
||||
// ------------------------------------------------
|
||||
// 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;
|
||||
};
|
Reference in New Issue
Block a user