Sophie

Sophie

distrib > Mageia > 8 > armv7hl > by-pkgid > af635717f33b99befbf0616f01df8dc5 > files > 2

audaspace-1.3.0-21.mga8.src.rpm

From 212b4b605d9a73b97a4bf95ec080731477b64741 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=B6rg=20M=C3=BCller?= <nexyon@gmail.com>
Date: Fri, 8 Jun 2018 18:18:09 +0200
Subject: [PATCH] Support newer ffmpeg versions.

---
 plugins/ffmpeg/FFMPEG.cpp       |   2 +
 plugins/ffmpeg/FFMPEGReader.cpp | 124 ++++++++++++++++++-----
 plugins/ffmpeg/FFMPEGReader.h   |   5 +
 plugins/ffmpeg/FFMPEGWriter.cpp | 216 +++++++++++++++++++++++++++++-----------
 plugins/ffmpeg/FFMPEGWriter.h   |  13 ++-
 5 files changed, 274 insertions(+), 86 deletions(-)

diff --git a/plugins/ffmpeg/FFMPEG.cpp b/plugins/ffmpeg/FFMPEG.cpp
index 7f9b762..3ffe963 100644
--- a/plugins/ffmpeg/FFMPEG.cpp
+++ b/plugins/ffmpeg/FFMPEG.cpp
@@ -23,7 +23,9 @@ AUD_NAMESPACE_BEGIN
 
 FFMPEG::FFMPEG()
 {
+#if LIBAVCODEC_VERSION_MAJOR < 58
 	av_register_all();
+#endif
 }
 
 void FFMPEG::registerPlugin()
diff --git a/plugins/ffmpeg/FFMPEGReader.cpp b/plugins/ffmpeg/FFMPEGReader.cpp
index 6b79cc5..2da84ce 100644
--- a/plugins/ffmpeg/FFMPEGReader.cpp
+++ b/plugins/ffmpeg/FFMPEGReader.cpp
@@ -22,37 +22,37 @@
 extern "C" {
 #include <libavcodec/avcodec.h>
 #include <libavformat/avio.h>
+#include <libavutil/avutil.h>
 }
 
 AUD_NAMESPACE_BEGIN
 
+#if LIBAVCODEC_VERSION_MAJOR < 58
+#define FFMPEG_OLD_CODE
+#endif
+
 int FFMPEGReader::decode(AVPacket& packet, Buffer& buffer)
 {
-	AVFrame* frame = nullptr;
+	int buf_size = buffer.getSize();
+	int buf_pos = 0;
+
+#ifdef FFMPEG_OLD_CODE
 	int got_frame;
 	int read_length;
 	uint8_t* orig_data = packet.data;
 	int orig_size = packet.size;
 
-	int buf_size = buffer.getSize();
-	int buf_pos = 0;
-
 	while(packet.size > 0)
 	{
 		got_frame = 0;
 
-		if(!frame)
-			frame = av_frame_alloc();
-		else
-			av_frame_unref(frame);
-
-		read_length = avcodec_decode_audio4(m_codecCtx, frame, &got_frame, &packet);
+		read_length = avcodec_decode_audio4(m_codecCtx, m_frame, &got_frame, &packet);
 		if(read_length < 0)
 			break;
 
 		if(got_frame)
 		{
-			int data_size = av_samples_get_buffer_size(nullptr, m_codecCtx->channels, frame->nb_samples, m_codecCtx->sample_fmt, 1);
+			int data_size = av_samples_get_buffer_size(nullptr, m_codecCtx->channels, m_frame->nb_samples, m_codecCtx->sample_fmt, 1);
 
 			if(buf_size - buf_pos < data_size)
 			{
@@ -62,18 +62,18 @@ int FFMPEGReader::decode(AVPacket& packet, Buffer& buffer)
 
 			if(m_tointerleave)
 			{
-				int single_size = data_size / m_codecCtx->channels / frame->nb_samples;
+				int single_size = data_size / m_codecCtx->channels / m_frame->nb_samples;
 				for(int channel = 0; channel < m_codecCtx->channels; channel++)
 				{
-					for(int i = 0; i < frame->nb_samples; i++)
+					for(int i = 0; i < m_frame->nb_samples; i++)
 					{
 						std::memcpy(((data_t*)buffer.getBuffer()) + buf_pos + ((m_codecCtx->channels * i) + channel) * single_size,
-							   frame->data[channel] + i * single_size, single_size);
+							   m_frame->data[channel] + i * single_size, single_size);
 					}
 				}
 			}
 			else
-				std::memcpy(((data_t*)buffer.getBuffer()) + buf_pos, frame->data[0], data_size);
+				std::memcpy(((data_t*)buffer.getBuffer()) + buf_pos, m_frame->data[0], data_size);
 
 			buf_pos += data_size;
 		}
@@ -83,7 +83,42 @@ int FFMPEGReader::decode(AVPacket& packet, Buffer& buffer)
 
 	packet.data = orig_data;
 	packet.size = orig_size;
-	av_free(frame);
+#else
+	avcodec_send_packet(m_codecCtx, &packet);
+
+	while(true)
+	{
+		auto ret = avcodec_receive_frame(m_codecCtx, m_frame);
+
+		if(ret != 0)
+			break;
+
+		int data_size = av_samples_get_buffer_size(nullptr, m_codecCtx->channels, m_frame->nb_samples, m_codecCtx->sample_fmt, 1);
+
+		if(buf_size - buf_pos < data_size)
+		{
+			buffer.resize(buf_size + data_size, true);
+			buf_size += data_size;
+		}
+
+		if(m_tointerleave)
+		{
+			int single_size = data_size / m_codecCtx->channels / m_frame->nb_samples;
+			for(int channel = 0; channel < m_codecCtx->channels; channel++)
+			{
+				for(int i = 0; i < m_frame->nb_samples; i++)
+				{
+					std::memcpy(((data_t*)buffer.getBuffer()) + buf_pos + ((m_codecCtx->channels * i) + channel) * single_size,
+						   m_frame->data[channel] + i * single_size, single_size);
+				}
+			}
+		}
+		else
+			std::memcpy(((data_t*)buffer.getBuffer()) + buf_pos, m_frame->data[0], data_size);
+
+		buf_pos += data_size;
+	}
+#endif
 
 	return buf_pos;
 }
@@ -101,7 +136,11 @@ void FFMPEGReader::init()
 
 	for(unsigned int i = 0; i < m_formatCtx->nb_streams; i++)
 	{
+#ifdef FFMPEG_OLD_CODE
 		if((m_formatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO)
+#else
+		if((m_formatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
+#endif
 			&& (m_stream < 0))
 		{
 			m_stream=i;
@@ -112,12 +151,34 @@ void FFMPEGReader::init()
 	if(m_stream == -1)
 		AUD_THROW(FileException, "File couldn't be read, no audio stream found by ffmpeg.");
 
-	m_codecCtx = m_formatCtx->streams[m_stream]->codec;
-
 	// get a decoder and open it
-	AVCodec* aCodec = avcodec_find_decoder(m_codecCtx->codec_id);
+#ifndef FFMPEG_OLD_CODE
+	AVCodec* aCodec = avcodec_find_decoder(m_formatCtx->streams[m_stream]->codecpar->codec_id);
+
 	if(!aCodec)
 		AUD_THROW(FileException, "File couldn't be read, no decoder found with ffmpeg.");
+#endif
+
+	m_frame = av_frame_alloc();
+
+	if(!m_frame)
+		AUD_THROW(FileException, "File couldn't be read, ffmpeg frame couldn't be allocated.");
+
+#ifdef FFMPEG_OLD_CODE
+	m_codecCtx = m_formatCtx->streams[m_stream]->codec;
+
+	AVCodec* aCodec = avcodec_find_decoder(m_codecCtx->codec_id);
+#else
+	m_codecCtx = avcodec_alloc_context3(aCodec);
+#endif
+
+	if(!m_codecCtx)
+		AUD_THROW(FileException, "File couldn't be read, ffmpeg context couldn't be allocated.");
+
+#ifndef FFMPEG_OLD_CODE
+	if(avcodec_parameters_to_context(m_codecCtx, m_formatCtx->streams[m_stream]->codecpar) < 0)
+		AUD_THROW(FileException, "File couldn't be read, ffmpeg decoder parameters couldn't be copied to decoder context.");
+#endif
 
 	if(avcodec_open2(m_codecCtx, aCodec, nullptr) < 0)
 		AUD_THROW(FileException, "File couldn't be read, ffmpeg codec couldn't be opened.");
@@ -157,6 +218,8 @@ void FFMPEGReader::init()
 FFMPEGReader::FFMPEGReader(std::string filename) :
 	m_pkgbuf(),
 	m_formatCtx(nullptr),
+	m_codecCtx(nullptr),
+	m_frame(nullptr),
 	m_aviocontext(nullptr),
 	m_membuf(nullptr)
 {
@@ -177,12 +240,14 @@ FFMPEGReader::FFMPEGReader(std::string filename) :
 
 FFMPEGReader::FFMPEGReader(std::shared_ptr<Buffer> buffer) :
 		m_pkgbuf(),
+		m_codecCtx(nullptr),
+		m_frame(nullptr),
 		m_membuffer(buffer),
 		m_membufferpos(0)
 {
-	m_membuf = reinterpret_cast<data_t*>(av_malloc(FF_MIN_BUFFER_SIZE + FF_INPUT_BUFFER_PADDING_SIZE));
+	m_membuf = reinterpret_cast<data_t*>(av_malloc(AV_INPUT_BUFFER_MIN_SIZE + AV_INPUT_BUFFER_PADDING_SIZE));
 
-	m_aviocontext = avio_alloc_context(m_membuf, FF_MIN_BUFFER_SIZE, 0, this, read_packet, nullptr, seek_packet);
+	m_aviocontext = avio_alloc_context(m_membuf, AV_INPUT_BUFFER_MIN_SIZE, 0, this, read_packet, nullptr, seek_packet);
 
 	if(!m_aviocontext)
 	{
@@ -212,7 +277,14 @@ FFMPEGReader::FFMPEGReader(std::shared_ptr<Buffer> buffer) :
 
 FFMPEGReader::~FFMPEGReader()
 {
+	if(m_frame)
+		av_frame_free(&m_frame);
+#ifdef FFMPEG_OLD_CODE
 	avcodec_close(m_codecCtx);
+#else
+	if(m_codecCtx)
+		avcodec_free_context(&m_codecCtx);
+#endif
 	avformat_close_input(&m_formatCtx);
 }
 
@@ -312,7 +384,7 @@ void FFMPEGReader::seek(int position)
 						}
 					}
 				}
-				av_free_packet(&packet);
+				av_packet_unref(&packet);
 			}
 		}
 		else
@@ -343,7 +415,7 @@ Specs FFMPEGReader::getSpecs() const
 void FFMPEGReader::read(int& length, bool& eos, sample_t* buffer)
 {
 	// read packages and decode them
-	AVPacket packet;
+	AVPacket packet = {};
 	int data_size = 0;
 	int pkgbuf_pos;
 	int left = length;
@@ -359,7 +431,7 @@ void FFMPEGReader::read(int& length, bool& eos, sample_t* buffer)
 		data_size = std::min(pkgbuf_pos, left * sample_size);
 		m_convert((data_t*) buf, (data_t*) m_pkgbuf.getBuffer(), data_size / AUD_FORMAT_SIZE(m_specs.format));
 		buf += data_size / AUD_FORMAT_SIZE(m_specs.format);
-		left -= data_size/sample_size;
+		left -= data_size / sample_size;
 	}
 
 	// for each frame read as long as there isn't enough data already
@@ -375,9 +447,9 @@ void FFMPEGReader::read(int& length, bool& eos, sample_t* buffer)
 			data_size = std::min(pkgbuf_pos, left * sample_size);
 			m_convert((data_t*) buf, (data_t*) m_pkgbuf.getBuffer(), data_size / AUD_FORMAT_SIZE(m_specs.format));
 			buf += data_size / AUD_FORMAT_SIZE(m_specs.format);
-			left -= data_size/sample_size;
+			left -= data_size / sample_size;
 		}
-		av_free_packet(&packet);
+		av_packet_unref(&packet);
 	}
 	// read more data than necessary?
 	if(pkgbuf_pos > data_size)
diff --git a/plugins/ffmpeg/FFMPEGReader.h b/plugins/ffmpeg/FFMPEGReader.h
index e2ae959..a69ac77 100644
--- a/plugins/ffmpeg/FFMPEGReader.h
+++ b/plugins/ffmpeg/FFMPEGReader.h
@@ -79,6 +79,11 @@ class AUD_PLUGIN_API FFMPEGReader : public IReader
 	 */
 	AVCodecContext* m_codecCtx;
 
+	/**
+	 * The AVFrame structure for using ffmpeg.
+	 */
+	AVFrame* m_frame;
+
 	/**
 	 * The AVIOContext to read the data from.
 	 */
diff --git a/plugins/ffmpeg/FFMPEGWriter.cpp b/plugins/ffmpeg/FFMPEGWriter.cpp
index f79f0f7..09b7089 100644
--- a/plugins/ffmpeg/FFMPEGWriter.cpp
+++ b/plugins/ffmpeg/FFMPEGWriter.cpp
@@ -27,6 +27,10 @@ extern "C" {
 
 AUD_NAMESPACE_BEGIN
 
+#if LIBAVCODEC_VERSION_MAJOR < 58
+#define FFMPEG_OLD_CODE
+#endif
+
 void FFMPEGWriter::encode()
 {
 	sample_t* data = m_input_buffer.getBuffer();
@@ -58,82 +62,106 @@ void FFMPEGWriter::encode()
 		if(m_input_size)
 			m_convert(reinterpret_cast<data_t*>(data), reinterpret_cast<data_t*>(data), m_input_samples * m_specs.channels);
 
-	AVPacket packet;
-
-	packet.data = nullptr;
-	packet.size = 0;
+#ifdef FFMPEG_OLD_CODE
+	m_packet->data = nullptr;
+	m_packet->size = 0;
 
-	av_init_packet(&packet);
+	av_init_packet(m_packet);
 
-	AVFrame* frame = av_frame_alloc();
-	av_frame_unref(frame);
+	av_frame_unref(m_frame);
 	int got_packet;
+#endif
 
-	frame->nb_samples = m_input_samples;
-	frame->format = m_codecCtx->sample_fmt;
-	frame->channel_layout = m_codecCtx->channel_layout;
+	m_frame->nb_samples = m_input_samples;
+	m_frame->format = m_codecCtx->sample_fmt;
+	m_frame->channel_layout = m_codecCtx->channel_layout;
 
-	if(avcodec_fill_audio_frame(frame, m_specs.channels, m_codecCtx->sample_fmt, reinterpret_cast<data_t*>(data), m_input_buffer.getSize(), 0) < 0)
+	if(avcodec_fill_audio_frame(m_frame, m_specs.channels, m_codecCtx->sample_fmt, reinterpret_cast<data_t*>(data), m_input_buffer.getSize(), 0) < 0)
 		AUD_THROW(FileException, "File couldn't be written, filling the audio frame failed with ffmpeg.");
 
 	AVRational sample_time = { 1, static_cast<int>(m_specs.rate) };
-	frame->pts = av_rescale_q(m_position - m_input_samples, m_codecCtx->time_base, sample_time);
+	m_frame->pts = av_rescale_q(m_position - m_input_samples, m_codecCtx->time_base, sample_time);
 
-	if(avcodec_encode_audio2(m_codecCtx, &packet, frame, &got_packet))
+#ifdef FFMPEG_OLD_CODE
+	if(avcodec_encode_audio2(m_codecCtx, m_packet, m_frame, &got_packet))
 	{
-		av_frame_free(&frame);
 		AUD_THROW(FileException, "File couldn't be written, audio encoding failed with ffmpeg.");
 	}
 
 	if(got_packet)
 	{
-		packet.flags |= AV_PKT_FLAG_KEY;
-		packet.stream_index = m_stream->index;
-		if(av_write_frame(m_formatCtx, &packet) < 0)
+		m_packet->flags |= AV_PKT_FLAG_KEY;
+		m_packet->stream_index = m_stream->index;
+		if(av_write_frame(m_formatCtx, m_packet) < 0)
 		{
-			av_free_packet(&packet);
-			av_frame_free(&frame);
+			av_free_packet(m_packet);
 			AUD_THROW(FileException, "Frame couldn't be writen to the file with ffmpeg.");
 		}
-		av_free_packet(&packet);
+		av_free_packet(m_packet);
 	}
+#else
+	if(avcodec_send_frame(m_codecCtx, m_frame) < 0)
+		AUD_THROW(FileException, "File couldn't be written, audio encoding failed with ffmpeg.");
+
+	while(avcodec_receive_packet(m_codecCtx, m_packet) == 0)
+	{
+		m_packet->stream_index = m_stream->index;
 
-	av_frame_free(&frame);
+		if(av_write_frame(m_formatCtx, m_packet) < 0)
+			AUD_THROW(FileException, "Frame couldn't be writen to the file with ffmpeg.");
+	}
+#endif
 }
 
 void FFMPEGWriter::close()
 {
+#ifdef FFMPEG_OLD_CODE
 	int got_packet = true;
 
 	while(got_packet)
 	{
-		AVPacket packet;
+		m_packet->data = nullptr;
+		m_packet->size = 0;
 
-		packet.data = nullptr;
-		packet.size = 0;
+		av_init_packet(m_packet);
 
-		av_init_packet(&packet);
-
-		if(avcodec_encode_audio2(m_codecCtx, &packet, nullptr, &got_packet))
+		if(avcodec_encode_audio2(m_codecCtx, m_packet, nullptr, &got_packet))
 			AUD_THROW(FileException, "File end couldn't be written, audio encoding failed with ffmpeg.");
 
 		if(got_packet)
 		{
-			packet.flags |= AV_PKT_FLAG_KEY;
-			packet.stream_index = m_stream->index;
-			if(av_write_frame(m_formatCtx, &packet))
+			m_packet->flags |= AV_PKT_FLAG_KEY;
+			m_packet->stream_index = m_stream->index;
+			if(av_write_frame(m_formatCtx, m_packet))
 			{
-				av_free_packet(&packet);
+				av_free_packet(m_packet);
 				AUD_THROW(FileException, "Final frames couldn't be writen to the file with ffmpeg.");
 			}
-			av_free_packet(&packet);
+			av_free_packet(m_packet);
 		}
 	}
+#else
+	if(avcodec_send_frame(m_codecCtx, nullptr) < 0)
+		AUD_THROW(FileException, "File couldn't be written, audio encoding failed with ffmpeg.");
+
+	while(avcodec_receive_packet(m_codecCtx, m_packet) == 0)
+	{
+		m_packet->stream_index = m_stream->index;
+
+		if(av_write_frame(m_formatCtx, m_packet) < 0)
+			AUD_THROW(FileException, "Frame couldn't be writen to the file with ffmpeg.");
+	}
+#endif
 }
 
 FFMPEGWriter::FFMPEGWriter(std::string filename, DeviceSpecs specs, Container format, Codec codec, unsigned int bitrate) :
 	m_position(0),
 	m_specs(specs),
+	m_formatCtx(nullptr),
+	m_codecCtx(nullptr),
+	m_stream(nullptr),
+	m_packet(nullptr),
+	m_frame(nullptr),
 	m_input_samples(0),
 	m_deinterleave(false)
 {
@@ -142,75 +170,105 @@ FFMPEGWriter::FFMPEGWriter(std::string filename, DeviceSpecs specs, Container fo
 	if(avformat_alloc_output_context2(&m_formatCtx, nullptr, formats[format], filename.c_str()) < 0)
 		AUD_THROW(FileException, "File couldn't be written, format couldn't be found with ffmpeg.");
 
-	m_outputFmt = m_formatCtx->oformat;
+	AVOutputFormat* outputFmt = m_formatCtx->oformat;
 
-	if(!m_outputFmt) {
+	if(!outputFmt) {
 		avformat_free_context(m_formatCtx);
 		AUD_THROW(FileException, "File couldn't be written, output format couldn't be found with ffmpeg.");
 	}
 
-	m_outputFmt->audio_codec = AV_CODEC_ID_NONE;
+	outputFmt->audio_codec = AV_CODEC_ID_NONE;
 
 	switch(codec)
 	{
 	case CODEC_AAC:
-		m_outputFmt->audio_codec = AV_CODEC_ID_AAC;
+		outputFmt->audio_codec = AV_CODEC_ID_AAC;
 		break;
 	case CODEC_AC3:
-		m_outputFmt->audio_codec = AV_CODEC_ID_AC3;
+		outputFmt->audio_codec = AV_CODEC_ID_AC3;
 		break;
 	case CODEC_FLAC:
-		m_outputFmt->audio_codec = AV_CODEC_ID_FLAC;
+		outputFmt->audio_codec = AV_CODEC_ID_FLAC;
 		break;
 	case CODEC_MP2:
-		m_outputFmt->audio_codec = AV_CODEC_ID_MP2;
+		outputFmt->audio_codec = AV_CODEC_ID_MP2;
 		break;
 	case CODEC_MP3:
-		m_outputFmt->audio_codec = AV_CODEC_ID_MP3;
+		outputFmt->audio_codec = AV_CODEC_ID_MP3;
 		break;
 	case CODEC_OPUS:
-		m_outputFmt->audio_codec = AV_CODEC_ID_OPUS;
+		outputFmt->audio_codec = AV_CODEC_ID_OPUS;
 		break;
 	case CODEC_PCM:
 		switch(specs.format)
 		{
 		case FORMAT_U8:
-			m_outputFmt->audio_codec = AV_CODEC_ID_PCM_U8;
+			outputFmt->audio_codec = AV_CODEC_ID_PCM_U8;
 			break;
 		case FORMAT_S16:
-			m_outputFmt->audio_codec = AV_CODEC_ID_PCM_S16LE;
+			outputFmt->audio_codec = AV_CODEC_ID_PCM_S16LE;
 			break;
 		case FORMAT_S24:
-			m_outputFmt->audio_codec = AV_CODEC_ID_PCM_S24LE;
+			outputFmt->audio_codec = AV_CODEC_ID_PCM_S24LE;
 			break;
 		case FORMAT_S32:
-			m_outputFmt->audio_codec = AV_CODEC_ID_PCM_S32LE;
+			outputFmt->audio_codec = AV_CODEC_ID_PCM_S32LE;
 			break;
 		case FORMAT_FLOAT32:
-			m_outputFmt->audio_codec = AV_CODEC_ID_PCM_F32LE;
+			outputFmt->audio_codec = AV_CODEC_ID_PCM_F32LE;
 			break;
 		case FORMAT_FLOAT64:
-			m_outputFmt->audio_codec = AV_CODEC_ID_PCM_F64LE;
+			outputFmt->audio_codec = AV_CODEC_ID_PCM_F64LE;
 			break;
 		default:
-			m_outputFmt->audio_codec = AV_CODEC_ID_NONE;
+			outputFmt->audio_codec = AV_CODEC_ID_NONE;
 			break;
 		}
 		break;
 	case CODEC_VORBIS:
-		m_outputFmt->audio_codec = AV_CODEC_ID_VORBIS;
+		outputFmt->audio_codec = AV_CODEC_ID_VORBIS;
 		break;
 	default:
-		m_outputFmt->audio_codec = AV_CODEC_ID_NONE;
+		outputFmt->audio_codec = AV_CODEC_ID_NONE;
+		break;
+	}
+
+	uint64_t channel_layout = 0;
+
+	switch(m_specs.channels)
+	{
+	case CHANNELS_MONO:
+		channel_layout = AV_CH_LAYOUT_MONO;
+		break;
+	case CHANNELS_STEREO:
+		channel_layout = AV_CH_LAYOUT_STEREO;
+		break;
+	case CHANNELS_STEREO_LFE:
+		channel_layout = AV_CH_LAYOUT_2POINT1;
+		break;
+	case CHANNELS_SURROUND4:
+		channel_layout = AV_CH_LAYOUT_QUAD;
+		break;
+	case CHANNELS_SURROUND5:
+		channel_layout = AV_CH_LAYOUT_5POINT0_BACK;
+		break;
+	case CHANNELS_SURROUND51:
+		channel_layout = AV_CH_LAYOUT_5POINT1_BACK;
+		break;
+	case CHANNELS_SURROUND61:
+		channel_layout = AV_CH_LAYOUT_6POINT1_BACK;
+		break;
+	case CHANNELS_SURROUND71:
+		channel_layout = AV_CH_LAYOUT_7POINT1;
 		break;
 	}
 
 	try
 	{
-		if(m_outputFmt->audio_codec == AV_CODEC_ID_NONE)
+		if(outputFmt->audio_codec == AV_CODEC_ID_NONE)
 			AUD_THROW(FileException, "File couldn't be written, audio codec not found with ffmpeg.");
 
-		AVCodec* codec = avcodec_find_encoder(m_outputFmt->audio_codec);
+		AVCodec* codec = avcodec_find_encoder(outputFmt->audio_codec);
 		if(!codec)
 			AUD_THROW(FileException, "File couldn't be written, audio encoder couldn't be found with ffmpeg.");
 
@@ -220,7 +278,14 @@ FFMPEGWriter::FFMPEGWriter(std::string filename, DeviceSpecs specs, Container fo
 
 		m_stream->id = m_formatCtx->nb_streams - 1;
 
+#ifdef FFMPEG_OLD_CODE
 		m_codecCtx = m_stream->codec;
+#else
+		m_codecCtx = avcodec_alloc_context3(codec);
+#endif
+
+		if(!m_codecCtx)
+			AUD_THROW(FileException, "File couldn't be written, context creation failed with ffmpeg.");
 
 		switch(m_specs.format)
 		{
@@ -247,7 +312,7 @@ FFMPEGWriter::FFMPEGWriter(std::string filename, DeviceSpecs specs, Container fo
 		}
 
 		if(m_formatCtx->oformat->flags & AVFMT_GLOBALHEADER)
-			m_codecCtx->flags |= CODEC_FLAG_GLOBAL_HEADER;
+			m_codecCtx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
 
 		bool format_supported = false;
 
@@ -328,9 +393,13 @@ FFMPEGWriter::FFMPEGWriter(std::string filename, DeviceSpecs specs, Container fo
 
 		m_specs.rate = m_codecCtx->sample_rate;
 
-		m_codecCtx->codec_id = m_outputFmt->audio_codec;
+#ifdef FFMPEG_OLD_CODE
+		m_codecCtx->codec_id = outputFmt->audio_codec;
+#endif
+
 		m_codecCtx->codec_type = AVMEDIA_TYPE_AUDIO;
 		m_codecCtx->bit_rate = bitrate;
+		m_codecCtx->channel_layout = channel_layout;
 		m_codecCtx->channels = m_specs.channels;
 		m_stream->time_base.num = m_codecCtx->time_base.num = 1;
 		m_stream->time_base.den = m_codecCtx->time_base.den = m_codecCtx->sample_rate;
@@ -338,6 +407,11 @@ FFMPEGWriter::FFMPEGWriter(std::string filename, DeviceSpecs specs, Container fo
 		if(avcodec_open2(m_codecCtx, codec, nullptr) < 0)
 			AUD_THROW(FileException, "File couldn't be written, encoder couldn't be opened with ffmpeg.");
 
+#ifndef FFMPEG_OLD_CODE
+		if(avcodec_parameters_from_context(m_stream->codecpar, m_codecCtx) < 0)
+			AUD_THROW(FileException, "File couldn't be written, codec parameters couldn't be copied to the context.");
+#endif
+
 		int samplesize = std::max(int(AUD_SAMPLE_SIZE(m_specs)), AUD_DEVICE_SAMPLE_SIZE(m_specs));
 
 		if((m_input_size = m_codecCtx->frame_size))
@@ -346,13 +420,26 @@ FFMPEGWriter::FFMPEGWriter(std::string filename, DeviceSpecs specs, Container fo
 		if(avio_open(&m_formatCtx->pb, filename.c_str(), AVIO_FLAG_WRITE))
 			AUD_THROW(FileException, "File couldn't be written, file opening failed with ffmpeg.");
 
-		avformat_write_header(m_formatCtx, nullptr);
+		if(avformat_write_header(m_formatCtx, nullptr) < 0)
+			AUD_THROW(FileException, "File couldn't be written, writing the header failed.");
 	}
 	catch(Exception&)
 	{
+#ifndef FFMPEG_OLD_CODE
+		if(m_codecCtx)
+			avcodec_free_context(&m_codecCtx);
+#endif
 		avformat_free_context(m_formatCtx);
 		throw;
 	}
+
+#ifdef FFMPEG_OLD_CODE
+	m_packet = new AVPacket({});
+#else
+	m_packet = av_packet_alloc();
+#endif
+
+	m_frame = av_frame_alloc();
 }
 
 FFMPEGWriter::~FFMPEGWriter()
@@ -365,9 +452,26 @@ FFMPEGWriter::~FFMPEGWriter()
 
 	av_write_trailer(m_formatCtx);
 
+	if(m_frame)
+		av_frame_free(&m_frame);
+
+	if(m_packet)
+	{
+#ifdef FFMPEG_OLD_CODE
+		delete m_packet;
+#else
+		av_packet_free(&m_packet);
+#endif
+	}
+
+#ifdef FFMPEG_OLD_CODE
 	avcodec_close(m_codecCtx);
+#else
+	if(m_codecCtx)
+		avcodec_free_context(&m_codecCtx);
+#endif
 
-	avio_close(m_formatCtx->pb);
+	avio_closep(&m_formatCtx->pb);
 	avformat_free_context(m_formatCtx);
 }
 
diff --git a/plugins/ffmpeg/FFMPEGWriter.h b/plugins/ffmpeg/FFMPEGWriter.h
index 690185d..c22f479 100644
--- a/plugins/ffmpeg/FFMPEGWriter.h
+++ b/plugins/ffmpeg/FFMPEGWriter.h
@@ -66,14 +66,19 @@ class AUD_PLUGIN_API FFMPEGWriter : public IWriter
 	AVCodecContext* m_codecCtx;
 
 	/**
-	 * The AVOutputFormat structure for using ffmpeg.
+	 * The AVStream structure for using ffmpeg.
 	 */
-	AVOutputFormat* m_outputFmt;
+	AVStream* m_stream;
 
 	/**
-	 * The AVStream structure for using ffmpeg.
+	 * The AVPacket structure for using ffmpeg.
 	 */
-	AVStream* m_stream;
+	AVPacket* m_packet;
+
+	/**
+	 * The AVFrame structure for using ffmpeg.
+	 */
+	AVFrame* m_frame;
 
 	/**
 	 * The input buffer for the format converted data before encoding.