ChannelMgr.cpp
上传用户:liguizhu
上传日期:2015-11-01
资源大小:2422k
文件大小:13k
源码类别:

P2P编程

开发平台:

Visual C++

  1. /*
  2.  *  Openmysee
  3.  *
  4.  *  This program is free software; you can redistribute it and/or modify
  5.  *  it under the terms of the GNU General Public License as published by
  6.  *  the Free Software Foundation; either version 2 of the License, or
  7.  *  (at your option) any later version.
  8.  *
  9.  *  This program is distributed in the hope that it will be useful,
  10.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  *  GNU General Public License for more details.
  13.  *
  14.  *  You should have received a copy of the GNU General Public License
  15.  *  along with this program; if not, write to the Free Software
  16.  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  17.  *
  18.  */
  19. #include "stdafx.h"
  20. #include "ChannelMgr.h"
  21. #include "LocalServer.h"
  22. #include "MultiLanguageMgr.h"
  23. #include "HttpRequest.h"
  24. #include "InfAnime.h"
  25. extern volatile HINSTANCE g_hInstance;
  26. extern volatile HWND g_hMainWnd;
  27. //extern CLocalServer *g_pLocalServer;
  28. void CChannelMgr::GetChannelName(CString& strRet)
  29. {
  30.     UINT len = 256;
  31.     if(m_Layer1.GetFileName(strRet.GetBuffer(len), len) == FALSE && len > 256)
  32.     {
  33.         len += 1;
  34.         strRet.ReleaseBuffer();
  35.         m_Layer1.GetFileName(strRet.GetBuffer(len), len);
  36.     }
  37.     strRet.ReleaseBuffer();
  38. /* if(m_ChannelNameBuf.IsEmpty())
  39. {
  40. UINT len = 200;
  41. TCHAR* pbuf = new TCHAR[len];
  42. if(m_Layer1.GetFileName(pbuf, len))
  43. {
  44. m_ChannelNameBuf = pbuf;
  45. strRet = pbuf;
  46. strRet += _T(":");
  47. }
  48. else
  49. {
  50. MultiLanguage LangDll;
  51. strRet = LangDll.GetStringByStr(_T("未知频道:"));
  52. }
  53. delete pbuf;
  54. }
  55. else
  56. {
  57. strRet = m_ChannelNameBuf;
  58. strRet += _T(":");
  59. }*/
  60. }
  61. CChannelMgr::CChannelMgr(CHANNELID ChannelID)
  62. : m_ChannelID(ChannelID), m_SockFromProxy(INVALID_SOCKET),
  63.   m_videopin(&m_Layer1, false), m_audiopin(&m_Layer1, true),
  64.   m_NameMsgID(0),h_RequestThread(NULL),m_PrevRequest(REQUEST_NOPP),
  65.   m_CoutPinInit(0)
  66. {
  67.     pInfAnime = new InfAnime;
  68. pHttpSession = new HttpRequest;
  69. pHttpSession->Create();
  70. }
  71. CChannelMgr::~CChannelMgr()
  72. {
  73. pHttpSession->SetStopRequest();
  74. if(h_RequestThread != NULL)
  75. {
  76.         m_CoutPinInit = -1;
  77. WaitForSingleObject(h_RequestThread,INFINITE);
  78. CloseHandle(h_RequestThread);
  79. }
  80. delete pHttpSession;
  81.     delete pInfAnime;
  82. }
  83. CChannelMgr* CChannelMgr::Allocator(CHANNELID ChannelID)
  84. {
  85. return new CChannelMgr(ChannelID);
  86. }
  87. void CChannelMgr::Dellocator(CChannelMgr* pdel, BOOL block)
  88. {
  89. if(block)
  90. delete pdel;
  91. else
  92. {
  93. unsigned int threadID;
  94. _beginthreadex(NULL, 0, &_DellocatorProc, pdel, 0, &threadID);
  95. }
  96. }
  97. unsigned int CALLBACK CChannelMgr::_DellocatorProc(void* lpParameter)
  98. {
  99. CChannelMgr* pdel = static_cast<CChannelMgr*>(lpParameter);
  100. delete pdel;
  101. return 0;
  102. }
  103. unsigned int CALLBACK CChannelMgr::_RequestFunc(void* lpParameter)
  104. {
  105. CChannelMgr* pMgr = static_cast<CChannelMgr*>(lpParameter);
  106. BOOL bOK = FALSE;
  107. CString filename;
  108. while(1)
  109. {
  110. if(GetTempPath(MAX_PATH, filename.GetBuffer(MAX_PATH)) == 0)
  111. {
  112. filename.ReleaseBuffer();
  113. break;
  114. }
  115. filename.ReleaseBuffer();
  116. CString tempname;
  117. tempname.Format(_T("gtvtemp%d.gtv"), pMgr->m_ChannelID);
  118. filename += tempname;
  119. HANDLE hfile = CreateFile(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
  120. if(hfile == NULL)
  121. break;
  122. pMgr->pHttpSession->SetFileMode(hfile);
  123. if(pMgr->pHttpSession->OpenRequest(pMgr->m_RequestURL))
  124. bOK = TRUE;
  125. CloseHandle(hfile);
  126. break;
  127. }
  128. P2P_RETURN_TYPE RetType;
  129. if(bOK)
  130. RetType = pMgr->m_Layer1.Request(filename, g_hMainWnd, WM_SENDTOLAYER1, pMgr->m_ChannelID);
  131. else
  132. RetType = pMgr->m_Layer1.Request(pMgr->m_RequestURL, g_hMainWnd, WM_SENDTOLAYER1, pMgr->m_ChannelID); //直接将URL给layer作最后的尝试
  133. if(PRT_OK != RetType)
  134. {
  135. // MultiLanguage LangDll;
  136. // CString strRet;
  137. // pMgr->HandleLayerErrCode(RetType, strRet);
  138. // pMgr->m_MsgMgr.UpdateMessage(pMgr->m_NameMsgID, strRet, CMsgMgr::TIMELESS | CMsgMgr::FORCESHOW);
  139.         pMgr->m_errorcode = RetType;
  140. InterlockedExchange(&pMgr->m_bRequesting, REQUEST_FAIL);
  141. }
  142. else
  143. {
  144.         while(pMgr->m_CoutPinInit != 3)
  145.         {
  146.             if(pMgr->m_CoutPinInit == -1)
  147.                 return 0;           //直接返回退出
  148.             Sleep(100); //等待两个pin都已经成功地初始化
  149.         }
  150. InterlockedExchange(&pMgr->m_bRequesting, REQUEST_TESTSTATE);
  151. }
  152. return 0;
  153. }
  154. BOOL CChannelMgr::Init(SOCKET SockFromProxy)
  155. {
  156. assert(INVALID_SOCKET != SockFromProxy);
  157. if(INVALID_SOCKET != SockFromProxy)
  158. {
  159. m_SockFromProxy = SockFromProxy;
  160. if(!m_NetworkStub.Init(m_SockFromProxy, this))
  161. {
  162. assert(0);
  163. return FALSE;
  164. }
  165. }
  166. m_NameMsgID = m_MsgMgr.CreateMsgID();
  167. /* m_RetByGetMsgID = m_MsgMgr.CreateMsgID(TIMELESS);
  168. m_RetByReqMsgID = m_MsgMgr.CreateMsgID(TIMELESS);
  169. m_NotifyMsgID = m_MsgMgr.CreateMsgID(TIMELESS);
  170. m_BufPercentMsgID = m_MsgMgr.CreateMsgID(TEMPORARY);*/
  171. return TRUE;
  172. }
  173. BOOL CChannelMgr::Request(LPCTSTR url)
  174. {
  175. assert(url != NULL);
  176. if(url != NULL)
  177. {
  178. unsigned int threadID;
  179. m_RequestURL = url;
  180.         InterlockedExchange(&m_bRequesting, REQUEST_INIT);
  181. h_RequestThread = (HANDLE) _beginthreadex(NULL, 0, &_RequestFunc, this, 0, &threadID);
  182. }
  183. return (h_RequestThread != NULL);
  184. }
  185. void CChannelMgr::Stop()
  186. {
  187. m_Layer1.Stop();
  188. // if(m_Hwnd != NULL)
  189. // DestroyWindow(m_Hwnd);
  190. ::PostMessage(g_hMainWnd, WM_CHANNELMGR_QUIT, (WPARAM)m_ChannelID, (LPARAM)0);
  191. }
  192. void    CChannelMgr::TestSwitchStatus()
  193. {
  194.     LONG temp = InterlockedExchange(&m_PrevRequest, m_bRequesting);
  195. MultiLanguage LangDll;
  196.     CString strRetErr;
  197.     if(temp != m_PrevRequest)//状态已经改变,需要进行切换
  198.     {
  199.         switch(m_bRequesting)
  200.         {
  201.         case REQUEST_INIT:
  202.             m_MsgMgr.UpdateMessage(m_NameMsgID, LangDll.GetStringByStr(_TEXT("正在打开")), CMsgMgr::TIMELESS);
  203.             pInfAnime->StartProxy(InfAnime::REQUEST_PROCESS);
  204.             break;
  205.         case REQUEST_TESTSTATE:
  206.             m_MsgMgr.UpdateMessage(m_NameMsgID, LangDll.GetStringByStr(_TEXT("切换节目的过程中,视音频正在同步")), CMsgMgr::TIMELESS);
  207.             pInfAnime->StartProxy(InfAnime::REQUEST_PROCESS);
  208.             break;
  209.         case REQUEST_BUFFER:
  210.             m_MsgMgr.UpdateMessage(m_NameMsgID, LangDll.GetStringByStr(_TEXT("正在缓冲数据中")), CMsgMgr::FORCESHOW | CMsgMgr::TIMELESS | CMsgMgr::WAIT);
  211.             pInfAnime->StartProxy(InfAnime::REQUEST_PROCESS);
  212.             break;
  213.         case REQUEST_OK:
  214.             m_MsgMgr.UpdateMessage(m_NameMsgID, LangDll.GetStringByStr(_TEXT("正在播放")), CMsgMgr::TIMELESS | CMsgMgr::FORCEHIDE);
  215.             pInfAnime->EndProxy();
  216.             m_audiopin.Start();
  217.             m_videopin.Start();
  218.             break;
  219.         case REQUEST_FAIL:
  220. //            CChannelMgr::HandleLayerErrCode(m_errorcode, strRetErr);
  221. //            m_MsgMgr.UpdateMessage(m_NameMsgID, strRetErr, CMsgMgr::FORCESHOW | CMsgMgr::TIMELESS);
  222. //            pInfAnime->StartProxy(InfAnime::REQUEST_FAIL);
  223.             break;
  224.         case REQUEST_DEAD:
  225.             break;
  226.         default:
  227.             assert(0);
  228.         }
  229.     }
  230.     
  231. }
  232. int CChannelMgr::GetData(SampleHeader &header, PBYTE &pData,
  233.                          const UINT maxSize, const bool bAudio,
  234.                          const bool bKeySample)
  235. {
  236.     P2P_RETURN_TYPE RetType = PRT_SYS;
  237.     MultiLanguage LangDll;
  238.     TestSwitchStatus();
  239. //处理正在打开URL的情况
  240. if(m_bRequesting == REQUEST_INIT)
  241.     {
  242.         m_MsgMgr.UpdateMessage(m_NameMsgID, LangDll.GetStringByStr(_TEXT("正在打开")));
  243.         if(bAudio)
  244.             m_CoutPinInit |= 1;
  245.         else
  246.             m_CoutPinInit |= 2;
  247.         if(pInfAnime->ProxyGetData(header, pData, maxSize, bAudio, bKeySample) == PRT_OK)
  248.             return 1;
  249.         else
  250.             return 0;
  251.     }
  252.     else if(m_bRequesting  == REQUEST_TESTSTATE)
  253.     {
  254.         m_MsgMgr.UpdateMessage(m_NameMsgID, LangDll.GetStringByStr(_TEXT("切换节目的过程中,视音频正在同步")));
  255.         if(bAudio)
  256.             RetType = m_audiopin.PeerData(header, pData, maxSize, bKeySample);
  257.         else
  258.             RetType = m_videopin.PeerData(header, pData, maxSize, bKeySample);
  259.         if(RetType == PRT_OK || RetType == PRT_BLOCK_NOTFOUND)
  260.         {
  261.             InterlockedExchange(&m_bRequesting, REQUEST_BUFFER);    //即使返回OK,也先进入buffer状态,等缓冲区满再播放
  262.             return 0;//GetData(header, pData, maxSize, bAudio, bKeySample);
  263.         }
  264.         else if(RetType != PRT_PROGRAM_SYNC)    //发生了其它类型的错误,挂了
  265.         {
  266.             m_errorcode = RetType;
  267.             InterlockedExchange(&m_bRequesting, REQUEST_FAIL);
  268.             return 0;//GetData(header, pData, maxSize, bAudio, bKeySample);
  269.         }
  270.         else
  271.         {
  272.             if(pInfAnime->ProxyGetData(header, pData, maxSize, bAudio, bKeySample) == PRT_OK)
  273.                 return 1;
  274.             else
  275.                 return 0;
  276.         }
  277.     }
  278.     else if(m_bRequesting  == REQUEST_BUFFER)
  279.     {
  280.     //处理正在缓冲的情况
  281.         RetType = pInfAnime->ProxyGetData(header, pData, maxSize, bAudio, bKeySample);
  282.         
  283.         //产生气球上的提示信息
  284.     CString strBufPercent;
  285.     MultiLanguage LangDll;
  286. int BufPercent = m_Layer1.GetBufferPercent();
  287. if(BufPercent < 0)  //挂了
  288.         {
  289. m_errorcode = PRT_SYS;
  290.             InterlockedExchange(&m_bRequesting, REQUEST_FAIL);
  291.             return 0;
  292.         }
  293.         else if(BufPercent >= 100)
  294.         {
  295.             m_Layer1.BufferFinished();
  296.             InterlockedExchange(&m_bRequesting, REQUEST_OK);
  297.         }
  298.         else
  299.         {
  300.             strBufPercent.Format(_T("%s%d%%"), LangDll.GetStringByStr(_TEXT("正在缓冲数据中")), BufPercent);
  301.         m_MsgMgr.UpdateMessage(m_NameMsgID, strBufPercent);
  302.         }
  303.         if(RetType == PRT_OK)
  304.             return 1;
  305.         else
  306.             return 0;
  307.     }
  308.     else if(m_bRequesting == REQUEST_OK)//正常播放中的的情况
  309.     {
  310.         m_MsgMgr.UpdateMessage(m_NameMsgID, LangDll.GetStringByStr(_TEXT("正在播放")));
  311.         if(bAudio)
  312.             RetType = m_audiopin.GetData(header, pData, maxSize, bKeySample);
  313.         else
  314.             RetType = m_videopin.GetData(header, pData, maxSize, bKeySample);
  315.     if(RetType == PRT_OK)
  316.     {
  317.             return 1;
  318.     }
  319.     
  320.         //以下处理错误的情况
  321.     if(RetType == PRT_BLOCK_NOTFOUND)
  322.     {
  323.             InterlockedExchange(&m_bRequesting, REQUEST_BUFFER);
  324.     }
  325.     else if(RetType == PRT_PROGRAM_SYNC)
  326.     {
  327.             InterlockedExchange(&m_bRequesting, REQUEST_TESTSTATE);
  328.     }
  329.     else
  330.     {
  331.     m_errorcode = RetType;
  332.             InterlockedExchange(&m_bRequesting, REQUEST_FAIL);
  333.     }
  334.         return 0; 
  335.     }
  336. else
  337.     {
  338. //        if(pInfAnime->ProxyGetData(header, pData, maxSize, bAudio, bKeySample) == PRT_OK)
  339. //            return 1;
  340. //        else
  341.             return -1;
  342.     }        
  343. return -1;
  344. }
  345. CMsgMgr* CChannelMgr::GetMsgMgr()
  346. {
  347. return &m_MsgMgr;
  348. }
  349. int CChannelMgr::HandleLayerErrCode(P2P_RETURN_TYPE RetType, CString& strRetErr)
  350. {
  351. MultiLanguage LangDll;
  352. int iRet = 0;
  353. switch(RetType)
  354. {
  355. case PRT_PROGRAM_SYNC:
  356. strRetErr = LangDll.GetStringByStr(_TEXT("切换节目的过程中,视音频正在同步"));
  357. iRet = 0;
  358. break;
  359. case PRT_ALLOC:
  360. strRetErr = LangDll.GetStringByStr(_TEXT("内存分配错误"));
  361. iRet = -1;
  362. break;
  363. case PRT_WRONG_ARG:
  364. strRetErr = LangDll.GetStringByStr(_TEXT("错误的参数"));
  365. iRet = -1;
  366. break;
  367. case PRT_NOT_INIT:
  368. strRetErr = LangDll.GetStringByStr(_TEXT("尚未初始化"));
  369. iRet = -1;
  370. break;
  371. case PRT_DUP_INIT:
  372. strRetErr = LangDll.GetStringByStr(_TEXT("重复初始化"));
  373. iRet = -1;
  374. break;
  375. case PRT_INIT_SOCK:
  376. strRetErr = LangDll.GetStringByStr(_TEXT("无法初始化windows socket"));
  377. iRet = -1;
  378. break;
  379. case PRT_TRACKER_IP:
  380. strRetErr = LangDll.GetStringByStr(_TEXT("非法的TrackServer地址"));
  381. iRet = -1;
  382. break;
  383. case PRT_INIT_BIND:
  384. strRetErr = LangDll.GetStringByStr(_TEXT("无法绑定网络端口"));
  385. iRet = -1;
  386. break;
  387. case PRT_UNSUPPORT_RES:
  388. strRetErr = LangDll.GetStringByStr(_TEXT("不支持的资源类型"));
  389. iRet = -1;
  390. break;
  391. case PRT_WRONG_IF:
  392. strRetErr = LangDll.GetStringByStr(_TEXT("调用了错误的接口,因为当前资源并非支持所有接口"));
  393. iRet = -1;
  394. break;
  395. case PRT_DISK_FULL:
  396. strRetErr = LangDll.GetStringByStr(_TEXT("磁盘空间不足"));
  397. iRet = -1;
  398. break;
  399. case PRT_BUFFER_FULL:
  400. strRetErr = LangDll.GetStringByStr(_TEXT("缓冲区已满"));
  401. iRet = -1;
  402. break;
  403. case PRT_SEEKING:
  404. strRetErr = LangDll.GetStringByStr(_TEXT("正在SEEK,不能读取数据"));
  405. iRet = -1;
  406. break;
  407. case PRT_WRONG_RES_INFO:
  408. strRetErr = LangDll.GetStringByStr(_TEXT("出现了两个资源的hashcode相同,但是参数却不尽相同的情况"));
  409. iRet = -1;
  410. break;
  411. case PRT_CANNOT_OPEN_BUF:
  412. strRetErr = LangDll.GetStringByStr(_TEXT("无法打开缓冲文件"));
  413. iRet = -1;
  414. break;
  415. case PRT_BAD_MEDIAFORMAT:
  416. strRetErr = LangDll.GetStringByStr(_TEXT("错误的直播媒体类型"));
  417. iRet = -1;
  418. break;
  419. case PRT_BAD_BLOCK:
  420. strRetErr = LangDll.GetStringByStr(_TEXT("错误的Block"));
  421. iRet = -1;
  422. break;
  423. case PRT_BAD_URL:
  424. strRetErr = LangDll.GetStringByStr(_TEXT("错误URL地址"));
  425. iRet = -1;
  426. break;
  427. case PRT_SYS:
  428. strRetErr = LangDll.GetStringByStr(_TEXT("系统错误"));
  429. iRet = -1;
  430. break;
  431. case PRT_NET:
  432. strRetErr = LangDll.GetStringByStr(_TEXT("网络错误"));
  433. iRet = -1;
  434. break;
  435. default:
  436. assert(0);
  437. iRet = -1;
  438. }
  439. return iRet;
  440. }