source: trunk/Utilities/RenderInterlacedVideo/MainPropertySheet.h @ 76

Last change on this file since 76 was 76, checked in by roman, 11 years ago

minor fix and EVR/DXVA2 logs

  • Property svn:keywords set to Id
File size: 56.6 KB
Line 
1////////////////////////////////////////////////////////////
2// Copyright (C) Roman Ryltsov, 2008-2012
3// Created by Roman Ryltsov roman@alax.info
4//
5// $Id: MainPropertySheet.h 76 2012-07-15 12:06:35Z roman $
6
7#pragma once
8
9#include "AboutDialog.h"
10#include <dshow.h>
11#include <d3d9.h>
12#include <vmr9.h>
13#include <evr.h>
14#include <evr9.h>
15#include <dxva.h>
16#include "rodshow.h"
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                CComQIPtr<IVMRFilterConfig> pVmrFilterConfig = pBaseFilter;
57                __D(pVmrFilterConfig, E_NOINTERFACE);
58                __C(pVmrFilterConfig->SetRenderingMode(VMRMode_Windowless));
59                // NOTE: Cause the VMR to load the mixer and compositor
60                //       See http://msdn.microsoft.com/en-us/library/windows/desktop/dd390448%28v=vs.85%29.aspx
61                __C(pVmrFilterConfig->SetNumberOfStreams(1));
62                m_pVmrWindowlessControl = CComQIPtr<IVMRWindowlessControl>(m_pBaseFilter);
63                __D(m_pVmrWindowlessControl, E_NOINTERFACE);
64                __C(m_pVmrWindowlessControl->SetVideoClippingWindow(m_hWnd));
65                CRect VideoPosition = GetVideoPosition();
66                _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());
67                __C(m_pVmrWindowlessControl->SetVideoPosition(NULL, VideoPosition));
68        }
69        VOID Terminate() throw()
70        {
71                m_pBaseFilter = NULL;
72                m_pVmrWindowlessControl = NULL;
73        }
74        CRect GetVideoPosition() const throw()
75        {
76                CRect Position;
77                _W(GetClientRect(Position));
78                return Position;
79        }
80
81// Window Message Handlers
82        LRESULT OnEraseBkgnd(CDCHandle Dc)
83        {
84                Dc;
85                if(m_pVmrWindowlessControl)
86                {
87                        return TRUE;
88                } else
89                        SetMsgHandled(FALSE);
90                return 0;
91        }
92        LRESULT OnPaint(CDCHandle)
93        {
94                if(m_pVmrWindowlessControl)
95                {
96                        CPaintDC Dc(m_hWnd);
97                        const HRESULT nRepaintVideoResult = m_pVmrWindowlessControl->RepaintVideo(m_hWnd, Dc);
98                        _Z4(atlTraceUI, SUCCEEDED(nRepaintVideoResult) ? 6 : 4, _T("nRepaintVideoResult 0x%08x\n"), nRepaintVideoResult);
99                } else
100                        SetMsgHandled(FALSE);
101                return 0;
102        }
103        LRESULT OnDisplayChange(UINT nDepth, CSize Extent)
104        {
105                if(m_pVmrWindowlessControl)
106                {
107                        const HRESULT nDisplayModeChangedResult = m_pVmrWindowlessControl->DisplayModeChanged();
108                        _Z4(atlTraceUI, 4, _T("nDisplayModeChangedResult 0x%08x\n"), nDisplayModeChangedResult);
109                }
110                return 0;
111        }
112        LRESULT OnSize(UINT nType, CSize)
113        {
114                if(nType != SIZE_MINIMIZED)
115                        if(m_pVmrWindowlessControl)
116                        {
117                                CRect VideoPosition = GetVideoPosition();
118                                const HRESULT nSetVideoPositionResult = m_pVmrWindowlessControl->SetVideoPosition(NULL, &VideoPosition);
119                                _Z4(atlTraceUI, SUCCEEDED(nSetVideoPositionResult) ? 6 : 4, _T("nSetVideoPositionResult 0x%08x\n"), nSetVideoPositionResult);
120                        }
121                return 0;
122        }
123        LRESULT OnLButtonDblClk(UINT, CPoint Position)
124        {
125                COlePropertyFrameDialog Dialog;
126                Dialog.SetObject(m_pBaseFilter);
127                Dialog.SetObjectPages();
128                Dialog.DoModal(m_hWnd);
129                return 0;
130        }
131};
132
133////////////////////////////////////////////////////////////
134// CVmr9Window
135
136class CVmr9Window :
137        public CControlWindowT<CVmr9Window>
138{
139public:
140
141BEGIN_MSG_MAP_EX(CVmr9Window)
142        //CHAIN_MSG_MAP(CControlWindowT<CVmr9Window>)
143        MSG_WM_ERASEBKGND(OnEraseBkgnd)
144        MSG_WM_PAINT(OnPaint)
145        MSG_WM_DISPLAYCHANGE(OnDisplayChange)
146        MSG_WM_SIZE(OnSize)
147        MSG_WM_LBUTTONDBLCLK(OnLButtonDblClk)
148END_MSG_MAP()
149
150public:
151        CComPtr<IBaseFilter> m_pBaseFilter;
152        CComPtr<IVMRWindowlessControl9> m_pVmrWindowlessControl;
153
154public:
155// CVmr7Window
156        static CLSID GetRendererClassIdentifier() throw()
157        {
158                return CLSID_VideoMixingRenderer9;
159        }
160        static CComPtr<IBaseFilter> CoCreateBaseFilterInstance()
161        {
162                CComPtr<IBaseFilter> pBaseFilter;
163                __C(pBaseFilter.CoCreateInstance(GetRendererClassIdentifier()));
164                return pBaseFilter;
165        }
166        VOID Initialize(IBaseFilter* pBaseFilter)
167        {
168                _A(pBaseFilter);
169                _A(!m_pBaseFilter && !m_pVmrWindowlessControl);
170                m_pBaseFilter = pBaseFilter;
171                CComQIPtr<IVMRFilterConfig9> pVmrFilterConfig = pBaseFilter;
172                __D(pVmrFilterConfig, E_NOINTERFACE);
173                __C(pVmrFilterConfig->SetRenderingMode(VMR9Mode_Windowless));
174                m_pVmrWindowlessControl = CComQIPtr<IVMRWindowlessControl9>(m_pBaseFilter);
175                __D(m_pVmrWindowlessControl, E_NOINTERFACE);
176                __C(m_pVmrWindowlessControl->SetVideoClippingWindow(m_hWnd));
177                CRect VideoPosition = GetVideoPosition();
178                _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());
179                __C(m_pVmrWindowlessControl->SetVideoPosition(NULL, VideoPosition));
180        }
181        VOID Terminate() throw()
182        {
183                m_pBaseFilter = NULL;
184                m_pVmrWindowlessControl = NULL;
185        }
186        CRect GetVideoPosition() const throw()
187        {
188                CRect Position;
189                _W(GetClientRect(Position));
190                return Position;
191        }
192
193// Window Message Handlers
194        LRESULT OnEraseBkgnd(CDCHandle Dc)
195        {
196                Dc;
197                if(m_pVmrWindowlessControl)
198                {
199                        return TRUE;
200                } else
201                        SetMsgHandled(FALSE);
202                return 0;
203        }
204        LRESULT OnPaint(CDCHandle)
205        {
206                if(m_pVmrWindowlessControl)
207                {
208                        CPaintDC Dc(m_hWnd);
209                        const HRESULT nRepaintVideoResult = m_pVmrWindowlessControl->RepaintVideo(m_hWnd, Dc);
210                        _Z4(atlTraceUI, SUCCEEDED(nRepaintVideoResult) ? 6 : 4, _T("nRepaintVideoResult 0x%08x\n"), nRepaintVideoResult);
211                } else
212                        SetMsgHandled(FALSE);
213                return 0;
214        }
215        LRESULT OnDisplayChange(UINT nDepth, CSize Extent)
216        {
217                if(m_pVmrWindowlessControl)
218                {
219                        const HRESULT nDisplayModeChangedResult = m_pVmrWindowlessControl->DisplayModeChanged();
220                        _Z4(atlTraceUI, 4, _T("nDisplayModeChangedResult 0x%08x\n"), nDisplayModeChangedResult);
221                }
222                return 0;
223        }
224        LRESULT OnSize(UINT nType, CSize)
225        {
226                if(nType != SIZE_MINIMIZED)
227                        if(m_pVmrWindowlessControl)
228                        {
229                                CRect VideoPosition = GetVideoPosition();
230                                const HRESULT nSetVideoPositionResult = m_pVmrWindowlessControl->SetVideoPosition(NULL, &VideoPosition);
231                                _Z4(atlTraceUI, SUCCEEDED(nSetVideoPositionResult) ? 6 : 4, _T("nSetVideoPositionResult 0x%08x\n"), nSetVideoPositionResult);
232                        }
233                return 0;
234        }
235        LRESULT OnLButtonDblClk(UINT, CPoint Position)
236        {
237                COlePropertyFrameDialog Dialog;
238                Dialog.SetObject(m_pBaseFilter);
239                Dialog.SetObjectPages();
240                Dialog.DoModal(m_hWnd);
241                return 0;
242        }
243};
244
245////////////////////////////////////////////////////////////
246// CEvrWindow
247
248class CEvrWindow :
249        public CControlWindowT<CEvrWindow>
250{
251public:
252
253BEGIN_MSG_MAP_EX(CEvrWindow)
254        //CHAIN_MSG_MAP(CControlWindowT<CEvrWindow>)
255        MSG_WM_ERASEBKGND(OnEraseBkgnd)
256        MSG_WM_PAINT(OnPaint)
257        MSG_WM_SIZE(OnSize)
258        MSG_WM_LBUTTONDBLCLK(OnLButtonDblClk)
259END_MSG_MAP()
260
261public:
262        CComPtr<IBaseFilter> m_pBaseFilter;
263        CComPtr<IMFVideoDisplayControl> m_pMfVideoDisplayControl;
264
265public:
266// CEvrWindow
267        static CLSID GetRendererClassIdentifier() throw()
268        {
269                return CLSID_EnhancedVideoRenderer;
270        }
271        static CComPtr<IBaseFilter> CoCreateBaseFilterInstance()
272        {
273                CComPtr<IBaseFilter> pBaseFilter;
274                __C(pBaseFilter.CoCreateInstance(GetRendererClassIdentifier()));
275                return pBaseFilter;
276        }
277        VOID Initialize(IBaseFilter* pBaseFilter)
278        {
279                _A(pBaseFilter);
280                _A(!m_pBaseFilter && !m_pMfVideoDisplayControl);
281                m_pBaseFilter = pBaseFilter;
282                CComQIPtr<IMFGetService> pMfGetInterface = pBaseFilter;
283                CComPtr<IMFVideoDisplayControl> pMfVideoDisplayControl;
284                __C(pMfGetInterface->GetService(MR_VIDEO_RENDER_SERVICE, __uuidof(IMFVideoDisplayControl), (VOID**) &pMfVideoDisplayControl));
285                _A(pMfVideoDisplayControl);
286                m_pMfVideoDisplayControl = pMfVideoDisplayControl;
287                __C(pMfVideoDisplayControl->SetVideoWindow(m_hWnd));
288                CRect VideoPosition = GetVideoPosition();
289                _Z4(atlTraceGeneral, 4, _T("pMfVideoDisplayControl 0x%p, VideoPosition at (%d, %d) size (%d, %d)\n"), pMfVideoDisplayControl, VideoPosition.left, VideoPosition.top, VideoPosition.Width(), VideoPosition.Height());
290                __C(pMfVideoDisplayControl->SetVideoPosition(NULL, VideoPosition));
291                //__C(pMfVideoDisplayControl->SetAspectRatioMode(MFVideoARMode_None)); // As opposed to default MFVideoARMode_Picture - disable letterboxing
292        }
293        VOID Terminate() throw()
294        {
295                m_pBaseFilter = NULL;
296                m_pMfVideoDisplayControl = NULL;
297        }
298        CRect GetVideoPosition() const throw()
299        {
300                CRect Position;
301                _W(GetClientRect(Position));
302                return Position;
303        }
304
305// Window Message Handlers
306        LRESULT OnEraseBkgnd(CDCHandle Dc)
307        {
308                Dc;
309                if(m_pMfVideoDisplayControl)
310                {
311                        return TRUE;
312                } else
313                        SetMsgHandled(FALSE);
314                return 0;
315        }
316        LRESULT OnPaint(CDCHandle)
317        {
318                if(m_pMfVideoDisplayControl)
319                {
320                        CPaintDC Dc(m_hWnd);
321                        const HRESULT nRepaintVideoResult = m_pMfVideoDisplayControl->RepaintVideo();
322                        _Z4(atlTraceUI, SUCCEEDED(nRepaintVideoResult) ? 6 : 4, _T("nRepaintVideoResult 0x%08x\n"), nRepaintVideoResult);
323                } else
324                        SetMsgHandled(FALSE);
325                return 0;
326        }
327        LRESULT OnSize(UINT nType, CSize)
328        {
329                if(nType != SIZE_MINIMIZED)
330                        if(m_pMfVideoDisplayControl)
331                        {
332                                CRect VideoPosition = GetVideoPosition();
333                                const HRESULT nSetVideoPositionResult = m_pMfVideoDisplayControl->SetVideoPosition(NULL, &VideoPosition);
334                                _Z4(atlTraceUI, SUCCEEDED(nSetVideoPositionResult) ? 6 : 4, _T("nSetVideoPositionResult 0x%08x\n"), nSetVideoPositionResult);
335                        }
336                return 0;
337        }
338        LRESULT OnLButtonDblClk(UINT, CPoint Position)
339        {
340                COlePropertyFrameDialog Dialog;
341                Dialog.SetObject(m_pBaseFilter);
342                Dialog.SetObjectPages();
343                Dialog.DoModal(m_hWnd);
344                return 0;
345        }
346};
347
348////////////////////////////////////////////////////////////
349// CMainPropertySheet
350
351class CMainPropertySheet : 
352        public CSizablePropertySheetT<CMainPropertySheet>
353{
354public:
355
356BEGIN_MSG_MAP_EX(CMainPropertySheet)
357        CHAIN_MSG_MAP(CSizablePropertySheet)
358        MESSAGE_HANDLER_EX(WM_SETLARGERINITIALPOSITION, OnSetLargerInitialPosition)
359END_MSG_MAP()
360
361public:
362
363        ////////////////////////////////////////////////////////
364        // Window Message Identifiers
365
366        enum
367        {
368                MW_FIRST = WM_APP + 100,
369                WM_SETLARGERINITIALPOSITION,
370        };
371
372        ////////////////////////////////////////////////////////
373        // CSourceFilter
374
375        class ATL_NO_VTABLE CSourceFilter :
376                public CComObjectRootEx<CComMultiThreadModelNoCS>,
377                public CComCoClass<CSourceFilter>,
378                public CPushSourceFilterT<CSourceFilter>,
379                public CBasePersistT<CSourceFilter>,
380                public CAmFilterMiscFlagsT<CSourceFilter, AM_FILTER_MISC_FLAGS_IS_SOURCE>
381        {
382        public:
383
384        DECLARE_NO_REGISTRY()
385
386        DECLARE_PROTECT_FINAL_CONSTRUCT()
387
388        //DECLARE_QI_TRACE(CSourceFilter)
389
390        BEGIN_COM_MAP(CSourceFilter)
391                COM_INTERFACE_ENTRY(IBaseFilter)
392                COM_INTERFACE_ENTRY(IMediaFilter)
393                COM_INTERFACE_ENTRY_IID(__uuidof(IPersist), IBaseFilter)
394                COM_INTERFACE_ENTRY(IAMFilterMiscFlags)
395        END_COM_MAP()
396
397        public:
398
399                ////////////////////////////////////////////////////////
400                // CThreadContext
401
402                class CThreadContext :
403                        public CPushSourceFilter::CThreadContext
404                {
405                public:
406                        SIZE_T m_nMediaSampleIndex;
407
408                public:
409                // CThreadContext
410                        CThreadContext(CEvent& TerminationEvent) throw() :
411                                CPushSourceFilter::CThreadContext(TerminationEvent),
412                                m_nMediaSampleIndex(0)
413                        {
414                        }
415                };
416
417                ////////////////////////////////////////////////////////
418                // COutputPin
419
420                class ATL_NO_VTABLE COutputPin :
421                        public CComObjectRootEx<CComMultiThreadModelNoCS>,
422                        public CPushSourceFilterT<CSourceFilter>::COutputPinT<COutputPin, CSourceFilter, CThreadContext>,
423                        public CAmPushSourceT<COutputPin, 0>
424                {
425                public:
426
427                //DECLARE_QI_TRACE(CSourceFilter::COutputPin)
428
429                BEGIN_COM_MAP(COutputPin)
430                        COM_INTERFACE_ENTRY(IPin)
431                        COM_INTERFACE_ENTRY(IAMPushSource)
432                        COM_INTERFACE_ENTRY(IAMLatency)
433                END_COM_MAP()
434
435                private:
436
437                        VOID Paint(BYTE* pnData, SSIZE_T nNextRowOffset, BYTE nColor)
438                        {
439                                // 400 px high from 40, 60 px wide from current, line step 2
440                                for(LONG nY = (480 - 2 * 40) / 2; nY > 0; nY--)
441                                {
442                                        for(LONG nX = 0; nX < 60; nX++)
443                                                pnData[nX * 2] = nColor;
444                                        pnData += 2 * nNextRowOffset;
445                                }
446                        }
447
448                public:
449                // COutputPin
450                        COutputPin() throw()
451                        {
452                                _Z4(atlTraceRefcount, 4, _T("this 0x%p\n"), this);
453                        }
454                        ~COutputPin() throw()
455                        {
456                                _Z4(atlTraceRefcount, 4, _T("this 0x%p\n"), this);
457                        }
458                        VOID EnumerateMediaTypes(CAtlList<CMediaType>& MediaTypeList)
459                        {
460                                //CRoCriticalSectionLock DataLock(GetDataCriticalSection());
461                                _W(MediaTypeList.AddTail(GetFilter()->m_pRequestedMediaType));
462                        }
463                        BOOL CheckMediaType(const CMediaType& pMediaType) const throw()
464                        {
465                                _A(pMediaType);
466                                if(pMediaType->majortype != MEDIATYPE_Video)
467                                        return FALSE;
468                                //CRoCriticalSectionLock DataLock(GetDataCriticalSection());
469                                _A(GetFilter()->m_pRequestedMediaType);
470                                //if(GetFilter()->m_pRequestedMediaType.Compare(pMediaType))
471                                //      return TRUE;
472                                return CVideoInfoHeader::Compare(&GetFilter()->m_pRequestedMediaType.GetCompatibleVideoInfoHeader(), &pMediaType.GetCompatibleVideoInfoHeader(), FALSE);
473                        }
474                        BOOL DecideMemAllocatorProperties(IMemAllocator* pMemAllocator, ALLOCATOR_PROPERTIES Properties) throw()
475                        {
476                                static const SIZE_T g_nMiminalBufferCount = 8;
477                                Properties.cBuffers = max(Properties.cBuffers, (LONG) g_nMiminalBufferCount);
478                                CRoCriticalSectionLock DataLock(GetDataCriticalSection());
479                                const CMediaType& pMediaType = GetMediaTypeReference();
480                                const CVideoInfoHeader VideoInfoHeader = pMediaType.GetCompatibleVideoInfoHeader();
481                                const CSize Extent = VideoInfoHeader.GetExtent();
482                                SIZE_T nBufferSize;
483                                if(Extent.cx >= 1080)
484                                {
485                                        // NOTE: At higher resolutions we are good to go with much smaller buffers
486                                        static const UINT g_nPixelBitCount = 7;
487                                        nBufferSize = Extent.cy * Extent.cx * g_nPixelBitCount / 8;
488                                } else
489                                {
490                                        static const UINT g_nPixelBitCount = 14;
491                                        nBufferSize = Extent.cy * Extent.cx * g_nPixelBitCount / 8;
492                                }
493                                return SetMemAllocatorBufferSize(pMemAllocator, Properties, nBufferSize);
494                        }
495                        BOOL ComposeMediaSample(CThreadContext& ThreadContext, IMediaSample* pMediaSample)
496                        {
497                                CMediaSampleProperties OutputProperties(pMediaSample);
498                                #pragma region Dynamic Type Change
499                                if(OutputProperties.dwSampleFlags & AM_SAMPLE_TYPECHANGED)
500                                {
501                                        _A(OutputProperties.pMediaType);
502                                        _A(CheckMediaType(OutputProperties.pMediaType));
503                                        SetMediaType(OutputProperties.pMediaType);
504                                } else
505                                        _A(!OutputProperties.pMediaType);
506                                #pragma endregion
507                                const CMediaType pMediaType = GetMediaType();
508                                const CVideoInfoHeader2* pVideoInfoHeader2 = pMediaType.GetVideoInfoHeader2();
509                                OutputProperties.dwTypeSpecificFlags = (!(ThreadContext.m_nMediaSampleIndex & 1) ? AM_VIDEO_FLAG_FIELD2 : AM_VIDEO_FLAG_FIELD1);
510                                OutputProperties.dwSampleFlags = AM_SAMPLE_SPLICEPOINT | (ThreadContext.m_nMediaSampleIndex ? 0 : AM_SAMPLE_DATADISCONTINUITY) | AM_SAMPLE_TIMEVALID | AM_SAMPLE_STOPVALID;
511                                OutputProperties.lActual = GetMediaType().GetCompatibleVideoInfoHeader().GetDataSize();
512                                OutputProperties.tStart = ThreadContext.m_nMediaSampleIndex * pVideoInfoHeader2->AvgTimePerFrame / 2;
513                                OutputProperties.tStop = OutputProperties.tStart + 1;
514                                OutputProperties.dwStreamId = 0;
515                                #pragma region Data
516                                FillMemory(OutputProperties.pbBuffer, OutputProperties.lActual, 0x80);
517                                const CSize Extent = pVideoInfoHeader2->GetExtent();
518                                SSIZE_T nFirstRowOffset, nNextRowOffset;
519                                pVideoInfoHeader2->GetData(nFirstRowOffset, nNextRowOffset);
520                                BYTE* pnData = OutputProperties.pbBuffer;
521                                static const REFERENCE_TIME g_nPeriod = 3 * 1000 * 10000i64; // 3 seconds for the move back and forth
522                                REFERENCE_TIME nField2Time = (ThreadContext.m_nMediaSampleIndex & ~1) * pVideoInfoHeader2->AvgTimePerFrame / 2;
523                                REFERENCE_TIME nField1Time = ((ThreadContext.m_nMediaSampleIndex - 1) | 1) * pVideoInfoHeader2->AvgTimePerFrame / 2;
524                                _Z5(atlTraceGeneral, 5, _T("m_nMediaSampleIndex %d, OutputProperties.tStart %s, nField2Time %s, nField1Time %s\n"), 
525                                        ThreadContext.m_nMediaSampleIndex,
526                                        _FilterGraphHelper::FormatReferenceTime(OutputProperties.tStart),
527                                        _FilterGraphHelper::FormatReferenceTime(nField2Time), 
528                                        _FilterGraphHelper::FormatReferenceTime(nField1Time), 
529                                        0);
530                                REFERENCE_TIME nPositionA = nField2Time % g_nPeriod;
531                                LONG nPositionB = (LONG) (abs((g_nPeriod / 2) - nPositionA) * (600 - 60) / (g_nPeriod / 2));
532                                Paint(pnData + nFirstRowOffset + (40 + 1) * nNextRowOffset + (60 + nPositionB) * 2, nNextRowOffset, 0xFF);
533                                REFERENCE_TIME nPositionC = nField1Time % g_nPeriod;
534                                LONG nPositionD = (LONG) (abs((g_nPeriod / 2) - nPositionC) * (600 - 60) / (g_nPeriod / 2));
535                                Paint(pnData + nFirstRowOffset + (40 + 0) * nNextRowOffset + (60 + nPositionD) * 2, nNextRowOffset, GetFilter()->GetColorize() ? 0x00 : 0xFF);
536                                if(GetFilter()->GetWeave())
537                                        OutputProperties.dwTypeSpecificFlags |= AM_VIDEO_FLAG_WEAVE;
538                                #pragma endregion
539                                OutputProperties.Set();
540                                ThreadContext.m_nMediaSampleIndex++;
541                                return TRUE;
542                        }
543                };
544
545        private:
546                CObjectPtr<COutputPin> m_pOutputPin;
547                CMediaType m_pRequestedMediaType;
548                BOOL m_bWeave;
549                BOOL m_bColorize;
550
551        public:
552        // CSourceFilter
553                CSourceFilter() throw() :
554                        CBasePersistT<CSourceFilter>(GetDataCriticalSection()),
555                        m_bWeave(FALSE),
556                        m_bColorize(FALSE)
557                {
558                        _Z4(atlTraceRefcount, 4, _T("this 0x%p\n"), this);
559                }
560                ~CSourceFilter() throw()
561                {
562                        _Z4(atlTraceRefcount, 4, _T("this 0x%p\n"), this);
563                }
564                HRESULT FinalConstruct() throw()
565                {
566                        _ATLTRY
567                        {
568                                m_pOutputPin.Construct()->Initialize(this, L"Output");
569                                AddPin(m_pOutputPin);
570                        }
571                        _ATLCATCH(Exception)
572                        {
573                                _C(Exception);
574                        }
575                        return S_OK;
576                }
577                VOID FinalRelease() throw()
578                {
579                        m_pOutputPin = NULL;
580                }
581                VOID DeliverBeginFlush(IPin*)
582                {
583                        m_pOutputPin->DeliverBeginFlush();
584                }
585                VOID DeliverEndFlush(IPin*)
586                {
587                        m_pOutputPin->DeliverEndFlush();
588                }
589                VOID DeliverNewSegment(IPin*, REFERENCE_TIME nStartTime, REFERENCE_TIME nStopTime, DOUBLE fRate)
590                {
591                        m_pOutputPin->DeliverNewSegment(nStartTime, nStopTime, fRate);
592                }
593                static BOOL CanCue() throw()
594                {
595                        return FALSE;
596                }
597                VOID CueFilter()
598                {
599                        m_pOutputPin->CuePin();
600                }
601                VOID RunFilter(REFERENCE_TIME nStartTime)
602                {
603                        m_pOutputPin->RunPin(nStartTime);
604                }
605                VOID PauseFilter() throw()
606                {
607                        m_pOutputPin->PausePin();
608                }
609                VOID StopFilter() throw()
610                {
611                        m_pOutputPin->StopPin();
612                }
613                const CObjectPtr<COutputPin>& GetOutputPin() const throw()
614                {
615                        return m_pOutputPin;
616                }
617                VOID Initialize()
618                {
619                        _A(!m_pRequestedMediaType);
620                        CMediaType pMediaType;
621                        //pMediaType.AllocateVideoInfo(720, 480, 16, MAKEFOURCC('Y', 'U', 'Y', '2'), 1000 * 10000i64 / 30);
622                        pMediaType.Allocate(MEDIATYPE_Video, MEDIASUBTYPE_YUY2, FORMAT_VideoInfo2, sizeof (VIDEOINFOHEADER2));
623                        CVideoInfoHeader2* pVideoInfoHeader2 = pMediaType.GetVideoInfoHeader2();
624                        CBitmapInfoHeader* pBitmapInfoHeader = &pVideoInfoHeader2->GetBitmapInfoHeader();
625                        pBitmapInfoHeader->biSize = sizeof (BITMAPINFOHEADER);
626                        pBitmapInfoHeader->biWidth = 720;
627                        pBitmapInfoHeader->biHeight = 480;
628                        pBitmapInfoHeader->biPlanes = 1;
629                        pBitmapInfoHeader->biBitCount = 16;
630                        pBitmapInfoHeader->biCompression = MEDIASUBTYPE_YUY2.Data1;
631                        pBitmapInfoHeader->biSizeImage = pBitmapInfoHeader->GetDataSize();
632                        pVideoInfoHeader2->GetSourcePosition().SetRect(0, 0, pBitmapInfoHeader->biWidth, pBitmapInfoHeader->biHeight);
633                        pVideoInfoHeader2->GetTargetPosition().SetRect(0, 0, pBitmapInfoHeader->biWidth, pBitmapInfoHeader->biHeight);
634                        pVideoInfoHeader2->AvgTimePerFrame = 1001 * 10000i64 / 30;
635//                      pVideoInfoHeader2->AvgTimePerFrame *= 10; // Uncomment to slow down 10 times
636                        pVideoInfoHeader2->dwBitRate = (DWORD) (8.0 * pBitmapInfoHeader->biSizeImage * 10000000.0 / pVideoInfoHeader2->AvgTimePerFrame + 0.5 - 1E-6);
637                        pVideoInfoHeader2->dwInterlaceFlags = AMINTERLACE_IsInterlaced | AMINTERLACE_FieldPatBothRegular | AMINTERLACE_DisplayModeBobOrWeave;
638//                      pVideoInfoHeader2->dwInterlaceFlags = 0; // Uncomment to remove interlacing
639                        pVideoInfoHeader2->dwPictAspectRatioX = 720;
640                        pVideoInfoHeader2->dwPictAspectRatioY = 480;
641                        pMediaType->bFixedSizeSamples = TRUE;
642                        pMediaType->lSampleSize = pBitmapInfoHeader->biSizeImage;
643                        m_pRequestedMediaType = pMediaType;
644                }
645                const CMediaType& GetRequestedMediaType() const throw()
646                {
647                        return m_pRequestedMediaType;
648                }
649                BOOL GetWeave() const throw()
650                {
651                        CRoCriticalSectionLock DataLock(GetDataCriticalSection());
652                        return m_bWeave;
653                }
654                VOID SetWeave(BOOL bWeave) throw()
655                {
656                        CRoCriticalSectionLock DataLock(GetDataCriticalSection());
657                        m_bWeave = bWeave;
658                }
659                BOOL GetColorize() const throw()
660                {
661                        CRoCriticalSectionLock DataLock(GetDataCriticalSection());
662                        return m_bColorize;
663                }
664                VOID SetColorize(BOOL bColorize) throw()
665                {
666                        CRoCriticalSectionLock DataLock(GetDataCriticalSection());
667                        m_bColorize = bColorize;
668                }
669        };
670
671        ////////////////////////////////////////////////////////////
672        // CAmGraphBuilderCallback
673
674        class ATL_NO_VTABLE CAmGraphBuilderCallback :
675                public CComObjectRootEx<CComMultiThreadModelNoCS>,
676                public IAMGraphBuilderCallback
677        {
678        public:
679
680        BEGIN_COM_MAP(CAmGraphBuilderCallback)
681                COM_INTERFACE_ENTRY(IAMGraphBuilderCallback)
682        END_COM_MAP()
683
684        public:
685        // CAmGraphBuilderCallback
686                CAmGraphBuilderCallback() throw()
687                {
688                        _Z4(atlTraceRefcount, 4, _T("this 0x%p\n"), this);
689                }
690                ~CAmGraphBuilderCallback() throw()
691                {
692                        _Z4(atlTraceRefcount, 4, _T("this 0x%p\n"), this);
693                }
694                VOID SetGraphBuilder(IUnknown* pGraphBuilderUnknown)
695                {
696                        const CComQIPtr<IObjectWithSite> pObjectWithSite = pGraphBuilderUnknown;
697                        __D(pObjectWithSite, E_NOINTERFACE);
698                        __C(pObjectWithSite->SetSite(this));
699                }
700
701        // IAMGraphBuilderCallback
702                STDMETHOD(SelectedFilter)(IMoniker* pMoniker) throw()
703                {
704                        _Z5(atlTraceCOM, 5, _T("...\n"));
705                        _ATLTRY
706                        {
707                                _A(pMoniker);
708                                CComPtr<IBindCtx> pBindCtx;
709                                __C(CreateBindCtx(0, &pBindCtx));
710                                if(_FilterGraphHelper::IsFilterNonGrata(pMoniker))
711                                        return E_FAIL;
712                                const CStringW sMonikerDisplayName = _FilterGraphHelper::GetMonikerDisplayName(pMoniker, pBindCtx);
713                                CComPtr<IPropertyBag> pPropertyBag;
714                                __C(pMoniker->BindToStorage(pBindCtx, NULL, __uuidof(IPropertyBag), (VOID**) &pPropertyBag));
715                                const CStringW sFriendlyName = _FilterGraphHelper::ReadPropertyBagString(pPropertyBag, OLESTR("FriendlyName"));
716                                const CStringW sClassIdentifierString = _FilterGraphHelper::ReadPropertyBagString(pPropertyBag, OLESTR("CLSID"));
717                                const CStringW sPath = _RegKeyHelper::QueryStringValue(HKEY_CLASSES_ROOT, AtlFormatString(_T("CLSID\\%ls\\InprocServer32"), sClassIdentifierString));
718                                _Z4(atlTraceGeneral, 4, _T("sMonikerDisplayName \"%ls\", sFriendlyName \"%ls\", sClassIdentifierString %ls, sPath \"%ls\"\n"), sMonikerDisplayName, sFriendlyName, sClassIdentifierString, sPath);
719                        }
720                        _ATLCATCH(Exception)
721                        {
722                                _C(Exception);
723                        }
724                        return S_OK;
725                }
726                STDMETHOD(CreatedFilter)(IBaseFilter* pBaseFilter) throw()
727                {
728                        _Z5(atlTraceCOM, 5, _T("...\n"));
729                        _ATLTRY
730                        {
731                                _A(pBaseFilter);
732                                _Z4(atlTraceGeneral, 4, _T("pBaseFilter %ls \"%ls\"\n"), _FilterGraphHelper::GetFilterClassIdentifierString(pBaseFilter), _FilterGraphHelper::GetFilterName(pBaseFilter));
733                        }
734                        _ATLCATCH(Exception)
735                        {
736                                _C(Exception);
737                        }
738                        return S_OK;
739                }
740        };
741
742        ////////////////////////////////////////////////////
743        // CVmr7PropertyPage
744
745        class CVmr7PropertyPage :
746                public CPropertyPageT<CVmr7PropertyPage>,
747                public CDialogResize<CVmr7PropertyPage>
748        {
749        public:
750                enum { IDD = IDD_MAIN_VMR7 };
751
752        BEGIN_MSG_MAP_EX(CVmr7PropertyPage)
753                CHAIN_MSG_MAP(CPropertyPageT<CVmr7PropertyPage>)
754                CHAIN_MSG_MAP(CDialogResize<CVmr7PropertyPage>)
755                MSG_WM_INITDIALOG(OnInitDialog)
756                MSG_WM_DESTROY(OnDestroy)
757                COMMAND_ID_HANDLER_EX(IDC_MAIN_VMR7_RUN, OnRunButtonClicked)
758                COMMAND_ID_HANDLER_EX(IDC_MAIN_VMR7_PAUSE, OnPauseButtonClicked)
759                COMMAND_ID_HANDLER_EX(IDC_MAIN_VMR7_STOP, OnStopButtonClicked)
760                COMMAND_ID_HANDLER_EX(IDC_MAIN_VMR7_WEAVE, OnWeaveButtonClicked)
761                COMMAND_ID_HANDLER_EX(IDC_MAIN_VMR7_COLORIZE, OnColorizeButtonClicked)
762                MESSAGE_HANDLER_EX(WM_FILTERGRAPHEVENT, OnFilterGraphEvent)
763                REFLECT_NOTIFICATIONS()
764        END_MSG_MAP()
765
766        BEGIN_DLGRESIZE_MAP(CVmr7PropertyPage)
767                DLGRESIZE_CONTROL(IDC_MAIN_VMR7_VIDEO, DLSZ_SIZE_X | DLSZ_SIZE_Y)
768                DLGRESIZE_CONTROL(IDC_MAIN_VMR7_RUN, DLSZ_MOVE_X)
769                DLGRESIZE_CONTROL(IDC_MAIN_VMR7_PAUSE, DLSZ_MOVE_X)
770                DLGRESIZE_CONTROL(IDC_MAIN_VMR7_STOP, DLSZ_MOVE_X)
771                DLGRESIZE_CONTROL(IDC_MAIN_VMR7_WEAVE, DLSZ_MOVE_Y)
772                DLGRESIZE_CONTROL(IDC_MAIN_VMR7_COLORIZE, DLSZ_MOVE_Y)
773        END_DLGRESIZE_MAP()
774
775        public:
776
777                ////////////////////////////////////////////////////////
778                // Window Message Identifiers
779
780                enum
781                {
782                        WM_FIRST = WM_APP,
783                        WM_FILTERGRAPHEVENT,
784                };
785
786        private:
787                CMainPropertySheet& m_Owner;
788                CStatic m_VideoStatic;
789                CGenericFilterGraph m_FilterGraph;
790                CObjectPtr<CSourceFilter> m_pSourceFilter;
791                CVmr7Window m_RendererWindow;
792                CButton m_RunButton;
793                CButton m_PauseButton;
794                CButton m_StopButton;
795                CButton m_WeaveButton;
796                CButton m_ColorizeButton;
797
798                VOID UpdateControls()
799                {
800                        OAFilterState State;
801                        if(SUCCEEDED(m_FilterGraph.m_pMediaControl->GetState(0, &State)))
802                        {
803                                m_RunButton.EnableWindow(State != State_Running);
804                                m_PauseButton.EnableWindow(State != State_Paused);
805                                m_StopButton.EnableWindow(State != State_Stopped);
806                        } else
807                        {
808                                m_RunButton.EnableWindow(FALSE);
809                                m_PauseButton.EnableWindow(FALSE);
810                                m_StopButton.EnableWindow(FALSE);
811                        }
812                }
813
814        public:
815        // CVmr7PropertyPage
816                CVmr7PropertyPage(CMainPropertySheet* pOwner) :
817                        m_Owner(*pOwner)
818                {
819                }
820
821        // CDialogResize
822                VOID DlgResize_UpdateLayout(INT nWidth, INT nHeight)
823                {
824                        __super::DlgResize_UpdateLayout(nWidth, nHeight);
825                        CRect VideoPosition;
826                        _W(m_VideoStatic.GetWindowRect(VideoPosition));
827                        _W(ScreenToClient(VideoPosition));
828                        _W(m_RendererWindow.MoveWindow(VideoPosition));
829                }
830
831        // Window Message Handelrs
832                LRESULT OnInitDialog(HWND, LPARAM)
833                {
834                        m_VideoStatic = GetDlgItem(IDC_MAIN_VMR7_VIDEO);
835                        m_VideoStatic.ShowWindow(SW_HIDE);
836                        CRect VideoPosition;
837                        _W(m_VideoStatic.GetWindowRect(VideoPosition));
838                        _W(ScreenToClient(VideoPosition));
839                        m_RunButton = GetDlgItem(IDC_MAIN_VMR7_RUN);
840                        m_PauseButton = GetDlgItem(IDC_MAIN_VMR7_PAUSE);
841                        m_StopButton = GetDlgItem(IDC_MAIN_VMR7_STOP);
842                        m_WeaveButton = GetDlgItem(IDC_MAIN_VMR7_WEAVE);
843                        m_ColorizeButton = GetDlgItem(IDC_MAIN_VMR7_COLORIZE);
844                        DlgResize_Init(TRUE);
845                        m_FilterGraph.CoCreateInstance();
846                        CObjectPtr<CAmGraphBuilderCallback> pAmGraphBuilderCallback;
847                        pAmGraphBuilderCallback.Construct();
848                        pAmGraphBuilderCallback->SetGraphBuilder(m_FilterGraph.m_pFilterGraph);
849                        const CComPtr<IBaseFilter> pBaseFilter = m_RendererWindow.CoCreateBaseFilterInstance();
850                        __C(m_FilterGraph->AddFilter(pBaseFilter, CT2CW(_T("VMR-7"))));
851                        m_RendererWindow.Create(m_hWnd);
852                        _W(m_RendererWindow.MoveWindow(VideoPosition));
853                        m_RendererWindow.ShowWindow(SW_SHOWNORMAL);
854                        m_RendererWindow.Initialize(pBaseFilter);
855                        CObjectPtr<CSourceFilter> pSourceFilter;
856                        pSourceFilter.Construct()->Initialize();
857                        pSourceFilter->SetWeave(m_WeaveButton.GetCheck());
858                        pSourceFilter->SetColorize(m_ColorizeButton.GetCheck());
859                        m_pSourceFilter = pSourceFilter;
860                        __C(m_FilterGraph->AddFilter(pSourceFilter, CT2CW(_T("Source"))));
861                        __C(m_FilterGraph->Connect(pSourceFilter->GetOutputPin(), _FilterGraphHelper::GetFilterPin(m_RendererWindow.m_pBaseFilter)));
862                        __C(m_FilterGraph.m_pMediaEventEx->SetNotifyWindow((OAHWND) m_hWnd, WM_FILTERGRAPHEVENT, (LONG_PTR) this));
863                        UpdateControls();
864                        return 0;
865                }
866                LRESULT OnDestroy() throw()
867                {
868                        if(m_FilterGraph.m_pMediaControl)
869                                _V(m_FilterGraph.m_pMediaControl->Stop());
870                        m_RendererWindow.Terminate();
871                        m_pSourceFilter.Release();
872                        m_FilterGraph.Release();
873                        return 0;
874                }
875                LRESULT OnRunButtonClicked(UINT, INT, HWND)
876                {
877                        CWaitCursor WaitCursor;
878                        __D(m_FilterGraph.m_pMediaControl, E_NOINTERFACE);
879                        __C(m_FilterGraph.m_pMediaControl->Run());
880                        UpdateControls();
881                        #pragma region Capabilities
882                        _ATLTRY
883                        {
884                                const CComQIPtr<IVMRDeinterlaceControl> pVmrDeinterlaceControl = m_RendererWindow.m_pBaseFilter;
885                                VMRVideoDesc VideoDescription;
886                                ZeroMemory(&VideoDescription, sizeof VideoDescription);
887                                VideoDescription.dwSize = sizeof VideoDescription;
888                                const CVideoInfoHeader2* pVideoInfoHeader2 = m_pSourceFilter->GetRequestedMediaType().GetVideoInfoHeader2();
889                                _A(pVideoInfoHeader2);
890                                const CSize Extent = pVideoInfoHeader2->GetExtent();
891                                VideoDescription.dwSampleWidth = Extent.cx;
892                                VideoDescription.dwSampleHeight = Extent.cy;
893                                VideoDescription.SingleFieldPerSample = FALSE;
894                                VideoDescription.dwFourCC = pVideoInfoHeader2->GetBitmapInfoHeader().biCompression;
895                                VideoDescription.InputSampleFreq.dwNumerator = 30000;
896                                VideoDescription.InputSampleFreq.dwDenominator = 1001;
897                                VideoDescription.OutputFrameFreq.dwNumerator = 60000;
898                                VideoDescription.OutputFrameFreq.dwDenominator = 1001;
899                                DWORD nModeCount = 16;
900                                CTempBufferT<GUID> pModes(nModeCount);
901                                const HRESULT nGetNumberOfDeinterlaceModesResult = pVmrDeinterlaceControl->GetNumberOfDeinterlaceModes(&VideoDescription, &nModeCount, pModes);
902                                _Z4(atlTraceGeneral, 4, _T("nGetNumberOfDeinterlaceModesResult 0x%08x, nModeCount %d\n"), nGetNumberOfDeinterlaceModesResult, nModeCount);
903                                if(SUCCEEDED(nGetNumberOfDeinterlaceModesResult))
904                                {
905                                        for(DWORD nModeIndex = 0; nModeIndex < nModeCount; nModeIndex++)
906                                        {
907                                                const GUID& Mode = pModes[nModeIndex];
908                                                _Z4(atlTraceGeneral, 4, _T("nModeIndex %d, Mode %s\n"), nModeIndex, FormatDeinterlaceMode(Mode));
909                                                VMRDeinterlaceCaps Capabilities;
910                                                ZeroMemory(&Capabilities, sizeof Capabilities);
911                                                Capabilities.dwSize = sizeof Capabilities;
912                                                const HRESULT nGetDeinterlaceModeCapsResult = pVmrDeinterlaceControl->GetDeinterlaceModeCaps(const_cast<GUID*>(&Mode), &VideoDescription, &Capabilities);
913                                                _Z4(atlTraceGeneral, 4, _T("nGetDeinterlaceModeCapsResult 0x%08x, Capabilities.dwNumPreviousOutputFrames %d, .dwNumForwardRefSamples %d, .dwNumBackwardRefSamples %d, .DeinterlaceTechnology 0x%x\n"), nGetDeinterlaceModeCapsResult, Capabilities.dwNumPreviousOutputFrames, Capabilities.dwNumForwardRefSamples, Capabilities.dwNumBackwardRefSamples, Capabilities.DeinterlaceTechnology);
914                                        }
915                                }
916                                GUID DeinterlaceMode = GUID_NULL;
917                                const HRESULT nGetDeinterlaceModeResult = pVmrDeinterlaceControl->GetDeinterlaceMode(0, &DeinterlaceMode);
918                                _Z4(atlTraceGeneral, 4, _T("nGetDeinterlaceModeResult 0x%08x\n"), nGetDeinterlaceModeResult);
919                                if(SUCCEEDED(nGetDeinterlaceModeResult) && !(nGetDeinterlaceModeResult == S_FALSE && DeinterlaceMode == GUID_NULL))
920                                        _Z4(atlTraceGeneral, 4, _T("DeinterlaceMode %s\n"), FormatDeinterlaceMode(DeinterlaceMode));
921                                DWORD nPreferences = 0;
922                                const HRESULT nGetDeinterlacePrefsResult = pVmrDeinterlaceControl->GetDeinterlacePrefs(&nPreferences);
923                                _Z4(atlTraceGeneral, 4, _T("nGetDeinterlacePrefsResult 0x%08x, nPreferences 0x%x\n"), nGetDeinterlacePrefsResult, nPreferences);
924                                GUID ActualDeinterlaceMode;
925                                const HRESULT nGetActualDeinterlaceModeResult = pVmrDeinterlaceControl->GetActualDeinterlaceMode(0, &ActualDeinterlaceMode);
926                                _Z4(atlTraceGeneral, 4, _T("nGetActualDeinterlaceModeResult 0x%08x\n"), nGetActualDeinterlaceModeResult);
927                                if(SUCCEEDED(nGetActualDeinterlaceModeResult))
928                                        _Z4(atlTraceGeneral, 4, _T("ActualDeinterlaceMode %s\n"), FormatDeinterlaceMode(ActualDeinterlaceMode));
929                        }
930                        _ATLCATCHALL()
931                        {
932                                _Z_EXCEPTION();
933                        }
934                        #pragma endregion
935                        return 0;
936                }
937                LRESULT OnPauseButtonClicked(UINT, INT, HWND)
938                {
939                        CWaitCursor WaitCursor;
940                        __D(m_FilterGraph.m_pMediaControl, E_NOINTERFACE);
941                        __C(m_FilterGraph.m_pMediaControl->Pause());
942                        UpdateControls();
943                        return 0;
944                }
945                LRESULT OnStopButtonClicked(UINT, INT, HWND)
946                {
947                        CWaitCursor WaitCursor;
948                        if(m_FilterGraph.m_pMediaControl)
949                                _V(m_FilterGraph.m_pMediaControl->Stop());
950                        UpdateControls();
951                        return 0;
952                }
953                LRESULT OnWeaveButtonClicked(UINT, INT, HWND)
954                {
955                        if(m_pSourceFilter)
956                                m_pSourceFilter->SetWeave(m_WeaveButton.GetCheck());
957                        return 0;
958                }
959                LRESULT OnColorizeButtonClicked(UINT, INT, HWND)
960                {
961                        if(m_pSourceFilter)
962                                m_pSourceFilter->SetColorize(m_ColorizeButton.GetCheck());
963                        return 0;
964                }
965                LRESULT OnFilterGraphEvent(UINT, WPARAM, LPARAM)
966                {
967                        if(!m_FilterGraph.m_pMediaEventEx)
968                                return 0;
969                        _ATLTRY
970                        {
971                                for(; ; )
972                                {
973                                        LONG nEventCode;
974                                        LONG_PTR nParameter1, nParameter2;
975                                        const HRESULT nGetEventResult = m_FilterGraph.m_pMediaEventEx->GetEvent(&nEventCode, &nParameter1, &nParameter2, 0);
976                                        if(nGetEventResult == E_ABORT)
977                                                break;
978                                        __C(nGetEventResult);
979                                        _ATLTRY
980                                        {
981                                                switch(nEventCode)
982                                                {
983                                                case EC_ERRORABORT:
984                                                        _Z2(atlTraceGeneral, 2, _T("nEventCode EC_ERRORABORT 0x%02X, nParameter1 0x%08x, nParameter2 0x%08x\n"), nEventCode, nParameter1, nParameter2);
985                                                        _A(FAILED(nParameter1));
986                                                        AtlMessageBoxEx(m_hWnd, (LPCTSTR) AtlFormatString(_T("EC_ERRORABORT Event: %s."), AtlFormatSystemMessage((HRESULT) nParameter1).TrimRight(_T("\t\n\r ."))), IDS_ERROR, MB_ICONERROR | MB_OK);
987                                                        break;
988                                                default:
989                                                        _Z1(atlTraceGeneral, 1, _T("nEventCode 0x%02X, nParameter1 0x%08x, nParameter2 0x%08x\n"), nEventCode, nParameter1, nParameter2);
990                                                }
991                                        }
992                                        _ATLCATCHALL()
993                                        {
994                                                _V(m_FilterGraph.m_pMediaEventEx->FreeEventParams(nEventCode, nParameter1, nParameter2));
995                                                _ATLRETHROW;
996                                        }
997                                        _V(m_FilterGraph.m_pMediaEventEx->FreeEventParams(nEventCode, nParameter1, nParameter2));
998                                }
999                        }
1000                        _ATLCATCHALL()
1001                        {
1002                                _Z_EXCEPTION();
1003                        }
1004                        return 0;
1005                }
1006                INT OnKillActive()
1007                {
1008                        m_StopButton.Click();
1009                        return 0;
1010                }
1011        };
1012
1013        ////////////////////////////////////////////////////
1014        // CVmr9PropertyPage
1015
1016        class CVmr9PropertyPage :
1017                public CPropertyPageT<CVmr9PropertyPage>,
1018                public CDialogResize<CVmr9PropertyPage>
1019        {
1020        public:
1021                enum { IDD = IDD_MAIN_VMR9 };
1022
1023        BEGIN_MSG_MAP_EX(CVmr9PropertyPage)
1024                CHAIN_MSG_MAP(CPropertyPageT<CVmr9PropertyPage>)
1025                CHAIN_MSG_MAP(CDialogResize<CVmr9PropertyPage>)
1026                MSG_WM_INITDIALOG(OnInitDialog)
1027                MSG_WM_DESTROY(OnDestroy)
1028                COMMAND_ID_HANDLER_EX(IDC_MAIN_VMR9_RUN, OnRunButtonClicked)
1029                COMMAND_ID_HANDLER_EX(IDC_MAIN_VMR9_PAUSE, OnPauseButtonClicked)
1030                COMMAND_ID_HANDLER_EX(IDC_MAIN_VMR9_STOP, OnStopButtonClicked)
1031                COMMAND_ID_HANDLER_EX(IDC_MAIN_VMR9_WEAVE, OnWeaveButtonClicked)
1032                COMMAND_ID_HANDLER_EX(IDC_MAIN_VMR9_COLORIZE, OnColorizeButtonClicked)
1033                MESSAGE_HANDLER_EX(WM_FILTERGRAPHEVENT, OnFilterGraphEvent)
1034                REFLECT_NOTIFICATIONS()
1035        END_MSG_MAP()
1036
1037        BEGIN_DLGRESIZE_MAP(CVmr9PropertyPage)
1038                DLGRESIZE_CONTROL(IDC_MAIN_VMR9_VIDEO, DLSZ_SIZE_X | DLSZ_SIZE_Y)
1039                DLGRESIZE_CONTROL(IDC_MAIN_VMR9_RUN, DLSZ_MOVE_X)
1040                DLGRESIZE_CONTROL(IDC_MAIN_VMR9_PAUSE, DLSZ_MOVE_X)
1041                DLGRESIZE_CONTROL(IDC_MAIN_VMR9_STOP, DLSZ_MOVE_X)
1042                DLGRESIZE_CONTROL(IDC_MAIN_VMR9_WEAVE, DLSZ_MOVE_Y)
1043                DLGRESIZE_CONTROL(IDC_MAIN_VMR9_COLORIZE, DLSZ_MOVE_Y)
1044        END_DLGRESIZE_MAP()
1045
1046        public:
1047
1048                ////////////////////////////////////////////////////////
1049                // Window Message Identifiers
1050
1051                enum
1052                {
1053                        WM_FIRST = WM_APP,
1054                        WM_FILTERGRAPHEVENT,
1055                };
1056
1057        private:
1058                CMainPropertySheet& m_Owner;
1059                CStatic m_VideoStatic;
1060                CGenericFilterGraph m_FilterGraph;
1061                CObjectPtr<CSourceFilter> m_pSourceFilter;
1062                CVmr9Window m_RendererWindow;
1063                CButton m_RunButton;
1064                CButton m_PauseButton;
1065                CButton m_StopButton;
1066                CButton m_WeaveButton;
1067                CButton m_ColorizeButton;
1068
1069                VOID UpdateControls()
1070                {
1071                        OAFilterState State;
1072                        if(SUCCEEDED(m_FilterGraph.m_pMediaControl->GetState(0, &State)))
1073                        {
1074                                m_RunButton.EnableWindow(State != State_Running);
1075                                m_PauseButton.EnableWindow(State != State_Paused);
1076                                m_StopButton.EnableWindow(State != State_Stopped);
1077                        } else
1078                        {
1079                                m_RunButton.EnableWindow(FALSE);
1080                                m_PauseButton.EnableWindow(FALSE);
1081                                m_StopButton.EnableWindow(FALSE);
1082                        }
1083                }
1084
1085        public:
1086        // CVmr9PropertyPage
1087                CVmr9PropertyPage(CMainPropertySheet* pOwner) :
1088                        m_Owner(*pOwner)
1089                {
1090                }
1091
1092        // CDialogResize
1093                VOID DlgResize_UpdateLayout(INT nWidth, INT nHeight)
1094                {
1095                        __super::DlgResize_UpdateLayout(nWidth, nHeight);
1096                        CRect VideoPosition;
1097                        _W(m_VideoStatic.GetWindowRect(VideoPosition));
1098                        _W(ScreenToClient(VideoPosition));
1099                        _W(m_RendererWindow.MoveWindow(VideoPosition));
1100                }
1101
1102        // Window Message Handelrs
1103                LRESULT OnInitDialog(HWND, LPARAM)
1104                {
1105                        m_VideoStatic = GetDlgItem(IDC_MAIN_VMR9_VIDEO);
1106                        m_VideoStatic.ShowWindow(SW_HIDE);
1107                        CRect VideoPosition;
1108                        _W(m_VideoStatic.GetWindowRect(VideoPosition));
1109                        _W(ScreenToClient(VideoPosition));
1110                        m_RunButton = GetDlgItem(IDC_MAIN_VMR9_RUN);
1111                        m_PauseButton = GetDlgItem(IDC_MAIN_VMR9_PAUSE);
1112                        m_StopButton = GetDlgItem(IDC_MAIN_VMR9_STOP);
1113                        m_WeaveButton = GetDlgItem(IDC_MAIN_VMR9_WEAVE);
1114                        m_ColorizeButton = GetDlgItem(IDC_MAIN_VMR9_COLORIZE);
1115                        DlgResize_Init(TRUE);
1116                        m_FilterGraph.CoCreateInstance();
1117                        CObjectPtr<CAmGraphBuilderCallback> pAmGraphBuilderCallback;
1118                        pAmGraphBuilderCallback.Construct();
1119                        pAmGraphBuilderCallback->SetGraphBuilder(m_FilterGraph.m_pFilterGraph);
1120                        const CComPtr<IBaseFilter> pBaseFilter = m_RendererWindow.CoCreateBaseFilterInstance();
1121                        __C(m_FilterGraph->AddFilter(pBaseFilter, CT2CW(_T("VMR-9"))));
1122                        m_RendererWindow.Create(m_hWnd);
1123                        _W(m_RendererWindow.MoveWindow(VideoPosition));
1124                        m_RendererWindow.ShowWindow(SW_SHOWNORMAL);
1125                        m_RendererWindow.Initialize(pBaseFilter);
1126                        CObjectPtr<CSourceFilter> pSourceFilter;
1127                        pSourceFilter.Construct()->Initialize();
1128                        pSourceFilter->SetWeave(m_WeaveButton.GetCheck());
1129                        pSourceFilter->SetColorize(m_ColorizeButton.GetCheck());
1130                        m_pSourceFilter = pSourceFilter;
1131                        __C(m_FilterGraph->AddFilter(pSourceFilter, CT2CW(_T("Source"))));
1132                        __C(m_FilterGraph->Connect(pSourceFilter->GetOutputPin(), _FilterGraphHelper::GetFilterPin(m_RendererWindow.m_pBaseFilter)));
1133                        __C(m_FilterGraph.m_pMediaEventEx->SetNotifyWindow((OAHWND) m_hWnd, WM_FILTERGRAPHEVENT, (LONG_PTR) this));
1134                        UpdateControls();
1135                        return 0;
1136                }
1137                LRESULT OnDestroy() throw()
1138                {
1139                        if(m_FilterGraph.m_pMediaControl)
1140                                _V(m_FilterGraph.m_pMediaControl->Stop());
1141                        m_RendererWindow.Terminate();
1142                        m_pSourceFilter.Release();
1143                        m_FilterGraph.Release();
1144                        return 0;
1145                }
1146                LRESULT OnRunButtonClicked(UINT, INT, HWND)
1147                {
1148                        CWaitCursor WaitCursor;
1149                        __D(m_FilterGraph.m_pMediaControl, E_NOINTERFACE);
1150                        __C(m_FilterGraph.m_pMediaControl->Run());
1151                        UpdateControls();
1152                        #pragma region Capabilities
1153                        _ATLTRY
1154                        {
1155                                const CComQIPtr<IVMRDeinterlaceControl9> pVmrDeinterlaceControl9 = m_RendererWindow.m_pBaseFilter;
1156                                VMR9VideoDesc VideoDescription;
1157                                ZeroMemory(&VideoDescription, sizeof VideoDescription);
1158                                VideoDescription.dwSize = sizeof VideoDescription;
1159                                const CVideoInfoHeader2* pVideoInfoHeader2 = m_pSourceFilter->GetRequestedMediaType().GetVideoInfoHeader2();
1160                                _A(pVideoInfoHeader2);
1161                                const CSize Extent = pVideoInfoHeader2->GetExtent();
1162                                VideoDescription.dwSampleWidth = Extent.cx;
1163                                VideoDescription.dwSampleHeight = Extent.cy;
1164                                VideoDescription.SampleFormat = VMR9_SampleFieldInterleavedEvenFirst;
1165                                VideoDescription.dwFourCC = pVideoInfoHeader2->GetBitmapInfoHeader().biCompression;
1166                                VideoDescription.InputSampleFreq.dwNumerator = 30000;
1167                                VideoDescription.InputSampleFreq.dwDenominator = 1001;
1168                                VideoDescription.OutputFrameFreq.dwNumerator = 60000;
1169                                VideoDescription.OutputFrameFreq.dwDenominator = 1001;
1170                                DWORD nModeCount = 16;
1171                                CTempBufferT<GUID> pModes(nModeCount);
1172                                const HRESULT nGetNumberOfDeinterlaceModesResult = pVmrDeinterlaceControl9->GetNumberOfDeinterlaceModes(&VideoDescription, &nModeCount, pModes);
1173                                _Z4(atlTraceGeneral, 4, _T("nGetNumberOfDeinterlaceModesResult 0x%08x, nModeCount %d\n"), nGetNumberOfDeinterlaceModesResult, nModeCount);
1174                                if(SUCCEEDED(nGetNumberOfDeinterlaceModesResult))
1175                                {
1176                                        for(DWORD nModeIndex = 0; nModeIndex < nModeCount; nModeIndex++)
1177                                        {
1178                                                const GUID& Mode = pModes[nModeIndex];
1179                                                _Z4(atlTraceGeneral, 4, _T("nModeIndex %d, Mode %s\n"), nModeIndex, FormatDeinterlaceMode(Mode));
1180                                                VMR9DeinterlaceCaps Capabilities;
1181                                                ZeroMemory(&Capabilities, sizeof Capabilities);
1182                                                Capabilities.dwSize = sizeof Capabilities;
1183                                                const HRESULT nGetDeinterlaceModeCapsResult = pVmrDeinterlaceControl9->GetDeinterlaceModeCaps(const_cast<GUID*>(&Mode), &VideoDescription, &Capabilities);
1184                                                _Z4(atlTraceGeneral, 4, _T("nGetDeinterlaceModeCapsResult 0x%08x, Capabilities.dwNumPreviousOutputFrames %d, .dwNumForwardRefSamples %d, .dwNumBackwardRefSamples %d, .DeinterlaceTechnology 0x%x\n"), nGetDeinterlaceModeCapsResult, Capabilities.dwNumPreviousOutputFrames, Capabilities.dwNumForwardRefSamples, Capabilities.dwNumBackwardRefSamples, Capabilities.DeinterlaceTechnology);
1185                                        }
1186                                }
1187                                GUID DeinterlaceMode = GUID_NULL;
1188                                const HRESULT nGetDeinterlaceModeResult = pVmrDeinterlaceControl9->GetDeinterlaceMode(0, &DeinterlaceMode);
1189                                _Z4(atlTraceGeneral, 4, _T("nGetDeinterlaceModeResult 0x%08x\n"), nGetDeinterlaceModeResult);
1190                                if(SUCCEEDED(nGetDeinterlaceModeResult) && !(nGetDeinterlaceModeResult == S_FALSE && DeinterlaceMode == GUID_NULL))
1191                                        _Z4(atlTraceGeneral, 4, _T("DeinterlaceMode %s\n"), FormatDeinterlaceMode(DeinterlaceMode));
1192                                DWORD nPreferences = 0;
1193                                const HRESULT nGetDeinterlacePrefsResult = pVmrDeinterlaceControl9->GetDeinterlacePrefs(&nPreferences);
1194                                _Z4(atlTraceGeneral, 4, _T("nGetDeinterlacePrefsResult 0x%08x, nPreferences 0x%x\n"), nGetDeinterlacePrefsResult, nPreferences);
1195                                GUID ActualDeinterlaceMode;
1196                                const HRESULT nGetActualDeinterlaceModeResult = pVmrDeinterlaceControl9->GetActualDeinterlaceMode(0, &ActualDeinterlaceMode);
1197                                _Z4(atlTraceGeneral, 4, _T("nGetActualDeinterlaceModeResult 0x%08x\n"), nGetActualDeinterlaceModeResult);
1198                                if(SUCCEEDED(nGetActualDeinterlaceModeResult))
1199                                        _Z4(atlTraceGeneral, 4, _T("ActualDeinterlaceMode %s\n"), FormatDeinterlaceMode(ActualDeinterlaceMode));
1200                        }
1201                        _ATLCATCHALL()
1202                        {
1203                                _Z_EXCEPTION();
1204                        }
1205                        #pragma endregion
1206                        return 0;
1207                }
1208                LRESULT OnPauseButtonClicked(UINT, INT, HWND)
1209                {
1210                        CWaitCursor WaitCursor;
1211                        __D(m_FilterGraph.m_pMediaControl, E_NOINTERFACE);
1212                        __C(m_FilterGraph.m_pMediaControl->Pause());
1213                        UpdateControls();
1214                        return 0;
1215                }
1216                LRESULT OnStopButtonClicked(UINT, INT, HWND)
1217                {
1218                        CWaitCursor WaitCursor;
1219                        if(m_FilterGraph.m_pMediaControl)
1220                                _V(m_FilterGraph.m_pMediaControl->Stop());
1221                        UpdateControls();
1222                        return 0;
1223                }
1224                LRESULT OnWeaveButtonClicked(UINT, INT, HWND)
1225                {
1226                        if(m_pSourceFilter)
1227                                m_pSourceFilter->SetWeave(m_WeaveButton.GetCheck());
1228                        return 0;
1229                }
1230                LRESULT OnColorizeButtonClicked(UINT, INT, HWND)
1231                {
1232                        if(m_pSourceFilter)
1233                                m_pSourceFilter->SetColorize(m_ColorizeButton.GetCheck());
1234                        return 0;
1235                }
1236                LRESULT OnFilterGraphEvent(UINT, WPARAM, LPARAM)
1237                {
1238                        if(!m_FilterGraph.m_pMediaEventEx)
1239                                return 0;
1240                        _ATLTRY
1241                        {
1242                                for(; ; )
1243                                {
1244                                        LONG nEventCode;
1245                                        LONG_PTR nParameter1, nParameter2;
1246                                        const HRESULT nGetEventResult = m_FilterGraph.m_pMediaEventEx->GetEvent(&nEventCode, &nParameter1, &nParameter2, 0);
1247                                        if(nGetEventResult == E_ABORT)
1248                                                break;
1249                                        __C(nGetEventResult);
1250                                        _ATLTRY
1251                                        {
1252                                                switch(nEventCode)
1253                                                {
1254                                                case EC_ERRORABORT:
1255                                                        _Z2(atlTraceGeneral, 2, _T("nEventCode EC_ERRORABORT 0x%02X, nParameter1 0x%08x, nParameter2 0x%08x\n"), nEventCode, nParameter1, nParameter2);
1256                                                        _A(FAILED(nParameter1));
1257                                                        AtlMessageBoxEx(m_hWnd, (LPCTSTR) AtlFormatString(_T("EC_ERRORABORT Event: %s."), AtlFormatSystemMessage((HRESULT) nParameter1).TrimRight(_T("\t\n\r ."))), IDS_ERROR, MB_ICONERROR | MB_OK);
1258                                                        break;
1259                                                default:
1260                                                        _Z1(atlTraceGeneral, 1, _T("nEventCode 0x%02X, nParameter1 0x%08x, nParameter2 0x%08x\n"), nEventCode, nParameter1, nParameter2);
1261                                                }
1262                                        }
1263                                        _ATLCATCHALL()
1264                                        {
1265                                                _V(m_FilterGraph.m_pMediaEventEx->FreeEventParams(nEventCode, nParameter1, nParameter2));
1266                                                _ATLRETHROW;
1267                                        }
1268                                        _V(m_FilterGraph.m_pMediaEventEx->FreeEventParams(nEventCode, nParameter1, nParameter2));
1269                                }
1270                        }
1271                        _ATLCATCHALL()
1272                        {
1273                                _Z_EXCEPTION();
1274                        }
1275                        return 0;
1276                }
1277                INT OnKillActive()
1278                {
1279                        m_StopButton.Click();
1280                        return 0;
1281                }
1282        };
1283
1284        ////////////////////////////////////////////////////
1285        // CEvrPropertyPage
1286
1287        class CEvrPropertyPage :
1288                public CPropertyPageT<CEvrPropertyPage>,
1289                public CDialogResize<CEvrPropertyPage>
1290        {
1291        public:
1292                enum { IDD = IDD_MAIN_EVR };
1293
1294        BEGIN_MSG_MAP_EX(CEvrPropertyPage)
1295                CHAIN_MSG_MAP(CPropertyPageT<CEvrPropertyPage>)
1296                CHAIN_MSG_MAP(CDialogResize<CEvrPropertyPage>)
1297                MSG_WM_INITDIALOG(OnInitDialog)
1298                MSG_WM_DESTROY(OnDestroy)
1299                COMMAND_ID_HANDLER_EX(IDC_MAIN_EVR_RUN, OnRunButtonClicked)
1300                COMMAND_ID_HANDLER_EX(IDC_MAIN_EVR_PAUSE, OnPauseButtonClicked)
1301                COMMAND_ID_HANDLER_EX(IDC_MAIN_EVR_STOP, OnStopButtonClicked)
1302                COMMAND_ID_HANDLER_EX(IDC_MAIN_EVR_WEAVE, OnWeaveButtonClicked)
1303                COMMAND_ID_HANDLER_EX(IDC_MAIN_EVR_COLORIZE, OnColorizeButtonClicked)
1304                MESSAGE_HANDLER_EX(WM_FILTERGRAPHEVENT, OnFilterGraphEvent)
1305                REFLECT_NOTIFICATIONS()
1306        END_MSG_MAP()
1307
1308        BEGIN_DLGRESIZE_MAP(CEvrPropertyPage)
1309                DLGRESIZE_CONTROL(IDC_MAIN_EVR_VIDEO, DLSZ_SIZE_X | DLSZ_SIZE_Y)
1310                DLGRESIZE_CONTROL(IDC_MAIN_EVR_RUN, DLSZ_MOVE_X)
1311                DLGRESIZE_CONTROL(IDC_MAIN_EVR_PAUSE, DLSZ_MOVE_X)
1312                DLGRESIZE_CONTROL(IDC_MAIN_EVR_STOP, DLSZ_MOVE_X)
1313                DLGRESIZE_CONTROL(IDC_MAIN_EVR_WEAVE, DLSZ_MOVE_Y)
1314                DLGRESIZE_CONTROL(IDC_MAIN_EVR_COLORIZE, DLSZ_MOVE_Y)
1315        END_DLGRESIZE_MAP()
1316
1317        public:
1318
1319                ////////////////////////////////////////////////////////
1320                // Window Message Identifiers
1321
1322                enum
1323                {
1324                        WM_FIRST = WM_APP,
1325                        WM_FILTERGRAPHEVENT,
1326                };
1327
1328        private:
1329                CMainPropertySheet& m_Owner;
1330                CStatic m_VideoStatic;
1331                CGenericFilterGraph m_FilterGraph;
1332                CObjectPtr<CSourceFilter> m_pSourceFilter;
1333                CEvrWindow m_RendererWindow;
1334                CButton m_RunButton;
1335                CButton m_PauseButton;
1336                CButton m_StopButton;
1337                CButton m_WeaveButton;
1338                CButton m_ColorizeButton;
1339
1340                VOID UpdateControls()
1341                {
1342                        OAFilterState State;
1343                        if(SUCCEEDED(m_FilterGraph.m_pMediaControl->GetState(0, &State)))
1344                        {
1345                                m_RunButton.EnableWindow(State != State_Running);
1346                                m_PauseButton.EnableWindow(State != State_Paused);
1347                                m_StopButton.EnableWindow(State != State_Stopped);
1348                        } else
1349                        {
1350                                m_RunButton.EnableWindow(FALSE);
1351                                m_PauseButton.EnableWindow(FALSE);
1352                                m_StopButton.EnableWindow(FALSE);
1353                        }
1354                }
1355
1356        public:
1357        // CEvrPropertyPage
1358                CEvrPropertyPage(CMainPropertySheet* pOwner) :
1359                        m_Owner(*pOwner)
1360                {
1361                }
1362
1363        // CDialogResize
1364                VOID DlgResize_UpdateLayout(INT nWidth, INT nHeight)
1365                {
1366                        __super::DlgResize_UpdateLayout(nWidth, nHeight);
1367                        CRect VideoPosition;
1368                        _W(m_VideoStatic.GetWindowRect(VideoPosition));
1369                        _W(ScreenToClient(VideoPosition));
1370                        _W(m_RendererWindow.MoveWindow(VideoPosition));
1371                }
1372
1373        // Window Message Handelrs
1374                LRESULT OnInitDialog(HWND, LPARAM)
1375                {
1376                        m_VideoStatic = GetDlgItem(IDC_MAIN_EVR_VIDEO);
1377                        m_VideoStatic.ShowWindow(SW_HIDE);
1378                        CRect VideoPosition;
1379                        _W(m_VideoStatic.GetWindowRect(VideoPosition));
1380                        _W(ScreenToClient(VideoPosition));
1381                        m_RunButton = GetDlgItem(IDC_MAIN_EVR_RUN);
1382                        m_PauseButton = GetDlgItem(IDC_MAIN_EVR_PAUSE);
1383                        m_StopButton = GetDlgItem(IDC_MAIN_EVR_STOP);
1384                        m_WeaveButton = GetDlgItem(IDC_MAIN_EVR_WEAVE);
1385                        m_ColorizeButton = GetDlgItem(IDC_MAIN_EVR_COLORIZE);
1386                        DlgResize_Init(TRUE);
1387                        m_FilterGraph.CoCreateInstance();
1388                        CObjectPtr<CAmGraphBuilderCallback> pAmGraphBuilderCallback;
1389                        pAmGraphBuilderCallback.Construct();
1390                        pAmGraphBuilderCallback->SetGraphBuilder(m_FilterGraph.m_pFilterGraph);
1391                        const CComPtr<IBaseFilter> pBaseFilter = m_RendererWindow.CoCreateBaseFilterInstance();
1392                        __C(m_FilterGraph->AddFilter(pBaseFilter, CT2CW(_T("EVR"))));
1393                        m_RendererWindow.Create(m_hWnd);
1394                        _W(m_RendererWindow.MoveWindow(VideoPosition));
1395                        m_RendererWindow.ShowWindow(SW_SHOWNORMAL);
1396                        m_RendererWindow.Initialize(pBaseFilter);
1397                        CObjectPtr<CSourceFilter> pSourceFilter;
1398                        pSourceFilter.Construct()->Initialize();
1399                        pSourceFilter->SetWeave(m_WeaveButton.GetCheck());
1400                        pSourceFilter->SetColorize(m_ColorizeButton.GetCheck());
1401                        m_pSourceFilter = pSourceFilter;
1402                        __C(m_FilterGraph->AddFilter(pSourceFilter, CT2CW(_T("Source"))));
1403                        __C(m_FilterGraph->Connect(pSourceFilter->GetOutputPin(), _FilterGraphHelper::GetFilterPin(m_RendererWindow.m_pBaseFilter)));
1404                        __C(m_FilterGraph.m_pMediaEventEx->SetNotifyWindow((OAHWND) m_hWnd, WM_FILTERGRAPHEVENT, (LONG_PTR) this));
1405                        UpdateControls();
1406                        return 0;
1407                }
1408                LRESULT OnDestroy() throw()
1409                {
1410                        if(m_FilterGraph.m_pMediaControl)
1411                                _V(m_FilterGraph.m_pMediaControl->Stop());
1412                        m_RendererWindow.Terminate();
1413                        m_pSourceFilter.Release();
1414                        m_FilterGraph.Release();
1415                        return 0;
1416                }
1417                LRESULT OnRunButtonClicked(UINT, INT, HWND)
1418                {
1419                        CWaitCursor WaitCursor;
1420                        __D(m_FilterGraph.m_pMediaControl, E_NOINTERFACE);
1421                        __C(m_FilterGraph.m_pMediaControl->Run());
1422                        UpdateControls();
1423                        #pragma region Capabilities
1424                        _ATLTRY
1425                        {
1426                                const CComQIPtr<IMFGetService> pMfGetService = m_RendererWindow.m_pBaseFilter;
1427                                __D(pMfGetService, E_NOINTERFACE);
1428                                CComQIPtr<IMFVideoProcessor> pMfVideoProcessor;
1429                                __C(pMfGetService->GetService(MR_VIDEO_MIXER_SERVICE, __uuidof(IMFVideoProcessor), (VOID**) &pMfVideoProcessor));
1430                                __D(pMfVideoProcessor, E_NOINTERFACE);
1431                                UINT nModeCount = 0;
1432                                CComHeapPtr<GUID> pModes;
1433                                const HRESULT nGetAvailableVideoProcessorModesResult = pMfVideoProcessor->GetAvailableVideoProcessorModes(&nModeCount, &pModes);
1434                                _Z4(atlTraceGeneral, 4, _T("nGetAvailableVideoProcessorModesResult 0x%08x, nModeCount %d\n"), nGetAvailableVideoProcessorModesResult, nModeCount);
1435                                if(SUCCEEDED(nGetAvailableVideoProcessorModesResult))
1436                                {
1437                                        for(DWORD nModeIndex = 0; nModeIndex < nModeCount; nModeIndex++)
1438                                        {
1439                                                const GUID& Mode = pModes[nModeIndex];
1440                                                _Z4(atlTraceGeneral, 4, _T("nModeIndex %d, Mode %s\n"), nModeIndex, FormatDeinterlaceMode(Mode));
1441                                                DXVA2_VideoProcessorCaps Capabilities;
1442                                                ZeroMemory(&Capabilities, sizeof Capabilities);
1443                                                const HRESULT nGetVideoProcessorCapsResult = pMfVideoProcessor->GetVideoProcessorCaps(const_cast<GUID*>(&Mode), &Capabilities);
1444                                                _Z4(atlTraceGeneral, 4, _T("nGetVideoProcessorCapsResult 0x%08x") _T(", ") 
1445                                                        _T("Capabilities") 
1446                                                        _T(".NumForwardRefSamples %d") _T(", ") 
1447                                                        _T(".NumBackwardRefSamples %d") _T(", ") 
1448                                                        _T(".DeinterlaceTechnology %d") _T(", ") 
1449                                                        _T(".ProcAmpControlCaps %d") _T(", ") 
1450                                                        _T(".VideoProcessorOperations %d") _T(", ") 
1451                                                        _T(".NoiseFilterTechnology %d") _T(", ") 
1452                                                        _T(".DetailFilterTechnology %d") _T(", ") 
1453                                                        _T("\n"), 
1454                                                        nGetVideoProcessorCapsResult, 
1455                                                        Capabilities.DeviceCaps,
1456                                                        //Capabilities.InputPool,
1457                                                        Capabilities.NumForwardRefSamples,
1458                                                        Capabilities.NumBackwardRefSamples,
1459                                                        Capabilities.DeinterlaceTechnology,
1460                                                        Capabilities.ProcAmpControlCaps,
1461                                                        Capabilities.VideoProcessorOperations,
1462                                                        Capabilities.NoiseFilterTechnology,
1463                                                        Capabilities.DetailFilterTechnology,
1464                                                        0);
1465                                        }
1466                                }
1467                                GUID Mode = GUID_NULL;
1468                                const HRESULT nGetVideoProcessorModeResult = pMfVideoProcessor->GetVideoProcessorMode(&Mode);
1469                                _Z4(atlTraceGeneral, 4, _T("nGetVideoProcessorModeResult 0x%08x\n"), nGetVideoProcessorModeResult);
1470                                if(SUCCEEDED(nGetVideoProcessorModeResult) && !(nGetVideoProcessorModeResult == S_FALSE && Mode == GUID_NULL))
1471                                        _Z4(atlTraceGeneral, 4, _T("Mode %s\n"), FormatDeinterlaceMode(Mode));
1472                        }
1473                        _ATLCATCHALL()
1474                        {
1475                                _Z_EXCEPTION();
1476                        }
1477                        #pragma endregion
1478                        return 0;
1479                }
1480                LRESULT OnPauseButtonClicked(UINT, INT, HWND)
1481                {
1482                        CWaitCursor WaitCursor;
1483                        __D(m_FilterGraph.m_pMediaControl, E_NOINTERFACE);
1484                        __C(m_FilterGraph.m_pMediaControl->Pause());
1485                        UpdateControls();
1486                        return 0;
1487                }
1488                LRESULT OnStopButtonClicked(UINT, INT, HWND)
1489                {
1490                        CWaitCursor WaitCursor;
1491                        if(m_FilterGraph.m_pMediaControl)
1492                                _V(m_FilterGraph.m_pMediaControl->Stop());
1493                        UpdateControls();
1494                        return 0;
1495                }
1496                LRESULT OnWeaveButtonClicked(UINT, INT, HWND)
1497                {
1498                        if(m_pSourceFilter)
1499                                m_pSourceFilter->SetWeave(m_WeaveButton.GetCheck());
1500                        return 0;
1501                }
1502                LRESULT OnColorizeButtonClicked(UINT, INT, HWND)
1503                {
1504                        if(m_pSourceFilter)
1505                                m_pSourceFilter->SetColorize(m_ColorizeButton.GetCheck());
1506                        return 0;
1507                }
1508                LRESULT OnFilterGraphEvent(UINT, WPARAM, LPARAM)
1509                {
1510                        if(!m_FilterGraph.m_pMediaEventEx)
1511                                return 0;
1512                        _ATLTRY
1513                        {
1514                                for(; ; )
1515                                {
1516                                        LONG nEventCode;
1517                                        LONG_PTR nParameter1, nParameter2;
1518                                        const HRESULT nGetEventResult = m_FilterGraph.m_pMediaEventEx->GetEvent(&nEventCode, &nParameter1, &nParameter2, 0);
1519                                        if(nGetEventResult == E_ABORT)
1520                                                break;
1521                                        __C(nGetEventResult);
1522                                        _ATLTRY
1523                                        {
1524                                                switch(nEventCode)
1525                                                {
1526                                                case EC_ERRORABORT:
1527                                                        _Z2(atlTraceGeneral, 2, _T("nEventCode EC_ERRORABORT 0x%02X, nParameter1 0x%08x, nParameter2 0x%08x\n"), nEventCode, nParameter1, nParameter2);
1528                                                        _A(FAILED(nParameter1));
1529                                                        AtlMessageBoxEx(m_hWnd, (LPCTSTR) AtlFormatString(_T("EC_ERRORABORT Event: %s."), AtlFormatSystemMessage((HRESULT) nParameter1).TrimRight(_T("\t\n\r ."))), IDS_ERROR, MB_ICONERROR | MB_OK);
1530                                                        break;
1531                                                default:
1532                                                        _Z1(atlTraceGeneral, 1, _T("nEventCode 0x%02X, nParameter1 0x%08x, nParameter2 0x%08x\n"), nEventCode, nParameter1, nParameter2);
1533                                                }
1534                                        }
1535                                        _ATLCATCHALL()
1536                                        {
1537                                                _V(m_FilterGraph.m_pMediaEventEx->FreeEventParams(nEventCode, nParameter1, nParameter2));
1538                                                _ATLRETHROW;
1539                                        }
1540                                        _V(m_FilterGraph.m_pMediaEventEx->FreeEventParams(nEventCode, nParameter1, nParameter2));
1541                                }
1542                        }
1543                        _ATLCATCHALL()
1544                        {
1545                                _Z_EXCEPTION();
1546                        }
1547                        return 0;
1548                }
1549                INT OnKillActive()
1550                {
1551                        m_StopButton.Click();
1552                        return 0;
1553                }
1554        };
1555
1556public:
1557        CVmr7PropertyPage m_Vmr7PropertyPage;
1558        CVmr9PropertyPage m_Vmr9PropertyPage;
1559        CEvrPropertyPage m_EvrPropertyPage;
1560
1561public:
1562// CMainPropertySheet
1563        CMainPropertySheet() :
1564                CSizablePropertySheetT<CMainPropertySheet>(_T("Render Interlaced Video")),
1565                m_Vmr7PropertyPage(this),
1566                m_Vmr9PropertyPage(this),
1567                m_EvrPropertyPage(this)
1568        {
1569                AddPage(m_Vmr7PropertyPage);
1570                AddPage(m_Vmr9PropertyPage);
1571                AddPage(m_EvrPropertyPage);
1572        }
1573        BOOL SetInitialPosition()
1574        {
1575                if(!__super::SetInitialPosition())
1576                        return FALSE;
1577                _W(PostMessage(WM_SETLARGERINITIALPOSITION));
1578                return TRUE;
1579        }
1580        static CString FormatDeinterlaceMode(const GUID& DeinterlaceMode)
1581        {
1582                // NOTE: Windows SDK does not provide a linkable identifier...
1583                #pragma region VMR-7/9
1584                struct __declspec(uuid("{335aa36e-7884-43a4-9c91-7f87faf3e37e}")) DXVA_DeinterlaceBobDevice;
1585                struct __declspec(uuid("{0e85cb93-3046-4ff0-aecc-d58cb5f035fd}")) DXVA_DeinterlaceContainerDevice;
1586                if(DeinterlaceMode == __uuidof(DXVA_DeinterlaceBobDevice))
1587                        return _T("DXVA_DeinterlaceBobDevice");
1588                if(DeinterlaceMode == __uuidof(DXVA_DeinterlaceContainerDevice))
1589                        return _T("DXVA_DeinterlaceContainerDevice");
1590                #pragma endregion
1591                #pragma region EVR, DXVA2
1592                struct __declspec(uuid("{5a54a0c9-c7ec-4bd9-8ede-f3c75dc4393b}")) DXVA2_VideoProcProgressiveDevice;
1593                struct __declspec(uuid("{335aa36e-7884-43a4-9c91-7f87faf3e37e}")) DXVA2_VideoProcBobDevice;
1594                struct __declspec(uuid("{4553d47f-ee7e-4e3f-9475-dbf1376c4810}")) DXVA2_VideoProcSoftwareDevice;
1595                if(DeinterlaceMode == __uuidof(DXVA2_VideoProcProgressiveDevice))
1596                        return _T("DXVA2_VideoProcProgressiveDevice");
1597                if(DeinterlaceMode == __uuidof(DXVA2_VideoProcBobDevice))
1598                        return _T("DXVA2_VideoProcBobDevice");
1599                if(DeinterlaceMode == __uuidof(DXVA2_VideoProcSoftwareDevice))
1600                        return _T("DXVA2_VideoProcSoftwareDevice");
1601                return CString(_PersistHelper::StringFromIdentifier(DeinterlaceMode));
1602        }
1603
1604// Window Message Handelrs
1605        LRESULT OnSetLargerInitialPosition(UINT, WPARAM, LPARAM)
1606        {
1607                CRect Position;
1608                _W(GetWindowRect(Position));
1609                Position.right += Position.Width();
1610                Position.bottom += Position.Height() / 4;
1611                _W(SetWindowPos(NULL, Position, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE));
1612                _W(CenterWindow());
1613                return 0;
1614        }
1615};
Note: See TracBrowser for help on using the repository browser.