[Title] improved camera performance & add win32 dll source
[sdk/emulator/qemu.git] / tizen / src / hw / camera_win32_dll / hwcfilter / hwcfilter / hwcfilter.cpp
1 #include "stdafx.h"\r
2 #include "hwcfilter.h"\r
3 #include <VFWMSGS.H>\r
4 #include <stdio.h>\r
5 \r
6 static HMODULE g_hModule = NULL;\r
7 static long g_cServerLocks = 0;\r
8 static long g_cComponents = 0;\r
9 \r
10 CHWCPin::CHWCPin(CHWCFilter *pFilter) :\r
11         m_pCFilter(pFilter), m_pConnectedPin(NULL), \r
12         m_pCallback(NULL), m_bReadOnly(FALSE), m_cRef(1)\r
13 {\r
14         InterlockedIncrement(&g_cComponents);\r
15 }\r
16 \r
17 CHWCPin::~CHWCPin(void)\r
18 {\r
19         InterlockedDecrement(&g_cComponents);\r
20 }\r
21 \r
22 STDMETHODIMP CHWCPin::QueryInterface(REFIID riid, void **ppv)\r
23 {\r
24         if (riid == IID_IUnknown) {\r
25                 *ppv = (IUnknown*)((IHWCPin*)this);\r
26         } else if (riid == IID_IPin) {\r
27                 *ppv = (IPin*)this;\r
28         } else if (riid == IID_IMemInputPin) {\r
29                 *ppv = (IMemInputPin*)this;\r
30         } else if (riid == IID_IHWCPin) {\r
31                 *ppv = (IHWCPin*)this;\r
32         } else {\r
33                 LPWSTR str;\r
34                 StringFromIID(riid, &str);\r
35                 *ppv = NULL;\r
36                 return E_NOINTERFACE;\r
37         }\r
38         reinterpret_cast<IHWCPin*>(this)->AddRef();\r
39         return S_OK;\r
40 }\r
41 \r
42 STDMETHODIMP_(ULONG) CHWCPin::AddRef()\r
43 {\r
44         return InterlockedIncrement(&m_cRef);\r
45 }\r
46 \r
47 STDMETHODIMP_(ULONG) CHWCPin::Release()\r
48 {\r
49         if( InterlockedDecrement(&m_cRef) == 0)\r
50         {\r
51                 delete this;\r
52                 return 0;\r
53         }\r
54         return m_cRef;\r
55 }\r
56 \r
57 STDMETHODIMP CHWCPin::Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt)\r
58 {\r
59         if ( !pmt )\r
60                 return S_OK;\r
61         return S_FALSE;\r
62 }\r
63 \r
64 STDMETHODIMP CHWCPin::ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt)\r
65 {\r
66         if (pConnector == NULL || pmt == NULL)\r
67                 return E_POINTER;\r
68 \r
69         if (m_pConnectedPin) {\r
70                 return VFW_E_ALREADY_CONNECTED;\r
71         }\r
72         FILTER_STATE fs;\r
73         m_pCFilter->GetState(0, &fs);\r
74         if (fs != State_Stopped) {\r
75                 return VFW_E_NOT_STOPPED;\r
76         }\r
77         PIN_DIRECTION pd;\r
78         pConnector->QueryDirection(&pd);\r
79         if (pd == PINDIR_INPUT) {\r
80                 return VFW_E_INVALID_DIRECTION;\r
81         }\r
82 \r
83         m_pConnectedPin = pConnector;\r
84         m_pConnectedPin->AddRef();\r
85         return S_OK;\r
86 }\r
87 \r
88 STDMETHODIMP CHWCPin::Disconnect(void)\r
89 {\r
90         HRESULT hr;\r
91         if (m_pConnectedPin == NULL) {\r
92                 hr = S_FALSE;\r
93         } else {\r
94                 m_pConnectedPin->Release();\r
95                 m_pConnectedPin = NULL;\r
96                 hr = S_OK;\r
97         }\r
98         return hr;\r
99 }\r
100 \r
101 STDMETHODIMP CHWCPin::ConnectedTo(IPin **pPin)\r
102 {\r
103         if (pPin == NULL)\r
104                 return E_POINTER;\r
105 \r
106         HRESULT hr;\r
107         if ( m_pConnectedPin == NULL ) {\r
108                 hr = VFW_E_NOT_CONNECTED;\r
109         } else {\r
110                 m_pConnectedPin->AddRef();\r
111                 *pPin = m_pConnectedPin;\r
112                 hr = S_OK;\r
113         }\r
114         return hr;\r
115 }\r
116 \r
117 STDMETHODIMP CHWCPin::ConnectionMediaType(AM_MEDIA_TYPE *pmt)\r
118 {       \r
119         if (pmt == NULL) {\r
120                 return E_POINTER;\r
121         }\r
122         return VFW_E_NOT_CONNECTED;\r
123 }\r
124 \r
125 STDMETHODIMP CHWCPin::QueryPinInfo(PIN_INFO *pInfo)\r
126 {\r
127         if (pInfo == NULL)\r
128                 return E_POINTER;\r
129 \r
130         pInfo->pFilter = (IBaseFilter*)m_pCFilter;\r
131         if (m_pCFilter)\r
132                 m_pCFilter->AddRef();\r
133         memcpy((void*)pInfo->achName, (void*)HWCPinName, sizeof(HWCPinName));\r
134         pInfo->dir = PINDIR_INPUT;\r
135         return S_OK;\r
136 }\r
137 \r
138 STDMETHODIMP CHWCPin::QueryDirection(PIN_DIRECTION *pPinDir)\r
139 {\r
140         if (pPinDir == NULL)\r
141                 return E_POINTER;\r
142         *pPinDir = PINDIR_INPUT;\r
143         return S_OK;\r
144 }\r
145 \r
146 STDMETHODIMP CHWCPin::QueryId(LPWSTR *Id)\r
147 {\r
148         if (Id == NULL)\r
149                 return E_POINTER;\r
150         PVOID pId = CoTaskMemAlloc(sizeof(HWCPinName));\r
151         memcpy((void*)pId, (void*)HWCPinName, sizeof(HWCPinName));\r
152         *Id = (LPWSTR)pId;\r
153         return S_OK;\r
154 }\r
155 \r
156 STDMETHODIMP CHWCPin::QueryAccept(const AM_MEDIA_TYPE *pmt)\r
157 {\r
158         if (pmt == NULL)\r
159                 return E_POINTER;\r
160         return S_OK;\r
161 }\r
162 \r
163 STDMETHODIMP CHWCPin::EnumMediaTypes(IEnumMediaTypes **ppEnum)\r
164 {\r
165         if (ppEnum == NULL)\r
166                         return E_POINTER;\r
167         return E_NOTIMPL;\r
168 }\r
169 \r
170 STDMETHODIMP CHWCPin::QueryInternalConnections(IPin **ppPin, ULONG *nPin)\r
171 {\r
172         return E_NOTIMPL;\r
173 }\r
174 \r
175 STDMETHODIMP CHWCPin::EndOfStream(void)\r
176 {\r
177         return S_OK;\r
178 }\r
179 \r
180 STDMETHODIMP CHWCPin::BeginFlush(void)\r
181 {\r
182         return S_OK;\r
183 }\r
184 \r
185 STDMETHODIMP CHWCPin::EndFlush(void)\r
186 {\r
187         return S_OK;\r
188 }\r
189 \r
190 STDMETHODIMP CHWCPin::NewSegment(REFERENCE_TIME tStart,\r
191                                                                 REFERENCE_TIME tStop,\r
192                                                                 double dRate)\r
193 {\r
194         return S_OK;\r
195 }\r
196 \r
197 STDMETHODIMP CHWCPin::GetAllocator(IMemAllocator **ppAllocator)\r
198 {\r
199         if (ppAllocator == NULL)\r
200                 return E_POINTER;\r
201         return VFW_E_NO_ALLOCATOR;\r
202 }\r
203 \r
204 STDMETHODIMP CHWCPin::NotifyAllocator(IMemAllocator *pAllocator,\r
205                                                                                 BOOL bReadOnly)\r
206 {\r
207         if (pAllocator == NULL)\r
208                 return E_POINTER;\r
209 \r
210         return NOERROR;\r
211 }\r
212 \r
213 STDMETHODIMP CHWCPin::GetAllocatorRequirements(ALLOCATOR_PROPERTIES *pProps)\r
214 {\r
215         return E_NOTIMPL;\r
216 }\r
217 \r
218 STDMETHODIMP CHWCPin::Receive(IMediaSample *pSample)\r
219 {\r
220         if (pSample == NULL)\r
221                 return E_POINTER;\r
222         if (m_pCallback != NULL) {\r
223                 HRESULT hr;\r
224                 BYTE* pBuffer = NULL;\r
225                 DWORD dwSize = 0;\r
226                 dwSize = pSample->GetSize();\r
227                 hr = pSample->GetPointer(&pBuffer);\r
228                 if (FAILED(hr))\r
229                         return hr;\r
230                 m_pCallback->CaptureCallback(dwSize, pBuffer);\r
231         }\r
232         return S_OK;\r
233 }\r
234 \r
235 STDMETHODIMP CHWCPin::ReceiveMultiple(IMediaSample **pSamples,\r
236                                                                                 long nSamples, long *nSamplesProcessed)\r
237 {\r
238         if (pSamples == NULL)\r
239                 return E_POINTER;\r
240         HRESULT hr = S_OK;\r
241         nSamplesProcessed = 0;\r
242         while (nSamples-- > 0) \r
243         {\r
244                 hr = Receive(pSamples[*nSamplesProcessed]);\r
245                 if (hr != S_OK)\r
246                         break;\r
247                 (*nSamplesProcessed)++;\r
248         }\r
249         return hr;\r
250 }\r
251 \r
252 STDMETHODIMP CHWCPin::ReceiveCanBlock(void)\r
253 {\r
254         return S_FALSE;\r
255 }\r
256 \r
257 STDMETHODIMP CHWCPin::SetCallback(ICaptureCallBack *pCaptureCB)\r
258 {\r
259         if (pCaptureCB == NULL) {\r
260                 m_pCallback->Release();\r
261         } else {\r
262                 m_pCallback = pCaptureCB;\r
263                 m_pCallback->AddRef();\r
264         }       \r
265         return S_OK;\r
266 }\r
267 \r
268 CHWCEnumPins::CHWCEnumPins(CHWCFilter *pCHWCFilter, int pos) :\r
269   m_pFilter(pCHWCFilter), m_pos(pos), m_cRef(1)\r
270 {\r
271         m_pFilter->AddRef();\r
272         InterlockedIncrement(&g_cComponents);\r
273 }\r
274 \r
275 CHWCEnumPins::~CHWCEnumPins(void)\r
276 {\r
277         m_pFilter->Release();\r
278         InterlockedDecrement(&g_cComponents);\r
279 }\r
280 \r
281 STDMETHODIMP CHWCEnumPins::QueryInterface(REFIID riid, void **ppv)\r
282 {\r
283         if (ppv == NULL)\r
284                 return E_POINTER;\r
285 \r
286         if (riid == IID_IUnknown) {\r
287                 *ppv = (IUnknown*)this;\r
288         } else if (riid == IID_IEnumPins) {\r
289                 *ppv = (IEnumPins*)this;\r
290         } else {\r
291                 *ppv = NULL;\r
292                 return E_NOINTERFACE;\r
293         }\r
294         reinterpret_cast<IUnknown*>(this)->AddRef();\r
295         return S_OK;\r
296 }\r
297 \r
298 STDMETHODIMP_(ULONG) CHWCEnumPins::AddRef()\r
299 {\r
300         return InterlockedIncrement(&m_cRef);\r
301 }\r
302 \r
303 STDMETHODIMP_(ULONG) CHWCEnumPins::Release()\r
304 {\r
305         if (InterlockedDecrement(&m_cRef) == 0) {\r
306                 delete this;\r
307                 return 0;\r
308         }\r
309         return m_cRef;\r
310 }\r
311 \r
312 STDMETHODIMP CHWCEnumPins::Next(ULONG cPins, IPin **ppPins,\r
313                                                                 ULONG *pcFetched)\r
314 {\r
315         if (ppPins == NULL)\r
316                         return E_POINTER;\r
317 \r
318         ULONG fetched;\r
319         if (m_pos < 1 && cPins > 0) {\r
320                 IPin *pPin;\r
321                 m_pFilter->FindPin(HWCPinName, &pPin);\r
322                 *ppPins = pPin;\r
323                 pPin->AddRef();\r
324                 fetched = 1;\r
325                 m_pos++;\r
326         } else {\r
327                 fetched = 0;\r
328         }\r
329         if (pcFetched != NULL ) {\r
330                 *pcFetched = fetched;\r
331         }\r
332 \r
333         return ( fetched == cPins ) ? S_OK : S_FALSE;\r
334 }\r
335 \r
336 STDMETHODIMP CHWCEnumPins::Skip(ULONG cPins)\r
337 {\r
338         m_pos += cPins;\r
339         return ( m_pos >= 1 ) ? S_FALSE : S_OK;\r
340 }\r
341 \r
342 STDMETHODIMP CHWCEnumPins::Reset(void)\r
343 {\r
344         m_pos = 0;\r
345         return S_OK;\r
346 }\r
347 \r
348 STDMETHODIMP CHWCEnumPins::Clone(IEnumPins **ppEnum)\r
349 {\r
350         if (ppEnum == NULL)\r
351                 return E_POINTER;\r
352         *ppEnum = new CHWCEnumPins(m_pFilter, m_pos);\r
353         if (*ppEnum == NULL) {\r
354                 return E_OUTOFMEMORY;\r
355         }\r
356         return NOERROR;\r
357 }\r
358 \r
359 CHWCFilter::CHWCFilter() : m_pFilterGraph(NULL), m_state(State_Stopped), m_cRef(1)\r
360 {\r
361         m_pPin = new CHWCPin(this);\r
362         InterlockedIncrement(&g_cComponents);\r
363 }\r
364 \r
365 CHWCFilter::~CHWCFilter()\r
366 {\r
367         InterlockedDecrement(&g_cComponents);\r
368 \r
369         if (m_pPin) {\r
370                 m_pPin->Release();\r
371                 m_pPin = NULL;\r
372         }\r
373         if (m_pFilterGraph) {\r
374                 m_pFilterGraph->Release();\r
375                 m_pFilterGraph = NULL;\r
376         }\r
377 }\r
378 \r
379 STDMETHODIMP CHWCFilter::QueryInterface(REFIID riid, void **ppv)\r
380 {\r
381         if( riid == IID_IUnknown ) {\r
382                 *ppv = (IUnknown*)this;\r
383         } else if( riid == IID_IPersist ) {\r
384                 *ppv = (IPersist*)this;\r
385         } else if( riid == IID_IMediaFilter ) {\r
386                 *ppv = (IMediaFilter*)this;\r
387         } else if( riid == IID_IBaseFilter ) {\r
388                 *ppv = (IBaseFilter*)this;\r
389         } else {\r
390                 LPWSTR str;\r
391                 StringFromIID(riid, &str);\r
392                 *ppv = NULL;\r
393                 return E_NOINTERFACE;\r
394         }\r
395         reinterpret_cast<IUnknown*>(this)->AddRef();\r
396 \r
397         return S_OK;\r
398 }\r
399 \r
400 STDMETHODIMP_(ULONG) CHWCFilter::AddRef()\r
401 {\r
402         return InterlockedIncrement(&m_cRef);\r
403 }\r
404 \r
405 STDMETHODIMP_(ULONG) CHWCFilter::Release()\r
406 {\r
407         if( InterlockedDecrement(&m_cRef) == 0) {\r
408                 delete this;\r
409                 return 0;\r
410         }\r
411         return m_cRef;\r
412 }\r
413 \r
414 STDMETHODIMP CHWCFilter::GetClassID(CLSID *pClsID)\r
415 {\r
416         if (pClsID == NULL)\r
417                 return E_POINTER;\r
418         return E_NOTIMPL;\r
419 }\r
420 \r
421 STDMETHODIMP CHWCFilter::GetState(DWORD dwMSecs, FILTER_STATE *State)\r
422 {\r
423         *State = m_state;\r
424         return S_OK;\r
425 }\r
426 \r
427 STDMETHODIMP CHWCFilter::SetSyncSource(IReferenceClock *pClock)\r
428 {\r
429         return S_OK;\r
430 }\r
431 \r
432 STDMETHODIMP CHWCFilter::GetSyncSource(IReferenceClock **pClock)\r
433 {\r
434         *pClock = NULL;\r
435         return NOERROR;\r
436 }\r
437 \r
438 STDMETHODIMP CHWCFilter::Stop()\r
439 {\r
440         m_pPin->EndFlush();\r
441         m_state = State_Stopped;\r
442         return S_OK;\r
443 }\r
444 \r
445 STDMETHODIMP CHWCFilter::Pause()\r
446 {\r
447         m_state = State_Paused;\r
448         return S_OK;\r
449 }\r
450 \r
451 STDMETHODIMP CHWCFilter::Run(REFERENCE_TIME tStart)\r
452 {\r
453         if (m_state == State_Stopped){\r
454                 HRESULT hr = Pause();\r
455                 if (FAILED(hr)) {\r
456                         return hr;\r
457                 }\r
458         }\r
459         m_state = State_Running;\r
460         return S_OK;\r
461 }\r
462 \r
463 STDMETHODIMP CHWCFilter::EnumPins(IEnumPins **ppEnum)\r
464 {\r
465         if (ppEnum == NULL)\r
466                 return E_POINTER;\r
467         *ppEnum = (IEnumPins*)(new CHWCEnumPins(this, 0));\r
468         return *ppEnum == NULL ? E_OUTOFMEMORY : S_OK;\r
469 }\r
470 \r
471 STDMETHODIMP CHWCFilter::FindPin(LPCWSTR Id, IPin **ppPin)\r
472 {\r
473         if (ppPin == NULL)\r
474                 return E_POINTER;\r
475 \r
476         if (memcmp((void*)Id, (void*)HWCPinName, sizeof(HWCPinName))) {\r
477                 return VFW_E_NOT_FOUND;\r
478         }\r
479 \r
480         if (!m_pPin) {\r
481                 m_pPin = new CHWCPin(this);\r
482         }\r
483         *ppPin = (IPin*)m_pPin;\r
484         m_pPin->AddRef();\r
485         return S_OK;\r
486 }\r
487 \r
488 STDMETHODIMP CHWCFilter::QueryFilterInfo(FILTER_INFO *pInfo)\r
489 {\r
490         if (pInfo == NULL)\r
491                 return E_POINTER;\r
492 \r
493         memcpy((void*)pInfo->achName, (void*)HWCFilterName, sizeof(HWCFilterName));\r
494         pInfo->pGraph = m_pFilterGraph;\r
495         if(m_pFilterGraph) {\r
496                 m_pFilterGraph->AddRef();\r
497         }\r
498         return S_OK;\r
499 }\r
500 \r
501 STDMETHODIMP CHWCFilter::JoinFilterGraph(IFilterGraph *pGraph,\r
502                                                                                 LPCWSTR pName)\r
503 {\r
504         m_pFilterGraph = pGraph;\r
505         pGraph->AddRef();\r
506         return S_OK;\r
507 }\r
508 \r
509 STDMETHODIMP CHWCFilter::QueryVendorInfo(LPWSTR* pVendorInfo)\r
510 {\r
511         return E_NOTIMPL;\r
512 }\r
513 \r
514 HWCClassFactory::HWCClassFactory(void) : m_cRef(1)\r
515 {\r
516 }\r
517 \r
518 HWCClassFactory::~HWCClassFactory(void)\r
519 {\r
520 }\r
521 \r
522 STDMETHODIMP HWCClassFactory::QueryInterface(REFIID riid, LPVOID* ppv)\r
523 {\r
524         if (riid == IID_IUnknown || riid == IID_IClassFactory) {\r
525                 *ppv = (IClassFactory*)this;\r
526         } else {\r
527                 *ppv = NULL;\r
528                 return E_NOINTERFACE;\r
529         }\r
530 \r
531         reinterpret_cast<IUnknown*>(*ppv)->AddRef();\r
532         return S_OK;\r
533 }\r
534 \r
535 STDMETHODIMP_(ULONG) HWCClassFactory::AddRef(void)\r
536 {\r
537         return InterlockedIncrement(&m_cRef);\r
538 }\r
539 \r
540 STDMETHODIMP_(ULONG) HWCClassFactory::Release(void)\r
541 {\r
542         if (InterlockedDecrement(&m_cRef) == 0) {\r
543                 delete this;\r
544                 return 0;\r
545         }\r
546         return m_cRef;\r
547 }\r
548 \r
549 STDMETHODIMP HWCClassFactory::CreateInstance(LPUNKNOWN pUnkOuter, REFIID riid, LPVOID* ppv)\r
550 {\r
551         HRESULT hr;\r
552         CHWCFilter* pFilter = NULL;\r
553         *ppv = NULL;\r
554 \r
555         if (pUnkOuter != NULL) {\r
556                 hr = CLASS_E_NOAGGREGATION;\r
557         } else {\r
558                 pFilter = new CHWCFilter;\r
559                 if (pFilter != NULL) {\r
560                         hr = pFilter->QueryInterface(riid, ppv);\r
561                         pFilter->Release();\r
562                 } else {\r
563                         return E_OUTOFMEMORY;\r
564                 }\r
565         }\r
566 \r
567         return hr;\r
568 }\r
569 \r
570 STDMETHODIMP HWCClassFactory::LockServer(BOOL bLock)\r
571 {\r
572         if (bLock) {\r
573                 InterlockedIncrement(&g_cServerLocks);\r
574         } else {\r
575                 InterlockedDecrement(&g_cServerLocks);\r
576         }\r
577         return S_OK;\r
578 }\r
579 \r
580 STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)\r
581 {\r
582         HRESULT hr = CLASS_E_CLASSNOTAVAILABLE;\r
583         HWCClassFactory *pFactory = NULL;\r
584 \r
585         if (rclsid != CLSID_HWCFilterClass) {\r
586                 return hr;\r
587         }\r
588 \r
589         pFactory = new HWCClassFactory;\r
590         if (pFactory == NULL) {\r
591                 hr = E_OUTOFMEMORY;\r
592         } else {\r
593                 hr = pFactory->QueryInterface(riid, ppv);\r
594                 pFactory->Release();\r
595         }\r
596 \r
597         return hr;\r
598 }\r
599 \r
600 STDAPI DllCanUnloadNow(void)\r
601 {\r
602         if ((g_cComponents == 0) && (g_cServerLocks == 0)) {\r
603                 return S_OK;\r
604         }\r
605         return S_FALSE;\r
606 }\r
607 \r
608 STDAPI DllRegisterServer(void)\r
609 {\r
610         return S_OK;\r
611 }\r
612 \r
613 STDAPI DllUnregisterServer(void)\r
614 {\r
615         return S_OK;\r
616 }\r