[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#1004805: xmms2: FTBFS with ffmpeg 5.0



Dear Maintainer,

I backported the work merged upstream around ffmpeg 5.  Please see attached.
This was sufficient to address the FTBFS both for Sid and Ubuntu Kinetic.

-Dan
Description: ffmpeg 5 compat
Author:      Dan Bungert <daniel.bungert@canonical.com>
Bug-Ubuntu:  https://bugs.launchpad.net/debian/+source/xmms2/+bug/1982419
Bug-Debian:  https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1004805
Forwarded:   not-needed
Origin:      https://github.com/xmms2/xmms2-devel/pull/11
Last-Update: 2022-07-20
diff --git a/src/plugins/avcodec/avcodec.c b/src/plugins/avcodec/avcodec.c
index 23fd4615e..a5c5aa0f4 100644
--- a/src/plugins/avcodec/avcodec.c
+++ b/src/plugins/avcodec/avcodec.c
@@ -31,6 +31,7 @@
 
 typedef struct {
 	AVCodecContext *codecctx;
+	AVPacket packet;
 
 	guchar *buffer;
 	guint buffer_length;
@@ -149,13 +150,12 @@ xmms_avcodec_init (xmms_xform_t *xform)
 	data->buffer = g_malloc (AVCODEC_BUFFER_SIZE);
 	data->buffer_size = AVCODEC_BUFFER_SIZE;
 	data->codecctx = NULL;
+	data->packet.size = 0;
 
 	data->read_out_frame = av_frame_alloc ();
 
 	xmms_xform_private_data_set (xform, data);
 
-	avcodec_register_all ();
-
 	mimetype = xmms_xform_indata_get_str (xform,
 	                                      XMMS_STREAM_TYPE_MIMETYPE);
 	data->codec_id = mimetype + strlen ("audio/x-ffmpeg-");
@@ -466,45 +466,37 @@ FF_INPUT_BUFFER_PADDING_SIZE long.
 static gint
 xmms_avcodec_internal_decode_some (xmms_avcodec_data_t *data)
 {
-	int got_frame = 0;
-	gint bytes_read = 0;
-	AVPacket packet;
+	int rc = 0;
 
-	av_init_packet (&packet);
-	packet.data = data->buffer;
-	packet.size = data->buffer_length;
+	if (data->packet.size == 0) {
+		av_init_packet (&data->packet);
+		data->packet.data = data->buffer;
+		data->packet.size = data->buffer_length;
 
-	/* clear buffers and reset fields to defaults */
-	av_frame_unref (data->read_out_frame);
-
-	bytes_read = avcodec_decode_audio4 (
-		data->codecctx, data->read_out_frame, &got_frame, &packet);
+		rc = avcodec_send_packet(data->codecctx, &data->packet);
+		if (rc == AVERROR_EOF)
+			rc = 0;
+	}
 
-	/* The DTS decoder of ffmpeg is buggy and always returns
-	 * the input buffer length, get frame length from header */
-	/* FIXME: Is ^^^^ still true? */
-	if (!strcmp (data->codec_id, "dca") && bytes_read > 0) {
-		bytes_read = ((int)data->buffer[5] << 12) |
-		             ((int)data->buffer[6] << 4) |
-		             ((int)data->buffer[7] >> 4);
-		bytes_read = (bytes_read & 0x3fff) + 1;
+	if (rc == 0) {
+		rc = avcodec_receive_frame(data->codecctx, data->read_out_frame);
+		if (rc < 0) {
+			data->packet.size = 0;
+			data->buffer_length = 0;
+			if (rc == AVERROR(EAGAIN)) rc = 0;
+			else if (rc == AVERROR_EOF) rc = 1;
+		}
+		else
+			rc = 1;
 	}
 
-	if (bytes_read < 0 || bytes_read > data->buffer_length) {
+	if (rc < 0) {
+		data->packet.size = 0;
 		XMMS_DBG ("Error decoding data!");
 		return -1;
 	}
 
-	if (bytes_read < data->buffer_length) {
-		data->buffer_length -= bytes_read;
-		g_memmove (data->buffer,
-		           data->buffer + bytes_read,
-		           data->buffer_length);
-	} else {
-		data->buffer_length = 0;
-	}
-
-	return got_frame ? 1 : 0;
+	return rc;
 }
 
 static void
diff --git a/src/plugins/avcodec/wscript b/src/plugins/avcodec/wscript
index 00b182b24..4b6227437 100644
--- a/src/plugins/avcodec/wscript
+++ b/src/plugins/avcodec/wscript
@@ -1,7 +1,7 @@
 from waftools.plugin import plugin
 
 ## Code fragments for configuration
-avcodec_decode_audio4_fragment = """
+avcodec_send_packet_fragment = """
 #ifdef HAVE_LIBAVCODEC_AVCODEC_H
 # include "libavcodec/avcodec.h"
 #else
@@ -9,11 +9,9 @@ avcodec_decode_audio4_fragment = """
 #endif
 int main(void) {
     AVCodecContext *ctx;
-    AVFrame *frame;
-    int got_frame;
     AVPacket *pkt;
 
-    avcodec_decode_audio4 (ctx, frame, &got_frame, pkt);
+    avcodec_send_packet (ctx, pkt);
 
     return 0;
 }
@@ -40,12 +38,12 @@ def plugin_configure(conf):
     conf.check_cc(header_name="avcodec.h", uselib="avcodec", type="cshlib", mandatory=False)
     conf.check_cc(header_name="libavcodec/avcodec.h", uselib="avcodec", type="cshlib", mandatory=False)
 
-    # mandatory function avcodec_decode_audio4 available since
-    # * ffmpeg: commit e4de716, lavc 53.40.0, release 0.9
-    # * libav: commit 0eea212, lavc 53.25.0, release 0.8
-    conf.check_cc(fragment=avcodec_decode_audio4_fragment, uselib="avcodec",
-                  uselib_store="avcodec_decode_audio4",
-                  msg="Checking for function avcodec_decode_audio4", mandatory=True)
+    # mandatory function avcodec_send_packet available since
+    # * ffmpeg: commit 7fc329e, lavc 57.37.100, release 3.1
+    # * libav: commit 05f6670, lavc 57.16.0, release 12
+    conf.check_cc(fragment=avcodec_send_packet_fragment, uselib="avcodec",
+                  uselib_store="avcodec_send_packet",
+                  msg="Checking for function avcodec_send_packet", mandatory=True)
 
     # non-mandatory function avcodec_free_frame since
     # * ffmpeg: commit 46a3595, lavc 54.59.100, release 1.0

Reply to: