队列容器
This commit is contained in:
parent
3309be9582
commit
39697786c9
@ -5,14 +5,91 @@ extern "C" {
|
|||||||
#include "libavformat/avformat.h"
|
#include "libavformat/avformat.h"
|
||||||
#include "libavutil/imgutils.h"
|
#include "libavutil/imgutils.h"
|
||||||
}
|
}
|
||||||
|
#include <queue>
|
||||||
|
#include <thread>
|
||||||
|
#include <condition_variable>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
struct DecoderParam {
|
struct VideoParam
|
||||||
|
{
|
||||||
AVFormatContext* fmtCtx;
|
AVFormatContext* fmtCtx;
|
||||||
AVCodecContext* codecCtx;
|
AVCodecContext* codecCtx;
|
||||||
int width;
|
int width;
|
||||||
int height;
|
int height;
|
||||||
int videoStreamIndex;
|
int videoStreamIndex;
|
||||||
};
|
};
|
||||||
void InitDecoder(const char* filepath, DecoderParam& param);
|
|
||||||
AVFrame* RequestFrame(DecoderParam& param);
|
template<typename T>
|
||||||
|
requires std::is_same_v<T, AVPacket> || std::is_same_v<T, AVFrame>
|
||||||
|
struct MediaQueue
|
||||||
|
{
|
||||||
|
std::queue<T> queue;
|
||||||
|
std::condition_variable cv;
|
||||||
|
std::mutex mut;
|
||||||
|
|
||||||
|
uint32_t size;
|
||||||
|
uint32_t count;
|
||||||
|
|
||||||
|
MediaQueue() = default;
|
||||||
|
bool push(const T* item);
|
||||||
|
bool pop(T* item, bool block = false, bool quit = false);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T> requires std::is_same_v<T, AVPacket> || std::is_same_v<T, AVFrame>
|
||||||
|
bool MediaQueue<T>::push(const T* item) {
|
||||||
|
if (item == nullptr) return false;
|
||||||
|
std::unique_lock lock(mut);
|
||||||
|
if constexpr (std::is_same_v<T, AVPacket>) {
|
||||||
|
auto temp = av_packet_alloc();
|
||||||
|
av_packet_ref(temp, item);
|
||||||
|
queue.push(*temp);
|
||||||
|
size += temp->size;
|
||||||
|
count++;
|
||||||
|
}else if(std::is_same_v<T, AVFrame>) {
|
||||||
|
auto temp = av_frame_alloc();
|
||||||
|
av_frame_ref(temp, item);
|
||||||
|
queue.push(*temp);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
cv.notify_all();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> requires std::is_same_v<T, AVPacket> || std::is_same_v<T, AVFrame>
|
||||||
|
bool MediaQueue<T>::pop(T* item, bool block, bool quit) {
|
||||||
|
std::unique_lock lock(mut);
|
||||||
|
while (!quit) {
|
||||||
|
if (!queue.empty()) {
|
||||||
|
T temp = queue.front();
|
||||||
|
if constexpr (std::is_same_v<T, AVPacket>) {
|
||||||
|
if (av_packet_ref(item, &temp) < 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
av_packet_unref(&temp);
|
||||||
|
}
|
||||||
|
else if (std::is_same_v<T, AVFrame>) {
|
||||||
|
if (av_frame_ref(item, &temp) < 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
av_frame_unref(&temp);
|
||||||
|
}
|
||||||
|
queue.pop();
|
||||||
|
count--;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (block) {
|
||||||
|
cv.wait(lock);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void InitDecoder(const char* filepath, VideoParam& param);
|
||||||
|
AVFrame* RequestFrame(VideoParam& param);
|
||||||
#endif
|
#endif
|
Loading…
Reference in New Issue
Block a user