source: trunk/Utilities/EnumerateVideoCaptureFilterCapabilities/EnumerateVideoCaptureFilterCapabilities.cpp @ 937

Last change on this file since 937 was 172, checked in by roman, 11 years ago
File size: 12.5 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#include "stdafx.h"
9#import "libid:1469D378-8829-4ff0-9B3B-07DD5B16F3CB" raw_interfaces_only // DecklinkPublicLib
10#include <windows.h>
11#include <dshow.h>
12#include <dvdmedia.h> // VIDEOINFOHEADER2
13
14#pragma comment(lib, "strmiids.lib")
15
16inline VOID __C(HRESULT nResult) { ATLENSURE_SUCCEEDED(nResult); }
17inline VOID __D(BOOL bResult, HRESULT nResult) { ATLENSURE_THROW(bResult, nResult); }
18inline VOID __D(const VOID* pvResult, HRESULT nResult) { ATLENSURE_THROW(pvResult, nResult); }
19
20//#pragma pack(show)
21
22CString StringFromData(const BYTE* pnData, SIZE_T nDataSize)
23{
24        CString sString;
25        for(SIZE_T nIndex = 0; nIndex < nDataSize; nIndex++)
26                sString.AppendFormat(_T("%02X "), pnData[nIndex]);
27        sString.TrimRight();
28        return sString;
29}
30CString StringFromData(const VOID* pvData, SIZE_T nDataSize)
31{
32        return StringFromData((const BYTE*) pvData, nDataSize);
33}
34CString StringFromCode(DWORD nCode)
35{
36        // NOTE: More precisely, we need to compare each byte against 0x20, but this one is good enough too
37        if(nCode < 0x20202020)
38                return (LPCTSTR) NULL;
39        TCHAR pszCode[] = 
40        {
41                (nCode >> 0) & 0xFF,
42                (nCode >> 8) & 0xFF,
43                (nCode >> 16) & 0xFF,
44                (nCode >> 24) & 0xFF,
45                0
46        };
47        return pszCode;
48}
49
50int _tmain(int argc, _TCHAR* argv[])
51{
52        _ATLTRY
53        {
54                __C(CoInitializeEx(NULL, COINIT_APARTMENTTHREADED));
55                _ATLTRY
56                {
57                        CComPtr<ICreateDevEnum> pCreateDevEnum;
58                        __C(pCreateDevEnum.CoCreateInstance(CLSID_SystemDeviceEnum));
59                        CComPtr<IEnumMoniker> pEnumMoniker;
60                        __C(pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnumMoniker, 0));
61                        CComPtr<IMoniker> pMoniker;
62                        while(pEnumMoniker->Next(1, &pMoniker, NULL) == S_OK)
63                        {
64                                _ATLTRY
65                                {
66                                        LPOLESTR pszDisplayName = NULL;
67                                        ATLVERIFY(SUCCEEDED(pMoniker->GetDisplayName(NULL, NULL, &pszDisplayName)));
68                                        // TODO: Free pszDisplayName
69                                        if(pszDisplayName)
70                                                _tprintf(_T("Moniker Display Name: %ls\n"), pszDisplayName);
71                                        CComPtr<IPropertyBag> pPropertyBag;
72                                        __C(pMoniker->BindToStorage(NULL, NULL, __uuidof(IPropertyBag), (VOID**) &pPropertyBag));
73                                        CComVariant vFriendlyName;
74                                        __C(pPropertyBag->Read(L"FriendlyName", &vFriendlyName, NULL));
75                                        __D(vFriendlyName.vt == VT_BSTR, E_FAIL);
76                                        _tprintf(_T("Friendly Name: %s\n"), CString(vFriendlyName.bstrVal));
77                                        CComPtr<IBaseFilter> pBaseFilter;
78                                        __C(pMoniker->BindToObject(NULL, NULL, __uuidof(IBaseFilter), (VOID**) &pBaseFilter));
79                                        #pragma region DeckLink Specific
80                                        const CComQIPtr<DecklinkPublicLib::IDecklinkIOControl> pDecklinkIoControl = pBaseFilter;
81                                        if(pDecklinkIoControl)
82                                                _ATLTRY
83                                                {
84                                                        ULONG nIoFeatures = 0;
85                                                        __C(pDecklinkIoControl->GetIOFeatures(&nIoFeatures));
86                                                        _tprintf(_T("DeckLink IO Features: 0x%08x\n"), nIoFeatures);
87                                                }
88                                                _ATLCATCHALL()
89                                                {
90                                                }
91                                        #pragma endregion
92                                        CComPtr<IEnumPins> pEnumPins;
93                                        __C(pBaseFilter->EnumPins(&pEnumPins));
94                                        CComPtr<IPin> pPin;
95                                        while(pEnumPins->Next(1, &pPin, NULL) == S_OK)
96                                        {
97                                                _ATLTRY
98                                                {
99                                                        PIN_INFO PinInformation;
100                                                        __C(pPin->QueryPinInfo(&PinInformation));
101                                                        reinterpret_cast<CComPtr<IBaseFilter>&>(PinInformation.pFilter) = NULL;
102                                                        _tprintf(_T("  Pin: %s\n"), CString(PinInformation.achName));
103                                                        #pragma region pKsPropertySet
104                                                        const CComQIPtr<IKsPropertySet> pKsPropertySet = pPin;
105                                                        if(pKsPropertySet)
106                                                        {
107                                                                GUID Category;
108                                                                DWORD nCategorySize;
109                                                                const HRESULT nGetResult = pKsPropertySet->Get(AMPROPSETID_Pin, AMPROPERTY_PIN_CATEGORY, NULL, 0, &Category, sizeof Category, &nCategorySize);
110                                                                if(SUCCEEDED(nGetResult))
111                                                                {
112                                                                        if(nCategorySize == sizeof Category)
113                                                                        {
114                                                                                // NOTE: Pin Property Set (Windows) http://msdn.microsoft.com/en-us/library/windows/desktop/dd377429%28v=vs.85%29.aspx
115                                                                                static const struct 
116                                                                                { 
117                                                                                        const GUID* pCategory; 
118                                                                                        LPCSTR pszName; 
119                                                                                } g_pMap[] = 
120                                                                                {
121                                                                                        #define A(x) { &x, #x },
122                                                                                        A(PIN_CATEGORY_CAPTURE)
123                                                                                        A(PIN_CATEGORY_PREVIEW)
124                                                                                        A(PIN_CATEGORY_ANALOGVIDEOIN)
125                                                                                        A(PIN_CATEGORY_VBI)
126                                                                                        A(PIN_CATEGORY_VIDEOPORT)
127                                                                                        A(PIN_CATEGORY_NABTS)
128                                                                                        A(PIN_CATEGORY_EDS)
129                                                                                        A(PIN_CATEGORY_TELETEXT)
130                                                                                        A(PIN_CATEGORY_CC)
131                                                                                        A(PIN_CATEGORY_STILL)
132                                                                                        A(PIN_CATEGORY_TIMECODE)
133                                                                                        A(PIN_CATEGORY_VIDEOPORT_VBI)
134                                                                                        #undef A
135                                                                                };
136                                                                                OLECHAR pszCategory[64] = { 0 };
137                                                                                ATLVERIFY(StringFromGUID2(Category, pszCategory, _countof(pszCategory)));
138                                                                                CString sCategory(pszCategory);
139                                                                                for(SIZE_T nIndex = 0; nIndex < _countof(g_pMap); nIndex++)
140                                                                                        if(*g_pMap[nIndex].pCategory == Category)
141                                                                                        {
142                                                                                                sCategory.AppendFormat(_T(" %hs"), g_pMap[nIndex].pszName);
143                                                                                                break;
144                                                                                        }
145                                                                                _tprintf(_T("    AMPROPSETID_Pin, AMPROPERTY_PIN_CATEGORY: %s\n"), sCategory);
146                                                                        } else
147                                                                                _tprintf(_T("    AMPROPSETID_Pin, AMPROPERTY_PIN_CATEGORY: Failed to Get Pin Category 0x%08x, %d (expected %d)\n"), nGetResult, nCategorySize, sizeof Category);
148                                                                } else
149                                                                        _tprintf(_T("    AMPROPSETID_Pin, AMPROPERTY_PIN_CATEGORY: Failed to Get Pin Category 0x%08x\n"), nGetResult);
150                                                        }
151                                                        #pragma endregion
152                                                        #pragma region IAMStreamConfig
153                                                        const CComQIPtr<IAMStreamConfig> pAmStreamConfig = pPin;
154                                                        if(pAmStreamConfig)
155                                                        {
156                                                                INT nCapabilityCount = 0;
157                                                                INT nSize = 0;
158                                                                __C(pAmStreamConfig->GetNumberOfCapabilities(&nCapabilityCount, &nSize));
159                                                                _tprintf(_T("    Capability Count: %d\n"), nCapabilityCount);
160                                                                _tprintf(_T("    Structure Size: %d (expected %d)\n"), nSize, sizeof (VIDEO_STREAM_CONFIG_CAPS));
161                                                                CTempBuffer<VIDEO_STREAM_CONFIG_CAPS> pCapability;
162                                                                __D(nSize >= sizeof *pCapability, E_FAIL);
163                                                                __D(pCapability.AllocateBytes(nSize), E_OUTOFMEMORY);
164                                                                for(INT nCapabilityIndex = 0; nCapabilityIndex < nCapabilityCount; nCapabilityIndex++)
165                                                                {
166                                                                        _tprintf(_T("    Capability %d:\n"), nCapabilityIndex);
167                                                                        AM_MEDIA_TYPE* pMediaType = NULL;
168                                                                        __C(pAmStreamConfig->GetStreamCaps(nCapabilityIndex, &pMediaType, (BYTE*) (VIDEO_STREAM_CONFIG_CAPS*) pCapability));
169                                                                        ATLASSERT(pMediaType);
170                                                                        // TODO: Free pMediaType
171                                                                        _tprintf(_T("    AM_MEDIA_TYPE:\n"));
172                                                                        _tprintf(_T("      Media Type Data: %s\n"), StringFromData(pMediaType, sizeof *pMediaType));
173                                                                        if(pMediaType->cbFormat)
174                                                                                _tprintf(_T("      Media Type Format Data: %s\n"), StringFromData(pMediaType->pbFormat, pMediaType->cbFormat));
175                                                                        // SUGG: majortype, subtype
176                                                                        if(memcmp((const BYTE*) &pMediaType->subtype + sizeof (DWORD), (const BYTE*) &MEDIASUBTYPE_MJPG + sizeof (DWORD), sizeof (GUID) -  sizeof (DWORD)) == 0)
177                                                                        {
178                                                                                const CString sSubtypeCode = StringFromCode(pMediaType->subtype.Data1);
179                                                                                if(!sSubtypeCode.IsEmpty())
180                                                                                        _tprintf(_T("      .subtype: %s\n"), sSubtypeCode);
181                                                                        }
182                                                                        _tprintf(_T("      .bFixedSizeSamples: %d\n"), pMediaType->bFixedSizeSamples);
183                                                                        _tprintf(_T("      .bTemporalCompression: %d\n"), pMediaType->bTemporalCompression);
184                                                                        _tprintf(_T("      .lSampleSize: %d\n"), pMediaType->lSampleSize);
185                                                                        // SUGG: formattype, pUnk
186                                                                        _tprintf(_T("      .cbFormat: %d\n"), pMediaType->cbFormat);
187                                                                        const BYTE* pnExtraData = pMediaType->pbFormat;
188                                                                        SIZE_T nExtraDataSize = pMediaType->cbFormat;
189                                                                        if(pMediaType->formattype == FORMAT_VideoInfo)
190                                                                        {
191                                                                                const VIDEOINFOHEADER* pVideoInfoHeader = (VIDEOINFOHEADER*) pMediaType->pbFormat;
192                                                                                _tprintf(_T("    VIDEOINFOHEADER:\n"));
193                                                                                _tprintf(_T("      .rcSource: (%d, %d) - (%d, %d)\n"), pVideoInfoHeader->rcSource);
194                                                                                _tprintf(_T("      .rcSource: (%d, %d) - (%d, %d)\n"), pVideoInfoHeader->rcTarget);
195                                                                                _tprintf(_T("      .dwBitRate: %d\n"), pVideoInfoHeader->dwBitRate);
196                                                                                _tprintf(_T("      .dwBitErrorRate: %d\n"), pVideoInfoHeader->dwBitErrorRate);
197                                                                                _tprintf(_T("      .AvgTimePerFrame: %I64d\n"), pVideoInfoHeader->AvgTimePerFrame);
198                                                                                _tprintf(_T("      BITMAPINFOHEADER:\n"));
199                                                                                _tprintf(_T("        .biSize: %d\n"), pVideoInfoHeader->bmiHeader.biSize);
200                                                                                _tprintf(_T("        .biWidth: %d\n"), pVideoInfoHeader->bmiHeader.biWidth);
201                                                                                _tprintf(_T("        .biHeight: %d\n"), pVideoInfoHeader->bmiHeader.biHeight);
202                                                                                _tprintf(_T("        .biPlanes: %d\n"), pVideoInfoHeader->bmiHeader.biPlanes);
203                                                                                _tprintf(_T("        .biBitCount: %d\n"), pVideoInfoHeader->bmiHeader.biBitCount);
204                                                                                _tprintf(_T("        .biCompression: %d %s\n"), pVideoInfoHeader->bmiHeader.biCompression, StringFromCode(pVideoInfoHeader->bmiHeader.biCompression));
205                                                                                _tprintf(_T("        .biSizeImage: %d\n"), pVideoInfoHeader->bmiHeader.biSizeImage);
206                                                                                pnExtraData += sizeof *pVideoInfoHeader;
207                                                                                nExtraDataSize -= sizeof *pVideoInfoHeader;
208                                                                        } else
209                                                                        if(pMediaType->formattype == FORMAT_VideoInfo2)
210                                                                        {
211                                                                                const VIDEOINFOHEADER2* pVideoInfoHeader2 = (VIDEOINFOHEADER2*) pMediaType->pbFormat;
212                                                                                _tprintf(_T("    VIDEOINFOHEADER2:\n"));
213                                                                                // SUGG: Extra data
214                                                                                pnExtraData += sizeof *pVideoInfoHeader2;
215                                                                                nExtraDataSize -= sizeof *pVideoInfoHeader2;
216                                                                        }
217                                                                        if(nExtraDataSize > 0)
218                                                                        {
219                                                                                CString sLine;
220                                                                                for(SIZE_T nIndex = 0; nIndex < nExtraDataSize && nIndex < 63; nIndex++)
221                                                                                {
222                                                                                        sLine.AppendFormat(_T("%02X "), pnExtraData[nIndex]);
223                                                                                        if(((nIndex + 1) % 0x10) == 0x00 || nIndex == 62)
224                                                                                        {
225                                                                                                if(nIndex == 62 && nExtraDataSize > nIndex + 1)
226                                                                                                        sLine.Append(_T("..."));
227                                                                                                _tprintf(_T("        Extra [%04X]: %s\n"), nIndex & ~0x000F, sLine);
228                                                                                                sLine.Empty();
229                                                                                        }
230                                                                                }
231                                                                                ATLASSERT(sLine.IsEmpty());
232                                                                        }
233                                                                        ATLASSERT(pCapability->guid == MEDIATYPE_Video);
234                                                                        _tprintf(_T("    VIDEO_STREAM_CONFIG_CAPS:\n"));
235                                                                        _tprintf(_T("      Data: %s\n"), StringFromData((VIDEO_STREAM_CONFIG_CAPS*) pCapability, sizeof *pCapability));
236                                                                        _tprintf(_T("      .VideoStandard: %d\n"), pCapability->VideoStandard);
237                                                                        _tprintf(_T("      .InputSize: %d x %d\n"), pCapability->InputSize);
238                                                                        _tprintf(_T("      .MinCroppingSize: %d x %d\n"), pCapability->MinCroppingSize);
239                                                                        _tprintf(_T("      .MaxCroppingSize: %d x %d\n"), pCapability->MaxCroppingSize);
240                                                                        _tprintf(_T("      .CropGranularityX: %d\n"), pCapability->CropGranularityX);
241                                                                        _tprintf(_T("      .CropAlignX: %d\n"), pCapability->CropAlignX);
242                                                                        _tprintf(_T("      .CropAlignY: %d\n"), pCapability->CropAlignY);
243                                                                        _tprintf(_T("      .MinOutputSize: %d x %d\n"), pCapability->MinOutputSize);
244                                                                        _tprintf(_T("      .MaxOutputSize: %d x %d\n"), pCapability->MaxOutputSize);
245                                                                        _tprintf(_T("      .OutputGranularityX: %d\n"), pCapability->OutputGranularityX);
246                                                                        _tprintf(_T("      .OutputGranularityY: %d\n"), pCapability->OutputGranularityY);
247                                                                        _tprintf(_T("      .StretchTapsX: %d\n"), pCapability->StretchTapsX);
248                                                                        _tprintf(_T("      .StretchTapsY: %d\n"), pCapability->StretchTapsY);
249                                                                        _tprintf(_T("      .ShrinkTapsX: %d\n"), pCapability->ShrinkTapsX);
250                                                                        _tprintf(_T("      .ShrinkTapsY: %d\n"), pCapability->ShrinkTapsY);
251                                                                        _tprintf(_T("      .MinFrameInterval: %I64d\n"), pCapability->MinFrameInterval);
252                                                                        _tprintf(_T("      .MaxFrameInterval: %I64d\n"), pCapability->MaxFrameInterval);
253                                                                        _tprintf(_T("      .MinBitsPerSecond: %d\n"), pCapability->MinBitsPerSecond);
254                                                                        _tprintf(_T("      .MaxBitsPerSecond: %d\n"), pCapability->MaxBitsPerSecond);
255                                                                }
256                                                        }
257                                                        #pragma endregion
258                                                }
259                                                _ATLCATCHALL()
260                                                {
261                                                        _tprintf(_T("An exception has been caught\n"));
262                                                }
263                                                pPin.Release();
264                                        }
265                                }
266                                _ATLCATCHALL()
267                                {
268                                        _tprintf(_T("An exception has been caught\n"));
269                                }
270                                pMoniker.Release();
271                                _tprintf(_T("\n"));
272                        }
273                }
274                _ATLCATCHALL()
275                {
276                        CoUninitialize();
277                        _ATLRETHROW;
278                }
279                CoUninitialize();
280        }
281        _ATLCATCHALL()
282        {
283        }
284        return 0;
285}
286
Note: See TracBrowser for help on using the repository browser.