Index | Thread | Search

From:
Brad Smith <brad@comstyle.com>
Subject:
UPDATE: xmms2
To:
ports@openbsd.org
Date:
Sat, 11 May 2024 01:52:10 -0400

Download raw body.

Thread
  • Brad Smith:

    UPDATE: xmms2

Here is a diff to backport the support for newer FFmpeg API from the
devel repo.


Index: Makefile
===================================================================
RCS file: /cvs/ports/audio/xmms2/Makefile,v
retrieving revision 1.63
diff -u -p -u -p -r1.63 Makefile
--- Makefile	21 Feb 2024 19:23:43 -0000	1.63
+++ Makefile	11 May 2024 05:49:55 -0000
@@ -3,7 +3,7 @@ COMMENT =		audio player daemon with libr
 V =			0.8
 DISTNAME =		xmms2-${V}DrO_o
 PKGNAME =		xmms2-${V}
-REVISION =		18
+REVISION =		19
 
 SHARED_LIBS +=		xmmsclient++		2.0 # 4.0.0
 SHARED_LIBS +=		xmmsclient++-glib	1.0 # 1.0.0
Index: patches/patch-src_plugins_avcodec_avcodec_c
===================================================================
RCS file: /cvs/ports/audio/xmms2/patches/patch-src_plugins_avcodec_avcodec_c,v
retrieving revision 1.5
diff -u -p -u -p -r1.5 patch-src_plugins_avcodec_avcodec_c
--- patches/patch-src_plugins_avcodec_avcodec_c	11 Mar 2022 18:20:36 -0000	1.5
+++ patches/patch-src_plugins_avcodec_avcodec_c	11 May 2024 05:49:55 -0000
@@ -1,7 +1,8 @@
 Deal with newer FFmpeg API.
 
---- src/plugins/avcodec/avcodec.c.orig	Thu Mar 27 01:42:57 2014
-+++ src/plugins/avcodec/avcodec.c	Thu Mar 27 01:52:27 2014
+Index: src/plugins/avcodec/avcodec.c
+--- src/plugins/avcodec/avcodec.c.orig
++++ src/plugins/avcodec/avcodec.c
 @@ -23,6 +23,7 @@
  #include <stdlib.h>
  #include <string.h>
@@ -10,7 +11,14 @@ Deal with newer FFmpeg API.
  
  #include "avcodec_compat.h"
  
-@@ -36,6 +37,8 @@ typedef struct {
+@@ -30,12 +31,15 @@
+ 
+ typedef struct {
+ 	AVCodecContext *codecctx;
++	AVPacket packet;
+ 
+ 	guchar *buffer;
+ 	guint buffer_length;
  	guint buffer_size;
  	gboolean no_demuxer;
  
@@ -19,7 +27,7 @@ Deal with newer FFmpeg API.
  	guint channels;
  	guint samplerate;
  	xmms_sample_format_t sampleformat;
-@@ -53,10 +56,14 @@ typedef struct {
+@@ -53,10 +57,14 @@ typedef struct {
  static gboolean xmms_avcodec_plugin_setup (xmms_xform_plugin_t *xform_plugin);
  static gboolean xmms_avcodec_init (xmms_xform_t *xform);
  static void xmms_avcodec_destroy (xmms_xform_t *xform);
@@ -34,7 +42,7 @@ Deal with newer FFmpeg API.
  
  /*
   * Plugin header
-@@ -85,13 +92,23 @@ xmms_avcodec_plugin_setup (xmms_xform_plugin_t *xform_
+@@ -85,13 +93,23 @@ xmms_avcodec_plugin_setup (xmms_xform_plugin_t *xform_
  	xmms_magic_add ("A/52 (AC-3) header", "audio/x-ffmpeg-ac3",
  	                "0 beshort 0x0b77", NULL);
  	xmms_magic_add ("DTS header", "audio/x-ffmpeg-dca",
@@ -59,7 +67,7 @@ Deal with newer FFmpeg API.
  	return TRUE;
  }
  
-@@ -107,6 +124,7 @@ xmms_avcodec_destroy (xmms_xform_t *xform)
+@@ -107,6 +125,7 @@ xmms_avcodec_destroy (xmms_xform_t *xform)
  
  	avcodec_close (data->codecctx);
  	av_free (data->codecctx);
@@ -67,18 +75,31 @@ Deal with newer FFmpeg API.
  
  	g_string_free (data->outbuf, TRUE);
  	g_free (data->buffer);
-@@ -132,9 +150,10 @@ xmms_avcodec_init (xmms_xform_t *xform)
+@@ -118,7 +137,7 @@ static gboolean
+ xmms_avcodec_init (xmms_xform_t *xform)
+ {
+ 	xmms_avcodec_data_t *data;
+-	AVCodec *codec;
++	const AVCodec *codec;
+ 	const gchar *mimetype;
+ 	const guchar *tmpbuf;
+ 	gsize tmpbuflen;
+@@ -131,12 +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_init ();
- 	avcodec_register_all ();
- 
+-	avcodec_register_all ();
+-
  	mimetype = xmms_xform_indata_get_str (xform,
+ 	                                      XMMS_STREAM_TYPE_MIMETYPE);
+ 	data->codec_id = mimetype + strlen ("audio/x-ffmpeg-");
 @@ -161,12 +180,12 @@ xmms_avcodec_init (xmms_xform_t *xform)
  		data->channels = ret;
  	}
@@ -326,7 +347,7 @@ Deal with newer FFmpeg API.
  	}
  
  	ret = xmms_xform_seek (xform, samples, whence, err);
-@@ -419,4 +358,179 @@ xmms_avcodec_seek (xmms_xform_t *xform, gint64 samples
+@@ -419,4 +358,171 @@ xmms_avcodec_seek (xmms_xform_t *xform, gint64 samples
  	}
  
  	return ret;
@@ -438,45 +459,37 @@ Deal with newer FFmpeg API.
 +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;
-+
-+	/* 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);
-+
-+	/* 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 (data->packet.size == 0) {
++		av_init_packet (&data->packet);
++		data->packet.data = data->buffer;
++		data->packet.size = data->buffer_length;
++
++		rc = avcodec_send_packet(data->codecctx, &data->packet);
++		if (rc == AVERROR_EOF)
++			rc = 0;
 +	}
 +
-+	if (bytes_read < 0 || bytes_read > data->buffer_length) {
-+		XMMS_DBG ("Error decoding data!");
-+		return -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 < data->buffer_length) {
-+		data->buffer_length -= bytes_read;
-+		g_memmove (data->buffer,
-+		           data->buffer + bytes_read,
-+		           data->buffer_length);
-+	} else {
-+		data->buffer_length = 0;
++	if (rc < 0) {
++		data->packet.size = 0;
++		XMMS_DBG ("Error decoding data!");
++		return -1;
 +	}
 +
-+	return got_frame ? 1 : 0;
++	return rc;
 +}
 +
 +static void
Index: patches/patch-src_plugins_avcodec_wscript
===================================================================
RCS file: patches/patch-src_plugins_avcodec_wscript
diff -N patches/patch-src_plugins_avcodec_wscript
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ patches/patch-src_plugins_avcodec_wscript	11 May 2024 05:49:55 -0000
@@ -0,0 +1,62 @@
+Deal with newer FFmpeg API.
+
+Index: src/plugins/avcodec/wscript
+--- src/plugins/avcodec/wscript.orig
++++ src/plugins/avcodec/wscript
+@@ -1,10 +1,56 @@
+ from waftools.plugin import plugin
+ 
++## Code fragments for configuration
++avcodec_send_packet_fragment = """
++#ifdef HAVE_LIBAVCODEC_AVCODEC_H
++# include "libavcodec/avcodec.h"
++#else
++# include "avcodec.h"
++#endif
++int main(void) {
++    AVCodecContext *ctx;
++    AVPacket *pkt;
++
++    avcodec_send_packet (ctx, pkt);
++
++    return 0;
++}
++"""
++
++avcodec_free_frame_fragment = """
++#ifdef HAVE_LIBAVCODEC_AVCODEC_H
++# include "libavcodec/avcodec.h"
++#else
++# include "avcodec.h"
++#endif
++int main(void) {
++    AVFrame *frame;
++
++    avcodec_free_frame (&frame);
++
++    return 0;
++}
++"""
++
+ def plugin_configure(conf):
+     conf.check_cfg(package="libavcodec", uselib_store="avcodec",
+             args="--cflags --libs")
+     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_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
++    # * libav: commit a42aada, lavc 54.28.0, release 9
++    conf.check_cc(fragment=avcodec_free_frame_fragment, uselib="avcodec",
++                  uselib_store="avcodec_free_frame",
++                  msg="Checking for function avcodec_free_frame", mandatory=False)
+ 
+ configure, build = plugin('avcodec', configure=plugin_configure,
+                           libs=["avcodec"])