121 lines
3.8 KiB
C++
121 lines
3.8 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 "IMediaSamples.h"
|
|
#include "AndroidVulkanTextureSample.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());
|
|
}
|
|
UE_LOGFMT(LogDirectVideo, VeryVerbose, "CSet video frame {0}", VideoSample.IsValid());
|
|
VideoSample = InSample;
|
|
}
|
|
|
|
virtual bool FetchVideo(TRange<FTimespan> TimeRange, TSharedPtr<IMediaTextureSample, ESPMode::ThreadSafe> &OutSample)
|
|
{
|
|
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)
|
|
{
|
|
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 void FlushSamples()
|
|
{
|
|
UE_LOGFMT(LogDirectVideo, VeryVerbose, "Flush samples {0}", VideoSample.IsValid());
|
|
// override in child classes, if supported
|
|
VideoSample.Reset();
|
|
}
|
|
|
|
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 False");
|
|
}
|
|
return false;
|
|
}
|
|
|
|
virtual int32 NumVideoSamples() const
|
|
{
|
|
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)
|
|
{
|
|
UE_LOGFMT(LogDirectVideo, VeryVerbose, "Discard video samples {0}", VideoSample.IsValid());
|
|
return false;
|
|
}
|
|
|
|
virtual uint32 PurgeOutdatedVideoSamples(const FMediaTimeStamp &ReferenceTime, bool bReversed, FTimespan MaxAge)
|
|
{
|
|
UE_LOGFMT(LogDirectVideo, VeryVerbose, "PurgeOutdatedVideoSamples {0} {1}", VideoSample.IsValid(), ReferenceTime.Time.GetTicks() * 100);
|
|
return 0;
|
|
};
|
|
|
|
|
|
TSharedPtr<AndroidVulkanTextureSample, ESPMode::ThreadSafe> VideoSample;
|
|
|
|
|
|
|
|
};
|