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

📄 channelmgr.cpp

📁 mysee网络直播源代码Mysee Lite是Mysee独立研发的网络视频流媒体播放系统。在应有了P2P技术和一系列先进流媒体技术之后
💻 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 "ChannelMgr.h"
#include "LocalServer.h"
#include "MultiLanguageMgr.h"
#include "HttpRequest.h"
#include "InfAnime.h"

extern volatile HINSTANCE g_hInstance;
extern volatile HWND g_hMainWnd;
//extern CLocalServer *g_pLocalServer;

void	CChannelMgr::GetChannelName(CString& strRet)
{
    UINT len = 256;
    if(m_Layer1.GetFileName(strRet.GetBuffer(len), len) == FALSE && len > 256)
    {
        len += 1;
        strRet.ReleaseBuffer();
        m_Layer1.GetFileName(strRet.GetBuffer(len), len);
    }
    strRet.ReleaseBuffer();
/*	if(m_ChannelNameBuf.IsEmpty())
	{
		UINT len = 200;
		TCHAR*	pbuf = new TCHAR[len];
		if(m_Layer1.GetFileName(pbuf, len))	
		{
			m_ChannelNameBuf = pbuf;
			strRet = pbuf;
			strRet += _T(":");
		}
		else
		{
			MultiLanguage	LangDll;
			strRet = LangDll.GetStringByStr(_T("未知频道:"));
		}
		delete pbuf;
	}
	else
	{
		strRet = m_ChannelNameBuf;
		strRet += _T(":");
	}*/
}

CChannelMgr::CChannelMgr(CHANNELID ChannelID)
: m_ChannelID(ChannelID), m_SockFromProxy(INVALID_SOCKET),
  m_videopin(&m_Layer1, false), m_audiopin(&m_Layer1, true),
  m_NameMsgID(0),h_RequestThread(NULL),m_PrevRequest(REQUEST_NOPP),
  m_CoutPinInit(0)
{
    pInfAnime = new InfAnime;
	pHttpSession = new HttpRequest;
	pHttpSession->Create();
}

CChannelMgr::~CChannelMgr()
{
	pHttpSession->SetStopRequest();

	if(h_RequestThread != NULL)
	{
        m_CoutPinInit = -1;
		WaitForSingleObject(h_RequestThread,INFINITE);
		CloseHandle(h_RequestThread);
	}
	delete pHttpSession;
    delete pInfAnime;
}

CChannelMgr*	CChannelMgr::Allocator(CHANNELID ChannelID)
{
	return new CChannelMgr(ChannelID);
}

void	CChannelMgr::Dellocator(CChannelMgr* pdel, BOOL block)
{
	if(block)
		delete pdel;
	else
	{
		unsigned int threadID;
		_beginthreadex(NULL, 0, &_DellocatorProc, pdel, 0, &threadID);
	}
}

unsigned int CALLBACK CChannelMgr::_DellocatorProc(void* lpParameter)
{
	CChannelMgr* pdel = static_cast<CChannelMgr*>(lpParameter);
	delete pdel;
	return 0;
}

unsigned int CALLBACK CChannelMgr::_RequestFunc(void* lpParameter)
{
	CChannelMgr* pMgr = static_cast<CChannelMgr*>(lpParameter);
	
	BOOL bOK = FALSE;

	CString filename;
	while(1)
	{
		if(GetTempPath(MAX_PATH, filename.GetBuffer(MAX_PATH)) == 0)
		{
			filename.ReleaseBuffer();
			break;
		}
		filename.ReleaseBuffer();

		CString tempname;
		tempname.Format(_T("gtvtemp%d.gtv"), pMgr->m_ChannelID);
		filename += tempname;

		HANDLE hfile = CreateFile(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
		if(hfile == NULL)
			break;

		pMgr->pHttpSession->SetFileMode(hfile);
		if(pMgr->pHttpSession->OpenRequest(pMgr->m_RequestURL))
			bOK = TRUE;

		CloseHandle(hfile);
		break;
	}

	P2P_RETURN_TYPE RetType;
	if(bOK)
		RetType = pMgr->m_Layer1.Request(filename, g_hMainWnd, WM_SENDTOLAYER1, pMgr->m_ChannelID);
	else
		RetType = pMgr->m_Layer1.Request(pMgr->m_RequestURL, g_hMainWnd, WM_SENDTOLAYER1, pMgr->m_ChannelID);	//直接将URL给layer作最后的尝试

	if(PRT_OK != RetType)
	{
//		MultiLanguage	LangDll;
//		CString strRet;
//		pMgr->HandleLayerErrCode(RetType, strRet);
//		pMgr->m_MsgMgr.UpdateMessage(pMgr->m_NameMsgID, strRet, CMsgMgr::TIMELESS | CMsgMgr::FORCESHOW);
        pMgr->m_errorcode = RetType;
		InterlockedExchange(&pMgr->m_bRequesting, REQUEST_FAIL);
	}
	else
	{
        while(pMgr->m_CoutPinInit != 3)
        {
            if(pMgr->m_CoutPinInit == -1)
                return 0;           //直接返回退出

            Sleep(100); //等待两个pin都已经成功地初始化
        }
		InterlockedExchange(&pMgr->m_bRequesting, REQUEST_TESTSTATE);
	}
	return 0;
}


BOOL CChannelMgr::Init(SOCKET SockFromProxy)
{
	assert(INVALID_SOCKET != SockFromProxy);
	if(INVALID_SOCKET != SockFromProxy)
	{
		m_SockFromProxy = SockFromProxy;
		if(!m_NetworkStub.Init(m_SockFromProxy, this))
		{
			assert(0);
			return FALSE;
		}
	}
	
	m_NameMsgID = m_MsgMgr.CreateMsgID();
/*	m_RetByGetMsgID = m_MsgMgr.CreateMsgID(TIMELESS);
	m_RetByReqMsgID = m_MsgMgr.CreateMsgID(TIMELESS);
	m_NotifyMsgID = m_MsgMgr.CreateMsgID(TIMELESS);
	m_BufPercentMsgID = m_MsgMgr.CreateMsgID(TEMPORARY);*/

	return TRUE;
}

BOOL CChannelMgr::Request(LPCTSTR url)
{
	assert(url != NULL);
	if(url != NULL)
	{	
		unsigned int threadID;
		m_RequestURL = url;
        InterlockedExchange(&m_bRequesting, REQUEST_INIT);
		h_RequestThread = (HANDLE) _beginthreadex(NULL, 0, &_RequestFunc, this, 0, &threadID);
	}

	return (h_RequestThread != NULL);
}

void CChannelMgr::Stop()
{
	m_Layer1.Stop();
//	if(m_Hwnd != NULL)
//		DestroyWindow(m_Hwnd);
	::PostMessage(g_hMainWnd, WM_CHANNELMGR_QUIT, (WPARAM)m_ChannelID, (LPARAM)0);
}


void    CChannelMgr::TestSwitchStatus()
{
    LONG temp = InterlockedExchange(&m_PrevRequest, m_bRequesting);

	MultiLanguage	LangDll;
    CString strRetErr;

    if(temp != m_PrevRequest)//状态已经改变,需要进行切换
    {
        switch(m_bRequesting)
        {
        case REQUEST_INIT:
            m_MsgMgr.UpdateMessage(m_NameMsgID, LangDll.GetStringByStr(_TEXT("正在打开")), CMsgMgr::TIMELESS);
            pInfAnime->StartProxy(InfAnime::REQUEST_PROCESS);
            break;
        case REQUEST_TESTSTATE:
            m_MsgMgr.UpdateMessage(m_NameMsgID, LangDll.GetStringByStr(_TEXT("切换节目的过程中,视音频正在同步")), CMsgMgr::TIMELESS);
            pInfAnime->StartProxy(InfAnime::REQUEST_PROCESS);
            break;
        case REQUEST_BUFFER:
            m_MsgMgr.UpdateMessage(m_NameMsgID, LangDll.GetStringByStr(_TEXT("正在缓冲数据中")), CMsgMgr::FORCESHOW | CMsgMgr::TIMELESS | CMsgMgr::WAIT);
            pInfAnime->StartProxy(InfAnime::REQUEST_PROCESS);
            break;
        case REQUEST_OK:
            m_MsgMgr.UpdateMessage(m_NameMsgID, LangDll.GetStringByStr(_TEXT("正在播放")), CMsgMgr::TIMELESS | CMsgMgr::FORCEHIDE);
            pInfAnime->EndProxy();
            m_audiopin.Start();
            m_videopin.Start();
            break;
        case REQUEST_FAIL:
//            CChannelMgr::HandleLayerErrCode(m_errorcode, strRetErr);
//            m_MsgMgr.UpdateMessage(m_NameMsgID, strRetErr, CMsgMgr::FORCESHOW | CMsgMgr::TIMELESS);
//            pInfAnime->StartProxy(InfAnime::REQUEST_FAIL);
            break;
        case REQUEST_DEAD:
            break;
        default:
            assert(0);
        }
    }

    
}

int CChannelMgr::GetData(SampleHeader &header, PBYTE &pData,
                         const UINT maxSize, const bool bAudio,
                         const bool bKeySample)
{
    P2P_RETURN_TYPE RetType = PRT_SYS;

    MultiLanguage	LangDll;
    TestSwitchStatus();

	//处理正在打开URL的情况
	if(m_bRequesting == REQUEST_INIT)
    {
        m_MsgMgr.UpdateMessage(m_NameMsgID, LangDll.GetStringByStr(_TEXT("正在打开")));

        if(bAudio)
            m_CoutPinInit |= 1;
        else
            m_CoutPinInit |= 2;

        if(pInfAnime->ProxyGetData(header, pData, maxSize, bAudio, bKeySample) == PRT_OK)
            return 1;
        else
            return 0;
    }
    else if(m_bRequesting  == REQUEST_TESTSTATE)
    {
        m_MsgMgr.UpdateMessage(m_NameMsgID, LangDll.GetStringByStr(_TEXT("切换节目的过程中,视音频正在同步")));

        if(bAudio)
            RetType = m_audiopin.PeerData(header, pData, maxSize, bKeySample);
        else
            RetType = m_videopin.PeerData(header, pData, maxSize, bKeySample);

        if(RetType == PRT_OK || RetType == PRT_BLOCK_NOTFOUND)
        {
            InterlockedExchange(&m_bRequesting, REQUEST_BUFFER);    //即使返回OK,也先进入buffer状态,等缓冲区满再播放
            return 0;//GetData(header, pData, maxSize, bAudio, bKeySample);
        }
        else if(RetType != PRT_PROGRAM_SYNC)    //发生了其它类型的错误,挂了
        {
            m_errorcode = RetType;
            InterlockedExchange(&m_bRequesting, REQUEST_FAIL);
            return 0;//GetData(header, pData, maxSize, bAudio, bKeySample);
        }
        else
        {
            if(pInfAnime->ProxyGetData(header, pData, maxSize, bAudio, bKeySample) == PRT_OK)
                return 1;
            else
                return 0;
        }
    }
    else if(m_bRequesting  == REQUEST_BUFFER)
    {	
	    //处理正在缓冲的情况
        RetType = pInfAnime->ProxyGetData(header, pData, maxSize, bAudio, bKeySample);
        
        //产生气球上的提示信息
	    CString strBufPercent;
	    MultiLanguage	LangDll;

		int	BufPercent = m_Layer1.GetBufferPercent();

		if(BufPercent < 0)  //挂了
        {
			m_errorcode = PRT_SYS;
            InterlockedExchange(&m_bRequesting, REQUEST_FAIL);
            return 0;
        }
        else if(BufPercent >= 100)
        {
            m_Layer1.BufferFinished();
            InterlockedExchange(&m_bRequesting, REQUEST_OK);
        }
        else
        {
            strBufPercent.Format(_T("%s%d%%"), LangDll.GetStringByStr(_TEXT("正在缓冲数据中")), BufPercent);
	        m_MsgMgr.UpdateMessage(m_NameMsgID, strBufPercent);
        }

        if(RetType == PRT_OK)
            return 1;
        else
            return 0;
    }
    else if(m_bRequesting == REQUEST_OK)//正常播放中的的情况
    {
        m_MsgMgr.UpdateMessage(m_NameMsgID, LangDll.GetStringByStr(_TEXT("正在播放")));

        if(bAudio)
            RetType = m_audiopin.GetData(header, pData, maxSize, bKeySample);
        else
            RetType = m_videopin.GetData(header, pData, maxSize, bKeySample);

	    if(RetType == PRT_OK)
	    {
            return 1;
	    }
    
        //以下处理错误的情况
	    if(RetType == PRT_BLOCK_NOTFOUND)
	    {
            InterlockedExchange(&m_bRequesting, REQUEST_BUFFER);
	    }
	    else if(RetType == PRT_PROGRAM_SYNC)
	    {
            InterlockedExchange(&m_bRequesting, REQUEST_TESTSTATE);
	    }
	    else
	    {
		    m_errorcode = RetType;
            InterlockedExchange(&m_bRequesting, REQUEST_FAIL);
	    }

        return 0; 
    }
	else
    {
//        if(pInfAnime->ProxyGetData(header, pData, maxSize, bAudio, bKeySample) == PRT_OK)
//            return 1;
//        else
            return -1;
    }        

	return -1;
}

CMsgMgr* CChannelMgr::GetMsgMgr()
{
	return &m_MsgMgr;
}


int		CChannelMgr::HandleLayerErrCode(P2P_RETURN_TYPE RetType, CString& strRetErr)
{
	MultiLanguage	LangDll;
	int iRet = 0;
	switch(RetType)
	{
	case PRT_PROGRAM_SYNC:
		strRetErr = LangDll.GetStringByStr(_TEXT("切换节目的过程中,视音频正在同步"));
		iRet = 0;
		break;
	case PRT_ALLOC:
		strRetErr = LangDll.GetStringByStr(_TEXT("内存分配错误"));
		iRet = -1;
		break;
	case PRT_WRONG_ARG:
		strRetErr = LangDll.GetStringByStr(_TEXT("错误的参数"));
		iRet = -1;
		break;
	case PRT_NOT_INIT:
		strRetErr = LangDll.GetStringByStr(_TEXT("尚未初始化"));
		iRet = -1;
		break;
	case PRT_DUP_INIT:
		strRetErr = LangDll.GetStringByStr(_TEXT("重复初始化"));
		iRet = -1;
		break;
	case PRT_INIT_SOCK:
		strRetErr = LangDll.GetStringByStr(_TEXT("无法初始化windows socket"));
		iRet = -1;
		break;
	case PRT_TRACKER_IP:
		strRetErr = LangDll.GetStringByStr(_TEXT("非法的TrackServer地址"));
		iRet = -1;
		break;
	case PRT_INIT_BIND:
		strRetErr = LangDll.GetStringByStr(_TEXT("无法绑定网络端口"));
		iRet = -1;
		break;
	case PRT_UNSUPPORT_RES:
		strRetErr = LangDll.GetStringByStr(_TEXT("不支持的资源类型"));
		iRet = -1;
		break;
	case PRT_WRONG_IF:
		strRetErr = LangDll.GetStringByStr(_TEXT("调用了错误的接口,因为当前资源并非支持所有接口"));
		iRet = -1;
		break;
	case PRT_DISK_FULL:
		strRetErr = LangDll.GetStringByStr(_TEXT("磁盘空间不足"));
		iRet = -1;
		break;
	case PRT_BUFFER_FULL:
		strRetErr = LangDll.GetStringByStr(_TEXT("缓冲区已满"));
		iRet = -1;
		break;
	case PRT_SEEKING:
		strRetErr = LangDll.GetStringByStr(_TEXT("正在SEEK,不能读取数据"));
		iRet = -1;
		break;
	case PRT_WRONG_RES_INFO:
		strRetErr = LangDll.GetStringByStr(_TEXT("出现了两个资源的hashcode相同,但是参数却不尽相同的情况"));
		iRet = -1;
		break;
	case PRT_CANNOT_OPEN_BUF:
		strRetErr = LangDll.GetStringByStr(_TEXT("无法打开缓冲文件"));
		iRet = -1;
		break;
	case PRT_BAD_MEDIAFORMAT:
		strRetErr = LangDll.GetStringByStr(_TEXT("错误的直播媒体类型"));
		iRet = -1;
		break;
	case PRT_BAD_BLOCK:
		strRetErr = LangDll.GetStringByStr(_TEXT("错误的Block"));
		iRet = -1;
		break;
	case PRT_BAD_URL:
		strRetErr = LangDll.GetStringByStr(_TEXT("错误URL地址"));
		iRet = -1;
		break;
	case PRT_SYS:
		strRetErr = LangDll.GetStringByStr(_TEXT("系统错误"));
		iRet = -1;
		break;
	case PRT_NET:
		strRetErr = LangDll.GetStringByStr(_TEXT("网络错误"));
		iRet = -1;
		break;
	default:
		assert(0);
		iRet = -1;
	}

	return iRet;
}



⌨️ 快捷键说明

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