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

Last change on this file since 86 was 86, checked in by roman, 12 years ago
  • Property svn:keywords set to Id
File size: 10.9 KB
RevLine 
[85]1////////////////////////////////////////////////////////////
2// Copyright (C) Roman Ryltsov, 2008-2012
3// Created by Roman Ryltsov roman@alax.info
4//
5// $Id: EnumerateTransforms.cpp 86 2012-08-05 13:50:38Z 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 },
[86]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)
[85]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;
[86]139                                        UINT32 nFriendlyNameLength;
140                                        if(SUCCEEDED(pMfActivate->GetAllocatedString(MFT_FRIENDLY_NAME_Attribute, &pszFriendlyName, &nFriendlyNameLength)))
[85]141                                                sItem.Insert(0, AtlFormatString(_T("%ls "), pszFriendlyName));
142                                        _tprintf(_T("\t") _T("%s\n"), sItem);
143                                        _ATLTRY
144                                        {
145                                                UINT32 nItemCount = 0;
146                                                __C(pMfActivate->GetCount(&nItemCount));
147                                                for(UINT32 nItemIndex = 0; nItemIndex < nItemCount; nItemIndex++)
148                                                {
149                                                        GUID Key;
150                                                        PROPVARIANT vValue;
151                                                        PropVariantInit(&vValue);
152                                                        __C(pMfActivate->GetItemByIndex(nItemIndex, &Key, &vValue));
153                                                        // NOTE: See PROPVARIANT Type Constants http://msdn.microsoft.com/en-us/library/cc235506%28v=prot.10%29.aspx
154                                                        if(Key == MF_TRANSFORM_CATEGORY_Attribute && vValue.vt == VT_CLSID && *vValue.puuid == *g_pMap[nCategoryIndex].pCategory)
155                                                                continue; // Matches Category
156                                                        if(Key == MFT_FRIENDLY_NAME_Attribute)
157                                                                continue; // Already Printed
158                                                        CString sStringValue;
159                                                        BOOL bStringValueAvailable = FALSE;
160                                                        BOOL bDefault = TRUE;
161                                                        #pragma region Format as Attribute
162                                                        if(Key == MF_TRANSFORM_FLAGS_Attribute && vValue.vt == VT_UI4)
163                                                        {
164                                                                sStringValue = FormatTransformFlags(vValue.ulVal);
165                                                                bStringValueAvailable = TRUE;
166                                                                bDefault = FALSE;
167                                                        } else
168                                                        if((Key == MFT_INPUT_TYPES_Attributes || Key == MFT_OUTPUT_TYPES_Attributes) && (VT_VECTOR | VT_UI1))
169                                                        {
170                                                                _A(!(vValue.caub.cElems % sizeof (MFT_REGISTER_TYPE_INFO)));
171                                                                const MFT_REGISTER_TYPE_INFO* pData = (MFT_REGISTER_TYPE_INFO*) vValue.caub.pElems;
172                                                                const SIZE_T nDataCount = vValue.caub.cElems / sizeof *pData;
173                                                                CRoArrayT<CString> Array;
174                                                                for(SIZE_T nIndex = 0; nIndex < nDataCount; nIndex++)
175                                                                        _W(Array.Add(AtlFormatString(_T("\t\t\t") _T("%ls %ls"), _FilterGraphHelper::StringFromMajorType(pData[nIndex].guidMajorType), _FilterGraphHelper::StringFromSubtype(pData[nIndex].guidSubtype))) >= 0);
176                                                                sStringValue += _StringHelper::Join(Array, _T("\n"));
177                                                                if(!sStringValue.IsEmpty())
178                                                                {
179                                                                        sStringValue.Insert(0, _T("\n"));
180                                                                        sStringValue.Append(_T("\n") _T("\t\t\t"));
181                                                                }
182                                                                bStringValueAvailable = TRUE;
183                                                                bDefault = FALSE;
184                                                        } else
185                                                                ;
186                                                        #pragma endregion
187                                                        #pragma region Format as Type
188                                                        if(bDefault)
189                                                        {
190                                                                if(vValue.vt == VT_LPSTR)
191                                                                {
192                                                                        sStringValue = CA2CT(vValue.pszVal);
193                                                                        bStringValueAvailable = TRUE;
194                                                                } else
195                                                                if(vValue.vt == VT_LPWSTR)
196                                                                {
197                                                                        sStringValue = CW2CT(vValue.pwszVal);
198                                                                        bStringValueAvailable = TRUE;
199                                                                } else
200                                                                if(vValue.vt == VT_CLSID)
201                                                                {
202                                                                        sStringValue = _PersistHelper::StringFromIdentifier(*vValue.puuid);
203                                                                        bStringValueAvailable = TRUE;
204                                                                } else
205                                                                if(vValue.vt == (VT_VECTOR | VT_UI1))
206                                                                {
207                                                                        sStringValue = AtlFormatString(_T("%d bytes"), vValue.caub.cElems);
208                                                                        if(vValue.caub.cElems > 0)
209                                                                        {
210                                                                                sStringValue += _T(", ");
211                                                                                ULONG nIndex;
212                                                                                for(nIndex = 0; nIndex < vValue.caub.cElems && nIndex < 24; nIndex++)
213                                                                                        sStringValue += AtlFormatString(_T("%02X "), vValue.caub.pElems[nIndex]);
214                                                                                if(nIndex < vValue.caub.cElems)
215                                                                                        sStringValue += _T("...");
216                                                                        }
217                                                                        bStringValueAvailable = TRUE;
218                                                                } else
219                                                                {
220                                                                        CComVariant vVariantValue;
221                                                                        bStringValueAvailable = SUCCEEDED(vVariantValue.ChangeType(VT_BSTR, &reinterpret_cast<VARIANT&>(vValue)));
222                                                                        if(bStringValueAvailable)
223                                                                                sStringValue = CString(vVariantValue.bstrVal);
224                                                                }
225                                                        }
226                                                        #pragma endregion
227                                                        if(bStringValueAvailable)
228                                                                _tprintf(_T("\t") _T("\t") _T("%s: %s (0x%x)\n"), FormatKey(Key), sStringValue, vValue.vt);
229                                                        else
230                                                                _tprintf(_T("\t") _T("\t") _T("%s: ??? (0x%x)\n"), FormatKey(Key), vValue.vt);
231                                                }
232                                        }
233                                        _ATLCATCHALL()
234                                        {
235                                                _Z_EXCEPTION();
236                                        }
237                                        _tprintf(_T("\n"));
238                                }
239                        }
240                        _ATLCATCHALL()
241                        {
242                                _Z_EXCEPTION();
243                        }
244                }
245        }
246};
247
248////////////////////////////////////////////////////////////
249// CArgumentException
250
251class CArgumentException :
252        public CAtlException
253{
254public:
255        CString m_sMessage;
256
257public:
258// CArgumentException
259        CArgumentException(const CString& sMessage, HRESULT nCode = E_FAIL) throw() :
260                CAtlException(nCode),
261                m_sMessage(sMessage)
262        {
263        }
264};
265
266////////////////////////////////////////////////////////////
267// Main
268
269int _tmain(int argc, _TCHAR* argv[])
270{
271        CModule Module;
272        _ATLTRY
273        {
274                #pragma region Syntax
275                //if(argc <= 1)
276                //{
277                //      CPath sName = FindFileName(argv[0]);
278                //      sName.RemoveExtension();
279                //      _tprintf(_T("Syntax:  %s [options] <media-file-path>\n"), sName);
280                //      _tprintf(_T("\n"));
281                //      _tprintf(_T("Options: ") _T("/x") _T(" - ") _T("show message box before running the graph\n"));
282                //      _tprintf(_T("\n"));
283                //      return 2;
284                //}
285                #pragma endregion
286                //for(INT nArgumentIndex = 1; nArgumentIndex < argc; nArgumentIndex++)
287                //{
288                //      CString sArgument = argv[nArgumentIndex];
289                //      _A(!sArgument.IsEmpty());
290                //      if(_tcschr(_T("-/"), sArgument[0]))
291                //      {
292                //              sArgument.Delete(0, 1);
293                //              if(sArgument.IsEmpty())
294                //                      throw CArgumentException(_T("Unexpected argument"));
295                //              switch(sArgument[0])
296                //              {
297                //              case 'X':
298                //              case 'x':
299                //                      Module.m_bShowMessageBox = TRUE;
300                //                      break;
301                //              default:
302                //                      throw CArgumentException(AtlFormatString(_T("Unexpected argument (%s)"), sArgument));
303                //              }
304                //              continue;
305                //      }
306                //      if(_tcslen(Module.m_sPath))
307                //              throw CArgumentException(_T("Unexpected argument: Input file name already specified"));
308                //      Module.m_sPath = (LPCTSTR) sArgument;
309                //      //throw CArgumentException(AtlFormatString(_T("Unexpected argument (%s)"), sArgument));
310                //}
311                //if(!_tcslen(Module.m_sPath))
312                //      throw CArgumentException(_T("Missing argument: No input file name specified"));
313                Module.WinMain(SW_SHOWNORMAL);
314        }
315        catch(CArgumentException Exception)
316        {
317                _tprintf(_T("Fatal Error: %s\n"), Exception.m_sMessage);
318                return 1;
319        }
320        _ATLCATCH(Exception)
321        {
322                _tprintf(_T("Fatal Error: 0x%08x %s\n"), (HRESULT) Exception, AtlFormatSystemMessage(Exception).TrimRight(_T("\t\n\r .")));
323                return 1;
324        }
325        _ATLCATCHALL()
326        {
327                _tprintf(_T("Fatal Error\n"));
328                return 1;
329        }
330        return 0;
331}
332
333// NOTE: See also Matthew van Eerde's "How to enumerate Media Foundation transforms on your system"
334//       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.