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

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

Sample to find largest video media sample in media file

  • Property svn:keywords set to Id
File size: 9.4 KB
Line 
1////////////////////////////////////////////////////////////
2// Copyright (C) Roman Ryltsov, 2008-2011
3// Created by Roman Ryltsov roman@alax.info
4//
5// $Id: FindLargestMediaSample.cpp 3 2011-08-16 21:15:30Z 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<IMediaEventEx> m_pMediaEventEx;
154        CComPtr<IMediaControl> m_pMediaControl;
155
156public:
157// CModule
158        CModule() throw()
159        {
160#if defined(_DEBUG)
161                AtlTraceLoadSettings(NULL);
162#endif // defined(_DEBUG)
163                ATLTRACE(atlTraceRefcount, 4, _T("this 0x%p\n"), this);
164        }
165        ~CModule() throw()
166        {
167                ATLTRACE(atlTraceRefcount, 4, _T("this 0x%p\n"), this);
168        }
169        VOID SetPath(LPCTSTR pszPath)
170        {
171                ATLENSURE_THROW(!_tcslen(m_sPath), E_INVALIDARG);
172                m_sPath = pszPath;
173        }
174        static CComPtr<IPin> GetFilterPin(IBaseFilter* pBaseFilter, PIN_DIRECTION Direction)
175        {
176                if(pBaseFilter)
177                {
178                        CComPtr<IEnumPins> pEnumPins;
179                        ATLENSURE_SUCCEEDED(pBaseFilter->EnumPins(&pEnumPins));
180                        CComPtr<IPin> pPin;
181                        while(pEnumPins->Next(1, &pPin, NULL) == S_OK)
182                        {
183                                PIN_DIRECTION PinDirection;
184                                ATLENSURE_SUCCEEDED(pPin->QueryDirection(&PinDirection));
185                                if(PinDirection == Direction)
186                                        return pPin;
187                                pPin = NULL;
188                        }
189                }
190                return NULL;
191        }
192        HRESULT Run(INT nShowCommand = SW_HIDE)
193        {
194                ATLENSURE_THROW(_tcslen(m_sPath), E_INVALIDARG);
195                _tprintf(_T("Using Source File: %s\n"), m_sPath);
196                ATLENSURE_SUCCEEDED(m_pFilterGraph.CoCreateInstance(CLSID_FilterGraph));
197                m_pMediaEventEx = CComQIPtr<IMediaEventEx>(m_pFilterGraph);
198                m_pMediaControl = CComQIPtr<IMediaControl>(m_pFilterGraph);
199                ATLENSURE_THROW(m_pMediaEventEx && m_pMediaControl, E_NOINTERFACE);
200                _ATLTRY
201                {       
202                        CComPtr<IPin> pCurrentOutputPin;
203                        #pragma region Source
204                        CComPtr<IBaseFilter> pSourceBaseFilter;
205                        ATLENSURE_SUCCEEDED(m_pFilterGraph->AddSourceFilter(CT2CW(m_sPath), CT2CW(_T("Source")), &pSourceBaseFilter));
206                        pCurrentOutputPin = GetFilterPin(pSourceBaseFilter, PINDIR_OUTPUT);
207                        #pragma endregion
208                        #pragma region Inspection Filter
209                        CComPtr<IBaseFilter> pInspectionBaseFilter;
210                        ATLENSURE_SUCCEEDED(pInspectionBaseFilter.CoCreateInstance(__uuidof(InspectionFilter)));
211                        ATLENSURE_SUCCEEDED(m_pFilterGraph->AddFilter(pInspectionBaseFilter, CT2CW(_T("Inspection"))));
212                        #pragma region Site
213                        CComQIPtr<IInspectionFilter> pInspectionFilter = pInspectionBaseFilter;
214                        CComObject<CInspectionFilterSite>* pInspectionFilterSite = NULL;
215                        ATLENSURE_SUCCEEDED(CComObject<CInspectionFilterSite>::CreateInstance(&pInspectionFilterSite));
216                        pInspectionFilterSite->Initialize(this);
217                        ATLENSURE_SUCCEEDED(pInspectionFilter->SetSite(pInspectionFilterSite));
218                        m_pInspectionFilterSite = pInspectionFilterSite;
219                        #pragma endregion
220                        ATLENSURE_SUCCEEDED(m_pFilterGraph->Connect(pCurrentOutputPin, GetFilterPin(pInspectionBaseFilter, PINDIR_INPUT)));
221                        pCurrentOutputPin = GetFilterPin(pInspectionBaseFilter, PINDIR_OUTPUT);
222                        #pragma endregion
223                        #pragma region Renderer
224                        CComPtr<IBaseFilter> pRendererBaseFilter;
225                        typedef struct __declspec(uuid("C1F400A4-3F08-11D3-9F0B-006008039E37")) _NullRenderer { } NullRenderer;
226                        ATLENSURE_SUCCEEDED(pRendererBaseFilter.CoCreateInstance(__uuidof(NullRenderer)));
227                        ATLENSURE_SUCCEEDED(m_pFilterGraph->AddFilter(pRendererBaseFilter, CT2CW(_T("Renderer"))));
228                        ATLENSURE_SUCCEEDED(m_pFilterGraph->Connect(pCurrentOutputPin, GetFilterPin(pRendererBaseFilter, PINDIR_INPUT)));
229                        pCurrentOutputPin = NULL;
230                        #pragma endregion
231                        ATLASSERT(!pCurrentOutputPin);
232                        //AtlMessageBox(GetActiveWindow(), _T("Break In"), _T("Debug"), MB_ICONERROR | MB_OK);
233                }
234                _ATLCATCH(Exception)
235                {
236                        Exception;
237#if _DEVELOPMENT
238                        AtlMessageBox(GetActiveWindow(), (LPCTSTR) AtlFormatString(_T("Error 0x%08x - Break In"), (HRESULT) Exception), _T("Debug"), MB_ICONERROR | MB_OK);
239#endif // _DEVELOPMENT
240                        _ATLRETHROW;
241                }
242                #pragma region Remove Reference Clock
243                CComQIPtr<IMediaFilter> pMediaFilter = m_pFilterGraph;
244                ATLENSURE_THROW(pMediaFilter, E_NOINTERFACE);
245                ATLENSURE_SUCCEEDED(pMediaFilter->SetSyncSource(NULL));
246                #pragma endregion
247                _tprintf(_T("Running Filter Graph\n"));
248                ATLENSURE_SUCCEEDED(m_pMediaControl->Run());
249                LONG nEventCode = 0;
250                ATLENSURE_SUCCEEDED(m_pMediaEventEx->WaitForCompletion(INFINITE, &nEventCode));
251                _tprintf(_T("Completion: Code 0x%02x\n"), nEventCode); // EC_COMPLETE 0x01
252                _tprintf(_T("Largest Video Media Sample Data Size: %d\n"), m_pInspectionFilterSite->GetMaximalDataSize());
253                #pragma region Terminate
254                ATLVERIFY(SUCCEEDED(m_pMediaControl->Stop()));
255                m_pMediaEventEx = NULL;
256                m_pMediaControl = NULL;
257                m_pInspectionFilterSite->Terminate();
258                m_pInspectionFilterSite = NULL;
259                m_pFilterGraph = NULL;
260                #pragma endregion
261                return S_OK;
262        }
263};
264
265////////////////////////////////////////////////////////////
266// Main
267
268int _tmain(int argc, _TCHAR* argv[])
269{
270        ATLVERIFY(SUCCEEDED(CoInitialize(NULL)));
271        _ATLTRY
272        {
273                CModule Module;
274                ATLENSURE_THROW(argc >= 2, E_INVALIDARG);
275                const CPath sPath = argv[1];
276                Module.SetPath(sPath);
277                Module.Run();
278        }
279        _ATLCATCH(Exception)
280        {
281                _tprintf(_T("Fatal Error 0x%08x\n"), (HRESULT) Exception);
282        }
283        _ATLCATCHALL()
284        {
285                _tprintf(_T("Fatal Error\n"));
286        }
287        CoUninitialize();
288        return 0;
289}
290
Note: See TracBrowser for help on using the repository browser.