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

📄 graphcenter.cpp

📁 mysee网络直播源代码Mysee Lite是Mysee独立研发的网络视频流媒体播放系统。在应有了P2P技术和一系列先进流媒体技术之后
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*
 *  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 + -