📄 directshowhelpers.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 + -