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

📄 cdxgraph.cpp

📁 WINCE下的播放器
💻 CPP
字号:
//
// CDXGraph.cpp
//

#include "stdafx.h"
#include <streams.h>
#include "CDXGraph.h"
#include "CDataAdmin.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

////////////////////////////////////////////////////////////////////////////////
CDXGraph::CDXGraph(CDataAdmin *inBuffer)
{
	// Interfaces
	mGraph        = NULL;
	mMediaControl = NULL;
	mEvent        = NULL;
	mBasicAudio   = NULL;
	mSeeking      = NULL;

	// Filter graph running status
	m_bInit = false;

	// Data buffer pointer
	m_pDataList = inBuffer;

}

CDXGraph::~CDXGraph()
{
	Release();
	m_pDataList = NULL;
}

//创建Fliter Graph
bool CDXGraph::Create(void)
{
	m_bInit = false;
	//  Create filter graph
    HRESULT hr = CoCreateInstance(CLSID_FilterGraph,
                                  NULL,
                                  CLSCTX_INPROC_SERVER,
                                  IID_IGraphBuilder,
                                  (void**)&mGraph);
	if (SUCCEEDED(hr))
	{
		m_bInit = true;
	}

	if (m_bInit)
	{
		// Media control interface
		hr = mGraph->QueryInterface(IID_IMediaControl, (void **)&mMediaControl);
		if (FAILED(hr))
		{
			m_bInit = false;
		}
	}

	if (m_bInit)
	{
		// Media event interface
		hr = mGraph->QueryInterface(IID_IMediaEventEx, (void **)&mEvent);
		if (FAILED(hr)) 
		{
			m_bInit = false;
		}
	}
	
	if (m_bInit)
	{
		// Media basic audio interface
		hr = mGraph->QueryInterface(IID_IBasicAudio, (void **)&mBasicAudio);
		if (FAILED(hr)) 
		{
			m_bInit = false;
		}
	}

	if (m_bInit)
	{
		// Media seeking interface
		hr = mGraph->QueryInterface(IID_IMediaSeeking, (void **)&mSeeking);
		if (FAILED(hr)) 
		{
			m_bInit = false;
		}
	}

	// construct source filter
	// Media type
	if (m_bInit)
	{
		//指定source filter输出pin上使用的媒体类型
		CMediaType   mt;      
		mt.majortype = MEDIATYPE_Stream;
		mt.subtype   = MEDIASUBTYPE_MPEG1Audio;
		m_pSourceStream  = new CMemStream(m_pDataList);
		m_pSourceReader  = new CMemReader(m_pSourceStream, &mt, &hr);
		//增加一个引用计数,防止COM的自动删除
		m_pSourceReader->AddRef();
		//将Source Fliter加到Fliter Graph中
		hr = mGraph->AddFilter(m_pSourceReader, NULL);
		if (FAILED(hr)) 
		{
			m_bInit = false;
		}  
	}

	if (m_bInit)
	{
		// Waiting for event to start filter graph
		//启动一个等待线程
		::AfxBeginThread((AFX_THREADPROC)CDXGraph::WaitingThrd, this);
	}

	return m_bInit;
}

void CDXGraph::Release(void)
{
	// Stop filter graph first
	HRESULT  hr;
	if (mMediaControl != NULL)
	{
		hr = mMediaControl->Stop(); 
	}

    if (mGraph != NULL)
	{
	    // remove the filter added before
	    mGraph->RemoveFilter(m_pSourceReader);//删除过滤器
		// media event interface
		SAFE_RELEASE(mEvent)
		// media seeking interface
		SAFE_RELEASE(mSeeking)
		// media control interface
		SAFE_RELEASE(mMediaControl)
		// basic audio interface
		SAFE_RELEASE(mBasicAudio)
		// graph builder interface
		SAFE_RELEASE(mGraph)

        SAFE_DELETE(m_pSourceStream)
	    SAFE_DELETE(m_pSourceReader)
	}
}

// When data buffer enough, start the filter graph
UINT CDXGraph::WaitingThrd(void * pParam)
{
	CDXGraph * pGraph = (CDXGraph *) pParam;
	if (pGraph != NULL && pGraph->m_pDataList != NULL)
	{
		//阻塞函数,询问数据接收队列管理器,是否已接收倒足够的数据
		::WaitForSingleObject(pGraph->m_pDataList->m_hBufEnough, INFINITE);
		if (!pGraph->IsRunning())
		{
			//开始构建完整的Fliter Granph
			pGraph->StartGraph();
		}
	}
	return 1;
}

//构建完整的Fliter Graph,并运行它
bool CDXGraph::StartGraph(void)
{
	if (m_bInit)
	{
		//将Source Fliter的Pin输出的数据渲染播放
		HRESULT hr  = mGraph->Render(m_pSourceReader->GetPin(0));
		if (FAILED(hr))
		{
			return false;
		}

		// run the filter graph
		hr = mMediaControl->Run();
		return true;
	}
	
	return false;
}

bool CDXGraph::ResetGraph(void)
{
    CDXGraph * mFilterGraph = NULL;
	if (mFilterGraph->IsRunning())
	{
		// If the filter graph running, release it first
		mFilterGraph->Release();
	}
	// Reset the datalist
	if (m_pDataList != NULL)
	{
		m_pDataList->ResetList();
		ResetEvent(m_pDataList->m_hBufEnough);
	}
	// Create a new filter graph
	Create();
	return true;
}

IGraphBuilder * CDXGraph::GetGraph(void)
{
	return mGraph;
}

IMediaEventEx * CDXGraph::GetEventHandle(void)
{
	return mEvent;
}

// Connect filter from the upstream output pin to the downstream input pin
bool CDXGraph::ConnectFilters(IPin * inOutputPin, IPin * inInputPin, 
							  const AM_MEDIA_TYPE * inMediaType)
{
	if (mGraph && inOutputPin && inInputPin)
	{
		HRESULT hr = mGraph->ConnectDirect(inOutputPin, inInputPin, inMediaType);
		return SUCCEEDED(hr) ? true : false;
	}
	return false;
}

void CDXGraph::DisconnectFilters(IPin * inOutputPin)
{
	if (mGraph && inOutputPin)
	{
		HRESULT hr = mGraph->Disconnect(inOutputPin);
	}
}

bool CDXGraph::Run(void)
{
	if (mGraph && mMediaControl)
	{
		if (!IsRunning())
		{
			if (SUCCEEDED(mMediaControl->Run()))
			{
				return true;
			}
		}
		else
		{
			return true;
		}
	}
	return false;
}

bool CDXGraph::Stop(void)
{
	if (mGraph && mMediaControl)
	{
		if (!IsStopped())
		{	
			if (SUCCEEDED(mMediaControl->Stop()))
			{
				return true;
			}
		}
		else
		{
			return true;
		}
	}
	return false;
}

bool CDXGraph::Pause(void)
{
	if (mGraph && mMediaControl)
	{
		if (!IsPaused())
		{	
			if (SUCCEEDED(mMediaControl->Pause()))
			{
				return true;
			}
		}
		else
		{
			return true;
		}
	}
	return false;
}

bool CDXGraph::IsRunning(void)
{
	if (mGraph && mMediaControl)
	{
		OAFilterState state = State_Stopped;
		if (SUCCEEDED(mMediaControl->GetState(10, &state)))
		{
			return state == State_Running;
		}
	}
	return false;
}

bool CDXGraph::IsStopped(void)
{
	if (mGraph && mMediaControl)
	{
		OAFilterState state = State_Stopped;
		if (SUCCEEDED(mMediaControl->GetState(10, &state)))
		{
			return state == State_Stopped;
		}
	}
	return false;
}

bool CDXGraph::IsPaused(void)
{
	if (mGraph && mMediaControl)
	{
		OAFilterState state = State_Stopped;
		if (SUCCEEDED(mMediaControl->GetState(10, &state)))
		{
			return state == State_Paused;
		}
	}
	return false;
}

// IMediaSeeking features
bool CDXGraph::GetCurrentPosition(double * outPosition)
{
	if (mSeeking)
	{
		__int64 position = 0;
		if (SUCCEEDED(mSeeking->GetCurrentPosition(&position)))
		{
			*outPosition = ((double)position) / 10000000.;
			return true;
		}
	}
	return false;
}

bool CDXGraph::GetStopPosition(double * outPosition)
{
	if (mSeeking)
	{
		__int64 position = 0;
		if (SUCCEEDED(mSeeking->GetStopPosition(&position)))
		{
			*outPosition = ((double)position) / 10000000.;
			return true;
		}
	}
	return false;
}

bool CDXGraph::SetCurrentPosition(double inPosition)
{
	if (mSeeking)
	{
		__int64 one = 10000000;
		__int64 position = (__int64)(one * inPosition);
		HRESULT hr = mSeeking->SetPositions(&position, AM_SEEKING_AbsolutePositioning | AM_SEEKING_SeekToKeyFrame, 
			0, AM_SEEKING_NoPositioning);
		return SUCCEEDED(hr);
	}
	return false;
}

bool CDXGraph::SetStartStopPosition(double inStart, double inStop)
{
	if (mSeeking)
	{
		__int64 one = 10000000;
		__int64 startPos = (__int64)(one * inStart);
		__int64 stopPos  = (__int64)(one * inStop);
		HRESULT hr = mSeeking->SetPositions(&startPos, AM_SEEKING_AbsolutePositioning | AM_SEEKING_SeekToKeyFrame, 
			&stopPos, AM_SEEKING_AbsolutePositioning | AM_SEEKING_SeekToKeyFrame);
		return SUCCEEDED(hr);
	}
	return false;
}

bool CDXGraph::GetDuration(double * outDuration)
{
	if (mSeeking)
	{
		__int64 length = 0;
		if (SUCCEEDED(mSeeking->GetDuration(&length)))
		{
			*outDuration = ((double)length) / 10000000.;
			return true;
		}
	}
	return false;
}

bool CDXGraph::SetPlaybackRate(double inRate)
{
	if (mSeeking)
	{
		if (SUCCEEDED(mSeeking->SetRate(inRate)))
		{
			return true;
		}
	}
	return false;
}

bool CDXGraph::RenderFile(const char * inFile)
{
	if (mGraph)
	{
		WCHAR    szFilePath[MAX_PATH];
		MultiByteToWideChar(CP_ACP, 0, inFile, -1, szFilePath, MAX_PATH);
		if (SUCCEEDED(mGraph->RenderFile(szFilePath, NULL)))
		{
			return true;
		}
	}
	return false;
}

⌨️ 快捷键说明

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