ffmpeg/avframe-queue: Upgrade to shared_ptr AVFrame

Removes problems with memory leaks due to lost references and other issues.
This commit is contained in:
Michael Fabian 'Xaymar' Dirks
2019-07-07 11:54:47 +02:00
parent 89fd38e604
commit c5ff5d224d
2 changed files with 19 additions and 36 deletions
+13 -24
View File
@@ -18,13 +18,15 @@
#include "avframe-queue.hpp"
#include "tools.hpp"
AVFrame* ffmpeg::avframe_queue::create_frame()
std::shared_ptr<AVFrame> ffmpeg::avframe_queue::create_frame()
{
AVFrame* frame = av_frame_alloc();
frame->width = this->resolution.first;
frame->height = this->resolution.second;
frame->format = this->format;
int res = av_frame_get_buffer(frame, 0);
std::shared_ptr<AVFrame> frame =
std::shared_ptr<AVFrame>(av_frame_alloc(), [](AVFrame* 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(), 0);
if (res < 0) {
throw std::exception(ffmpeg::tools::get_error_description(res));
}
@@ -32,14 +34,6 @@ AVFrame* ffmpeg::avframe_queue::create_frame()
return frame;
}
void ffmpeg::avframe_queue::destroy_frame(AVFrame* frame)
{
if (frame == nullptr)
return;
av_frame_free(&frame);
}
ffmpeg::avframe_queue::avframe_queue() {}
ffmpeg::avframe_queue::~avframe_queue()
@@ -89,23 +83,19 @@ void ffmpeg::avframe_queue::precache(size_t count)
void ffmpeg::avframe_queue::clear()
{
std::unique_lock<std::mutex> ulock(this->lock);
for (AVFrame* frame : frames) {
destroy_frame(frame);
}
frames.clear();
}
void ffmpeg::avframe_queue::push(AVFrame* frame)
void ffmpeg::avframe_queue::push(std::shared_ptr<AVFrame> frame)
{
std::unique_lock<std::mutex> ulock(this->lock);
frames.push_back(frame);
}
AVFrame* ffmpeg::avframe_queue::pop()
std::shared_ptr<AVFrame> ffmpeg::avframe_queue::pop()
{
std::unique_lock<std::mutex> ulock(this->lock);
AVFrame* ret = nullptr;
std::shared_ptr<AVFrame> ret;
while (ret == nullptr) {
if (frames.size() == 0) {
ret = create_frame();
@@ -117,7 +107,6 @@ AVFrame* ffmpeg::avframe_queue::pop()
frames.pop_front();
if ((ret->width != this->resolution.first) || (ret->height != this->resolution.second)
|| (ret->format != this->format)) {
destroy_frame(ret);
ret = nullptr;
}
}
@@ -126,13 +115,13 @@ AVFrame* ffmpeg::avframe_queue::pop()
return ret;
}
AVFrame* ffmpeg::avframe_queue::pop_only()
std::shared_ptr<AVFrame> ffmpeg::avframe_queue::pop_only()
{
std::unique_lock<std::mutex> ulock(this->lock);
if (frames.size() == 0) {
return nullptr;
}
AVFrame* ret = frames.front();
std::shared_ptr<AVFrame> ret = frames.front();
if (ret == nullptr) {
return nullptr;
}
+6 -12
View File
@@ -15,10 +15,7 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#ifndef OBS_FFMPEG_FFMPEG_AVFRAME_QUEUE
#define OBS_FFMPEG_FFMPEG_AVFRAME_QUEUE
#pragma once
#include <deque>
#include <mutex>
@@ -31,14 +28,13 @@ extern "C" {
namespace ffmpeg {
class avframe_queue {
std::deque<AVFrame*> frames;
std::mutex lock;
std::deque<std::shared_ptr<AVFrame>> frames;
std::mutex lock;
std::pair<uint32_t, uint32_t> resolution;
AVPixelFormat format = AV_PIX_FMT_NONE;
AVFrame* create_frame();
void destroy_frame(AVFrame* frame);
std::shared_ptr<AVFrame> create_frame();
public:
avframe_queue();
@@ -56,16 +52,14 @@ namespace ffmpeg {
void clear();
void push(AVFrame* frame);
void push(std::shared_ptr<AVFrame> frame);
AVFrame* pop();
std::shared_ptr<AVFrame> pop();
AVFrame* pop_only();
std::shared_ptr<AVFrame> pop_only();
bool empty();
size_t size();
};
} // namespace ffmpeg
#endif OBS_FFMPEG_FFMPEG_AVFRAME_QUEUE