From f4cbde38021d9330dc73d2e3dfa8a70da3ff5721 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bernhard=20Rosenkr=C3=A4nzer?= <bero@lindev.ch>
Date: Sun, 16 Jan 2022 02:40:04 +0100
Subject: [PATCH 1/2] Fix build with ffmpeg 5.0
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Adapt to ffmpeg 5.0 requiring more const-ness for AVCodec.

Signed-off-by: Bernhard Rosenkränzer <bero@lindev.ch>
---
 src/AV/Output/AudioEncoder.cpp |  6 +++---
 src/AV/Output/AudioEncoder.h   |  4 ++--
 src/AV/Output/BaseEncoder.cpp  |  4 ++--
 src/AV/Output/BaseEncoder.h    |  4 ++--
 src/AV/Output/Muxer.cpp        | 12 ++++++------
 src/AV/Output/Muxer.h          |  4 ++--
 src/AV/Output/VideoEncoder.cpp |  6 +++---
 src/AV/Output/VideoEncoder.h   |  4 ++--
 8 files changed, 22 insertions(+), 22 deletions(-)

diff --git a/src/AV/Output/AudioEncoder.cpp b/src/AV/Output/AudioEncoder.cpp
index 34d015cf..cefc2e02 100644
--- a/src/AV/Output/AudioEncoder.cpp
+++ b/src/AV/Output/AudioEncoder.cpp
@@ -34,7 +34,7 @@ const std::vector<AudioEncoder::SampleFormatData> AudioEncoder::SUPPORTED_SAMPLE
 
 const unsigned int AudioEncoder::DEFAULT_FRAME_SAMPLES = 1024;
 
-AudioEncoder::AudioEncoder(Muxer* muxer, AVStream* stream, AVCodecContext *codec_context, AVCodec* codec, AVDictionary** options)
+AudioEncoder::AudioEncoder(Muxer* muxer, AVStream* stream, AVCodecContext *codec_context, const AVCodec* codec, AVDictionary** options)
 	: BaseEncoder(muxer, stream, codec_context, codec, options) {
 
 #if !SSR_USE_AVCODEC_ENCODE_AUDIO2
@@ -77,7 +77,7 @@ unsigned int AudioEncoder::GetSampleRate() {
 }
 
 bool AudioEncoder::AVCodecIsSupported(const QString& codec_name) {
-	AVCodec *codec = avcodec_find_encoder_by_name(codec_name.toUtf8().constData());
+	const AVCodec *codec = avcodec_find_encoder_by_name(codec_name.toUtf8().constData());
 	if(codec == NULL)
 		return false;
 	if(!av_codec_is_encoder(codec))
@@ -93,7 +93,7 @@ bool AudioEncoder::AVCodecIsSupported(const QString& codec_name) {
 	return false;
 }
 
-void AudioEncoder::PrepareStream(AVStream* stream, AVCodecContext* codec_context, AVCodec* codec, AVDictionary** options, const std::vector<std::pair<QString, QString> >& codec_options,
+void AudioEncoder::PrepareStream(AVStream* stream, AVCodecContext* codec_context, const AVCodec* codec, AVDictionary** options, const std::vector<std::pair<QString, QString> >& codec_options,
 								 unsigned int bit_rate, unsigned int channels, unsigned int sample_rate) {
 
 	if(channels == 0) {
diff --git a/src/AV/Output/AudioEncoder.h b/src/AV/Output/AudioEncoder.h
index c93278cf..ae9c82ee 100644
--- a/src/AV/Output/AudioEncoder.h
+++ b/src/AV/Output/AudioEncoder.h
@@ -40,7 +40,7 @@ class AudioEncoder : public BaseEncoder {
 #endif
 
 public:
-	AudioEncoder(Muxer* muxer, AVStream* stream, AVCodecContext* codec_context, AVCodec* codec, AVDictionary** options);
+	AudioEncoder(Muxer* muxer, AVStream* stream, AVCodecContext* codec_context, const AVCodec* codec, AVDictionary** options);
 	~AudioEncoder();
 
 	// Returns the required frame size, i.e. the number of samples (for each channel).
@@ -57,7 +57,7 @@ class AudioEncoder : public BaseEncoder {
 
 public:
 	static bool AVCodecIsSupported(const QString& codec_name);
-	static void PrepareStream(AVStream* stream, AVCodecContext* codec_context, AVCodec* codec, AVDictionary** options, const std::vector<std::pair<QString, QString> >& codec_options,
+	static void PrepareStream(AVStream* stream, AVCodecContext* codec_context, const AVCodec* codec, AVDictionary** options, const std::vector<std::pair<QString, QString> >& codec_options,
 							  unsigned int bit_rate, unsigned int channels, unsigned int sample_rate);
 
 private:
diff --git a/src/AV/Output/BaseEncoder.cpp b/src/AV/Output/BaseEncoder.cpp
index 7c01ef30..4780aafd 100644
--- a/src/AV/Output/BaseEncoder.cpp
+++ b/src/AV/Output/BaseEncoder.cpp
@@ -42,7 +42,7 @@ double ParseCodecOptionDouble(const QString& key, const QString& value, double m
 	return clamp(value_double, min, max) * multiply;
 }
 
-BaseEncoder::BaseEncoder(Muxer* muxer, AVStream* stream, AVCodecContext* codec_context, AVCodec* codec, AVDictionary** options) {
+BaseEncoder::BaseEncoder(Muxer* muxer, AVStream* stream, AVCodecContext* codec_context, const AVCodec* codec, AVDictionary** options) {
 
 	m_muxer = muxer;
 	m_stream = stream;
@@ -157,7 +157,7 @@ void BaseEncoder::IncrementPacketCounter() {
 	++lock->m_total_packets;
 }
 
-void BaseEncoder::Init(AVCodec* codec, AVDictionary** options) {
+void BaseEncoder::Init(const AVCodec* codec, AVDictionary** options) {
 
 	// open codec
 	if(avcodec_open2(m_codec_context, codec, options) < 0) {
diff --git a/src/AV/Output/BaseEncoder.h b/src/AV/Output/BaseEncoder.h
index 3d92f298..7f02bbd6 100644
--- a/src/AV/Output/BaseEncoder.h
+++ b/src/AV/Output/BaseEncoder.h
@@ -51,7 +51,7 @@ class BaseEncoder {
 	std::atomic<bool> m_should_stop, m_should_finish, m_is_done, m_error_occurred;
 
 protected:
-	BaseEncoder(Muxer* muxer, AVStream* stream, AVCodecContext* codec_context, AVCodec* codec, AVDictionary** options);
+	BaseEncoder(Muxer* muxer, AVStream* stream, AVCodecContext* codec_context, const AVCodec* codec, AVDictionary** options);
 
 public:
 	virtual ~BaseEncoder(); // encoders will be deleted by Muxer, don't delete them yourself!
@@ -117,7 +117,7 @@ class BaseEncoder {
 	void IncrementPacketCounter();
 
 private:
-	void Init(AVCodec* codec, AVDictionary** options);
+	void Init(const AVCodec* codec, AVDictionary** options);
 	void Free();
 
 	void EncoderThread();
diff --git a/src/AV/Output/Muxer.cpp b/src/AV/Output/Muxer.cpp
index ad583803..14650b03 100644
--- a/src/AV/Output/Muxer.cpp
+++ b/src/AV/Output/Muxer.cpp
@@ -87,7 +87,7 @@ Muxer::~Muxer() {
 
 VideoEncoder* Muxer::AddVideoEncoder(const QString& codec_name, const std::vector<std::pair<QString, QString> >& codec_options,
 									 unsigned int bit_rate, unsigned int width, unsigned int height, unsigned int frame_rate) {
-	AVCodec *codec = FindCodec(codec_name);
+	const AVCodec *codec = FindCodec(codec_name);
 	AVCodecContext *codec_context = NULL;
 	AVStream *stream = AddStream(codec, &codec_context);
 	VideoEncoder *encoder;
@@ -111,7 +111,7 @@ VideoEncoder* Muxer::AddVideoEncoder(const QString& codec_name, const std::vecto
 
 AudioEncoder* Muxer::AddAudioEncoder(const QString& codec_name, const std::vector<std::pair<QString, QString> >& codec_options,
 									 unsigned int bit_rate, unsigned int channels, unsigned int sample_rate) {
-	AVCodec *codec = FindCodec(codec_name);
+	const AVCodec *codec = FindCodec(codec_name);
 	AVCodecContext *codec_context = NULL;
 	AVStream *stream = AddStream(codec, &codec_context);
 	AudioEncoder *encoder;
@@ -194,7 +194,7 @@ unsigned int Muxer::GetQueuedPacketCount(unsigned int stream_index) {
 void Muxer::Init() {
 
 	// get the format we want (this is just a pointer, we don't have to free this)
-	AVOutputFormat *format = av_guess_format(m_container_name.toUtf8().constData(), NULL, NULL);
+	const AVOutputFormat *format = av_guess_format(m_container_name.toUtf8().constData(), NULL, NULL);
 	if(format == NULL) {
 		Logger::LogError("[Muxer::Init] " + Logger::tr("Error: Can't find chosen output format!"));
 		throw LibavException();
@@ -261,8 +261,8 @@ void Muxer::Free() {
 	}
 }
 
-AVCodec* Muxer::FindCodec(const QString& codec_name) {
-	AVCodec *codec = avcodec_find_encoder_by_name(codec_name.toUtf8().constData());
+const AVCodec* Muxer::FindCodec(const QString& codec_name) {
+	const AVCodec *codec = avcodec_find_encoder_by_name(codec_name.toUtf8().constData());
 	if(codec == NULL) {
 		Logger::LogError("[Muxer::FindCodec] " + Logger::tr("Error: Can't find codec!"));
 		throw LibavException();
@@ -270,7 +270,7 @@ AVCodec* Muxer::FindCodec(const QString& codec_name) {
 	return codec;
 }
 
-AVStream* Muxer::AddStream(AVCodec* codec, AVCodecContext** codec_context) {
+AVStream* Muxer::AddStream(const AVCodec* codec, AVCodecContext** codec_context) {
 	assert(!m_started);
 	assert(m_format_context->nb_streams < MUXER_MAX_STREAMS);
 
diff --git a/src/AV/Output/Muxer.h b/src/AV/Output/Muxer.h
index d72347d6..b104bcb1 100644
--- a/src/AV/Output/Muxer.h
+++ b/src/AV/Output/Muxer.h
@@ -114,8 +114,8 @@ class Muxer {
 	void Init();
 	void Free();
 
-	AVCodec* FindCodec(const QString& codec_name);
-	AVStream* AddStream(AVCodec* codec, AVCodecContext** codec_context);
+	const AVCodec* FindCodec(const QString& codec_name);
+	AVStream* AddStream(const AVCodec* codec, AVCodecContext** codec_context);
 
 	void MuxerThread();
 
diff --git a/src/AV/Output/VideoEncoder.cpp b/src/AV/Output/VideoEncoder.cpp
index 8087e8ed..fc8b5d11 100644
--- a/src/AV/Output/VideoEncoder.cpp
+++ b/src/AV/Output/VideoEncoder.cpp
@@ -34,7 +34,7 @@ const std::vector<VideoEncoder::PixelFormatData> VideoEncoder::SUPPORTED_PIXEL_F
 	{"rgb", AV_PIX_FMT_RGB24, false},
 };
 
-VideoEncoder::VideoEncoder(Muxer* muxer, AVStream* stream, AVCodecContext* codec_context, AVCodec* codec, AVDictionary** options)
+VideoEncoder::VideoEncoder(Muxer* muxer, AVStream* stream, AVCodecContext* codec_context, const AVCodec* codec, AVDictionary** options)
 	: BaseEncoder(muxer, stream, codec_context, codec, options) {
 
 #if !SSR_USE_AVCODEC_ENCODE_VIDEO2
@@ -95,7 +95,7 @@ unsigned int VideoEncoder::GetFrameRate() {
 }
 
 bool VideoEncoder::AVCodecIsSupported(const QString& codec_name) {
-	AVCodec *codec = avcodec_find_encoder_by_name(codec_name.toUtf8().constData());
+	const AVCodec *codec = avcodec_find_encoder_by_name(codec_name.toUtf8().constData());
 	if(codec == NULL)
 		return false;
 	if(!av_codec_is_encoder(codec))
@@ -111,7 +111,7 @@ bool VideoEncoder::AVCodecIsSupported(const QString& codec_name) {
 	return false;
 }
 
-void VideoEncoder::PrepareStream(AVStream* stream, AVCodecContext* codec_context, AVCodec* codec, AVDictionary** options, const std::vector<std::pair<QString, QString> >& codec_options,
+void VideoEncoder::PrepareStream(AVStream* stream, AVCodecContext* codec_context, const AVCodec* codec, AVDictionary** options, const std::vector<std::pair<QString, QString> >& codec_options,
 								 unsigned int bit_rate, unsigned int width, unsigned int height, unsigned int frame_rate) {
 
 	if(width == 0 || height == 0) {
diff --git a/src/AV/Output/VideoEncoder.h b/src/AV/Output/VideoEncoder.h
index cb7ca275..68d872ed 100644
--- a/src/AV/Output/VideoEncoder.h
+++ b/src/AV/Output/VideoEncoder.h
@@ -40,7 +40,7 @@ class VideoEncoder : public BaseEncoder {
 #endif
 
 public:
-	VideoEncoder(Muxer* muxer, AVStream* stream, AVCodecContext* codec_context, AVCodec* codec, AVDictionary** options);
+	VideoEncoder(Muxer* muxer, AVStream* stream, AVCodecContext* codec_context, const AVCodec* codec, AVDictionary** options);
 	~VideoEncoder();
 
 	// Returns the required pixel format.
@@ -55,7 +55,7 @@ class VideoEncoder : public BaseEncoder {
 
 public:
 	static bool AVCodecIsSupported(const QString& codec_name);
-	static void PrepareStream(AVStream* stream, AVCodecContext* codec_context, AVCodec* codec, AVDictionary** options, const std::vector<std::pair<QString, QString> >& codec_options,
+	static void PrepareStream(AVStream* stream, AVCodecContext* codec_context, const AVCodec* codec, AVDictionary** options, const std::vector<std::pair<QString, QString> >& codec_options,
 							  unsigned int bit_rate, unsigned int width, unsigned int height, unsigned int frame_rate);
 
 private:

From f8988d9f8b48ddfb48079b1a7552c979cff6a912 Mon Sep 17 00:00:00 2001
From: Jordan Bucklin <jordan.bucklin@gmail.com>
Date: Sun, 23 Jun 2024 14:21:28 -0700
Subject: [PATCH 2/2] Update references to AVChannelLayout for compatibility
 with FFmpeg 7

---
 src/AV/Output/AudioEncoder.cpp | 14 +++++++++-----
 src/AV/Output/BaseEncoder.cpp  |  2 +-
 src/AV/Output/Synchronizer.cpp |  2 +-
 3 files changed, 11 insertions(+), 7 deletions(-)

diff --git a/src/AV/Output/AudioEncoder.cpp b/src/AV/Output/AudioEncoder.cpp
index 3efde703..3a38a619 100644
--- a/src/AV/Output/AudioEncoder.cpp
+++ b/src/AV/Output/AudioEncoder.cpp
@@ -42,7 +42,7 @@ AudioEncoder::AudioEncoder(Muxer* muxer, AVStream* stream, AVCodecContext *codec
 	if(GetCodecContext()->frame_size <= 1) {
 		// This is really weird, the old API uses the size of the *output* buffer to determine the number of
 		// input samples if the number of input samples (i.e. frame_size) is not fixed (i.e. frame_size <= 1).
-		m_temp_buffer.resize(DEFAULT_FRAME_SAMPLES * GetCodecContext()->channels * av_get_bits_per_sample(GetCodecContext()->codec_id) / 8);
+		m_temp_buffer.resize(DEFAULT_FRAME_SAMPLES * GetCodecContext()->ch_layout.nb_channels * av_get_bits_per_sample(GetCodecContext()->codec_id) / 8);
 	} else {
 		m_temp_buffer.resize(std::max(FF_MIN_BUFFER_SIZE, 256 * 1024));
 	}
@@ -53,6 +53,7 @@ AudioEncoder::AudioEncoder(Muxer* muxer, AVStream* stream, AVCodecContext *codec
 }
 
 AudioEncoder::~AudioEncoder() {
+    av_channel_layout_uninit(&GetCodecContext()->ch_layout);
 	StopThread();
 }
 
@@ -69,7 +70,7 @@ AVSampleFormat AudioEncoder::GetSampleFormat() {
 }
 
 unsigned int AudioEncoder::GetChannels() {
-	return GetCodecContext()->channels;
+	return GetCodecContext()->ch_layout.nb_channels;
 }
 
 unsigned int AudioEncoder::GetSampleRate() {
@@ -107,8 +108,11 @@ void AudioEncoder::PrepareStream(AVStream* stream, AVCodecContext* codec_context
 	}
 
 	codec_context->bit_rate = bit_rate;
-	codec_context->channels = channels;
-	codec_context->channel_layout = (channels == 1)? AV_CH_LAYOUT_MONO : AV_CH_LAYOUT_STEREO;
+    if(channels == 1) {
+        av_channel_layout_from_mask(&codec_context->ch_layout, AV_CH_LAYOUT_MONO);
+    } else {
+        av_channel_layout_from_mask(&codec_context->ch_layout, AV_CH_LAYOUT_STEREO);
+    }
 	codec_context->sample_rate = sample_rate;
 	codec_context->time_base.num = 1;
 	codec_context->time_base.den = sample_rate;
@@ -158,7 +162,7 @@ bool AudioEncoder::EncodeFrame(AVFrameWrapper* frame) {
 		assert((unsigned int) frame->GetFrame()->nb_samples == GetFrameSize());
 #endif
 #if SSR_USE_AVFRAME_CHANNELS
-		assert(frame->GetFrame()->channels == GetCodecContext()->channels);
+		assert(frame->GetFrame()->channels == GetCodecContext()->ch_layout.nb_channels);
 #endif
 #if SSR_USE_AVFRAME_SAMPLE_RATE
 		assert(frame->GetFrame()->sample_rate == GetCodecContext()->sample_rate);
diff --git a/src/AV/Output/BaseEncoder.cpp b/src/AV/Output/BaseEncoder.cpp
index 7c01ef30..6fa8bbca 100644
--- a/src/AV/Output/BaseEncoder.cpp
+++ b/src/AV/Output/BaseEncoder.cpp
@@ -176,7 +176,7 @@ void BaseEncoder::Init(AVCodec* codec, AVDictionary** options) {
 
 void BaseEncoder::Free() {
 	if(m_codec_opened) {
-		avcodec_close(m_codec_context);
+		avcodec_free_context(&m_codec_context);
 		m_codec_opened = false;
 	}
 }
diff --git a/src/AV/Output/Synchronizer.cpp b/src/AV/Output/Synchronizer.cpp
index b109dc67..0faa28d7 100644
--- a/src/AV/Output/Synchronizer.cpp
+++ b/src/AV/Output/Synchronizer.cpp
@@ -180,7 +180,7 @@ static std::unique_ptr<AVFrameWrapper> CreateAudioFrame(unsigned int channels, u
 	frame->GetFrame()->nb_samples = samples;
 #endif
 #if SSR_USE_AVFRAME_CHANNELS
-	frame->GetFrame()->channels = channels;
+	frame->GetFrame()->ch_layout.nb_channels = channels;
 #endif
 #if SSR_USE_AVFRAME_SAMPLE_RATE
 	frame->GetFrame()->sample_rate = sample_rate;
