[MediaFoundation] Volume controls of different media elements should be independent
[WebKit-https.git] / Source / WebCore / platform / graphics / win / MediaPlayerPrivateMediaFoundation.h
1 /*
2  * Copyright (C) 2014 Alex Christensen <achristensen@webkit.org>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26
27 #pragma once
28
29 #include "COMPtr.h"
30 #include "MediaPlayerPrivate.h"
31
32 #include <D3D9.h>
33 #include <Dxva2api.h>
34
35 #include <Mfapi.h>
36 #include <Mferror.h>
37 #include <Mfidl.h>
38 #include <evcode.h>
39 #include <evr.h>
40
41 #include <wtf/Deque.h>
42 #include <wtf/Lock.h>
43 #include <wtf/ThreadingPrimitives.h>
44 #include <wtf/WeakPtr.h>
45 #include <wtf/win/Win32Handle.h>
46
47 namespace WebCore {
48
49 class MediaPlayerPrivateMediaFoundation : public MediaPlayerPrivateInterface {
50 public:
51     explicit MediaPlayerPrivateMediaFoundation(MediaPlayer*);
52     ~MediaPlayerPrivateMediaFoundation();
53     static void registerMediaEngine(MediaEngineRegistrar);
54
55     static void getSupportedTypes(HashSet<String, ASCIICaseInsensitiveHash>& types);
56     static MediaPlayer::SupportsType supportsType(const MediaEngineSupportParameters&);
57     static bool isAvailable();
58
59     void load(const String& url) override;
60     void cancelLoad() override;
61
62     void prepareToPlay() override;
63
64     void play() override;
65     void pause() override;
66
67     bool supportsFullscreen() const override;
68
69     FloatSize naturalSize() const override;
70
71     bool hasVideo() const override;
72     bool hasAudio() const override;
73
74     void setVisible(bool) override;
75
76     bool seeking() const override;
77     void seek(float) override;
78
79     void setRate(float) override;
80
81     float duration() const override;
82
83     float currentTime() const override;
84
85     bool paused() const override;
86
87     void setVolume(float) override;
88
89     bool supportsMuting() const override;
90     void setMuted(bool) override;
91
92     MediaPlayer::NetworkState networkState() const override;
93     MediaPlayer::ReadyState readyState() const override;
94
95     float maxTimeSeekable() const override;
96
97     std::unique_ptr<PlatformTimeRanges> buffered() const override;
98
99     bool didLoadingProgress() const override;
100
101     void setSize(const IntSize&) override;
102
103     void paint(GraphicsContext&, const FloatRect&) override;
104
105 private:
106     MediaPlayer* m_player;
107     IntSize m_size;
108     bool m_visible;
109     bool m_loadingProgress;
110     bool m_paused;
111     bool m_hasAudio;
112     bool m_hasVideo;
113     bool m_preparingToPlay;
114     float m_volume;
115     HWND m_hwndVideo;
116     MediaPlayer::NetworkState m_networkState;
117     MediaPlayer::ReadyState m_readyState;
118     FloatRect m_lastPaintRect;
119
120     class MediaPlayerListener;
121     HashSet<MediaPlayerListener*> m_listeners;
122     Lock m_mutexListeners;
123
124     FloatSize m_cachedNaturalSize;
125     mutable Lock m_cachedNaturalSizeLock;
126
127     WeakPtrFactory<MediaPlayerPrivateMediaFoundation> m_weakPtrFactory;
128     COMPtr<IMFMediaSession> m_mediaSession;
129     COMPtr<IMFSourceResolver> m_sourceResolver;
130     COMPtr<IMFMediaSource> m_mediaSource;
131     COMPtr<IMFTopology> m_topology;
132     COMPtr<IMFPresentationDescriptor> m_sourcePD;
133     COMPtr<IMFVideoDisplayControl> m_videoDisplay;
134
135     bool createSession();
136     bool startSession();
137     bool endSession();
138     bool startCreateMediaSource(const String& url);
139     bool endCreatedMediaSource(IMFAsyncResult*);
140     bool endGetEvent(IMFAsyncResult*);
141     bool createTopologyFromSource();
142     bool addBranchToPartialTopology(int stream);
143     bool createOutputNode(COMPtr<IMFStreamDescriptor> sourceSD, COMPtr<IMFTopologyNode>&);
144     bool createSourceStreamNode(COMPtr<IMFStreamDescriptor> sourceSD, COMPtr<IMFTopologyNode>&);
145
146     void updateReadyState();
147
148     COMPtr<IMFVideoDisplayControl> videoDisplay();
149
150     void onCreatedMediaSource();
151     void onTopologySet();
152     void onBufferingStarted();
153     void onBufferingStopped();
154     void onSessionEnded();
155
156     LPCWSTR registerVideoWindowClass();
157     void createVideoWindow();
158     void destroyVideoWindow();
159
160     void invalidateFrameView();
161
162     void addListener(MediaPlayerListener*);
163     void removeListener(MediaPlayerListener*);
164     void setNaturalSize(const FloatSize&);
165     void notifyDeleted();
166
167     static LRESULT CALLBACK VideoViewWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
168
169     bool setAllChannelVolumes(float);
170
171     class MediaPlayerListener {
172     public:
173         MediaPlayerListener() { }
174         virtual ~MediaPlayerListener() { }
175
176         virtual void onMediaPlayerDeleted() { }
177     };
178
179     class AsyncCallback : public IMFAsyncCallback, public MediaPlayerListener {
180     public:
181         AsyncCallback(MediaPlayerPrivateMediaFoundation*, bool event);
182         ~AsyncCallback();
183
184         HRESULT STDMETHODCALLTYPE QueryInterface(_In_ REFIID riid, __RPC__deref_out void __RPC_FAR *__RPC_FAR *ppvObject) override;
185         ULONG STDMETHODCALLTYPE AddRef() override;
186         ULONG STDMETHODCALLTYPE Release() override;
187
188         HRESULT STDMETHODCALLTYPE GetParameters(__RPC__out DWORD *pdwFlags, __RPC__out DWORD *pdwQueue) override;
189         HRESULT STDMETHODCALLTYPE Invoke(__RPC__in_opt IMFAsyncResult *pAsyncResult) override;
190
191         void onMediaPlayerDeleted() override;
192
193     private:
194         ULONG m_refCount;
195         MediaPlayerPrivateMediaFoundation* m_mediaPlayer;
196         bool m_event;
197         Lock m_mutex;
198     };
199
200     typedef Deque<COMPtr<IMFSample>> VideoSampleList;
201
202     class VideoSamplePool {
203     public:
204         VideoSamplePool() { }
205         virtual ~VideoSamplePool() { }
206
207         HRESULT initialize(VideoSampleList& samples);
208         void clear();
209
210         HRESULT getSample(COMPtr<IMFSample>&);
211         HRESULT returnSample(IMFSample*);
212         bool areSamplesPending();
213
214     private:
215         Lock m_lock;
216         VideoSampleList m_videoSampleQueue;
217         bool m_initialized { false };
218         unsigned m_pending { 0 };
219     };
220
221     class Direct3DPresenter;
222
223     class VideoScheduler {
224     public:
225         VideoScheduler() { }
226         virtual ~VideoScheduler() { }
227
228         void setPresenter(Direct3DPresenter* presenter) { m_presenter = presenter; }
229
230         void setFrameRate(const MFRatio& fps);
231         void setClockRate(float rate) { m_playbackRate = rate; }
232
233         const LONGLONG& lastSampleTime() const { return m_lastSampleTime; }
234         const LONGLONG& frameDuration() const { return m_frameDuration; }
235
236         HRESULT startScheduler(IMFClock*);
237         HRESULT stopScheduler();
238
239         HRESULT scheduleSample(IMFSample*, bool presentNow);
240         HRESULT processSamplesInQueue(LONG& nextSleep);
241         HRESULT processSample(IMFSample*, LONG& nextSleep);
242         HRESULT flush();
243
244     private:
245         static DWORD WINAPI schedulerThreadProc(LPVOID lpParameter);
246         DWORD schedulerThreadProcPrivate();
247
248         Deque<COMPtr<IMFSample>> m_scheduledSamples;
249         Lock m_lock;
250
251         COMPtr<IMFClock> m_clock;
252         Direct3DPresenter* m_presenter { nullptr };
253
254         DWORD m_threadID { 0 };
255         WTF::Win32Handle m_schedulerThread;
256         WTF::Win32Handle m_threadReadyEvent;
257         WTF::Win32Handle m_flushEvent;
258
259         float m_playbackRate { 1.0f };
260         MFTIME m_frameDuration { 0 };
261         MFTIME m_lastSampleTime { 0 };
262
263         std::atomic<bool> m_exitThread { false };
264
265         void stopThread() { m_exitThread = true; }
266     };
267
268     class Direct3DPresenter {
269     public:
270         Direct3DPresenter();
271         ~Direct3DPresenter();
272
273         enum DeviceState {
274             DeviceOK,
275             DeviceReset,
276             DeviceRemoved,
277         };
278
279         // Returns the IDirect3DDeviceManager9 interface.
280         HRESULT getService(REFGUID guidService, REFIID riid, void** ppv);
281
282         HRESULT checkFormat(D3DFORMAT);
283
284         HRESULT setVideoWindow(HWND);
285         HWND getVideoWindow() const { return m_hwnd; }
286         HRESULT setDestinationRect(const RECT& destRect);
287         RECT getDestinationRect() const { return m_destRect; };
288
289         HRESULT createVideoSamples(IMFMediaType* format, VideoSampleList& videoSampleQueue);
290         void releaseResources();
291
292         HRESULT checkDeviceState(DeviceState&);
293         HRESULT presentSample(IMFSample*, LONGLONG target);
294
295         UINT refreshRate() const { return m_displayMode.RefreshRate; }
296
297         void paintCurrentFrame(GraphicsContext&, const FloatRect&);
298
299     private:
300         HRESULT initializeD3D();
301         HRESULT getSwapChainPresentParameters(IMFMediaType*, D3DPRESENT_PARAMETERS* presentParams);
302         HRESULT createD3DDevice();
303         HRESULT createD3DSample(IDirect3DSwapChain9*, COMPtr<IMFSample>& videoSample);
304         HRESULT updateDestRect();
305
306         HRESULT presentSwapChain(IDirect3DSwapChain9*, IDirect3DSurface9*);
307
308         UINT m_deviceResetToken { 0 };
309         HWND m_hwnd { nullptr };
310         RECT m_destRect;
311         D3DDISPLAYMODE m_displayMode;
312
313         Lock m_lock;
314         
315         COMPtr<IDirect3D9Ex> m_direct3D9;
316         COMPtr<IDirect3DDevice9Ex> m_device;
317         COMPtr<IDirect3DDeviceManager9> m_deviceManager;
318         COMPtr<IDirect3DSurface9> m_surfaceRepaint;
319
320         COMPtr<IDirect3DSurface9> m_memSurface;
321         int m_width { 0 };
322         int m_height { 0 };
323     };
324
325     class CustomVideoPresenter
326         : public IMFVideoPresenter
327         , public IMFVideoDeviceID
328         , public IMFTopologyServiceLookupClient
329         , public IMFGetService
330         , public IMFActivate
331         , public IMFVideoDisplayControl
332         , public IMFAsyncCallback
333         , public MediaPlayerListener {
334     public:
335         CustomVideoPresenter(MediaPlayerPrivateMediaFoundation*);
336         ~CustomVideoPresenter();
337
338         HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, __RPC__deref_out void __RPC_FAR *__RPC_FAR *ppvObject) override;
339         ULONG STDMETHODCALLTYPE AddRef() override;
340         ULONG STDMETHODCALLTYPE Release() override;
341
342         // IMFClockStateSink
343         HRESULT STDMETHODCALLTYPE OnClockStart(MFTIME hnsSystemTime, LONGLONG llClockStartOffset) override;
344         HRESULT STDMETHODCALLTYPE OnClockStop(MFTIME hnsSystemTime) override;
345         HRESULT STDMETHODCALLTYPE OnClockPause(MFTIME hnsSystemTime) override;
346         HRESULT STDMETHODCALLTYPE OnClockRestart(MFTIME hnsSystemTime) override;
347         HRESULT STDMETHODCALLTYPE OnClockSetRate(MFTIME hnsSystemTime, float flRate) override;
348
349         // IMFVideoPresenter
350         HRESULT STDMETHODCALLTYPE ProcessMessage(MFVP_MESSAGE_TYPE eMessage, ULONG_PTR ulParam) override;
351         HRESULT STDMETHODCALLTYPE GetCurrentMediaType(_Outptr_  IMFVideoMediaType **ppMediaType) override;
352
353         // IMFVideoDeviceID
354         HRESULT STDMETHODCALLTYPE GetDeviceID(IID* pDeviceID) override;
355
356         // IMFTopologyServiceLookupClient
357         HRESULT STDMETHODCALLTYPE InitServicePointers(_In_  IMFTopologyServiceLookup *pLookup) override;
358         HRESULT STDMETHODCALLTYPE ReleaseServicePointers(void) override;
359
360         // IMFGetService
361         virtual HRESULT STDMETHODCALLTYPE GetService(REFGUID guidService, REFIID riid, LPVOID *ppvObject);
362
363         // IMFActivate
364         virtual HRESULT STDMETHODCALLTYPE ActivateObject(REFIID riid, void **ppv);
365         virtual HRESULT STDMETHODCALLTYPE DetachObject();
366         virtual HRESULT STDMETHODCALLTYPE ShutdownObject();
367
368         // IMFAttributes
369         virtual HRESULT STDMETHODCALLTYPE GetItem(__RPC__in REFGUID guidKey, __RPC__inout_opt PROPVARIANT *pValue) { return E_NOTIMPL; }
370         virtual HRESULT STDMETHODCALLTYPE GetItemType(__RPC__in REFGUID guidKey, __RPC__out MF_ATTRIBUTE_TYPE *pType) { return E_NOTIMPL; }
371         virtual HRESULT STDMETHODCALLTYPE CompareItem(__RPC__in REFGUID guidKey, __RPC__in REFPROPVARIANT Value, __RPC__out BOOL *pbResult) { return E_NOTIMPL; }
372         virtual HRESULT STDMETHODCALLTYPE Compare(__RPC__in_opt IMFAttributes *pTheirs, MF_ATTRIBUTES_MATCH_TYPE MatchType, __RPC__out BOOL *pbResult) { return E_NOTIMPL; }
373         virtual HRESULT STDMETHODCALLTYPE GetUINT32(__RPC__in REFGUID guidKey, __RPC__out UINT32 *punValue) { return E_NOTIMPL; }
374         virtual HRESULT STDMETHODCALLTYPE GetUINT64(__RPC__in REFGUID guidKey, __RPC__out UINT64 *punValue) { return E_NOTIMPL; }
375         virtual HRESULT STDMETHODCALLTYPE GetDouble(__RPC__in REFGUID guidKey, __RPC__out double *pfValue) { return E_NOTIMPL; }
376         virtual HRESULT STDMETHODCALLTYPE GetGUID(__RPC__in REFGUID guidKey, __RPC__out GUID *pguidValue) { return E_NOTIMPL; }
377         virtual HRESULT STDMETHODCALLTYPE GetStringLength(__RPC__in REFGUID guidKey, __RPC__out UINT32 *pcchLength) { return E_NOTIMPL; }
378         virtual HRESULT STDMETHODCALLTYPE GetString(__RPC__in REFGUID guidKey, __RPC__out_ecount_full(cchBufSize) LPWSTR pwszValue, UINT32 cchBufSize, __RPC__inout_opt UINT32 *pcchLength) { return E_NOTIMPL; }
379         virtual HRESULT STDMETHODCALLTYPE GetAllocatedString(__RPC__in REFGUID guidKey, __RPC__deref_out_ecount_full_opt((*pcchLength + 1)) LPWSTR *ppwszValue, __RPC__out UINT32 *pcchLength) { return E_NOTIMPL; }
380         virtual HRESULT STDMETHODCALLTYPE GetBlobSize(__RPC__in REFGUID guidKey, __RPC__out UINT32 *pcbBlobSize) { return E_NOTIMPL; }
381         virtual HRESULT STDMETHODCALLTYPE GetBlob(__RPC__in REFGUID guidKey, __RPC__out_ecount_full(cbBufSize) UINT8 *pBuf, UINT32 cbBufSize, __RPC__inout_opt UINT32 *pcbBlobSize) { return E_NOTIMPL; }
382         virtual HRESULT STDMETHODCALLTYPE GetAllocatedBlob(__RPC__in REFGUID guidKey, __RPC__deref_out_ecount_full_opt(*pcbSize) UINT8 **ppBuf, __RPC__out UINT32 *pcbSize) { return E_NOTIMPL; }
383         virtual HRESULT STDMETHODCALLTYPE GetUnknown(__RPC__in REFGUID guidKey, __RPC__in REFIID riid, __RPC__deref_out_opt LPVOID *ppv) { return E_NOTIMPL; }
384         virtual HRESULT STDMETHODCALLTYPE SetItem(__RPC__in REFGUID guidKey, __RPC__in REFPROPVARIANT Value) { return E_NOTIMPL; }
385         virtual HRESULT STDMETHODCALLTYPE DeleteItem(__RPC__in REFGUID guidKey) { return E_NOTIMPL; }
386         virtual HRESULT STDMETHODCALLTYPE DeleteAllItems(void) { return E_NOTIMPL; }
387         virtual HRESULT STDMETHODCALLTYPE SetUINT32(__RPC__in REFGUID guidKey, UINT32 unValue) { return E_NOTIMPL; }
388         virtual HRESULT STDMETHODCALLTYPE SetUINT64(__RPC__in REFGUID guidKey, UINT64 unValue) { return E_NOTIMPL; }
389         virtual HRESULT STDMETHODCALLTYPE SetDouble(__RPC__in REFGUID guidKey, double fValue) { return E_NOTIMPL; }
390         virtual HRESULT STDMETHODCALLTYPE SetGUID(__RPC__in REFGUID guidKey, __RPC__in REFGUID guidValue) { return E_NOTIMPL; }
391         virtual HRESULT STDMETHODCALLTYPE SetString(__RPC__in REFGUID guidKey, __RPC__in_string LPCWSTR wszValue) { return E_NOTIMPL; }
392         virtual HRESULT STDMETHODCALLTYPE SetBlob(__RPC__in REFGUID guidKey, __RPC__in_ecount_full(cbBufSize) const UINT8 *pBuf, UINT32 cbBufSize) { return E_NOTIMPL; }
393         virtual HRESULT STDMETHODCALLTYPE SetUnknown(__RPC__in REFGUID guidKey, __RPC__in_opt IUnknown *pUnknown) { return E_NOTIMPL; }
394         virtual HRESULT STDMETHODCALLTYPE LockStore(void) { return E_NOTIMPL; }
395         virtual HRESULT STDMETHODCALLTYPE UnlockStore(void) { return E_NOTIMPL; }
396         virtual HRESULT STDMETHODCALLTYPE GetCount(__RPC__out UINT32 *pcItems) { return E_NOTIMPL; }
397         virtual HRESULT STDMETHODCALLTYPE GetItemByIndex(UINT32 unIndex, __RPC__out GUID *pguidKey, __RPC__inout_opt PROPVARIANT *pValue) { return E_NOTIMPL; }
398         virtual HRESULT STDMETHODCALLTYPE CopyAllItems(__RPC__in_opt IMFAttributes *pDest) { return E_NOTIMPL; }
399
400         // IMFVideoDisplayControl
401         virtual HRESULT STDMETHODCALLTYPE GetNativeVideoSize(SIZE* pszVideo, SIZE* pszARVideo) { return E_NOTIMPL; }
402         virtual HRESULT STDMETHODCALLTYPE GetIdealVideoSize(SIZE* pszMin, SIZE* pszMax) { return E_NOTIMPL; }
403         virtual HRESULT STDMETHODCALLTYPE SetVideoPosition(const MFVideoNormalizedRect* pnrcSource, const LPRECT prcDest);
404         virtual HRESULT STDMETHODCALLTYPE GetVideoPosition(MFVideoNormalizedRect* pnrcSource, LPRECT prcDest);
405         virtual HRESULT STDMETHODCALLTYPE SetAspectRatioMode(DWORD dwAspectRatioMode) { return E_NOTIMPL; }
406         virtual HRESULT STDMETHODCALLTYPE GetAspectRatioMode(DWORD* pdwAspectRatioMode) { return E_NOTIMPL; }
407         virtual HRESULT STDMETHODCALLTYPE SetVideoWindow(HWND hwndVideo);
408         virtual HRESULT STDMETHODCALLTYPE GetVideoWindow(HWND* phwndVideo);
409         virtual HRESULT STDMETHODCALLTYPE RepaintVideo();
410         virtual HRESULT STDMETHODCALLTYPE GetCurrentImage(BITMAPINFOHEADER* pBih, BYTE** pDib, DWORD* pcbDib, LONGLONG* pTimeStamp) { return E_NOTIMPL; }
411         virtual HRESULT STDMETHODCALLTYPE SetBorderColor(COLORREF Clr) { return E_NOTIMPL; }
412         virtual HRESULT STDMETHODCALLTYPE GetBorderColor(COLORREF* pClr) { return E_NOTIMPL; }
413         virtual HRESULT STDMETHODCALLTYPE SetRenderingPrefs(DWORD dwRenderFlags) { return E_NOTIMPL; }
414         virtual HRESULT STDMETHODCALLTYPE GetRenderingPrefs(DWORD* pdwRenderFlags) { return E_NOTIMPL; }
415         virtual HRESULT STDMETHODCALLTYPE SetFullscreen(BOOL bFullscreen) { return E_NOTIMPL; }
416         virtual HRESULT STDMETHODCALLTYPE GetFullscreen(BOOL* pbFullscreen) { return E_NOTIMPL; }
417
418         // IMFAsyncCallback methods
419         virtual HRESULT STDMETHODCALLTYPE GetParameters(DWORD*, DWORD*) { return E_NOTIMPL; }
420         virtual HRESULT STDMETHODCALLTYPE Invoke(IMFAsyncResult* pAsyncResult);
421
422         // MediaPlayerListener
423         void onMediaPlayerDeleted() override;
424
425         void paintCurrentFrame(GraphicsContext&, const FloatRect&);
426
427         float currentTime();
428
429         float maxTimeLoaded() const { return m_maxTimeLoaded; }
430
431     private:
432         ULONG m_refCount { 0 };
433         Lock m_lock;
434         MediaPlayerPrivateMediaFoundation* m_mediaPlayer;
435
436         enum RenderState {
437             RenderStateStarted = 1,
438             RenderStateStopped,
439             RenderStatePaused,
440             RenderStateShutdown,
441         };
442
443         RenderState m_renderState { RenderStateShutdown };
444         COMPtr<IMFClock> m_clock;
445         COMPtr<IMediaEventSink> m_mediaEventSink;
446         COMPtr<IMFTransform> m_mixer;
447         COMPtr<IMFMediaType> m_mediaType;
448         std::unique_ptr<Direct3DPresenter> m_presenterEngine;
449         MFVideoNormalizedRect m_sourceRect;
450         bool m_sampleNotify { false };
451         bool m_prerolled { false };
452         bool m_repaint { false };
453         bool m_endStreaming { false };
454         VideoScheduler m_scheduler;
455         VideoSamplePool m_samplePool;
456         unsigned m_tokenCounter { 0 };
457         float m_rate { 1.0f };
458         float m_maxTimeLoaded { 0.0f };
459
460         bool isActive() const;
461
462         bool isScrubbing() const { return m_rate == 0.0f; }
463
464         HRESULT configureMixer(IMFTransform* mixer);
465         HRESULT flush();
466         HRESULT setMediaType(IMFMediaType*);
467         HRESULT checkShutdown() const;
468         HRESULT renegotiateMediaType();
469         HRESULT processInputNotify();
470         HRESULT beginStreaming();
471         HRESULT endStreaming();
472         HRESULT checkEndOfStream();
473         HRESULT isMediaTypeSupported(IMFMediaType*);
474         HRESULT createOptimalVideoType(IMFMediaType* proposedType, IMFMediaType** optimalType);
475         HRESULT calculateOutputRectangle(IMFMediaType* proposedType, RECT& outputRect);
476
477         void processOutputLoop();
478         HRESULT processOutput();
479         HRESULT deliverSample(IMFSample*, bool repaint);
480         HRESULT trackSample(IMFSample*);
481         void releaseResources();
482
483         HRESULT onSampleFree(IMFAsyncResult*);
484
485         void notifyEvent(long EventCode, LONG_PTR Param1, LONG_PTR Param2);
486     };
487
488     COMPtr<CustomVideoPresenter> m_presenter;
489 };
490
491 }