00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #ifdef HAVE_DIRECTCAM
00033
00034 #define WIN32_LEAN_AND_MEAN
00035
00036 #undef Configure
00037
00038 #pragma warning(disable:4100) // warning C4100: unreferenced formal parameter
00039 #pragma warning(disable:4201) // warning C4201: nonstandard extension used : nameless struct/union
00040 #pragma warning(disable:4511) // warning C4511: copy constructor could not be generated
00041 #pragma warning(disable:4512) // warning C4512: assignment operator could not be generated
00042 #pragma warning(disable:4514) // warning C4514: "unreferenced inline function has been removed"
00043
00044 #include <windows.h>
00045 #include <windowsx.h>
00046 #include <olectl.h>
00047 #include <mmsystem.h>
00048 #include <strmif.h>
00049 #include <amvideo.h>
00050 #include <amaudio.h>
00051 #include <control.h>
00052 #include <evcode.h>
00053 #include <uuids.h>
00054 #include <errors.h>
00055 #include <edevdefs.h>
00056 #include <audevcod.h>
00057 #include <dvdevcod.h>
00058 #include <comutil.h>
00059
00060 #include <wchar.h>
00061 #include <string.h>
00062 #include <windows.h>
00063
00064
00065
00066
00067
00068
00069 #pragma include_alias( "dxtrans.h", "qedit.h" )
00070 #define __IDxtCompositor_INTERFACE_DEFINED__
00071 #define __IDxtAlphaSetter_INTERFACE_DEFINED__
00072 #define __IDxtJpeg_INTERFACE_DEFINED_
00073 #define __IDxtKey_INTERFACE_DEFINED__
00074 #define IDXEffect IUnknown
00075 #include <qedit.h>
00076 #include <atlbase.h>
00077
00078
00079
00080
00081
00082
00083 class WebcamVideoDS : public WebcamVideo
00084 {
00085 public:
00086 static void find_all_webcams_ds();
00087 friend void find_all_webcams_ds();
00088
00089 private:
00090 typedef pvector<PT(WebcamVideoDS)> WebcamVideoList;
00091
00092 static int media_score(AM_MEDIA_TYPE *media);
00093 static int media_x(AM_MEDIA_TYPE *media);
00094 static int media_y(AM_MEDIA_TYPE *media);
00095 static int media_fps(AM_MEDIA_TYPE *media);
00096 static void delete_media_type(AM_MEDIA_TYPE *media);
00097 static string bstr_to_string(const BSTR &source);
00098 static string get_moniker_name(IMoniker *pMoniker);
00099 static void add_device(WebcamVideoList &list, IMoniker *pMoniker, AM_MEDIA_TYPE *media);
00100
00101 virtual PT(MovieVideoCursor) open();
00102
00103 IMoniker *_moniker;
00104 AM_MEDIA_TYPE *_media;
00105
00106 friend class WebcamVideoCursorDS;
00107
00108 public:
00109 static TypeHandle get_class_type() {
00110 return _type_handle;
00111 }
00112 static void init_type() {
00113 WebcamVideo::init_type();
00114 register_type(_type_handle, "WebcamVideoDS",
00115 WebcamVideo::get_class_type());
00116 }
00117 virtual TypeHandle get_type() const {
00118 return get_class_type();
00119 }
00120 virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
00121
00122 private:
00123 static TypeHandle _type_handle;
00124 };
00125
00126 TypeHandle WebcamVideoDS::_type_handle;
00127
00128
00129
00130
00131
00132
00133
00134 class WebcamVideoCursorDS : public MovieVideoCursor
00135 {
00136 public:
00137 WebcamVideoCursorDS(WebcamVideoDS *src);
00138 virtual ~WebcamVideoCursorDS();
00139 virtual PT(Buffer) fetch_buffer();
00140
00141 public:
00142 void cleanup();
00143
00144 class CSampleGrabberCB : public ISampleGrabberCB
00145 {
00146 public:
00147 WebcamVideoCursorDS *_host;
00148
00149 ULONG __stdcall AddRef() { return 2; }
00150 ULONG __stdcall Release() { return 1; }
00151
00152 HRESULT __stdcall QueryInterface(REFIID riid, void ** ppv);
00153 HRESULT __stdcall SampleCB(double SampleTime, IMediaSample *pSample);
00154 HRESULT __stdcall BufferCB(double dblSampleTime, BYTE *pBuffer, long lBufferSize);
00155 };
00156
00157 unsigned char *_buffer;
00158 IMediaSample *_saved;
00159
00160 IGraphBuilder *_pGraphBuilder;
00161 ICaptureGraphBuilder2 *_pCaptureBuilder;
00162 IBaseFilter *_pSrcFilter;
00163 IAMStreamConfig *_pStreamConfig;
00164 CComPtr<ISampleGrabber> _pSampleGrabber;
00165 IBaseFilter *_pStreamRenderer;
00166 IMediaControl *_pMediaCtrl;
00167
00168 CSampleGrabberCB _sample_cb;
00169
00170 public:
00171 static TypeHandle get_class_type() {
00172 return _type_handle;
00173 }
00174 static void init_type() {
00175 MovieVideoCursor::init_type();
00176 register_type(_type_handle, "WebcamVideoCursorDS",
00177 MovieVideoCursor::get_class_type());
00178 }
00179 virtual TypeHandle get_type() const {
00180 return get_class_type();
00181 }
00182 virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
00183
00184 private:
00185 static TypeHandle _type_handle;
00186 };
00187
00188 TypeHandle WebcamVideoCursorDS::_type_handle;
00189
00190
00191
00192
00193
00194
00195
00196 int WebcamVideoDS::
00197 media_score(AM_MEDIA_TYPE *media) {
00198 const GUID &subtype = media->subtype;
00199 if (subtype == MEDIASUBTYPE_RGB24) return 1;
00200 if (subtype == MEDIASUBTYPE_RGB32) return 2;
00201 if (subtype == MEDIASUBTYPE_RGB555) return 3;
00202 if (subtype == MEDIASUBTYPE_RGB565) return 3;
00203 return 4;
00204 }
00205
00206
00207
00208
00209
00210
00211 int WebcamVideoDS::
00212 media_x(AM_MEDIA_TYPE *media) {
00213 VIDEOINFOHEADER *header = (VIDEOINFOHEADER*)(media->pbFormat);
00214 return (header->bmiHeader.biWidth);
00215 }
00216
00217
00218
00219
00220
00221
00222 int WebcamVideoDS::
00223 media_y(AM_MEDIA_TYPE *media) {
00224 VIDEOINFOHEADER *header = (VIDEOINFOHEADER*)(media->pbFormat);
00225 return (header->bmiHeader.biHeight);
00226 }
00227
00228
00229
00230
00231
00232
00233 int WebcamVideoDS::
00234 media_fps(AM_MEDIA_TYPE *media) {
00235 VIDEOINFOHEADER *header = (VIDEOINFOHEADER*)(media->pbFormat);
00236 return int(10000000.0 / (header->AvgTimePerFrame));
00237 }
00238
00239
00240
00241
00242
00243
00244 void WebcamVideoDS::
00245 delete_media_type(AM_MEDIA_TYPE *pmt) {
00246 if (pmt == NULL) {
00247 return;
00248 }
00249 if (pmt->cbFormat != 0) {
00250 CoTaskMemFree((PVOID)pmt->pbFormat);
00251 pmt->cbFormat = 0;
00252 pmt->pbFormat = NULL;
00253 }
00254 if (pmt->pUnk != NULL) {
00255
00256 pmt->pUnk->Release();
00257 pmt->pUnk = NULL;
00258 }
00259 CoTaskMemFree(pmt);
00260 }
00261
00262
00263
00264
00265
00266
00267 string WebcamVideoDS::
00268 bstr_to_string(const BSTR &source) {
00269 string res = "";
00270 int count = 0;
00271 while( source[count] != 0x00 ) {
00272 res.push_back(source[count]);
00273 count++;
00274 }
00275 return res;
00276 }
00277
00278
00279
00280
00281
00282
00283 string WebcamVideoDS::
00284 get_moniker_name(IMoniker *pMoniker) {
00285 string res = "Unknown Device";
00286 IPropertyBag *propBag=NULL;
00287 VARIANT name; HRESULT hResult;
00288 pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void**)&propBag);
00289 VariantInit(&name);
00290 hResult = propBag->Read(L"FriendlyName", &name, 0);
00291 if (!hResult != S_OK) {
00292 res = bstr_to_string(name.bstrVal);
00293 goto done;
00294 }
00295 hResult = propBag->Read(L"Description", &name, 0);
00296 if (!hResult != S_OK) {
00297 res = bstr_to_string(name.bstrVal);
00298 goto done;
00299 }
00300 done:
00301 VariantClear(&name);
00302 propBag->Release();
00303 return res;
00304 }
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315 void WebcamVideoDS::
00316 add_device(WebcamVideoList &list, IMoniker *pMoniker, AM_MEDIA_TYPE *media) {
00317 for (int i=0; i<(int)list.size(); i++) {
00318 if ((list[i]->_moniker == pMoniker)&&
00319 (media_x(list[i]->_media) == media_x(media))&&
00320 (media_y(list[i]->_media) == media_y(media))) {
00321 int oldscore = media_score(list[i]->_media);
00322 if (media_score(media) < oldscore) {
00323 delete_media_type(list[i]->_media);
00324 list[i]->_media = media;
00325 } else {
00326 delete_media_type(media);
00327 }
00328 return;
00329 }
00330 }
00331 PT(WebcamVideoDS) wc = new WebcamVideoDS;
00332 wc->set_name(get_moniker_name(pMoniker));
00333 wc->_size_x = media_x(media);
00334 wc->_size_y = media_y(media);
00335 wc->_fps = media_fps(media);
00336 wc->_moniker = pMoniker;
00337 wc->_media = media;
00338 list.push_back(wc);
00339 cerr << "Added device: DirectShow: " << wc << "\n";
00340 }
00341
00342
00343
00344
00345
00346
00347
00348
00349 void WebcamVideoDS::
00350 find_all_webcams_ds() {
00351
00352 pvector <PT(WebcamVideoDS)> list;
00353
00354 ICreateDevEnum *pCreateDevEnum=NULL;
00355 IEnumMoniker *pEnumMoniker=NULL;
00356 IGraphBuilder *pGraphBuilder=NULL;
00357 ICaptureGraphBuilder2 *pCaptureGraphBuilder2=NULL;
00358 IMoniker *pMoniker=NULL;
00359 IBaseFilter *pBaseFilter=NULL;
00360 IAMStreamConfig *pStreamConfig=NULL;
00361 HRESULT hResult;
00362 ULONG cFetched;
00363
00364 hResult=CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC,
00365 IID_IGraphBuilder,(void**)&pGraphBuilder);
00366 if (hResult != S_OK) goto cleanup;
00367 hResult=CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC,
00368 IID_ICaptureGraphBuilder2, (void**)&pCaptureGraphBuilder2);
00369 if (hResult != S_OK) goto cleanup;
00370 hResult = pCaptureGraphBuilder2->SetFiltergraph(pGraphBuilder);
00371 if (hResult != S_OK) goto cleanup;
00372 hResult=CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
00373 IID_ICreateDevEnum, (void**)&pCreateDevEnum);
00374 if (hResult != S_OK) goto cleanup;
00375 hResult=pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,
00376 &pEnumMoniker, 0);
00377 if(hResult != S_OK) goto cleanup;
00378
00379 while(1) {
00380 if (pMoniker) { pMoniker->Release(); pMoniker=0; }
00381 if (pBaseFilter) { pBaseFilter->Release(); pBaseFilter=0; }
00382 if (pStreamConfig) { pStreamConfig->Release(); pStreamConfig=0; }
00383
00384 hResult = pEnumMoniker->Next(1, &pMoniker, &cFetched);
00385 if (hResult != S_OK) break;
00386
00387 hResult = pMoniker->BindToObject(NULL,NULL,IID_IBaseFilter, (void**)&pBaseFilter);
00388 if (hResult != S_OK) continue;
00389 hResult = pCaptureGraphBuilder2->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, pBaseFilter,
00390 IID_IAMStreamConfig, (void **)&pStreamConfig);
00391 if (hResult != S_OK) continue;
00392 int iCount, iSize;
00393 hResult = pStreamConfig->GetNumberOfCapabilities(&iCount, &iSize);
00394 if (hResult != S_OK || (iSize != sizeof(VIDEO_STREAM_CONFIG_CAPS))) continue;
00395 for (int iFormat=0; iFormat<iCount; iFormat++) {
00396 AM_MEDIA_TYPE *mtype;
00397 VIDEO_STREAM_CONFIG_CAPS caps;
00398 hResult = pStreamConfig->GetStreamCaps(iFormat, &mtype, (BYTE*)&caps);
00399 if (mtype->majortype == MEDIATYPE_Video) {
00400 VIDEOINFOHEADER *header = (VIDEOINFOHEADER*)(mtype->pbFormat);
00401 header->bmiHeader.biWidth = caps.MaxOutputSize.cx;
00402 header->bmiHeader.biHeight = caps.MaxOutputSize.cy;
00403 add_device(list, pMoniker, mtype);
00404 }
00405 }
00406
00407 pMoniker = 0;
00408 }
00409
00410 cleanup:
00411 if (pCreateDevEnum) { pCreateDevEnum->Release(); pCreateDevEnum=0; }
00412 if (pEnumMoniker) { pEnumMoniker->Release(); pEnumMoniker=0; }
00413 if (pGraphBuilder) { pGraphBuilder->Release(); pGraphBuilder=0; }
00414 if (pCaptureGraphBuilder2) { pCaptureGraphBuilder2->Release(); pCaptureGraphBuilder2=0; }
00415 if (pMoniker) { pMoniker->Release(); pMoniker=0; }
00416 if (pBaseFilter) { pBaseFilter->Release(); pBaseFilter=0; }
00417 if (pStreamConfig) { pStreamConfig->Release(); pStreamConfig=0; }
00418
00419 for (int i=0; i<(int)list.size(); i++) {
00420 WebcamVideoDS *obj = list[i];
00421 _all_webcams.push_back(obj);
00422 }
00423 }
00424
00425 void find_all_webcams_ds() {
00426 WebcamVideoDS::init_type();
00427 WebcamVideoCursorDS::init_type();
00428 WebcamVideoDS::find_all_webcams_ds();
00429 }
00430
00431
00432
00433
00434
00435
00436 PT(MovieVideoCursor) WebcamVideoDS::
00437 open() {
00438 return new WebcamVideoCursorDS(this);
00439 }
00440
00441
00442
00443
00444
00445
00446 WebcamVideoCursorDS::
00447 WebcamVideoCursorDS(WebcamVideoDS *src) :
00448 MovieVideoCursor(src),
00449 _pGraphBuilder(NULL),
00450 _pCaptureBuilder(NULL),
00451 _pSrcFilter(NULL),
00452 _pStreamConfig(NULL),
00453 _pStreamRenderer(NULL),
00454 _pMediaCtrl(NULL)
00455 {
00456 AM_MEDIA_TYPE mediaType;
00457 VIDEOINFOHEADER *pVideoInfo;
00458
00459 HRESULT hResult;
00460
00461 hResult=CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC,
00462 IID_IGraphBuilder,(void**)&_pGraphBuilder);
00463 if(hResult != S_OK) { cleanup(); return; }
00464
00465 hResult=CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC,
00466 IID_ICaptureGraphBuilder2, (void**)&_pCaptureBuilder);
00467 if(hResult != S_OK) { cleanup(); return; }
00468
00469 _pCaptureBuilder->SetFiltergraph(_pGraphBuilder);
00470 cerr << " IID_IGraphBuilder & IID_ICaptureGraphBuilder2 are established.\n";
00471
00472 hResult=_pGraphBuilder->QueryInterface(IID_IMediaControl, (void **)&_pMediaCtrl);
00473 if(hResult != S_OK)
00474 { cerr << " Can not get the IID_IMediaControl interface!";
00475 cleanup(); return; }
00476 cerr << " IID_IMediaControl interface is acquired.\n";
00477
00478 src->_moniker->BindToObject(NULL,NULL,IID_IBaseFilter, (void**)&_pSrcFilter);
00479 if(_pSrcFilter == NULL)
00480 { cerr << " Such capture device is not found.\n";
00481 cleanup(); return; }
00482 cerr << " The capture filter is acquired.\n";
00483
00484 hResult=_pGraphBuilder->AddFilter(_pSrcFilter, L"Capture Filter");
00485 if(hResult != DD_OK)
00486 { cerr << " The capture filter can not be added to the graph.\n";
00487 cleanup(); return; }
00488 cerr << " The capture filter has been added to the graph.\n";
00489
00490
00491 hResult = _pCaptureBuilder->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, _pSrcFilter,
00492 IID_IAMStreamConfig, (void **)&_pStreamConfig);
00493 if (hResult != S_OK) {
00494 cerr << "Could not get stream config interface.\n";
00495 cleanup(); return;
00496 }
00497 hResult = _pStreamConfig->SetFormat(src->_media);
00498 if (hResult != S_OK) {
00499 cerr << "Could not select desired video resolution\n";
00500 cleanup(); return;
00501 }
00502
00503 _pSampleGrabber.CoCreateInstance(CLSID_SampleGrabber);
00504 if(!_pSampleGrabber)
00505 { cerr << " Can not create the sample grabber, maybe qedit.dll is not registered?";
00506 cleanup(); return; }
00507
00508
00509 CComQIPtr< IBaseFilter, &IID_IBaseFilter > pGrabberFilter(_pSampleGrabber);
00510 cerr << " IID_IBaseFilter of CLSID_SampleGrabber is acquired.\n";
00511
00512 ZeroMemory(&mediaType, sizeof(AM_MEDIA_TYPE));
00513 mediaType.majortype=MEDIATYPE_Video;
00514 mediaType.subtype=MEDIASUBTYPE_RGB24;
00515 hResult=_pSampleGrabber->SetMediaType(&mediaType);
00516 if(hResult != S_OK)
00517 { cerr << " Fail to set the media type!";
00518 cleanup(); return; }
00519 cerr << " The media type of the sample grabber is set 24-bit RGB.\n";
00520
00521 hResult=_pGraphBuilder->AddFilter(pGrabberFilter, L"Sample Grabber");
00522 if(hResult != S_OK)
00523 { cerr << " Fail to add the sample grabber to the graph.";
00524 cleanup(); return; }
00525 cerr << " The sample grabber has been added to the graph.\n";
00526
00527
00528 hResult = CoCreateInstance(CLSID_NullRenderer, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&_pStreamRenderer);
00529 if(hResult != S_OK)
00530 { cerr << " Can not create the null renderer.";
00531 cleanup(); return; }
00532 cerr << " IID_IBaseFilter of CLSID_NullRenderer is acquired.\n";
00533
00534 hResult=_pGraphBuilder->AddFilter(_pStreamRenderer, L"Stream Renderer");
00535 if(hResult != S_OK)
00536 { cerr << " Fail to add the Null Renderer to the graph.";
00537 cleanup(); return; }
00538 cerr << " The Null Renderer has been added to the graph.\n";
00539
00540 hResult=_pCaptureBuilder->RenderStream(&PIN_CATEGORY_CAPTURE,
00541 &MEDIATYPE_Video, _pSrcFilter, pGrabberFilter, _pStreamRenderer);
00542 if(hResult != S_OK) {
00543 cerr << " ICaptureGraphBuilder2::RenderStream() can not connect the pins\n";
00544 cleanup(); return;
00545 }
00546
00547 hResult=_pSampleGrabber->GetConnectedMediaType(&mediaType);
00548 if(hResult != S_OK) {
00549 cerr << " Failed to read the connected media type.";
00550 cleanup(); return;
00551 }
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581 pVideoInfo=(VIDEOINFOHEADER*)mediaType.pbFormat;
00582 _size_x = pVideoInfo->bmiHeader.biWidth;
00583 _size_y = pVideoInfo->bmiHeader.biHeight;
00584 cerr << "Connected media type " << _size_x << " x " << _size_y << "\n";
00585
00586 _sample_cb._host = this;
00587 _num_components = 3;
00588 _length = 1.0E10;
00589 _can_seek = false;
00590 _can_seek_fast = false;
00591 _aborted = false;
00592 _streaming = true;
00593 _buffer = new unsigned char[_size_x * _size_y * 3];
00594 _ready = false;
00595
00596 if(mediaType.cbFormat != 0) {
00597 CoTaskMemFree((PVOID)mediaType.pbFormat);
00598 mediaType.cbFormat=0;
00599 mediaType.pbFormat=NULL;
00600 }
00601
00602 if(mediaType.pUnk != NULL) {
00603 mediaType.pUnk->Release();
00604 mediaType.pUnk=NULL;
00605 }
00606
00607 _pSampleGrabber->SetBufferSamples(FALSE);
00608 _pSampleGrabber->SetOneShot(FALSE);
00609
00610 hResult=_pSampleGrabber->SetCallback(&_sample_cb, 0);
00611 if(hResult != S_OK) {
00612 cerr << " Can not set the callback interface!";
00613 cleanup(); return;
00614 }
00615
00616 _pMediaCtrl->Run();
00617 }
00618
00619
00620
00621
00622
00623
00624 void WebcamVideoCursorDS::
00625 cleanup() {
00626 if (_buffer) {
00627 delete[] _buffer;
00628 _buffer = 0;
00629 }
00630
00631 if (_pMediaCtrl) {
00632 _pMediaCtrl->Stop();
00633 }
00634
00635 if(_pMediaCtrl) { _pMediaCtrl->Release(); _pMediaCtrl=NULL; }
00636 if(_pCaptureBuilder) { _pCaptureBuilder->Release(); _pCaptureBuilder=NULL; }
00637 if(_pGraphBuilder) { _pGraphBuilder->Release(); _pGraphBuilder=NULL; }
00638 if(_pSampleGrabber.p) { _pSampleGrabber.Release(); }
00639 if(_pStreamRenderer) { _pStreamRenderer->Release(); _pStreamRenderer=NULL; }
00640 if(_pSrcFilter) { _pSrcFilter->Release(); _pSrcFilter=NULL; }
00641 if(_pStreamConfig) { _pStreamConfig->Release(); _pStreamConfig=NULL; }
00642 }
00643
00644
00645
00646
00647
00648
00649 WebcamVideoCursorDS::
00650 ~WebcamVideoCursorDS() {
00651 cleanup();
00652 }
00653
00654
00655
00656
00657
00658
00659 PT(MovieVideoCursor::Buffer) WebcamVideoCursorDS::
00660 fetch_buffer() {
00661 if (!_ready) {
00662 return NULL;
00663 }
00664
00665 Buffer *buffer = get_standard_buffer();
00666 unsigned char *block = buffer->_block;
00667 #ifdef LOCKING_MODE
00668 unsigned char *ptr;
00669 int pixels = _size_x * _size_y;
00670 HRESULT res = _saved->GetPointer(&ptr);
00671 if (res == S_OK) {
00672 int size = _saved->GetActualDataLength();
00673 if (size == pixels * 3) {
00674 memcpy(block, ptr, pixels * 3);
00675 }
00676 }
00677 _saved->Release();
00678 #else
00679 int pixels = _size_x * _size_y;
00680 memcpy(block, _buffer, pixels * 3);
00681 #endif
00682
00683 _ready = false;
00684 return buffer;
00685 }
00686
00687
00688
00689
00690
00691
00692
00693 HRESULT __stdcall WebcamVideoCursorDS::CSampleGrabberCB::QueryInterface(REFIID riid, void **ppv)
00694 {
00695 if((riid == IID_ISampleGrabberCB) || (riid == IID_IUnknown)) {
00696 *ppv=(void *)static_cast<ISampleGrabberCB *> (this);
00697 return NOERROR;
00698 }
00699 return E_NOINTERFACE;
00700 }
00701
00702
00703
00704
00705
00706
00707
00708 HRESULT __stdcall WebcamVideoCursorDS::CSampleGrabberCB::SampleCB(double SampleTime, IMediaSample *pSample)
00709 {
00710 if (_host->_ready) {
00711 return 0;
00712 }
00713
00714 #ifdef LOCKING_MODE
00715 pSample->AddRef();
00716 _host->_saved = pSample;
00717 #else
00718 unsigned char *ptr;
00719 int pixels = _host->_size_x * _host->_size_y;
00720 HRESULT res = pSample->GetPointer(&ptr);
00721 if (res == S_OK) {
00722 int size = pSample->GetActualDataLength();
00723 if (size == pixels * 3) {
00724 memcpy(_host->_buffer, ptr, size);
00725 }
00726 }
00727 #endif
00728
00729 _host->_ready = true;
00730 return 0;
00731 }
00732
00733
00734
00735
00736
00737
00738 HRESULT __stdcall WebcamVideoCursorDS::CSampleGrabberCB::BufferCB(double dblSampleTime, BYTE *pBuffer, long lBufferSize)
00739 {
00740
00741 return 0;
00742 }
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776 #endif // HAVE_DIRECTSHOW