⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 capturedevicedshow.cpp

📁 VideoMan is a very easy image acquisition library. It is able to manage many video inputs at the sam
💻 CPP
字号:
#include "StdAfx.h"

#include <iostream>

#include "CaptureDeviceDShow.h"
#include "DirectShowHelpers.h"

using namespace std;

CaptureDeviceDShow::CaptureDeviceDShow(void)
{	
}

CaptureDeviceDShow::~CaptureDeviceDShow(void)
{
}

bool CaptureDeviceDShow::initCamera( const std::string &friendlyName, const std::string &devicePath, VideoManInputFormat *aFormat )
{
    // Initialize DirectShow and query for needed interfaces
    HRESULT hr = initDirectShow();
    if ( FAILED( hr ) )
    {
		cerr << "Failed to initialize DirectShow!" << endl;
		freeDirectShow();
		return false;
    }

	identification.friendlyName = friendlyName;
	identification.devicePath = devicePath;

	hr = prepareMedia( identification.friendlyName, identification.devicePath, aFormat );	
    if (FAILED(hr))
    {
		cerr << "Failed preparing media! " << endl;
		cerr << "friendlyName: " << identification.friendlyName << endl;
		cerr << "devicePath: " << identification.devicePath << endl;
        freeDirectShow();     
        return false;
    }

	hr = pMC->Run();
	if ( FAILED( hr ) )
	{
		cerr << "Failed running camera!" << endl;
		freeDirectShow();
		return false;
	}

	frameCaptured = false;

	if ( format.width<=0 || format.height<=0 )
	{
		freeDirectShow();
		return false;
	}
	if (format.fps<=0)
		format.fps=30;

	if ( aFormat != NULL )	
		*aFormat = format;

	return true;
}

HRESULT CaptureDeviceDShow::prepareMedia( std::string &friendlyName, std::string &devicePath, VideoManInputFormat *aFormat  )
{
    HRESULT hr = S_OK;

	if ( FAILED ( hr = CoCreateInstance(CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER,
		IID_IBaseFilter, (void**)&pSG) ) )
		return hr;	
	if ( FAILED( pSG->QueryInterface(IID_ISampleGrabber,(void**)&sampleGrabber)) )
		return(hr);
  	
  	//std::string selectedName = name;
	hr = findCaptureDevice( &videoSource, friendlyName, devicePath );
	if ( SUCCEEDED( hr ) )
	{
		if ( FAILED(hr = pGB->AddFilter(videoSource, L"Video Source")))
			return hr;
	}
	else
		return E_FAIL;

	CComPtr<IPin> outPinVideoSource = NULL;
	if ( FAILED( hr = getPin( videoSource, PINDIR_OUTPUT, 1, outPinVideoSource ) ) ) 
		return hr;

	CComPtr <IAMStreamConfig> pStreamConfig = NULL;
	hr = pCGB->FindInterface(&PIN_CATEGORY_CAPTURE,NULL,videoSource,IID_IAMStreamConfig,(void**)&pStreamConfig);
	if (FAILED(hr))		
		return hr;
	

	AM_MEDIA_TYPE mediaType;
	//Find the first media type
	/*if ( findOneMediaType( outPinVideoSource, &mediaType ) == S_OK )
	{
		//Set this media type to initilize pin propeties
		pStreamConfig->SetFormat( &mediaType );
	}*/
	if ( aFormat == NULL || aFormat->showDlg )
	{
		//if( FAILED( hr = displayPinProperties(outPinVideoSource) ) ) 
		//	return(hr);
		displayPinProperties(outPinVideoSource);
	}
	else
	{
		//AM_MEDIA_TYPE mediaType;
		bool notFound = false;
		if ( FAILED ( hr = findMediaType( outPinVideoSource, aFormat, &mediaType ) ) )
		{
			notFound = true;
		}
		else if ( FAILED( hr = pStreamConfig->SetFormat( &mediaType ) ) )
		{
			return hr;
		}

		if( notFound )
		{
			if ( FAILED( hr = displayPinProperties(outPinVideoSource) ) ) 
				return(hr);
		}
	}

	CComPtr <IBaseFilter> pVideoRenderer = NULL;
	if ( FAILED( hr = CoCreateInstance(CLSID_NullRenderer, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&(pVideoRenderer) ) ) )
		return hr;
	if ( FAILED ( hr = pGB->AddFilter(pVideoRenderer, L"NULL Video Renderer") ) )
		return hr;	
	if ( FAILED( hr = CoCreateInstance(CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER,
		IID_IBaseFilter, (void**)&pSG) ) )
		return hr;	
	if ( FAILED( hr = pSG->QueryInterface(IID_ISampleGrabber,(void**)&sampleGrabber)) )
		return(hr);
	
	//Set sampleGrabber format
	AM_MEDIA_TYPE _mt;
	ZeroMemory(&_mt,sizeof(AM_MEDIA_TYPE));
	_mt.majortype = MEDIATYPE_Video;
	_mt.formattype = GUID_NULL;
	if ( aFormat != NULL )	
		_mt.subtype = translatePIXEL_FORMAT( aFormat->getPixelFormatOut() );
	else
		_mt.subtype = translatePIXEL_FORMAT( RGB24 );
	if ( FAILED( hr = sampleGrabber->SetMediaType(&_mt) ) )
		return hr;
	if ( FAILED( hr = pGB->AddFilter(pSG, L"Sample Grabber") ) )
		return hr;

	//Conect the source and the grabber
	if ( FAILED( hr = autoConnectFilters(videoSource,1,pSG,1,pGB) )	 )
		return hr;
	//Conect the grabber and the renderer
	if ( FAILED( hr = autoConnectFilters(pSG,1,pVideoRenderer,1,pGB) ) )
		return hr;
	
	#ifdef _DEBUG
		hr = addToRot( pGB, &dwRegisterROT);
	#endif

//	AM_MEDIA_TYPE mediaType;
	CComPtr<IPin> rendererPin = NULL;
	if(FAILED(hr = getPin(pVideoRenderer,PINDIR_INPUT,1,rendererPin))) return(hr);

	rendererPin->ConnectionMediaType(&mediaType);

	VIDEOINFOHEADER *pvi = (VIDEOINFOHEADER *) mediaType.pbFormat;

	FILTER_INFO filter_info;
	videoSource->QueryFilterInfo(&filter_info);
	if( filter_info.pGraph != NULL )
		filter_info.pGraph->Release(); 

	GUID subtype  = mediaType.subtype;
	format.width  = pvi->bmiHeader.biWidth;
	format.height = pvi->bmiHeader.biHeight;
	format.fps = referenceTime2fps( pvi->AvgTimePerFrame );
 	format.setPixelFormat( UNKNOWN, translateMEDIASUBTYPE( mediaType.subtype ) );
	FreeMediaType(mediaType);

	hr = EnableMemoryBuffer();
	if ( aFormat != NULL )
		dropFrames = aFormat->dropFrames;

	//pMS->SetRate(2);

    return hr;
}

inline char *CaptureDeviceDShow::getFrame( bool wait)
{
/*	m_CSec.Lock();
	if ( mb.size() > 0 )
	{
		mb.front().blocked = true;
		m_CSec.Unlock();
		mb.front().media_sample->GetPointer((BYTE**)&pixelBuffer);
		frameCaptured = true;
		return pixelBuffer;
	}
	m_CSec.Unlock();
	return NULL;*/
	if ( mediaSample != NULL )
	{
		mediaSample->GetPointer((BYTE**)&pixelBuffer);
		frameCaptured = true;
		return pixelBuffer;
	}	
	return NULL;
}


void CaptureDeviceDShow::releaseFrame()
{
	/*if (frameCaptured)
	{
		pixelBuffer = NULL;
		mb.front().media_sample->Release();
		mb.front().blocked = false;
		mb.pop_front();
		frameCaptured = false;
	}*/
	if ( mediaSample != NULL )
	{
		pixelBuffer = NULL;		
		mediaSample->Release();
		mediaSample = NULL;
		frameCaptured = false;		
		if ( !dropFrames )
			play();
	}
}


void CaptureDeviceDShow::play()
{
	if ( pMC != NULL )
		pMC->Run();	
}


void CaptureDeviceDShow::pause()
{
	if ( pMC != NULL )
		pMC->Pause();
}


void CaptureDeviceDShow::stop()
{
	stopMedia();
}


void CaptureDeviceDShow::showPropertyPage()
{
	DWORD dwThreadID;
	HANDLE hFPropThread = CreateThread(NULL,0,showFilterPropertiesThread,(LPVOID)videoSource,0,&dwThreadID);
}

void CaptureDeviceDShow::getAvailableDevices( std::vector<inputIdentification> &deviceList  )
{
	//Create a device enumerator
	ICreateDevEnum *pSysDevEnum = NULL;
	HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, 
								IID_ICreateDevEnum,(void **)&pSysDevEnum);
	
	if (FAILED(hr))
		return;

	// Get an enumerator class for the video inpout category
	IEnumMoniker *pEnumCat = NULL;
	hr = pSysDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnumCat, 0);	
	if (hr == S_OK)
	{
		IMoniker *pMoniker = NULL;
		ULONG cFetched;
		//list=new CStringArray();
		while ((pEnumCat->Next(1, &pMoniker, &cFetched) == S_OK))
		{
			IPropertyBag *pPropBag;
			hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag,(void **)&pPropBag);
			if (SUCCEEDED(hr))
			{				
				VARIANT varName;				
				VariantInit(&varName);
				hr = pPropBag->Read(L"FriendlyName", &varName, 0);				
				if (SUCCEEDED(hr))
				{					
					std::string friendlyName;					
					int ret = WideCharToMultiByte( CP_ACP, 0, (LPCWSTR)varName.pcVal, -1, NULL, 0, NULL, NULL );
					std::vector<char> friendlyNameAux( ret + 1 );					
					WideCharToMultiByte( CP_ACP, 0, (LPCWSTR)varName.pcVal, -1, &friendlyNameAux[0], ret, NULL, NULL );
					friendlyName = &friendlyNameAux[0];
					hr = pPropBag->Read(L"DevicePath", &varName, 0);
					std::string devicePath;
					if (SUCCEEDED(hr))
					{						
						int ret = WideCharToMultiByte( CP_ACP, 0, (LPCWSTR)varName.pcVal, -1, &friendlyName[0], 0, NULL, NULL );
						std::vector<char> deviceAux( ret + 1 );						
						WideCharToMultiByte( CP_ACP, 0, (LPCWSTR)varName.pcVal, -1, &deviceAux[0], ret, NULL, NULL );
						devicePath = &deviceAux[0];
						/*std::string aux;
						size_t ind = devicePath.find( '?' );
						aux.resize( devicePath.length() - ind - 2 );
						devicePath.copy( &aux[0], devicePath.length() - ind - 2, ind + 2 );
						ind = aux.find( '#' );
						std::string type;
						type.resize(10);
						aux.copy( &type[0], ind, 0 );
						type.resize(ind);
						std::string pathAux;
						pathAux.resize( devicePath.length() );
						ind = devicePath.rfind( '#' );						
						devicePath.resize( ind );						
						ind = devicePath.rfind( '#' ); //second #
						devicePath.erase( devicePath.begin(), devicePath.begin() + ind + 1 );												
						*/
					}
					
					inputIdentification device;
					device.devicePath = devicePath;
					device.friendlyName = friendlyName;						
					device.identifier = "DSHOW_CAPTURE_DEVICE";							
					deviceList.push_back( device );												
								
				}
				VariantClear(&varName);
				SAFE_RELEASE(pPropBag);
			}
			SAFE_RELEASE(pMoniker);
		}	
	}
	SAFE_RELEASE(pEnumCat);
	SAFE_RELEASE(pSysDevEnum);
	return;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -