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

📄 mediaarray.h

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