From 08272cdee2b886f759ffe632c3310e3ead095b62 Mon Sep 17 00:00:00 2001
From: Max Kellermann <max@musicpd.org>
Date: Sun, 4 Nov 2018 21:55:06 +0100
Subject: [PATCH] decoder/ffmpeg: require FFmpeg 3.1 or later

Drop some compatibility code.
---
 NEWS                                        |  2 +
 src/decoder/plugins/FfmpegDecoderPlugin.cxx | 80 +--------------------
 src/lib/ffmpeg/meson.build                  |  6 +-
 3 files changed, 8 insertions(+), 80 deletions(-)

diff --git a/NEWS b/NEWS
index f3ebb81de..5eca473d4 100644
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,6 @@
 ver 0.21.2 (not yet released)
+* decoder
+  - ffmpeg: require FFmpeg 3.1 or later
 
 ver 0.21.1 (2018/11/04)
 * protocol
diff --git a/src/decoder/plugins/FfmpegDecoderPlugin.cxx b/src/decoder/plugins/FfmpegDecoderPlugin.cxx
index 3d7c6e63d..92ab33afa 100644
--- a/src/decoder/plugins/FfmpegDecoderPlugin.cxx
+++ b/src/decoder/plugins/FfmpegDecoderPlugin.cxx
@@ -105,15 +105,6 @@ ffmpeg_finish() noexcept
 	av_dict_free(&avformat_options);
 }
 
-#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 25, 0) /* FFmpeg 3.1 */
-
-gcc_pure
-static const AVCodecParameters &
-GetCodecParameters(const AVStream &stream) noexcept
-{
-	return *stream.codecpar;
-}
-
 gcc_pure
 static AVSampleFormat
 GetSampleFormat(const AVCodecParameters &codec_params) noexcept
@@ -121,29 +112,11 @@ GetSampleFormat(const AVCodecParameters &codec_params) noexcept
 	return AVSampleFormat(codec_params.format);
 }
 
-#else
-
-gcc_pure
-static const AVCodecContext &
-GetCodecParameters(const AVStream &stream) noexcept
-{
-	return *stream.codec;
-}
-
-gcc_pure
-static AVSampleFormat
-GetSampleFormat(const AVCodecContext &codec_context) noexcept
-{
-	return codec_context.sample_fmt;
-}
-
-#endif
-
 gcc_pure
 static bool
 IsAudio(const AVStream &stream) noexcept
 {
-	return GetCodecParameters(stream).codec_type == AVMEDIA_TYPE_AUDIO;
+	return stream.codecpar->codec_type == AVMEDIA_TYPE_AUDIO;
 }
 
 gcc_pure
@@ -278,8 +251,6 @@ FfmpegSendFrame(DecoderClient &client, InputStream &is,
 				 codec_context.bit_rate / 1000);
 }
 
-#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 37, 0)
-
 static DecoderCommand
 FfmpegReceiveFrames(DecoderClient &client, InputStream &is,
 		    AVCodecContext &codec_context,
@@ -324,8 +295,6 @@ FfmpegReceiveFrames(DecoderClient &client, InputStream &is,
 	}
 }
 
-#endif
-
 /**
  * Decode an #AVPacket and send the resulting PCM data to the decoder
  * API.
@@ -357,7 +326,6 @@ ffmpeg_send_packet(DecoderClient &client, InputStream &is,
 								  stream.time_base));
 	}
 
-#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 37, 0)
 	bool eof = false;
 
 	int err = avcodec_send_packet(&codec_context, &packet);
@@ -386,30 +354,6 @@ ffmpeg_send_packet(DecoderClient &client, InputStream &is,
 
 	if (eof)
 		cmd = DecoderCommand::STOP;
-#else
-	DecoderCommand cmd = DecoderCommand::NONE;
-	while (packet.size > 0 && cmd == DecoderCommand::NONE) {
-		int got_frame = 0;
-		int len = avcodec_decode_audio4(&codec_context,
-						&frame, &got_frame,
-						&packet);
-		if (len < 0) {
-			/* if error, we skip the frame */
-			LogFfmpegError(len, "decoding failed, frame skipped");
-			break;
-		}
-
-		packet.data += len;
-		packet.size -= len;
-
-		if (!got_frame || frame.nb_samples <= 0)
-			continue;
-
-		cmd = FfmpegSendFrame(client, is, codec_context,
-				      frame, skip_bytes,
-				      buffer);
-	}
-#endif
 
 	return cmd;
 }
@@ -585,11 +529,7 @@ FfmpegDecode(DecoderClient &client, InputStream &input,
 
 	AVStream &av_stream = *format_context.streams[audio_stream];
 
-#if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(57, 5, 0)
-	AVCodecContext *codec_context = av_stream.codec;
-#endif
-
-	const auto &codec_params = GetCodecParameters(av_stream);
+	const auto &codec_params = *av_stream.codecpar;
 
 	const AVCodecDescriptor *codec_descriptor =
 		avcodec_descriptor_get(codec_params.codec_id);
@@ -604,7 +544,6 @@ FfmpegDecode(DecoderClient &client, InputStream &input,
 		return;
 	}
 
-#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(57, 5, 0)
 	AVCodecContext *codec_context = avcodec_alloc_context3(codec);
 	if (codec_context == nullptr) {
 		LogError(ffmpeg_domain, "avcodec_alloc_context3() failed");
@@ -615,10 +554,7 @@ FfmpegDecode(DecoderClient &client, InputStream &input,
 		avcodec_free_context(&codec_context);
 	};
 
-#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 25, 0) /* FFmpeg 3.1 */
 	avcodec_parameters_to_context(codec_context, av_stream.codecpar);
-#endif
-#endif
 
 	const SampleFormat sample_format =
 		ffmpeg_sample_format(GetSampleFormat(codec_params));
@@ -642,12 +578,6 @@ FfmpegDecode(DecoderClient &client, InputStream &input,
 		return;
 	}
 
-#if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(57, 5, 0)
-	AtScopeExit(codec_context) {
-		avcodec_close(codec_context);
-	};
-#endif
-
 	const SignedSongTime total_time =
 		av_stream.duration != (int64_t)AV_NOPTS_VALUE
 		? FromFfmpegTimeChecked(av_stream.duration, av_stream.time_base)
@@ -711,11 +641,7 @@ FfmpegDecode(DecoderClient &client, InputStream &input,
 		} else
 			cmd = client.GetCommand();
 
-#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56, 25, 100)
 		av_packet_unref(&packet);
-#else
-		av_free_packet(&packet);
-#endif
 	}
 }
 
@@ -769,7 +695,7 @@ FfmpegScanStream(AVFormatContext &format_context,
 		handler.OnDuration(FromFfmpegTime(format_context.duration,
 						  AV_TIME_BASE_Q));
 
-	const auto &codec_params = GetCodecParameters(stream);
+	const auto &codec_params = *stream.codecpar;
 	try {
 		handler.OnAudioFormat(CheckAudioFormat(codec_params.sample_rate,
 						       ffmpeg_sample_format(GetSampleFormat(codec_params)),
diff --git a/src/lib/ffmpeg/meson.build b/src/lib/ffmpeg/meson.build
index f39c22097..6b90edeba 100644
--- a/src/lib/ffmpeg/meson.build
+++ b/src/lib/ffmpeg/meson.build
@@ -1,6 +1,6 @@
-libavformat_dep = dependency('libavformat', version: '>= 56.1', required: get_option('ffmpeg'))
-libavcodec_dep = dependency('libavcodec', version: '>= 56.1', required: get_option('ffmpeg'))
-libavutil_dep = dependency('libavutil', version: '>= 54.3', required: get_option('ffmpeg'))
+libavformat_dep = dependency('libavformat', version: '>= 57.40', required: get_option('ffmpeg'))
+libavcodec_dep = dependency('libavcodec', version: '>= 57.48', required: get_option('ffmpeg'))
+libavutil_dep = dependency('libavutil', version: '>= 55.27', required: get_option('ffmpeg'))
 
 enable_ffmpeg = libavformat_dep.found() and libavcodec_dep.found() and libavutil_dep.found()
 conf.set('ENABLE_FFMPEG', enable_ffmpeg)