1 | //////////////////////////////////////////////////////////// |
---|
2 | // Copyright (C) Roman Ryltsov, 2008-2011 |
---|
3 | // Created by Roman Ryltsov roman@alax.info |
---|
4 | // |
---|
5 | // $Id: SetLifeCamStudioResolutionSample.cpp 15 2011-09-13 07:19:11Z roman $ |
---|
6 | |
---|
7 | #include "stdafx.h" |
---|
8 | #include <dshow.h> |
---|
9 | //#include <qedit.h> |
---|
10 | |
---|
11 | #pragma comment(lib, "strmiids.lib") |
---|
12 | |
---|
13 | #pragma region Formerly located in qedit.h in Windows SDK, now obsoleted and defined within project |
---|
14 | |
---|
15 | struct __declspec(uuid("0579154a-2b53-4994-b0d0-e773148eff85")) |
---|
16 | ISampleGrabberCB : IUnknown |
---|
17 | { |
---|
18 | // |
---|
19 | // Raw methods provided by interface |
---|
20 | // |
---|
21 | |
---|
22 | virtual HRESULT __stdcall SampleCB ( |
---|
23 | double SampleTime, |
---|
24 | struct IMediaSample * pSample ) = 0; |
---|
25 | virtual HRESULT __stdcall BufferCB ( |
---|
26 | double SampleTime, |
---|
27 | unsigned char * pBuffer, |
---|
28 | long BufferLen ) = 0; |
---|
29 | }; |
---|
30 | |
---|
31 | struct __declspec(uuid("6b652fff-11fe-4fce-92ad-0266b5d7c78f")) |
---|
32 | ISampleGrabber : IUnknown |
---|
33 | { |
---|
34 | // |
---|
35 | // Raw methods provided by interface |
---|
36 | // |
---|
37 | |
---|
38 | virtual HRESULT __stdcall SetOneShot ( |
---|
39 | long OneShot ) = 0; |
---|
40 | virtual HRESULT __stdcall SetMediaType ( |
---|
41 | struct _AMMediaType * pType ) = 0; |
---|
42 | virtual HRESULT __stdcall GetConnectedMediaType ( |
---|
43 | struct _AMMediaType * pType ) = 0; |
---|
44 | virtual HRESULT __stdcall SetBufferSamples ( |
---|
45 | long BufferThem ) = 0; |
---|
46 | virtual HRESULT __stdcall GetCurrentBuffer ( |
---|
47 | /*[in,out]*/ long * pBufferSize, |
---|
48 | /*[out]*/ long * pBuffer ) = 0; |
---|
49 | virtual HRESULT __stdcall GetCurrentSample ( |
---|
50 | /*[out,retval]*/ struct IMediaSample * * ppSample ) = 0; |
---|
51 | virtual HRESULT __stdcall SetCallback ( |
---|
52 | struct ISampleGrabberCB * pCallback, |
---|
53 | long WhichMethodToCallback ) = 0; |
---|
54 | }; |
---|
55 | |
---|
56 | struct __declspec(uuid("c1f400a0-3f08-11d3-9f0b-006008039e37")) |
---|
57 | SampleGrabber; |
---|
58 | // [ default ] interface ISampleGrabber |
---|
59 | |
---|
60 | #pragma endregion |
---|
61 | |
---|
62 | #undef ATLENSURE_SUCCEEDED |
---|
63 | #define ATLENSURE_SUCCEEDED(x) { HRESULT __a = (x); if(FAILED(__a)) { _tprintf(_T("Error 0x%08x in line %d\n"), __a, __LINE__); AtlThrow(__a); } } |
---|
64 | |
---|
65 | CComPtr<IPin> GetPin(IBaseFilter* pBaseFilter, SIZE_T nIndex = 0) |
---|
66 | { |
---|
67 | ATLASSERT(pBaseFilter); |
---|
68 | CComPtr<IEnumPins> pEnumPins; |
---|
69 | ATLENSURE_SUCCEEDED(pBaseFilter->EnumPins(&pEnumPins)); |
---|
70 | ATLASSERT(pEnumPins); |
---|
71 | for(; ; nIndex--) |
---|
72 | { |
---|
73 | CComPtr<IPin> pPin; |
---|
74 | ATLENSURE_SUCCEEDED(pEnumPins->Next(1, &pPin, NULL) == S_OK); |
---|
75 | ATLASSERT(pPin); |
---|
76 | if(nIndex == 0) |
---|
77 | return pPin; |
---|
78 | } |
---|
79 | AtlThrow(E_UNEXPECTED); |
---|
80 | } |
---|
81 | |
---|
82 | int _tmain(int argc, _TCHAR* argv[]) |
---|
83 | { |
---|
84 | CoInitialize(NULL); |
---|
85 | _ATLTRY |
---|
86 | { |
---|
87 | CComPtr<IFilterGraph2> pFilterGraph; |
---|
88 | ATLENSURE_SUCCEEDED(pFilterGraph.CoCreateInstance(CLSID_FilterGraph)); |
---|
89 | #pragma region Camera (Source) Filter |
---|
90 | CComPtr<ICreateDevEnum> pCreateDevEnum; |
---|
91 | ATLENSURE_SUCCEEDED(pCreateDevEnum.CoCreateInstance(CLSID_SystemDeviceEnum)); |
---|
92 | CComPtr<IEnumMoniker> pEnumMoniker; |
---|
93 | ATLENSURE_SUCCEEDED(pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnumMoniker, 0)); |
---|
94 | CComPtr<IMoniker> pMoniker; |
---|
95 | for(LONG nSkipCount = 0; ; nSkipCount--) // Adjust to skip certain number of devices until you reach the one you need |
---|
96 | { |
---|
97 | ATLENSURE_THROW(pEnumMoniker->Next(1, &pMoniker, NULL) == S_OK, E_FAIL); |
---|
98 | ATLASSERT(pMoniker); |
---|
99 | if(nSkipCount <= 0) |
---|
100 | break; |
---|
101 | pMoniker.Release(); |
---|
102 | } |
---|
103 | ATLASSERT(pMoniker); |
---|
104 | CComPtr<IBindCtx> pBindCtx; |
---|
105 | ATLENSURE_SUCCEEDED(CreateBindCtx(0, &pBindCtx)); |
---|
106 | CComPtr<IBaseFilter> pSourceBaseFilter; |
---|
107 | ATLENSURE_SUCCEEDED(pMoniker->BindToObject(pBindCtx, NULL, __uuidof(IBaseFilter), (VOID**) &pSourceBaseFilter)); |
---|
108 | ATLASSERT(pSourceBaseFilter); |
---|
109 | ATLENSURE_SUCCEEDED(pFilterGraph->AddFilter(pSourceBaseFilter, L"Source")); |
---|
110 | CComPtr<IPin> pCurrentOutputPin; |
---|
111 | #pragma region Resolution |
---|
112 | { |
---|
113 | const CComPtr<IPin> pPin = GetPin(pSourceBaseFilter); |
---|
114 | const CComQIPtr<IAMStreamConfig> pAmStreamConfig = pPin; |
---|
115 | ATLASSERT(pAmStreamConfig); |
---|
116 | VIDEOINFOHEADER VideoInfoHeader = |
---|
117 | { |
---|
118 | { 0, 0, 0, 0 }, |
---|
119 | { 0, 0, 0, 0 }, |
---|
120 | 0, |
---|
121 | 0, |
---|
122 | 1000 * 10000i64 / 30, // 30 fps |
---|
123 | { |
---|
124 | sizeof BITMAPINFOHEADER, |
---|
125 | 512, |
---|
126 | 384, |
---|
127 | 1, |
---|
128 | 16, |
---|
129 | MEDIASUBTYPE_YUY2.Data1, |
---|
130 | 384 * 512 * 12 / 8, |
---|
131 | 0, |
---|
132 | 0, |
---|
133 | 0, |
---|
134 | 0, |
---|
135 | } |
---|
136 | }; |
---|
137 | AM_MEDIA_TYPE MediaType = |
---|
138 | { |
---|
139 | MEDIATYPE_Video, |
---|
140 | MEDIASUBTYPE_YUY2, |
---|
141 | TRUE, |
---|
142 | FALSE, |
---|
143 | VideoInfoHeader.bmiHeader.biSizeImage, |
---|
144 | FORMAT_VideoInfo, |
---|
145 | NULL, |
---|
146 | sizeof VideoInfoHeader, |
---|
147 | (BYTE*) &VideoInfoHeader |
---|
148 | }; |
---|
149 | //ATLENSURE_SUCCEEDED(pAmStreamConfig->SetFormat(&MediaType)); |
---|
150 | MessageBox(GetActiveWindow(), _T("After IAMStreamConfig::SetFormat Set"), _T("Debug"), MB_OK); |
---|
151 | pCurrentOutputPin = pPin; |
---|
152 | } |
---|
153 | #pragma endregion |
---|
154 | #pragma endregion |
---|
155 | #pragma region Non-RGB Sample Grabber |
---|
156 | { |
---|
157 | CComPtr<IBaseFilter> pBaseFilter; |
---|
158 | ATLENSURE_SUCCEEDED(pBaseFilter.CoCreateInstance(__uuidof(SampleGrabber))); |
---|
159 | ATLENSURE_SUCCEEDED(pFilterGraph->AddFilter(pBaseFilter, L"Non-RGB Sample Grabber")); // This will connect in MJPG format |
---|
160 | const CComQIPtr<ISampleGrabber> pSampleGrabber = pBaseFilter; |
---|
161 | ATLASSERT(pSampleGrabber); |
---|
162 | #if TRUE |
---|
163 | // NOTE: IFilterGraph::Connect would do just fine, but with a real capture device, if we prefer having Smart Tee added, we need to use |
---|
164 | // Capture Graph Builder (only here) |
---|
165 | CComPtr<ICaptureGraphBuilder2> pCaptureGraphBuilder; |
---|
166 | ATLENSURE_SUCCEEDED(pCaptureGraphBuilder.CoCreateInstance(CLSID_CaptureGraphBuilder2)); |
---|
167 | ATLENSURE_SUCCEEDED(pCaptureGraphBuilder->SetFiltergraph(pFilterGraph)); |
---|
168 | ATLENSURE_SUCCEEDED(pCaptureGraphBuilder->RenderStream(&PIN_CATEGORY_CAPTURE, NULL, pCurrentOutputPin, NULL, pBaseFilter)); |
---|
169 | #else |
---|
170 | ATLENSURE_SUCCEEDED(pFilterGraph->Connect(pCurrentOutputPin, GetPin(pBaseFilter, 0))); |
---|
171 | #endif |
---|
172 | MessageBox(GetActiveWindow(), _T("After Non-RGB Sample Grabber Connected"), _T("Debug"), MB_OK); |
---|
173 | pCurrentOutputPin = GetPin(pBaseFilter, 1); |
---|
174 | } |
---|
175 | #pragma endregion |
---|
176 | #pragma region RGB Sample Grabber |
---|
177 | { |
---|
178 | CComPtr<IBaseFilter> pBaseFilter; |
---|
179 | ATLENSURE_SUCCEEDED(pBaseFilter.CoCreateInstance(__uuidof(SampleGrabber))); |
---|
180 | ATLENSURE_SUCCEEDED(pFilterGraph->AddFilter(pBaseFilter, L"RGB Sample Grabber")); |
---|
181 | const CComQIPtr<ISampleGrabber> pSampleGrabber = pBaseFilter; |
---|
182 | ATLASSERT(pSampleGrabber); |
---|
183 | AM_MEDIA_TYPE MediaType; |
---|
184 | ZeroMemory(&MediaType, sizeof MediaType); |
---|
185 | MediaType.majortype = MEDIATYPE_Video; |
---|
186 | MediaType.subtype = MEDIASUBTYPE_RGB24; |
---|
187 | ATLENSURE_SUCCEEDED(pSampleGrabber->SetMediaType(&MediaType)); |
---|
188 | ATLENSURE_SUCCEEDED(pFilterGraph->Connect(pCurrentOutputPin, GetPin(pBaseFilter, 0))); |
---|
189 | MessageBox(GetActiveWindow(), _T("After RGB Sample Grabber Connected"), _T("Debug"), MB_OK); |
---|
190 | pCurrentOutputPin = GetPin(pBaseFilter, 1); |
---|
191 | } |
---|
192 | #pragma endregion |
---|
193 | } |
---|
194 | _ATLCATCH(Exception) |
---|
195 | { |
---|
196 | _tprintf(_T("Error 0x%08x\n"), (HRESULT) Exception); |
---|
197 | } |
---|
198 | _ATLCATCHALL() |
---|
199 | { |
---|
200 | _tprintf(_T("Error\n")); |
---|
201 | } |
---|
202 | CoUninitialize(); |
---|
203 | return 0; |
---|
204 | } |
---|
205 | |
---|