📄 channelmgr.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 + -