From 960443c348778e7bae065e6f45531faad50b8415 Mon Sep 17 00:00:00 2001
From: tytan652 <tytan652@tytanium.xyz>
Date: Mon, 11 Nov 2024 19:47:03 +0100
Subject: [PATCH] obs-ffmpeg: Fix deprecation with FFmpeg 7.1

---
 .../obs-ffmpeg/obs-ffmpeg-audio-encoders.c    | 23 +++++++++---
 plugins/obs-ffmpeg/obs-ffmpeg-output.c        | 36 +++++++++++++------
 2 files changed, 44 insertions(+), 15 deletions(-)

diff --git a/plugins/obs-ffmpeg/obs-ffmpeg-audio-encoders.c b/plugins/obs-ffmpeg/obs-ffmpeg-audio-encoders.c
index baa39072b8d56d..4258be19d6ba4f 100644
--- a/plugins/obs-ffmpeg/obs-ffmpeg-audio-encoders.c
+++ b/plugins/obs-ffmpeg/obs-ffmpeg-audio-encoders.c
@@ -236,11 +236,24 @@ static void *enc_create(obs_data_t *settings, obs_encoder_t *encoder, const char
 
 	enc->context->sample_rate = audio_output_get_sample_rate(audio);
 
-	if (enc->codec->sample_fmts) {
+	const enum AVSampleFormat *sample_fmts = NULL;
+	const int *supported_samplerates = NULL;
+
+#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(61, 13, 100)
+	sample_fmts = enc->codec->sample_fmts;
+	supported_samplerates = enc->codec->supported_samplerates;
+#else
+	avcodec_get_supported_config(enc->context, enc->codec, AV_CODEC_CONFIG_SAMPLE_FORMAT, 0,
+				     (const void **)&sample_fmts, NULL);
+	avcodec_get_supported_config(enc->context, enc->codec, AV_CODEC_CONFIG_SAMPLE_RATE, 0,
+				     (const void **)&supported_samplerates, NULL);
+#endif
+
+	if (sample_fmts) {
 		/* Check if the requested format is actually available for the specified
 		 * encoder. This may not always be the case due to FFmpeg changes or a
 		 * fallback being used (for example, when libopus is unavailable). */
-		const enum AVSampleFormat *fmt = enc->codec->sample_fmts;
+		const enum AVSampleFormat *fmt = sample_fmts;
 		while (*fmt != AV_SAMPLE_FMT_NONE) {
 			if (*fmt == sample_format) {
 				enc->context->sample_fmt = *fmt;
@@ -251,15 +264,15 @@ static void *enc_create(obs_data_t *settings, obs_encoder_t *encoder, const char
 
 		/* Fall back to default if requested format was not found. */
 		if (enc->context->sample_fmt == AV_SAMPLE_FMT_NONE)
-			enc->context->sample_fmt = enc->codec->sample_fmts[0];
+			enc->context->sample_fmt = sample_fmts[0];
 	} else {
 		/* Fall back to planar float if codec does not specify formats. */
 		enc->context->sample_fmt = AV_SAMPLE_FMT_FLTP;
 	}
 
 	/* check to make sure sample rate is supported */
-	if (enc->codec->supported_samplerates) {
-		const int *rate = enc->codec->supported_samplerates;
+	if (supported_samplerates) {
+		const int *rate = supported_samplerates;
 		int cur_rate = enc->context->sample_rate;
 		int closest = 0;
 
diff --git a/plugins/obs-ffmpeg/obs-ffmpeg-output.c b/plugins/obs-ffmpeg/obs-ffmpeg-output.c
index 28a0dda03e3ff0..9615abee7a6b37 100644
--- a/plugins/obs-ffmpeg/obs-ffmpeg-output.c
+++ b/plugins/obs-ffmpeg/obs-ffmpeg-output.c
@@ -170,6 +170,7 @@ static bool create_video_stream(struct ffmpeg_data *data)
 	enum AVPixelFormat closest_format;
 	AVCodecContext *context;
 	struct obs_video_info ovi;
+	const enum AVPixelFormat *pix_fmts = NULL;
 
 	if (!obs_get_video_info(&ovi)) {
 		ffmpeg_log_error(LOG_WARNING, data, "No active video");
@@ -180,13 +181,6 @@ static bool create_video_stream(struct ffmpeg_data *data)
 			data->config.video_encoder))
 		return false;
 
-	closest_format = data->config.format;
-	if (data->vcodec->pix_fmts) {
-		const int has_alpha = closest_format == AV_PIX_FMT_BGRA;
-		closest_format =
-			avcodec_find_best_pix_fmt_of_list(data->vcodec->pix_fmts, closest_format, has_alpha, NULL);
-	}
-
 	context = avcodec_alloc_context3(data->vcodec);
 	context->bit_rate = (int64_t)data->config.video_bitrate * 1000;
 	context->width = data->config.scale_width;
@@ -194,14 +188,28 @@ static bool create_video_stream(struct ffmpeg_data *data)
 	context->time_base = (AVRational){ovi.fps_den, ovi.fps_num};
 	context->framerate = (AVRational){ovi.fps_num, ovi.fps_den};
 	context->gop_size = data->config.gop_size;
-	context->pix_fmt = closest_format;
 	context->color_range = data->config.color_range;
 	context->color_primaries = data->config.color_primaries;
 	context->color_trc = data->config.color_trc;
 	context->colorspace = data->config.colorspace;
-	context->chroma_sample_location = determine_chroma_location(closest_format, data->config.colorspace);
 	context->thread_count = 0;
 
+#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(61, 13, 100)
+	pix_fmts = data->vcodec->pix_fmts;
+#else
+	avcodec_get_supported_config(context, data->vcodec, AV_CODEC_CONFIG_PIX_FORMAT, 0, (const void **)&pix_fmts,
+				     NULL);
+#endif
+
+	closest_format = data->config.format;
+	if (pix_fmts) {
+		const int has_alpha = closest_format == AV_PIX_FMT_BGRA;
+		closest_format = avcodec_find_best_pix_fmt_of_list(pix_fmts, closest_format, has_alpha, NULL);
+	}
+
+	context->pix_fmt = closest_format;
+	context->chroma_sample_location = determine_chroma_location(closest_format, data->config.colorspace);
+
 	data->video->time_base = context->time_base;
 	data->video->avg_frame_rate = (AVRational){ovi.fps_num, ovi.fps_den};
 
@@ -305,6 +313,7 @@ static bool create_audio_stream(struct ffmpeg_data *data, int idx)
 	AVStream *stream;
 	struct obs_audio_info aoi;
 	int channels;
+	const enum AVSampleFormat *sample_fmts = NULL;
 
 	if (!obs_get_audio_info(&aoi)) {
 		ffmpeg_log_error(LOG_WARNING, data, "No active audio");
@@ -324,7 +333,14 @@ static bool create_audio_stream(struct ffmpeg_data *data, int idx)
 	if (aoi.speakers == SPEAKERS_4POINT1)
 		context->ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_4POINT1;
 
-	context->sample_fmt = data->acodec->sample_fmts ? data->acodec->sample_fmts[0] : AV_SAMPLE_FMT_FLTP;
+#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(61, 13, 100)
+	sample_fmts = data->acodec->sample_fmts;
+#else
+	avcodec_get_supported_config(context, data->acodec, AV_CODEC_CONFIG_SAMPLE_FORMAT, 0,
+				     (const void **)&sample_fmts, NULL);
+#endif
+
+	context->sample_fmt = sample_fmts ? sample_fmts[0] : AV_SAMPLE_FMT_FLTP;
 
 	stream->time_base = context->time_base;
 
