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

395 lines
7.4 KiB
C
Raw Permalink Normal View History

2024-11-27 12:47:45 +00:00
#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 falsetrue
*
* @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 truefalse
*
* @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__