www.pudn.com > mysee.zip > BufferMgr.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  
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 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