source: trunk/DirectShowSpy/Helper.cpp @ 441

Last change on this file since 441 was 441, checked in by roman, 7 years ago

Added filtering in media sample trace UI; fixed thread safety problem; fixed file mapping initialization issue; removed media sample leak feature (to extend file mapping lifetime) and replaced with file mapping ownership transfer to UI process; added menu item to jump right to filter graph

File size: 8.0 KB
Line 
1////////////////////////////////////////////////////////////
2// Copyright (C) Roman Ryltsov, 2008-2015
3// Created by Roman Ryltsov roman@alax.info, http://alax.info
4//
5// This source code is published to complement DirectShowSpy developer powertoy
6// and demonstrate the internal use of APIs and tricks powering the tool. It is
7// allowed to freely re-use the portions of the code in other projects, commercial
8// or otherwise (provided that you don’t pretend that you wrote the original tool).
9//
10// Please keep in mind that DirectShowSpy is a developer tool, it is strongly recommended
11// that it is not shipped with release grade software. It is allowed to distribute
12// DirectShowSpy if only it is not registered with Windows by default and either
13// used privately, or registered on specific throubleshooting request. The advice applies
14// to hooking methods used by DirectShowSpy in general as well.
15
16#include "stdafx.h"
17#include "resource.h"
18#include "FilterGraphHelper.h"
19#include "MediaSampleTrace.h"
20
21////////////////////////////////////////////////////////////
22// Test
23
24#if _DEVELOPMENT && FALSE
25
26COMPILER_MESSAGE("Development: CFilterGraphHelper::DoPropertyFrameModal as Test")
27
28#if defined(_WIN64)
29        extern "C" __declspec(dllexport) 
30#else
31        #pragma comment(linker, "/EXPORT:Test=_Test@0,PRIVATE")
32        extern "C" // __declspec(dllexport)
33#endif // defined(_WIN64)
34
35HRESULT STDMETHODCALLTYPE Test()
36{
37        _ATLTRY
38        {
39                CSingleThreadedApartment SingleThreadedApartment;
40                CGenericFilterGraph FilterGraph;
41                FilterGraph.CoCreateInstance();
42                __C(FilterGraph.m_pFilterGraph->RenderFile(_T("E:\\Media\\Robotica_1080.wmv"), NULL));
43                _ATLTRY
44                {
45                        const CComQIPtr<ISpy> pSpy = FilterGraph.m_pFilterGraph;
46                        if(pSpy)
47                                __C(pSpy->put_FriendlyName(CComBSTR(_T("Test"))));
48                }
49                _ATLCATCHALL()
50                {
51                        _Z_EXCEPTION();
52                }
53                CLocalObjectPtr<CFilterGraphHelper> pHelper;
54                pHelper->SetFilterGraph(FilterGraph.m_pFilterGraph);
55                pHelper->DoPropertyFrameModal(0);
56        }
57        _ATLCATCH(Exception)
58        {
59                _C(Exception);
60        }
61        return S_OK;
62}
63
64#endif // _DEVELOPMENT
65
66#if _DEVELOPMENT //&& FALSE
67
68COMPILER_MESSAGE("Development: MediaSampleTrace test as Test")
69
70////////////////////////////////////////////////////////////
71// CRendererFilter
72
73class ATL_NO_VTABLE CRendererFilter :
74        public CComObjectRootEx<CComMultiThreadModelNoCS>,
75        //public CComCoClass<CRendererFilter>,
76        public CBaseFilterT<CRendererFilter>,
77        public CBasePersistT<CRendererFilter>,
78        public CAmFilterMiscFlagsT<CRendererFilter, AM_FILTER_MISC_FLAGS_IS_RENDERER>,
79        public CUpstreamMediaPositionAwareRendererFilterT<CRendererFilter>
80{
81public:
82        //enum { IDR = };
83
84DECLARE_NO_REGISTRY() //DECLARE_REGISTRY_RESOURCEID(IDR)
85
86DECLARE_PROTECT_FINAL_CONSTRUCT()
87
88//DECLARE_QI_TRACE(CRendererFilter)
89
90BEGIN_COM_MAP(CRendererFilter)
91        COM_INTERFACE_ENTRY(IBaseFilter)
92        COM_INTERFACE_ENTRY(IMediaFilter)
93        COM_INTERFACE_ENTRY_IID(__uuidof(IPersist), IBaseFilter)
94        COM_INTERFACE_ENTRY(IAMFilterMiscFlags)
95        COM_INTERFACE_ENTRY_FUNC(__uuidof(IMediaSeeking), 0, QueryUpstreamMediaPositionInterface)
96        COM_INTERFACE_ENTRY_FUNC(__uuidof(IDispatch), 0, QueryUpstreamMediaPositionInterface)
97        COM_INTERFACE_ENTRY_FUNC(__uuidof(IMediaPosition), 0, QueryUpstreamMediaPositionInterface)
98END_COM_MAP()
99
100public:
101
102        ////////////////////////////////////////////////////////
103        // CInputPin
104
105        class ATL_NO_VTABLE CInputPin :
106                public CComObjectRootEx<CComMultiThreadModelNoCS>,
107                public CInputPinT<CInputPin, CRendererFilter>
108        {
109        public:
110
111        //DECLARE_QI_TRACE(CRendererFilter::CInputPin)
112
113        BEGIN_COM_MAP(CInputPin)
114                COM_INTERFACE_ENTRY(IPin)
115                COM_INTERFACE_ENTRY(IMemInputPin)
116        END_COM_MAP()
117
118        public:
119        // CInputPin
120                CInputPin()
121                {
122                        _Z5_THIS();
123                }
124                ~CInputPin()
125                {
126                        _Z5_THIS();
127                }
128                BOOL CheckMediaType(const CMediaType& pMediaType) const
129                {
130                        _A(pMediaType);
131                        return TRUE;
132                }
133        };
134
135private:
136        CObjectPtr<CInputPin> m_pInputPin;
137        mutable CRoCriticalSection m_ReceiveCriticalSection;
138        CComPtr<IMediaSampleTrace> m_pMediaSampleTrace;
139
140public:
141// CRendererFilter
142        CRendererFilter() :
143                CBasePersistT<CRendererFilter>(GetDataCriticalSection())
144        {
145                _Z4_THIS();
146        }
147        ~CRendererFilter()
148        {
149                _Z4_THIS();
150        }
151        HRESULT FinalConstruct()
152        {
153                _ATLTRY
154                {
155                        m_pInputPin.Construct()->Initialize(this, L"Input");
156                        AddPin(m_pInputPin);
157                        CreateUpstreamMediaPosition();
158                }
159                _ATLCATCH(Exception)
160                {
161                        _C(Exception);
162                }
163                return S_OK;
164        }
165        VOID FinalRelease()
166        {
167                DestroyUpstreamMediaPosition();
168                m_pInputPin.Release();
169        }
170        VOID DeliverNewSegment(IPin*, REFERENCE_TIME nStartTime, REFERENCE_TIME nStopTime, DOUBLE fRate)
171        {
172                CRoCriticalSectionLock ReceiveLock(m_ReceiveCriticalSection);
173                if(m_pMediaSampleTrace)
174                        _V(m_pMediaSampleTrace->RegisterNewSegment((IBaseFilter*) this, L"Main", nStartTime, nStopTime, fRate, NULL));
175        }
176        VOID DeliverEndOfStream(CInputPin*)
177        {
178                CRoCriticalSectionLock ReceiveLock(m_ReceiveCriticalSection);
179                if(m_pMediaSampleTrace)
180                        _V(m_pMediaSampleTrace->RegisterEndOfStream((IBaseFilter*) this, L"Main", L"That's All!"));
181                NotifyComplete(S_OK);
182        }
183        VOID CueFilter()
184        {
185                CRoCriticalSectionLock ReceiveLock(m_ReceiveCriticalSection);
186                CRoCriticalSectionLock DataLock(GetDataCriticalSection());
187                if(!m_pInputPin->IsPeerPinAvailable())
188                {
189                        NotifyComplete(S_FALSE);
190                        return;
191                }
192                const CComQIPtr<ISpy> pSpy = GetFilterGraph();
193                _A(pSpy);
194                CComPtr<IMediaSampleTrace> pMediaSampleTrace;
195                __C(pSpy->CreateMediaSampleTrace(&pMediaSampleTrace));
196                m_pMediaSampleTrace = pMediaSampleTrace;
197        }
198        VOID StopFilter()
199        {
200                CRoCriticalSectionLock ReceiveLock(m_ReceiveCriticalSection);
201                CRoCriticalSectionLock DataLock(GetDataCriticalSection());
202                m_pMediaSampleTrace.Release();
203        }
204        VOID ReceiveMediaSample(CInputPin* pInputPin, IMediaSample2* pMediaSample, HRESULT& nReceiveResult)
205        {
206                CRoCriticalSectionLock ReceiveLock(m_ReceiveCriticalSection);
207                CMediaSampleProperties Properties(pMediaSample);
208                CRoCriticalSectionLock DataLock(GetDataCriticalSection());
209                if(m_pMediaSampleTrace)
210                        _V(m_pMediaSampleTrace->RegisterMediaSample((IBaseFilter*) this, L"Main", (BYTE*) (AM_SAMPLE2_PROPERTIES*) &Properties, NULL));
211                nReceiveResult = S_OK;
212        }
213        const CObjectPtr<CInputPin>& GetInputPin() const
214        {
215                return m_pInputPin;
216        }
217};
218
219#if defined(_WIN64)
220        extern "C" __declspec(dllexport) 
221#else
222        #pragma comment(linker, "/EXPORT:Test=_Test@0,PRIVATE")
223        extern "C" // __declspec(dllexport)
224#endif // defined(_WIN64)
225
226HRESULT STDMETHODCALLTYPE Test()
227{
228        _ATLTRY
229        {
230                CSingleThreadedApartment SingleThreadedApartment;
231                CGenericFilterGraph FilterGraph;
232                FilterGraph.CoCreateInstance();
233                const CComPtr<IBaseFilter> pSourceBaseFilter = FilterGraph.AddSourceFilter(
234                        _T("E:\\Media\\Robotica_1080.wmv")
235                        //_T("E:\\Media\\Windows Phone - Design for Developers.mp4")
236                        );
237                CComPtr<IPin> pOutputPin = _FilterGraphHelper::GetFilterPin(pSourceBaseFilter, PINDIR_OUTPUT);
238                if(FALSE)
239                {
240                        class __declspec(uuid("{025BE2E4-1787-4DA4-A585-C5B2B9EEB57C}")) Demultiplexer;
241                        CComPtr<IBaseFilter> pBaseFilter;
242                        __C(pBaseFilter.CoCreateInstance(__uuidof(Demultiplexer)));
243                        __C(FilterGraph.AddFilter(pBaseFilter, _T("Demultiplexer")));
244                        __C(FilterGraph.Connect(pOutputPin, _FilterGraphHelper::GetFilterPin(pBaseFilter, PINDIR_INPUT)));
245                        pOutputPin = _FilterGraphHelper::GetFilterPin(pBaseFilter, PINDIR_OUTPUT);
246                }
247                CObjectPtr<CRendererFilter> pRendererFilter;
248                pRendererFilter.Construct();
249                __C(FilterGraph.AddFilter(pRendererFilter, _T("Renderer")));
250                __C(FilterGraph.Connect(pOutputPin, pRendererFilter->GetInputPin()));
251                __C(FilterGraph.m_pMediaFilter->SetSyncSource(NULL));
252                const CComQIPtr<ISpy> pSpy = FilterGraph.m_pFilterGraph;
253                _A(pSpy);
254                __C(pSpy->put_FriendlyName(CComBSTR(_T("Test"))));
255                __C(FilterGraph.m_pMediaControl->Run());
256                __C(FilterGraph.WaitForCompletionDispatchingMessages());
257                CMediaSampleTracePropertySheet PropertySheet;
258                PropertySheet.DoModal(GetActiveWindow());
259        }
260        _ATLCATCH(Exception)
261        {
262                _C(Exception);
263        }
264        return S_OK;
265}
266
267#endif // _DEVELOPMENT
Note: See TracBrowser for help on using the repository browser.