c、c++实现环形数据缓存区(视频帧数据为例)

缓存区初始化

/**
 * buffer_init
 * 环形缓存去初始化接口
 * BUFFER_SIZE 缓存区大小
 * 
*/
void buffer_init()
{
    AVPACKETQ_BUFFER_P *buffer_pool =(AVPACKETQ_BUFFER_P*) calloc(1, sizeof(AVPACKETQ_BUFFER_P));
    buffer_pool->recorder_buffer = (uint8_t *)malloc(BUFFER_SIZE);
    buffer_pool->avpacket_list = new AVPACKET_LIST();
    buffer_pool->r_flag = true;
    buffer_pool->deq_data = (uint8_t* )malloc(AVPAKCET_BUFFER_SIZE);
    buffer_pool->recorder_buffer_list = new std::queue<recorder_buffer_data>;
}

数据接收区

/**
 * record_buffer_set_data_thread_proc
 * 数据无延时进队列,防止函数做耗时操作导致数据丢失
 * 适用于数据不可丢,且传输速度快的场景
*/

static void* record_buffer_set_data_thread_proc(void *argv)
{ 
    AVPACKETQ_BUFFER_P *buffer_p = (AVPACKETQ_BUFFER_P*)argv;
    if(!buffer_p) 
    {
        fprintf(stderr, " avpacket buffer is NULL\n");
        return NULL;
    }
    if(!buffer_p->avpacketq || !buffer_p->recorder_buffer) 
    {
        fprintf(stderr, " avpacket or recorder buffer is NULL\n");
        return NULL;
    }
    avpacket_info_t avpacket_info;
    recorder_buffer_data buffer_data;
    std::queue<recorder_buffer_data> recorder_buffer_list;
    static int pFrameCount = 0;
    while(buffer_p->r_flag)
    {
        avpacket_info.data = buffer_p->deq_data;
        avpacket_info.data_len = AVPAKCET_BUFFER_SIZE;
        buffer_data.iframe = avpacket_info.iframe;
        buffer_data.data_len = avpacket_info.data_len;
        buffer_data.pts = avpacket_info.ts;
        buffer_data.sn = avpacket_info.sn;
        memcpy(buffer_data.data, avpacket_info.data, packet_size);
        buffer_p->data_list_mutex.lock();
        buffer_p->recorder_buffer_list->push(buffer_data);
        buffer_p->data_list_mutex.unlock();
    }
    
}

数据存入环形缓存区业务处理函数

/**
 * record_buffer_get_data_thread_proc
 * 数据存入环形缓存区业务处理函数
 *
*/
static void* record_buffer_get_data_thread_proc(void *argv)   //数据进缓存区
{
    AVPACKETQ_BUFFER_P *buffer_p = (AVPACKETQ_BUFFER_P*)argv;
    if(!buffer_p) 
    {
        fprintf(stderr, " avpacket buffer is NULL\n");
        return NULL;
    }
    if(!buffer_p->avpacketq || !buffer_p->recorder_buffer) 
    {
        fprintf(stderr, " avpacket or recorder buffer is NULL\n");
        return NULL;
    }
    recorder_buffer_info_t buffer_info_t;
    unsigned long long Count_size = BUFFER_SIZE;
    while(buffer_p->r_flag)
    {
        if(buffer_p->recorder_buffer_list->empty())
        {
            usleep(100);
            continue;
        }
  
        recorder_buffer_data buffer_data_t;
        buffer_p->data_list_mutex.lock();
        buffer_data_t = buffer_p->recorder_buffer_list->front();
        buffer_p->data_list_mutex.unlock();
        buffer_info_t.iframe = buffer_data_t.iframe;
        buffer_info_t.data_len = buffer_data_t.data_len;
        buffer_info_t.pts = buffer_data_t.pts;
        buffer_info_t.sn = buffer_data_t.sn;

        if(buffer_p->avpacket_list->empty())   //判断数据缓冲区是否为空
        {
            memcpy(buffer_p->recorder_buffer, buffer_data_t.data, buffer_data_t.data_len);
            buffer_info_t.data = buffer_p->recorder_buffer ;
            buffer_p->avpacket_list->push_back(buffer_info_t);
            Count_size -=  buffer_data_t.data_len;

        }else 
        {
            recorder_buffer_info_t buffer_front = buffer_p->avpacket_list->at(1);
            if(buffer_front.data_len == -1) 
            {
                fprintf(stderr, " %s 头数据为空   %d   %d\n",buffer_p->avpacketq->name, buffer_p->avpacket_list->empty(), buffer_p->avpacket_list->size());
                buffer_p->avpacket_list->pop_front();
                continue;
            }
            recorder_buffer_info_t buffer_back = buffer_p->avpacket_list->at(buffer_p->avpacket_list->size());
            if(buffer_back.data_len == -1) 
            {
                fprintf(stderr, " %s 尾数据为空  size:%d\n",buffer_p->avpacketq->name, buffer_p->avpacket_list->size());
                buffer_p->avpacket_list->pop_back();
                continue;
            }

            // 顺序存储
            if(buffer_back.data - buffer_front.data >= 0)
            {

                if(BUFFER_SIZE - (buffer_back.data + buffer_back.data_len - buffer_p->recorder_buffer) >=  buffer_data_t.data_len) //无需覆盖
                {
                    memcpy(buffer_back.data + buffer_back.data_len, buffer_data_t.data, buffer_data_t.data_len);
                    buffer_info_t.data = buffer_back.data + buffer_back.data_len ;
                    buffer_p->avpacket_list->push_back(buffer_info_t);
                    Count_size -=  buffer_data_t.data_len;
                }
                else //存储满,重头来
                {
                    /*  
                        循环出队,直到I帧之前可以放入新的数据帧
                    */
                    while(buffer_p->r_flag)
                    {
                        recorder_buffer_info_t buffer_temp = buffer_p->avpacket_list->at(1);
                        if(buffer_temp.data_len == -1) 
                        {
                            fprintf(stderr, " [%s]1 buffer_temp data is Null %d   %d\n", buffer_p->avpacketq->name, buffer_p->avpacket_list->empty(), buffer_p->avpacket_list->size());
                            if(buffer_p->avpacket_list->empty())
                                break;
                            buffer_p->avpacket_list->pop_front();
                            continue;
                        }
                        if(buffer_temp.iframe)
                        {
                            //    fprintf(stderr, " channl:%s  data size :%d   pts:%llu   list size:%d  buffer_temp data:%p  buffer_back:%p  bufferpool:%p  Count_size:%llu\n", buffer_p->avpacketq->name, packet_size, avpacket_info.ts, buffer_p->avpacket_list->size(),  buffer_p->avpacket_list->at(1).data, buffer_p->avpacket_list->at(buffer_p->avpacket_list->size()).data + buffer_p->avpacket_list->at(buffer_p->avpacket_list->size()).data_len, buffer_p->recorder_buffer, Count_size);
                            if((buffer_temp.data - buffer_back.data < 0) &&  (buffer_temp.data - buffer_p->recorder_buffer >=  buffer_data_t.data_len))
                            {
                                memcpy(buffer_p->recorder_buffer,buffer_data_t.data, buffer_data_t.data_len);
                                buffer_info_t.data = buffer_p->recorder_buffer ;
                                buffer_p->avpacket_list->push_back(buffer_info_t);
                                Count_size -=  buffer_data_t.data_len;
                                break;
                            }
                  
                        }
                        buffer_p->avpacket_list->pop_front();
                        Count_size += buffer_temp.data_len;
                    }    
                }

            }else //覆盖存储
            {
                if(buffer_front.data - (buffer_back.data + buffer_back.data_len) >=  buffer_data_t.data_len)  //判断中间剩余空间是否足够本帧数据存储
                {
                    memcpy(buffer_back.data + buffer_back.data_len, buffer_data_t.data, buffer_data_t.data_len);
                    buffer_info_t.data = buffer_back.data + buffer_back.data_len;
                    buffer_p->avpacket_list->push_back(buffer_info_t);
                    Count_size -=  buffer_data_t.data_len;
                }else
                {
                    while(buffer_p->r_flag)
                    {
                        int sum_size = 0;
                        recorder_buffer_info_t buffer_temp = buffer_p->avpacket_list->at(1);

                        if(buffer_temp.data_len == -1) 
                        {
                            
                            fprintf(stderr, " [%s]2 buffer_temp data is Null %d   %d   next:%d\n", buffer_p->avpacketq->name, buffer_p->avpacket_list->empty(), buffer_p->avpacket_list->size(), buffer_p->avpacket_list->at(2).data_len);
                            if(buffer_p->avpacket_list->empty())
                                break;
                            buffer_p->avpacket_list->pop_front();
                            Count_size += buffer_temp.data_len;
                            continue;
                        }
                        /*  
                           找到缓冲数据区 顺序路径 最后一个数据 
                           判断是否是I帧
                             是:I帧之前是否够新的数据帧 
                             不是I帧或不够新的数据帧插入,出队

                        */
                        sum_size += buffer_temp.data_len;
                        if(buffer_temp.data - buffer_p->avpacket_list->at(2).data < 0)
                        {
                            if(buffer_temp.iframe)
                            {
                                if(buffer_temp.data - (buffer_back.data + buffer_back.data_len) >=  buffer_data_t.data_len)
                                {
                                    memcpy(buffer_back.data + buffer_back.data_len, buffer_data_t.data, buffer_data_t.data_len);
                                    buffer_info_t.data = buffer_back.data + buffer_back.data_len ;
                                    buffer_p->avpacket_list->push_back(buffer_info_t);
                                    Count_size -=  buffer_data_t.data_len;
                                    break;
                                }
                            }

                        }else
                        {
                            /*  
                                缓冲区 数据队尾直到最后 不够新的数据帧插入;即 重头存储
                                1、是否I帧
                                    I帧之前是否够新的数据帧 
                                    不是I帧或不够新的数据帧插入,出队
                                2、队尾数据直到最后 是否足够新的数据帧插入
                                    够,插入新的数据帧, 并出队直至I帧
                                    不够,出队直至I帧,判断I帧之前是否够新的数据插入

                            */
                            
                            if(buffer_temp.iframe)
                            {
                                if(buffer_temp.data - (buffer_back.data + buffer_back.data_len) >=  buffer_data_t.data_len)
                                {
                                    memcpy(buffer_back.data + buffer_back.data_len, buffer_data_t.data, buffer_data_t.data_len);
                                    buffer_info_t.data = buffer_back.data + buffer_back.data_len ;
                                    buffer_p->avpacket_list->push_back(buffer_info_t);
                                    Count_size -=  buffer_data_t.data_len;
                                    break;
                                }
                            }
                            if((BUFFER_SIZE - (buffer_back.data + buffer_back.data_len - buffer_p->recorder_buffer)) >=  buffer_data_t.data_len)
                            {
                                memcpy(buffer_back.data + buffer_back.data_len, buffer_data_t.data, buffer_data_t.data_len);
                                buffer_info_t.data = buffer_back.data + buffer_back.data_len ;
                                buffer_p->avpacket_list->push_back(buffer_info_t);
                                Count_size -=  buffer_data_t.data_len;
                                while(buffer_p->r_flag)
                                {
                                    buffer_p->avpacket_list->pop_front();
                                    buffer_temp = buffer_p->avpacket_list->at(1);
                                    Count_size += buffer_temp.data_len;
                                    if(buffer_temp.iframe)
                                    {
                                        break;
                                    }
                                }
                                break;  
                            }else
                            {
                                while(buffer_p->r_flag)
                                {
                                    buffer_p->avpacket_list->pop_front();
                                    buffer_temp = buffer_p->avpacket_list->at(1);
                                    if(buffer_temp.iframe)
                                    {
                                        if(buffer_temp.data - buffer_p->recorder_buffer >=  buffer_data_t.data_len)
                                        {
                                            memcpy(buffer_p->recorder_buffer, buffer_data_t.data, buffer_data_t.data_len);
                                            buffer_info_t.data = buffer_p->recorder_buffer ;
                                            buffer_p->avpacket_list->push_back(buffer_info_t);
                                            Count_size -=  buffer_data_t.data_len;
                                            break;
                                        }
                                        
                                    }
                                }
                                break;
                            }
                            
                        }
                        Count_size += buffer_temp.data_len;
                        buffer_p->avpacket_list->pop_front();
                        }  
                
                }
            }
        }
        buffer_p->data_list_mutex.lock();
        buffer_p->recorder_buffer_list->pop();
        buffer_p->data_list_mutex.unlock(); 
    }
   return NULL;
}

完整代码

1、avpack_list.cpp

#include <iostream>
#include "avpack_list.h"
// //链表节点结构体 
// typedef struct stData
// {
//     recorder_buffer_info_t data;
//     struct stData *pNext;
// }stData;


// static AVPACKET_LIST *avpacket_list;
AVPACKET_LIST::AVPACKET_LIST()
{
    buffer_null.data = NULL;
    buffer_null.data_len = -1;
	buffer_null.sn = 0;
	buffer_null.pts = 0;
    this->head = new Node;    //给头结点指针实例化一个结点
	this->head->data = buffer_null;   //头结点数据,头结点一般不存放数据
	this->head->next = this->head;  //头结点指针指向自己
	this->counter = 0;        //未插入数据前,元素个数为0

}

AVPACKET_LIST::~AVPACKET_LIST()
{
    if (this->counter == 0)
	{
		delete head;
	}
	else
	{
		Node* temp = this->head->next;
		Node* temp2 = NULL;
 
 
		while (temp != this->head)
		{
			temp2 = temp->next;
			delete temp;
			temp = temp2;
		}
		delete temp;
	}
}
//判断链表是否为空,为空返回1,不为空返回0
bool AVPACKET_LIST::empty()
{
    std::lock_guard<std::mutex> lock(list_mtx);
	if (this->head->next == this->head || this->head == NULL)//(头结点不算做链表中的元素,因此在此若只有头结点也算空链表)
	{
		return true;
	}
	else
	{
		return false;
	}
}
//返回链表元素个数
int AVPACKET_LIST::size()
{
    std::lock_guard<std::mutex> lock(list_mtx);
	return this->counter;
}
//打印遍历整个链表
void AVPACKET_LIST::traverse()
{
    std::lock_guard<std::mutex> lock(list_mtx);
	Node* temp = this->head->next;//创建一个结点指针遍历每个结点
	while (temp != this->head)
	{
		// cout << temp->data << " ";
		temp = temp->next;
	}
	// cout << endl;
}
//清空链表
void AVPACKET_LIST::clear()
{
    std::lock_guard<std::mutex> lock(list_mtx);
	if (this->counter == 0)
	{
		return;
	}
	Node* temp = this->head->next;
	Node* temp2 = NULL;
 
	while (temp != this->head)
	{
		temp2 = temp->next;
		delete temp;
		temp = temp2;
	}
	this->head->next = head;
	this->counter = 0;
}
//头插
void AVPACKET_LIST::push_front(recorder_buffer_info_t newelem)
{
    std::lock_guard<std::mutex> lock(list_mtx);
	if (this->head == NULL)
	{
		return;
	}
	Node* newnode = new Node;
	newnode->data = newelem;
	newnode->next = this->head->next;
	this->head->next = newnode;
	this->counter = this->counter + 1;//元素个数加一
}
//尾插
void AVPACKET_LIST::push_back(recorder_buffer_info_t newelem)
{
    std::lock_guard<std::mutex> lock(list_mtx);
	if (this->head == NULL)
	{
		return;
	}
	Node* newnode = new Node;
	Node* temp = head;
	newnode->data = newelem;
	newnode->next = this->head;
	for (int i = 0; i < this->counter; i++)
	{
		temp = temp->next;
	}
	temp->next = newnode;
	this->counter = this->counter + 1;//元素个数加一
}
//头删
void AVPACKET_LIST::pop_front()
{
    std::lock_guard<std::mutex> lock(list_mtx);
	if (this->head == NULL || this->counter == 0)
	{
		return;
	}
	Node* temp;
	temp = this->head->next;
	this->head->next = temp->next;
	delete temp;
	this->counter = this->counter - 1;//元素个数减一
}
//尾删
void AVPACKET_LIST::pop_back()
{
    std::lock_guard<std::mutex> lock(list_mtx);
	if (this->head == NULL || this->counter == 0)
	{
		return;
	}
	Node* temp = this->head;
	Node* temp2;
	for (int i = 1; i < this->counter; i++)
	{
		temp = temp->next;
	}
	temp2 = temp->next;
	temp->next = this->head;
	delete temp2;
	this->counter = this->counter - 1;//元素个数减一
}
//任意位置插入
void AVPACKET_LIST::insert(int pos, recorder_buffer_info_t newelem)
{
    std::lock_guard<std::mutex> lock(list_mtx);
	if (this->head == NULL || pos > this->counter)
	{
		return;
	}
	Node* newnode = new Node;
	Node* temp = head;
	newnode->data = newelem;
	for (int i = 1; i < pos; i++)
	{
		temp = temp->next;
 
	}
	newnode->next = temp->next;
	temp->next = newnode;
	this->counter = this->counter + 1;//元素个数加一
}
//任意位置删除
void AVPACKET_LIST::erase(int pos)
{
    std::lock_guard<std::mutex> lock(list_mtx);
	if (this->head == NULL || pos > this->counter)
	{
		return;
	}
	Node* temp = this->head;
	Node* temp2;
	for (int i = 1; i < pos; i++)
	{
		temp = temp->next;
	}
	temp2 = temp->next;
	temp->next = temp2->next;
	delete temp2;
	this->counter = this->counter - 1;//元素个数减一
}
//返回索引位置数据
recorder_buffer_info_t AVPACKET_LIST::at(int pos)
{
    std::lock_guard<std::mutex> lock(list_mtx);
	if (this->head == NULL || pos > this->counter)
	{
		return buffer_null;
	}
	Node* temp = head;
	for (int i = 0; i < pos; i++)
	{
		temp = temp->next;
	}
	return temp->data;
}
//重载[],返回索引位置数据
recorder_buffer_info_t AVPACKET_LIST::operator[](int pos)
{
    std::lock_guard<std::mutex> lock(list_mtx);
	if (this->head == NULL || pos > this->counter)
	{
		return buffer_null;
	}
	Node* temp = head;
	for (int i = 0; i < pos; i++)
	{
		temp = temp->next;
	}
	return temp->data;
}

2、avpack_list.h

#ifndef __AVPACK_LIST_H__
#define __AVPACK_LIST_H__
#include <mutex>

typedef struct recorder_buffer_info {
	uint8_t *data;  // 数据存储区
	int data_len;   // 数据长度
	int iframe;   // 贞的类别,是否为 I 贞, 1 表示当前包是 I 贞, 0 则不是
    unsigned long long pts; // 时间戳:单位 微妙
    unsigned long long sn; // 序列码
} recorder_buffer_info_t;


//创建结点类
class Node
{
public:
	recorder_buffer_info_t data; //结点中的数据域
	Node* next;    //结点中的指针域,结点类型的指针
};

class AVPACKET_LIST
{
    public:
        AVPACKET_LIST();
        ~AVPACKET_LIST();
        bool empty();//判断链表是否为空,为空返回1,不为空返回0
        int size();//返回链表元素个数
        void traverse();//打印遍历整个链表
        void clear();//清空链表
        void push_front(recorder_buffer_info_t);//头插
        void push_back(recorder_buffer_info_t);//尾插
        void pop_front();//头删
        void pop_back();//尾删
        void insert(int, recorder_buffer_info_t);//任意位置插入
        void erase(int);//删除任意位置元素
        recorder_buffer_info_t at(int);//返回索引位置数据
        recorder_buffer_info_t operator[](int);//重载[],返回索引位置数据
    
        int counter;//链表元素个数
        Node* head;//创建头结点指针,结点类型指针,当前未赋值
    private:
        std::mutex list_mtx;
        recorder_buffer_info_t buffer_null;
        
};

#endif

3、业务

#include "avpack_list.h"

typedef struct _recorder_buffer_info {
	uint8_t data[1024*1024];  // 数据存储区
	int data_len;   // 数据长度
	int iframe;   // 贞的类别,是否为 I 贞, 1 表示当前包是 I 贞, 0 则不是
    unsigned long long pts; // 时间戳:单位 微妙
    unsigned long long sn; // 序列码
} recorder_buffer_data;

typedef struct _AVPACKETQ_BUFFER_P{

    bool r_flag = false;
    pthread_t pthread;
    pthread_t pthread_set_data;

    avpacketq_t *avpacketq;

    pthread_mutex_t mtx_lock;
    uint8_t *recorder_buffer;
    AVPACKET_LIST *avpacket_list;
    uint8_t * deq_data;
    std::mutex data_list_mutex;
    std::queue<recorder_buffer_data>* recorder_buffer_list ;
} AVPACKETQ_BUFFER_P;


/**
 * buffer_init
 * 环形缓存去初始化接口
 * BUFFER_SIZE 缓存区大小
 * 
*/
void buffer_init()
{
    AVPACKETQ_BUFFER_P *buffer_pool =(AVPACKETQ_BUFFER_P*) calloc(1, sizeof(AVPACKETQ_BUFFER_P));
    buffer_pool->recorder_buffer = (uint8_t *)malloc(BUFFER_SIZE);
    buffer_pool->avpacket_list = new AVPACKET_LIST();
    buffer_pool->r_flag = true;
    buffer_pool->deq_data = (uint8_t* )malloc(AVPAKCET_BUFFER_SIZE);
    buffer_pool->recorder_buffer_list = new std::queue<recorder_buffer_data>;
}

/**
 * record_buffer_set_data_thread_proc
 * 数据无延时进队列,防止函数做耗时操作导致数据丢失
 * 适用于数据不可丢,且传输速度快的场景
*/

static void* record_buffer_set_data_thread_proc(void *argv)
{ 
    AVPACKETQ_BUFFER_P *buffer_p = (AVPACKETQ_BUFFER_P*)argv;
    if(!buffer_p) 
    {
        fprintf(stderr, " avpacket buffer is NULL\n");
        return NULL;
    }
    if(!buffer_p->avpacketq || !buffer_p->recorder_buffer) 
    {
        fprintf(stderr, " avpacket or recorder buffer is NULL\n");
        return NULL;
    }
    avpacket_info_t avpacket_info;
    recorder_buffer_data buffer_data;
    std::queue<recorder_buffer_data> recorder_buffer_list;
    static int pFrameCount = 0;
    while(buffer_p->r_flag)
    {
        avpacket_info.data = buffer_p->deq_data;
        avpacket_info.data_len = AVPAKCET_BUFFER_SIZE;
        buffer_data.iframe = avpacket_info.iframe;
        buffer_data.data_len = avpacket_info.data_len;
        buffer_data.pts = avpacket_info.ts;
        buffer_data.sn = avpacket_info.sn;
        memcpy(buffer_data.data, avpacket_info.data, packet_size);
        buffer_p->data_list_mutex.lock();
        buffer_p->recorder_buffer_list->push(buffer_data);
        buffer_p->data_list_mutex.unlock();
    }
    
}
/**
 * record_buffer_get_data_thread_proc
 * 数据存入环形缓存区业务处理函数
 *
*/
static void* record_buffer_get_data_thread_proc(void *argv)   //数据进缓存区
{
    AVPACKETQ_BUFFER_P *buffer_p = (AVPACKETQ_BUFFER_P*)argv;
    if(!buffer_p) 
    {
        fprintf(stderr, " avpacket buffer is NULL\n");
        return NULL;
    }
    if(!buffer_p->avpacketq || !buffer_p->recorder_buffer) 
    {
        fprintf(stderr, " avpacket or recorder buffer is NULL\n");
        return NULL;
    }
    recorder_buffer_info_t buffer_info_t;
    unsigned long long Count_size = BUFFER_SIZE;
    while(buffer_p->r_flag)
    {
        if(buffer_p->recorder_buffer_list->empty())
        {
            usleep(100);
            continue;
        }
  
        recorder_buffer_data buffer_data_t;
        buffer_p->data_list_mutex.lock();
        buffer_data_t = buffer_p->recorder_buffer_list->front();
        buffer_p->data_list_mutex.unlock();
        buffer_info_t.iframe = buffer_data_t.iframe;
        buffer_info_t.data_len = buffer_data_t.data_len;
        buffer_info_t.pts = buffer_data_t.pts;
        buffer_info_t.sn = buffer_data_t.sn;

        if(buffer_p->avpacket_list->empty())   //判断数据缓冲区是否为空
        {
            memcpy(buffer_p->recorder_buffer, buffer_data_t.data, buffer_data_t.data_len);
            buffer_info_t.data = buffer_p->recorder_buffer ;
            buffer_p->avpacket_list->push_back(buffer_info_t);
            Count_size -=  buffer_data_t.data_len;

        }else 
        {
            recorder_buffer_info_t buffer_front = buffer_p->avpacket_list->at(1);
            if(buffer_front.data_len == -1) 
            {
                fprintf(stderr, " %s 头数据为空   %d   %d\n",buffer_p->avpacketq->name, buffer_p->avpacket_list->empty(), buffer_p->avpacket_list->size());
                buffer_p->avpacket_list->pop_front();
                continue;
            }
            recorder_buffer_info_t buffer_back = buffer_p->avpacket_list->at(buffer_p->avpacket_list->size());
            if(buffer_back.data_len == -1) 
            {
                fprintf(stderr, " %s 尾数据为空  size:%d\n",buffer_p->avpacketq->name, buffer_p->avpacket_list->size());
                buffer_p->avpacket_list->pop_back();
                continue;
            }

            // 顺序存储
            if(buffer_back.data - buffer_front.data >= 0)
            {

                if(BUFFER_SIZE - (buffer_back.data + buffer_back.data_len - buffer_p->recorder_buffer) >=  buffer_data_t.data_len) //无需覆盖
                {
                    memcpy(buffer_back.data + buffer_back.data_len, buffer_data_t.data, buffer_data_t.data_len);
                    buffer_info_t.data = buffer_back.data + buffer_back.data_len ;
                    buffer_p->avpacket_list->push_back(buffer_info_t);
                    Count_size -=  buffer_data_t.data_len;
                }
                else //存储满,重头来
                {
                    /*  
                        循环出队,直到I帧之前可以放入新的数据帧
                    */
                    while(buffer_p->r_flag)
                    {
                        recorder_buffer_info_t buffer_temp = buffer_p->avpacket_list->at(1);
                        if(buffer_temp.data_len == -1) 
                        {
                            fprintf(stderr, " [%s]1 buffer_temp data is Null %d   %d\n", buffer_p->avpacketq->name, buffer_p->avpacket_list->empty(), buffer_p->avpacket_list->size());
                            if(buffer_p->avpacket_list->empty())
                                break;
                            buffer_p->avpacket_list->pop_front();
                            continue;
                        }
                        if(buffer_temp.iframe)
                        {
                            //    fprintf(stderr, " channl:%s  data size :%d   pts:%llu   list size:%d  buffer_temp data:%p  buffer_back:%p  bufferpool:%p  Count_size:%llu\n", buffer_p->avpacketq->name, packet_size, avpacket_info.ts, buffer_p->avpacket_list->size(),  buffer_p->avpacket_list->at(1).data, buffer_p->avpacket_list->at(buffer_p->avpacket_list->size()).data + buffer_p->avpacket_list->at(buffer_p->avpacket_list->size()).data_len, buffer_p->recorder_buffer, Count_size);
                            if((buffer_temp.data - buffer_back.data < 0) &&  (buffer_temp.data - buffer_p->recorder_buffer >=  buffer_data_t.data_len))
                            {
                                memcpy(buffer_p->recorder_buffer,buffer_data_t.data, buffer_data_t.data_len);
                                buffer_info_t.data = buffer_p->recorder_buffer ;
                                buffer_p->avpacket_list->push_back(buffer_info_t);
                                Count_size -=  buffer_data_t.data_len;
                                break;
                            }
                  
                        }
                        buffer_p->avpacket_list->pop_front();
                        Count_size += buffer_temp.data_len;
                    }    
                }

            }else //覆盖存储
            {
                if(buffer_front.data - (buffer_back.data + buffer_back.data_len) >=  buffer_data_t.data_len)  //判断中间剩余空间是否足够本帧数据存储
                {
                    memcpy(buffer_back.data + buffer_back.data_len, buffer_data_t.data, buffer_data_t.data_len);
                    buffer_info_t.data = buffer_back.data + buffer_back.data_len;
                    buffer_p->avpacket_list->push_back(buffer_info_t);
                    Count_size -=  buffer_data_t.data_len;
                }else
                {
                    while(buffer_p->r_flag)
                    {
                        int sum_size = 0;
                        recorder_buffer_info_t buffer_temp = buffer_p->avpacket_list->at(1);

                        if(buffer_temp.data_len == -1) 
                        {
                            
                            fprintf(stderr, " [%s]2 buffer_temp data is Null %d   %d   next:%d\n", buffer_p->avpacketq->name, buffer_p->avpacket_list->empty(), buffer_p->avpacket_list->size(), buffer_p->avpacket_list->at(2).data_len);
                            if(buffer_p->avpacket_list->empty())
                                break;
                            buffer_p->avpacket_list->pop_front();
                            Count_size += buffer_temp.data_len;
                            continue;
                        }
                        /*  
                           找到缓冲数据区 顺序路径 最后一个数据 
                           判断是否是I帧
                             是:I帧之前是否够新的数据帧 
                             不是I帧或不够新的数据帧插入,出队

                        */
                        sum_size += buffer_temp.data_len;
                        if(buffer_temp.data - buffer_p->avpacket_list->at(2).data < 0)
                        {
                            if(buffer_temp.iframe)
                            {
                                if(buffer_temp.data - (buffer_back.data + buffer_back.data_len) >=  buffer_data_t.data_len)
                                {
                                    memcpy(buffer_back.data + buffer_back.data_len, buffer_data_t.data, buffer_data_t.data_len);
                                    buffer_info_t.data = buffer_back.data + buffer_back.data_len ;
                                    buffer_p->avpacket_list->push_back(buffer_info_t);
                                    Count_size -=  buffer_data_t.data_len;
                                    break;
                                }
                            }

                        }else
                        {
                            /*  
                                缓冲区 数据队尾直到最后 不够新的数据帧插入;即 重头存储
                                1、是否I帧
                                    I帧之前是否够新的数据帧 
                                    不是I帧或不够新的数据帧插入,出队
                                2、队尾数据直到最后 是否足够新的数据帧插入
                                    够,插入新的数据帧, 并出队直至I帧
                                    不够,出队直至I帧,判断I帧之前是否够新的数据插入

                            */
                            
                            if(buffer_temp.iframe)
                            {
                                if(buffer_temp.data - (buffer_back.data + buffer_back.data_len) >=  buffer_data_t.data_len)
                                {
                                    memcpy(buffer_back.data + buffer_back.data_len, buffer_data_t.data, buffer_data_t.data_len);
                                    buffer_info_t.data = buffer_back.data + buffer_back.data_len ;
                                    buffer_p->avpacket_list->push_back(buffer_info_t);
                                    Count_size -=  buffer_data_t.data_len;
                                    break;
                                }
                            }
                            if((BUFFER_SIZE - (buffer_back.data + buffer_back.data_len - buffer_p->recorder_buffer)) >=  buffer_data_t.data_len)
                            {
                                memcpy(buffer_back.data + buffer_back.data_len, buffer_data_t.data, buffer_data_t.data_len);
                                buffer_info_t.data = buffer_back.data + buffer_back.data_len ;
                                buffer_p->avpacket_list->push_back(buffer_info_t);
                                Count_size -=  buffer_data_t.data_len;
                                while(buffer_p->r_flag)
                                {
                                    buffer_p->avpacket_list->pop_front();
                                    buffer_temp = buffer_p->avpacket_list->at(1);
                                    Count_size += buffer_temp.data_len;
                                    if(buffer_temp.iframe)
                                    {
                                        break;
                                    }
                                }
                                break;  
                            }else
                            {
                                while(buffer_p->r_flag)
                                {
                                    buffer_p->avpacket_list->pop_front();
                                    buffer_temp = buffer_p->avpacket_list->at(1);
                                    if(buffer_temp.iframe)
                                    {
                                        if(buffer_temp.data - buffer_p->recorder_buffer >=  buffer_data_t.data_len)
                                        {
                                            memcpy(buffer_p->recorder_buffer, buffer_data_t.data, buffer_data_t.data_len);
                                            buffer_info_t.data = buffer_p->recorder_buffer ;
                                            buffer_p->avpacket_list->push_back(buffer_info_t);
                                            Count_size -=  buffer_data_t.data_len;
                                            break;
                                        }
                                        
                                    }
                                }
                                break;
                            }
                            
                        }
                        Count_size += buffer_temp.data_len;
                        buffer_p->avpacket_list->pop_front();
                        }  
                
                }
            }
        }
        buffer_p->data_list_mutex.lock();
        buffer_p->recorder_buffer_list->pop();
        buffer_p->data_list_mutex.unlock(); 
    }
   return NULL;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值