25 #include "VideoSource_DSHOW.hh"
26 #include <Base/Image/ImageIO.hh>
27 #include <Base/Image/ImageConvert.hh>
35 #ifdef BIAS_HAVE_PTHREADS
37 pthread_mutex_t imageMutex_;
44 #ifdef BIAS_HAVE_PTHREADS
45 pthread_mutex_init (&imageMutex_,NULL);
108 BIASWARNONCE(
"VideoSource::InitImage() should be called with uninitialized image");
129 BIASERR(
"Error initialising Video capture:"<<e.
what());
131 BIASERR(
"Error initialising Video capture!");
140 SetSize(width,height,channels);
146 BIASERR(
"Error initialising Video capture:"<<e.
what());
148 BIASERR(
"Error initialising Video capture!");
176 LONG_PTR p1=NULL,p2=NULL;
181 case EC_DEVICE_LOST: BEXCEPTION(
"Camera diconnected.");
break;
186 #ifdef BIAS_HAVE_PTHREADS
187 pthread_mutex_lock(&imageMutex_);
191 #ifdef BIAS_HAVE_PTHREADS
192 pthread_mutex_unlock(&imageMutex_);
195 #ifdef BIAS_HAVE_PTHREADS
197 pthread_mutex_lock(&imageMutex_);
207 #ifdef BIAS_HAVE_PTHREADS
209 pthread_mutex_unlock(&imageMutex_);
225 if (pmt->cbFormat != 0) {
226 CoTaskMemFree((PVOID)pmt->pbFormat);
230 pmt->pbFormat = NULL;
232 if (pmt->pUnk != NULL) {
233 pmt->pUnk->Release();
237 CoTaskMemFree((PVOID)pmt);
248 while(pthread_mutex_trylock(&imageMutex_)==EBUSY)
250 pthread_mutex_destroy(&imageMutex_);
256 CComPtr<ISpecifyPropertyPages> pPages;
258 HRESULT hr = pSrcPin->QueryInterface(IID_ISpecifyPropertyPages, (
void**)&pPages);
262 pSrcPin->QueryPinInfo(&PinInfo);
265 pPages->GetPages(&caGUID);
267 OleCreatePropertyFrame(
273 (IUnknown **)&(pSrcPin),
280 CoTaskMemFree(caGUID.pElems);
281 PinInfo.pFilter->Release();
288 CComPtr<ISpecifyPropertyPages> pProp;
289 HRESULT hr = pFilter->QueryInterface(IID_ISpecifyPropertyPages, (
void **)&pProp);
293 FILTER_INFO FilterInfo;
294 pFilter->QueryFilterInfo(&FilterInfo);
298 pProp->GetPages(&caGUID);
299 OleCreatePropertyFrame(
304 (IUnknown **)&pFilter,
311 if(FilterInfo.pGraph != NULL)
312 FilterInfo.pGraph->Release();
313 CoTaskMemFree(caGUID.pElems);
332 CComPtr<ISpecifyPropertyPages> pProp;
333 HRESULT hr = pFilter->QueryInterface(IID_ISpecifyPropertyPages, (
void **)&pProp);
337 FILTER_INFO FilterInfo;
338 pFilter->QueryFilterInfo(&FilterInfo);
342 pProp->GetPages(&caGUID);
343 OleCreatePropertyFrame(
348 (IUnknown **)&pFilter,
355 if(FilterInfo.pGraph != NULL)
356 FilterInfo.pGraph->Release();
357 CoTaskMemFree(caGUID.pElems);
420 BEXCEPTION(
"Failed to get DirectShow interfaces! ");
436 BEXCEPTION(
"Couldn't add the capture filter to the graph! \n"<<
437 "If you have a working video capture device, please make sure\n"<<
438 "that it is connected and is not being used by another application.");
448 BEXCEPTION(
"Could not find Source Outpin");
455 else BEXCEPTION(
"Did not fine outpin");
460 IAMStreamConfig * pConfig=0;
467 &MEDIATYPE_Interleaved,
472 BEXCEPTION(
"FindInterface unsucessfull");
476 AM_MEDIA_TYPE *pSourceVideoFormat = NULL, * pNewVideoFormat = NULL;
478 bool validCamResFound =
false;
479 pConfig->GetNumberOfCapabilities(&ccount,&csize);
480 BYTE* construct =
new BYTE[csize];
481 AM_MEDIA_TYPE* tmpMediaType;
482 for(
int c=0; c<ccount; c++)
485 if(pConfig->GetStreamCaps(c,&tmpMediaType,construct)!=S_OK)
486 BEXCEPTION(
"GetStreamCaps failed");
488 if(tmpMediaType->majortype==MEDIATYPE_Video)
490 if((tmpMediaType->formattype==FORMAT_VideoInfo) )
496 VIDEOINFOHEADER *vih = (VIDEOINFOHEADER *)tmpMediaType->pbFormat;
508 if((vih->bmiHeader.biWidth==
GetWidth())&&
509 (abs(vih->bmiHeader.biHeight)==
GetHeight()))
511 cout <<
"Matched width and height: "<<vih->bmiHeader.biWidth<<
"x"<<vih->bmiHeader.biHeight<<endl;
512 pSourceVideoFormat = tmpMediaType;
516 if((tmpMediaType->subtype==MEDIASUBTYPE_RGB24)||(tmpMediaType->subtype==MEDIASUBTYPE_RGB32)) {
517 cout <<
"Found requested RGB type"<<endl;
518 validCamResFound =
true;
523 if(tmpMediaType->subtype==MEDIASUBTYPE_YUY2) {
524 cout <<
"Found requested YUYV422"<<endl;
526 validCamResFound =
true;
532 if((tmpMediaType->subtype==MEDIASUBTYPE_RGB24)
533 ||(tmpMediaType->subtype==MEDIASUBTYPE_RGB32)) {
534 cout <<
"Accepting preferred RGB color model from camera"<<endl;
537 validCamResFound =
true;
540 if(tmpMediaType->subtype==MEDIASUBTYPE_YUY2) {
541 cout <<
"Accepting YUV422 color model from camera"<<endl;
544 validCamResFound =
true;
551 cout <<
"Unmatched width and height: "<<vih->bmiHeader.biWidth<<
"x"<<vih->bmiHeader.biHeight<<endl;
561 if(!pSourceVideoFormat)
563 BEXCEPTION(
"no usable camera resolution format found");
565 if(!validCamResFound)
567 cout <<
"no required video resolution found\n"<<endl;
573 if(pSourceVideoFormat->majortype == MEDIATYPE_Video)
585 BEXCEPTION(
"The major format type is NOT video");
589 BIASASSERT(pSourceVideoFormat->formattype==FORMAT_VideoInfo);
591 VIDEOINFOHEADER *vih = (VIDEOINFOHEADER *)pSourceVideoFormat->pbFormat;
592 vih->bmiHeader.biWidth =
GetWidth();
594 cout <<
"requesting "<<vih->bmiHeader.biWidth<<
"x"<<vih->bmiHeader.biHeight<<endl;
596 vih->bmiHeader.biSizeImage= DIBSIZE(vih->bmiHeader);
597 hr = pConfig->SetFormat( pSourceVideoFormat );
599 BEXCEPTION(
"Error Videoformat is inconsistent");
601 cout <<
"got requested format\n";
608 IEnumMediaTypes * pMedia=0;
609 vector<AM_MEDIA_TYPE *> vpfnt;
612 hr =
pOutPin_->EnumMediaTypes( &pMedia );
613 if( (hr =
pOutPin_->EnumMediaTypes( &pMedia )) == S_OK)
615 cout<<
"pOutPin_->EnumMediaTypes success"<< endl;
616 bool FoundOne =
false;
617 while(pMedia->Next(1, &pSourceVideoFormat, 0) == S_OK && !FoundOne)
619 if( pSourceVideoFormat->formattype == FORMAT_VideoInfo )
621 VIDEOINFOHEADER *vih = (VIDEOINFOHEADER *)pSourceVideoFormat->pbFormat;
622 int dCurWidth = vih->bmiHeader.biWidth;
623 int dCurHeight = abs(vih->bmiHeader.biHeight);
628 pNewVideoFormat = pSourceVideoFormat;
629 cout<<
"copying pin format to newvideoformat"<<endl;
634 BEXCEPTION(
"No useful format on pin found");
637 else if( pSourceVideoFormat->formattype == FORMAT_None )
638 cout<<
"Format type: FORMAT_None"<<endl;
639 else if( pSourceVideoFormat->formattype == FORMAT_DvInfo )
640 cout<<
"Format type: FORMAT_DvInfo"<<endl;
641 else if( pSourceVideoFormat->formattype == FORMAT_MPEGVideo )
642 cout<<
"Format type: FORMAT_MPEGVideo"<<endl;
643 else if( pSourceVideoFormat->formattype == FORMAT_MPEG2Video )
644 cout<<
"Format type: FORMAT_MPEG2Video"<<endl;
645 else if( pSourceVideoFormat->formattype == FORMAT_VideoInfo2 )
646 cout<<
"Format type: FORMAT_VideoInfo2"<<endl;
652 BEXCEPTION(
"pOutPin_->EnumMediaTypes failed");
656 if( pNewVideoFormat != 0 )
658 hr = pConfig->SetFormat( pNewVideoFormat );
661 BEXCEPTION(
"errro setting format");
663 int dWidth = ((VIDEOINFOHEADER *)pNewVideoFormat->pbFormat)->bmiHeader.biWidth;
664 int dHeight = ((VIDEOINFOHEADER *)pNewVideoFormat->pbFormat)->bmiHeader.biHeight;
665 double dDepth = ((VIDEOINFOHEADER *)pNewVideoFormat->pbFormat)->bmiHeader.biBitCount;
675 CComQIPtr< IBaseFilter, &IID_IBaseFilter > pGrabberBase(
pGrabber_ );
676 if ( (hr =
pGraphBuilder_->AddFilter(pGrabberBase,L
"SampleGrabber")) != S_OK)
678 BEXCEPTION(
"Couldn't add the grab filter.");
681 hr = pConfig->GetFormat( &pNewVideoFormat );
682 if( (hr =
pGrabber_->SetMediaType(pNewVideoFormat)) != S_OK )
684 BEXCEPTION(
"Setting Media Type failed!");
690 if (pGrabberBase->FindPin(L
"In",&
pInPin_) != S_OK)
691 BEXCEPTION(
"Could not find SampleGrabber Input Pin");
695 BEXCEPTION(
"Could not not connect Camera Source and SampleGrabber Pins")
697 cout<<
"Succesfully connected Camera Source and SampleGrabber Pins" <<endl;
702 BEXCEPTION(
"Couldn't add the grab filter.");
707 BEXCEPTION(
"Pin out of SampleGrabber not found");
711 BEXCEPTION(
"Could not find NullRenderer Input Pin");
715 BEXCEPTION(
"Could not not connect SampleGrabber and NullRenderer Pins")
717 cout<<
"Succesfully connected SampleGrabber and NullRenderer Pins" << endl;
730 if (FAILED(hr)) BEXCEPTION(
"Couldn't run the graph! ");
752 BIASERR(
"Error initialising Video capture:"<<e.
what());
755 BIASERR(
"Error initialising Video capture!");
757 if(ret <0)
return ret;
766 inline string ConvertBSTRToString(BSTR pSrc)
768 DWORD cb,cwch = ::SysStringLen(pSrc);
772 os.open("E:\\USBIdentifier.txt");
773 for ( unsigned i=0; i<cwch; i++ ) {
774 os << pSrc[i] << endl;
782 cb = ::WideCharToMultiByte(CP_ACP, 0, pSrc, cwch, NULL, 0, 0, 0);
784 szOut =
new char[cb];
786 szOut[cb - 1] =
'\0';
787 if(!::WideCharToMultiByte(CP_ACP, 0,pSrc, cwch, szOut, cb, 0, 0))
803 ICreateDevEnum *pSysDevEnum = NULL;
804 hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
805 IID_ICreateDevEnum, (
void **)&pSysDevEnum);
806 if (FAILED(hr))
return -1;
808 IEnumMoniker *pEnumCat = NULL;
809 hr = pSysDevEnum->CreateClassEnumerator((GUID)CLSID_VideoInputDeviceCategory,
813 IMoniker *pMoniker = NULL;
815 while(pEnumCat->Next(1, &pMoniker, &cFetched) == S_OK) {
816 IPropertyBag *pPropBag;
817 hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag,
821 VariantInit(&varName);
822 hr = pPropBag->Read(L
"Description", &varName, 0);
825 hr = pPropBag->Read(L
"FriendlyName", &varName, 0);
828 devices.push_back(ConvertBSTRToString(varName.bstrVal));
835 pSysDevEnum->Release();
845 hr = CoCreateInstance (CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
848 BIASERR(
"Could not create instance of Filtergraph for VideosourceDShow!");
851 if (hr!=S_OK)
return hr;
855 hr = CoCreateInstance(CLSID_CaptureGraphBuilder2 , NULL, CLSCTX_INPROC,
858 BIASERR(
"Could not create instance of CaptureGraphBuilder for VideosourceDShow!");
867 BIASERR(
"Failed to set capture filter graph!");
887 hr =
pGrabber_.CoCreateInstance(CLSID_SampleGrabber);
890 BIASERR(
"Could not create the SampleGrabber filter.");
902 IBaseFilter * pSrc = NULL;
909 CComPtr <ICreateDevEnum> pDevEnum =NULL;
911 hr = CoCreateInstance (CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC,
912 IID_ICreateDevEnum, (
void **) &pDevEnum);
915 BIASERR(
"Couldn't create system enumerator!");
920 IEnumMoniker* pClassEnum = 0;
922 hr = pDevEnum->CreateClassEnumerator (CLSID_VideoInputDeviceCategory, &pClassEnum, 0);
925 BIASERR(
"Couldn't create class enumerator! No DirectShow hardware?");
932 while(hr = pClassEnum->Next(1, &pM, &cFetched), hr==S_OK )
935 hr = pM->BindToStorage(0, 0, IID_IPropertyBag, (
void **)&pBag);
938 IErrorLog* errorLog=NULL;
942 hr = pBag->Read(L
"FriendlyName", &var, errorLog);
945 string cDevName = (
char*)((_bstr_t)(var.bstrVal));
951 cout<<
"Found CaptureDevice: " << cDevName.c_str() <<endl;
953 hr = pM->BindToObject(0, 0, IID_IBaseFilter, (
void**)&pSrc);
955 cout<<
"Failed to bind to object!" <<endl;
957 cout<<
"Successfully bound to object!" <<endl;
961 cout<<
"The defined device is not found taking next.."<<endl;
962 SysFreeString(var.bstrVal);
974 IEnumFilters *pEnum = NULL;
975 IBaseFilter *pFilter;
978 HRESULT hr = pGraph->EnumFilters(&pEnum);
979 if (FAILED(hr))
return hr;
981 while(pEnum->Next(1, &pFilter, &cFetched) == S_OK)
983 FILTER_INFO FilterInfo;
984 hr = pFilter->QueryFilterInfo(&FilterInfo);
987 MessageBox(NULL, TEXT(
"Could not get the filter info"),
988 TEXT(
"Error"), MB_OK | MB_ICONERROR);
994 if (FilterInfo.pGraph != NULL)
996 FilterInfo.pGraph->Release();
1017 cout <<
"Have a CameraControl"<<endl;
1050 cout<<
"Exposure control:"<<endl;
1061 cout <<
"Have a VideoProcAmp"<<endl;
1073 cout<<
"Brightness control:"<<endl;
1102 const WCHAR wszStreamName[] = L
"ActiveMovieGraph";
1104 IStorage *pStorage = NULL;
1107 hr = StgCreateDocfile(
1109 STGM_CREATE | STGM_TRANSACTED | STGM_READWRITE |
1110 STGM_SHARE_EXCLUSIVE,
1119 hr = pStorage->CreateStream(
1121 STGM_WRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE,
1125 pStorage->Release();
1131 IPersistStream *pPersist = NULL;
1132 pGraph->QueryInterface(IID_IPersistStream,
1133 reinterpret_cast<void**>(&pPersist));
1134 hr = pPersist->Save(pStream, TRUE);
1136 pPersist->Release();
1139 hr = pStorage->Commit(STGC_DEFAULT);
1141 pStorage->Release();
1149 long prop = CameraControl_Exposure;
1155 float exptime = float(value)/10000.0f;
1166 long prop = CameraControl_Exposure;
1167 long value,flags = CameraControl_Flags_Manual;
1172 value = long(exptime);
1176 if (SUCCEEDED(hr)) {
1189 long prop = CameraControl_Exposure;
1190 long value,flags = CameraControl_Flags_Auto;
1191 if(!b) flags = CameraControl_Flags_Manual;
1200 long prop = CameraControl_Exposure;
1201 long value,flags = CameraControl_Flags_Auto;
1204 if (SUCCEEDED(hr))
return true;
1231 float br = float(value);
1242 long value = long(g);
1255 flags = VideoProcAmp_Flags_Auto;
1257 flags = VideoProcAmp_Flags_Manual;
1292 value = (int)rint(br);
1294 return (
int)rint(br);
1305 flags = VideoProcAmp_Flags_Auto;
1307 flags = VideoProcAmp_Flags_Manual;
1356 #ifdef BIAS_HAVE_PTHREADS
1358 pthread_mutex_lock(&imageMutex_);
1362 memcpy(pImageData,pBuffer,BufferLen);
1370 #ifdef BIAS_HAVE_PTHREADS
1372 pthread_mutex_unlock(&imageMutex_);
1380 #ifdef BIAS_HAVE_PTHREADS
1381 pthread_mutex_lock(&imageMutex_);
1387 pSample->GetPointer(&pSampleData);
1388 long size = pSample->GetSize();
1391 memcpy(pImageData,pSampleData,size);
1399 #ifdef BIAS_HAVE_PTHREADS
1400 pthread_mutex_unlock(&imageMutex_);
1409 if( riid == IID_ISampleGrabberCB || riid == IID_IUnknown ) {
1410 *ppv = (
void *) static_cast<ISampleGrabberCB*> (
this );
1413 return E_NOINTERFACE;
STDMETHODIMP SampleCB(double SampleTime, IMediaSample *pSample)
EColorModel
These are the most often used color models.
void Release()
reimplemented from ImageBase
YUYV422, 2 channels, full luminance Y, subsampled half U,V.
virtual void SetSize(int w, int h, int bytesperpixel=1)
Set image size and number of bytes per pixel (e.g.
CComPtr< IAMVideoProcAmp > pVideoProcControl_
int GetCapabilities(VideoSourceCapabilities &caps)
Use this method to learn something about the capabilities of the source (only useful for V4L sources...
bool HasControlBrightness()
bool GetCapabilitiesOnly_
HRESULT GetInterfaces_(void)
int GrabSingle(BIAS::Camera< unsigned char > &image)
int SetBrightness(float g)
Set brightness as value in interval [0, 100]. */.
int PostGrab()
Stop anything started in PreGrab()
int SetShutter(float exptime)
Set shutter (exposure time) to exptime in seconds.
Defines a common interface to different devices.
STDMETHODIMP QueryInterface(REFIID riid, void **ppv)
STDMETHODIMP BufferCB(double SampleTime, BYTE *pBuffer, long BufferLen)
CComPtr< IBaseFilter > pNullRenderer_
void SetSizeAndColorModel(int width, int height, int bytesperpixel=1, BIAS::ImageBase::EColorModel model=BIAS::ImageBase::CM_invalid)
BIAS::Camera< unsigned char > camera_
bool IsEmpty() const
check if ImageData_ points to allocated image buffer or not
bool HasControlContrast()
void CopyIn_NoInit(void *data)
Take some data and fill it into the Image.
void DeleteMediaType_(AM_MEDIA_TYPE *pmt)
YUV411, 2 channles, full luminance, 1 U, 1 V.
unsigned char * lastMemorySample_
bool DisplayCameraProperties()
void SetColorModel(EColorModel Model)
unsigned int GetSizeByte() const
returns the nr.
BIAS::ImageBase::EColorModel ColorMode_
Color mode used by camera.
CComPtr< IGraphBuilder > pGraphBuilder_
CComPtr< IAMCameraControl > pCameraControl_
bool DisplayPinProperties_(CComPtr< IPin > pSrcPin)
CameraControl ControlExposure_
bool WaitForNew_
Wait for new frames in GrabSingle()
CComPtr< IBaseFilter > pSrcFilter_
HRESULT InitVideoCapture_()
int GetColorChannels() const
void DisplaySourcePinProperties()
float GetContrast()
Get contrast as value in interval [0, 100]. */.
CameraControl ControlTilt_
Image< unsigned char > & GetImage()
MySampleGrabberCB(int width, int height, int depth)
YUV420P, 2 channels, full luminance Y, 1 U, 1 V. Y, U and V are grouped together for better compressi...
CComPtr< ICaptureGraphBuilder2 > pCaptureGraphBuilder2_
void DetermineBIASColorModel_()
int InitImage(BIAS::ImageBase &Image)
color values, 3 channels, order: blue,green,red
virtual int SetColorModel(BIAS::ImageBase::EColorModel mode)
Select colormodel to use.
void ResetPanTiltZoom(void)
Reset digital zoom, pan, and tilt to defaults to ensure compliance with calibration.
std::string Identifier_
Verbose camera descriptor.
int OpenDevice()
selects the first available device to open (e.g.
BIAS::ImageBase::EColorModel BIASColorModel_
color values, 3 channels, order: red,green,blue
bool DisplayFilterProperties(CComPtr< IBaseFilter > pFilter)
CComPtr< ISampleGrabber > pGrabber_
UYVY422, 2 channels, full luminance Y, subsampled half U,V inverse order.
HRESULT SaveGraphFile_(IGraphBuilder *pGraph, WCHAR *wszPath)
The image template class for specific storage types.
CComPtr< IMediaEventEx > pMediaEvent_
void DetermineColorModel_()
void Init(unsigned int Width, unsigned int Height, unsigned int channels=1, enum EStorageType storageType=ST_unsignedchar, const bool interleaved=true)
calls Init from ImageBase storageType is ignored, just dummy argument
const StorageType * GetImageData() const
overloaded GetImageData() from ImageBase
void SetUID(const BIAS::UUID &id)
RGBA, 4 channels, order: red,green,blue,alpha.
GUID MediaSubTypeColorModel_
void Release(const bool reset_storage_type=false)
Free the allocated data structures Hands off: Do !!NOT!! change the default of reset_storage_type: Im...
HRESULT FindCaptureDevice_(IBaseFilter **ppSrcFilter)
HRESULT EnumFilters_(IFilterGraph *pGraph)
unsigned char * pImageBuffer_
void AddMode(unsigned int width, unsigned int height, float fps, ImageBase::EColorModel colormodel, bool interlaced=false)
unsigned char * currentMemorySample_
void Init(unsigned int width, unsigned int height, unsigned int nChannels=1, enum EStorageType storageType=ST_unsignedchar, const bool interleaved=true)
Initialize image size and channels.
CameraControl ControlBrightness_
invalid (not set) image format
Checks for VideoSource capabilities.
virtual const char * what() const
Returns a C-style character string describing the general cause of the current error.
VideoSource_DSHOW(bool bShowDialogs=false)
int Flip()
flips the image vertically (row order is inverted) In place function return 0 in case of success...
int GetAllDevices(std::vector< std::string > &devices)
void SetAutoBrightness(bool b)
void SetNewImageCheck(bool check=true)
void SetAutoShutter(bool b)
CComPtr< IPin > pSampleOutPin_
CameraControl ControlZoom_
std::string sCaptureDeviceName_
float GetBrightness()
Get brightness as value in interval [0, 100]. */.
int PreGrab()
Do last preparations before grabbing (e.g. start ISO transfer)
float GetShutter()
Get shutter (exposure time) in seconds.
This is the base class for images in BIAS.
static UUID GenerateUUID(const bool &consecutively=DEFAULT_UUID_CONSECUTIVELY)
static function which simply produces a uuid and returns
CameraControl ControlContrast_
CComPtr< IMediaControl > pMediaControl_
int SetContrast(float g)
Set contrast as value in interval [0, 100]. */.
void SetAutoContrast(bool b)
VideoSourceCapabilities Capabilities_
CameraControl ControlPan_