// AUTOGENERATED COPYRIGHT HEADER START // Copyright (C) 2020-2023 Michael Fabian 'Xaymar' Dirks // Copyright (C) 2022 lainon // AUTOGENERATED COPYRIGHT HEADER END #include "avframe-queue.hpp" #include "tools.hpp" using namespace streamfx::ffmpeg; std::shared_ptr avframe_queue::create_frame() { std::shared_ptr frame = std::shared_ptr(av_frame_alloc(), [](AVFrame* frame) { av_frame_unref(frame); av_frame_free(&frame); }); frame->width = this->_resolution.first; frame->height = this->_resolution.second; frame->format = this->_format; int res = av_frame_get_buffer(frame.get(), 32); if (res < 0) { throw std::runtime_error(tools::get_error_description(res)); } return frame; } avframe_queue::avframe_queue() = default; avframe_queue::~avframe_queue() { clear(); } void avframe_queue::set_resolution(int32_t const width, int32_t const height) { this->_resolution.first = width; this->_resolution.second = height; } void avframe_queue::get_resolution(int32_t& width, int32_t& height) { width = this->_resolution.first; height = this->_resolution.second; } int32_t avframe_queue::get_width() { return this->_resolution.first; } int32_t avframe_queue::get_height() { return this->_resolution.second; } void avframe_queue::set_pixel_format(AVPixelFormat const format) { this->_format = format; } AVPixelFormat avframe_queue::get_pixel_format() { return this->_format; } void avframe_queue::precache(std::size_t count) { for (std::size_t n = 0; n < count; n++) { push(create_frame()); } } void avframe_queue::clear() { std::unique_lock ulock(this->_lock); _frames.clear(); } void avframe_queue::push(std::shared_ptr const frame) { std::unique_lock ulock(this->_lock); _frames.push_back(frame); } std::shared_ptr avframe_queue::pop() { std::unique_lock ulock(this->_lock); std::shared_ptr ret; while (ret == nullptr) { if (_frames.size() == 0) { ret = create_frame(); } else { ret = _frames.front(); if (ret == nullptr) { ret = create_frame(); } else { _frames.pop_front(); if ((static_cast(ret->width) != this->_resolution.first) || (static_cast(ret->height) != this->_resolution.second) || (ret->format != this->_format)) { ret = nullptr; } } } } return ret; } std::shared_ptr avframe_queue::pop_only() { std::unique_lock ulock(this->_lock); if (_frames.size() == 0) { return nullptr; } std::shared_ptr ret = _frames.front(); if (ret == nullptr) { return nullptr; } _frames.pop_front(); return ret; } bool avframe_queue::empty() { return _frames.empty(); } std::size_t avframe_queue::size() { return _frames.size(); }