From 39697786c98be6e4c799a6bc635e0c718d710afb Mon Sep 17 00:00:00 2001 From: jie Date: Wed, 21 Feb 2024 21:20:14 +0800 Subject: [PATCH] =?UTF-8?q?=E9=98=9F=E5=88=97=E5=AE=B9=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/decoder.h | 83 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 80 insertions(+), 3 deletions(-) diff --git a/include/decoder.h b/include/decoder.h index 174d863..1d8881b 100644 --- a/include/decoder.h +++ b/include/decoder.h @@ -5,14 +5,91 @@ extern "C" { #include "libavformat/avformat.h" #include "libavutil/imgutils.h" } +#include +#include +#include +#include -struct DecoderParam { +struct VideoParam +{ AVFormatContext* fmtCtx; AVCodecContext* codecCtx; int width; int height; int videoStreamIndex; }; -void InitDecoder(const char* filepath, DecoderParam& param); -AVFrame* RequestFrame(DecoderParam& param); + +template + requires std::is_same_v || std::is_same_v +struct MediaQueue +{ + std::queue 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 requires std::is_same_v || std::is_same_v +bool MediaQueue::push(const T* item) { + if (item == nullptr) return false; + std::unique_lock lock(mut); + if constexpr (std::is_same_v) { + auto temp = av_packet_alloc(); + av_packet_ref(temp, item); + queue.push(*temp); + size += temp->size; + count++; + }else if(std::is_same_v) { + auto temp = av_frame_alloc(); + av_frame_ref(temp, item); + queue.push(*temp); + count++; + } + cv.notify_all(); + return true; +} + +template requires std::is_same_v || std::is_same_v +bool MediaQueue::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) { + if (av_packet_ref(item, &temp) < 0) { + return false; + } + av_packet_unref(&temp); + } + else if (std::is_same_v) { + 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 \ No newline at end of file