📄 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 <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 + -