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

📄 buffermgr.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
*
*/
#ifndef __BUFFERMGR_H_
#define __BUFFERMGR_H_

#include <map>
using namespace std;

class MediaData {
public:
	explicit MediaData() {
		memset(&videoType, 0, sizeof(videoType));
		memset(&audioType, 0, sizeof(audioType));
		videoData = audioData = NULL;
	};
	// 拷贝构造函数
	explicit MediaData(const MediaData& another) {
		videoType = another.videoType;
		audioType = another.audioType;

		videoData = new BYTE[videoType.cbFormat];
		audioData = new BYTE[audioType.cbFormat];

		memcpy(videoData, another.videoData, videoType.cbFormat);
		memcpy(audioData, another.audioData, audioType.cbFormat);
	};
	virtual ~MediaData() {
		delete [] videoData;
		delete [] audioData;
	};
	bool operator == (const MediaData& a) const {
		return (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);
	};
	MediaData& operator=(const MediaData& another) {
		videoType = another.videoType;
		audioType = another.audioType;

		delete [] videoData;
		delete [] audioData;
		videoData = new BYTE[videoType.cbFormat];
		audioData = new BYTE[audioType.cbFormat];
		memcpy(videoData, another.videoData, videoType.cbFormat);
		memcpy(audioData, another.audioData, audioType.cbFormat);
		return *this;
	}
    bool IsEmpty() const {
        return videoType.cbFormat == 0 && audioType.cbFormat == 0;
    }

public:
	TVMEDIATYPESECTION	videoType;
	PBYTE		        videoData;
	TVMEDIATYPESECTION	audioType;
	PBYTE		        audioData;
};

class CaptureServer;
class LogMgr;

class BufferMgr {
public:
	BufferMgr(CaptureServer* c);
	virtual ~BufferMgr();

	BOOL PutSample(const SampleHeader& header, BYTE* pData, LogMgr* log);
	/*
	 * 按blockID查找此block,如果没有找到,则返回错误;如果找到,
	 * 则将数据复制到buf, 将size置为该block的实际大小。
	 */
	BOOL GetBlock(UINT blockID, BYTE* buf, UINT& size);

    // 获取一个块的编码类型
    BOOL GetMediaData(UINT blockID, MediaData& data);

    // 标志切换编码的Block
    BOOL AttachMediaDataToCurrentBlock(const TVMEDIATYPESECTION& tv, const BYTE* data, BOOL bAudio, LogMgr* log);

	UINT GetMaxBlockID() {return maxBlockID;};

	// 检查是不是过长时间没有接受到Sample了。
	BOOL CheckRecvingSample() {
		return (time(NULL) - lastRecvSampleTime <= MAX_SAMPLE_INTERVAL);
	};

protected:
	/*将NewBlock存入缓冲文件,并将blockCount++.*/
	BOOL SaveNewBlock(BYTE* buf, UINT size);
	void RemoveOldTmpFile();
	BOOL SaveSample(UINT dataOff, const UINT allSize);
	UINT GetPlayingBlock() { return blockCount==0 ? 0 : blockCount-1; }; // blockCount-1 is blockID
	
protected:
	static BOOL ExCreateFile(HANDLE&, LPCTSTR lpFileName, DWORD dwDesiredAccess,
                    DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes,
                    DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, 
                    HANDLE hTemplateFile);
	static BOOL ExCreateFile(HANDLE&, LPCTSTR lpFileName, DWORD dwCreationDisposition);
	static int  ExReadFile(HANDLE, LPVOID buf, int toBeRead);
	static BOOL ExWriteFile(HANDLE, LPVOID buf, int toBeWrite);
	static BOOL ExSetFilePointer(HANDLE, int offset);
	static BOOL ExSetFileSize(HANDLE, int size);     // 更改文件大小

private:
	string		bufferPath;		// 缓冲文件路径
	HANDLE		hBufferFile;	// 缓冲文件handle
	CCritSec	bufferfile_cs;	// 缓冲文件操作的互斥变量

	UINT*		blockArray;	// 存储块的数组              //
	UINT*		blockSize;	// 存储块的大小              //暂时没有用
	UINT		maxBlockNum;// 存储块的最大个数          // 
	UINT		maxBlockID;

private:
	enum {
		BUFFER_SPACE = 150994944,	// 缓冲区大小144MB
		MAX_SAMPLE_INTERVAL = 20,	// 两个Sample之间最长的间隔,单位是秒
#ifdef _DEBUG
        TIME4WAIT2STORE = 10,
#else
        TIME4WAIT2STORE = 30,
#endif
	};
	BYTE*		newBlock;			// 正在生成的块
	UINT		newBlockSize;		// newBlock的大小
	BYTE*		sampleBuffer;		// 将Sample存入Block的中转站
	UINT		sampleBufferSize;

    bool        bSwitchMedia;       // 编码方式发生变化

	UINT		blockCount;			// 所有已生成块的个数
	BOOL		firstKeySample;		// 当前块中第一个KeySample

    MediaData   currMediaData;      // 当前块编码类型,可能为空
    map<UINT, MediaData> mediaMap;  // 所有附带编码类型的块

private:
	LONGLONG sampleStartTime;
	time_t startseconds;

	// TEST: 检测时光倒退的问题
	LONGLONG lastSampleStart;

	// 上次接收到Sample的时间。
	time_t lastRecvSampleTime;

	CaptureServer* cs;

public:
	void StartSave();
	void StopSave();
	BOOL ShouldConnect() {return bShouldConnect;};
private:
	BOOL bShouldSave;
	BOOL bShouldConnect;
};

#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -