📄 graphcenter.cpp
字号:
/*
* Openmysee
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include "stdafx.h"
#include "GraphCenter.h"
#include <stdio.h>
#include "../captureserver/TVSourceConfig.h"
#include "../captureserver/uuids.h"
#include <atlcomcli.h>
#define SAFE_RELEASE(p) { if(p) p->Release(); p = NULL; }
//构造析构函数
CGraphCenter::CGraphCenter() :mpAsfReader( NULL)
{
m_pTVStreamSink = NULL;
m_pSourceFile = NULL;
m_pAviSplitter = NULL;
m_pGB = NULL;
m_pMC = NULL;
m_pEvent = NULL;
InitializeCriticalSection(&moCriticalSection);
//保护停止标志位。
EnterCriticalSection(&moCriticalSection);
m_iIsStop = 1; //0为运行,1为停止。-1为发生意外错误停止
LeaveCriticalSection(&moCriticalSection);
CreateDebugInfo();
}
CGraphCenter::~CGraphCenter()
{
Uninitialize();
EnterCriticalSection(&moCriticalSection);
m_iIsStop = 1; //0为运行,1为停止。-1为发生意外错误停止
LeaveCriticalSection(&moCriticalSection);
DeleteCriticalSection(&moCriticalSection); //保护停止标志位。
}
//将Filter添加到图中去
STDMETHODIMP CGraphCenter::AddFilter(CLSID clsidFilter,
IBaseFilter** ppIFilter,
LPCTSTR pstrFilterName)
{
HRESULT hr;
assert(m_pGB);
assert(ppIFilter);
(*ppIFilter) = NULL;
// try to instantiate the filter
hr = CoCreateInstance(clsidFilter,
NULL,
CLSCTX_INPROC,
IID_IBaseFilter,
(LPVOID*)(ppIFilter));
if(FAILED(hr))
{
//DbgLog((LOG_TRACE, 5, TEXT("Could not instantiate filter")));
//TRACE("Could not instantiate filter");
return hr;
}
// Check for unicode or not
#ifndef _UNICODE
if(pstrFilterName)
{
// not unicode, we need to unicodify the string
WCHAR wstrFilterName[256];
MultiByteToWideChar(CP_ACP,
MB_PRECOMPOSED | MB_USEGLYPHCHARS,
pstrFilterName,
-1,
wstrFilterName,
sizeof(wstrFilterName) / sizeof(WCHAR));
// try to add it to the filter graph
hr = m_pGB->AddFilter(*ppIFilter, wstrFilterName);
}
else
{
// No filter name specified, cannot convert
// try to add it to the filter graph
hr = m_pGB->AddFilter(*ppIFilter, NULL);
}
#else
// already unicode, no need to change anything
// try to add it to the filter graph
hr = m_pGB->AddFilter(*ppIFilter, pstrFilterName);
#endif
// check the result of the operation
if(FAILED(hr))
{
//TRACE("Could not add filter to filter graph\n");
// free the filter definitely
(*ppIFilter)->Release();
(*ppIFilter) = NULL;
return hr;
}
// that's it
return hr;
}
//pin的连接
STDMETHODIMP CGraphCenter::ConnectPins(IBaseFilter* pIFilterOutput,
LPCTSTR pstrPinNameOutput,
IBaseFilter* pIFilterInput,
LPCTSTR pstrPinNameInput,
AM_MEDIA_TYPE* pmt)
{
HRESULT hr;
assert(m_pGB);
// Parameters...
if((!pIFilterOutput) || (!pIFilterInput))
{
assert(pIFilterOutput && pIFilterInput);
//TRACE("ConnectPins called with NULL parameter\n");
return E_INVALIDARG;
}
// Find the first pin
IPin* pIPinOutput = FindPinOnFilter(pIFilterOutput,
pstrPinNameOutput,
PINDIR_OUTPUT);
if(!pIPinOutput)
{
assert(pIPinOutput);
return E_FAIL;
}
// Find the second pin
IPin* pIPinInput = FindPinOnFilter(pIFilterInput,
pstrPinNameInput,
PINDIR_INPUT);
if(!pIPinInput)
{
assert(pIPinInput);
// release the other pin
pIPinOutput->Release();
return E_FAIL;
}
if(FAILED(pIPinOutput->Disconnect()))
{
assert(FALSE);
return E_FAIL;
}
if(FAILED(pIPinInput->Disconnect()))
{
assert(FALSE);
return E_FAIL;
}
// Now just connect the two pins
hr = m_pGB->ConnectDirect(pIPinOutput, pIPinInput, pmt);
// assert(SUCCEEDED(hr));
if(FAILED(hr))
{
TraceLog1("Could not direct connect pins!, try intelligent connect");
hr = m_pGB->Connect(pIPinOutput, pIPinInput);
}
// Release the two pins and return the result
pIPinOutput->Release();
pIPinInput->Release();
return hr;
}
//自动连接Filter
STDMETHODIMP CGraphCenter::ConnectAutoPins(IBaseFilter* pIFilterOutput,
LPCTSTR pstrPinNameOutput,
IBaseFilter* pIFilterInput,
LPCTSTR pstrPinNameInput)
{
HRESULT hr;
assert(m_pGB);
// Parameters...
if((!pIFilterOutput) || (!pIFilterInput))
{
assert(pIFilterOutput && pIFilterInput);
//TRACE("ConnectPins called with NULL parameter\n");
return E_INVALIDARG;
}
// Find the first pin
IPin* pIPinOutput = FindPinOnFilter(pIFilterOutput,
pstrPinNameOutput,
PINDIR_OUTPUT);
if(!pIPinOutput)
{
assert(pIPinOutput);
return E_FAIL;
}
// Find the second pin
IPin* pIPinInput = FindPinOnFilter(pIFilterInput,
pstrPinNameInput,
PINDIR_INPUT);
if(!pIPinInput)
{
assert(pIPinInput);
// release the other pin
pIPinOutput->Release();
return E_FAIL;
}
if(FAILED(pIPinOutput->Disconnect()))
{
assert(FALSE);
return E_FAIL;
}
if(FAILED(pIPinInput->Disconnect()))
{
assert(FALSE);
return E_FAIL;
}
// Now just connect the two pins
hr = m_pGB->Connect(pIPinOutput, pIPinInput);
assert(SUCCEEDED(hr));
if(FAILED(hr))
//TRACE("Could not connect pins!");
// Release the two pins and return the result
pIPinOutput->Release();
pIPinInput->Release();
return hr;
}
//查找filter上的pin
STDMETHODIMP_(IPin*) CGraphCenter::FindPinOnFilter(IBaseFilter* pIFilter,
LPCTSTR pstrPinName,
PIN_DIRECTION dir)
{
HRESULT hr;
IEnumPins* pIEnumPins;
IPin* pIPin;
PIN_INFO pi;
assert(m_pGB);
// Parameters...
if(!pIFilter)
return NULL;
// Enumerate pins on the filter
hr = pIFilter->EnumPins(&pIEnumPins);
if(FAILED(hr))
// pin was not found!
return NULL;
// Loop till we find no more pins
IPin* pIPinFound = NULL;
while( (!pIPinFound) && (pIEnumPins->Next(1, &pIPin, NULL)==S_OK) )
{
// Is this the pin?
hr = pIPin->QueryPinInfo(&pi);
if(!FAILED(hr))
{
// check if it is the right direction
if(pi.dir == dir)
{
// Let the graph builder find the right filter
TCHAR strFoundPinName[256];
#ifndef _UNICODE
// not unicode, we need to de-unicodify the returned pin name
WideCharToMultiByte(CP_ACP, NULL,
pi.achName, -1,
strFoundPinName, sizeof(strFoundPinName),
NULL, NULL);
#else
// just make a copy of the string
lstrcpyn(strFoundPinName, pi.achName, sizeof(strFoundPinName));
#endif
// check if there is a pin name specified
if(!pstrPinName)
{
// no name specified, take the first pin found
pIPinFound = pIPin;
pIPinFound->AddRef();
}
// check if we have the right pin name
else if(lstrcmp(strFoundPinName, pstrPinName)==0)
{
// yes we have!
pIPinFound = pIPin;
pIPinFound->AddRef();
}
}
// release the PIN_INFO data
pi.pFilter->Release();
}
// release the IPin pointer
pIPin->Release();
}
// Finished with the enumerator, let it go (be free)
pIEnumPins->Release();
// Return whatever we have found
return pIPinFound;
}
//pin的连接
STDMETHODIMP CGraphCenter::ConnectPinsEX(IBaseFilter* pIFilterOutput,
Pin_type atype,
IBaseFilter* pIFilterInput,
LPCTSTR pstrPinNameInput,
BOOL bisAuto,AM_MEDIA_TYPE* pmt)
{
HRESULT hr;
assert(m_pGB);
// Parameters...
if((!pIFilterOutput) || (!pIFilterInput))
{
assert(pIFilterOutput && pIFilterInput);
//TRACE("ConnectPins called with NULL parameter\n");
return E_INVALIDARG;
}
// Find the first pin
IPin* pIPinOutput = FindPinOnFilterbyType(pIFilterOutput,
atype,
PINDIR_OUTPUT);
if(!pIPinOutput)
{
assert(pIPinOutput);
return E_FAIL;
}
// Find the second pin
IPin* pIPinInput = FindPinOnFilter(pIFilterInput,
pstrPinNameInput,
PINDIR_INPUT);
if(!pIPinInput)
{
assert(pIPinInput);
// release the other pin
pIPinOutput->Release();
return E_FAIL;
}
if(FAILED(pIPinOutput->Disconnect()))
{
assert(FALSE);
return E_FAIL;
}
if(FAILED(pIPinInput->Disconnect()))
{
assert(FALSE);
return E_FAIL;
}
if (FALSE == bisAuto)
{
hr = m_pGB->ConnectDirect(pIPinOutput, pIPinInput, pmt);
}
else
{
hr = m_pGB->Connect(pIPinOutput, pIPinInput);
}
// Now just connect the two pins
// assert(SUCCEEDED(hr));
if(FAILED(hr))
{
TraceLog1("Could not direct connect pins!, try intelligent connect");
hr = m_pGB->Connect(pIPinOutput, pIPinInput);
}
// Release the two pins and return the result
pIPinOutput->Release();
pIPinInput->Release();
return hr;
}
//查找filter上满足一定条件的的媒体类型
STDMETHODIMP_(IPin*) CGraphCenter::FindPinOnFilterbyType(IBaseFilter* pIFilter,
Pin_type aType,
PIN_DIRECTION dir)
{
HRESULT hr;
IEnumPins* enum_pin;
IPin* findpin = NULL;
IPin* pin = NULL;
IEnumMediaTypes* enum_media_type;
AM_MEDIA_TYPE* media_type = NULL;
AM_MEDIA_TYPE* tempmedia_type = NULL;
PIN_DIRECTION temp_dir;
assert(m_pGB);
hr = pIFilter->EnumPins(&enum_pin);
if (FAILED(hr))
{
return NULL;
}
enum_pin->Reset();
GUID formattype = (aType == VIDEO)? FORMAT_VideoInfo:FORMAT_WaveFormatEx;
ULONG liCount = 0;
hr = enum_pin->Next(1,&pin,&liCount);
while (!findpin && SUCCEEDED(hr))
{
//Is this the pin? 不计数
hr = pin->QueryDirection(&temp_dir);
if (FAILED(hr))
{
break;//return NULL;
}
if (temp_dir != dir)
{
continue;
}
//枚举媒体类型
hr = pin->EnumMediaTypes(&enum_media_type);
if (FAILED(hr))
{
break;
}
/*
enum_media_type->AddRef();
iii = enum_media_type->Release();计数:1
*/
enum_media_type->Reset();
media_type = NULL;
hr = enum_media_type->Next(1,&media_type,&liCount);
while (NULL == tempmedia_type && SUCCEEDED(hr))
{
if((*media_type).formattype == formattype || (*media_type).formattype == FORMAT_MPEGVideo)
{
tempmedia_type = media_type;
findpin = pin;
findpin->AddRef();
break;
}
hr = enum_media_type->Next(1,&media_type,&liCount);
if (0 == liCount)
{
break;
}
}
hr = enum_pin->Next(1,&pin,&liCount);
enum_media_type->Release();
if (0 == liCount)
{
break;
}
}
enum_pin->Release();
return findpin;
}
STDMETHODIMP CGraphCenter::RemoveFilter(IBaseFilter* pIFilter)
{
HRESULT hr;
// Parameters...
if(!pIFilter)
// DON'T return an error, this is expected
return NOERROR;
assert(m_pGB);
// Just remove it from the graph
hr = m_pGB->RemoveFilter(pIFilter);
return hr;
}
//////////////////////////////////////////////////////////////////////////
//以下为处理接口函数
//////////////////////////////////////////////////////////////////////////
//初始化库
STDMETHODIMP CGraphCenter::Initialize()
{
HRESULT hr = CoInitialize(NULL);
if (FAILED(hr))
{
//TRACE0("ERROR - Could not initialize COM library");
return hr;
}
// Create the filter graph manager and query for interfaces.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -