一个简易的数据帧缓冲队列 (一)

4 篇文章 0 订阅
3 篇文章 0 订阅

一个简易的数据帧缓冲队列 (一)
数据帧缓冲队列(继上一篇的简单队列,改进)(二)
数据帧缓冲队列(改进,数据可视化)(三)
需要将连续的实时帧数据进行缓存,由于每个帧数据的长度不定,就没有使用大结构体的生产者消费者模式实现,而是动态的申请内存。此代码频繁申请释放内存可能存在效率问题,作为一个队列的使用例子。

//#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

 

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值