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

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. #pragma once
  20. #include <list>
  21. using namespace std;
  22. class MediaInterval {
  23. public:
  24. explicit MediaInterval() {
  25. start = 0xffffffff;
  26. size = 0;
  27. cnamesize = pnamesize = 0;
  28. memset(&videoType, 0, sizeof(videoType));
  29. memset(&audioType, 0, sizeof(audioType));
  30. videoData = audioData = NULL;
  31. cname = pname = NULL;
  32. progtime = 0;
  33. };
  34. // 拷贝构造函数
  35. explicit MediaInterval(const MediaInterval& another) {
  36. start = another.start;
  37. size = another.size;
  38. cnamesize = another.cnamesize;
  39. pnamesize = another.pnamesize;
  40. progtime = another.progtime;
  41. videoType = another.videoType;
  42. audioType = another.audioType;
  43. videoData = new BYTE[videoType.cbFormat];
  44. audioData = new BYTE[audioType.cbFormat];
  45. pname = new char[pnamesize+1];
  46. cname = new char[cnamesize+1];
  47. memcpy(videoData, another.videoData, videoType.cbFormat);
  48. memcpy(audioData, another.audioData, audioType.cbFormat);
  49. memcpy(cname, another.cname, cnamesize);
  50. cname[cnamesize] = 0;
  51. memcpy(pname, another.pname, pnamesize);
  52. pname[pnamesize] = 0;
  53. };
  54. virtual ~MediaInterval() {
  55. size = 0;
  56. progtime = 0;
  57. cnamesize = pnamesize = 0;
  58. delete [] videoData;
  59. delete [] audioData;
  60. delete [] cname;
  61. delete [] pname;
  62. };
  63. bool operator == (const MediaInterval& a) const {
  64. return (start == a.start && size == a.size && 
  65. cnamesize == a.cnamesize && pnamesize == a.pnamesize  && progtime == a.progtime &&
  66. memcmp(&videoType, &a.videoType, sizeof(videoType)) == 0 && 
  67. memcmp(&audioType, &a.audioType, sizeof(audioType)) == 0 && 
  68. memcmp(videoData, a.videoData, videoType.cbFormat) == 0 && 
  69. memcmp(audioData, a.audioData, audioType.cbFormat) == 0 && 
  70. memcmp(cname, a.cname, cnamesize) == 0 && 
  71. memcmp(pname, a.pname, pnamesize) == 0);
  72. };
  73. MediaInterval& operator=(const MediaInterval& another) {
  74. start = another.start;
  75. size = another.size;
  76. cnamesize = another.cnamesize;
  77. pnamesize = another.pnamesize;
  78. progtime = another.progtime;
  79. videoType = another.videoType;
  80. audioType = another.audioType;
  81. delete [] videoData;
  82. delete [] audioData;
  83. delete [] cname;
  84. delete [] pname;
  85. videoData = new BYTE[videoType.cbFormat];
  86. audioData = new BYTE[audioType.cbFormat];
  87. pname = new char[pnamesize+1];
  88. cname = new char[cnamesize+1];
  89. memcpy(videoData, another.videoData, videoType.cbFormat);
  90. memcpy(audioData, another.audioData, audioType.cbFormat);
  91. memcpy(cname, another.cname, cnamesize);
  92. cname[cnamesize] = 0;
  93. memcpy(pname, another.pname, pnamesize);
  94. pname[pnamesize] = 0;
  95. return *this;
  96. }
  97. static bool cmp_type(const MediaInterval& i1, const MediaInterval& i2) {
  98. return (memcmp(&i1.videoType, &i2.videoType, sizeof(i1.videoType)) == 0 && 
  99. memcmp(&i1.audioType, &i2.audioType, sizeof(i1.audioType)) == 0 && 
  100. memcmp(i1.videoData, i2.videoData, i1.videoType.cbFormat) == 0 && 
  101. memcmp(i1.audioData, i2.audioData, i1.audioType.cbFormat) == 0);
  102. };
  103. public:
  104. UINT start;
  105. UINT size;
  106. MediaType videoType;
  107. PBYTE videoData;
  108. MediaType audioType;
  109. PBYTE audioData;
  110. UINT8 pnamesize; // 节目名
  111. char* pname; // 节目名长度
  112. UINT32 progtime; // 节目时间
  113. UINT8 cnamesize; // 频道名
  114. char* cname; // 频道名长度
  115. };
  116. class MediaArray {
  117. public:
  118. void Clear() {
  119. m_array.clear();
  120. };
  121. // 查找一个block是否存在
  122. bool FindBlock(const UINT blockID) const {
  123. for(CMIIt cit = m_array.begin(); cit != m_array.end(); ++cit) {
  124. if(cit->start > blockID)
  125. return false;
  126. // 注意start+size不在区间之内
  127. else if(cit->start+cit->size > blockID)
  128. return true;
  129. }
  130. return false;
  131. };
  132. // 添加一个区间
  133. bool AddInterval(const MediaInterval& interval, bool* bLiveChangeMediaData = NULL) {
  134. if(interval.start == UINT_MAX)
  135. return false;
  136. assert(interval.size != 0);
  137. if(interval.size == 0)
  138. return false;
  139.         // TODO: 特殊情况,直播切换编码的情形,新的interval的end = UINT_MAX
  140.         if(interval.start + interval.size == UINT_MAX) {
  141.             MIIt it = m_array.begin();
  142.     for(; it != m_array.end(); ++it) {
  143.                 if(it->start == interval.start) {
  144.                     assert(it->start + it->size == UINT_MAX || interval.start + interval.size == UINT_MAX);
  145.                     return true;
  146.                 }
  147.                 else if(it->start > interval.start) {
  148.                     // 插入到列表中间的位置
  149.                     MediaInterval temp(interval);
  150.                     temp.size = it->start-interval.start;
  151.                     m_array.insert(it, temp);
  152.                     if(bLiveChangeMediaData)
  153.                         *bLiveChangeMediaData = true;
  154.                     return true;
  155.                 }
  156.             }
  157.             // 插入到列表尾部
  158.             it--;
  159.             it->size = interval.start-it->start;
  160.             it++;
  161.             m_array.insert(it, interval);
  162.             if(bLiveChangeMediaData)
  163.                 *bLiveChangeMediaData = true;
  164.             return true;
  165.         }
  166. // 不能与现有任何区间有交集
  167. for(MIIt it = m_array.begin(); it != m_array.end(); ++it) {
  168. if( it->start > interval.start && it->start < interval.start+interval.size || 
  169. it->start+it->size > interval.start && it->start+it->size < interval.start+interval.size)
  170. {
  171. assert(0);
  172. return false;
  173. }
  174. if( it->start == interval.start && it->size == interval.size)
  175. return true; // dup interval
  176. }
  177. // 在区间数组的当前位置添加区间
  178. m_array.insert(it, interval);
  179. return true;
  180. };
  181. // 获取某块对应的区间
  182. bool GetInterval(const UINT blockID, MediaInterval& interval) const {
  183. for(CMIIt cit = m_array.begin(); cit != m_array.end(); ++cit) {
  184. if(cit->start > blockID)
  185. return false;
  186. // 注意start+size不在区间之内
  187. else if(cit->start+cit->size > blockID) {
  188. interval = *cit;
  189. return true;
  190. }
  191. }
  192. return false;
  193. }
  194. private:
  195. list<MediaInterval> m_array;
  196. typedef list<MediaInterval>::iterator MIIt;
  197. typedef list<MediaInterval>::const_iterator CMIIt;
  198. };