📄 mediaarray.h
字号:
/*
* 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
*
*/
#pragma once
#include <list>
using namespace std;
class MediaInterval {
public:
explicit MediaInterval() {
start = 0xffffffff;
size = 0;
cnamesize = pnamesize = 0;
memset(&videoType, 0, sizeof(videoType));
memset(&audioType, 0, sizeof(audioType));
videoData = audioData = NULL;
cname = pname = NULL;
progtime = 0;
};
// 拷贝构造函数
explicit MediaInterval(const MediaInterval& another) {
start = another.start;
size = another.size;
cnamesize = another.cnamesize;
pnamesize = another.pnamesize;
progtime = another.progtime;
videoType = another.videoType;
audioType = another.audioType;
videoData = new BYTE[videoType.cbFormat];
audioData = new BYTE[audioType.cbFormat];
pname = new char[pnamesize+1];
cname = new char[cnamesize+1];
memcpy(videoData, another.videoData, videoType.cbFormat);
memcpy(audioData, another.audioData, audioType.cbFormat);
memcpy(cname, another.cname, cnamesize);
cname[cnamesize] = 0;
memcpy(pname, another.pname, pnamesize);
pname[pnamesize] = 0;
};
virtual ~MediaInterval() {
size = 0;
progtime = 0;
cnamesize = pnamesize = 0;
delete [] videoData;
delete [] audioData;
delete [] cname;
delete [] pname;
};
bool operator == (const MediaInterval& a) const {
return (start == a.start && size == a.size &&
cnamesize == a.cnamesize && pnamesize == a.pnamesize && progtime == a.progtime &&
memcmp(&videoType, &a.videoType, sizeof(videoType)) == 0 &&
memcmp(&audioType, &a.audioType, sizeof(audioType)) == 0 &&
memcmp(videoData, a.videoData, videoType.cbFormat) == 0 &&
memcmp(audioData, a.audioData, audioType.cbFormat) == 0 &&
memcmp(cname, a.cname, cnamesize) == 0 &&
memcmp(pname, a.pname, pnamesize) == 0);
};
MediaInterval& operator=(const MediaInterval& another) {
start = another.start;
size = another.size;
cnamesize = another.cnamesize;
pnamesize = another.pnamesize;
progtime = another.progtime;
videoType = another.videoType;
audioType = another.audioType;
delete [] videoData;
delete [] audioData;
delete [] cname;
delete [] pname;
videoData = new BYTE[videoType.cbFormat];
audioData = new BYTE[audioType.cbFormat];
pname = new char[pnamesize+1];
cname = new char[cnamesize+1];
memcpy(videoData, another.videoData, videoType.cbFormat);
memcpy(audioData, another.audioData, audioType.cbFormat);
memcpy(cname, another.cname, cnamesize);
cname[cnamesize] = 0;
memcpy(pname, another.pname, pnamesize);
pname[pnamesize] = 0;
return *this;
}
static bool cmp_type(const MediaInterval& i1, const MediaInterval& i2) {
return (memcmp(&i1.videoType, &i2.videoType, sizeof(i1.videoType)) == 0 &&
memcmp(&i1.audioType, &i2.audioType, sizeof(i1.audioType)) == 0 &&
memcmp(i1.videoData, i2.videoData, i1.videoType.cbFormat) == 0 &&
memcmp(i1.audioData, i2.audioData, i1.audioType.cbFormat) == 0);
};
public:
UINT start;
UINT size;
MediaType videoType;
PBYTE videoData;
MediaType audioType;
PBYTE audioData;
UINT8 pnamesize; // 节目名
char* pname; // 节目名长度
UINT32 progtime; // 节目时间
UINT8 cnamesize; // 频道名
char* cname; // 频道名长度
};
class MediaArray {
public:
void Clear() {
m_array.clear();
};
// 查找一个block是否存在
bool FindBlock(const UINT blockID) const {
for(CMIIt cit = m_array.begin(); cit != m_array.end(); ++cit) {
if(cit->start > blockID)
return false;
// 注意start+size不在区间之内
else if(cit->start+cit->size > blockID)
return true;
}
return false;
};
// 添加一个区间
bool AddInterval(const MediaInterval& interval, bool* bLiveChangeMediaData = NULL) {
if(interval.start == UINT_MAX)
return false;
assert(interval.size != 0);
if(interval.size == 0)
return false;
// TODO: 特殊情况,直播切换编码的情形,新的interval的end = UINT_MAX
if(interval.start + interval.size == UINT_MAX) {
MIIt it = m_array.begin();
for(; it != m_array.end(); ++it) {
if(it->start == interval.start) {
assert(it->start + it->size == UINT_MAX || interval.start + interval.size == UINT_MAX);
return true;
}
else if(it->start > interval.start) {
// 插入到列表中间的位置
MediaInterval temp(interval);
temp.size = it->start-interval.start;
m_array.insert(it, temp);
if(bLiveChangeMediaData)
*bLiveChangeMediaData = true;
return true;
}
}
// 插入到列表尾部
it--;
it->size = interval.start-it->start;
it++;
m_array.insert(it, interval);
if(bLiveChangeMediaData)
*bLiveChangeMediaData = true;
return true;
}
// 不能与现有任何区间有交集
for(MIIt it = m_array.begin(); it != m_array.end(); ++it) {
if( it->start > interval.start && it->start < interval.start+interval.size ||
it->start+it->size > interval.start && it->start+it->size < interval.start+interval.size)
{
assert(0);
return false;
}
if( it->start == interval.start && it->size == interval.size)
return true; // dup interval
}
// 在区间数组的当前位置添加区间
m_array.insert(it, interval);
return true;
};
// 获取某块对应的区间
bool GetInterval(const UINT blockID, MediaInterval& interval) const {
for(CMIIt cit = m_array.begin(); cit != m_array.end(); ++cit) {
if(cit->start > blockID)
return false;
// 注意start+size不在区间之内
else if(cit->start+cit->size > blockID) {
interval = *cit;
return true;
}
}
return false;
}
private:
list<MediaInterval> m_array;
typedef list<MediaInterval>::iterator MIIt;
typedef list<MediaInterval>::const_iterator CMIIt;
};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -