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"])

Reply via email to