《一个简易的数据帧缓冲队列 (一)》
《数据帧缓冲队列(继上一篇的简单队列,改进)(二)》
《数据帧缓冲队列(改进,数据可视化)(三)》
需要将连续的实时帧数据进行缓存,由于每个帧数据的长度不定,就没有使用大结构体的生产者消费者模式实现,而是动态的申请内存。此代码频繁申请释放内存可能存在效率问题,作为一个队列的使用例子。
//#include "queue.h"
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include <pthread.h>
typedef unsigned char uint8_t; //无符号8位数
typedef struct _H264_FRAME_BUFF_
{
uint8_t *buffer;
int len;
struct _H264_FRAME_BUFF_* next;
struct _H264_FRAME_BUFF_* pre;
}H264_FRAME_BUFFER;
class CQueue
{
public:
CQueue(int maxlen);
~CQueue();
int pop(uint8_t *data,int *len);
int push(uint8_t *data,int len);
private:
int mMaxlen;
int mCurlen;
H264_FRAME_BUFFER *mHead;
H264_FRAME_BUFFER *mTail;
pthread_mutex_t mlock;
};
#define DebugBlue(fmt,args...) do {printf("\033[1;34;40m [%s,%s,%d]",__FILE__,__FUNCTION__,__LINE__);printf(fmt,##args);printf("\033[0m");} while(0)
CQueue::CQueue(int maxlen)
{
mMaxlen = maxlen;
mCurlen = 0;
mHead = NULL;
mTail = NULL;
pthread_mutex_init(&mlock, NULL);
}
CQueue::~CQueue()
{
//释放掉全部数据
while(mHead)
{
pop(NULL,NULL);
}
}
int CQueue::pop(uint8_t *data,int *len)
{
pthread_mutex_lock(&mlock);
if(mTail == NULL)
{
pthread_mutex_unlock(&mlock);
return -1;
}
H264_FRAME_BUFFER *delBuffer = mTail;
mTail = delBuffer->pre;
if(mTail)
{
mTail->next = NULL;
}
else
{//已经取空
mHead = mTail;
}
if(data)
{
//printf("*len %d delbufferlen %d \n",*len,delBuffer->len);
int copylen = (delBuffer->len < *len)?(delBuffer->len):(*len);
if(*len < delBuffer->len)
{
DebugBlue("[%d %s] buffer too short,delBuffer->len %d *len %d !\n",__LINE__,__FUNCTION__,delBuffer->len,*len);
}
//printf("get data :%s copylen %d \n",delBuffer->buffer,copylen);
memcpy(data,delBuffer->buffer,copylen);
*len = copylen;
}
free(delBuffer->buffer);
free(delBuffer);
mCurlen --;
pthread_mutex_unlock(&mlock);
return 0;
}
int CQueue::push(uint8_t *data,int len)
{
if(NULL == data)
{
return -2;
}
if(mCurlen >= mMaxlen)
{
//覆盖老数据
pop(NULL,NULL);
DebugBlue("wangcover \n");
//return -1;
}
///新数据
int ret =0;
pthread_mutex_lock(&mlock);
H264_FRAME_BUFFER *newbuf =(H264_FRAME_BUFFER *)malloc(sizeof(H264_FRAME_BUFFER));
if(newbuf == NULL)
{
DebugBlue("erro to malloc!\n");
ret = -1;
goto erro;
}
newbuf->buffer = (uint8_t*)malloc(len);
newbuf->len = len;
if(newbuf == NULL)
{
DebugBlue("erro to malloc,malloc len: %d !\n",len);
ret = -1;
goto erro;
}
memcpy(newbuf->buffer,data,len);
///头插
newbuf->pre = NULL;
newbuf->next = mHead;
if(mHead == NULL)
{
mTail = newbuf;
}
else
{
mHead->pre = newbuf;
}
mHead = newbuf;
mCurlen ++;
//DebugBlue("wangpushdat len %d : %d %s\n",len,__LINE__,__FUNCTION__);
erro:
pthread_mutex_unlock(&mlock);
return ret;
}
#if 1
int main()
{
CQueue * pQueue = new CQueue(3);
uint8_t buf1[128]="11111";
uint8_t buf2[128]="22222";
uint8_t buf3[128]="33333";
uint8_t buf4[128]="44444";
uint8_t buf5[128]="55555";
uint8_t bufget[128]={0};
pQueue->push(buf1,sizeof(buf1));
pQueue->push(buf2,sizeof(buf2));
pQueue->push(buf3,sizeof(buf3));
pQueue->push(buf4,sizeof(buf4));
pQueue->push(buf5,sizeof(buf5));
int len = sizeof(bufget);
pQueue->pop(bufget,&len);
printf("wang bufget :%s \n",bufget);
pQueue->pop(bufget,&len);
printf("wang bufget :%s \n",bufget);
pQueue->pop(bufget,&len);
printf("wang bufget :%s \n",bufget);
pQueue->pop(bufget,&len);
printf("wang bufget :%s \n",bufget);
pQueue->pop(bufget,&len);
printf("wang bufget :%s \n",bufget);
pQueue->push(buf1,sizeof(buf1));
len = sizeof(bufget);
pQueue->pop(bufget,&len);
printf("wang bufget :%s \n",bufget);
delete pQueue;
return 0;
}
#endif