[Title] improved camera performance & add win32 dll source
[sdk/emulator/qemu.git] / tizen / src / hw / camera_win32_dll / hwcfilter / hwcfilter / hwcsp.cpp
1 #include "hwcsp.h"\r
2 \r
3 CCallback::CCallback() : m_pCallback(NULL), m_cRef(1)\r
4 {\r
5 }\r
6 \r
7 CCallback::~CCallback()\r
8 {\r
9         if (m_pCallback) {\r
10                 m_pCallback = NULL;\r
11         }\r
12 }\r
13 \r
14 STDMETHODIMP CCallback::QueryInterface(REFIID riid, void **ppv)\r
15 {\r
16         if (riid == IID_IUnknown) {\r
17                 *ppv = static_cast<IUnknown*>(this);\r
18         } else if (riid == IID_ICaptureCallBack) {\r
19                 *ppv = static_cast<ICaptureCallBack*>(this);\r
20         } else {\r
21                 LPWSTR str;\r
22                 StringFromIID(riid, &str);\r
23                 *ppv = NULL;\r
24                 return E_NOINTERFACE;\r
25         }\r
26         reinterpret_cast<IUnknown*>(this)->AddRef();\r
27         return S_OK;\r
28 }\r
29 \r
30 STDMETHODIMP CCallback::CaptureCallback(ULONG dwSize, BYTE *pBuffer)\r
31 {       \r
32         if (m_pCallback(dwSize, pBuffer)) {\r
33                 return S_OK;\r
34         }\r
35         return E_FAIL;\r
36 }\r
37 \r
38 STDMETHODIMP CCallback::SetCallback(CallbackFn pCallbackFn)\r
39 {\r
40         m_pCallback = pCallbackFn;\r
41         return S_OK;\r
42 }\r
43 \r
44 STDMETHODIMP_(ULONG) CCallback::AddRef()\r
45 {\r
46         return InterlockedIncrement(&m_cRef);\r
47 }\r
48 \r
49 STDMETHODIMP_(ULONG) CCallback::Release()\r
50 {\r
51         if( InterlockedDecrement(&m_cRef) == 0)\r
52         {\r
53                 delete this;\r
54                 return 0;\r
55         }\r
56         return m_cRef;\r
57 }\r
58 \r
59 HWCSP::HWCSP()\r
60 {\r
61         CoInitialize(NULL);\r
62         m_pGB = NULL;\r
63         m_pCGB = NULL;\r
64         m_pMC = NULL;\r
65         m_pME = NULL;\r
66         m_pOutputPin = NULL;\r
67         m_pInputPin = NULL;\r
68         m_pDF = NULL;\r
69         m_pSF = NULL;\r
70         m_hDLL = NULL;\r
71         m_pCallback = NULL;\r
72         m_dwFourcc = MAKEFOURCC('Y','U','Y','2');\r
73         m_dwWidth = 640;\r
74         m_dwHeight = 480;\r
75         m_dwAvgInterval = 333333;\r
76 }\r
77 \r
78 HWCSP::~HWCSP()\r
79 {\r
80         CloseInterfaces();\r
81         CoUninitialize();\r
82 }\r
83 \r
84 STDMETHODIMP HWCSP::Init()\r
85 {\r
86         HRESULT hr;\r
87 \r
88         hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC, IID_IGraphBuilder, (void**)&m_pGB);\r
89         if (FAILED(hr))\r
90                 return hr;\r
91 \r
92         hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC, IID_ICaptureGraphBuilder2, (void**)&m_pCGB);\r
93         if (FAILED(hr))\r
94                 return hr;\r
95 \r
96         hr = m_pCGB->SetFiltergraph(m_pGB);\r
97         if (FAILED(hr))\r
98                 return hr;\r
99 \r
100         hr = m_pGB->QueryInterface(IID_IMediaControl, (void **)&m_pMC);\r
101         if (FAILED(hr))\r
102                 return hr;\r
103 \r
104         hr = m_pGB->QueryInterface(IID_IMediaEventEx, (void **)&m_pME);\r
105         if (FAILED(hr))\r
106                 return hr;\r
107 \r
108         m_pCallback = new CCallback;\r
109         if (m_pCallback == NULL)\r
110                 hr = E_OUTOFMEMORY;\r
111 \r
112         return hr;\r
113 }\r
114 \r
115 STDMETHODIMP HWCSP::BindSourceFilter()\r
116 {\r
117         HRESULT hr;\r
118         \r
119         ICreateDevEnum *pCreateDevEnum = NULL;\r
120         hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC, IID_ICreateDevEnum, (void**)&pCreateDevEnum);\r
121         if (FAILED(hr))\r
122                 return hr;\r
123 \r
124         IEnumMoniker *pEnumMK = NULL;\r
125         hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnumMK, 0);\r
126         if (FAILED(hr))\r
127         {\r
128                 pCreateDevEnum->Release();\r
129                 return hr;\r
130         }\r
131         \r
132         if (!pEnumMK)\r
133         {\r
134                 pCreateDevEnum->Release();\r
135                 return E_FAIL;\r
136         }\r
137         pEnumMK->Reset();\r
138 \r
139         IMoniker *pMoniKer;\r
140         hr = pEnumMK->Next(1, &pMoniKer, NULL);\r
141         if (hr == S_FALSE)\r
142         {\r
143                 hr = E_FAIL;\r
144         }\r
145         if (SUCCEEDED(hr))\r
146         {\r
147                 IPropertyBag *pBag = NULL;\r
148                 IBaseFilter *temp = NULL;\r
149                 hr = pMoniKer->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pBag);\r
150                 if(SUCCEEDED(hr)) \r
151                 {\r
152                         VARIANT var;\r
153                         var.vt = VT_BSTR;\r
154                         hr = pBag->Read(L"FriendlyName", &var, NULL);\r
155                         if (hr == NOERROR)\r
156                         {\r
157                                 hr = pMoniKer->BindToObject(NULL, NULL, IID_IBaseFilter, (void**)&m_pDF);\r
158                                 if (FAILED(hr))\r
159                                 {\r
160                                         //Counldn't bind moniker to filter object!!\r
161                                 }\r
162                                 else\r
163                                 {\r
164                                         m_pDF->AddRef();\r
165                                 }\r
166                                 SysFreeString(var.bstrVal);\r
167                         }\r
168                         pBag->Release();\r
169                 }\r
170                 pMoniKer->Release();\r
171         }\r
172 \r
173         if (SUCCEEDED(hr))\r
174         {\r
175                 hr = m_pGB->AddFilter(m_pDF, L"Video Capture");\r
176                 if (hr != S_OK && hr != S_FALSE)\r
177                 {\r
178                         //Counldn't add Video Capture filter to our graph!\r
179                 }\r
180         }\r
181 \r
182         return hr;\r
183 }\r
184 \r
185 STDMETHODIMP HWCSP::BindTargetFilter()\r
186 {\r
187         HRESULT hr;\r
188         IClassFactory *pClassFactory= NULL;\r
189         hr = DllGetClassObject(CLSID_HWCFilterClass, IID_IClassFactory, (void**)&pClassFactory);\r
190         if (FAILED(hr))\r
191                 return hr;\r
192 \r
193         IBaseFilter *pHWCFilter = NULL;\r
194         pClassFactory->CreateInstance(NULL, IID_IBaseFilter, (void**)&pHWCFilter);\r
195         if (FAILED(hr))\r
196         {\r
197                 SAFE_RELEASE(pClassFactory);\r
198                 return hr;\r
199         }\r
200         m_pSF = pHWCFilter;\r
201 \r
202         if (SUCCEEDED(hr))\r
203         {\r
204                 hr = m_pGB->AddFilter(m_pSF, L"HWCFilter");\r
205                 if (FAILED(hr))\r
206                 {\r
207                         //Counldn't add HWCFilterr to our graph!\r
208                 }\r
209         }\r
210         SAFE_RELEASE(pClassFactory);\r
211         \r
212         return hr;\r
213 }\r
214 \r
215 STDMETHODIMP HWCSP::ConnectFilters()\r
216 {\r
217         HRESULT hr;\r
218 \r
219         hr = GetPin(m_pDF, PINDIR_OUTPUT , &m_pOutputPin);\r
220         if (FAILED(hr))\r
221                 return hr;\r
222 \r
223         hr = GetPin(m_pSF, PINDIR_INPUT , &m_pInputPin);\r
224         if (FAILED(hr))\r
225                 return hr;\r
226 \r
227         hr = m_pGB->Connect(m_pOutputPin, m_pInputPin);\r
228         return hr;\r
229 }\r
230 \r
231 STDMETHODIMP_(void) HWCSP::CloseInterfaces() \r
232 {\r
233         if (m_pMC)\r
234                 m_pMC->Stop();\r
235         \r
236         if (m_pOutputPin)\r
237                 m_pOutputPin->Disconnect();\r
238 \r
239         SAFE_RELEASE(m_pGB);\r
240         SAFE_RELEASE(m_pCGB);\r
241         SAFE_RELEASE(m_pMC);\r
242         SAFE_RELEASE(m_pME);\r
243         SAFE_RELEASE(m_pOutputPin);\r
244         SAFE_RELEASE(m_pInputPin);\r
245         SAFE_RELEASE(m_pDF);\r
246         SAFE_RELEASE(m_pSF);\r
247         SAFE_RELEASE(m_pCallback);\r
248 \r
249         if (m_hDLL) {\r
250                 FreeLibrary(m_hDLL);\r
251                 m_hDLL = NULL;\r
252         }\r
253 }\r
254 \r
255 STDMETHODIMP_(void) HWCSP::DeleteMediaType(AM_MEDIA_TYPE *pmt)\r
256 {\r
257         if (pmt == NULL) {\r
258                 return;\r
259         }\r
260 \r
261         if (pmt->cbFormat != 0) {\r
262                 CoTaskMemFree((PVOID)pmt->pbFormat);\r
263                 pmt->cbFormat = 0;\r
264                 pmt->pbFormat = NULL;\r
265         }\r
266         if (pmt->pUnk != NULL) {\r
267                 pmt->pUnk->Release();\r
268                 pmt->pUnk = NULL;\r
269         }\r
270 \r
271         CoTaskMemFree((PVOID)pmt);\r
272 }\r
273 \r
274 STDMETHODIMP HWCSP::GetPin(IBaseFilter *pFilter, PIN_DIRECTION PinDir, IPin **ppPin)\r
275 {\r
276         HRESULT hr;\r
277         IEnumPins *pEnum = NULL;\r
278         IPin *pPin = NULL;\r
279 \r
280         if (ppPin == NULL)\r
281         {\r
282                 return E_POINTER;\r
283         }\r
284 \r
285         hr = pFilter->EnumPins(&pEnum);\r
286         if (FAILED(hr))\r
287                 return hr;\r
288 \r
289         while(pEnum->Next(1, &pPin, 0) == S_OK)\r
290         {\r
291                 PIN_DIRECTION PinDirThis;\r
292                 hr = pPin->QueryDirection(&PinDirThis);\r
293                 if (FAILED(hr))\r
294                 {\r
295                         SAFE_RELEASE(pPin);\r
296                         SAFE_RELEASE(pEnum);\r
297                         return hr;\r
298                 }\r
299                 if (PinDir == PinDirThis)\r
300                 {\r
301                         *ppPin = pPin;\r
302                         SAFE_RELEASE(pEnum);\r
303                         return S_OK;\r
304                 }\r
305                 SAFE_RELEASE(pPin);\r
306         }\r
307 \r
308         SAFE_RELEASE(pEnum);\r
309         return S_FALSE;\r
310 }\r
311 \r
312 STDMETHODIMP HWCSP::QueryVideoProcAmp(long nProperty, long *pMin, long *pMax, long *pStep, long *pDefault)\r
313 {\r
314         HRESULT hr;\r
315 \r
316         IAMVideoProcAmp *pProcAmp = NULL;\r
317         hr = m_pDF->QueryInterface(IID_IAMVideoProcAmp, (void**)&pProcAmp);\r
318         if (FAILED(hr))\r
319         {\r
320                 return hr;\r
321         }\r
322 \r
323         long Flags;\r
324         hr = pProcAmp->GetRange(nProperty, pMin, pMax, pStep, pDefault, &Flags);\r
325 \r
326         SAFE_RELEASE(pProcAmp);\r
327         return hr;\r
328 }\r
329 \r
330 STDMETHODIMP HWCSP::GetVideoProcAmp(long nProperty, long *pValue)\r
331 {\r
332         HRESULT hr;\r
333 \r
334         IAMVideoProcAmp *pProcAmp = NULL;\r
335         hr = m_pDF->QueryInterface(IID_IAMVideoProcAmp, (void**)&pProcAmp);\r
336         if (FAILED(hr))\r
337                 return hr;\r
338 \r
339         long Flags;\r
340         hr = pProcAmp->Get(nProperty, pValue, &Flags);\r
341         if (FAILED(hr))\r
342         {\r
343         }\r
344         SAFE_RELEASE(pProcAmp);\r
345         return hr;\r
346 }\r
347 \r
348 STDMETHODIMP HWCSP::SetVideoProcAmp(long nProperty, long value)\r
349 {\r
350         HRESULT hr;\r
351 \r
352         IAMVideoProcAmp *pProcAmp = NULL;\r
353         hr = m_pDF->QueryInterface(IID_IAMVideoProcAmp, (void**)&pProcAmp);\r
354         if (FAILED(hr))\r
355                 return hr;\r
356 \r
357         hr = pProcAmp->Set(nProperty, value, VideoProcAmp_Flags_Manual);\r
358         SAFE_RELEASE(pProcAmp);\r
359         return hr;\r
360 }\r
361 \r
362 STDMETHODIMP HWCSP::StartPreview()\r
363 {\r
364         HRESULT hr;\r
365 \r
366         hr = ((IHWCPin*)m_pInputPin)->SetCallback((ICaptureCallBack*)m_pCallback);\r
367         if (FAILED(hr)) \r
368                 return hr;\r
369 \r
370         hr = m_pMC->Run();\r
371         return hr;\r
372 }\r
373 \r
374 STDMETHODIMP HWCSP::StopPreview()\r
375 {\r
376         HRESULT hr;\r
377         hr = ((IHWCPin*)m_pInputPin)->SetCallback(NULL);\r
378 \r
379         if (SUCCEEDED(hr))\r
380                 hr = m_pMC->Stop();\r
381         return hr;\r
382 }\r
383 STDMETHODIMP HWCSP::GetDeviceCaps(ULONG *fourcc, ULONG *width, ULONG *height, ULONG *fps)\r
384 {\r
385         HRESULT hr;\r
386         IAMStreamConfig* vsc = NULL;\r
387         AM_MEDIA_TYPE* pmt = NULL;\r
388         hr = m_pCGB->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, m_pDF, IID_IAMStreamConfig, (void**)&vsc);\r
389         if (FAILED(hr))\r
390                 return hr;\r
391 \r
392         hr = vsc->GetFormat(&pmt);\r
393         if (FAILED(hr)) \r
394         {\r
395                 vsc->Release();\r
396                 return hr;\r
397         }\r
398 \r
399         if (pmt != NULL)\r
400         {\r
401                 if (pmt->formattype == FORMAT_VideoInfo)\r
402                 {\r
403                         VIDEOINFOHEADER* pvi = (VIDEOINFOHEADER*)pmt->pbFormat;\r
404                         if (pvi->bmiHeader.biBitCount == 24 && pvi->bmiHeader.biCompression == BI_RGB) {\r
405                                 *fourcc = MAKEFOURCC('R', 'G', 'B', '3');\r
406                         } else {\r
407                                 *fourcc = (ULONG)pvi->bmiHeader.biCompression;\r
408                         }\r
409                         *width = (ULONG)pvi->bmiHeader.biWidth;\r
410                         *height = (ULONG)pvi->bmiHeader.biHeight;\r
411                         *fps = (ULONG)pvi->AvgTimePerFrame;\r
412                 }\r
413                 DeleteMediaType(pmt);\r
414         }\r
415         vsc->Release();\r
416 \r
417         return hr;\r
418 }\r
419 \r
420 STDMETHODIMP HWCSP::SetFPS(REFERENCE_TIME inFps)\r
421 {\r
422         HRESULT hr;\r
423         IAMStreamConfig* vsc = NULL;\r
424         AM_MEDIA_TYPE* pmt = NULL;\r
425         hr = m_pCGB->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, m_pDF, IID_IAMStreamConfig, (void**)&vsc);\r
426         if (FAILED(hr))\r
427                 return hr;\r
428 \r
429         hr = vsc->GetFormat(&pmt);\r
430         if (FAILED(hr))\r
431         {\r
432                 vsc->Release();\r
433                 return hr;\r
434         }\r
435 \r
436         if (pmt != NULL)\r
437         {\r
438                 if (pmt->formattype == FORMAT_VideoInfo)\r
439                 {\r
440                         VIDEOINFOHEADER* pvi = (VIDEOINFOHEADER*)pmt->pbFormat;\r
441                         pvi->AvgTimePerFrame = inFps;\r
442                         hr = vsc->SetFormat(pmt);\r
443                 }\r
444                 DeleteMediaType(pmt);\r
445         }\r
446         vsc->Release();\r
447         return hr;\r
448 }\r
449 \r
450 STDMETHODIMP HWCSP::GetFPS(REFERENCE_TIME *outFps)\r
451 {\r
452         HRESULT hr;\r
453         IAMStreamConfig* vsc = NULL;\r
454         AM_MEDIA_TYPE* pmt = NULL;\r
455         hr = m_pCGB->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, m_pDF, IID_IAMStreamConfig, (void**)&vsc);\r
456         if (FAILED(hr))\r
457                 return hr;\r
458 \r
459         hr = vsc->GetFormat(&pmt);\r
460         if (FAILED(hr))\r
461         {\r
462                 vsc->Release();\r
463                 return hr;\r
464         }\r
465 \r
466         if (pmt != NULL)\r
467         {\r
468                 if (pmt->formattype == FORMAT_VideoInfo)\r
469                 {\r
470                         VIDEOINFOHEADER* pvi = (VIDEOINFOHEADER*)pmt->pbFormat;\r
471                         *outFps = pvi->AvgTimePerFrame;\r
472                 }\r
473                 DeleteMediaType(pmt);\r
474         }\r
475         vsc->Release();\r
476         return hr;\r
477 }\r
478 \r
479 \r
480 STDMETHODIMP HWCSP::SetResolution(LONG width, LONG height)\r
481 {\r
482         HRESULT hr;\r
483         IAMStreamConfig* vsc = NULL;\r
484         AM_MEDIA_TYPE* pmt = NULL;\r
485         hr = m_pCGB->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, m_pDF, IID_IAMStreamConfig, (void**)&vsc);\r
486         if (FAILED(hr))\r
487                 return hr;\r
488 \r
489         hr = vsc->GetFormat(&pmt);\r
490         if (FAILED(hr))\r
491         {\r
492                 vsc->Release();\r
493                 return hr;\r
494         }\r
495 \r
496         if (pmt != NULL)\r
497         {\r
498                 if (pmt->formattype == FORMAT_VideoInfo)\r
499                 {\r
500                         VIDEOINFOHEADER* pvi = (VIDEOINFOHEADER*)pmt->pbFormat;\r
501                         pvi->bmiHeader.biWidth = width;\r
502                         pvi->bmiHeader.biHeight = height;\r
503                         pvi->AvgTimePerFrame = 333333;\r
504                         pvi->bmiHeader.biSizeImage = ((width * pvi->bmiHeader.biBitCount) >> 3 ) * height;\r
505                         hr = vsc->SetFormat(pmt);\r
506                 }\r
507                 DeleteMediaType(pmt);\r
508         }\r
509         vsc->Release();\r
510         return hr;\r
511 }\r
512 \r
513 STDMETHODIMP HWCSP::GetResolution(LONG *width, LONG *height)\r
514 {\r
515         HRESULT hr;\r
516         IAMStreamConfig* vsc = NULL;\r
517         AM_MEDIA_TYPE* pmt = NULL;\r
518         hr = m_pCGB->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, m_pDF, IID_IAMStreamConfig, (void**)&vsc);\r
519         if (FAILED(hr))\r
520                 return hr;\r
521 \r
522         hr = vsc->GetFormat(&pmt);\r
523         if (FAILED(hr))\r
524         {\r
525                 vsc->Release();\r
526                 return hr;\r
527         }\r
528 \r
529         if (pmt != NULL)\r
530         {\r
531                 if (pmt->formattype == FORMAT_VideoInfo)\r
532                 {\r
533                         VIDEOINFOHEADER* pvi = (VIDEOINFOHEADER*)pmt->pbFormat;\r
534                         *width = pvi->bmiHeader.biWidth;\r
535                         *height = pvi->bmiHeader.biHeight;\r
536                 }\r
537                 DeleteMediaType(pmt);\r
538         }\r
539         vsc->Release();\r
540         return hr;\r
541 }\r
542 \r
543 STDMETHODIMP HWCSP::GetFormats(LPVOID pData)\r
544 {\r
545         HRESULT hr;\r
546         IAMStreamConfig *pSC;\r
547 \r
548         if (pData == NULL)\r
549                 return E_POINTER;\r
550 \r
551         HWCParam *param = (HWCParam*)pData;\r
552 \r
553         hr = m_pCGB->FindInterface(&PIN_CATEGORY_CAPTURE, 0, m_pDF, IID_IAMStreamConfig, (void**)&pSC);\r
554         if (FAILED(hr))\r
555                 return hr;\r
556 \r
557         int iCount = 0, iSize = 0, nIndex = 0;\r
558         hr = pSC->GetNumberOfCapabilities(&iCount, &iSize);\r
559         if (FAILED(hr))\r
560         {\r
561                 pSC->Release();\r
562                 return hr;\r
563         }\r
564 \r
565         if (iSize == sizeof(VIDEO_STREAM_CONFIG_CAPS))\r
566         {\r
567                 for (int iFormat = 0; iFormat < iCount; iFormat++)\r
568                 {\r
569                         VIDEO_STREAM_CONFIG_CAPS scc;\r
570                         AM_MEDIA_TYPE *pmtConfig;\r
571                         hr = pSC->GetStreamCaps(iFormat, &pmtConfig, (BYTE*)&scc);\r
572                         if (SUCCEEDED(hr))\r
573                         {\r
574                                 if (pmtConfig != NULL && pmtConfig->formattype == FORMAT_VideoInfo)\r
575                                 {\r
576                                         VIDEOINFOHEADER* pvi = (VIDEOINFOHEADER*)pmtConfig->pbFormat;\r
577                                         // processing!!!!\r
578                                 }\r
579                         }\r
580                         DeleteMediaType(pmtConfig);\r
581                 }\r
582         }\r
583         pSC->Release();\r
584         return hr;\r
585 }\r
586 \r
587 STDMETHODIMP HWCSP::GetFrameSizes(LPVOID pData)\r
588 {\r
589         HRESULT hr;\r
590         IAMStreamConfig *pSC;\r
591 \r
592         if (pData == NULL)\r
593                 return E_POINTER;\r
594 \r
595         HWCParam *param = (HWCParam*)pData;\r
596         hr = m_pCGB->FindInterface(&PIN_CATEGORY_CAPTURE, 0, m_pDF, IID_IAMStreamConfig, (void**)&pSC);\r
597         if (FAILED(hr))\r
598                 return hr;\r
599 \r
600         int iCount = 0, iSize = 0, nIndex = 0;\r
601         hr = pSC->GetNumberOfCapabilities(&iCount, &iSize);\r
602         if (FAILED(hr))\r
603         {\r
604                 pSC->Release();\r
605                 return hr;\r
606         }\r
607 \r
608         if (iSize == sizeof(VIDEO_STREAM_CONFIG_CAPS))\r
609         {\r
610                 for (int iFormat = 0; iFormat < iCount; iFormat++)\r
611                 {\r
612                         VIDEO_STREAM_CONFIG_CAPS scc;\r
613                         AM_MEDIA_TYPE *pmtConfig;\r
614                         hr = pSC->GetStreamCaps(iFormat, &pmtConfig, (BYTE*)&scc);\r
615                         if (SUCCEEDED(hr))\r
616                         {\r
617                                 if (pmtConfig != NULL && pmtConfig->formattype == FORMAT_VideoInfo)\r
618                                 {\r
619                                         VIDEOINFOHEADER* pvi = (VIDEOINFOHEADER*)pmtConfig->pbFormat;\r
620                                         // processing!!!!\r
621                                 }\r
622                         }\r
623                         DeleteMediaType(pmtConfig);\r
624                 }\r
625         }\r
626         pSC->Release();\r
627         return hr;\r
628 }\r
629 \r
630 STDMETHODIMP HWCSP::SetDefaultValues()\r
631 {\r
632         HRESULT hr;\r
633         IAMStreamConfig *pSConfig;\r
634 \r
635         hr = m_pCGB->FindInterface(&PIN_CATEGORY_CAPTURE, 0, m_pDF, IID_IAMStreamConfig, (void**)&pSConfig);\r
636         if (FAILED(hr))\r
637                 return hr;\r
638 \r
639         int iCount = 0, iSize = 0;\r
640         hr = pSConfig->GetNumberOfCapabilities(&iCount, &iSize);\r
641         if (FAILED(hr))\r
642         {\r
643                 pSConfig->Release();\r
644                 return hr;\r
645         }\r
646 \r
647         if (iSize == sizeof(VIDEO_STREAM_CONFIG_CAPS))\r
648         {\r
649                 for (int iFormat = 0; iFormat < iCount; iFormat++)\r
650                 {\r
651                         VIDEO_STREAM_CONFIG_CAPS scc;\r
652                         AM_MEDIA_TYPE *pmtConfig;\r
653 \r
654                         hr = pSConfig->GetStreamCaps(iFormat, &pmtConfig, (BYTE*)&scc);\r
655                         if (SUCCEEDED(hr))\r
656                         {\r
657                                 if (pmtConfig->formattype == FORMAT_VideoInfo)\r
658                                 {\r
659                                         VIDEOINFOHEADER* pvi = (VIDEOINFOHEADER*)pmtConfig->pbFormat;\r
660                                         if ((pvi->bmiHeader.biWidth == m_dwWidth) && \r
661                                                 (pvi->bmiHeader.biHeight == m_dwHeight) && \r
662                                                 (pvi->bmiHeader.biCompression == m_dwFourcc)) \r
663                                         {\r
664                                                 pvi->AvgTimePerFrame = (REFERENCE_TIME)m_dwAvgInterval;\r
665                                                 pSConfig->SetFormat(pmtConfig);\r
666                                         }\r
667                                 }\r
668                         }\r
669                         DeleteMediaType(pmtConfig);\r
670                 }\r
671         }\r
672         pSConfig->Release();\r
673         return hr;\r
674 }\r
675 \r
676 STDMETHODIMP HWCSP::GetFrameIntervals(LPVOID pData)\r
677 {\r
678 }\r
679 \r
680 STDMETHODIMP HWCSP::SetCallback(CallbackFn pCallback)\r
681 {\r
682         if (m_pCallback == NULL) {\r
683                 return E_FAIL;\r
684         }\r
685         return m_pCallback->SetCallback(pCallback);\r
686 }\r
687 \r
688 static HWCSP *g_pObject = NULL;\r
689 \r
690 STDMETHODIMP HWCOpen()\r
691 {\r
692         HRESULT hr;\r
693 \r
694         g_pObject = new HWCSP();\r
695         hr = g_pObject->Init();\r
696         if (FAILED(hr))\r
697                 goto error_failed;\r
698 \r
699         hr = g_pObject->BindSourceFilter();\r
700         if (hr != S_OK)\r
701                 goto error_failed;\r
702 \r
703         hr = g_pObject->BindTargetFilter();\r
704         if (FAILED(hr))\r
705                 goto error_failed;\r
706 \r
707         hr = g_pObject->ConnectFilters();\r
708         if (FAILED(hr))\r
709                 goto error_failed;\r
710 \r
711         hr = g_pObject->SetDefaultValues();\r
712         if (FAILED(hr))\r
713                 goto error_failed;\r
714 \r
715         return NOERROR;\r
716 \r
717 error_failed:\r
718         delete g_pObject;\r
719         return hr;\r
720 }\r
721 \r
722 STDMETHODIMP HWCClose()\r
723 {\r
724         if (g_pObject)\r
725                 delete g_pObject;\r
726         return NOERROR;\r
727 }\r
728 \r
729 STDMETHODIMP HWCStart()\r
730 {\r
731         if (g_pObject)\r
732                 return g_pObject->StartPreview();\r
733 \r
734         return E_FAIL;\r
735 }\r
736 \r
737 STDMETHODIMP HWCStop()\r
738 {\r
739         if (g_pObject)\r
740                 return g_pObject->StopPreview();\r
741 \r
742         return E_FAIL;\r
743 }\r
744 \r
745 STDMETHODIMP HWCSetFPS(long num, long denom)\r
746 {\r
747         HRESULT hr;\r
748         REFERENCE_TIME inFps = (REFERENCE_TIME)(10000000 * num / denom);\r
749         hr = g_pObject->SetFPS(inFps);\r
750         return hr;\r
751 }\r
752 \r
753 STDMETHODIMP HWCGetFPS(long *num, long *denom)\r
754 {\r
755         HRESULT hr;\r
756         REFERENCE_TIME outFps = 0;\r
757         hr = g_pObject->GetFPS(&outFps);\r
758         if (SUCCEEDED(hr)) {\r
759                 *num = 1;\r
760                 *denom = (long)(10000000 / outFps);\r
761         } else {\r
762                 *num = 0;\r
763                 *denom = 0;\r
764         }\r
765         return hr;\r
766 }\r
767 \r
768 STDMETHODIMP HWCSetFormat(long width, long height)\r
769 {\r
770         HRESULT hr;\r
771         hr = g_pObject->SetResolution(width, height);\r
772         return hr;\r
773 }\r
774 STDMETHODIMP HWCGetFormat()\r
775 {\r
776         return NOERROR;\r
777 }\r
778 STDMETHODIMP HWCTryFormat()\r
779 {\r
780         return NOERROR;\r
781 }\r
782 STDMETHODIMP HWCEnumFormat()\r
783 {\r
784         return NOERROR;\r
785 }\r
786 \r
787 STDMETHODIMP HWCQueryControl(long nProperty, long *pMin, long *pMax, long *pStep, long *pDefault)\r
788 {\r
789         if (g_pObject)\r
790                 return g_pObject->QueryVideoProcAmp(nProperty, pMin, pMax, pStep, pDefault);\r
791 \r
792         return E_FAIL;\r
793 }\r
794 \r
795 STDMETHODIMP HWCSetControlValue(long nProperty, long value)\r
796 {\r
797         if (g_pObject)\r
798                 return g_pObject->SetVideoProcAmp(nProperty, value);\r
799 \r
800         return E_FAIL;\r
801 }\r
802 \r
803 STDMETHODIMP HWCGetControlValue(long nProperty, long *pVal)\r
804 {\r
805         if (g_pObject)\r
806                 return g_pObject->GetVideoProcAmp(nProperty, pVal);\r
807 \r
808         return E_FAIL;\r
809 }\r
810 \r
811 STDMETHODIMP HWCEnumFrameSizes()\r
812 {\r
813         return NOERROR;\r
814 }\r
815 STDMETHODIMP HWCEnumFrameIntervals()\r
816 {\r
817         return NOERROR;\r
818 }\r
819 \r
820 HWCFILTER_API HWCSetCallback(CallbackFn pCallback)\r
821 {\r
822         HRESULT hr = g_pObject->SetCallback(pCallback);\r
823         return hr;\r
824 }\r
825 \r
826 HWCFILTER_API HWCCtrl(UINT nCmd, UINT nSize, LPVOID pBuf)\r
827 {\r
828         HRESULT hr;\r
829         HWCParam *param = NULL;\r
830         \r
831         if (nSize  && pBuf)\r
832                 param = (HWCParam *)pBuf;\r
833 \r
834         switch (nCmd)\r
835         {\r
836         case HWC_OPEN:\r
837                 hr = HWCOpen();\r
838                 break;\r
839         case HWC_CLOSE:\r
840                 hr = HWCClose();\r
841                 break;\r
842         case HWC_START:\r
843                 hr = HWCStart();\r
844                 break;\r
845         case HWC_STOP:\r
846                 hr = HWCStop();\r
847                 break;\r
848         case HWC_S_FPS:\r
849                 hr = HWCSetFPS(param->val1, param->val2);\r
850                 break;\r
851         case HWC_G_FPS:\r
852                 hr = HWCGetFPS(&param->val1, &param->val2);\r
853                 break;\r
854         case HWC_S_FMT:\r
855                 hr = HWCSetFormat(param->val1, param->val2);\r
856                 break;\r
857         case HWC_G_FMT:\r
858                 break;\r
859         case HWC_TRY_FMT:\r
860                 break;\r
861         case HWC_ENUM_FMT:\r
862                 break;\r
863         case HWC_QCTRL:\r
864                 hr = HWCQueryControl(param->val1, &param->val2, &param->val3,\r
865                                                                 &param->val4, &param->val5);\r
866                 break;\r
867         case HWC_S_CTRL:\r
868                 hr = HWCSetControlValue(param->val1, param->val2);\r
869                 break;\r
870         case HWC_G_CTRL:\r
871                 hr = HWCGetControlValue(param->val1, &param->val2);\r
872                 break;\r
873         case HWC_ENUM_FSIZES:\r
874                 break;\r
875         case HWC_ENUM_INTERVALS:\r
876                 break;\r
877         default:\r
878                 hr = E_INVALIDARG;\r
879                 break;\r
880         }\r
881         return hr;\r
882 }