156 lines
4.9 KiB
C++
156 lines
4.9 KiB
C++
// ------------------------------------------------
|
|
// 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;
|
|
};
|