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

📄 directshowhelpers.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 "DirectShowHelpers.h"

#include <sstream>
#include <objbase.h>
#include <comutil.h>
#include <process.h>
#include <math.h> 

// Make a lowercase copy of s: 
void lowerCase( std::wstring &s )
{ 
	for( size_t i = 0; i < s.length(); ++i ) 
		s[i] = tolower( s[i] );
}

HRESULT addToRot(IUnknown *pUnkGraph, DWORD *pdwRegister) 
// see Microsoft DirectX SDK 9.0 "Loading a Graph From an External Process" 
{
	CComPtr<IMoniker> pMoniker;
	CComPtr<IRunningObjectTable> pROT;
	if (FAILED(GetRunningObjectTable(0, &pROT))) {
		return E_FAIL;
	}	
	std::ostringstream text;	
	text << "FilterGraph " << static_cast<unsigned long>((DWORD_PTR)pUnkGraph) << "pid " << GetCurrentProcessId();
	HRESULT hr = CreateItemMoniker(L"!", _bstr_t(text.str().c_str()), &pMoniker);
	if (SUCCEEDED(hr))
		hr = pROT->Register(0, pUnkGraph, pMoniker, pdwRegister);	
	return hr;
}

void removeFromRot(DWORD pdwRegister)
{
	CComPtr<IRunningObjectTable> pROT;
	if (SUCCEEDED(GetRunningObjectTable(0, &pROT))) {
		pROT->Revoke(pdwRegister);
	}
}

	

HRESULT getPin(IBaseFilter *flt, PIN_DIRECTION dir, const GUID &mediaType, CComPtr<IPin> &pRetPin)
{	
	IPin* Pin;
	IEnumPins*	EnumPins;
	ULONG		fetched;
	PIN_INFO	pinfo;

	flt->EnumPins(&EnumPins);
	EnumPins->Reset();
	EnumPins->Next(1, &Pin, &fetched);
	Pin->QueryPinInfo(&pinfo);
	//pinfo.pFilter->Release();

	//std::wstring ltype = type;
	//lowerCase( ltype );

	while( fetched > 0 )
	{
		// the pFilter member has an outstanding ref count -> release it, we do not use it anyways!
		pinfo.pFilter->Release();
		pinfo.pFilter = 0;
		if( pinfo.dir == dir && checkSupportMediaType( Pin, mediaType ) )
		{
			EnumPins->Release();
			pRetPin = Pin;				
			return S_OK;
		}
		Pin->Release();
		EnumPins->Next(1, &Pin, &fetched);		
		Pin->QueryPinInfo(&pinfo);
	}
	pinfo.pFilter->Release();
	EnumPins->Release();
	return E_FAIL;
}

HRESULT getPin(IBaseFilter *flt, PIN_DIRECTION dir, int number, CComPtr<IPin> &pRetPin)
{
	int n=0;
	IPin* Pin;
	IEnumPins*	EnumPins;
	ULONG		fetched;
	PIN_INFO	pinfo;

	flt->EnumPins(&EnumPins);
	EnumPins->Reset();
	EnumPins->Next(1, &Pin, &fetched);
	Pin->QueryPinInfo(&pinfo);
	//pinfo.pFilter->Release();

	do
	{
		// the pFilter member has an outstanding ref count -> release it, we do not use it anyways!
		pinfo.pFilter->Release();
		pinfo.pFilter = 0;
		if(pinfo.dir == dir)
		{
			n++;
			if(n==number) 
			{
				EnumPins->Release();
				pRetPin = Pin;
				return S_OK;
			}
			else
			{
				Pin->Release();
				EnumPins->Next(1, &Pin, &fetched);
				if(fetched == 0) // no more pins
				{
					EnumPins->Release();
					pRetPin = NULL;
					return(E_FAIL);
				}
				Pin->QueryPinInfo(&pinfo);
			}
		}
		else //if (pinfo.dir != dir)
		{
			Pin->Release();
			EnumPins->Next(1, &Pin, &fetched);
			if(fetched == 0) // no more pins
			{
				EnumPins->Release();
				pRetPin = NULL;
				return(E_FAIL);
			}
			Pin->QueryPinInfo(&pinfo);
			//pinfo.pFilter->Release();
		}
	} while(Pin != NULL);

	EnumPins->Release();
	return E_FAIL;
}

HRESULT connectFilters(IBaseFilter *filter_out, int out_pin_nr, 
					   IBaseFilter *in_filter, int in_pin_nr)
{
	HRESULT hr;
	CComPtr<IPin> OutPin = NULL;
	CComPtr<IPin> InPin = NULL;
	if(FAILED(hr = getPin(filter_out,PINDIR_OUTPUT,out_pin_nr,OutPin))) return(hr);
	if(FAILED(hr = getPin(in_filter,PINDIR_INPUT,in_pin_nr,InPin))) return(hr);
	if(OutPin == NULL || InPin== NULL) return(E_FAIL);
	
	if(FAILED(hr = OutPin->Connect(InPin,NULL))) return(E_FAIL);
	else return(S_OK);
}

HRESULT autoConnectFilters(IBaseFilter *filter_out, int out_pin_nr, IBaseFilter *in_filter,
											  int in_pin_nr, IGraphBuilder *pGraphBuilder)
{
	HRESULT hr;
	CComPtr<IPin> OutPin  = NULL;
	CComPtr<IPin> InPin  = NULL;
	if(FAILED(hr = getPin(filter_out,PINDIR_OUTPUT,out_pin_nr,OutPin))) return(hr);
	if(FAILED(hr = getPin(in_filter,PINDIR_INPUT,in_pin_nr,InPin))) return(hr);
	if(OutPin == NULL || InPin== NULL) return(E_FAIL);
	
	if(FAILED(hr = pGraphBuilder->Connect(OutPin,InPin))) return(E_FAIL);
	else return(S_OK);
}

PIXEL_FORMAT translateMEDIASUBTYPE( GUID format )
{	
	if(format == MEDIASUBTYPE_UYVY)   return(YUV411);
	else if(format == MEDIASUBTYPE_YUY2)   return(YUV422);
	//if(format == MEDIASUBTYPE_RGB565) return(PIXELFORMAT_RGB565);
	//if(format == MEDIASUBTYPE_RGB555) return(PIXELFORMAT_RGB555);
	else if(format == MEDIASUBTYPE_RGB8) return(GREY8);	
	else if(format == MEDIASUBTYPE_RGB24)  return(BGR24);
	else if(format == MEDIASUBTYPE_RGB32)  return(BGR32);
	return UNKNOWN;
}

GUID translatePIXEL_FORMAT( PIXEL_FORMAT format )
{
	switch ( format )
	{
		case YUV411:	return(MEDIASUBTYPE_Y411);	
		case  YUV422:	return(MEDIASUBTYPE_UYVY);
		case  IYUV:		return(MEDIASUBTYPE_IYUV);
		case GREY8:		return(MEDIASUBTYPE_RGB8);	
		case BGR24:		return(MEDIASUBTYPE_RGB24);
		case RGB24:		return(MEDIASUBTYPE_RGB24);
		case BGR32:		return(MEDIASUBTYPE_RGB32);
		case RGB32:		return(MEDIASUBTYPE_RGB32);
		default:		return GUID_NULL;
	}
}

double referenceTime2fps( REFERENCE_TIME AvgTimePerFrame )
{ 
	double fps = 10000000.0 / static_cast<double>( AvgTimePerFrame );
	return( roundDecimals( fps ) ); 
}

double referenceTime2seconds( REFERENCE_TIME time )
{ 
	double refTime = static_cast<double>( time ) / 10000000.0;
	return( roundDecimals( refTime ) ); 
}

REFERENCE_TIME seconds2referenceTime( double seconds )
{ 
	return (REFERENCE_TIME)( seconds * 10000000.0 ); 
}

REFERENCE_TIME fps2referenceTime( double fps )
{
	return((REFERENCE_TIME)( 1.0 / fps * 10000000.0 ) );
}

HRESULT displayPinProperties(CComPtr<IPin> pSrcPin, HWND hWnd)
{
	CComPtr<ISpecifyPropertyPages> pPages;

	HRESULT hr = pSrcPin->QueryInterface(IID_ISpecifyPropertyPages, (void**)&pPages);
	if (SUCCEEDED(hr))
	{
		PIN_INFO PinInfo;
		pSrcPin->QueryPinInfo(&PinInfo);

		CAUUID caGUID;
		pPages->GetPages(&caGUID);

		OleCreatePropertyFrame(
			hWnd,
			0,
			0,
			L"Property Sheet",
			1,
			(IUnknown **)&(pSrcPin.p),
			caGUID.cElems,
			caGUID.pElems,
			0,
			0,
			NULL);
		CoTaskMemFree(caGUID.pElems);
		PinInfo.pFilter->Release();
	}
	else return(hr);

	return(S_OK);
}

HRESULT displayFilterProperties(IBaseFilter *pFilter, HWND hWnd)
{
	CComPtr<ISpecifyPropertyPages> pProp;
	HRESULT hr = pFilter->QueryInterface(IID_ISpecifyPropertyPages, (void **)&pProp);
	if (SUCCEEDED(hr)) 
	{
		// Get the filter's name and IUnknown pointer.
		FILTER_INFO FilterInfo;
		pFilter->QueryFilterInfo(&FilterInfo); 

		// Show the page. 
		CAUUID caGUID;
		pProp->GetPages(&caGUID);
		OleCreatePropertyFrame(
			hWnd,                   // Parent window
			0, 0,                   // (Reserved)
			FilterInfo.achName,     // Caption for the dialog box
			1,                      // Number of objects (just the filter)
			(IUnknown **)&pFilter,  // Array of object pointers. 
			caGUID.cElems,          // Number of property pages
			caGUID.pElems,          // Array of property page CLSIDs
			0,                      // Locale identifier
			0, NULL);               // Reserved

		// Clean up.
		if(FilterInfo.pGraph != NULL) FilterInfo.pGraph->Release(); 
		CoTaskMemFree(caGUID.pElems);
	}
	return(hr);
}

DWORD WINAPI showFilterPropertiesThread(LPVOID lpParameter)
{
	return(displayFilterProperties((IBaseFilter*)lpParameter));
}


double roundDecimals(const double &number, const int num_digits)
{
    static const double doBase = 10.0;
    double doComplete5, doComplete5i;
    
    doComplete5 = number * pow(doBase, (double) (num_digits + 1));
    
    if(number < 0.0)
        doComplete5 -= 5.0;
    else
        doComplete5 += 5.0;
    
    doComplete5 /= doBase;
    modf(doComplete5, &doComplete5i);
    
    return doComplete5i / pow(doBase, (double) num_digits);
}

HRESULT findFilter( IGraphBuilder *pGB, const std::wstring &name, IBaseFilter **filter )
{
	//CComPtr <IBaseFilter> pStreamSplitter = NULL;
	//pGB->FindFilterByName( L"Splitter", &pStreamSplitter );
	//pGB->EnumFilters()

	//hr = pGB->Render(OutPin);

	IBaseFilter *pFilter;
	CComPtr<IEnumFilters> EnumFilters;
	ULONG		fetched;
	FILTER_INFO	finfo;

	pGB->EnumFilters(&EnumFilters);
	EnumFilters->Reset();
	EnumFilters->Next(1, &pFilter, &fetched);
	pFilter->QueryFilterInfo(&finfo);

	std::wstring lname = name;
	lowerCase( lname );

	 while(fetched > 0)
	{
		if ( finfo.pGraph  != NULL )
			finfo.pGraph->Release();
		std::wstring fname = finfo.achName;
		lowerCase( fname );
		if ( fname.find( lname ) != std::string::npos )
		{
			*filter = pFilter;			
            return S_OK;
		}		
		EnumFilters->Next(1, &pFilter, &fetched);
		pFilter->QueryFilterInfo(&finfo);
	}
	if ( finfo.pGraph  != NULL )
		finfo.pGraph->Release();
	return E_FAIL;
}

bool checkSupportMediaType( IPin *Pin, const GUID &mediaType )
{
	CComPtr<IEnumMediaTypes> enumMTypes;
	Pin->EnumMediaTypes( &enumMTypes );
	ULONG fetched;
	
	AM_MEDIA_TYPE *pmType = NULL;	
	enumMTypes->Reset();
	enumMTypes->Next( 1, &pmType, &fetched);
	while( fetched > 0 )
	{
		if ( pmType->majortype == mediaType )		
			return true;
		enumMTypes->Next( 1, &pmType, &fetched);
	}
	return false;
}

⌨️ 快捷键说明

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