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