source: trunk/Utilities/StressEvr/MainDialog.h @ 937

Last change on this file since 937 was 335, checked in by roman, 8 years ago

Removed unnecessary stuff, upgraded to VS2012

  • Property svn:keywords set to Id
File size: 31.0 KB
Line 
1////////////////////////////////////////////////////////////
2// Copyright (C) Roman Ryltsov, 2008-2014
3// Created by Roman Ryltsov roman@alax.info
4
5#pragma once
6
7#include <dxgi.h>
8#include "AboutDialog.h"
9#include <dshow.h>
10#include <d3d9.h>
11#include <vmr9.h>
12#include <evr.h>
13#include <evr9.h>
14#include "rodshow.h"
15
16#pragma comment(lib, "dxgi.lib")
17
18////////////////////////////////////////////////////////////
19// CVmr7Window
20
21class CVmr7Window :
22        public CControlWindowT<CVmr7Window>
23{
24public:
25
26BEGIN_MSG_MAP_EX(CVmr7Window)
27        //CHAIN_MSG_MAP(CControlWindowT<CVmr7Window>)
28        MSG_WM_ERASEBKGND(OnEraseBkgnd)
29        MSG_WM_PAINT(OnPaint)
30        MSG_WM_DISPLAYCHANGE(OnDisplayChange)
31        MSG_WM_SIZE(OnSize)
32        MSG_WM_LBUTTONDBLCLK(OnLButtonDblClk)
33END_MSG_MAP()
34
35public:
36        CComPtr<IBaseFilter> m_pBaseFilter;
37        CComPtr<IVMRWindowlessControl> m_pVmrWindowlessControl;
38
39public:
40// CVmr7Window
41        static CLSID GetRendererClassIdentifier() throw()
42        {
43                return CLSID_VideoMixingRenderer;
44        }
45        static CComPtr<IBaseFilter> CoCreateBaseFilterInstance()
46        {
47                CComPtr<IBaseFilter> pBaseFilter;
48                __C(pBaseFilter.CoCreateInstance(GetRendererClassIdentifier()));
49                return pBaseFilter;
50        }
51        VOID Initialize(IBaseFilter* pBaseFilter)
52        {
53                _A(pBaseFilter);
54                _A(!m_pBaseFilter && !m_pVmrWindowlessControl);
55                m_pBaseFilter = pBaseFilter;
56                const CComQIPtr<IVMRFilterConfig> pVmrFilterConfig = pBaseFilter;
57                __D(pVmrFilterConfig, E_NOINTERFACE);
58                __C(pVmrFilterConfig->SetRenderingMode(VMRMode_Windowless));
59                m_pVmrWindowlessControl = CComQIPtr<IVMRWindowlessControl>(m_pBaseFilter);
60                __D(m_pVmrWindowlessControl, E_NOINTERFACE);
61                __C(m_pVmrWindowlessControl->SetVideoClippingWindow(m_hWnd));
62                CRect VideoPosition = GetVideoPosition();
63                _Z4(atlTraceGeneral, 4, _T(".m_pVmrWindowlessControl 0x%p, VideoPosition at (%d, %d) size (%d, %d)\n"), m_pVmrWindowlessControl, VideoPosition.left, VideoPosition.top, VideoPosition.Width(), VideoPosition.Height());
64                __C(m_pVmrWindowlessControl->SetVideoPosition(NULL, VideoPosition));
65        }
66        VOID Terminate() throw()
67        {
68                m_pBaseFilter = NULL;
69                m_pVmrWindowlessControl = NULL;
70        }
71        CRect GetVideoPosition() const throw()
72        {
73                CRect Position;
74                _W(GetClientRect(Position));
75                return Position;
76        }
77
78// Window Message Handlers
79        LRESULT OnEraseBkgnd(CDCHandle Dc)
80        {
81                Dc;
82                if(m_pVmrWindowlessControl)
83                {
84                        return TRUE;
85                } else
86                        SetMsgHandled(FALSE);
87                return 0;
88        }
89        LRESULT OnPaint(CDCHandle)
90        {
91                if(m_pVmrWindowlessControl)
92                {
93                        CPaintDC Dc(m_hWnd);
94                        const HRESULT nRepaintVideoResult = m_pVmrWindowlessControl->RepaintVideo(m_hWnd, Dc);
95                        _Z45_HRESULT(nRepaintVideoResult);
96                } else
97                        SetMsgHandled(FALSE);
98                return 0;
99        }
100        LRESULT OnDisplayChange(UINT nDepth, CSize Extent)
101        {
102                if(m_pVmrWindowlessControl)
103                {
104                        const HRESULT nDisplayModeChangedResult = m_pVmrWindowlessControl->DisplayModeChanged();
105                        _Z45_HRESULT(nDisplayModeChangedResult);
106                }
107                return 0;
108        }
109        LRESULT OnSize(UINT nType, CSize)
110        {
111                if(nType != SIZE_MINIMIZED)
112                        if(m_pVmrWindowlessControl)
113                        {
114                                CRect VideoPosition = GetVideoPosition();
115                                const HRESULT nSetVideoPositionResult = m_pVmrWindowlessControl->SetVideoPosition(NULL, &VideoPosition);
116                                _Z45_HRESULT(nSetVideoPositionResult);
117                        }
118                return 0;
119        }
120        LRESULT OnLButtonDblClk(UINT, CPoint)
121        {
122                COlePropertyFrameDialog Dialog(m_pBaseFilter, _T("VMR-7"));
123                Dialog.SetObjectPages();
124                Dialog.DoModal(m_hWnd);
125                return 0;
126        }
127};
128
129////////////////////////////////////////////////////////////
130// CEvrWindow
131
132class CEvrWindow :
133        public CControlWindowT<CEvrWindow>
134{
135public:
136
137BEGIN_MSG_MAP_EX(CEvrWindow)
138        //CHAIN_MSG_MAP(CControlWindowT<CEvrWindow>)
139        MSG_WM_ERASEBKGND(OnEraseBkgnd)
140        MSG_WM_PAINT(OnPaint)
141        MSG_WM_SIZE(OnSize)
142        MSG_WM_LBUTTONDBLCLK(OnLButtonDblClk)
143END_MSG_MAP()
144
145public:
146        CComPtr<IBaseFilter> m_pBaseFilter;
147        CComPtr<IMFVideoDisplayControl> m_pMfVideoDisplayControl;
148
149public:
150// CEvrWindow
151        static CLSID GetRendererClassIdentifier() throw()
152        {
153                return CLSID_EnhancedVideoRenderer;
154        }
155        static CComPtr<IBaseFilter> CoCreateBaseFilterInstance()
156        {
157                CComPtr<IBaseFilter> pBaseFilter;
158                HRESULT nCoCreateInstanceResult = pBaseFilter.CoCreateInstance(GetRendererClassIdentifier());
159                _Z45_HRESULT(nCoCreateInstanceResult);
160                if(nCoCreateInstanceResult == REGDB_E_CLASSNOTREG)
161                {
162                        #pragma region Windows XP Second Chance Instantiation
163                        HINSTANCE hInstance = CoLoadLibrary(CT2OLE(_T("evr.dll")), TRUE);
164                        if(hInstance)
165                        {
166                                _ATLTRY
167                                {
168                                        typedef HRESULT (STDMETHODCALLTYPE *DLLGETCLASSOBJECT)(REFCLSID ClassIdentifier, REFIID InterfaceIdentifier, LPVOID* ppvObject);
169                                        DLLGETCLASSOBJECT pDllGetClassObject = (DLLGETCLASSOBJECT) GetProcAddress(hInstance, "DllGetClassObject");
170                                        __E(pDllGetClassObject);
171                                        CComPtr<IClassFactory> pClassFactory;
172                                        __C((pDllGetClassObject)(GetRendererClassIdentifier(), __uuidof(IClassFactory), (VOID**) &pClassFactory));
173                                        _A(pClassFactory);
174                                        const HRESULT nCreateInstanceResult = pClassFactory->CreateInstance(NULL, __uuidof(IBaseFilter), (VOID**) &pBaseFilter);
175                                        _Z45_HRESULT(nCreateInstanceResult);
176                                        if(SUCCEEDED(nCreateInstanceResult))
177                                                nCoCreateInstanceResult = nCreateInstanceResult;
178                                }
179                                _ATLCATCHALL()
180                                {
181                                        _Z_EXCEPTION();
182                                }
183                                //CoFreeLibrary(hInstance);
184                        }
185                        #pragma endregion
186                }
187                __C(nCoCreateInstanceResult);
188                return pBaseFilter;
189        }
190        VOID Initialize(IBaseFilter* pBaseFilter)
191        {
192                _A(pBaseFilter);
193                _A(!m_pBaseFilter && !m_pMfVideoDisplayControl);
194                m_pBaseFilter = pBaseFilter;
195                CComQIPtr<IMFGetService> pMfGetInterface = pBaseFilter;
196                CComPtr<IMFVideoDisplayControl> pMfVideoDisplayControl;
197                __C(pMfGetInterface->GetService(MR_VIDEO_RENDER_SERVICE, __uuidof(IMFVideoDisplayControl), (VOID**) &pMfVideoDisplayControl));
198                _A(pMfVideoDisplayControl);
199                m_pMfVideoDisplayControl = pMfVideoDisplayControl;
200                __C(pMfVideoDisplayControl->SetVideoWindow(m_hWnd));
201                CRect VideoPosition = GetVideoPosition();
202                _Z4(atlTraceGeneral, 4, _T("pMfVideoDisplayControl 0x%p, VideoPosition at (%d, %d) size (%d, %d)\n"), pMfVideoDisplayControl, VideoPosition.left, VideoPosition.top, VideoPosition.Width(), VideoPosition.Height());
203                __C(pMfVideoDisplayControl->SetVideoPosition(NULL, VideoPosition));
204                //__C(pMfVideoDisplayControl->SetAspectRatioMode(MFVideoARMode_None)); // As opposed to default MFVideoARMode_Picture - disable letterboxing
205        }
206        VOID Terminate() throw()
207        {
208                m_pBaseFilter = NULL;
209                m_pMfVideoDisplayControl = NULL;
210        }
211        CRect GetVideoPosition() const throw()
212        {
213                CRect Position;
214                _W(GetClientRect(Position));
215                return Position;
216        }
217
218// Window Message Handlers
219        LRESULT OnEraseBkgnd(CDCHandle Dc)
220        {
221                Dc;
222                if(m_pMfVideoDisplayControl)
223                {
224                        return TRUE;
225                } else
226                        SetMsgHandled(FALSE);
227                return 0;
228        }
229        LRESULT OnPaint(CDCHandle)
230        {
231                if(m_pMfVideoDisplayControl)
232                {
233                        CPaintDC Dc(m_hWnd);
234                        const HRESULT nRepaintVideoResult = m_pMfVideoDisplayControl->RepaintVideo();
235                        _Z4(atlTraceUI, SUCCEEDED(nRepaintVideoResult) ? 6 : 4, _T("nRepaintVideoResult 0x%08x\n"), nRepaintVideoResult);
236                } else
237                        SetMsgHandled(FALSE);
238                return 0;
239        }
240        LRESULT OnSize(UINT nType, CSize)
241        {
242                if(nType != SIZE_MINIMIZED)
243                        if(m_pMfVideoDisplayControl)
244                        {
245                                CRect VideoPosition = GetVideoPosition();
246                                const HRESULT nSetVideoPositionResult = m_pMfVideoDisplayControl->SetVideoPosition(NULL, &VideoPosition);
247                                _Z4(atlTraceUI, SUCCEEDED(nSetVideoPositionResult) ? 6 : 4, _T("nSetVideoPositionResult 0x%08x\n"), nSetVideoPositionResult);
248                        }
249                return 0;
250        }
251        LRESULT OnLButtonDblClk(UINT, CPoint Position)
252        {
253                COlePropertyFrameDialog Dialog(m_pBaseFilter, _T("EVR"));
254                Dialog.SetObjectPages();
255                Dialog.DoModal(m_hWnd);
256                return 0;
257        }
258};
259
260////////////////////////////////////////////////////////////
261// CBaseVideoDialog
262
263class CBaseVideoDialog
264{
265public:
266// CBaseVideoDialog
267        virtual HWND Create(HWND hParentWindow) = 0;
268        virtual BOOL DestroyWindow() = 0;
269        virtual BOOL IsWindow() = 0;
270        virtual BOOL MoveWindow(const CRect& Position) = 0;
271        virtual INT ShowWindow(INT nShowCommand) = 0;
272};
273
274////////////////////////////////////////////////////////////
275// CVideoDialogT
276
277template <typename T, typename CVrWindow, LPCTSTR* t_ppszType>
278class CVideoDialogT : 
279        public CDialogImpl<T>,
280        public CDialogResize<T>,
281        public CBaseVideoDialog
282{
283        typedef CVideoDialogT<T, CVrWindow, t_ppszType> CVideoDialog;
284
285public:
286        enum { IDD = IDD_VIDEO };
287
288BEGIN_MSG_MAP_EX(CVideoDialog)
289        //CHAIN_MSG_MAP(CDialogImpl<CVideoDialog>)
290        CHAIN_MSG_MAP(CDialogResize<T>)
291        MSG_WM_INITDIALOG(OnInitDialog)
292        MSG_WM_DESTROY(OnDestroy)
293        COMMAND_ID_HANDLER_EX(IDCANCEL, OnCommand)
294        COMMAND_ID_HANDLER_EX(IDC_VIDEO_RUN, OnRunButtonClicked)
295        COMMAND_ID_HANDLER_EX(IDC_VIDEO_PAUSE, OnPauseButtonClicked)
296        COMMAND_ID_HANDLER_EX(IDC_VIDEO_STOP, OnStopButtonClicked)
297        MESSAGE_HANDLER_EX(WM_FILTERGRAPHEVENT, OnFilterGraphEvent)
298END_MSG_MAP()
299
300BEGIN_DLGRESIZE_MAP(CVideoDialog)
301        DLGRESIZE_CONTROL(IDC_VIDEO_AREA, DLSZ_SIZE_X | DLSZ_SIZE_Y)
302        DLGRESIZE_CONTROL(IDC_VIDEO_RUN, DLSZ_MOVE_Y)
303        DLGRESIZE_CONTROL(IDC_VIDEO_PAUSE, DLSZ_MOVE_Y)
304        DLGRESIZE_CONTROL(IDC_VIDEO_STOP, DLSZ_MOVE_Y)
305        DLGRESIZE_CONTROL(IDCANCEL, DLSZ_MOVE_X | DLSZ_MOVE_Y)
306END_DLGRESIZE_MAP()
307
308public:
309
310        ////////////////////////////////////////////////////////
311        // Window Message Identifiers
312
313        enum
314        {
315                WM_FIRST = WM_APP,
316                WM_FILTERGRAPHEVENT,
317        };
318
319        ////////////////////////////////////////////////////////
320        // CSourceFilter
321
322        class ATL_NO_VTABLE CSourceFilter :
323                public CComObjectRootEx<CComMultiThreadModelNoCS>,
324                public CComCoClass<CSourceFilter>,
325                public CPushSourceFilterT<CSourceFilter>,
326                public CBasePersistT<CSourceFilter>,
327                public CAmFilterMiscFlagsT<CSourceFilter, AM_FILTER_MISC_FLAGS_IS_SOURCE>
328        {
329        public:
330
331        DECLARE_NO_REGISTRY()
332
333        DECLARE_PROTECT_FINAL_CONSTRUCT()
334
335        //DECLARE_QI_TRACE(CSourceFilter)
336
337        BEGIN_COM_MAP(CSourceFilter)
338                COM_INTERFACE_ENTRY(IBaseFilter)
339                COM_INTERFACE_ENTRY(IMediaFilter)
340                COM_INTERFACE_ENTRY_IID(__uuidof(IPersist), IBaseFilter)
341                COM_INTERFACE_ENTRY(IAMFilterMiscFlags)
342        END_COM_MAP()
343
344        public:
345
346                ////////////////////////////////////////////////////////
347                // COutputPin
348
349                class ATL_NO_VTABLE COutputPin :
350                        public CComObjectRootEx<CComMultiThreadModelNoCS>,
351                        public CPushSourceFilterT<CSourceFilter>::COutputPinT<COutputPin, CSourceFilter, CThreadContext>,
352                        public CAmPushSourceT<COutputPin, 0>
353                {
354                public:
355
356                //DECLARE_QI_TRACE(CSourceFilter::COutputPin)
357
358                BEGIN_COM_MAP(COutputPin)
359                        COM_INTERFACE_ENTRY(IPin)
360                        COM_INTERFACE_ENTRY(IAMPushSource)
361                        COM_INTERFACE_ENTRY(IAMLatency)
362                END_COM_MAP()
363
364                public:
365                // COutputPin
366                        COutputPin() throw()
367                        {
368                                _Z4(atlTraceRefcount, 4, _T("this 0x%p\n"), this);
369                        }
370                        ~COutputPin() throw()
371                        {
372                                _Z4(atlTraceRefcount, 4, _T("this 0x%p\n"), this);
373                        }
374                        VOID EnumerateMediaTypes(CAtlList<CMediaType>& MediaTypeList)
375                        {
376                                //CRoCriticalSectionLock DataLock(GetDataCriticalSection());
377                                _W(MediaTypeList.AddTail(GetFilter()->m_pRequestedMediaType));
378                        }
379                        BOOL CheckMediaType(const CMediaType& pMediaType) const throw()
380                        {
381                                _A(pMediaType);
382                                //CRoCriticalSectionLock DataLock(GetDataCriticalSection());
383                                _A(GetFilter()->m_pRequestedMediaType);
384                                return CVideoInfoHeader::Compare(&GetFilter()->m_pRequestedMediaType.GetCompatibleVideoInfoHeader(), &pMediaType.GetCompatibleVideoInfoHeader(), FALSE);
385                        }
386                        BOOL DecideMemAllocatorProperties(IMemAllocator* pMemAllocator, ALLOCATOR_PROPERTIES Properties) throw()
387                        {
388                                static const SIZE_T g_nMiminalBufferCount = 8;
389                                Properties.cBuffers = max(Properties.cBuffers, (LONG) g_nMiminalBufferCount);
390                                CRoCriticalSectionLock DataLock(GetDataCriticalSection());
391                                const CMediaType& pMediaType = GetMediaTypeReference();
392                                const CVideoInfoHeader VideoInfoHeader = pMediaType.GetCompatibleVideoInfoHeader();
393                                const CSize Extent = VideoInfoHeader.GetExtent();
394                                SIZE_T nBufferSize;
395                                if(Extent.cx >= 1080)
396                                {
397                                        // NOTE: At higher resolutions we are good to go with much smaller buffers
398                                        static const UINT g_nPixelBitCount = 7;
399                                        nBufferSize = Extent.cy * Extent.cx * g_nPixelBitCount / 8;
400                                } else
401                                {
402                                        static const UINT g_nPixelBitCount = 14;
403                                        nBufferSize = Extent.cy * Extent.cx * g_nPixelBitCount / 8;
404                                }
405                                return SetMemAllocatorBufferSize(pMemAllocator, Properties, nBufferSize);
406                        }
407                        BOOL ComposeMediaSample(CThreadContext& ThreadContext, IMediaSample* pMediaSample)
408                        {
409                                CMediaSampleProperties OutputProperties(pMediaSample);
410                                #pragma region Dynamic Type Change
411                                if(OutputProperties.dwSampleFlags & AM_SAMPLE_TYPECHANGED)
412                                {
413                                        _A(OutputProperties.pMediaType);
414                                        _A(CheckMediaType(OutputProperties.pMediaType));
415                                        SetMediaType(OutputProperties.pMediaType);
416                                } else
417                                        _A(!OutputProperties.pMediaType);
418                                #pragma endregion
419                                OutputProperties.dwTypeSpecificFlags = 0;
420                                OutputProperties.dwSampleFlags = 0; // AM_SAMPLE_DATADISCONTINUITY
421                                OutputProperties.lActual = GetMediaType().GetCompatibleVideoInfoHeader().GetDataSize();
422                                OutputProperties.dwStreamId = 0;
423                                FillMemory(OutputProperties.pbBuffer, OutputProperties.lActual, rand() & 0xFF);
424                                OutputProperties.Set();
425                                return TRUE;
426                        }
427                };
428
429        private:
430                CObjectPtr<COutputPin> m_pOutputPin;
431                CMediaType m_pRequestedMediaType;
432
433        public:
434        // CSourceFilter
435                CSourceFilter() throw() :
436                        CBasePersistT<CSourceFilter>(GetDataCriticalSection())
437                {
438                        _Z4(atlTraceRefcount, 4, _T("this 0x%p\n"), this);
439                }
440                ~CSourceFilter() throw()
441                {
442                        _Z4(atlTraceRefcount, 4, _T("this 0x%p\n"), this);
443                }
444                HRESULT FinalConstruct() throw()
445                {
446                        _ATLTRY
447                        {
448                                m_pOutputPin.Construct()->Initialize(this, L"Output");
449                                AddPin(m_pOutputPin);
450                        }
451                        _ATLCATCH(Exception)
452                        {
453                                _C(Exception);
454                        }
455                        return S_OK;
456                }
457                VOID FinalRelease() throw()
458                {
459                        m_pOutputPin = NULL;
460                }
461                VOID DeliverBeginFlush(IPin*)
462                {
463                        m_pOutputPin->DeliverBeginFlush();
464                }
465                VOID DeliverEndFlush(IPin*)
466                {
467                        m_pOutputPin->DeliverEndFlush();
468                }
469                VOID DeliverNewSegment(IPin*, REFERENCE_TIME nStartTime, REFERENCE_TIME nStopTime, DOUBLE fRate)
470                {
471                        m_pOutputPin->DeliverNewSegment(nStartTime, nStopTime, fRate);
472                }
473                static BOOL CanCue() throw()
474                {
475                        return FALSE;
476                }
477                VOID CueFilter()
478                {
479                        m_pOutputPin->CuePin();
480                }
481                VOID RunFilter(REFERENCE_TIME nStartTime)
482                {
483                        m_pOutputPin->RunPin(nStartTime);
484                }
485                VOID PauseFilter() throw()
486                {
487                        m_pOutputPin->PausePin();
488                }
489                VOID StopFilter() throw()
490                {
491                        m_pOutputPin->StopPin();
492                }
493                const CObjectPtr<COutputPin>& GetOutputPin() const throw()
494                {
495                        return m_pOutputPin;
496                }
497                VOID Initialize(CMediaType& pMediaType)
498                {
499                        _A(!m_pRequestedMediaType && pMediaType);
500                        m_pRequestedMediaType = pMediaType;
501                }
502        };
503
504private:
505        CMediaType m_pMediaType;
506        SIZE_T m_nLayout;
507        CStatic m_AreaStatic;
508        CGenericFilterGraph m_FilterGraph;
509        CRoArrayT<CVrWindow> m_VrWindowArray;
510        CButton m_RunButton;
511        CButton m_PauseButton;
512        CButton m_StopButton;
513
514        CRect GetVideoPosition(const CRect& Position, SIZE_T nIndex)
515        {
516                CRect VideoPosition;
517                VideoPosition.SetRectEmpty();
518                switch(m_nLayout)
519                {
520                case 0: // 1
521                        if(nIndex < 1)
522                                VideoPosition = Position;
523                        break;
524                case 1: // 4
525                case 2: // 9
526                case 3: // 16
527                case 4: // 25
528                case 5: // 36
529                        if(nIndex < (m_nLayout + 1) * (m_nLayout + 1))
530                        {
531                                const SIZE_T nZ = m_nLayout + 1;
532                                VideoPosition.left = (LONG) (Position.left + (Position.Width() - (nZ - 1) * Position.left) * (nIndex % nZ) / nZ + Position.left * (nIndex % nZ));
533                                VideoPosition.top = (LONG) (Position.top + (Position.Height() - (nZ - 1) * Position.top) * (nIndex / nZ) / nZ + Position.top * (nIndex / nZ));
534                                VideoPosition.right = (LONG) (VideoPosition.left + (Position.Width() - (nZ - 1) * Position.left) / nZ);
535                                VideoPosition.bottom = (LONG) (VideoPosition.top + (Position.Height() - (nZ - 1) * Position.top) / nZ);
536                        }
537                        break;
538                //default:
539                        //VideoPosition.SetRectEmpty();
540                }
541                _A(!VideoPosition.IsRectEmpty());
542                return VideoPosition;
543        }
544        CRect GetVideoPosition(SIZE_T nIndex)
545        {
546                CRect Position;
547                _W(m_AreaStatic.GetWindowRect(Position));
548                _W(ScreenToClient(Position));
549                return GetVideoPosition(Position, nIndex);
550        }
551        VOID UpdateControls()
552        {
553                if(m_FilterGraph.m_pMediaControl)
554                {
555                        OAFilterState State;
556                        if(SUCCEEDED(m_FilterGraph.m_pMediaControl->GetState(0, &State)))
557                        {
558                                m_RunButton.EnableWindow(State != State_Running);
559                                m_PauseButton.EnableWindow(State != State_Paused);
560                                m_StopButton.EnableWindow(State != State_Stopped);
561                                return;
562                        }
563                }
564                m_RunButton.EnableWindow(FALSE);
565                m_PauseButton.EnableWindow(FALSE);
566                m_StopButton.EnableWindow(FALSE);
567        }
568
569public:
570// CVideoDialog
571        CVideoDialogT(const CMediaType& pMediaType, SIZE_T nLayout) :
572                m_pMediaType(pMediaType),
573                m_nLayout(nLayout)
574        {
575                _Z4(atlTraceRefcount, 4, _T("this 0x%p\n"), this);
576        }
577        ~CVideoDialogT() throw()
578        {
579                _Z4(atlTraceRefcount, 4, _T("this 0x%p\n"), this);
580        }
581
582// CDialogImpl
583        VOID OnFinalMessage(HWND)
584        {
585                T* pT = static_cast<T*>(this);
586                delete pT;
587        }
588
589// CBaseVideoDialog
590        HWND Create(HWND hParentWindow)
591        {
592                return CDialogImpl<T>::Create(hParentWindow);
593        }
594        BOOL DestroyWindow()
595        {
596                return CDialogImpl<T>::DestroyWindow();
597        }
598        BOOL IsWindow()
599        {
600                return CDialogImpl<T>::IsWindow();
601        }
602        BOOL MoveWindow(const CRect& Position)
603        {
604                return CDialogImpl<T>::MoveWindow(Position);
605        }
606        INT ShowWindow(INT nShowCommand)
607        {
608                return CDialogImpl<T>::ShowWindow(nShowCommand);
609        }
610
611// CDialogResize
612        VOID DlgResize_UpdateLayout(INT nWidth, INT nHeight)
613        {
614                __super::DlgResize_UpdateLayout(nWidth, nHeight);
615                CRect Position;
616                _W(m_AreaStatic.GetWindowRect(Position));
617                _W(ScreenToClient(Position));
618                CDeferWindowPos DeferWindowPos;
619                _W(DeferWindowPos.Begin((INT) m_VrWindowArray.GetCount()));
620                for(SIZE_T nIndex = 0; nIndex < m_VrWindowArray.GetCount(); nIndex++)
621                        _W(DeferWindowPos.SetWindowPos(m_VrWindowArray[nIndex], NULL, GetVideoPosition(Position, nIndex), SWP_NOZORDER | SWP_NOACTIVATE));
622                _W(DeferWindowPos.End());
623        }
624
625// Window Message Handelrs
626        LRESULT OnInitDialog(HWND, LPARAM)
627        {
628                m_AreaStatic = GetDlgItem(IDC_VIDEO_AREA);
629                m_AreaStatic.ShowWindow(SW_HIDE);
630                m_RunButton = GetDlgItem(IDC_VIDEO_RUN);
631                m_PauseButton = GetDlgItem(IDC_VIDEO_PAUSE);
632                m_StopButton = GetDlgItem(IDC_VIDEO_STOP);
633                DlgResize_Init(TRUE);
634                UpdateControls();
635                m_FilterGraph.CoCreateInstance();
636                const SIZE_T nCount = (m_nLayout + 1) * (m_nLayout + 1); // 1, 4, 9, 16, ...
637                _A(m_VrWindowArray.IsEmpty());
638                _W(m_VrWindowArray.SetCount(0, (INT) nCount));
639                for(SIZE_T nIndex = 0; nIndex < nCount; nIndex++)
640                {
641                        CVrWindow& VrWindow = m_VrWindowArray[m_VrWindowArray.Add()];
642                        CComPtr<IBaseFilter> pBaseFilter = CVrWindow::CoCreateBaseFilterInstance();
643                        __C(m_FilterGraph->AddFilter(pBaseFilter, CT2CW(AtlFormatString(_T("Renderer %02d"), nIndex + 1))));
644                        VrWindow.Create(m_hWnd);
645                        VrWindow.ShowWindow(SW_SHOWNORMAL);
646                        VrWindow.Initialize(pBaseFilter);
647                        CObjectPtr<CSourceFilter> pSourceFilter;
648                        pSourceFilter.Construct()->Initialize(m_pMediaType);
649                        __C(m_FilterGraph->AddFilter(pSourceFilter, CT2CW(AtlFormatString(_T("Source %02d"), nIndex + 1))));
650                        m_FilterGraph->Connect(pSourceFilter->GetOutputPin(), _FilterGraphHelper::GetFilterPin(VrWindow.m_pBaseFilter));
651                }
652                __C(m_FilterGraph.m_pMediaEventEx->SetNotifyWindow((OAHWND) m_hWnd, WM_FILTERGRAPHEVENT, (LONG_PTR) this));
653                UpdateControls();
654                CRect Position;
655                _W(GetClientRect(Position));
656                DlgResize_UpdateLayout(Position.Width(), Position.Height());
657                CString sCaption;
658                GetWindowText(sCaption);
659                const CSize Extent = m_pMediaType.GetCompatibleVideoInfoHeader().GetExtent();
660                SetWindowText(AtlFormatString(sCaption, nCount, *t_ppszType, Extent.cx, Extent.cy));
661                return 0;
662        }
663        LRESULT OnDestroy() throw()
664        {
665                if(m_FilterGraph.m_pMediaControl)
666                        _V(m_FilterGraph.m_pMediaControl->Stop());
667                for(SIZE_T nIndex = 0; nIndex < m_VrWindowArray.GetCount(); nIndex++)
668                        m_VrWindowArray[nIndex].Terminate();
669                m_FilterGraph.Release();
670                CWindow OwnerWindow = GetWindow(GW_OWNER);
671                if(OwnerWindow.IsWindow())
672                        OwnerWindow.SendMessage(WM_COMMAND, 'CL', (LPARAM) (CBaseVideoDialog*) this);
673                return 0;
674        }
675        LRESULT OnCommand(UINT, INT nIdentifier, HWND)
676        {
677                DestroyWindow();
678                return 0;
679        }
680        LRESULT OnRunButtonClicked(UINT, INT, HWND)
681        {
682                CWaitCursor WaitCursor;
683                __D(m_FilterGraph.m_pMediaControl, E_NOINTERFACE);
684                __C(m_FilterGraph.m_pMediaControl->Run());
685                UpdateControls();
686                return 0;
687        }
688        LRESULT OnPauseButtonClicked(UINT, INT, HWND)
689        {
690                CWaitCursor WaitCursor;
691                __D(m_FilterGraph.m_pMediaControl, E_NOINTERFACE);
692                __C(m_FilterGraph.m_pMediaControl->Pause());
693                UpdateControls();
694                return 0;
695        }
696        LRESULT OnStopButtonClicked(UINT, INT, HWND)
697        {
698                CWaitCursor WaitCursor;
699                if(m_FilterGraph.m_pMediaControl)
700                        _V(m_FilterGraph.m_pMediaControl->Stop());
701                UpdateControls();
702                return 0;
703        }
704        LRESULT OnFilterGraphEvent(UINT, WPARAM, LPARAM)
705        {
706                if(!m_FilterGraph.m_pMediaEventEx)
707                        return 0;
708                _ATLTRY
709                {
710                        for(; ; )
711                        {
712                                LONG nEventCode;
713                                LONG_PTR nParameter1, nParameter2;
714                                const HRESULT nGetEventResult = m_FilterGraph.m_pMediaEventEx->GetEvent(&nEventCode, &nParameter1, &nParameter2, 0);
715                                if(nGetEventResult == E_ABORT)
716                                        break;
717                                __C(nGetEventResult);
718                                _ATLTRY
719                                {
720                                        switch(nEventCode)
721                                        {
722                                        case EC_ERRORABORT:
723                                                _Z2(atlTraceGeneral, 2, _T("nEventCode EC_ERRORABORT 0x%02X, nParameter1 0x%08x, nParameter2 0x%08x\n"), nEventCode, nParameter1, nParameter2);
724                                                _A(FAILED(nParameter1));
725                                                AtlMessageBoxEx(m_hWnd, (LPCTSTR) AtlFormatString(_T("EC_ERRORABORT Event: %s."), AtlFormatSystemMessage((HRESULT) nParameter1).TrimRight(_T("\t\n\r ."))), IDS_ERROR, MB_ICONERROR | MB_OK);
726                                                break;
727                                        default:
728                                                _Z1(atlTraceGeneral, 1, _T("nEventCode 0x%02X, nParameter1 0x%08x, nParameter2 0x%08x\n"), nEventCode, nParameter1, nParameter2);
729                                        }
730                                }
731                                _ATLCATCHALL()
732                                {
733                                        _V(m_FilterGraph.m_pMediaEventEx->FreeEventParams(nEventCode, nParameter1, nParameter2));
734                                        _ATLRETHROW;
735                                }
736                                _V(m_FilterGraph.m_pMediaEventEx->FreeEventParams(nEventCode, nParameter1, nParameter2));
737                        }
738                }
739                _ATLCATCHALL()
740                {
741                        _Z_EXCEPTION();
742                }
743                return 0;
744        }
745};
746
747////////////////////////////////////////////////////////////
748// CVmr7VideoDialog, CEvrVideoDialog
749
750LPCTSTR g_pszVmr7 = _T("VMR-7");
751
752class CVmr7VideoDialog :
753        public CVideoDialogT<CVmr7VideoDialog, CVmr7Window, &g_pszVmr7>
754{
755public:
756// CVmr7VideoDialog
757        CVmr7VideoDialog(const CMediaType& pMediaType, SIZE_T nLayout) :
758                CVideoDialogT<CVmr7VideoDialog, CVmr7Window, &g_pszVmr7>(pMediaType, nLayout)
759        {
760        }
761};
762
763LPCTSTR g_pszEvr = _T("EVR");
764
765class CEvrVideoDialog :
766        public CVideoDialogT<CEvrVideoDialog, CEvrWindow, &g_pszEvr>
767{
768public:
769// CEvrVideoDialog
770        CEvrVideoDialog(const CMediaType& pMediaType, SIZE_T nLayout) :
771                CVideoDialogT<CEvrVideoDialog, CEvrWindow, &g_pszEvr>(pMediaType, nLayout)
772        {
773        }
774};
775
776////////////////////////////////////////////////////////////
777// CMainDialog
778
779class CMainDialog : 
780        public CDialogImpl<CMainDialog>
781{
782public:
783        enum { IDD = IDD_MAIN };
784
785BEGIN_MSG_MAP_EX(CMainDialog)
786        //CHAIN_MSG_MAP(CDialogImpl<CMainDialog>)
787        MSG_WM_INITDIALOG(OnInitDialog)
788        MSG_WM_DESTROY(OnDestroy)
789        MSG_WM_TIMER(OnTimer)
790        MSG_WM_SYSCOMMAND(OnSysCommand)
791        COMMAND_ID_HANDLER_EX(IDCANCEL, OnCommand)
792        COMMAND_ID_HANDLER_EX(IDC_CREATE, OnCreateButtonClicked)
793        COMMAND_ID_HANDLER_EX('CL', OnCloseVideoDialog)
794        REFLECT_NOTIFICATIONS()
795END_MSG_MAP()
796
797public:
798
799        ////////////////////////////////////////////////////////
800        // Time Identifiers
801
802        enum
803        {
804                TIMER_FIRST = 0,
805                TIMER_UPDATEADAPTERS,
806        };
807
808private:
809        CRoEdit m_DxgiEdit;
810        CComPtr<IDXGIFactory> m_pDxgiFactory;
811        CRect m_DefaultPosition;
812        CRoListT<CBaseVideoDialog*> m_VideoDialogList;
813
814public:
815// CMainDialog
816        CMainDialog()
817        {
818        }
819
820// Window Message Handelrs
821        LRESULT OnInitDialog(HWND, LPARAM)
822        {
823                SetIcon(AtlLoadIconImage(IDI_MODULE, LR_DEFAULTCOLOR, GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON)), TRUE);
824                SetIcon(AtlLoadIconImage(IDI_MODULE, LR_DEFAULTCOLOR, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON)), FALSE);
825                CMenuHandle Menu = GetSystemMenu(FALSE);
826                _W(Menu.AppendMenu(MF_SEPARATOR));
827                _W(Menu.AppendMenu(MF_STRING, ID_APP_ABOUT, _T("&About...")));
828                {
829                        CString sCaption;
830                        GetWindowText(sCaption);
831                        #if defined(_WIN64)
832                                sCaption.Append(_T(" (64-bit)"));
833                        #else
834                                if(SafeIsWow64Process())
835                                        sCaption.Append(_T(" (32-bit)"));
836                        #endif // defined(_WIN64)
837                        SetWindowText(sCaption);
838                }
839                _W(CenterWindow());
840                CButton(GetDlgItem(IDC_TYPE_EVR)).SetCheck(TRUE);
841                CButton(GetDlgItem(IDC_RESOLUTION_19201080)).SetCheck(TRUE);
842                CButton(GetDlgItem(IDC_PIXELFORMAT_NV12)).SetCheck(TRUE);
843                CButton(GetDlgItem(IDC_LAYOUT_9)).SetCheck(TRUE);
844                #pragma region DXGI
845                m_DxgiEdit = GetDlgItem(IDC_DXGI);
846                if(GetOsVersion() >= 0x00060000) // Windows Vista+
847                {
848                        _ATLTRY
849                        {
850                                __C(CreateDXGIFactory(__uuidof(IDXGIFactory), (VOID**) &m_pDxgiFactory));
851                                SetTimer(TIMER_UPDATEADAPTERS, 5 * 1000); // 5 seconds
852                                _W(PostMessage(WM_TIMER, TIMER_UPDATEADAPTERS));
853                        }
854                        _ATLCATCH(Exception)
855                        {
856                                _Z_ATLEXCEPTION(Exception);
857                                m_DxgiEdit.SetValue(AtlFormatString(_T("Failed to initialize with DXGI: %s."), AtlFormatSystemMessage(Exception).TrimRight(_T("\t\n\r ."))));
858                        }
859                } else
860                        m_DxgiEdit.SetValue(_T("DXGI is not available."));
861                #pragma endregion
862                _W(GetWindowRect(m_DefaultPosition));
863                GetDlgItem(IDC_CREATE).SetFocus();
864                return FALSE;
865        }
866        LRESULT OnDestroy() throw()
867        {
868                for(POSITION Position = m_VideoDialogList.GetHeadPosition(); Position; m_VideoDialogList.GetNext(Position))
869                {
870                        CBaseVideoDialog* pVideoDialog = m_VideoDialogList.GetAt(Position);
871                        _A(pVideoDialog);
872                        if(pVideoDialog->IsWindow())
873                                _W(pVideoDialog->DestroyWindow());
874                }
875                m_VideoDialogList.RemoveAll();
876                return 0;
877        }
878        LRESULT OnTimer(UINT_PTR nEvent)
879        {
880                switch(nEvent)
881                {
882                case TIMER_UPDATEADAPTERS:
883                        _ATLTRY
884                        {
885                                _A(m_pDxgiFactory);
886                                CWaitCursor WaitCursor;
887                                CString sText;
888                                for(UINT nAdapter = 0; ; nAdapter++)
889                                {
890                                        CComPtr<IDXGIAdapter> pDxgiAdapter;
891                                        const HRESULT nEnumAdaptersResult = m_pDxgiFactory->EnumAdapters(nAdapter, &pDxgiAdapter);
892                                        _Z4(atlTraceGeneral, 4, _T("nAdapter %d, nEnumAdaptersResult 0x%08x\n"), nAdapter, nEnumAdaptersResult);
893                                        if(nEnumAdaptersResult == DXGI_ERROR_NOT_FOUND)
894                                                break;
895                                        _ATLTRY
896                                        {
897                                                DXGI_ADAPTER_DESC Description;
898                                                __C(pDxgiAdapter->GetDesc(&Description));
899                                                sText.AppendFormat(_T("Adatper %d: %ls, Vendor 0x%x, Device 0x%x, Subsystem 0x%x, Revision 0x%x\n"), nAdapter, Description.Description, Description.VendorId, Description.DeviceId, Description.SubSysId, Description.Revision);
900                                                sText.AppendFormat(
901                                                        _T("  ") _T("DedicatedVideoMemory %s") _T("\n")
902                                                        _T("  ") _T("DedicatedSystemMemory %s") _T("\n")
903                                                        _T("  ") _T("SharedSystemMemory %s") _T("\n")
904                                                        _T("  ") _T("AdapterLuid %d.%u") _T("\n")
905                                                        , 
906                                                        _StringHelper::FormatNumber((LONGLONG) Description.DedicatedVideoMemory), 
907                                                        _StringHelper::FormatNumber((LONGLONG) Description.DedicatedSystemMemory), 
908                                                        _StringHelper::FormatNumber((LONGLONG) Description.SharedSystemMemory), 
909                                                        Description.AdapterLuid.HighPart, Description.AdapterLuid.LowPart,
910                                                        0);
911                                        }
912                                        _ATLCATCH(Exception)
913                                        {
914                                                _Z_ATLEXCEPTION(Exception);
915                                                sText.AppendFormat(_T("Adatper %d Failure: %s\n"), nAdapter, AtlFormatSystemMessage(Exception).TrimRight(_T("\t\n\r .")));
916                                        }
917                                }
918                                sText.Replace(_T("\n"), _T("\r\n"));
919                                m_DxgiEdit.SetValue(sText);
920                        }
921                        _ATLCATCH(Exception)
922                        {
923                                _Z_ATLEXCEPTION(Exception);
924                                m_DxgiEdit.SetValue(AtlFormatString(_T("Failed to initialize with DXGI: %s."), AtlFormatSystemMessage(Exception).TrimRight(_T("\t\n\r ."))));
925                        }
926                        break;
927                default:
928                        SetMsgHandled(FALSE);
929                }
930                return 0;
931        }
932        LRESULT OnSysCommand(UINT nCommand, CPoint)
933        {
934                switch(nCommand)
935                {
936                case ID_APP_ABOUT:
937                        {
938                                CAboutDialog Dialog;
939                                Dialog.DoModal(m_hWnd);
940                        }
941                        break;
942                default:
943                        SetMsgHandled(FALSE);
944                }
945                return 0;
946        }
947        LRESULT OnCommand(UINT, INT nIdentifier, HWND)
948        {
949                _W(EndDialog(nIdentifier));
950                return 0;
951        }
952        LRESULT OnCreateButtonClicked(UINT, INT, HWND)
953        {
954                CWaitCursor WaitCursor;
955                #pragma region Query Controls
956                SIZE_T nType;
957                for(INT nIdentifier = IDC_TYPE_VMR7; nIdentifier <= IDC_TYPE_EVR; nIdentifier++)
958                        if(IsDlgButtonChecked(nIdentifier))
959                        {
960                                nType = nIdentifier - IDC_TYPE_VMR7;
961                                break;
962                        }
963                SIZE_T nResolution;
964                for(INT nIdentifier = IDC_RESOLUTION_720576; nIdentifier <= IDC_RESOLUTION_19201080; nIdentifier++)
965                        if(IsDlgButtonChecked(nIdentifier))
966                        {
967                                nResolution = nIdentifier - IDC_RESOLUTION_720576;
968                                break;
969                        }
970                SIZE_T nPixelFormat;
971                for(INT nIdentifier = IDC_PIXELFORMAT_NV12; nIdentifier <= IDC_PIXELFORMAT_RGB32; nIdentifier++)
972                        if(IsDlgButtonChecked(nIdentifier))
973                        {
974                                nPixelFormat = nIdentifier - IDC_PIXELFORMAT_NV12;
975                                break;
976                        }
977                SIZE_T nLayout;
978                for(INT nIdentifier = IDC_LAYOUT_1; nIdentifier <= IDC_LAYOUT_36; nIdentifier++)
979                        if(IsDlgButtonChecked(nIdentifier))
980                        {
981                                nLayout = nIdentifier - IDC_LAYOUT_1;
982                                break;
983                        }
984                #pragma endregion
985                static const SIZE g_pExtents[] = { { 720, 576 }, { 1280, 720 }, { 1920, 1080} };
986                static const DWORD g_pnCompressions[] = { MAKEFOURCC('N', 'V', '1', '2'), MAKEFOURCC('Y', 'U', 'Y', '2'), BI_RGB, BI_RGB };
987                static const WORD g_pnBitCounts[] = { 12, 16, 24, 32 };
988                CMediaType pMediaType;
989                pMediaType.AllocateVideoInfo(g_pExtents[nResolution], g_pnBitCounts[nPixelFormat], g_pnCompressions[nPixelFormat]);
990                CBaseVideoDialog* pVideoDialog;
991                switch(nType)
992                {
993                case 0: // IDC_TYPE_VMR7
994                        pVideoDialog = new CVmr7VideoDialog(pMediaType, nLayout);
995                        break;
996                case 1: // IDC_TYPE_EVR
997                        pVideoDialog = new CEvrVideoDialog(pMediaType, nLayout);
998                        break;
999                default:
1000                        __C(E_NOTIMPL);
1001                }
1002                _ATLTRY
1003                {
1004                        pVideoDialog->Create(m_hWnd);
1005                        _ATLTRY
1006                        {
1007                                CRect Position;
1008                                GetWindowRect(Position);
1009                                if(Position == m_DefaultPosition && m_VideoDialogList.IsEmpty())
1010                                {
1011                                        Position.OffsetRect(-Position.Width() / 3, 0);
1012                                        _W(MoveWindow(Position));
1013                                }
1014                                Position.left += Position.Width();
1015                                const LONG nOffset = GetSystemMetrics(SM_CYCAPTION);
1016                                Position.OffsetRect(nOffset * (INT) m_VideoDialogList.GetCount(), nOffset * (INT) m_VideoDialogList.GetCount());
1017                                _W(pVideoDialog->MoveWindow(Position));
1018                                pVideoDialog->ShowWindow(SW_SHOWNORMAL);
1019                                m_VideoDialogList.AddTail(pVideoDialog);
1020                        }
1021                        _ATLCATCHALL()
1022                        {
1023                                _W(pVideoDialog->DestroyWindow());
1024                                _ATLRETHROW;
1025                        }
1026                }
1027                _ATLCATCHALL()
1028                {
1029                        delete pVideoDialog;
1030                        _ATLRETHROW;
1031                }
1032                return 0;
1033        }
1034        LRESULT OnCloseVideoDialog(UINT, INT, HWND hWindow)
1035        {
1036                CBaseVideoDialog* pBaseVideoDialog = (CBaseVideoDialog*) hWindow;
1037                POSITION Position;
1038                if(m_VideoDialogList.FindFirst(pBaseVideoDialog, &Position))
1039                        m_VideoDialogList.RemoveAt(Position);
1040                return 0;
1041        }
1042};
Note: See TracBrowser for help on using the repository browser.