source: trunk/Utilities/DumpMediaSamples/DumpMediaSamples.cpp @ 142

Last change on this file since 142 was 142, checked in by roman, 11 years ago
  • Property svn:keywords set to Id
File size: 19.3 KB
Line 
1////////////////////////////////////////////////////////////
2// Copyright (C) Roman Ryltsov, 2006-2012
3// Created by Roman Ryltsov roman@alax.info
4//
5// A permission to use the source code is granted as long as reference to
6// source website http://alax.info is retained.
7//
8// $Id: DumpMediaSamples.cpp 142 2012-11-15 19:37:46Z roman $
9
10#include "stdafx.h"
11//#include <qedit.h>
12#include "rodshow.h"
13
14#pragma region Re-Adding Removed from Windows SDK qedit.h
15
16struct __declspec(uuid("0579154a-2b53-4994-b0d0-e773148eff85"))
17ISampleGrabberCB : IUnknown
18{
19    //
20    // Raw methods provided by interface
21    //
22
23      virtual HRESULT __stdcall SampleCB (
24        double SampleTime,
25        struct IMediaSample * pSample ) = 0;
26      virtual HRESULT __stdcall BufferCB (
27        double SampleTime,
28        unsigned char * pBuffer,
29        long BufferLen ) = 0;
30};
31
32struct __declspec(uuid("6b652fff-11fe-4fce-92ad-0266b5d7c78f"))
33ISampleGrabber : IUnknown
34{
35    //
36    // Raw methods provided by interface
37    //
38
39      virtual HRESULT __stdcall SetOneShot (
40        long OneShot ) = 0;
41      virtual HRESULT __stdcall SetMediaType (
42        struct _AMMediaType * pType ) = 0;
43      virtual HRESULT __stdcall GetConnectedMediaType (
44        struct _AMMediaType * pType ) = 0;
45      virtual HRESULT __stdcall SetBufferSamples (
46        long BufferThem ) = 0;
47      virtual HRESULT __stdcall GetCurrentBuffer (
48        /*[in,out]*/ long * pBufferSize,
49        /*[out]*/ long * pBuffer ) = 0;
50      virtual HRESULT __stdcall GetCurrentSample (
51        /*[out,retval]*/ struct IMediaSample * * ppSample ) = 0;
52      virtual HRESULT __stdcall SetCallback (
53        struct ISampleGrabberCB * pCallback,
54        long WhichMethodToCallback ) = 0;
55};
56
57struct __declspec(uuid("c1f400a0-3f08-11d3-9f0b-006008039e37"))
58SampleGrabber;
59    // [ default ] interface ISampleGrabber
60
61#pragma endregion
62
63////////////////////////////////////////////////////////////
64// CFormatFlagHelper
65
66class CFormatFlagHelper
67{
68public:
69
70        ////////////////////////////////////////////////////
71        // FLAGNAME
72
73        typedef struct _FLAGNAME
74        {
75                DWORD nValue;
76                LPCTSTR pszName;
77        } FLAGNAME;
78
79public:
80// CFormatFlagHelper
81        static CString StringFromFlags(DWORD nValue, const FLAGNAME* pFlagNames, SIZE_T nFlagNameCount)
82        {
83                CString sText;
84                DWORD nKnownValues = 0;
85                for(SIZE_T nIndex = 0; nIndex < nFlagNameCount; nIndex++)
86                {
87                        nKnownValues |= pFlagNames[nIndex].nValue;
88                        if(!(nValue & pFlagNames[nIndex].nValue))
89                                continue;
90                        if(!sText.IsEmpty())
91                                sText.Append(_T(" | "));
92                        sText.Append(pFlagNames[nIndex].pszName);
93                }
94                DWORD nUnnamedValue = nValue & ~nKnownValues;
95                if(nUnnamedValue)
96                {
97                        if(!sText.IsEmpty())
98                                sText.Append(_T(" | "));
99                        sText.AppendFormat(_T("0x%08x"), nUnnamedValue);
100                }
101                return sText;
102        }
103        template <SIZE_T t_nCount>
104        static CString StringFromFlags(DWORD nValue, const FLAGNAME (&pFlagNames)[t_nCount])
105        {
106                return StringFromFlags(nValue, pFlagNames, t_nCount);
107        }
108        static CString StringFromTypeSpecificFlags(DWORD nValue)
109        {
110                static const FLAGNAME g_pNames[] =
111                {
112                        //{ AM_VIDEO_FLAG_FIELD_MASK
113                        //{ AM_VIDEO_FLAG_INTERLEAVED_FRAME
114                        { AM_VIDEO_FLAG_FIELD1, _T("AM_VIDEO_FLAG_FIELD1") },
115                        { AM_VIDEO_FLAG_FIELD2, _T("AM_VIDEO_FLAG_FIELD2") },
116                        { AM_VIDEO_FLAG_FIELD1FIRST, _T("AM_VIDEO_FLAG_FIELD1FIRST") },
117                        { AM_VIDEO_FLAG_WEAVE, _T("AM_VIDEO_FLAG_WEAVE") },
118                        //{ AM_VIDEO_FLAG_IPB_MASK
119                        //{ AM_VIDEO_FLAG_I_SAMPLE
120                        { AM_VIDEO_FLAG_P_SAMPLE, _T("AM_VIDEO_FLAG_P_SAMPLE") },
121                        { AM_VIDEO_FLAG_B_SAMPLE, _T("AM_VIDEO_FLAG_B_SAMPLE") },
122                        { AM_VIDEO_FLAG_REPEAT_FIELD, _T("AM_VIDEO_FLAG_REPEAT_FIELD") },
123                };
124                return StringFromFlags(nValue, g_pNames);
125        }
126        static CString StringFromSampleFlags(DWORD nValue)
127        {
128                static const FLAGNAME g_pNames[] =
129                {
130                        { AM_SAMPLE_SPLICEPOINT, _T("AM_SAMPLE_SPLICEPOINT") },
131                        { AM_SAMPLE_PREROLL, _T("AM_SAMPLE_PREROLL") },
132                        { AM_SAMPLE_DATADISCONTINUITY, _T("AM_SAMPLE_DATADISCONTINUITY") },
133                        { AM_SAMPLE_TYPECHANGED, _T("AM_SAMPLE_TYPECHANGED") },
134                        { AM_SAMPLE_TIMEVALID, _T("AM_SAMPLE_TIMEVALID") },
135                        { AM_SAMPLE_TIMEDISCONTINUITY, _T("AM_SAMPLE_TIMEDISCONTINUITY") },
136                        { AM_SAMPLE_FLUSH_ON_PAUSE, _T("AM_SAMPLE_FLUSH_ON_PAUSE") },
137                        { AM_SAMPLE_STOPVALID, _T("AM_SAMPLE_STOPVALID") },
138                        { AM_SAMPLE_ENDOFSTREAM, _T("AM_SAMPLE_ENDOFSTREAM") },
139                        //{ AM_STREAM_MEDIA
140                        //{ AM_STREAM_CONTROL
141                };
142                return StringFromFlags(nValue, g_pNames);
143        }
144};
145
146////////////////////////////////////////////////////////////
147// CModule
148
149class CModule :
150        public CAtlExeModuleT<CModule>
151{
152public:
153
154        ////////////////////////////////////////////////////////
155        // CSampleGrabberCallback
156
157        class ATL_NO_VTABLE CSampleGrabberCallback :
158                public CComObjectRootEx<CComMultiThreadModel>,
159                public ISampleGrabberCB,
160                public CFormatFlagHelper
161        {
162        public:
163
164        BEGIN_COM_MAP(CSampleGrabberCallback)
165                COM_INTERFACE_ENTRY(ISampleGrabberCB)
166        END_COM_MAP()
167
168        private:
169                CString m_sName;
170                CString m_sNamePrefix;
171                mutable CRoCriticalSection m_DataCriticalSection;
172                CMediaType m_pMediaType;
173
174        public:
175        // CSampleGrabberCallback
176                VOID SetName(const CString& sName)
177                {
178                        _A(m_sName.IsEmpty());
179                        m_sName = sName;
180                        m_sNamePrefix = AtlFormatString(_T("[%s] "), sName);
181                }
182                VOID SetMediaType(const AM_MEDIA_TYPE* pMediaType)
183                {
184                        CRoCriticalSectionLock DataLock(m_DataCriticalSection);
185                        PrintMediaType(pMediaType);
186                        m_pMediaType = pMediaType;
187                }
188                static VOID PrintMediaType(const CMediaType& pMediaType)
189                {
190                        _tprintf(_T("Media Type:\n\n"));
191                        _tprintf(_T("majortype %ls, subtype %ls, pUnk 0x%08x\n"), _PersistHelper::StringFromIdentifier(pMediaType->majortype), _PersistHelper::StringFromIdentifier(pMediaType->subtype), (LONG) (LONG_PTR) pMediaType->pUnk);
192                        _tprintf(_T("bFixedSizeSamples %d, bTemporalCompression %d, lSampleSize %d\n"), pMediaType->bFixedSizeSamples, pMediaType->bTemporalCompression, pMediaType->lSampleSize);
193                        _tprintf(_T("formattype %ls, cbFormat %d, pbFormat 0x%08x\n"), _PersistHelper::StringFromIdentifier(pMediaType->formattype), pMediaType->cbFormat, (UINT) (UINT_PTR) pMediaType->pbFormat);
194                        if(pMediaType->formattype == FORMAT_VideoInfo)
195                        {
196                                const VIDEOINFOHEADER* pVideoInfoHeader = (const VIDEOINFOHEADER*) (pMediaType->pbFormat ? pMediaType->pbFormat : (BYTE*) (pMediaType + 1));
197                                _tprintf(_T("pbFormat as VIDEOINFOHEADER:\n"));
198                                _tprintf(_T("  rcSource { %d, %d, %d, %d ), rcTarget { %d, %d, %d, %d }\n"), pVideoInfoHeader->rcSource.left, pVideoInfoHeader->rcSource.top, pVideoInfoHeader->rcSource.right, pVideoInfoHeader->rcSource.bottom, pVideoInfoHeader->rcTarget.left, pVideoInfoHeader->rcTarget.top, pVideoInfoHeader->rcTarget.right, pVideoInfoHeader->rcTarget.bottom);
199                                _tprintf(_T("  dwBitRate %d, dwBitErrorRate %d, AvgTimePerFrame %s\n"), pVideoInfoHeader->dwBitRate, pVideoInfoHeader->dwBitErrorRate, _FilterGraphHelper::FormatReferenceTime(pVideoInfoHeader->AvgTimePerFrame));
200                                _tprintf(_T("  bmiHeader.biSize %d, bmiHeader.biWidth %d, bmiHeader.biHeight %d, bmiHeader.biPlanes %d, bmiHeader.biBitCount %d, bmiHeader.biCompression %s\n"), pVideoInfoHeader->bmiHeader.biSize, pVideoInfoHeader->bmiHeader.biWidth, pVideoInfoHeader->bmiHeader.biHeight, pVideoInfoHeader->bmiHeader.biPlanes, pVideoInfoHeader->bmiHeader.biBitCount, _FilterGraphHelper::GetFourccCodeString(pVideoInfoHeader->bmiHeader.biCompression));
201                                _tprintf(_T("  bmiHeader.biSizeImage %d, bmiHeader.biXPelsPerMeter %d, bmiHeader.biYPelsPerMeter %d, bmiHeader.biClrUsed %d, bmiHeader.biClrImportant %d\n"), pVideoInfoHeader->bmiHeader.biSizeImage, pVideoInfoHeader->bmiHeader.biXPelsPerMeter, pVideoInfoHeader->bmiHeader.biYPelsPerMeter, pVideoInfoHeader->bmiHeader.biClrUsed, pVideoInfoHeader->bmiHeader.biClrImportant);
202                        } else
203                        if(pMediaType->formattype == FORMAT_VideoInfo2)
204                        {
205                                const VIDEOINFOHEADER2* pVideoInfoHeader2 = (const VIDEOINFOHEADER2*) (pMediaType->pbFormat ? pMediaType->pbFormat : (BYTE*) (pMediaType + 1));
206                                _tprintf(_T("pbFormat as VIDEOINFOHEADER2:\n"));
207                                _tprintf(_T("  rcSource { %d, %d, %d, %d ), rcTarget { %d, %d, %d, %d }\n"), pVideoInfoHeader2->rcSource.left, pVideoInfoHeader2->rcSource.top, pVideoInfoHeader2->rcSource.right, pVideoInfoHeader2->rcSource.bottom, pVideoInfoHeader2->rcTarget.left, pVideoInfoHeader2->rcTarget.top, pVideoInfoHeader2->rcTarget.right, pVideoInfoHeader2->rcTarget.bottom);
208                                _tprintf(_T("  dwBitRate %d, dwBitErrorRate %d, AvgTimePerFrame %s\n"), pVideoInfoHeader2->dwBitRate, pVideoInfoHeader2->dwBitErrorRate, _FilterGraphHelper::FormatReferenceTime(pVideoInfoHeader2->AvgTimePerFrame));
209                                _tprintf(_T("  dwInterlaceFlags 0x%x, dwCopyProtectFlags 0x%x, dwPictAspectRatioX %d, dwPictAspectRatioY %d, dwControlFlags 0x%x\n"), pVideoInfoHeader2->dwInterlaceFlags, pVideoInfoHeader2->dwCopyProtectFlags, pVideoInfoHeader2->dwPictAspectRatioX, pVideoInfoHeader2->dwPictAspectRatioY, pVideoInfoHeader2->dwControlFlags);
210                                _tprintf(_T("  bmiHeader.biSize %d, bmiHeader.biWidth %d, bmiHeader.biHeight %d, bmiHeader.biPlanes %d, bmiHeader.biBitCount %d, bmiHeader.biCompression %s\n"), pVideoInfoHeader2->bmiHeader.biSize, pVideoInfoHeader2->bmiHeader.biWidth, pVideoInfoHeader2->bmiHeader.biHeight, pVideoInfoHeader2->bmiHeader.biPlanes, pVideoInfoHeader2->bmiHeader.biBitCount, _FilterGraphHelper::GetFourccCodeString(pVideoInfoHeader2->bmiHeader.biCompression));
211                                _tprintf(_T("  bmiHeader.biSizeImage %d, bmiHeader.biXPelsPerMeter %d, bmiHeader.biYPelsPerMeter %d, bmiHeader.biClrUsed %d, bmiHeader.biClrImportant %d\n"), pVideoInfoHeader2->bmiHeader.biSizeImage, pVideoInfoHeader2->bmiHeader.biXPelsPerMeter, pVideoInfoHeader2->bmiHeader.biYPelsPerMeter, pVideoInfoHeader2->bmiHeader.biClrUsed, pVideoInfoHeader2->bmiHeader.biClrImportant);
212                        } else
213                        if(pMediaType->formattype == FORMAT_WaveFormatEx)
214                        {
215                                const WAVEFORMATEX* pWaveFormatEx = (const WAVEFORMATEX*) (pMediaType->pbFormat ? pMediaType->pbFormat : (BYTE*) (pMediaType + 1));
216                                _tprintf(_T("pbFormat as WAVEFORMATEX:\n"));
217                                _tprintf(_T("  wFormatTag %d\n"), pWaveFormatEx->wFormatTag);
218                                _tprintf(_T("  nChannels %d\n"), pWaveFormatEx->nChannels);
219                                _tprintf(_T("  nSamplesPerSec %d\n"), pWaveFormatEx->nSamplesPerSec);
220                                _tprintf(_T("  nAvgBytesPerSec %d\n"), pWaveFormatEx->nAvgBytesPerSec);
221                                _tprintf(_T("  nBlockAlign %d\n"), pWaveFormatEx->nBlockAlign);
222                                _tprintf(_T("  wBitsPerSample %d\n"), pWaveFormatEx->wBitsPerSample);
223                                _tprintf(_T("  cbSize %d\n"), pWaveFormatEx->cbSize);
224                                if(pWaveFormatEx->cbSize > 0)
225                                {
226                                        const BYTE* pnExtraData = (const BYTE*) (pWaveFormatEx + 1);
227                                        const SIZE_T nExtraDataSize = pWaveFormatEx->cbSize;
228                                        for(SIZE_T nIndex1 = 0; nIndex1 < nExtraDataSize; nIndex1 += 0x10)
229                                        {
230                                                CString sText;
231                                                for(SIZE_T nIndex2 = nIndex1; nIndex2 < min(nIndex1 + 0x10, nExtraDataSize); nIndex2++)
232                                                        sText.AppendFormat(_T("%02X "), pnExtraData[nIndex2]);
233                                                sText.TrimRight(_T(" "));
234                                                _tprintf(_T("  pnExtraData[0x%04x] %s\n"), nIndex1, sText);
235                                        }
236                                }
237                        } else
238                                ;
239                        _tprintf(_T("\n"));
240                }
241
242        // ISampleGrabberCB
243        STDMETHOD(SampleCB)(DOUBLE fSampleTime, IMediaSample* pMediaSample) throw()
244                {
245                        _A(pMediaSample);
246                        _ATLTRY
247                        {
248                                CMediaSampleProperties Properties(pMediaSample);
249                                _A(!Properties.pMediaType);
250                                _tprintf(_T("%s") _T("fSampleTime %s, .dwTypeSpecificFlags 0x%08x%s, .dwSampleFlags 0x%08x%s, .tStart %s, .tStop %s, .dwStreamId %d\n"), 
251                                        m_sNamePrefix,
252                                        _StringHelper::FormatNumber(fSampleTime, 3),
253                                        Properties.dwTypeSpecificFlags, Properties.dwTypeSpecificFlags ? (LPCTSTR) AtlFormatString(_T(" (%s)"), StringFromTypeSpecificFlags(Properties.dwTypeSpecificFlags)) : _T(""),
254                                        Properties.dwSampleFlags, Properties.dwSampleFlags ? (LPCTSTR) AtlFormatString(_T(" (%s)"), StringFromSampleFlags(Properties.dwSampleFlags)) : _T(""),
255                                        _FilterGraphHelper::FormatReferenceTime(Properties.tStart), 
256                                        _FilterGraphHelper::FormatReferenceTime(Properties.tStop),
257                                        Properties.dwStreamId,
258                                        0);
259                                CRoCriticalSectionLock DataLock(m_DataCriticalSection);
260                                BOOL bBufferHandled = FALSE;
261                                if(!bBufferHandled)
262                                {
263                                        CString sBuffer;
264                                        static const SIZE_T g_nMaximalPrintSize = 48;
265                                        SIZE_T nIndex;
266                                        for(nIndex = 0; nIndex < (SIZE_T) Properties.lActual && nIndex < g_nMaximalPrintSize; nIndex++)
267                                                sBuffer.AppendFormat(_T("%02X "), Properties.pbBuffer[nIndex]);
268                                        if(nIndex > g_nMaximalPrintSize)
269                                                sBuffer.Append(_T("..."));
270                                        _tprintf(_T("%s") _T(".cbBuffer %d, .lActual %d, pbBuffer %s\n"), 
271                                                m_sNamePrefix,
272                                                Properties.cbBuffer,
273                                                Properties.lActual,
274                                                sBuffer,
275                                                0);
276                                }
277                                _tprintf(_T("\n"));
278                        }
279                        _ATLCATCH(Exception)
280                        {
281                                _C(Exception);
282                        }
283                        return S_OK;
284                }
285        STDMETHOD(BufferCB)(DOUBLE fSampleTime, BYTE* pnBuffer, LONG nBufferSize) throw()
286                {
287                        return S_OK;
288                }
289        };
290
291private:
292
293public:
294        CPath m_sPath;
295        BOOL m_bNoReferenceClock;
296
297public:
298// CModule
299        static VOID LoadGraphBuilderFromFile(IGraphBuilder* pGraphBuilder, LPCTSTR pszPath)
300        {
301                _A(pGraphBuilder && pszPath);
302                CComQIPtr<IPersistStream> pPersistStream = pGraphBuilder;
303                __D(pPersistStream, E_NOINTERFACE);
304                CStringW sPathW(pszPath);
305                __C(StgIsStorageFile(sPathW));
306                CComPtr<IStorage> pStorage;
307                __C(StgOpenStorage(sPathW, 0, STGM_TRANSACTED | STGM_READ | STGM_SHARE_DENY_WRITE, 0, 0, &pStorage));
308                CComPtr<IStream> pStream;
309                __C(pStorage->OpenStream(L"ActiveMovieGraph", 0, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &pStream));
310                __C(pPersistStream->Load(pStream));
311        }
312        static CPath GetDefaultPath()
313        {
314                TCHAR pszPath[MAX_PATH] = { 0 };
315                _W(GetModuleFileName(_AtlBaseModule.GetModuleInstance(), pszPath, DIM(pszPath)));
316                _W(RemoveFileSpec(pszPath));
317                _W(RemoveFileSpec(pszPath));
318                _W(Combine(pszPath, pszPath, _T("Debug.grf")));
319                return pszPath;
320        }
321        CModule() throw()
322        {
323                //m_sPath = GetDefaultPath();
324                m_bNoReferenceClock = FALSE;
325        }
326        ~CModule() throw()
327        {
328        }
329        HRESULT PreMessageLoop(INT nShowCommand)
330        {
331                __C(__super::PreMessageLoop(nShowCommand));
332                return S_OK;
333        }
334        VOID RunMessageLoop()
335        {
336                CGenericFilterGraph FilterGraph;
337                FilterGraph.CoCreateInstance();
338                LoadGraphBuilderFromFile(FilterGraph.m_pFilterGraph, m_sPath);
339                #pragma region Sample Grabbers
340                _FilterGraphHelper::CFilterArray FilterArray;
341                _FilterGraphHelper::GetGraphFilters(FilterGraph.m_pFilterGraph, FilterArray);
342                __D(!FilterArray.IsEmpty(), E_UNNAMED);
343                SIZE_T nSampleGrabberIndex = 0;
344                for(SIZE_T nIndex = 0; nIndex < FilterArray.GetCount(); nIndex++)
345                {
346                        const CComQIPtr<ISampleGrabber> pSampleGrabber = FilterArray[nIndex];
347                        if(!pSampleGrabber)
348                                continue;
349                        CObjectPtr<CSampleGrabberCallback> pSampleGrabberCallback;
350                        pSampleGrabberCallback.Construct();
351                        if(FilterArray.GetCount() > 1)
352                                pSampleGrabberCallback->SetName(AtlFormatString(_T("%c"), 'A' + nSampleGrabberIndex));
353                        __C(pSampleGrabber->SetCallback(pSampleGrabberCallback, 0));
354                        nSampleGrabberIndex++;
355                        const CMediaType pMediaType = _FilterGraphHelper::GetPinMediaType(_FilterGraphHelper::GetFilterPin(CComQIPtr<IBaseFilter>(pSampleGrabber), PINDIR_INPUT));
356                        pSampleGrabberCallback->SetMediaType(pMediaType);
357                }
358                #pragma endregion
359                if(m_bNoReferenceClock)
360                        __C(FilterGraph.m_pMediaFilter->SetSyncSource(NULL));
361                _tprintf(_T("Media Samples:\n\n"));
362                __C(FilterGraph.m_pMediaControl->Run());
363                #pragma region Wait for Completion
364                #if TRUE
365                        const CComPtr<IMediaEventEx>& pMediaEvent = FilterGraph.m_pMediaEventEx;
366                        for(; ; )
367                        {
368                                // SUGG: Replace Sleep/GetMessage with MsgWaitForMultipleObjects/PeekMessage to wait for graph event and window messages
369                                static const ULONG g_nTimeout = 10;
370                                if(pMediaEvent)
371                                {
372                                        LONG nCompletionEventCode = 0;
373                                        const HRESULT nWaitForCompletionResult = pMediaEvent->WaitForCompletion(g_nTimeout, &nCompletionEventCode);
374                                        for(; ; )
375                                        {
376                                                LONG nEventCode = 0;
377                                                LONG_PTR nParameter1 = 0, nParameter2 = 0;
378                                                const HRESULT nGetEventResult = pMediaEvent->GetEvent(&nEventCode, &nParameter1, &nParameter2, 0);
379                                                if(nGetEventResult == E_ABORT)
380                                                        break;
381                                                __C(nGetEventResult);
382                                                _ATLTRY
383                                                {
384                                                        switch(nEventCode)
385                                                        {
386                                                        case EC_COMPLETE:
387                                                                _tprintf(_T("Event: EC_COMPLETE (0x%x), Error Code 0x%08x (%s), Parameter2 0x%08x\n"), nEventCode, (HRESULT) nParameter1, AtlFormatSystemMessage((HRESULT) nParameter1).TrimRight(_T("\t\n\r .")), nParameter2);
388                                                                break;
389                                                        case EC_USERABORT:
390                                                                _tprintf(_T("Event: EC_USERABORT (0x%x), Parameter1 0x%08x, Parameter2 0x%08x\n"), nEventCode, nParameter1, nParameter2);
391                                                                break;
392                                                        case EC_ERRORABORT:
393                                                                _tprintf(_T("Event: EC_ERRORABORT (0x%x), Error Code 0x%08x (%s), Parameter2 0x%08x\n"), nEventCode, nParameter1, AtlFormatSystemMessage((HRESULT) nParameter1).TrimRight(_T("\t\n\r .")), nParameter2);
394                                                                break;
395                                                        default:
396                                                                _tprintf(_T("Event: Code 0x%x, Parameter1 0x%08x, Parameter2 0x%08x\n"), nEventCode, nParameter1, nParameter2);
397                                                        }
398                                                }
399                                                _ATLCATCHALL()
400                                                {
401                                                        _V(pMediaEvent->FreeEventParams(nEventCode, nParameter1, nParameter2));
402                                                        _ATLRETHROW;
403                                                }
404                                                _V(pMediaEvent->FreeEventParams(nEventCode, nParameter1, nParameter2));
405                                        }
406                                        if(nWaitForCompletionResult != E_ABORT)
407                                        {
408                                                __C(nWaitForCompletionResult);
409                                                _tprintf(_T("\nCompleted: Event Code 0x%x\n"), nCompletionEventCode);
410                                                break;
411                                        }
412                                } else
413                                        Sleep(g_nTimeout);
414                                MSG Message;
415                                while(PeekMessage(&Message, NULL, WM_NULL, WM_NULL, PM_REMOVE))
416                                {
417                                        TranslateMessage(&Message);
418                                        DispatchMessage(&Message);
419                                }
420                        }
421                #else
422                        MSG Message;
423                        while(GetMessage(&Message, NULL, WM_NULL, WM_NULL) > 0)
424                        {
425                                TranslateMessage(&Message);
426                                DispatchMessage(&Message);
427                        }
428                #endif
429                #pragma endregion
430        }
431};
432
433////////////////////////////////////////////////////////////
434// Main
435
436int _tmain(int argc, _TCHAR* argv[])
437{
438        INT nResult = 0;
439        _ATLTRY
440        {
441                CModule Module;
442                #pragma region Parse Command Line
443                for(INT nIndex = 1; nIndex < argc; nIndex++)
444                {
445                        CString sArgument = argv[nIndex];
446                        _A(!sArgument.IsEmpty());
447                        #pragma region Switches
448                        if(_tcschr(_T("-/"), sArgument[0]))
449                        {
450                                sArgument.Delete(0);
451                                #pragma region Switch Value/Specification
452                                CString sArgumentValue;
453                                if(sArgument.GetLength() > 1)
454                                {
455                                        SIZE_T nIndex = 1;
456                                        if(sArgument[1] == _T(':'))
457                                                nIndex++;
458                                        sArgumentValue = (LPCTSTR) sArgument + nIndex;
459                                }
460                                INT nIntegerArgumentValue = 0;
461                                const BOOL bIntegerArgumentValueValid = !sArgumentValue.IsEmpty() ? AtlStringToInteger(sArgumentValue, nIntegerArgumentValue) : FALSE;
462                                #pragma endregion
463                                if(_tcschr(_T("Cc"), sArgument[0])) // No Reference Clock
464                                {
465                                        Module.m_bNoReferenceClock = TRUE;
466                                }
467                                continue;
468                        }
469                        #pragma endregion
470                        if(sArgument.GetLength() >= 2 && sArgument[0] == _T('"') && sArgument[sArgument.GetLength() - 1] == _T('"'))
471                                sArgument = sArgument.Mid(1, sArgument.GetLength() - 2);
472                        __D(!_tcslen(Module.m_sPath), E_UNNAMED);
473                        Module.m_sPath = (LPCTSTR) sArgument;
474                }
475                #pragma endregion
476                __D(_tcslen(Module.m_sPath), E_UNNAMED);
477                nResult = Module.WinMain(SW_SHOWNORMAL);
478        }
479        _ATLCATCH(Exception)
480        {
481                _tprintf(_T("Fatal: Error 0x%08x\n"), (HRESULT) Exception);
482        }
483        _ATLCATCHALL()
484        {
485                _tprintf(_T("Fatal: Fatal error\n"));
486        }
487        return nResult;
488}
Note: See TracBrowser for help on using the repository browser.