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

📄 mmsgraph.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 "mmsgraph.h"
#include "configFile.h"
#include "string.h"

//  {6B6D0800-9ADA-11d0-A520-00A0D10129C0}
DEFINE_GUID(CLSID_NetShowSource, 
0x6b6d0800, 0x9ada, 0x11d0, 0xa5, 0x20, 0x0, 0xa0, 0xd1, 0x1, 0x29, 0xc0);

//////////////////////////////////////////////
// Only for Debug
static DWORD g_dwRegister;
static HRESULT AddGraphToRot(IUnknown *pUnkGraph, DWORD *pdwRegister) 
{
#ifdef _DEBUG
    IMoniker * pMoniker;
    IRunningObjectTable *pROT;
    HRESULT hr;

    hr = GetRunningObjectTable(0, &pROT);
    if (FAILED(hr)) return hr;

    WCHAR wsz[128];
    wsprintfW(wsz, L"FilterGraph %08x pid %08x", (DWORD_PTR)pUnkGraph, GetCurrentProcessId());
    hr = CreateItemMoniker(L"!", wsz, &pMoniker);
    if (SUCCEEDED(hr)) 
	{
        hr = pROT->Register(0, pUnkGraph, pMoniker, pdwRegister);
        pMoniker->Release();
    }
    pROT->Release(); 
    return hr;
#endif
	
	return S_OK;
}

static void RemoveGraphFromRot(DWORD pdwRegister)
{
#ifdef _DEBUG
    IRunningObjectTable *pROT;
    if (SUCCEEDED(GetRunningObjectTable(0, &pROT))) 
	{
        pROT->Revoke(pdwRegister);
        pROT->Release();
    }
#endif
}

/////////////////////////////////////////////////////////////////
// CMMSGraph
CMMSGraph::CMMSGraph(string strChannel, string strMMSAddr, HRESULT *hr)
{
	m_pGB = NULL;
	m_pMC = NULL;
	m_pMMSSource = NULL;
	m_pSink = NULL;
	m_pAsfAcmHandler = NULL;
	m_pAsfIcmHandler = NULL;
	m_pAudioSmartTee = NULL;
	m_pTVConfig = NULL;

	m_pMMSInfo = new MMSGRAPHINFO;
	m_pMMSInfo->fDataRate = 0.0;
	m_pMMSInfo->fTotalBytes=0;
	m_pMMSInfo->m_oldtotalbyte=0;
	m_pMMSInfo->mmsState = INIT;
	m_pMMSInfo->llTimeEscaped = 0;
	m_pMMSInfo->strChannelName = strChannel;
	m_pMMSInfo->strMMSAddr = strMMSAddr;
	m_pMMSInfo->llTimeEscaped = 0;
    m_pMMSInfo->m_time=0;

    m_bReconnecting = false;

	*hr = Initialize();
}

CMMSGraph::~CMMSGraph()
{
    m_bReconnecting = false;

	SAFE_RELEASE(m_pSink);
	SAFE_RELEASE(m_pTVConfig);

	Uninitialize();

	if(m_pMMSInfo)
	{
		delete m_pMMSInfo;
		m_pMMSInfo = NULL;
	}
}

STDMETHODIMP CMMSGraph::Run()
{
	if(m_pMC)
		return m_pMC->Run();

	return E_FAIL;
}

STDMETHODIMP CMMSGraph::Stop()
{
	if(m_pMC)
		return m_pMC->Stop();

	return E_FAIL;
}

STDMETHODIMP CMMSGraph::Pause()
{
	if(m_pMC)
		return m_pMC->Pause();

	return E_FAIL;
}


STDMETHODIMP CMMSGraph::Uninitialize()
{
	RemoveGraphFromRot(g_dwRegister);

	DisassembleGraph();

	// release all objects
	SAFE_RELEASE(m_pGB);
	SAFE_RELEASE(m_pMC);

	// release COM lib
	CoUninitialize();

	return S_OK;
}

STDMETHODIMP CMMSGraph::BuildGraph(bool bAssumeAudioFirst)
{
	// add/config source filter
	if(FAILED(CreateAddFilter(CLSID_NetShowSource, &m_pMMSSource)))
	{
		AfxMessageBox("can not create & add mms source filter!");
		return E_FAIL;
	}

	IFileSourceFilter *pSF;
	if(FAILED(m_pMMSSource->QueryInterface(IID_IFileSourceFilter, (VOID**)&pSF)))
	{
		AfxMessageBox("can not query interface of mms source filter!");
		return E_FAIL;
	}

	WCHAR wstrAddr[1024];
	MultiByteToWideChar(CP_ACP, 
						MB_PRECOMPOSED | MB_USEGLYPHCHARS,
						m_pMMSInfo->strMMSAddr.data(),
						-1, 
						wstrAddr, 
						sizeof(wstrAddr) / sizeof(WCHAR));
	HRESULT hr;
	hr =  pSF->Load(wstrAddr, NULL);  
	if(FAILED(hr))
	{
		string strError;
		char s[100];
		wsprintf(s, "无法读取mms流:%s,请检查这个流是否可用。", m_pMMSInfo->strMMSAddr.data());
	  	strError.append(s);
	 	//AfxMessageBox(strError.data());
	    return FALSE;
		 
	}
	pSF->Release();

    /*
    IEnumPins* enumPin = NULL;
    hr = m_pMMSSource->EnumPins(&enumPin);
    IPin* pins = NULL
    hr = enumPin->Next(1, &pins, NULL);
    AM_MEDIA_TYPE type;
    hr = pins->ConnectionMediaType(&type);
    if(type.formattype == FORMAT_VideoInfo) {
        pins->ConnectedTo(
    }
    */

    if(m_pSink == NULL) {
	    // add our sink filter
 	    if(FAILED(CreateAddFilter(CLSID_TVStreamSink, &m_pSink)))
	    {
		    AfxMessageBox("can not create & add capture filter!");
		    return E_FAIL;
	    }
     
	    if(FAILED(m_pSink->QueryInterface(IID_ITVSouceConfig, (VOID**)&m_pTVConfig)))
	    {
		    AfxMessageBox("can not query interface of captureserver!");
		    return E_FAIL;
	    }
    }
    else {
		// No filter name specified, cannot convert
		// try to add it to the filter graph
		hr = m_pGB->AddFilter(m_pSink, NULL);
        if(hr != S_OK)
	    {
		    AfxMessageBox("can not add capture filter!");
		    return E_FAIL;
	    }
    }

	// connect graph
	// audio channel
	BOOL bHasAudio = TRUE;
	BOOL bHasVideo = TRUE;
	if(SUCCEEDED(FindASFHandler("ASF ACM Handler")))
	{
		VERIFY(SUCCEEDED(m_pGB->AddFilter(m_pAsfAcmHandler, NULL)));

        hr = ConnectPins(m_pMMSSource, bAssumeAudioFirst?__T("Stream 1"):__T("Stream 2"), m_pAsfAcmHandler,NULL);
        if(hr != S_OK) {
            DisassembleGraph();
            hr = BuildGraph(false);
            return hr;
        }
        hr = ConnectPins(m_pAsfAcmHandler, NULL, m_pSink, __T("Audio"));
        if(hr != S_OK) {
	        ASSERT(0);
			bHasAudio = FALSE;
			RemoveFilter(m_pAsfAcmHandler);
			SAFE_RELEASE(m_pAsfAcmHandler);
        }

        /*
        if((FAILED(ConnectPins(m_pMMSSource, __T("Stream 1"), m_pAsfAcmHandler,NULL) && 
           FAILED(ConnectPins(m_pMMSSource, __T("Stream 2"), m_pAsfAcmHandler,NULL)) || 
           FAILED(ConnectPins(m_pAsfAcmHandler, NULL, m_pSink, __T("Audio"))))))
		{
	        ASSERT(0);
			bHasAudio = FALSE;
			RemoveFilter(m_pAsfAcmHandler);
			SAFE_RELEASE(m_pAsfAcmHandler);
		}
        */
	}
	else
		bHasAudio = FALSE;

	// video channel
	if(SUCCEEDED(FindASFHandler("ASF ICM Handler")))
	{
        VERIFY(SUCCEEDED(m_pGB->AddFilter(m_pAsfIcmHandler, NULL)));
        hr = ConnectPins(m_pMMSSource, bAssumeAudioFirst?__T("Stream 2"):__T("Stream 1"), m_pAsfIcmHandler,NULL);
        if(hr != S_OK) {
            DisassembleGraph();
            hr = BuildGraph(false);
            return hr;
        }
        hr = ConnectPins(m_pAsfIcmHandler, NULL, m_pSink, __T("Video"));
        if(hr != S_OK) {
            ASSERT(0);
            bHasVideo = FALSE;
            RemoveFilter(m_pAsfIcmHandler);
            SAFE_RELEASE(m_pAsfIcmHandler);
        }

        /*
		if((FAILED(ConnectPins(m_pMMSSource, __T("Stream 2"), m_pAsfIcmHandler,NULL) &&
           FAILED(ConnectPins(m_pMMSSource, __T("Stream 1"), m_pAsfIcmHandler,NULL)) ||
		   FAILED(ConnectPins(m_pAsfIcmHandler, NULL, m_pSink, __T("Video"))))))
		{ 
	        ASSERT(0);
			bHasVideo = FALSE;
			RemoveFilter(m_pAsfIcmHandler);
			SAFE_RELEASE(m_pAsfIcmHandler);
		}
        */

#ifdef TIME_EXPIRE
        /// 如果过了2006-03-21日,就返回错误
        tm expire_tm;
        memset(&expire_tm, 0, sizeof(expire_tm));
        expire_tm.tm_year = 106;
        expire_tm.tm_mon = 2;
        expire_tm.tm_mday = 21;

        time_t expire_seconds = mktime(&expire_tm);
        time_t now;
        time( &now );                /* Get time as long integer. */

        if(now > expire_seconds)
            return E_FAIL;
#endif
	}
	else
		bHasVideo = FALSE;

	if(!bHasVideo && !bHasAudio)
	{
		AfxMessageBox("Sorry, MMS Server cant get media. plz check mms address is right!");
		return E_FAIL;
	}
	if(!bHasVideo)
	{
	//	AfxMessageBox("warning:no video captured!");
		//return S_FALSE;

 		m_pTVConfig->SetAudioOrVideoOnly(TRUE); // set audio only
	}
	if(!bHasAudio)
	{
		AfxMessageBox("warning:no audio captured!");
		return S_FALSE;
	}

	return 1 ; 
}

STDMETHODIMP CMMSGraph::DisassembleGraph()
{
	Stop();

	// remove all filters from graph
	RemoveFilter(m_pMMSSource);
	RemoveFilter(m_pSink);
	if(m_pAsfAcmHandler)
		RemoveFilter(m_pAsfAcmHandler);
	if(m_pAsfAcmHandler)
		RemoveFilter(m_pAsfIcmHandler);
	if(m_pAudioSmartTee)
		RemoveFilter(m_pAudioSmartTee);

	SAFE_RELEASE(m_pMMSSource);
	SAFE_RELEASE(m_pAsfIcmHandler);
	SAFE_RELEASE(m_pAsfAcmHandler);
	SAFE_RELEASE(m_pAudioSmartTee);

	return S_OK;
}

MMSGRAPHINFO *CMMSGraph::GetMMSGraphInfo()
{ 
    ////////////Get  the  value of  the ResStartTime 
	CString str_path;
	GetModuleFileName(NULL,str_path.GetBuffer(MAX_PATH),MAX_PATH);
	str_path.ReleaseBuffer();
	int index = str_path.ReverseFind('\\');
    str_path= 	str_path.Left(index+1);
    int ResStartTime = 10;

    static bool reconnecting = false;
	
	// speed
	m_pMMSInfo->fDataRate = m_pTVConfig->GetCompressedSpeed();	
    m_pMMSInfo->fTotalBytes=m_pTVConfig->GetTotalBytes(); //get current totalbytes
	 
	 if(m_pMMSInfo->fTotalBytes>m_pMMSInfo->m_oldtotalbyte) //if we got new data
	{
		if (m_pMMSInfo->mmsState==RUNNING)
			 m_pMMSInfo->llTimeEscaped++;

    	m_pMMSInfo->m_time=0;   //recount
	 }
	 else  if(m_pMMSInfo->mmsState != STOPPED )//if data stopped
	 {
		 m_pMMSInfo->m_time++;
         if(m_pTVConfig->EndOfStream() || m_pMMSInfo->m_time >= ResStartTime) {
            if(!m_bReconnecting) {
                m_bReconnecting = true;
                HRESULT ret = this->DisassembleGraph();
                ret = this->BuildGraph();
                ret = this->Run();
                m_bReconnecting = false;
            }
			m_pMMSInfo->m_time=0;  //recount
        }
	 }
	 
	 if (m_pMMSInfo->m_time==0)  
		 m_pMMSInfo->m_oldtotalbyte=m_pMMSInfo->fTotalBytes;	
	 
	    // state
	 OAFilterState os;
	 m_pMC->GetState(100, &os);
	 
	 if(os == State_Running)
		 m_pMMSInfo->mmsState = RUNNING;
     else if(os == State_Stopped) {
		 m_pMMSInfo->mmsState = STOPPED;
         if(m_bReconnecting)
             m_pMMSInfo->mmsState = RECONNECTING;
     }
	 else if(os == State_Paused)
		 m_pMMSInfo->mmsState = PAUSED;
	 else
		 m_pMMSInfo->mmsState = INIT;
	 
	 // time escaped 
	 return m_pMMSInfo;
}

STDMETHODIMP CMMSGraph::CreateAddFilter(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))
	{
		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));

⌨️ 快捷键说明

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