AV: Fix all memory leaks

The most substantial memory leak came from `PacketQueue::get`
not unreferencing its argument packet.

Other leaks came from using `av_free` instead of type-specific free
functions.

Also modifies `PacketQueue::put` for readability.
pull/3051/head
Gleb Mazovetskiy 3 years ago
parent eb93fdfbea
commit 58d33aa95b

@ -287,9 +287,9 @@ void FFmpeg_Decoder::close()
mStream = nullptr; mStream = nullptr;
av_packet_unref(&mPacket); av_packet_unref(&mPacket);
av_freep(&mFrame);
swr_free(&mSwr);
av_freep(&mDataBuf); av_freep(&mDataBuf);
av_frame_free(&mFrame);
swr_free(&mSwr);
if(mFormatCtx) if(mFormatCtx)
{ {
@ -302,11 +302,9 @@ void FFmpeg_Decoder::close()
// //
if (mFormatCtx->pb->buffer != nullptr) if (mFormatCtx->pb->buffer != nullptr)
{ {
av_free(mFormatCtx->pb->buffer); av_freep(&mFormatCtx->pb->buffer);
mFormatCtx->pb->buffer = nullptr;
} }
av_free(mFormatCtx->pb); avio_context_free(&mFormatCtx->pb);
mFormatCtx->pb = nullptr;
} }
avformat_close_input(&mFormatCtx); avformat_close_input(&mFormatCtx);
} }

@ -91,7 +91,7 @@ MovieAudioDecoder::~MovieAudioDecoder()
if(mAudioContext) if(mAudioContext)
avcodec_free_context(&mAudioContext); avcodec_free_context(&mAudioContext);
av_freep(&mFrame); av_frame_free(&mFrame);
av_freep(&mDataBuf); av_freep(&mDataBuf);
} }
@ -222,7 +222,7 @@ int MovieAudioDecoder::audio_decode_frame(AVFrame *frame, int &sample_skip)
return result; return result;
} }
av_packet_unref(&mPacket); av_packet_unref(pkt);
mGetNextPacket = true; mGetNextPacket = true;
/* next packet */ /* next packet */

@ -83,10 +83,11 @@ void PacketQueue::put(AVPacket *pkt)
pkt1 = (AVPacketList*)av_malloc(sizeof(AVPacketList)); pkt1 = (AVPacketList*)av_malloc(sizeof(AVPacketList));
if(!pkt1) throw std::bad_alloc(); if(!pkt1) throw std::bad_alloc();
if(pkt != &flush_pkt && !pkt->buf && av_packet_ref(&pkt1->pkt, pkt) < 0) if(pkt == &flush_pkt)
throw std::runtime_error("Failed to duplicate packet"); pkt1->pkt = *pkt;
else
av_packet_move_ref(&pkt1->pkt, pkt);
pkt1->pkt = *pkt;
pkt1->next = nullptr; pkt1->next = nullptr;
this->mutex.lock (); this->mutex.lock ();
@ -117,7 +118,8 @@ int PacketQueue::get(AVPacket *pkt, VideoState *is)
this->nb_packets--; this->nb_packets--;
this->size -= pkt1->pkt.size; this->size -= pkt1->pkt.size;
*pkt = pkt1->pkt; av_packet_unref(pkt);
av_packet_move_ref(pkt, &pkt1->pkt);
av_free(pkt1); av_free(pkt1);
return 1; return 1;
@ -364,6 +366,7 @@ public:
{ {
VideoState* self = mVideoState; VideoState* self = mVideoState;
AVPacket pkt1, *packet = &pkt1; AVPacket pkt1, *packet = &pkt1;
av_init_packet(packet);
AVFrame *pFrame; AVFrame *pFrame;
pFrame = av_frame_alloc(); pFrame = av_frame_alloc();
@ -436,6 +439,7 @@ public:
AVFormatContext *pFormatCtx = self->format_ctx; AVFormatContext *pFormatCtx = self->format_ctx;
AVPacket pkt1, *packet = &pkt1; AVPacket pkt1, *packet = &pkt1;
av_init_packet(packet);
try try
{ {
@ -691,16 +695,13 @@ void VideoState::init(std::shared_ptr<std::istream> inputstream, const std::stri
{ {
if (this->format_ctx->pb != nullptr) if (this->format_ctx->pb != nullptr)
{ {
av_free(this->format_ctx->pb->buffer); av_freep(&this->format_ctx->pb->buffer);
this->format_ctx->pb->buffer = nullptr; avio_context_free(&this->format_ctx->pb);
av_free(this->format_ctx->pb);
this->format_ctx->pb = nullptr;
} }
} }
// "Note that a user-supplied AVFormatContext will be freed on failure." // "Note that a user-supplied AVFormatContext will be freed on failure."
this->format_ctx = nullptr; this->format_ctx = nullptr;
av_free(ioCtx); avio_context_free(&ioCtx);
throw std::runtime_error("Failed to open video input"); throw std::runtime_error("Failed to open video input");
} }
@ -774,11 +775,8 @@ void VideoState::deinit()
/// ///
if (this->format_ctx->pb != nullptr) if (this->format_ctx->pb != nullptr)
{ {
av_free(this->format_ctx->pb->buffer); av_freep(&this->format_ctx->pb->buffer);
this->format_ctx->pb->buffer = nullptr; avio_context_free(&this->format_ctx->pb);
av_free(this->format_ctx->pb);
this->format_ctx->pb = nullptr;
} }
avformat_close_input(&this->format_ctx); avformat_close_input(&this->format_ctx);
} }

Loading…
Cancel
Save