diff --git a/src/media/media_decoder.cpp b/src/media/media_decoder.cpp
index cf842b3ebdc1435213ce1b881c4932d77499ca50..c59f71f10a2af96c0a92a9e0159adc2674b2e5cc 100644
--- a/src/media/media_decoder.cpp
+++ b/src/media/media_decoder.cpp
@@ -49,13 +49,18 @@ MediaDecoder::~MediaDecoder()
     if (decoderCtx_)
         avcodec_close(decoderCtx_);
 
-    if (inputCtx_ and inputCtx_->nb_streams > 0) {
+    if (inputCtx_) {
+        if (inputCtx_->nb_streams > 0) {
 #if LIBAVFORMAT_VERSION_CHECK(53, 17, 0, 25, 0)
-        avformat_close_input(&inputCtx_);
+            avformat_close_input(&inputCtx_);
 #else
-        av_close_input_file(inputCtx_);
+            av_close_input_file(inputCtx_);
 #endif
+        }
+        avformat_free_context(inputCtx_);
     }
+
+    av_dict_free(&options_);
 }
 
 int MediaDecoder::openInput(const DeviceParams& params)
diff --git a/src/media/media_encoder.cpp b/src/media/media_encoder.cpp
index c95f14b91f265760785ed3d4a30079fa7a547267..826458e4adf341541309835d197e3205165b356b 100644
--- a/src/media/media_encoder.cpp
+++ b/src/media/media_encoder.cpp
@@ -45,17 +45,17 @@ MediaEncoder::MediaEncoder()
 
 MediaEncoder::~MediaEncoder()
 {
-    if (outputCtx_ and outputCtx_->priv_data)
-        av_write_trailer(outputCtx_);
+    if (outputCtx_) {
+        if (outputCtx_->priv_data)
+            av_write_trailer(outputCtx_);
 
-    if (encoderCtx_)
-        avcodec_close(encoderCtx_);
+        if (encoderCtx_)
+            avcodec_close(encoderCtx_);
 
-    av_free(scaledFrameBuffer_);
+        avformat_free_context(outputCtx_);
+    }
 
-#if (LIBAVCODEC_VERSION_MAJOR < 54)
-    av_free(encoderBuffer_);
-#endif
+    av_dict_free(&options_);
 }
 
 void MediaEncoder::setDeviceOptions(const DeviceParams& args)
@@ -235,16 +235,11 @@ MediaEncoder::openOutput(const char *filename,
 
 #if (LIBAVCODEC_VERSION_MAJOR < 54)
         encoderBufferSize_ = scaledFrameBufferSize_; // seems to be ok
-        encoderBuffer_ = (uint8_t*) av_malloc(encoderBufferSize_);
-        if (!encoderBuffer_)
-            throw MediaEncoderException("Could not allocate encoder buffer");
+        encoderBuffer_.reserve(encoderBufferSize_);
 #endif
 
-        scaledFrameBuffer_ = (uint8_t*) av_malloc(scaledFrameBufferSize_);
-        if (!scaledFrameBuffer_)
-            throw MediaEncoderException("Could not allocate scaled frame buffer");
-
-        scaledFrame_.setFromMemory(scaledFrameBuffer_, format, width, height);
+        scaledFrameBuffer_.reserve(scaledFrameBufferSize_);
+        scaledFrame_.setFromMemory(scaledFrameBuffer_.data(), format, width, height);
     }
 #endif // RING_VIDEO
 }
@@ -342,7 +337,7 @@ MediaEncoder::encode(VideoFrame& input, bool is_keyframe,
 
 #else
 
-    int ret = avcodec_encode_video(encoderCtx_, encoderBuffer_,
+    int ret = avcodec_encode_video(encoderCtx_, encoderBuffer_.data(),
                                    encoderBufferSize_, frame);
     if (ret < 0) {
         print_averror("avcodec_encode_video", ret);
@@ -350,7 +345,7 @@ MediaEncoder::encode(VideoFrame& input, bool is_keyframe,
         return ret;
     }
 
-    pkt.data = encoderBuffer_;
+    pkt.data = encoderBuffer_.data();
     pkt.size = ret;
 
     // rescale pts from encoded video framerate to rtp clock rate
@@ -389,9 +384,8 @@ int MediaEncoder::encode_audio(const AudioBuffer &buffer)
         return -1;
     }
 
-    AudioSample *sample_data = reinterpret_cast<AudioSample*>(av_malloc(needed_bytes));
-    if (!sample_data)
-        return -1;
+    std::vector<AudioSample> samples (needed_bytes / sizeof(AudioSample));
+    AudioSample* sample_data = samples.data();
 
     AudioSample *offset_ptr = sample_data;
     int nb_frames = buffer.frames();
@@ -408,10 +402,8 @@ int MediaEncoder::encode_audio(const AudioBuffer &buffer)
 
     while (nb_frames > 0) {
         AVFrame *frame = av_frame_alloc();
-        if (!frame) {
-            av_freep(&sample_data);
+        if (!frame)
             return -1;
-        }
 
         if (encoderCtx_->frame_size)
             frame->nb_samples = std::min<int>(nb_frames,
@@ -439,7 +431,6 @@ int MediaEncoder::encode_audio(const AudioBuffer &buffer)
             av_strerror(err, errbuf, sizeof(errbuf));
             RING_ERR("Couldn't fill audio frame: %s: %d %d", errbuf,
                      frame->nb_samples, buffer_size);
-            av_freep(&sample_data);
             av_frame_free(&frame);
             return -1;
         }
@@ -457,7 +448,6 @@ int MediaEncoder::encode_audio(const AudioBuffer &buffer)
         if (ret < 0) {
             print_averror("avcodec_encode_audio2", ret);
             av_free_packet(&pkt);
-            av_freep(&sample_data);
             av_frame_free(&frame);
             return ret;
         }
@@ -482,8 +472,6 @@ int MediaEncoder::encode_audio(const AudioBuffer &buffer)
         av_frame_free(&frame);
     }
 
-    av_freep(&sample_data);
-
     return 0;
 }
 
@@ -512,7 +500,7 @@ int MediaEncoder::flush()
             RING_ERR("write_frame failed");
     }
 #else
-    ret = avcodec_encode_video(encoderCtx_, encoderBuffer_,
+    ret = avcodec_encode_video(encoderCtx_, encoderBuffer_.data(),
                                encoderBufferSize_, NULL);
     if (ret < 0) {
         RING_ERR("avcodec_encode_video failed");
@@ -520,7 +508,7 @@ int MediaEncoder::flush()
         return ret;
     }
 
-    pkt.data = encoderBuffer_;
+    pkt.data = encoderBuffer_.data();
     pkt.size = ret;
 
     // write the compressed frame
diff --git a/src/media/media_encoder.h b/src/media/media_encoder.h
index d6458fefeec94b782674a76f28303df856858199..5892fc5fa15bf60253218e3c371281c54b0764bd 100644
--- a/src/media/media_encoder.h
+++ b/src/media/media_encoder.h
@@ -35,6 +35,7 @@
 #include <map>
 #include <memory>
 #include <string>
+#include <vector>
 
 class AVCodecContext;
 class AVStream;
@@ -105,11 +106,11 @@ private:
     VideoFrame scaledFrame_;
 #endif // RING_VIDEO
 
-    uint8_t *scaledFrameBuffer_ = nullptr;
+    std::vector<uint8_t> scaledFrameBuffer_;
     int scaledFrameBufferSize_ = 0;
     int streamIndex_ = -1;
 #if defined(LIBAVCODEC_VERSION_MAJOR) && (LIBAVCODEC_VERSION_MAJOR < 54)
-    uint8_t *encoderBuffer_ = nullptr;
+    std::vector<uint8_t> encoderBuffer_;
     int encoderBufferSize_ = 0;
 #endif
     bool is_muted = false;
diff --git a/src/media/media_io_handle.cpp b/src/media/media_io_handle.cpp
index d34fc906347184b998a23e3ec0c7824a40b55230..6fc0d5462fd982aa46cedd5c7188cab2d3e649ca 100644
--- a/src/media/media_io_handle.cpp
+++ b/src/media/media_io_handle.cpp
@@ -28,15 +28,15 @@ MediaIOHandle::MediaIOHandle(std::size_t buffer_size,
                              io_readcallback read_cb,
                              io_writecallback write_cb,
                              io_seekcallback seek_cb,
-                             void *opaque) : ctx_(0), buf_(0)
+                             void *opaque) : ctx_(0)
 
 {
-    buf_ = static_cast<unsigned char *>(av_malloc(buffer_size));
-    ctx_ = avio_alloc_context(buf_, buffer_size, writeable, opaque, read_cb,
+    buf_.reserve(buffer_size);
+    ctx_ = avio_alloc_context(buf_.data(), buffer_size, writeable, opaque, read_cb,
                               write_cb, seek_cb);
     ctx_->max_packet_size = buffer_size;
 }
 
-MediaIOHandle::~MediaIOHandle() { av_free(ctx_); av_free(buf_); }
+MediaIOHandle::~MediaIOHandle() { av_free(ctx_); }
 
 } // namespace ring
diff --git a/src/media/media_io_handle.h b/src/media/media_io_handle.h
index 56a79b3ddd326274afd18e7e42e4351dd03269d1..9853b32049b45b83816b1170699ce30324b11ea9 100644
--- a/src/media/media_io_handle.h
+++ b/src/media/media_io_handle.h
@@ -25,6 +25,7 @@
 
 #include <cstdlib>
 #include <cstdint>
+#include <vector>
 
 #ifndef AVFORMAT_AVIO_H
 class AVIOContext;
@@ -51,7 +52,7 @@ public:
 private:
     NON_COPYABLE(MediaIOHandle);
     AVIOContext *ctx_;
-    unsigned char *buf_;
+    std::vector<uint8_t> buf_ {};
 };
 
 } // namespace ring