VCarContainer/tools/jetson_multimedia/include/video_codec/FF_CircleQueue.h

395 lines
7.4 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#ifndef _FF_CIRCLEQUEUE_H__
#define _FF_CIRCLEQUEUE_H__
#include <iostream>
#include <memory>
#include <queue>
#include <string>
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include "QueueStructDefine.h"
using namespace std;
template<typename T>
class FF_CircleQueue
{
public:
/**
* @brief Construct a new ff circlequeue object
*
* @param Size Circle Queue元素数量
* @param ElemArray 元素数组
*/
FF_CircleQueue(int Size, T ElemArray);
~FF_CircleQueue();
/**
* @brief 慢队列 入队
*
* @param Elem
* @return int
*/
int EnFullQueue(const T& Elem);
/**
* @brief 满队列 出队
*
* @param Elem
* @return int
*/
int DeFullQueue(T& Elem);
/**
* @brief 满队列尝试出对如果此时队列为空返回false有数据返回true
*
* @param Elem
* @return true
* @return false
*/
bool Try_DeFullQueue(T& Elem);
/**
* @brief
*
* @param Elem
* @return int
*/
int Peek_DeFullQueue(T& Elem); ///< 获取数据,但不出队
/**
* @brief
*
* @param Elem
* @return int
*/
int TryPeek_DeFullQueue(T& Elem);
/**
* @brief 空队列 入队
*
* @param Elem
* @return int
*/
int EnFreeQueue(const T& Elem);
/**
* @brief 空队列 出队
*
* @param Elem
* @return int
*/
int DeFreeQueue(T& Elem);
/**
* @brief 空队列尝试出对有数据为true无数据返回false
*
* @param Elem
* @return true
* @return false
*/
bool Try_DeFreeQueue(T& Elem);
/**
* @brief
*
* @return true
* @return false
*/
bool IsValid();
/**
* @brief 获取各队列所持有元素数量
*
* @return unsigned int
*/
unsigned int GetFullQueueSize();
unsigned int GetFreeQueueSize();
private:
void SetValid()
{
qValid = true;
}
void SetInvalid()
{
qValid = false;
}
bool qValid;
int NumElem;
/**
* @brief 空队列,及其锁,条件变量
*
*/
std::queue<T> free_queue_;
pthread_mutexattr_t free_mutAttr_;
pthread_mutex_t free_mutex_;
pthread_cond_t free_condition_ = PTHREAD_COND_INITIALIZER;
/**
* @brief 满队列,及其锁,条件变量
*
*/
std::queue<T> full_queue_;
pthread_mutexattr_t full_mutAttr_;
pthread_mutex_t full_mutex_;
pthread_cond_t full_condition_ = PTHREAD_COND_INITIALIZER;
};
/**
* Implementation of Circle Queue, Designed by Derek.
*/
/**
* @brief Construct a new queuemanager object
* @tparam T
* @param Size
* @param ElemArray
*/
template<typename T>
FF_CircleQueue<T>::FF_CircleQueue(int Size, T ElemArray)
{
qValid = false;
NumElem = 0;
/// Prevent invalid queue element
if(Size==0 || ElemArray==NULL){
/// NULL
}
memset(&free_mutAttr_, 0, sizeof(pthread_mutexattr_t));
pthread_mutexattr_init(&free_mutAttr_);
pthread_mutexattr_settype(&free_mutAttr_, PTHREAD_MUTEX_RECURSIVE_NP);
pthread_mutex_init(&free_mutex_, &free_mutAttr_);
memset(&full_mutAttr_, 0, sizeof(pthread_mutexattr_t));
pthread_mutexattr_init(&full_mutAttr_);
pthread_mutexattr_settype(&full_mutAttr_, PTHREAD_MUTEX_RECURSIVE_NP);
pthread_mutex_init(&full_mutex_, &full_mutAttr_);
NumElem = Size; ///< Element size
for(int i=0; i<NumElem; i++){
free_queue_.push(&ElemArray[i]);
}
SetValid();
}
/**
* @brief Destroy the queuemanager object
* @tparam T
*/
template<typename T>
FF_CircleQueue<T>::~FF_CircleQueue()
{
pthread_mutex_destroy(&free_mutex_);
pthread_mutex_destroy(&full_mutex_);
/// NULL
}
/**
* @brief
* @param Elem
* @return int
*/
template<typename T>
int FF_CircleQueue<T>::EnFullQueue(const T& Elem) ///< 入队
{
pthread_mutex_lock(&full_mutex_);
full_queue_.push(Elem);
pthread_mutex_unlock(&full_mutex_); ///< 主动释放
pthread_cond_signal(&full_condition_);
return 0;
}
/**
* @brief
* @param Elem
* @return int
*/
template<typename T>
int FF_CircleQueue<T>::DeFullQueue(T& Elem) ///< 出队
{
pthread_mutex_lock(&full_mutex_);
while (full_queue_.empty()) {
pthread_cond_wait(&full_condition_, &full_mutex_);
}
Elem = full_queue_.front();
full_queue_.pop();
pthread_mutex_unlock(&full_mutex_);
return 0;
}
/**
* @brief
* @param Elem
* @return int
*/
template<typename T>
int FF_CircleQueue<T>::Peek_DeFullQueue(T& Elem) ///< 获取数据,但不出队
{
// *Elem = full_queue_.peek();
return 0;
}
/**
* @brief
* @tparam T
* @param Elem
* @return int
*/
template<typename T>
bool FF_CircleQueue<T>::Try_DeFullQueue(T& Elem)
{
pthread_mutex_lock(&full_mutex_);
if (full_queue_.empty()) {
pthread_mutex_unlock(&full_mutex_);
return false;
}
Elem = full_queue_.front();
full_queue_.pop();
pthread_mutex_unlock(&full_mutex_);
return true;
}
/**
* @brief
* @tparam T
* @param Elem
* @return int
*/
template<typename T>
int FF_CircleQueue<T>::TryPeek_DeFullQueue(T& Elem)
{
//bool ret = false;
pthread_mutex_lock(&full_mutex_);
if (full_queue_.empty()) {
pthread_mutex_unlock(&full_mutex_);
return -1;
}
Elem = full_queue_.front();
pthread_mutex_unlock(&full_mutex_);
return 0;
}
/**
* @brief
* @param Elem
* @return int
*/
template<typename T>
int FF_CircleQueue<T>::EnFreeQueue(const T& Elem)
{
pthread_mutex_lock(&free_mutex_);
free_queue_.push(Elem);
pthread_mutex_unlock(&free_mutex_); ///< 主动释放
pthread_cond_signal(&free_condition_);
return 0;
}
/**
* @brief
* @param Elem
* @return int
*/
template<typename T>
int FF_CircleQueue<T>::DeFreeQueue(T& Elem)
{
pthread_mutex_lock(&free_mutex_);
while (free_queue_.empty()) {
pthread_cond_wait(&free_condition_, &free_mutex_);
}
Elem = free_queue_.front();
free_queue_.pop();
pthread_mutex_unlock(&free_mutex_);
return 0;
}
/**
* @brief
* @tparam T
* @param Elem
* @return int
*/
template<typename T>
bool FF_CircleQueue<T>::Try_DeFreeQueue(T& Elem)
{
pthread_mutex_lock(&free_mutex_);
if (free_queue_.empty()) {
pthread_mutex_unlock(&free_mutex_);
return false;
}
Elem = free_queue_.front();
free_queue_.pop();
pthread_mutex_unlock(&free_mutex_);
return true;
}
/**
* @brief Check if queue manager is valid
* @return true
* @return false
*/
template<typename T>
bool FF_CircleQueue<T>::IsValid()
{
return qValid;
}
/**
* @brief Get the number of elements in the fullqueue
* @tparam T
* @return int
*/
template<typename T>
unsigned int FF_CircleQueue<T>::GetFullQueueSize()
{
return full_queue_.size();
}
/**
* @brief Get the number of elements in the freequeue
* @tparam T
* @return int
*/
template<typename T>
unsigned int FF_CircleQueue<T>::GetFreeQueueSize()
{
return free_queue_.size();
}
template class FF_CircleQueue<FFQBuffer*>; ///< TEST
template class FF_CircleQueue<ListenerQBuffer*>; ///< TEST
template class FF_CircleQueue<VideoQBuffer*>; ///< TEST
// int fun();
///////////////////////////////////////////////////////////////////////////////////
#endif ///_FF_QUEUE_MANAGER_H__