4#ifndef EVRCUSTOMPRESENTER_H
5#define EVRCUSTOMPRESENTER_H
23#include <qvideoframeformat.h>
24#include <qvideosink.h>
26#include <QtCore/private/qcomptr_p.h>
40class D3DPresentEngine;
59 if (iid == __uuidof(IUnknown)) {
60 *ppv =
static_cast<IUnknown*>(
static_cast<IMFAsyncCallback*>(
this));
61 }
else if (iid == __uuidof(IMFAsyncCallback)) {
62 *ppv =
static_cast<IMFAsyncCallback*>(
this);
126 DWORD schedulerThreadProcPrivate();
127 bool isSampleReadyToPresent(IMFSample *sample, LONG *pNextSleep)
const;
131 QQueue<ComPtr<IMFSample>> m_scheduledSamples;
133 ComPtr<IMFClock> m_clock;
136 ThreadHandle m_schedulerThread;
137 EventHandle m_threadReadyEvent;
138 EventHandle m_flushEvent;
140 float m_playbackRate;
141 MFTIME m_perFrame_1_4th;
161 QList<ComPtr<IMFSample>> m_videoSampleQueue;
201 EVRCustomPresenter(QVideoSink *sink = 0);
238 void setSink(QVideoSink *sink);
245 bool event(QEvent *)
override;
251 HRESULT checkShutdown()
const
253 if (m_renderState == RenderShutdown)
254 return MF_E_SHUTDOWN;
260 inline bool isActive()
const
262 return ((m_renderState == RenderStarted) || (m_renderState == RenderPaused));
266 inline bool isScrubbing()
const {
return m_playbackRate == 0.0f; }
269 void notifyEvent(
long eventCode, LONG_PTR param1, LONG_PTR param2)
271 if (m_mediaEventSink)
272 m_mediaEventSink->Notify(eventCode, param1, param2);
275 float getMaxRate(
bool thin);
278 HRESULT configureMixer(IMFTransform *mixer);
281 HRESULT createOptimalVideoType(IMFMediaType* proposed, IMFMediaType **optimal);
282 HRESULT setMediaType(IMFMediaType *mediaType);
283 HRESULT isMediaTypeSupported(IMFMediaType *mediaType);
287 HRESULT renegotiateMediaType();
288 HRESULT processInputNotify();
289 HRESULT beginStreaming();
290 HRESULT endStreaming();
291 HRESULT checkEndOfStream();
294 void processOutputLoop();
295 HRESULT processOutput();
296 HRESULT deliverSample(
const ComPtr<IMFSample> &sample);
297 HRESULT trackSample(
const ComPtr<IMFSample> &sample);
298 void releaseResources();
301 HRESULT prepareFrameStep(DWORD steps);
302 HRESULT startFrameStep();
303 HRESULT deliverFrameStepSample(
const ComPtr<IMFSample> &sample);
304 HRESULT completeFrameStep(
const ComPtr<IMFSample> &sample);
305 HRESULT cancelFrameStep();
308 HRESULT onSampleFree(IMFAsyncResult *result);
315 QList<ComPtr<IMFSample>> samples;
317 DWORD_PTR sampleNoRef = 0;
322 RenderState m_renderState;
323 FrameStep m_frameStep;
330 DWORD m_tokenCounter;
337 MFVideoNormalizedRect m_sourceRect;
338 float m_playbackRate;
340 D3DPresentEngine *m_presentEngine;
342 ComPtr<IMFClock> m_clock;
343 ComPtr<IMFTransform> m_mixer;
344 ComPtr<IMediaEventSink> m_mediaEventSink;
345 ComPtr<IMFMediaType> m_mediaType;
347 QPointer<QVideoSink> m_videoSink;
348 bool m_canRenderToSurface;
349 qint64 m_positionOffset;
STDMETHODIMP_(ULONG) AddRef() override
AsyncCallback(T *parent, InvokeFn fn)
STDMETHODIMP QueryInterface(REFIID iid, void **ppv) override
STDMETHODIMP GetDeviceID(IID *deviceID) override
STDMETHODIMP GetSlowestRate(MFRATE_DIRECTION direction, BOOL thin, float *rate) override
STDMETHODIMP OnClockStop(MFTIME systemTime) override
STDMETHODIMP ReleaseServicePointers() override
STDMETHODIMP QueryInterface(REFIID riid, void **ppv) override
STDMETHODIMP OnClockRestart(MFTIME systemTime) override
STDMETHODIMP InitServicePointers(IMFTopologyServiceLookup *lookup) override
STDMETHODIMP GetService(REFGUID guidService, REFIID riid, LPVOID *ppvObject) override
void supportedFormatsChanged()
void setCropRect(QRect cropRect)
STDMETHODIMP_(ULONG) AddRef() override
STDMETHODIMP IsRateSupported(BOOL thin, float rate, float *nearestSupportedRate) override
STDMETHODIMP OnClockSetRate(MFTIME systemTime, float rate) override
STDMETHODIMP GetCurrentMediaType(IMFVideoMediaType **mediaType) override
void setSink(QVideoSink *sink)
STDMETHODIMP GetFastestRate(MFRATE_DIRECTION direction, BOOL thin, float *rate) override
void presentSample(const ComPtr< IMFSample > &sample)
STDMETHODIMP OnClockStart(MFTIME systemTime, LONGLONG clockStartOffset) override
STDMETHODIMP OnClockPause(MFTIME systemTime) override
STDMETHODIMP ProcessMessage(MFVP_MESSAGE_TYPE message, ULONG_PTR param) override
~EVRCustomPresenter() override
EVRCustomPresenter(QVideoSink *sink=0)
ComPtr< IMFSample > sample() const
PresentSampleEvent(const ComPtr< IMFSample > &sample)
ComPtr< IMFSample > takeSample()
void returnSample(const ComPtr< IMFSample > &sample)
HRESULT initialize(QList< ComPtr< IMFSample > > &&samples)
Scheduler(EVRCustomPresenter *presenter)
HRESULT startScheduler(ComPtr< IMFClock > clock)
void setFrameRate(const MFRatio &fps)
void setClockRate(float rate)
HRESULT processSamplesInQueue(LONG *nextSleep)
bool areSamplesScheduled()
HRESULT scheduleSample(const ComPtr< IMFSample > &sample, bool presentNow)
static LONG MFTimeToMsec(const LONGLONG &time)
static QVideoFrameFormat::PixelFormat pixelFormatFromMediaType(IMFMediaType *type)
static HRESULT setMixerSourceRect(IMFTransform *mixer, const MFVideoNormalizedRect &nrcSource)
#define QMM_PRESENTATION_CURRENT_POSITION
static const DWORD SCHEDULER_TIMEOUT
bool qt_evr_setCustomPresenter(IUnknown *evr, EVRCustomPresenter *presenter)
static const LONG ONE_MSEC
static const MFTIME ONE_SECOND
static const MFRatio g_DefaultFrameRate
Combined button and popup list for selecting options.
#define qCWarning(category,...)
#define qCDebug(category,...)
#define Q_STATIC_LOGGING_CATEGORY(name,...)