<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[146012] trunk/dports/audio/xmms2</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="https://trac.macports.org/changeset/146012">146012</a></dd>
<dt>Author</dt> <dd>devans@macports.org</dd>
<dt>Date</dt> <dd>2016-02-24 13:38:08 -0800 (Wed, 24 Feb 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>xmms2: patch plugin avcodec through upstream commit fc66249 (2014-01-29) for ffmpeg-3.0 compatibility, increment revision.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkdportsaudioxmms2Portfile">trunk/dports/audio/xmms2/Portfile</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkdportsaudioxmms2filespatchffmpeg30diff">trunk/dports/audio/xmms2/files/patch-ffmpeg-3.0.diff</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkdportsaudioxmms2Portfile"></a>
<div class="modfile"><h4>Modified: trunk/dports/audio/xmms2/Portfile (146011 => 146012)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/dports/audio/xmms2/Portfile        2016-02-24 19:59:35 UTC (rev 146011)
+++ trunk/dports/audio/xmms2/Portfile        2016-02-24 21:38:08 UTC (rev 146012)
</span><span class="lines">@@ -6,7 +6,7 @@
</span><span class="cx"> 
</span><span class="cx"> name                    xmms2
</span><span class="cx"> version                 0.8DrO_o
</span><del>-revision                10
</del><ins>+revision                11
</ins><span class="cx"> categories              audio
</span><span class="cx"> # Mostly LGPL, some plugins and clients are GPL
</span><span class="cx"> license                 LGPL-2.1+ GPL-2+ GPL-2
</span><span class="lines">@@ -54,8 +54,13 @@
</span><span class="cx">                         port:libcdio \
</span><span class="cx">                         port:libcdio-paranoia
</span><span class="cx"> 
</span><ins>+# the first 3 patchfiles sequentially patch src/plugins/avcodec - order is important!
+# patch-ffmpeg-3.0.diff patches the avcodec plugin through upstream commit fc66249 (2014-01-29)
+# https://git.xmms2.org/xmms2/xmms2-devel/commit/src/plugins/avcodec?id=fc66249
+
</ins><span class="cx"> patchfiles              patch-ffmpeg-2.0.diff \
</span><span class="cx">                         patch-nellymoser.diff \
</span><ins>+                        patch-ffmpeg-3.0.diff \
</ins><span class="cx">                         patch-src-plugins-modplug-modplug.c.diff \
</span><span class="cx">                         patch-wscript.diff \
</span><span class="cx">                         patch-src-clients-vistest-wscript.diff \
</span></span></pre></div>
<a id="trunkdportsaudioxmms2filespatchffmpeg30diff"></a>
<div class="addfile"><h4>Added: trunk/dports/audio/xmms2/files/patch-ffmpeg-3.0.diff (0 => 146012)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/dports/audio/xmms2/files/patch-ffmpeg-3.0.diff                                (rev 0)
+++ trunk/dports/audio/xmms2/files/patch-ffmpeg-3.0.diff        2016-02-24 21:38:08 UTC (rev 146012)
</span><span class="lines">@@ -0,0 +1,576 @@
</span><ins>+diff -ur src/plugins/avcodec.orig/avcodec.c src/plugins/avcodec/avcodec.c
+--- src/plugins/avcodec.orig/avcodec.c        2016-02-24 11:59:39.000000000 -0800
++++ src/plugins/avcodec/avcodec.c        2016-02-24 12:01:27.000000000 -0800
+@@ -1,7 +1,7 @@
+ /** @file avcodec.c
+  *  Decoder plugin for ffmpeg avcodec formats
+  *
+- *  Copyright (C) 2006-2011 XMMS2 Team
++ *  Copyright (C) 2006-2014 XMMS2 Team
+  *
+  *  This library is free software; you can redistribute it and/or
+  *  modify it under the terms of the GNU Lesser General Public
+@@ -14,20 +14,20 @@
+  *  Lesser General Public License for more details.
+  */

+-#include &quot;xmms_configuration.h&quot;
+-#include &quot;xmms/xmms_xformplugin.h&quot;
+-#include &quot;xmms/xmms_sample.h&quot;
+-#include &quot;xmms/xmms_log.h&quot;
++#include &lt;xmms_configuration.h&gt;
++#include &lt;xmms/xmms_xformplugin.h&gt;
++#include &lt;xmms/xmms_sample.h&gt;
++#include &lt;xmms/xmms_log.h&gt;

+ #include &lt;stdio.h&gt;
+ #include &lt;stdlib.h&gt;
+ #include &lt;string.h&gt;
+ #include &lt;glib.h&gt;
++#include &lt;libavutil/mem.h&gt;

+ #include &quot;avcodec_compat.h&quot;

+ #define AVCODEC_BUFFER_SIZE 16384
+-#define MAX_AUDIO_FRAME_SIZE 192000 // 1 second of 48khz 32bit audio

+ typedef struct {
+         AVCodecContext *codecctx;
+@@ -37,6 +37,8 @@
+         guint buffer_size;
+         gboolean no_demuxer;

++        AVFrame *read_out_frame;
++
+         guint channels;
+         guint samplerate;
+         xmms_sample_format_t sampleformat;
+@@ -54,10 +56,14 @@
+ 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);
++static gint xmms_avcodec_internal_read_some (xmms_xform_t *xform, xmms_avcodec_data_t *data, xmms_error_t *error);
++static gint xmms_avcodec_internal_decode_some (xmms_avcodec_data_t *data);
++static void xmms_avcodec_internal_append (xmms_avcodec_data_t *data);
+ static gint xmms_avcodec_read (xmms_xform_t *xform, xmms_sample_t *buf, gint len,
+                                xmms_error_t *error);
+ static gint64 xmms_avcodec_seek (xmms_xform_t *xform, gint64 samples,
+                                  xmms_xform_seek_mode_t whence, xmms_error_t *err);
++static xmms_sample_format_t xmms_avcodec_translate_sample_format (enum AVSampleFormat av_sample_format);

+ /*
+  * Plugin header
+@@ -93,6 +99,16 @@
+                                       &quot;audio/x-ffmpeg-*&quot;,
+                                       NULL);

++        XMMS_DBG (&quot;avcodec version at build time is %d.%d.%d&quot;,
++                  (LIBAVCODEC_VERSION_INT &gt;&gt; 16),
++                  (LIBAVCODEC_VERSION_INT &gt;&gt; 8) &amp; 0xff,
++                  LIBAVCODEC_VERSION_INT &amp; 0xff);
++        XMMS_DBG (&quot;avcodec version at run time is %d.%d.%d&quot;,
++                  (avcodec_version() &gt;&gt; 16),
++                  (avcodec_version() &gt;&gt; 8) &amp; 0xff,
++                  avcodec_version() &amp; 0xff);
++        XMMS_DBG (&quot;avcodec configuration is %s&quot;, avcodec_configuration());
++
+         return TRUE;
+ }

+@@ -108,6 +124,7 @@

+         avcodec_close (data-&gt;codecctx);
+         av_free (data-&gt;codecctx);
++        av_frame_free (&amp;data-&gt;read_out_frame);

+         g_string_free (data-&gt;outbuf, TRUE);
+         g_free (data-&gt;buffer);
+@@ -133,8 +150,11 @@
+         data-&gt;buffer_size = AVCODEC_BUFFER_SIZE;
+         data-&gt;codecctx = NULL;

++        data-&gt;read_out_frame = av_frame_alloc ();
++
+         xmms_xform_private_data_set (xform, data);

++        avcodec_init ();
+         avcodec_register_all ();

+         mimetype = xmms_xform_indata_get_str (xform,
+@@ -161,12 +181,12 @@
+                 data-&gt;channels = ret;
+         }

+-        /* bitrate required for WMA files */
++        /* Required by WMA xform. */
+         xmms_xform_auxdata_get_int (xform,
+                                     &quot;bitrate&quot;,
+                                     &amp;data-&gt;bitrate);

+-        /* ALAC and MAC require bits per sample field to be 16 */
++        /* Required by tta and apefile xforms. */
+         xmms_xform_auxdata_get_int (xform,
+                                     &quot;samplebits&quot;,
+                                     &amp;data-&gt;samplebits);
+@@ -197,11 +217,11 @@
+                 } else {
+                         /* A demuxer plugin forgot to give decoder config? */
+                         xmms_log_error (&quot;Decoder config data not found!&quot;);
+-                        return FALSE;
++                        goto err;
+                 }
+         }

+-        data-&gt;codecctx = avcodec_alloc_context3 (NULL);
++        data-&gt;codecctx = avcodec_alloc_context3 (codec);
+         data-&gt;codecctx-&gt;sample_rate = data-&gt;samplerate;
+         data-&gt;codecctx-&gt;channels = data-&gt;channels;
+         data-&gt;codecctx-&gt;bit_rate = data-&gt;bitrate;
+@@ -221,7 +241,7 @@

+                 /* some codecs need to have something read before they set
+                  * the samplerate and channels correctly, unfortunately... */
+-                if ((ret = xmms_avcodec_read (xform, buf, 42, &amp;error)) &gt; 0) {
++                if ((ret = xmms_avcodec_read (xform, buf, sizeof (buf), &amp;error)) &gt; 0) {
+                         g_string_insert_len (data-&gt;outbuf, 0, buf, ret);
+                 } else {
+                         XMMS_DBG (&quot;First read failed, codec is not working...&quot;);
+@@ -232,12 +252,17 @@

+         data-&gt;samplerate = data-&gt;codecctx-&gt;sample_rate;
+         data-&gt;channels = data-&gt;codecctx-&gt;channels;
++        data-&gt;sampleformat = xmms_avcodec_translate_sample_format (data-&gt;codecctx-&gt;sample_fmt);
++        if (data-&gt;sampleformat == XMMS_SAMPLE_FORMAT_UNKNOWN) {
++                avcodec_close (data-&gt;codecctx);
++                goto err;
++        }

+         xmms_xform_outdata_type_add (xform,
+                                      XMMS_STREAM_TYPE_MIMETYPE,
+                                      &quot;audio/pcm&quot;,
+                                      XMMS_STREAM_TYPE_FMT_FORMAT,
+-                                     XMMS_SAMPLE_FORMAT_S16,
++                                     data-&gt;sampleformat,
+                                      XMMS_STREAM_TYPE_FMT_CHANNELS,
+                                      data-&gt;channels,
+                                      XMMS_STREAM_TYPE_FMT_SAMPLERATE,
+@@ -252,6 +277,9 @@
+         if (data-&gt;codecctx) {
+                 av_free (data-&gt;codecctx);
+         }
++        if (data-&gt;read_out_frame) {
++                avcodec_free_frame (&amp;data-&gt;read_out_frame);
++        }
+         g_string_free (data-&gt;outbuf, TRUE);
+         g_free (data-&gt;extradata);
+         g_free (data);
+@@ -264,102 +292,24 @@
+                    xmms_error_t *error)
+ {
+         xmms_avcodec_data_t *data;
+-        char outbuf[MAX_AUDIO_FRAME_SIZE];
+-        gint outbufsize, bytes_read = 0;
+         guint size;

+         data = xmms_xform_private_data_get (xform);
+         g_return_val_if_fail (data, -1);

+-        size = MIN (data-&gt;outbuf-&gt;len, len);
+-        while (size == 0) {
+-                AVPacket packet;
+-                av_init_packet (&amp;packet);
++        while (0 == (size = MIN (data-&gt;outbuf-&gt;len, len))) {
++                gint res;

+                 if (data-&gt;no_demuxer || data-&gt;buffer_length == 0) {
+-                        gint read_total;
+-
+-                        bytes_read = xmms_xform_read (xform,
+-                                                      (gchar *) (data-&gt;buffer + data-&gt;buffer_length),
+-                                                      data-&gt;buffer_size - data-&gt;buffer_length,
+-                                                      error);
+-
+-                        if (bytes_read &lt; 0) {
+-                                XMMS_DBG (&quot;Error while reading data&quot;);
+-                                return bytes_read;
+-                        } else if (bytes_read == 0) {
+-                                XMMS_DBG (&quot;EOF&quot;);
+-                                return 0;
+-                        }
++                        gint bytes_read;

+-                        read_total = bytes_read;
+-
+-                        /* If we have a demuxer plugin, make sure we read the whole packet */
+-                        while (read_total == data-&gt;buffer_size &amp;&amp; !data-&gt;no_demuxer) {
+-                                /* multiply the buffer size and try to read again */
+-                                data-&gt;buffer = g_realloc (data-&gt;buffer, data-&gt;buffer_size * 2);
+-                                bytes_read = xmms_xform_read (xform,
+-                                                              (gchar *) data-&gt;buffer +
+-                                                                data-&gt;buffer_size,
+-                                                              data-&gt;buffer_size,
+-                                                              error);
+-                                data-&gt;buffer_size *= 2;
+-
+-                                if (bytes_read &lt; 0) {
+-                                        XMMS_DBG (&quot;Error while reading data&quot;);
+-                                        return bytes_read;
+-                                }
+-
+-                                read_total += bytes_read;
+-
+-                                if (read_total &lt; data-&gt;buffer_size) {
+-                                        /* finally double the buffer size for performance reasons, the
+-                                         * hotspot handling likes to fit two frames in the buffer */
+-                                        data-&gt;buffer = g_realloc (data-&gt;buffer, data-&gt;buffer_size * 2);
+-                                        data-&gt;buffer_size *= 2;
+-                                        XMMS_DBG (&quot;Reallocated avcodec internal buffer to be %d bytes&quot;,
+-                                                  data-&gt;buffer_size);
+-
+-                                        break;
+-                                }
+-                        }
+-
+-                        /* Update the buffer length */
+-                        data-&gt;buffer_length += read_total;
++                        bytes_read = xmms_avcodec_internal_read_some (xform, data, error);
++                        if (bytes_read &lt;= 0) { return bytes_read; }
+                 }

+-                packet.data = data-&gt;buffer;
+-                packet.size = data-&gt;buffer_length;
+-
+-                outbufsize = sizeof (outbuf);
+-                bytes_read = avcodec_decode_audio3 (data-&gt;codecctx, (short *) outbuf,
+-                                                    &amp;outbufsize, &amp;packet);
+-
+-                /* The DTS decoder of ffmpeg is buggy and always returns
+-                 * the input buffer length, get frame length from header */
+-                if (!strcmp (data-&gt;codec_id, &quot;dca&quot;) &amp;&amp; bytes_read &gt; 0) {
+-                        bytes_read = ((int)data-&gt;buffer[5] &lt;&lt; 12) |
+-                                     ((int)data-&gt;buffer[6] &lt;&lt; 4) |
+-                                     ((int)data-&gt;buffer[7] &gt;&gt; 4);
+-                        bytes_read = (bytes_read &amp; 0x3fff) + 1;
+-                }
+-
+-                if (bytes_read &lt; 0 || bytes_read &gt; data-&gt;buffer_length) {
+-                        XMMS_DBG (&quot;Error decoding data!&quot;);
+-                        return -1;
+-                } else if (bytes_read != data-&gt;buffer_length) {
+-                        g_memmove (data-&gt;buffer,
+-                                   data-&gt;buffer + bytes_read,
+-                                   data-&gt;buffer_length - bytes_read);
+-                }
+-
+-                data-&gt;buffer_length -= bytes_read;
+-
+-                if (outbufsize &gt; 0) {
+-                        g_string_append_len (data-&gt;outbuf, outbuf, outbufsize);
+-                }
+-
+-                size = MIN (data-&gt;outbuf-&gt;len, len);
++                res = xmms_avcodec_internal_decode_some (data);
++                if (res &lt; 0) { return res; }
++                if (res &gt; 0) { xmms_avcodec_internal_append (data); }
+         }

+         memcpy (buf, data-&gt;outbuf-&gt;str, size);
+@@ -372,8 +322,6 @@
+ xmms_avcodec_seek (xmms_xform_t *xform, gint64 samples, xmms_xform_seek_mode_t whence, xmms_error_t *err)
+ {
+         xmms_avcodec_data_t *data;
+-        char outbuf[MAX_AUDIO_FRAME_SIZE];
+-        gint outbufsize, bytes_read = 0;
+         gint64 ret = -1;

+         g_return_val_if_fail (xform, -1);
+@@ -391,23 +339,11 @@

+         /* The buggy ape decoder doesn't flush buffers, so we need to finish decoding
+          * the frame before seeking to avoid segfaults... this hack sucks */
++        /* FIXME: Is ^^^ still true? */
+         while (data-&gt;buffer_length &gt; 0) {
+-                AVPacket packet;
+-                av_init_packet (&amp;packet);
+-                packet.data = data-&gt;buffer;
+-                packet.size = data-&gt;buffer_length;
+-
+-                outbufsize = sizeof (outbuf);
+-                bytes_read = avcodec_decode_audio3 (data-&gt;codecctx, (short *) outbuf,
+-                                                    &amp;outbufsize, &amp;packet);
+-
+-                if (bytes_read &lt; 0 || bytes_read &gt; data-&gt;buffer_length) {
+-                        XMMS_DBG (&quot;Error decoding data!&quot;);
++                if (xmms_avcodec_internal_decode_some (data) &lt; 0) {
+                         return -1;
+                 }
+-
+-                data-&gt;buffer_length -= bytes_read;
+-                g_memmove (data-&gt;buffer, data-&gt;buffer + bytes_read, data-&gt;buffer_length);
+         }

+         ret = xmms_xform_seek (xform, samples, whence, err);
+@@ -421,3 +357,178 @@

+         return ret;
+ }
++
++static xmms_sample_format_t
++xmms_avcodec_translate_sample_format (enum AVSampleFormat av_sample_format)
++{
++        switch (av_sample_format) {
++        case AV_SAMPLE_FMT_U8:
++        case AV_SAMPLE_FMT_U8P:
++                return XMMS_SAMPLE_FORMAT_U8;
++        case AV_SAMPLE_FMT_S16:
++        case AV_SAMPLE_FMT_S16P:
++                return XMMS_SAMPLE_FORMAT_S16;
++        case AV_SAMPLE_FMT_S32:
++        case AV_SAMPLE_FMT_S32P:
++                return XMMS_SAMPLE_FORMAT_S32;
++        case AV_SAMPLE_FMT_FLT:
++        case AV_SAMPLE_FMT_FLTP:
++                return XMMS_SAMPLE_FORMAT_FLOAT;
++        case AV_SAMPLE_FMT_DBL:
++        case AV_SAMPLE_FMT_DBLP:
++                return XMMS_SAMPLE_FORMAT_DOUBLE;
++        default:
++                XMMS_DBG (&quot;AVSampleFormat (%i: %s) not supported.&quot;, av_sample_format,
++                          av_get_sample_fmt_name (av_sample_format));
++                return XMMS_SAMPLE_FORMAT_UNKNOWN;
++        }
++}
++
++/*
++Read some data from our source of data to data-&gt;buffer, updating buffer_length
++and buffer_size as needed.
++
++Returns: on error: negative
++         on EOF: zero
++         otherwise: number of bytes read.
++*/
++static gint
++xmms_avcodec_internal_read_some (xmms_xform_t *xform,
++                                 xmms_avcodec_data_t *data,
++                                 xmms_error_t *error)
++{
++        gint bytes_read, read_total;
++
++        bytes_read = xmms_xform_read (xform,
++                                      (gchar *) (data-&gt;buffer + data-&gt;buffer_length),
++                                      data-&gt;buffer_size - data-&gt;buffer_length,
++                                      error);
++
++        if (bytes_read &lt; 0) {
++                XMMS_DBG (&quot;Error while reading data&quot;);
++                return bytes_read;
++        } else if (bytes_read == 0) {
++                XMMS_DBG (&quot;EOF&quot;);
++                return 0;
++        }
++
++        read_total = bytes_read;
++
++        /* If we have a demuxer plugin, make sure we read the whole packet */
++        while (read_total == data-&gt;buffer_size &amp;&amp; !data-&gt;no_demuxer) {
++                /* multiply the buffer size and try to read again */
++                data-&gt;buffer = g_realloc (data-&gt;buffer, data-&gt;buffer_size * 2);
++                bytes_read = xmms_xform_read (xform,
++                                              (gchar *) data-&gt;buffer +
++                                                data-&gt;buffer_size,
++                                              data-&gt;buffer_size,
++                                              error);
++                data-&gt;buffer_size *= 2;
++
++                if (bytes_read &lt; 0) {
++                        XMMS_DBG (&quot;Error while reading data&quot;);
++                        return bytes_read;
++                }
++
++                read_total += bytes_read;
++
++                if (read_total &lt; data-&gt;buffer_size) {
++                        /* finally double the buffer size for performance reasons, the
++                         * hotspot handling likes to fit two frames in the buffer */
++                        data-&gt;buffer = g_realloc (data-&gt;buffer, data-&gt;buffer_size * 2);
++                        data-&gt;buffer_size *= 2;
++                        XMMS_DBG (&quot;Reallocated avcodec internal buffer to be %d bytes&quot;,
++                                  data-&gt;buffer_size);
++
++                        break;
++                }
++        }
++
++        /* Update the buffer length */
++        data-&gt;buffer_length += read_total;
++
++        return read_total;
++}
++
++/*
++Decode some data from data-&gt;buffer[0..data-&gt;buffer_length-1] to
++data-&gt;read_out_frame
++
++Returns: on error: negative
++         on no new data produced: zero
++         otherwise: positive
++
++FIXME: data-&gt;buffer should be at least data-&gt;buffer_length +
++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;
++
++        av_init_packet (&amp;packet);
++        packet.data = data-&gt;buffer;
++        packet.size = data-&gt;buffer_length;
++
++        /* clear buffers and reset fields to defaults */
++        av_frame_unref (data-&gt;read_out_frame);
++
++        bytes_read = avcodec_decode_audio4 (
++                data-&gt;codecctx, data-&gt;read_out_frame, &amp;got_frame, &amp;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-&gt;codec_id, &quot;dca&quot;) &amp;&amp; bytes_read &gt; 0) {
++                bytes_read = ((int)data-&gt;buffer[5] &lt;&lt; 12) |
++                             ((int)data-&gt;buffer[6] &lt;&lt; 4) |
++                             ((int)data-&gt;buffer[7] &gt;&gt; 4);
++                bytes_read = (bytes_read &amp; 0x3fff) + 1;
++        }
++
++        if (bytes_read &lt; 0 || bytes_read &gt; data-&gt;buffer_length) {
++                XMMS_DBG (&quot;Error decoding data!&quot;);
++                return -1;
++        }
++
++        if (bytes_read &lt; data-&gt;buffer_length) {
++                data-&gt;buffer_length -= bytes_read;
++                g_memmove (data-&gt;buffer,
++                           data-&gt;buffer + bytes_read,
++                           data-&gt;buffer_length);
++        } else {
++                data-&gt;buffer_length = 0;
++        }
++
++        return got_frame ? 1 : 0;
++}
++
++static void
++xmms_avcodec_internal_append (xmms_avcodec_data_t *data)
++{
++        enum AVSampleFormat fmt = (enum AVSampleFormat) data-&gt;read_out_frame-&gt;format;
++        int samples = data-&gt;read_out_frame-&gt;nb_samples;
++        int channels = data-&gt;codecctx-&gt;channels;
++        int bps = av_get_bytes_per_sample (fmt);
++
++        if (av_sample_fmt_is_planar (fmt)) {
++                /* Convert from planar to packed format */
++                gint i, j;
++
++                for (i = 0; i &lt; samples; i++) {
++                        for (j = 0; j &lt; channels; j++) {
++                                g_string_append_len (
++                                        data-&gt;outbuf,
++                                        (gchar *) (data-&gt;read_out_frame-&gt;extended_data[j] + i*bps),
++                                        bps
++                                );
++                        }
++                }
++        } else {
++                g_string_append_len (data-&gt;outbuf,
++                                     (gchar *) data-&gt;read_out_frame-&gt;extended_data[0],
++                                     samples * channels * bps);
++        }
++}
+diff -ur src/plugins/avcodec.orig/avcodec_compat.h src/plugins/avcodec/avcodec_compat.h
+--- src/plugins/avcodec.orig/avcodec_compat.h        2016-02-24 11:59:39.000000000 -0800
++++ src/plugins/avcodec/avcodec_compat.h        2016-02-24 12:02:03.000000000 -0800
+@@ -1,7 +1,7 @@
+ /** @file avcodec_compat.h
+  *  Compatibility header for libavcodec backwards compatibility
+  *
+- *  Copyright (C) 2011 XMMS2 Team
++ *  Copyright (C) 2011-2014 XMMS2 Team
+  *
+  *  This library is free software; you can redistribute it and/or
+  *  modify it under the terms of the GNU Lesser General Public
+@@ -65,3 +65,35 @@
+ # define AVMEDIA_TYPE_AUDIO CODEC_TYPE_AUDIO
+ #endif

++/* Calling avcodec_init is not necessary after 53.04 (ffmpeg 0.9) */
++#if LIBAVCODEC_VERSION_INT &gt;= 0x350400
++# define avcodec_init()
++#endif
++
++/* Map avcodec_alloc_context3 into the deprecated version
++ * avcodec_alloc_context in versions earlier than 53.04 (ffmpeg 0.9) */
++#if LIBAVCODEC_VERSION_INT &lt; 0x350400
++# define avcodec_alloc_context3(codec) \
++    avcodec_alloc_context()
++#endif
++
++/* Map avcodec_open2 into the deprecated version
++ * avcodec_open in versions earlier than 53.04 (ffmpeg 0.9) */
++#if LIBAVCODEC_VERSION_INT &lt; 0x350400
++# define avcodec_open2(avctx, codec, options) \
++    avcodec_open(avctx, codec)
++#endif
++
++/* Map avcodec_free_frame to av_freep if the former doesn't exist.
++ * (This is in versions earlier than 54.28.0 (libav) or 54.59.100 (ffmpeg)) */
++#if ! HAVE_AVCODEC_FREE_FRAME
++# define avcodec_free_frame av_freep
++#endif
++
++/* Map av_frame_alloc, av_frame_unref, av_frame_free into their
++ * deprecated versions in versions earlier than 55.28.1 */
++#if LIBAVCODEC_VERSION_INT &lt; 0x371c01
++# define av_frame_alloc avcodec_alloc_frame
++# define av_frame_unref avcodec_get_frame_defaults
++# define av_frame_free avcodec_free_frame
++#endif
+diff -ur src/plugins/avcodec.orig/wscript src/plugins/avcodec/wscript
+--- src/plugins/avcodec.orig/wscript        2016-02-24 11:59:39.000000000 -0800
++++ src/plugins/avcodec/wscript        2016-02-24 12:00:41.000000000 -0800
+@@ -1,10 +1,33 @@
+ from waftools.plugin import plugin

++## Code fragments for configuration
++avcodec_free_frame_fragment = &quot;&quot;&quot;
++#ifdef HAVE_LIBAVCODEC_AVCODEC_H
++# include &quot;libavcodec/avcodec.h&quot;
++#else
++# include &quot;avcodec.h&quot;
++#endif
++int main(void) {
++    AVFrame *frame;
++
++    avcodec_free_frame (&amp;frame);
++
++    return 0;
++}
++&quot;&quot;&quot;
++
+ def plugin_configure(conf):
+     conf.check_cfg(package=&quot;libavcodec&quot;, uselib_store=&quot;avcodec&quot;,
+             args=&quot;--cflags --libs&quot;)
+     conf.check_cc(header_name=&quot;avcodec.h&quot;, uselib=&quot;avcodec&quot;, type=&quot;cshlib&quot;, mandatory=False)
+     conf.check_cc(header_name=&quot;libavcodec/avcodec.h&quot;, uselib=&quot;avcodec&quot;, type=&quot;cshlib&quot;, mandatory=False)

++    # 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=&quot;avcodec&quot;,
++                  uselib_store=&quot;avcodec_free_frame&quot;,
++                  msg=&quot;Checking for function avcodec_free_frame&quot;, mandatory=False)
++
+ configure, build = plugin('avcodec', configure=plugin_configure,
+                           libs=[&quot;avcodec&quot;])
</ins></span></pre>
</div>
</div>

</body>
</html>