source: trunk/DirectShowTools/Samples/FindLargestMediaSample/FindLargestMediaSample.cpp @ 4

Last change on this file since 4 was 4, checked in by roman, 13 years ago
  • Property svn:keywords set to Id
File size: 9.5 KB
Line 
1////////////////////////////////////////////////////////////
2// Copyright (C) Roman Ryltsov, 2008-2011
3// Created by Roman Ryltsov roman@alax.info
4//
5// $Id: FindLargestMediaSample.cpp 4 2011-08-16 21:47:23Z roman $
6
7#include "stdafx.h"
8#include <dshow.h>
9#import "libid:C8D585EA-23F9-4D3E-9727-23CD02ED96C7" no_namespace raw_interfaces_only named_guids
10#pragma comment(lib, "strmiids.lib")
11
12////////////////////////////////////////////////////////////
13// CModule
14
15class CModule : 
16        public CAtlExeModuleT<CModule>
17{
18public:
19
20        ////////////////////////////////////////////////////////
21        // CInspectionFilterSite
22
23        class ATL_NO_VTABLE CInspectionFilterSite :
24                public CComObjectRootEx<CComMultiThreadModelNoCS>,
25                public IInspectionFilterSite
26        {
27        public:
28
29        BEGIN_COM_MAP(CInspectionFilterSite)
30                COM_INTERFACE_ENTRY(IInspectionFilterSite)
31        END_COM_MAP()
32
33        private:
34                mutable CComAutoCriticalSection m_DataCriticalSection;
35                CModule* m_pOwner;
36                SIZE_T m_nMaximalDataSize;
37                REFERENCE_TIME m_nLastReportTime;
38
39        public:
40        // CInspectionFilterSite
41                CInspectionFilterSite() throw() :
42                        m_pOwner(NULL)
43                {
44                        ATLTRACE(atlTraceRefcount, 4, _T("this 0x%p\n"), this);
45                }
46                ~CInspectionFilterSite() throw()
47                {
48                        ATLTRACE(atlTraceRefcount, 4, _T("this 0x%p\n"), this);
49                        ATLASSERT(!m_pOwner);
50                }
51                VOID Initialize(CModule* pOwner)
52                {
53                        ATLASSERT(pOwner);
54                        CComCritSecLock<CComAutoCriticalSection> DataLock(m_DataCriticalSection);
55                        m_pOwner = pOwner;
56                        m_nMaximalDataSize = 0;
57                        m_nLastReportTime = 0;
58                }
59                VOID Terminate() throw()
60                {
61                        CComCritSecLock<CComAutoCriticalSection> DataLock(m_DataCriticalSection);
62                        m_pOwner = NULL;
63                }
64                SIZE_T GetMaximalDataSize() const throw()
65                {
66                        CComCritSecLock<CComAutoCriticalSection> DataLock(m_DataCriticalSection);
67                        return m_nMaximalDataSize;
68                }
69
70        // IInspectionFilterSite
71                STDMETHOD(EnumerateMediaTypes)(BYTE** ppnMediaTypes, ULONG* pnMediaTypeCount) throw()
72                {
73                        ATLTRACE(atlTraceCOM, 4, _T("...\n"));
74                        _ATLTRY
75                        {
76                                ATLENSURE_THROW(ppnMediaTypes && pnMediaTypeCount, E_POINTER);
77                                CComHeapPtr<AM_MEDIA_TYPE*> ppMediaTypes;
78                                ATLENSURE_THROW(ppMediaTypes.Allocate(1), E_OUTOFMEMORY);
79                                AM_MEDIA_TYPE* pMediaType = ppMediaTypes[0];
80                                {
81                                        CComHeapPtr<AM_MEDIA_TYPE> pMediaType;
82                                        ATLENSURE_THROW(pMediaType.Allocate(1), E_OUTOFMEMORY);
83                                        ZeroMemory(pMediaType, sizeof *pMediaType);
84                                        pMediaType->majortype = MEDIATYPE_Video;
85                                        pMediaType->subtype = MEDIASUBTYPE_NULL;
86                                        ppMediaTypes[0] = pMediaType.Detach();
87                                }
88                                *ppnMediaTypes = (BYTE*) ppMediaTypes.Detach();
89                                *pnMediaTypeCount = 1;
90                        }
91                        _ATLCATCH(Exception)
92                        {
93                                return Exception;
94                        }
95                        return S_OK;
96                }
97                STDMETHOD(CheckMediaType)(BYTE* pnMediaType) throw()
98                {
99                        ATLTRACE(atlTraceCOM, 4, _T("...\n"));
100                        _ATLTRY
101                        {
102                                const AM_MEDIA_TYPE* pMediaType = reinterpret_cast<const AM_MEDIA_TYPE*>(pnMediaType);
103                                if(pMediaType->majortype != MEDIATYPE_Video)
104                                        return S_FALSE; // Not Video
105                        }
106                        _ATLCATCH(Exception)
107                        {
108                                return Exception;
109                        }
110                        return S_OK;
111                }
112                STDMETHOD(HandleMediaSample)(IUnknown* pMediaSampleUnknown) throw()
113                {
114                        ATLTRACE(atlTraceCOM, 4, _T("...\n"));
115                        _ATLTRY
116                        {
117                                const CComQIPtr<IMediaSample> pMediaSample = pMediaSampleUnknown;
118                                ATLASSERT(pMediaSample);
119                                CComCritSecLock<CComAutoCriticalSection> DataLock(m_DataCriticalSection);
120                                const SIZE_T nDataSize = (SIZE_T) pMediaSample->GetActualDataLength();
121                                if(nDataSize > m_nMaximalDataSize)
122                                        m_nMaximalDataSize = nDataSize;
123                                #pragma region Report Time
124                                REFERENCE_TIME nStartTime, nStopTime;
125                                const HRESULT nGetTimeResult = pMediaSample->GetTime(&nStartTime, &nStopTime);
126                                if(SUCCEEDED(nGetTimeResult))
127                                        if(nStartTime > m_nLastReportTime + 60 * 1000 * 10000i64)
128                                        {
129                                                m_nLastReportTime = nStartTime;
130                                                nStartTime /= 1000 * 10000i64;
131                                                const INT nHours = (INT) (nStartTime / (60 * 60));
132                                                nStartTime -= nHours * (60 * 60);
133                                                const INT nMinutes = (INT) (nStartTime / (60));
134                                                nStartTime -= nMinutes * (60);
135                                                const INT nSeconds = (INT) nStartTime;
136                                                _tprintf(_T("Progress: %02d:%02d:%02d, Currently Largest Video Media Sample Data Size: %d\n"), nHours, nMinutes, nSeconds, m_nMaximalDataSize);
137                                        }
138                                #pragma endregion
139                        }
140                        _ATLCATCH(Exception)
141                        {
142                                return Exception;
143                        }
144                        return S_OK;
145                }
146        };
147
148private:
149        CPath m_sPath;
150        BOOL m_bSuppressCompressorPropertyPages;
151        CComPtr<IFilterGraph2> m_pFilterGraph;
152        CComObject<CInspectionFilterSite>* m_pInspectionFilterSite;
153        CComPtr<IUnknown> m_pInspectionFilterSiteUnknown;
154        CComPtr<IMediaEventEx> m_pMediaEventEx;
155        CComPtr<IMediaControl> m_pMediaControl;
156
157public:
158// CModule
159        CModule() throw()
160        {
161#if defined(_DEBUG)
162                AtlTraceLoadSettings(NULL);
163#endif // defined(_DEBUG)
164                ATLTRACE(atlTraceRefcount, 4, _T("this 0x%p\n"), this);
165        }
166        ~CModule() throw()
167        {
168                ATLTRACE(atlTraceRefcount, 4, _T("this 0x%p\n"), this);
169        }
170        VOID SetPath(LPCTSTR pszPath)
171        {
172                ATLENSURE_THROW(!_tcslen(m_sPath), E_INVALIDARG);
173                m_sPath = pszPath;
174        }
175        static CComPtr<IPin> GetFilterPin(IBaseFilter* pBaseFilter, PIN_DIRECTION Direction)
176        {
177                if(pBaseFilter)
178                {
179                        CComPtr<IEnumPins> pEnumPins;
180                        ATLENSURE_SUCCEEDED(pBaseFilter->EnumPins(&pEnumPins));
181                        CComPtr<IPin> pPin;
182                        while(pEnumPins->Next(1, &pPin, NULL) == S_OK)
183                        {
184                                PIN_DIRECTION PinDirection;
185                                ATLENSURE_SUCCEEDED(pPin->QueryDirection(&PinDirection));
186                                if(PinDirection == Direction)
187                                        return pPin;
188                                pPin = NULL;
189                        }
190                }
191                return NULL;
192        }
193        HRESULT Run(INT nShowCommand = SW_HIDE)
194        {
195                ATLENSURE_THROW(_tcslen(m_sPath), E_INVALIDARG);
196                _tprintf(_T("Using Source File: %s\n"), m_sPath);
197                ATLENSURE_SUCCEEDED(m_pFilterGraph.CoCreateInstance(CLSID_FilterGraph));
198                m_pMediaEventEx = CComQIPtr<IMediaEventEx>(m_pFilterGraph);
199                m_pMediaControl = CComQIPtr<IMediaControl>(m_pFilterGraph);
200                ATLENSURE_THROW(m_pMediaEventEx && m_pMediaControl, E_NOINTERFACE);
201                _ATLTRY
202                {       
203                        CComPtr<IPin> pCurrentOutputPin;
204                        #pragma region Source
205                        CComPtr<IBaseFilter> pSourceBaseFilter;
206                        ATLENSURE_SUCCEEDED(m_pFilterGraph->AddSourceFilter(CT2CW(m_sPath), CT2CW(_T("Source")), &pSourceBaseFilter));
207                        pCurrentOutputPin = GetFilterPin(pSourceBaseFilter, PINDIR_OUTPUT);
208                        #pragma endregion
209                        #pragma region Inspection Filter
210                        CComPtr<IBaseFilter> pInspectionBaseFilter;
211                        ATLENSURE_SUCCEEDED(pInspectionBaseFilter.CoCreateInstance(__uuidof(InspectionFilter)));
212                        ATLENSURE_SUCCEEDED(m_pFilterGraph->AddFilter(pInspectionBaseFilter, CT2CW(_T("Inspection"))));
213                        #pragma region Site
214                        CComQIPtr<IInspectionFilter> pInspectionFilter = pInspectionBaseFilter;
215                        CComObject<CInspectionFilterSite>* pInspectionFilterSite = NULL;
216                        ATLENSURE_SUCCEEDED(CComObject<CInspectionFilterSite>::CreateInstance(&pInspectionFilterSite));
217                        pInspectionFilterSite->Initialize(this);
218                        ATLENSURE_SUCCEEDED(pInspectionFilter->SetSite(pInspectionFilterSite));
219                        m_pInspectionFilterSiteUnknown = pInspectionFilterSite;
220                        m_pInspectionFilterSite = pInspectionFilterSite;
221                        #pragma endregion
222                        ATLENSURE_SUCCEEDED(m_pFilterGraph->Connect(pCurrentOutputPin, GetFilterPin(pInspectionBaseFilter, PINDIR_INPUT)));
223                        pCurrentOutputPin = GetFilterPin(pInspectionBaseFilter, PINDIR_OUTPUT);
224                        #pragma endregion
225                        #pragma region Renderer
226                        CComPtr<IBaseFilter> pRendererBaseFilter;
227                        typedef struct __declspec(uuid("C1F400A4-3F08-11D3-9F0B-006008039E37")) _NullRenderer { } NullRenderer;
228                        ATLENSURE_SUCCEEDED(pRendererBaseFilter.CoCreateInstance(__uuidof(NullRenderer)));
229                        ATLENSURE_SUCCEEDED(m_pFilterGraph->AddFilter(pRendererBaseFilter, CT2CW(_T("Renderer"))));
230                        ATLENSURE_SUCCEEDED(m_pFilterGraph->Connect(pCurrentOutputPin, GetFilterPin(pRendererBaseFilter, PINDIR_INPUT)));
231                        pCurrentOutputPin = NULL;
232                        #pragma endregion
233                        ATLASSERT(!pCurrentOutputPin);
234                        //AtlMessageBox(GetActiveWindow(), _T("Break In"), _T("Debug"), MB_ICONERROR | MB_OK);
235                }
236                _ATLCATCH(Exception)
237                {
238                        Exception;
239#if _DEVELOPMENT
240                        AtlMessageBox(GetActiveWindow(), (LPCTSTR) AtlFormatString(_T("Error 0x%08x - Break In"), (HRESULT) Exception), _T("Debug"), MB_ICONERROR | MB_OK);
241#endif // _DEVELOPMENT
242                        _ATLRETHROW;
243                }
244                #pragma region Remove Reference Clock
245                {
246                        const CComQIPtr<IMediaFilter> pMediaFilter = m_pFilterGraph;
247                        ATLENSURE_THROW(pMediaFilter, E_NOINTERFACE);
248                        ATLENSURE_SUCCEEDED(pMediaFilter->SetSyncSource(NULL));
249                }
250                #pragma endregion
251                _tprintf(_T("Running Filter Graph\n"));
252                ATLENSURE_SUCCEEDED(m_pMediaControl->Run());
253                LONG nEventCode = 0;
254                ATLENSURE_SUCCEEDED(m_pMediaEventEx->WaitForCompletion(INFINITE, &nEventCode));
255                _tprintf(_T("Completion: Code 0x%02x\n"), nEventCode); // EC_COMPLETE 0x01
256                _tprintf(_T("Largest Video Media Sample Data Size: %d\n"), m_pInspectionFilterSite->GetMaximalDataSize());
257                #pragma region Terminate
258                ATLVERIFY(SUCCEEDED(m_pMediaControl->Stop()));
259                m_pMediaEventEx = NULL;
260                m_pMediaControl = NULL;
261                m_pFilterGraph = NULL;
262                m_pInspectionFilterSite->Terminate();
263                m_pInspectionFilterSite = NULL;
264                m_pInspectionFilterSiteUnknown = NULL;
265                #pragma endregion
266                return S_OK;
267        }
268};
269
270////////////////////////////////////////////////////////////
271// Main
272
273int _tmain(int argc, _TCHAR* argv[])
274{
275        ATLVERIFY(SUCCEEDED(CoInitialize(NULL)));
276        _ATLTRY
277        {
278                CModule Module;
279                ATLENSURE_THROW(argc >= 2, E_INVALIDARG);
280                const CPath sPath = argv[1];
281                Module.SetPath(sPath);
282                Module.Run();
283        }
284        _ATLCATCH(Exception)
285        {
286                _tprintf(_T("Fatal Error 0x%08x\n"), (HRESULT) Exception);
287        }
288        _ATLCATCHALL()
289        {
290                _tprintf(_T("Fatal Error\n"));
291        }
292        CoUninitialize();
293        return 0;
294}
295
Note: See TracBrowser for help on using the repository browser.