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

📄 videoinputdshow.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 "VideoInputDShow.h"
#include "DirectShowHelpers.h"
#include <iostream>

using namespace std;

VideoInputDShow::VideoInputDShow(void)
{
	pGB = NULL;
	pCGB = NULL;
	pMS = NULL;
	pMC = NULL;
	pSG = NULL;
	sampleGrabber = NULL;
	videoSource = NULL;
	dropFrames = true;
	mediaSample = NULL;
}

VideoInputDShow::~VideoInputDShow(void)
{
	#ifdef _DEBUG
		removeFromRot(dwRegisterROT);
		dwRegisterROT = 0;
	#endif
	if ( pMC )
		pMC->Pause();
	if ( mediaSample != NULL )
	{
		mediaSample->Release();
		mediaSample = NULL;
	}	
	stopMedia();
	freeDirectShow();	
}

HRESULT VideoInputDShow::initDirectShow(void)
{
	CoInitialize(NULL);

    HRESULT hr = S_OK;	

    hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC, IID_IGraphBuilder,
                        (void **)&pGB);	
	if ( SUCCEEDED( hr ) )	hr = CoCreateInstance (CLSID_CaptureGraphBuilder2 , NULL, CLSCTX_INPROC,		IID_ICaptureGraphBuilder2, (void **) &pCGB);	

    if ( SUCCEEDED( hr ) )
		hr = pGB->QueryInterface(IID_IMediaControl,  (void **)&pMC);
    if ( SUCCEEDED( hr ) )
		hr = pGB->QueryInterface(IID_IMediaSeeking,  (void **)&pMS);

	if ( SUCCEEDED( hr ) )
		return S_OK;
	else
	{
		freeDirectShow();
		return(hr);
	}
}

HRESULT VideoInputDShow::freeDirectShow(void)
{
    HRESULT hr=S_OK;

    stopMedia();

    SAFE_RELEASE(pMC);
    SAFE_RELEASE(pMS);
	SAFE_RELEASE(pSG);
	SAFE_RELEASE(sampleGrabber);
	SAFE_RELEASE(videoSource);
	SAFE_RELEASE(pCGB);	
	SAFE_RELEASE(pGB);		

    return hr;
}

HRESULT VideoInputDShow::stopMedia()
{
    HRESULT hr = S_OK;

    if ( pMC != NULL )
	{
		hr = pMC->Stop();
		if (FAILED(hr)) 
		{
			cerr << "Failed in Stop()!" << endl;
			return hr;
		}
	}
    return E_FAIL;
}

HRESULT VideoInputDShow::EnableMemoryBuffer(unsigned int _maxConcurrentClients,						   unsigned int _allocatorBuffersPerClient){
	HRESULT hr;
    
	if(_allocatorBuffersPerClient < 1)
		_allocatorBuffersPerClient = 1;
	if(_maxConcurrentClients <= 0)
		_maxConcurrentClients = 1;

	int currentAllocatorBuffers = _maxConcurrentClients * _allocatorBuffersPerClient;

	// ------
	CComPtr<IPin> sgPin = NULL;	if(FAILED(hr=getPin(pSG,PINDIR_INPUT,1,sgPin))) return(hr); 	CComPtr<IMemAllocator> pAllocator = NULL;	CComPtr<IMemInputPin> sgmiPin = NULL; 	if ( FAILED( hr = sgPin->QueryInterface(IID_IMemInputPin, (void**)&sgmiPin) ) )		return(hr);	if( FAILED(hr = sgmiPin->GetAllocator(&pAllocator)))		return(hr);	if( FAILED(hr = pAllocator->Decommit()))		return(hr);	ALLOCATOR_PROPERTIES requestedProperties;	ALLOCATOR_PROPERTIES actualProperties;	pAllocator->GetProperties(&requestedProperties);	if(requestedProperties.cBuffers != currentAllocatorBuffers)		requestedProperties.cBuffers = currentAllocatorBuffers;	if ( FAILED( hr = pAllocator->SetProperties(&requestedProperties,&actualProperties) ) )		return(hr);

	sampleGrabber->SetBufferSamples(FALSE);	sampleGrabber->SetOneShot(FALSE);		CComPtr<ISampleGrabberCB> custom_sgCB;	if ( FAILED( hr = QueryInterface(IID_ISampleGrabberCB, (void**)&custom_sgCB) ) )			return(hr);	hr = sampleGrabber->SetCallback(custom_sgCB,0);		return(hr);}

HRESULT VideoInputDShow::findMediaType(IPin *pin, VideoManInputFormat *requestedFormat, AM_MEDIA_TYPE *requestedMT ) {	HRESULT hr;	CComPtr<IEnumMediaTypes> enum_mt;	pin->EnumMediaTypes(&enum_mt);	enum_mt->Reset();	AM_MEDIA_TYPE *mediaType = NULL;	GUID requestedSubtype;	requestedSubtype =GUID_NULL;//;GUID_NULL;//translatePIXEL_FORMAT( requestedFormat->pixelFormat );	requestedSubtype = translatePIXEL_FORMAT( requestedFormat->getPixelFormatIn() );	while( S_OK == ( hr = enum_mt->Next( 1, &mediaType, NULL ) ) )	{		VIDEOINFOHEADER *pvi = (VIDEOINFOHEADER *) mediaType->pbFormat;		if ( requestedFormat->fps > 0 )			pvi->AvgTimePerFrame = fps2referenceTime( requestedFormat->fps );		CopyMediaType( requestedMT, mediaType );				if( ((mediaType->subtype == requestedSubtype) || (requestedSubtype == GUID_NULL)) &&			(pvi->bmiHeader.biHeight == requestedFormat->height) &&			(pvi->bmiHeader.biWidth  == requestedFormat->width) )					{			DeleteMediaType(mediaType);			return(S_OK);		}		else DeleteMediaType(mediaType);	}	return(E_FAIL);}

HRESULT VideoInputDShow::findOneMediaType(IPin *pin, AM_MEDIA_TYPE *requestedMT ) {	HRESULT hr;	CComPtr<IEnumMediaTypes> enum_mt;	pin->EnumMediaTypes(&enum_mt);	enum_mt->Reset();	AM_MEDIA_TYPE *mediaType = NULL;	GUID requestedSubtype;	requestedSubtype =GUID_NULL;	if ( S_OK == ( hr = enum_mt->Next( 1, &mediaType, NULL ) ) )	{		VIDEOINFOHEADER *pvi = (VIDEOINFOHEADER *) mediaType->pbFormat;				pvi->AvgTimePerFrame = fps2referenceTime( 30.0 );		CopyMediaType( requestedMT, mediaType );		DeleteMediaType(mediaType);		return(S_OK);			}	return(E_FAIL);}


HRESULT VideoInputDShow::findCaptureDevice( IBaseFilter ** ppSrcFilter, std::string &friendlyName, std::string &devicePath )
{
	//Create a device enumerator
	ICreateDevEnum *pSysDevEnum = NULL;
	HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, 
								IID_ICreateDevEnum,(void **)&pSysDevEnum);
	if (FAILED(hr))
		return hr;

	// 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 fName;
					std::string dPath;
					int ret = WideCharToMultiByte( CP_ACP, 0, (LPCWSTR)varName.pcVal, -1, &fName[0], 0, NULL, NULL );
					std::vector<char> friendlyNameAux( ret + 1 );					
					WideCharToMultiByte( CP_ACP, 0, (LPCWSTR)varName.pcVal, -1, &friendlyNameAux[0], ret, NULL, NULL );					
					fName = &friendlyNameAux[0];
					hr = pPropBag->Read(L"DevicePath", &varName, 0);
					if ( SUCCEEDED( hr ) )
					{					
						int ret = WideCharToMultiByte( CP_ACP, 0, (LPCWSTR)varName.pcVal, -1, &fName[0], 0, NULL, NULL );
						std::vector<char> deviceAux( ret + 1 );						
						WideCharToMultiByte( CP_ACP, 0, (LPCWSTR)varName.pcVal, -1, &deviceAux[0], ret, NULL, NULL );						
						dPath = &deviceAux[0];
					}
					if ( ( friendlyName.empty() && devicePath.empty() ) ||
							( friendlyName.empty() && !devicePath.empty() && devicePath == dPath ) ||
							( !friendlyName.empty() && devicePath.empty() && friendlyName == fName ) ||
							( !friendlyName.empty() && !devicePath.empty() && friendlyName == fName && devicePath == dPath) )
					{
						friendlyName = fName;
						devicePath = dPath;
						// Bind Moniker to a filter object						hr = pMoniker->BindToObject(0,0,IID_IBaseFilter, (void**)ppSrcFilter);
						SAFE_RELEASE(pPropBag);
						SAFE_RELEASE(pMoniker);
						SAFE_RELEASE(pEnumCat);
						SAFE_RELEASE(pSysDevEnum);
						return hr;
					}					

					/*Parse the devicepath
						"\\?\1394#sony&dfw-v_500_2.30#780c02002460008#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\global"
					*/
					/*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 );
					if ( type == "usb" || type == "USB" )
					{
						//devicePath = devicePath.Left( devicePath.ReverseFind( '#' ) );
						std::string pathAux;
						pathAux.resize( devicePath.length() );
						ind = devicePath.rfind( '#' );						
						devicePath.resize( ind );
						//devicePath.copy( &pathAux[0], ind, 0);
						ind = devicePath.rfind( '#' ); //second #
						devicePath.erase( devicePath.begin(), devicePath.begin() + ind + 1 );
						
						if ( name.empty() )							
						{
							name = friendlyName;
							// Bind Moniker to a filter object							hr = pMoniker->BindToObject(0,0,IID_IBaseFilter, (void**)ppSrcFilter);
							SAFE_RELEASE(pPropBag);
							SAFE_RELEASE(pMoniker);
							SAFE_RELEASE(pEnumCat);
							SAFE_RELEASE(pSysDevEnum);
							return hr;
						}
						else if ( devicePath == name )
						{
							// Bind Moniker to a filter object							hr = pMoniker->BindToObject(0,0,IID_IBaseFilter, (void**)ppSrcFilter);
							SAFE_RELEASE(pPropBag);
							SAFE_RELEASE(pMoniker);
							SAFE_RELEASE(pEnumCat);
							SAFE_RELEASE(pSysDevEnum);
							return hr;
						}
					}
					else if ( type == "1394" )
					{
						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 );							
						if ( name.empty() )
						{
							name = devicePath;
							// Bind Moniker to a filter object							hr = pMoniker->BindToObject(0,0,IID_IBaseFilter, (void**)ppSrcFilter);
							SAFE_RELEASE(pPropBag);
							SAFE_RELEASE(pMoniker);
							SAFE_RELEASE(pEnumCat);
							SAFE_RELEASE(pSysDevEnum);
							return hr;
						}
						else if ( devicePath == name )
						{
							// Bind Moniker to a filter object							hr = pMoniker->BindToObject(0,0,IID_IBaseFilter, (void**)ppSrcFilter);
							SAFE_RELEASE(pPropBag);
							SAFE_RELEASE(pMoniker);
							SAFE_RELEASE(pEnumCat);
							SAFE_RELEASE(pSysDevEnum);
							return hr;
						}							
					}*/						
				}
				VariantClear(&varName);
				SAFE_RELEASE(pPropBag);
			}
			SAFE_RELEASE(pMoniker);
		}
		SAFE_RELEASE(pEnumCat);
	}
	SAFE_RELEASE(pSysDevEnum);
	return E_FAIL;
}


//// ISampleGrabberCB interface methods -----------------

HRESULT WINAPI VideoInputDShow::QueryInterface(REFIID iid, void** ppvObject )
{
	// Return requested interface
	if (IID_IUnknown == iid)
	{
		*ppvObject = dynamic_cast<IUnknown*>( this );
	}
	else if (IID_ISampleGrabberCB == iid)
	{
		// Sample grabber callback object
		*ppvObject = dynamic_cast<ISampleGrabberCB*>( this );
	}
	else
	{     
		// No interface for requested iid - return error.
		*ppvObject = NULL;
		return E_NOINTERFACE;
	}

	// inc reference count
	this->AddRef();
	return S_OK;
}

ULONG WINAPI VideoInputDShow::AddRef()
{
	return(fRefCount++);
}

ULONG WINAPI VideoInputDShow::Release()
{
	return (fRefCount--);
}


HRESULT WINAPI VideoInputDShow::SampleCB( double SampleTime, IMediaSample *pSample ){		/*while( be.media_sample != NULL )	{	}			pSample->AddRef();	be.media_sample = pSample;			LONGLONG time, endT;	pSample->GetMediaTime( &time, &endT );	std::cout << "nuevo sample " << static_cast<double>( time  ) << std::endl;	return(S_OK);*/	if ( !dropFrames )	{		pMC->Pause();			}	if ( mediaSample == NULL )	{		pSample->AddRef();		mediaSample = pSample;		//LONGLONG time, endT;		//pSample->GetMediaTime( &time, &endT );		return(S_OK);	}		/*if ( dropFrames )	{		if ( mb.size() < 2 )		{		//	m_CSec.Unlock();
			MemoryBufferEntry mb_entry;	
			mb_entry.media_sample = pSample;			mb_entry.blocked = false;			pSample->AddRef();
			mb.push_back( mb_entry );
		}
		else	
		{
			pSample->AddRef();
			pSample->Release();
		}
	}
	else
	{		//m_CSec.Unlock();
		MemoryBufferEntry mb_entry;	
		mb_entry.media_sample = pSample;		mb_entry.blocked = false;		pSample->AddRef();
		mb.push_back( mb_entry );
	}*/
		return(S_FALSE);}HRESULT WINAPI VideoInputDShow::BufferCB(double sampleTimeSec, BYTE* bufferPtr, long bufferLength){	return(E_NOTIMPL);}

⌨️ 快捷键说明

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