source: trunk/Utilities/MediaFoundation/EnumerateTransforms/EnumerateTransforms.cpp @ 85

Last change on this file since 85 was 85, checked in by roman, 12 years ago
  • Property svn:keywords set to Id
File size: 10.9 KB
Line 
1////////////////////////////////////////////////////////////
2// Copyright (C) Roman Ryltsov, 2008-2012
3// Created by Roman Ryltsov roman@alax.info
4//
5// $Id: EnumerateTransforms.cpp 85 2012-08-05 11:09:49Z roman $
6
7#include "stdafx.h"
8#include <mfapi.h>
9#include <mftransform.h>
10#include "rodshow.h"
11
12#pragma comment(lib, "mfplat.lib")
13#pragma comment(lib, "mfuuid.lib")
14
15////////////////////////////////////////////////////////////
16// CModule
17
18class CModule :
19        public CAtlExeModuleT<CModule>
20{
21public:
22        static CString FormatKey(const GUID& Key)
23        {
24                static const struct { const GUID* pIdentifier; LPCSTR pszName; } g_pMap[] = 
25                {
26                        #define A(x) { &x, #x },
27                        A(MF_TRANSFORM_FLAGS_Attribute)
28                        A(MF_TRANSFORM_CATEGORY_Attribute)
29                        A(MFT_TRANSFORM_CLSID_Attribute)
30                        A(MFT_INPUT_TYPES_Attributes)
31                        A(MFT_OUTPUT_TYPES_Attributes)
32                        A(MFT_ENUM_HARDWARE_URL_Attribute)
33                        A(MFT_FRIENDLY_NAME_Attribute)
34                        A(MFT_CONNECTED_STREAM_ATTRIBUTE)
35                        A(MFT_PREFERRED_OUTPUTTYPE_Attribute)
36                        A(MFT_PROCESS_LOCAL_Attribute)
37                        A(MFT_HW_TIMESTAMP_WITH_QPC_Attribute)
38                        A(MFT_FIELDOFUSE_UNLOCK_Attribute)
39                        A(MFT_CODEC_MERIT_Attribute)
40                        A(MFT_ENUM_TRANSCODE_ONLY_ATTRIBUTE)
41                        #undef A
42                };
43                for(SIZE_T nIndex = 0; nIndex < DIM(g_pMap); nIndex++)
44                        if(*g_pMap[nIndex].pIdentifier == Key)
45                                return CString(g_pMap[nIndex].pszName);
46                return CString(_PersistHelper::StringFromIdentifier(Key));
47        }
48        static CString FormatTransformFlags(ULONG nTransformFlags)
49        {
50                CRoArrayT<CString> Array;
51                static const struct { ULONG nValue; LPCSTR pszName; } g_pMap[] = 
52                {
53                        #define A(x) { x, #x },
54                        A(MFT_ENUM_FLAG_SYNCMFT)
55                        A(MFT_ENUM_FLAG_ASYNCMFT)
56                        A(MFT_ENUM_FLAG_HARDWARE)
57                        A(MFT_ENUM_FLAG_FIELDOFUSE)
58                        A(MFT_ENUM_FLAG_LOCALMFT)
59                        A(MFT_ENUM_FLAG_TRANSCODE_ONLY)
60                        //A(MFT_ENUM_FLAG_SORTANDFILTER)
61                        //A(MFT_ENUM_FLAG_ALL)
62                        #undef A
63                };
64                for(SIZE_T nIndex = 0; nIndex < DIM(g_pMap); nIndex++)
65                        if(nTransformFlags & g_pMap[nIndex].nValue)
66                        {
67                                _W(Array.Add(CA2CT(g_pMap[nIndex].pszName)) >= 0);
68                                nTransformFlags &= ~g_pMap[nIndex].nValue;
69                        }
70                if(!Array.IsEmpty())
71                {
72                        if(nTransformFlags)
73                                _W(Array.Add(AtlFormatString(_T("0x%x"), nTransformFlags)) >= 0);
74                        return _StringHelper::Join(Array, _T(" | "));
75                }
76                if(!nTransformFlags)
77                        return _T("0");
78                return AtlFormatString(_T("0x%x"), nTransformFlags);
79        }
80
81public:
82// CModule
83        CModule() throw()
84        {
85                _Z4(atlTraceRefcount, 4, _T("this 0x%p"), this);
86                _W(CExceptionFilter::Initialize());
87                #if defined(_DEBUG)
88                AtlTraceLoadSettings(NULL);
89                #endif // defined(_DEBUG)
90        }
91        ~CModule() throw()
92        {
93                _Z4(atlTraceRefcount, 4, _T("this 0x%p"), this);
94                CExceptionFilter::Terminate();
95        }
96        HRESULT PreMessageLoop(INT nShowCommand)
97        {
98                const HRESULT nResult = __super::PreMessageLoop(nShowCommand);
99                return SUCCEEDED(nResult) ? S_OK : nResult;
100        }
101        VOID RunMessageLoop()
102        {
103                static const struct { const GUID* pCategory; LPCSTR pszName; } g_pMap[] = 
104                {
105                        #define A(x) { &x, #x },
106                        A(MFT_CATEGORY_VIDEO_DECODER)
107                        A(MFT_CATEGORY_VIDEO_ENCODER)
108                        A(MFT_CATEGORY_VIDEO_EFFECT)
109                        A(MFT_CATEGORY_MULTIPLEXER)
110                        A(MFT_CATEGORY_DEMULTIPLEXER)
111                        A(MFT_CATEGORY_AUDIO_DECODER)
112                        A(MFT_CATEGORY_AUDIO_ENCODER)
113                        A(MFT_CATEGORY_AUDIO_EFFECT)
114                        A(MFT_CATEGORY_VIDEO_PROCESSOR)
115                        A(MFT_CATEGORY_OTHER)
116                        #undef A
117                };
118                for(SIZE_T nCategoryIndex = 0; nCategoryIndex < DIM(g_pMap); nCategoryIndex++)
119                {
120                        _tprintf(_T("Category: %hs %ls\n"), g_pMap[nCategoryIndex].pszName, _PersistHelper::StringFromIdentifier(*g_pMap[nCategoryIndex].pCategory));
121                        _tprintf(_T("\n"));
122                        _ATLTRY
123                        {
124                                CComHeapPtr<IMFActivate*> ppMfActivates;
125                                UINT32 nMfActivateCount = 0;
126                                __C(MFTEnumEx(*g_pMap[nCategoryIndex].pCategory, MFT_ENUM_FLAG_ALL, NULL, NULL, &ppMfActivates, &nMfActivateCount));
127                                CRoArrayT<CComPtr<IMFActivate>> ActivateArray;
128                                for(UINT32 nMfActivateIndex = 0; nMfActivateIndex < nMfActivateCount; nMfActivateIndex++)
129                                {
130                                        CComPtr<IMFActivate>& pMfActivate = reinterpret_cast<CComPtr<IMFActivate>&>(ppMfActivates[nMfActivateIndex]);
131                                        _W(ActivateArray.Add(pMfActivate) >= 0);
132                                        pMfActivate = NULL;
133                                }
134                                for(SIZE_T nActivateIndex = 0; nActivateIndex < ActivateArray.GetCount(); nActivateIndex++)
135                                {
136                                        const CComPtr<IMFActivate>& pMfActivate = ActivateArray[nActivateIndex];
137                                        CString sItem = AtlFormatString(_T("#%d"), nActivateIndex);
138                                        CComHeapPtr<WCHAR> pszFriendlyName;
139                                        if(SUCCEEDED(pMfActivate->GetAllocatedString(MFT_FRIENDLY_NAME_Attribute, &pszFriendlyName, NULL)))
140                                                sItem.Insert(0, AtlFormatString(_T("%ls "), pszFriendlyName));
141                                        _tprintf(_T("\t") _T("%s\n"), sItem);
142                                        _ATLTRY
143                                        {
144                                                UINT32 nItemCount = 0;
145                                                __C(pMfActivate->GetCount(&nItemCount));
146                                                for(UINT32 nItemIndex = 0; nItemIndex < nItemCount; nItemIndex++)
147                                                {
148                                                        GUID Key;
149                                                        PROPVARIANT vValue;
150                                                        PropVariantInit(&vValue);
151                                                        __C(pMfActivate->GetItemByIndex(nItemIndex, &Key, &vValue));
152                                                        // NOTE: See PROPVARIANT Type Constants http://msdn.microsoft.com/en-us/library/cc235506%28v=prot.10%29.aspx
153                                                        if(Key == MF_TRANSFORM_CATEGORY_Attribute && vValue.vt == VT_CLSID && *vValue.puuid == *g_pMap[nCategoryIndex].pCategory)
154                                                                continue; // Matches Category
155                                                        if(Key == MFT_FRIENDLY_NAME_Attribute)
156                                                                continue; // Already Printed
157                                                        CString sStringValue;
158                                                        BOOL bStringValueAvailable = FALSE;
159                                                        BOOL bDefault = TRUE;
160                                                        #pragma region Format as Attribute
161                                                        if(Key == MF_TRANSFORM_FLAGS_Attribute && vValue.vt == VT_UI4)
162                                                        {
163                                                                sStringValue = FormatTransformFlags(vValue.ulVal);
164                                                                bStringValueAvailable = TRUE;
165                                                                bDefault = FALSE;
166                                                        } else
167                                                        if((Key == MFT_INPUT_TYPES_Attributes || Key == MFT_OUTPUT_TYPES_Attributes) && (VT_VECTOR | VT_UI1))
168                                                        {
169                                                                _A(!(vValue.caub.cElems % sizeof (MFT_REGISTER_TYPE_INFO)));
170                                                                const MFT_REGISTER_TYPE_INFO* pData = (MFT_REGISTER_TYPE_INFO*) vValue.caub.pElems;
171                                                                const SIZE_T nDataCount = vValue.caub.cElems / sizeof *pData;
172                                                                CRoArrayT<CString> Array;
173                                                                for(SIZE_T nIndex = 0; nIndex < nDataCount; nIndex++)
174                                                                        _W(Array.Add(AtlFormatString(_T("\t\t\t") _T("%ls %ls"), _FilterGraphHelper::StringFromMajorType(pData[nIndex].guidMajorType), _FilterGraphHelper::StringFromSubtype(pData[nIndex].guidSubtype))) >= 0);
175                                                                sStringValue += _StringHelper::Join(Array, _T("\n"));
176                                                                if(!sStringValue.IsEmpty())
177                                                                {
178                                                                        sStringValue.Insert(0, _T("\n"));
179                                                                        sStringValue.Append(_T("\n") _T("\t\t\t"));
180                                                                }
181                                                                bStringValueAvailable = TRUE;
182                                                                bDefault = FALSE;
183                                                        } else
184                                                                ;
185                                                        #pragma endregion
186                                                        #pragma region Format as Type
187                                                        if(bDefault)
188                                                        {
189                                                                if(vValue.vt == VT_LPSTR)
190                                                                {
191                                                                        sStringValue = CA2CT(vValue.pszVal);
192                                                                        bStringValueAvailable = TRUE;
193                                                                } else
194                                                                if(vValue.vt == VT_LPWSTR)
195                                                                {
196                                                                        sStringValue = CW2CT(vValue.pwszVal);
197                                                                        bStringValueAvailable = TRUE;
198                                                                } else
199                                                                if(vValue.vt == VT_CLSID)
200                                                                {
201                                                                        sStringValue = _PersistHelper::StringFromIdentifier(*vValue.puuid);
202                                                                        bStringValueAvailable = TRUE;
203                                                                } else
204                                                                if(vValue.vt == (VT_VECTOR | VT_UI1))
205                                                                {
206                                                                        sStringValue = AtlFormatString(_T("%d bytes"), vValue.caub.cElems);
207                                                                        if(vValue.caub.cElems > 0)
208                                                                        {
209                                                                                sStringValue += _T(", ");
210                                                                                ULONG nIndex;
211                                                                                for(nIndex = 0; nIndex < vValue.caub.cElems && nIndex < 24; nIndex++)
212                                                                                        sStringValue += AtlFormatString(_T("%02X "), vValue.caub.pElems[nIndex]);
213                                                                                if(nIndex < vValue.caub.cElems)
214                                                                                        sStringValue += _T("...");
215                                                                        }
216                                                                        bStringValueAvailable = TRUE;
217                                                                } else
218                                                                {
219                                                                        CComVariant vVariantValue;
220                                                                        bStringValueAvailable = SUCCEEDED(vVariantValue.ChangeType(VT_BSTR, &reinterpret_cast<VARIANT&>(vValue)));
221                                                                        if(bStringValueAvailable)
222                                                                                sStringValue = CString(vVariantValue.bstrVal);
223                                                                }
224                                                        }
225                                                        #pragma endregion
226                                                        if(bStringValueAvailable)
227                                                                _tprintf(_T("\t") _T("\t") _T("%s: %s (0x%x)\n"), FormatKey(Key), sStringValue, vValue.vt);
228                                                        else
229                                                                _tprintf(_T("\t") _T("\t") _T("%s: ??? (0x%x)\n"), FormatKey(Key), vValue.vt);
230                                                }
231                                        }
232                                        _ATLCATCHALL()
233                                        {
234                                                _Z_EXCEPTION();
235                                        }
236                                        _tprintf(_T("\n"));
237                                }
238                        }
239                        _ATLCATCHALL()
240                        {
241                                _Z_EXCEPTION();
242                        }
243                }
244        }
245};
246
247////////////////////////////////////////////////////////////
248// CArgumentException
249
250class CArgumentException :
251        public CAtlException
252{
253public:
254        CString m_sMessage;
255
256public:
257// CArgumentException
258        CArgumentException(const CString& sMessage, HRESULT nCode = E_FAIL) throw() :
259                CAtlException(nCode),
260                m_sMessage(sMessage)
261        {
262        }
263};
264
265////////////////////////////////////////////////////////////
266// Main
267
268int _tmain(int argc, _TCHAR* argv[])
269{
270        CModule Module;
271        _ATLTRY
272        {
273                #pragma region Syntax
274                //if(argc <= 1)
275                //{
276                //      CPath sName = FindFileName(argv[0]);
277                //      sName.RemoveExtension();
278                //      _tprintf(_T("Syntax:  %s [options] <media-file-path>\n"), sName);
279                //      _tprintf(_T("\n"));
280                //      _tprintf(_T("Options: ") _T("/x") _T(" - ") _T("show message box before running the graph\n"));
281                //      _tprintf(_T("\n"));
282                //      return 2;
283                //}
284                #pragma endregion
285                //for(INT nArgumentIndex = 1; nArgumentIndex < argc; nArgumentIndex++)
286                //{
287                //      CString sArgument = argv[nArgumentIndex];
288                //      _A(!sArgument.IsEmpty());
289                //      if(_tcschr(_T("-/"), sArgument[0]))
290                //      {
291                //              sArgument.Delete(0, 1);
292                //              if(sArgument.IsEmpty())
293                //                      throw CArgumentException(_T("Unexpected argument"));
294                //              switch(sArgument[0])
295                //              {
296                //              case 'X':
297                //              case 'x':
298                //                      Module.m_bShowMessageBox = TRUE;
299                //                      break;
300                //              default:
301                //                      throw CArgumentException(AtlFormatString(_T("Unexpected argument (%s)"), sArgument));
302                //              }
303                //              continue;
304                //      }
305                //      if(_tcslen(Module.m_sPath))
306                //              throw CArgumentException(_T("Unexpected argument: Input file name already specified"));
307                //      Module.m_sPath = (LPCTSTR) sArgument;
308                //      //throw CArgumentException(AtlFormatString(_T("Unexpected argument (%s)"), sArgument));
309                //}
310                //if(!_tcslen(Module.m_sPath))
311                //      throw CArgumentException(_T("Missing argument: No input file name specified"));
312                Module.WinMain(SW_SHOWNORMAL);
313        }
314        catch(CArgumentException Exception)
315        {
316                _tprintf(_T("Fatal Error: %s\n"), Exception.m_sMessage);
317                return 1;
318        }
319        _ATLCATCH(Exception)
320        {
321                _tprintf(_T("Fatal Error: 0x%08x %s\n"), (HRESULT) Exception, AtlFormatSystemMessage(Exception).TrimRight(_T("\t\n\r .")));
322                return 1;
323        }
324        _ATLCATCHALL()
325        {
326                _tprintf(_T("Fatal Error\n"));
327                return 1;
328        }
329        return 0;
330}
331
332// NOTE: See also Matthew van Eerde's "How to enumerate Media Foundation transforms on your system"
333//       http://blogs.msdn.com/b/matthew_van_eerde/archive/2010/05/03/how-to-enumerate-media-foundation-transforms-on-your-system.aspx
Note: See TracBrowser for help on using the repository browser.