📄 wingrab.cpp
字号:
pEm->Reset(); ULONG ulFetched; IMoniker * pM; while ( pEm->Next(1, &pM, &ulFetched) == S_OK ) { CComPtr< IBindCtx > pbc; hr = CreateBindCtx(0, &pbc); if ( FAILED(hr) ) { fprintf(stderr, "failed CreateBindCtx\n"); return false; } int strSize = 512; char *devInfoString = new char[strSize]; sprintDeviceInfo(pM, pbc, devInfoString, strSize); fprintf(stderr, "%s", devInfoString); IBaseFilter * pCaptureFilter = 0; CComPtr<IPin> pOutPin = 0; hr = pM->BindToObject(pbc, 0, IID_IBaseFilter, (void **)&pCaptureFilter); if ( FAILED(hr) ) { fprintf(stderr, "failed BindToObject\n"); goto clean_continue; } pOutPin = GetOutPin( pCaptureFilter, 0 ); if ( !pOutPin ) { fprintf(stderr, "failed getting source output pin\n"); goto clean_continue; } AM_MEDIA_TYPE * pMediaType = GetMediaType(pOutPin, allowAlternates); if ( pMediaType ) { pM->Release(); *ppCaptureFilter = pCaptureFilter; *ppOutPin = pOutPin; *ppMediaType = pMediaType; return true; } fprintf(stderr, "did not match media type\n");clean_continue: if ( pCaptureFilter ) pCaptureFilter->Release(); if ( pOutPin ) pOutPin.Release(); pM->Release(); } return false; } HRESULT GetPin( IBaseFilter * pFilter, PIN_DIRECTION dirrequired, int iNum, IPin **ppPin) { *ppPin = NULL; CComPtr< IEnumPins > pEnum; HRESULT hr = pFilter->EnumPins(&pEnum); if ( FAILED(hr) ) return hr; ULONG ulFound; IPin * pPin; hr = E_FAIL; while ( S_OK == pEnum->Next(1, &pPin, &ulFound) ) { PIN_DIRECTION pindir; pPin->QueryDirection(&pindir); if ( pindir == dirrequired ) { if ( iNum == 0 ) { *ppPin = pPin; hr = S_OK; break; } iNum--; } pPin->Release(); } return hr; } IPin * GetInPin( IBaseFilter * pFilter, int nPin ) { CComPtr<IPin> pComPin = 0; GetPin(pFilter, PINDIR_INPUT, nPin, &pComPin); return pComPin; } IPin * GetOutPin( IBaseFilter * pFilter, int nPin ) { CComPtr<IPin> pComPin = 0; GetPin(pFilter, PINDIR_OUTPUT, nPin, &pComPin); return pComPin; } int Init( grab_callback_t grab_callback, void *grab_callback_data, int w, int h) { USES_CONVERSION; this->grab_callback = grab_callback; this->grab_callback_data = grab_callback_data; this->width = w; this->height = h; // Create the sample grabber // CComPtr< ISampleGrabber > pGrabber; pGrabber.CoCreateInstance( CLSID_SampleGrabber ); if ( !pGrabber ) { fprintf(stderr, "failed instantiating sample grabber\n"); return 0; } CComQIPtr< IBaseFilter, &IID_IBaseFilter > pGrabberBase(pGrabber); // Get whatever capture device exists // IBaseFilter * pSourceTmp; IPin * pSourceOutPinTmp; AM_MEDIA_TYPE * pMediaType; // First pass: look for I420 / IYUV formats if ( !GetDefaultCapDevice(&pSourceTmp, &pSourceOutPinTmp, &pMediaType, false) ) { // Second pass: look for YUY2 fprintf(stderr, "Expanding search for supported image formats.\n"); if ( !GetDefaultCapDevice(&pSourceTmp, &pSourceOutPinTmp, &pMediaType, true) ) return 0; } // Put the results into smart pointers so the references to // these objects are tracked properly. CComPtr< IBaseFilter > pSource(pSourceTmp); CComPtr< IPin > pSourceOutPin(pSourceOutPinTmp); CComPtr< IBaseFilter > pNullRenderer; pNullRenderer.CoCreateInstance( CLSID_NullRenderer ); if ( !pNullRenderer ) { fprintf(stderr, "failed instantiating null renderer\n"); return 0; } // Create the graph // CComPtr< IGraphBuilder > pGraph; pGraph.CoCreateInstance( CLSID_FilterGraph ); if ( !pGraph ) { fprintf(stderr, "failed instantiating filter graph\n"); return 0; } HRESULT hr; // Put them in the graph // hr = pGraph->AddFilter( pSource, L"Source" ); if ( FAILED(hr) ) { fprintf(stderr, "failed adding source filter\n"); return 0; } hr = pGraph->AddFilter( pGrabberBase, L"Grabber" ); if ( FAILED(hr) ) { fprintf(stderr, "failed adding grabber filter\n"); return 0; } hr = pGraph->AddFilter( pNullRenderer, L"NullRenderer" ); if ( FAILED(hr) ) { fprintf(stderr, "failed adding null renderer filter\n"); return 0; } CComPtr< IPin > pGrabPin = GetInPin( pGrabberBase, 0 ); if ( !pGrabPin ) { fprintf(stderr, "failed to get input pin\n"); return 0; } CComPtr< IPin > pGrabOutPin = GetOutPin( pGrabberBase, 0 ); if ( !pGrabOutPin ) { fprintf(stderr, "failed to get grabber out pin\n"); return 0; } CComPtr< IPin > pNullRendererInPin = GetInPin( pNullRenderer, 0 ); if ( !pNullRendererInPin ) { fprintf(stderr, "failed to get null renderer input pin\n"); return 0; } hr = pGrabber->SetMediaType( pMediaType ); if ( FAILED(hr) ) { fprintf(stderr, "failed to set media type\n"); return 0; } // Don't buffer the samples as they pass through // hr = pGrabber->SetBufferSamples( FALSE ); if ( FAILED(hr) ) { fprintf(stderr, "failed SetBufferSamples\n"); return 0; } // Only grab one at a time, stop stream after // grabbing one sample // hr = pGrabber->SetOneShot( FALSE ); if ( FAILED(hr) ) { fprintf(stderr, "failed SetOneShot\n"); return 0; } // Set the callback, so we can grab the one sample // hr = pGrabber->SetCallback( this, 1 ); if ( FAILED(hr) ) { fprintf(stderr, "failed to set callback\n"); return 0; } fflush(stderr); // ... and connect them // hr = pGraph->ConnectDirect( pSourceOutPin, pGrabPin, pMediaType); if ( FAILED(hr) ) { fprintf(stderr, "failed to connect source and grabber\n"); return 0; } hr = pGraph->ConnectDirect( pGrabOutPin, pNullRendererInPin, pMediaType); if ( FAILED(hr) ) { fprintf(stderr, "failed to connect grabber to null renderer %d\n", hr); return 0; } MyFreeMediaType(*pMediaType); // activate the threads pControl = CComQIPtr<IMediaControl, &IID_IMediaControl>(pGraph); pControl->Run(); return TRUE; } void Destroy() { if (pControl) { pControl->Stop(); pControl.Release(); width = 0; height = 0; grab_callback = 0; grab_callback_data = 0; } }};static CSampleGrabberCB CB;_invalid_parameter_handler oldHandler, newHandler;void myInvalidParameterHandler(const wchar_t* expression, const wchar_t* function, const wchar_t* file, unsigned int line, uintptr_t pReserved){ wprintf(L"Invalid parameter detected in function %s." L" File: %s Line: %d\n", function, file, line); wprintf(L"Expression: %s\n", expression);}int listVidCapDevices(char *buff, int buffSize){ newHandler = myInvalidParameterHandler; oldHandler = _set_invalid_parameter_handler(newHandler); // Disable the message box for assertions. _CrtSetReportMode(_CRT_ASSERT, 0); return CB.inventoryVideoCaptureDevices(buff, buffSize);}int grabber_format_check(unsigned int format){ return CB.imageFormat == format;}void *grabber_init( grab_callback_t grab_callback, void *grab_callback_data, int w, int h){ HRESULT hr = CoInitialize(NULL); if ( FAILED(hr) ) { fprintf(stderr, "failed CoInitialize\n"); return 0; } grabber_destroy(NULL); if (CB.Init(grab_callback, grab_callback_data, w, h)) { return &CB; } else { fprintf(stderr, "sample grabber init failed\n"); return 0; }}void grabber_destroy( void *opaque ){ CB.Destroy();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -