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: