数据读取/写入——环型缓存区

来源:互联网 发布:大学生程序员 编辑:程序博客网 时间:2024/05/02 06:13

    数据的读取和写入管理,可以通过列表和环型列表来实现,文本使用环型列表来实现数据的读取和写入操作,当写数据超过缓冲区大小时,通过读写位置重复利用已读取的区域写入数据值。

    代码:

/*描述: 环型缓存区操作类说明:本类对内存做环型缓存区管理*/#ifndef  __CircleBuffer_H__#define  __CircleBuffer_H__#pragma once#include <boost/thread/shared_mutex.hpp>#include <Windows.h>using namespace std;#defineMax_Video_Width1024//视频宽度#defineMax_Video_Height720//视频高度#defineMax_Video_FrameNum500//视频最大帧数//帧类型typedef enum e_FrameType{FrameType_Invalid_Frame=0,//无效帧FrameType_Header_Frame=0x68643030,//头帧('00hd')FrameType_Video_IFrame=0x62643030,//视频主帧('00db')FrameType_Video_VFrame=0x63643030,//视频虚帧('00dc')FrameType_Audio_Frame=0x62773030,//音频帧('00wb')}FrameType;//帧数据typedef struct tagFrameData{unsigned long long ullTimeStamp;//时间戳int nFrameType;//帧类型int nFrameDataLength;//帧数据长度int nDataBlock1StartPos;//数据块1开始位置(针对m_pBufferData)int nDataBlock1StopPos;//数据块1结束位置int nDataBlock2StartPos;//数据块2开始位置int nDataBlock2StopPos;//数据块2结束位置}FrameData;class CircleBuffer{public:CircleBuffer(void);virtual ~CircleBuffer(void);//初始化BOOL Init(int nTotalDataBufferLength,int nFrameSize=Max_Video_FrameNum);//反初始化void UnInit();//剩余可写空间(多少帧)int RemainWriteFrameNum();//剩余可读空间(多少帧)int RemainReadFrameNum();//获取获取buffer中帧的持续时间unsigned int GetBufferFrameTime();//重置帧void Reset();//重置帧(保留最后视频I帧之后的数据)void ResetToSaveVideoIFrame();//读取一帧数据int  ReadFrameData(int & nFrameType,unsigned char *pFrameData,int & nFrameDataLength);//写入一帧数据int  WriteFrameData(int nFrameType,unsigned char *pFrameData,int nFrameDataLength);static int iabs(int x);protected:FrameData * m_pAllFrameData;//FrameData指针int m_nFrameSize;//FrameData个数int m_nFrameReadPos;//FrameData写位置int m_nFrameWritePos;//FrameData读位置int m_nFrameEmptySize;//FrameData剩余大小unsigned char *m_pBufferData;//内存缓存区指针intm_nBufferSize;//内存缓存区大小int m_nBufferReadPos;//内存缓存区读位置int m_nBufferWritePos;//内存缓存区写位置int m_nBufferEmptySize;//内存缓存区剩余大小int m_nLastVideoIFramePos;//最后视频I帧索引int m_nLastAudioIFramePos;//最后音频帧索引boost::shared_mutexm_mutexFrameData;//资源列表控制锁};#endif

#include "stdafx.h"#include "CircleBuffer.h"#include <math.h>#include <boost/thread.hpp>#include <boost/function.hpp>typedef boost::shared_lock<boost::shared_mutex>boost_share_lock;typedef boost::unique_lock<boost::shared_mutex>boost_unique_lock;CircleBuffer::CircleBuffer(void){m_nFrameReadPos = 0;m_nFrameWritePos = 0;m_nFrameEmptySize = 0;m_pAllFrameData = NULL;m_pBufferData = NULL;m_nBufferReadPos = 0;m_nBufferWritePos = 0;m_nBufferEmptySize = 0;m_nLastVideoIFramePos = -1;m_nLastAudioIFramePos = -1;}CircleBuffer::~CircleBuffer(void){UnInit();}int CircleBuffer::iabs(int x){return x>0 ? x:-x;}//初始化BOOL CircleBuffer::Init(int nTotalDataBufferLength,int nFrameSize){if(m_pBufferData){delete []m_pBufferData;m_pBufferData = NULL;}m_pBufferData = new unsigned char[nTotalDataBufferLength];if(!m_pBufferData){return FALSE;}m_nBufferSize = nTotalDataBufferLength;m_nBufferEmptySize = nTotalDataBufferLength;m_nBufferReadPos = 0;m_nBufferWritePos = 0;m_nFrameSize = nFrameSize;m_nFrameEmptySize = m_nFrameSize;m_nFrameReadPos = 0;m_nFrameWritePos = 0;m_pAllFrameData = new FrameData[m_nFrameSize];for(int j=0; j<m_nFrameSize; j++){m_pAllFrameData[j].ullTimeStamp = 0;m_pAllFrameData[j].nFrameType = 0;m_pAllFrameData[j].nFrameDataLength = 0;m_pAllFrameData[j].nDataBlock1StartPos = 0;m_pAllFrameData[j].nDataBlock1StopPos = 0;m_pAllFrameData[j].nDataBlock2StartPos = 0;m_pAllFrameData[j].nDataBlock2StopPos = 0;}m_nLastVideoIFramePos = -1;m_nLastAudioIFramePos = -1;return TRUE;}//反初始化void CircleBuffer::UnInit(){if(m_pBufferData != NULL){delete []m_pBufferData;m_pBufferData = NULL;}if(m_pAllFrameData != NULL){delete [] m_pAllFrameData;m_pAllFrameData = NULL;}}//剩余可写空间(多少帧)int CircleBuffer::RemainWriteFrameNum(){boost_share_lock lockReader(m_mutexFrameData);return m_nFrameEmptySize;}//剩余可读空间(多少帧)int CircleBuffer::RemainReadFrameNum(){boost_share_lock lockReader(m_mutexFrameData);return m_nFrameSize - m_nFrameEmptySize;}unsigned int CircleBuffer::GetBufferFrameTime(){boost_share_lock lockReader(m_mutexFrameData);unsigned int uiDiffTime = 0;if(m_nFrameWritePos == m_nFrameReadPos){return 0;}else if(m_nFrameWritePos > m_nFrameReadPos){if(m_nFrameReadPos >0){uiDiffTime = m_pAllFrameData[m_nFrameWritePos-1].ullTimeStamp - m_pAllFrameData[m_nFrameReadPos-1].ullTimeStamp;}}else{if((m_nFrameWritePos-1) < 0){uiDiffTime = m_pAllFrameData[m_nFrameSize-1].ullTimeStamp - m_pAllFrameData[m_nFrameReadPos-1].ullTimeStamp;}else{uiDiffTime = m_pAllFrameData[m_nFrameWritePos-1].ullTimeStamp - m_pAllFrameData[m_nFrameReadPos-1].ullTimeStamp;}}return uiDiffTime;}//重置帧void CircleBuffer::Reset(){boost_unique_lock lockWriter(m_mutexFrameData);m_nFrameReadPos = m_nFrameWritePos = 0;m_nBufferReadPos = m_nBufferWritePos = 0;m_nBufferEmptySize = m_nBufferSize;m_nFrameEmptySize = m_nFrameSize; for(int j=0; j<m_nFrameSize; j++){m_pAllFrameData[j].ullTimeStamp = 0;m_pAllFrameData[j].nFrameType = 0;m_pAllFrameData[j].nFrameDataLength = 0;m_pAllFrameData[j].nDataBlock1StartPos = 0;m_pAllFrameData[j].nDataBlock1StopPos = 0;m_pAllFrameData[j].nDataBlock2StartPos = 0;m_pAllFrameData[j].nDataBlock2StopPos = 0;}m_nLastVideoIFramePos = -1;m_nLastAudioIFramePos = -1;}//重置帧(保留最后视频I帧之后的数据)void CircleBuffer::ResetToSaveVideoIFrame(){boost_unique_lock lockWriter(m_mutexFrameData);if(m_nLastVideoIFramePos != -1){int nFrameNumTmp = 0;m_nFrameReadPos = m_nLastVideoIFramePos;if(m_nLastVideoIFramePos > m_nFrameWritePos){nFrameNumTmp = m_nFrameWritePos + m_nFrameSize - m_nLastVideoIFramePos;}else{nFrameNumTmp = m_nFrameWritePos - m_nLastVideoIFramePos;}m_nFrameEmptySize = m_nFrameSize - nFrameNumTmp;}else{m_nFrameReadPos = m_nFrameWritePos = 0;m_nBufferReadPos = m_nBufferWritePos = 0;m_nBufferEmptySize = m_nBufferSize;m_nFrameEmptySize = m_nFrameSize; for(int j=0; j<m_nFrameSize; j++){m_pAllFrameData[j].ullTimeStamp = 0;m_pAllFrameData[j].nFrameType = 0;m_pAllFrameData[j].nFrameDataLength = 0;m_pAllFrameData[j].nDataBlock1StartPos = 0;m_pAllFrameData[j].nDataBlock1StopPos = 0;m_pAllFrameData[j].nDataBlock2StartPos = 0;m_pAllFrameData[j].nDataBlock2StopPos = 0;}m_nLastVideoIFramePos = -1;m_nLastAudioIFramePos = -1;}}//读取一帧数据int  CircleBuffer::ReadFrameData(int & nFrameType,unsigned char *pFrameData,int & nFrameDataLength){boost_unique_lock lockWriter(m_mutexFrameData);int nRemainFrameNum = 0;nRemainFrameNum = m_nFrameSize - m_nFrameEmptySize;if(nRemainFrameNum < 1){//没有数据帧,可读return -1;}if(nFrameDataLength < m_pAllFrameData[m_nFrameReadPos].nFrameDataLength){return -2;//数据缓冲区空间不够}nFrameType = m_pAllFrameData[m_nFrameReadPos].nFrameType;nFrameDataLength = m_pAllFrameData[m_nFrameReadPos].nFrameDataLength;int nLen1 = m_pAllFrameData[m_nFrameReadPos].nDataBlock1StopPos - m_pAllFrameData[m_nFrameReadPos].nDataBlock1StartPos;if(nLen1 != 0 && nLen1 == nFrameDataLength){memcpy(pFrameData,m_pBufferData+m_pAllFrameData[m_nFrameReadPos].nDataBlock1StartPos,nLen1);}else{int nLen2 = m_pAllFrameData[m_nFrameReadPos].nDataBlock2StopPos - m_pAllFrameData[m_nFrameReadPos].nDataBlock2StartPos;if(nLen2 != 0){memcpy(pFrameData,m_pBufferData+m_pAllFrameData[m_nFrameReadPos].nDataBlock1StartPos,nLen1);memcpy(pFrameData+nLen1,m_pBufferData,nLen2);}}if(m_pAllFrameData[m_nFrameReadPos].nDataBlock1StopPos == m_nBufferSize && m_pAllFrameData[m_nFrameReadPos].nDataBlock2StopPos != 0){m_nBufferReadPos = m_pAllFrameData[m_nFrameReadPos].nDataBlock2StopPos;}else{m_nBufferReadPos = m_pAllFrameData[m_nFrameReadPos].nDataBlock1StopPos;}m_nBufferEmptySize +=nFrameDataLength;if(m_nBufferEmptySize >= m_nBufferSize){m_nBufferEmptySize = m_nBufferSize;}if(m_nLastVideoIFramePos != -1 && m_nFrameReadPos == m_nLastVideoIFramePos){m_nLastVideoIFramePos = -1;}if(m_nLastAudioIFramePos != -1 && m_nFrameReadPos == m_nLastAudioIFramePos){m_nLastAudioIFramePos = -1;}m_nFrameReadPos++;if(m_nFrameReadPos >= m_nFrameSize){m_nFrameReadPos = 0;}m_nFrameEmptySize++;if(m_nFrameEmptySize >= m_nFrameSize){m_nFrameEmptySize = m_nFrameSize;}return 0;}//写入一帧数据int  CircleBuffer::WriteFrameData(int nFrameType,unsigned char *pFrameData,int nFrameDataLength){boost_unique_lock lockWriter(m_mutexFrameData);if(m_nFrameEmptySize < 1){//超过帧最大数,不可写入return -1;}if(m_nBufferEmptySize < nFrameDataLength){return -2;//数据缓冲区空间不够}memcpy((void *)&m_pAllFrameData[m_nFrameWritePos].ullTimeStamp,(void *)pFrameData,8);//时间戳m_pAllFrameData[m_nFrameWritePos].nFrameType = nFrameType;m_pAllFrameData[m_nFrameWritePos].nFrameDataLength = nFrameDataLength;if((m_nBufferSize - m_nBufferWritePos) >= nFrameDataLength){memcpy(m_pBufferData+m_nBufferWritePos,pFrameData,nFrameDataLength);m_pAllFrameData[m_nFrameWritePos].nDataBlock1StartPos = m_nBufferWritePos;m_pAllFrameData[m_nFrameWritePos].nDataBlock1StopPos = m_nBufferWritePos+nFrameDataLength;m_pAllFrameData[m_nFrameWritePos].nDataBlock2StartPos = 0;m_pAllFrameData[m_nFrameWritePos].nDataBlock2StopPos = 0;m_nBufferEmptySize -=nFrameDataLength;m_nBufferWritePos +=nFrameDataLength;}else{int len1 = m_nBufferSize - m_nBufferWritePos;int len2 = nFrameDataLength - len1;memcpy(m_pBufferData+m_nBufferWritePos,pFrameData,len1);memcpy(m_pBufferData,pFrameData,len2);m_pAllFrameData[m_nFrameWritePos].nDataBlock1StartPos = m_nBufferWritePos;m_pAllFrameData[m_nFrameWritePos].nDataBlock1StopPos = m_nBufferWritePos+len1;m_pAllFrameData[m_nFrameWritePos].nDataBlock2StartPos = 0;m_pAllFrameData[m_nFrameWritePos].nDataBlock2StopPos = len2;m_nBufferEmptySize -=nFrameDataLength;m_nBufferWritePos = len2;}//记录最后音频,视频帧if(nFrameType == FrameType_Video_IFrame){m_nLastVideoIFramePos = m_nFrameWritePos;}else if(nFrameType == FrameType_Audio_Frame){m_nLastAudioIFramePos = m_nFrameWritePos;}m_nFrameWritePos++;if(m_nFrameWritePos >= m_nFrameSize){m_nFrameWritePos = 0;}m_nFrameEmptySize--;if(m_nFrameEmptySize <= 0){m_nFrameEmptySize = 0;}if(m_nBufferEmptySize <= 0){m_nBufferEmptySize = 0;}return 0;}

0 0