diff --git a/audio/xmms2/Makefile b/audio/xmms2/Makefile index 7ecbc88b07e3..5d200575375d 100644 --- a/audio/xmms2/Makefile +++ b/audio/xmms2/Makefile @@ -1,392 +1,396 @@ # Created by: Alexander Botero-Lowry # $FreeBSD$ PORTNAME?= xmms2 PORTVERSION= 0.8 -PORTREVISION?= 5 DISTVERSIONSUFFIX=DrO_o +PORTREVISION?= 5 CATEGORIES?= audio MASTER_SITES= SF/${PORTNAME}/${PORTNAME}/${PORTVERSION}%20${DISTVERSIONSUFFIX} MAINTAINER?= madpilot@FreeBSD.org COMMENT?= Rewrite of xmms as a client/server system (developer release) USE_BZIP2= yes USE_PYTHON_BUILD= yes USES+= pkgconfig .if !defined(XMMS2_SLAVE) USE_GNOME= glib20 USE_SQLITE= 3 USE_LDCONFIG= yes PLIST_SUB+= INCLUDEDIR="include/${PORTNAME}" LIBDIR="lib/${PORTNAME}" CPPFLAGS+= -I${LOCALBASE}/include OPTIONS_DEFINE= AIRPLAY AO APE AVCODEC CDDA CURL ET FAAD FAM FLAC \ GME GVFS ICES JACK MAD MDNS MMS \ MODPLUG MPG123 MUSEPACK OFA PULSEAUDIO SAMBA SID \ SNDFILE SPEEX TREMOR VISUAL VOCODER VORBIS WAVPACK XML OPTIONS_SINGLE= MDNS OPTIONS_SINGLE_MDNS= MDNS_APPLE MDNS_AVAHI OPTIONS_DEFAULT= CURL FAAD FLAC MAD MDNS MDNS_APPLE VORBIS AIRPLAY_DESC= Support output via Airport Express AVCODEC_DESC= Avcodevc playback support CDDA_DESC= AudioCD support ET_DESC= Install usage feedback reporting client FAM_DESC= Support to update Media Library on file change GME_DESC= Video game music files support GVFS_DESC= Playback files via GVFS ICES_DESC= Playback files to an icecast server MDNS_DESC= Announce XMMS2d via mDNS (Choose implementation) MDNS_APPLE_DESC= Use Apple mDNS implementation MDNS_AVAHI_DESC= Use Avahi mDNS implementation OFA_DESC= Collect MusicDNS fingerprints SAMBA_DESC= Playback files via SMB SID_DESC= Playback SID files VISUAL_DESC= Visualization plugins support VOCODER_DESC= Phase Vocoder effect plugin WAVPACK_DESC= Playback WV files XML_DESC= Support XML based playlists (XSPF, RSS) .endif # !XMMS_SLAVE .include .if defined(XMMS2_SLAVE) EXCLUDE+= --without-xmms2d .if ${XMMS2_SLAVE} == "python" EXCLUDE+= --with-optionals="python" .elif ${XMMS2_SLAVE} == "ruby" EXCLUDE+= --with-optionals="ruby" .elif ${XMMS2_SLAVE} == "perl" EXCLUDE+= --with-optionals="perl" .elif ${XMMS2_SLAVE} == "ruby-ecore" EXCLUDE+= --with-optionals="ruby" --with-optionals="xmmsclient-ecore" .elif ${XMMS2_SLAVE} == "cpp" EXCLUDE+= --with-optionals="xmmsclient++" \ --with-optionals="xmmsclient++-glib" .endif .else # XMMS2_SLAVE EXCLUDE+= --without-optionals="python" \ --without-optionals="ruby" \ --without-optionals="xmmsclient-ecore" \ --without-optionals="xmmsclient++" \ --without-optionals="xmmsclient++-glib" \ --without-optionals="perl" .endif # XMMS2_SLAVE .if !defined(XMMS2_SLAVE) .if ${PORT_OPTIONS:MAIRPLAY} USE_OPENSSL= yes PLIST_SUB+= AIRPLAY="" .else EXCLUDE+= --without-plugins="airplay" PLIST_SUB+= AIRPLAY="@comment " .endif .if ${PORT_OPTIONS:MAO} LIB_DEPENDS+= libao.so:${PORTSDIR}/audio/libao PLIST_SUB+= AO="" .else EXCLUDE+= --without-plugins="ao" PLIST_SUB+= AO="@comment " .endif .if ${PORT_OPTIONS:MAPE} LIB_DEPENDS+= libmac.so:${PORTSDIR}/audio/mac PLIST_SUB+= MAC="" .else EXCLUDE+= --without-plugins="mac" PLIST_SUB+= MAC="@comment " .endif .if ${PORT_OPTIONS:MAVCODEC} LIB_DEPENDS+= libavutil.so:${PORTSDIR}/multimedia/ffmpeg PLIST_SUB+= AVCODEC="" .else EXCLUDE+= --without-plugins="avcodec" PLIST_SUB+= AVCODEC="@comment " .endif .if ${PORT_OPTIONS:MCDDA} LIB_DEPENDS+= libcdio.so:${PORTSDIR}/sysutils/libcdio \ libdiscid.so:${PORTSDIR}/audio/libdiscid PLIST_SUB+= CDDA="" .else EXCLUDE+= --without-plugins="cdda" PLIST_SUB+= CDDA="@comment " .endif .if ${PORT_OPTIONS:MCURL} LIB_DEPENDS+= libcurl.so:${PORTSDIR}/ftp/curl PLIST_SUB+= CURL="" .else EXCLUDE+= --without-plugins="curl" --without-plugins="icymetaint" PLIST_SUB+= CURL="@comment " .endif .if ${PORT_OPTIONS:MFAAD} LIB_DEPENDS+= libfaad.so:${PORTSDIR}/audio/faad PLIST_SUB+= FAAD="" .else EXCLUDE+= --without-plugins="faad" --without-plugins="mp4" PLIST_SUB+= FAAD="@comment " .endif .if ${PORT_OPTIONS:MFAM} USES+= fam:gamin PLIST_SUB+= FAM="" .else EXCLUDE+= --without-optionals="medialib-updater" PLIST_SUB+= FAM="@comment " .endif .if ${PORT_OPTIONS:MFLAC} LIB_DEPENDS+= libFLAC.so:${PORTSDIR}/audio/flac PLIST_SUB+= FLAC="" .else EXCLUDE+= --without-plugins="flac" PLIST_SUB+= FLAC="@comment " .endif .if ${PORT_OPTIONS:MGME} LIB_DEPENDS+= libgme.so:${PORTSDIR}/audio/libgme PLIST_SUB+= GME="" .else EXCLUDE+= --without-plugins="gme" PLIST_SUB+= GME="@comment " .endif .if ${PORT_OPTIONS:MGVFS} USE_GNOME+= gvfs PLIST_SUB+= GVFS="" .else EXCLUDE+= --without-plugins="gvfs" PLIST_SUB+= GVFS="@comment " .endif .if ${PORT_OPTIONS:MICES} LIB_DEPENDS+= libshout.so:${PORTSDIR}/audio/libshout2 PLIST_SUB+= ICES="" .else EXCLUDE+= --without-plugins="ices" PLIST_SUB+= ICES="@comment " .endif .if ${PORT_OPTIONS:MJACK} LIB_DEPENDS+= libjack.so:${PORTSDIR}/audio/jack PLIST_SUB+= JACK="" .else EXCLUDE+= --without-plugins="jack" PLIST_SUB+= JACK="@comment " .endif .if ${PORT_OPTIONS:MMAD} LIB_DEPENDS+= libmad.so:${PORTSDIR}/audio/libmad PLIST_SUB+= MAD="" .else EXCLUDE+= --without-plugins="mad" PLIST_SUB+= MAD="@comment " .endif .if empty(PORT_OPTIONS:MMDNS) EXCLUDE+= --without-optionals="mdns" .endif .if ${PORT_OPTIONS:MMDNS_APPLE} EXCLUDE+= --with-mdns-backend="dns_sd" LIB_DEPENDS+= libdns_sd.so:${PORTSDIR}/net/mDNSResponder PLIST_SUB+= MDNS_APPLE="" .else PLIST_SUB+= MDNS_APPLE="@comment " .endif .if ${PORT_OPTIONS:MMDNS_AVAHI} EXCLUDE+= --with-mdns-backend="avahi" LIB_DEPENDS+= libavahi-core.so:${PORTSDIR}/net/avahi-app PLIST_SUB+= MDNS_AVAHI="" MAN1+= xmms2-mdns-avahi.1 .else PLIST_SUB+= MDNS_AVAHI="@comment " .endif .if ${PORT_OPTIONS:MMMS} LIB_DEPENDS+= libmms.so:${PORTSDIR}/net/libmms PLIST_SUB+= MMS="" .else EXCLUDE+= --without-plugins="mms" PLIST_SUB+= MMS="@comment " .endif .if ${PORT_OPTIONS:MMODPLUG} LIB_DEPENDS+= libmodplug.so:${PORTSDIR}/audio/libmodplug PLIST_SUB+= MODPLUG="" .else EXCLUDE+= --without-plugins="modplug" PLIST_SUB+= MODPLUG="@comment " .endif .if ${PORT_OPTIONS:MMPG123} LIB_DEPENDS+= libmpg123.so:${PORTSDIR}/audio/mpg123 PLIST_SUB+= MPG123="" .else EXCLUDE+= --without-plugins="mpg123" PLIST_SUB+= MPG123="@comment " .endif .if ${PORT_OPTIONS:MMUSEPACK} LIB_DEPENDS+= libmpcdec.so:${PORTSDIR}/audio/musepack PLIST_SUB+= MUSEPACK="" .else EXCLUDE+= --without-plugins="musepack" PLIST_SUB+= MUSEPACK="@comment " .endif .if ${PORT_OPTIONS:MOFA} LIB_DEPENDS+= libofa.so:${PORTSDIR}/audio/libofa PLIST_SUB+= OFA="" .else EXCLUDE+= --without-plugins="ofa" PLIST_SUB+= OFA="@comment " .endif .if ${PORT_OPTIONS:MPULSEAUDIO} LIB_DEPENDS+= libpulse.so:${PORTSDIR}/audio/pulseaudio PLIST_SUB+= PULSE="" .else EXCLUDE+= --without-plugins="pulse" PLIST_SUB+= PULSE="@comment " .endif .if ${PORT_OPTIONS:MSAMBA} LIB_DEPENDS+= libsmbclient.so:${PORTSDIR}/net/samba-libsmbclient PLIST_SUB+= SAMBA="" .else EXCLUDE+= --without-plugins="samba" PLIST_SUB+= SAMBA="@comment " .endif .if ${PORT_OPTIONS:MSID} LIB_DEPENDS+= libsidplay2.so:${PORTSDIR}/audio/libsidplay2 PLIST_SUB+= SID="" .else EXCLUDE+= --without-plugins="sid" PLIST_SUB+= SID="@comment " .endif .if ${PORT_OPTIONS:MSNDFILE} LIB_DEPENDS+= libsndfile.so:${PORTSDIR}/audio/libsndfile PLIST_SUB+= SNDFILE="" .else EXCLUDE+= --without-plugins="sndfile" PLIST_SUB+= SNDFILE="@comment " .endif .if ${PORT_OPTIONS:MSPEEX} LIB_DEPENDS+= libspeex.so:${PORTSDIR}/audio/speex PLIST_SUB+= SPEEX="" .else EXCLUDE+= --without-plugins="speex" PLIST_SUB+= SPEEX="@comment " .endif .if ${PORT_OPTIONS:MTREMOR} LIB_DEPENDS+= libvorbisidec.so:${PORTSDIR}/audio/libtremor PLIST_SUB+= TREMOR="" .else EXCLUDE+= --without-plugins="tremor" PLIST_SUB+= TREMOR="@comment " .endif # xmms2-ripper .if ${PORT_OPTIONS:MVISUAL} && ${PORT_OPTIONS:MVORBIS} LIB_DEPENDS+= libvorbisenc.so:${PORTSDIR}/audio/libvorbis .else EXTRA_PATCHES+= ${FILESDIR}/extra-patch-src-clients-vistest-wscript .endif # XXX: shm support requires semtimedop(2) .if ${PORT_OPTIONS:MVISUAL} USE_SDL= yes LIB_DEPENDS+= libvisual-0.4.so:${PORTSDIR}/graphics/libvisual04 .else EXCLUDE+= --without-optionals="vistest" .endif .if ${PORT_OPTIONS:MVISUAL} && ${EXCLUDE:M--with-vis-reference-clients} PLIST_SUB+= VISUAL="" .else PLIST_SUB+= VISUAL="@comment " .endif .if ${PORT_OPTIONS:MVOCODER} LIB_DEPENDS+= libfftw3f.so:${PORTSDIR}/math/fftw3-float \ libsamplerate.so:${PORTSDIR}/audio/libsamplerate PLIST_SUB+= VOCODER="" .else EXCLUDE+= --without-plugins="vocoder" PLIST_SUB+= VOCODER="@comment " .endif .if ${PORT_OPTIONS:MVORBIS} LIB_DEPENDS+= libvorbis.so:${PORTSDIR}/audio/libvorbis PLIST_SUB+= VORBIS="" .else EXCLUDE+= --without-plugins="vorbis" PLIST_SUB+= VORBIS="@comment " .endif .if ${PORT_OPTIONS:MWAVPACK} LIB_DEPENDS+= libwavpack.so:${PORTSDIR}/audio/wavpack PLIST_SUB+= WAVPACK="" .else EXCLUDE+= --without-plugins="wavpack" PLIST_SUB+= WAVPACK="@comment " .endif .if ${PORT_OPTIONS:MXML} USE_GNOME+= libxml2 PLIST_SUB+= XML="" .else EXCLUDE+= --without-plugins="xml" --without-plugins="rss" \ --without-plugins="xspf" PLIST_SUB+= XML="@comment " .endif .if ${PORT_OPTIONS:MET} PLIST_SUB+= ET="" MAN1+= xmms2-et.1 .else EXCLUDE+= --without-optionals="et" PLIST_SUB+= ET="@comment " .endif .endif # !XMMS2_SLAVE post-patch: @${REINPLACE_CMD} -e "s|%%WRKSRC%%|${WRKSRC}|" ${WRKSRC}/wscript +.if ${PORT_OPTIONS:MVISUAL} && ${PORT_OPTIONS:MVORBIS} + @${REINPLACE_CMD} -e "s|'vorbisenc',|'vorbisenc vorbis ogg',|" \ + ${WRKSRC}/src/clients/vistest/wscript +.endif do-configure: cd ${WRKSRC} && ${SETENV} ${MAKE_ENV} ${PYTHON_CMD} waf ${_MAKE_JOBS} configure \ --conf-prefix=${LOCALBASE} --prefix=${PREFIX} \ --mandir=${PREFIX}/man ${EXCLUDE} do-build: cd ${WRKSRC} && ${SETENV} ${MAKE_ENV} ${PYTHON_CMD} waf ${_MAKE_JOBS} build do-install: cd ${WRKSRC} && ${SETENV} ${MAKE_ENV} ${PYTHON_CMD} waf install --destdir=${STAGEDIR} --without-ldconfig .if !defined(XMMS2_SLAVE) if [ ! -d ${STAGEDIR}${DATADIR}/scripts/startup.d ]; then \ ${MKDIR} ${STAGEDIR}${DATADIR}/scripts/startup.d; \ fi .endif .include diff --git a/audio/xmms2/files/patch-src_plugins_avcodec_avcodec.c b/audio/xmms2/files/patch-src_plugins_avcodec_avcodec.c index 13988ff5a6c4..f7b5449c557e 100644 --- a/audio/xmms2/files/patch-src_plugins_avcodec_avcodec.c +++ b/audio/xmms2/files/patch-src_plugins_avcodec_avcodec.c @@ -1,13 +1,527 @@ ---- src/plugins/avcodec/avcodec.c.orig 2013-10-25 14:04:33.493859184 -0200 -+++ src/plugins/avcodec/avcodec.c 2013-10-25 14:08:39.342858585 -0200 -@@ -28,6 +28,10 @@ +--- src/plugins/avcodec/avcodec.c.orig 2011-10-20 21:26:08.000000000 +0200 ++++ src/plugins/avcodec/avcodec.c 2014-02-27 18:55:51.060717698 +0100 +@@ -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,15 +14,16 @@ + * Lesser General Public License for more details. + */ - #define AVCODEC_BUFFER_SIZE 16384 +-#include "xmms_configuration.h" +-#include "xmms/xmms_xformplugin.h" +-#include "xmms/xmms_sample.h" +-#include "xmms/xmms_log.h" ++#include ++#include ++#include ++#include -+#ifndef AVCODEC_MAX_AUDIO_FRAME_SIZE -+#define AVCODEC_MAX_AUDIO_FRAME_SIZE 192000 // 1 second of 48khz 32bit audio -+#endif + #include + #include + #include + #include ++#include + + #include "avcodec_compat.h" + +@@ -36,6 +37,8 @@ + guint buffer_size; + gboolean no_demuxer; + ++ AVFrame *read_out_frame; ++ + guint channels; + guint samplerate; + xmms_sample_format_t sampleformat; +@@ -53,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 +@@ -85,13 +92,23 @@ + 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", +- "0 belong 0x7ffe8001", NULL); ++ "0 belong 0x7ffe8001", NULL); + + xmms_xform_plugin_indata_add (xform_plugin, + XMMS_STREAM_TYPE_MIMETYPE, + "audio/x-ffmpeg-*", + NULL); + ++ XMMS_DBG ("avcodec version at build time is %d.%d.%d", ++ (LIBAVCODEC_VERSION_INT >> 16), ++ (LIBAVCODEC_VERSION_INT >> 8) & 0xff, ++ LIBAVCODEC_VERSION_INT & 0xff); ++ XMMS_DBG ("avcodec version at run time is %d.%d.%d", ++ (avcodec_version() >> 16), ++ (avcodec_version() >> 8) & 0xff, ++ avcodec_version() & 0xff); ++ XMMS_DBG ("avcodec configuration is %s", avcodec_configuration()); + - typedef struct { - AVCodecContext *codecctx; + return TRUE; + } + +@@ -107,6 +124,7 @@ + + avcodec_close (data->codecctx); + av_free (data->codecctx); ++ av_frame_free (&data->read_out_frame); + + g_string_free (data->outbuf, TRUE); + g_free (data->buffer); +@@ -132,9 +150,10 @@ + data->buffer_size = AVCODEC_BUFFER_SIZE; + data->codecctx = NULL; + ++ data->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 +180,12 @@ + data->channels = ret; + } + +- /* bitrate required for WMA files */ ++ /* Required by WMA xform. */ + xmms_xform_auxdata_get_int (xform, + "bitrate", + &data->bitrate); + +- /* ALAC and MAC require bits per sample field to be 16 */ ++ /* Required by tta and apefile xforms. */ + xmms_xform_auxdata_get_int (xform, + "samplebits", + &data->samplebits); +@@ -188,7 +207,8 @@ + !strcmp (data->codec_id, "adpcm_swf") || + !strcmp (data->codec_id, "pcm_s16le") || + !strcmp (data->codec_id, "ac3") || +- !strcmp (data->codec_id, "dca")) { ++ !strcmp (data->codec_id, "dca") || ++ !strcmp (data->codec_id, "nellymoser")) { + /* number 1024 taken from libavformat raw.c RAW_PACKET_SIZE */ + data->extradata = g_malloc0 (1024); + data->extradata_size = 1024; +@@ -196,22 +216,22 @@ + } else { + /* A demuxer plugin forgot to give decoder config? */ + xmms_log_error ("Decoder config data not found!"); +- return FALSE; ++ goto err; + } + } + +- data->codecctx = avcodec_alloc_context (); ++ data->codecctx = avcodec_alloc_context3 (codec); + data->codecctx->sample_rate = data->samplerate; + data->codecctx->channels = data->channels; + data->codecctx->bit_rate = data->bitrate; +- CONTEXT_BPS (data->codecctx) = data->samplebits; ++ data->codecctx->bits_per_coded_sample = data->samplebits; + data->codecctx->block_align = data->block_align; + data->codecctx->extradata = data->extradata; + data->codecctx->extradata_size = data->extradata_size; + data->codecctx->codec_id = codec->id; + data->codecctx->codec_type = codec->type; + +- if (avcodec_open (data->codecctx, codec) < 0) { ++ if (avcodec_open2 (data->codecctx, codec, NULL) < 0) { + XMMS_DBG ("Opening decoder '%s' failed", codec->name); + goto err; + } else { +@@ -220,7 +240,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, &error)) > 0) { ++ if ((ret = xmms_avcodec_read (xform, buf, sizeof (buf), &error)) > 0) { + g_string_insert_len (data->outbuf, 0, buf, ret); + } else { + XMMS_DBG ("First read failed, codec is not working..."); +@@ -231,19 +251,27 @@ + + data->samplerate = data->codecctx->sample_rate; + data->channels = data->codecctx->channels; ++ data->sampleformat = xmms_avcodec_translate_sample_format (data->codecctx->sample_fmt); ++ if (data->sampleformat == XMMS_SAMPLE_FORMAT_UNKNOWN) { ++ avcodec_close (data->codecctx); ++ goto err; ++ } + + xmms_xform_outdata_type_add (xform, + XMMS_STREAM_TYPE_MIMETYPE, + "audio/pcm", + XMMS_STREAM_TYPE_FMT_FORMAT, +- XMMS_SAMPLE_FORMAT_S16, ++ data->sampleformat, + XMMS_STREAM_TYPE_FMT_CHANNELS, + data->channels, + XMMS_STREAM_TYPE_FMT_SAMPLERATE, + data->samplerate, + XMMS_STREAM_TYPE_END); + +- XMMS_DBG ("Decoder '%s' initialized successfully!", codec->name); ++ XMMS_DBG ("Decoder %s at rate %d with %d channels of format %s initialized", ++ codec->name, data->codecctx->sample_rate, ++ data->codecctx->channels, ++ av_get_sample_fmt_name (data->codecctx->sample_fmt)); + + return TRUE; + +@@ -251,6 +279,9 @@ + if (data->codecctx) { + av_free (data->codecctx); + } ++ if (data->read_out_frame) { ++ avcodec_free_frame (&data->read_out_frame); ++ } + g_string_free (data->outbuf, TRUE); + g_free (data->extradata); + g_free (data); +@@ -263,102 +294,24 @@ + xmms_error_t *error) + { + xmms_avcodec_data_t *data; +- char outbuf[AVCODEC_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->outbuf->len, len); +- while (size == 0) { +- AVPacket packet; +- av_init_packet (&packet); ++ while (0 == (size = MIN (data->outbuf->len, len))) { ++ gint res; + + if (data->no_demuxer || data->buffer_length == 0) { +- gint read_total; +- +- bytes_read = xmms_xform_read (xform, +- (gchar *) (data->buffer + data->buffer_length), +- data->buffer_size - data->buffer_length, +- error); +- +- if (bytes_read < 0) { +- XMMS_DBG ("Error while reading data"); +- return bytes_read; +- } else if (bytes_read == 0) { +- XMMS_DBG ("EOF"); +- 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->buffer_size && !data->no_demuxer) { +- /* multiply the buffer size and try to read again */ +- data->buffer = g_realloc (data->buffer, data->buffer_size * 2); +- bytes_read = xmms_xform_read (xform, +- (gchar *) data->buffer + +- data->buffer_size, +- data->buffer_size, +- error); +- data->buffer_size *= 2; +- +- if (bytes_read < 0) { +- XMMS_DBG ("Error while reading data"); +- return bytes_read; +- } +- +- read_total += bytes_read; +- +- if (read_total < data->buffer_size) { +- /* finally double the buffer size for performance reasons, the +- * hotspot handling likes to fit two frames in the buffer */ +- data->buffer = g_realloc (data->buffer, data->buffer_size * 2); +- data->buffer_size *= 2; +- XMMS_DBG ("Reallocated avcodec internal buffer to be %d bytes", +- data->buffer_size); +- +- break; +- } +- } +- +- /* Update the buffer length */ +- data->buffer_length += read_total; ++ bytes_read = xmms_avcodec_internal_read_some (xform, data, error); ++ if (bytes_read <= 0) { return bytes_read; } + } + +- packet.data = data->buffer; +- packet.size = data->buffer_length; +- +- outbufsize = sizeof (outbuf); +- bytes_read = avcodec_decode_audio3 (data->codecctx, (short *) outbuf, +- &outbufsize, &packet); +- +- /* The DTS decoder of ffmpeg is buggy and always returns +- * the input buffer length, get frame length from header */ +- 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 (bytes_read < 0 || bytes_read > data->buffer_length) { +- XMMS_DBG ("Error decoding data!"); +- return -1; +- } else if (bytes_read != data->buffer_length) { +- g_memmove (data->buffer, +- data->buffer + bytes_read, +- data->buffer_length - bytes_read); +- } +- +- data->buffer_length -= bytes_read; +- +- if (outbufsize > 0) { +- g_string_append_len (data->outbuf, outbuf, outbufsize); +- } +- +- size = MIN (data->outbuf->len, len); ++ res = xmms_avcodec_internal_decode_some (data); ++ if (res < 0) { return res; } ++ if (res > 0) { xmms_avcodec_internal_append (data); } + } + + memcpy (buf, data->outbuf->str, size); +@@ -371,8 +324,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[AVCODEC_MAX_AUDIO_FRAME_SIZE]; +- gint outbufsize, bytes_read = 0; + gint64 ret = -1; + g_return_val_if_fail (xform, -1); +@@ -390,23 +341,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->buffer_length > 0) { +- AVPacket packet; +- av_init_packet (&packet); +- packet.data = data->buffer; +- packet.size = data->buffer_length; +- +- outbufsize = sizeof (outbuf); +- bytes_read = avcodec_decode_audio3 (data->codecctx, (short *) outbuf, +- &outbufsize, &packet); +- +- if (bytes_read < 0 || bytes_read > data->buffer_length) { +- XMMS_DBG ("Error decoding data!"); ++ if (xmms_avcodec_internal_decode_some (data) < 0) { + return -1; + } +- +- data->buffer_length -= bytes_read; +- g_memmove (data->buffer, data->buffer + bytes_read, data->buffer_length); + } + + ret = xmms_xform_seek (xform, samples, whence, err); +@@ -420,3 +359,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 ("AVSampleFormat (%i: %s) not supported.", 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->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->buffer + data->buffer_length), ++ data->buffer_size - data->buffer_length, ++ error); ++ ++ if (bytes_read < 0) { ++ XMMS_DBG ("Error while reading data"); ++ return bytes_read; ++ } else if (bytes_read == 0) { ++ XMMS_DBG ("EOF"); ++ return 0; ++ } ++ ++ read_total = bytes_read; ++ ++ /* If we have a demuxer plugin, make sure we read the whole packet */ ++ while (read_total == data->buffer_size && !data->no_demuxer) { ++ /* multiply the buffer size and try to read again */ ++ data->buffer = g_realloc (data->buffer, data->buffer_size * 2); ++ bytes_read = xmms_xform_read (xform, ++ (gchar *) data->buffer + ++ data->buffer_size, ++ data->buffer_size, ++ error); ++ data->buffer_size *= 2; ++ ++ if (bytes_read < 0) { ++ XMMS_DBG ("Error while reading data"); ++ return bytes_read; ++ } ++ ++ read_total += bytes_read; ++ ++ if (read_total < data->buffer_size) { ++ /* finally double the buffer size for performance reasons, the ++ * hotspot handling likes to fit two frames in the buffer */ ++ data->buffer = g_realloc (data->buffer, data->buffer_size * 2); ++ data->buffer_size *= 2; ++ XMMS_DBG ("Reallocated avcodec internal buffer to be %d bytes", ++ data->buffer_size); ++ ++ break; ++ } ++ } ++ ++ /* Update the buffer length */ ++ data->buffer_length += read_total; ++ ++ return read_total; ++} ++ ++/* ++Decode some data from data->buffer[0..data->buffer_length-1] to ++data->read_out_frame ++ ++Returns: on error: negative ++ on no new data produced: zero ++ otherwise: positive ++ ++FIXME: data->buffer should be at least data->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 (&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 (bytes_read < 0 || bytes_read > data->buffer_length) { ++ 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; ++} ++ ++static void ++xmms_avcodec_internal_append (xmms_avcodec_data_t *data) ++{ ++ enum AVSampleFormat fmt = (enum AVSampleFormat) data->read_out_frame->format; ++ int samples = data->read_out_frame->nb_samples; ++ int channels = data->codecctx->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 < samples; i++) { ++ for (j = 0; j < channels; j++) { ++ g_string_append_len ( ++ data->outbuf, ++ (gchar *) (data->read_out_frame->extended_data[j] + i*bps), ++ bps ++ ); ++ } ++ } ++ } else { ++ g_string_append_len (data->outbuf, ++ (gchar *) data->read_out_frame->extended_data[0], ++ samples * channels * bps); ++ } ++} diff --git a/audio/xmms2/files/patch-src_plugins_avcodec_avcodec__compat.h b/audio/xmms2/files/patch-src_plugins_avcodec_avcodec__compat.h new file mode 100644 index 000000000000..c7b0376c45dc --- /dev/null +++ b/audio/xmms2/files/patch-src_plugins_avcodec_avcodec__compat.h @@ -0,0 +1,69 @@ +--- src/plugins/avcodec/avcodec_compat.h.orig 2011-10-20 21:26:08.000000000 +0200 ++++ src/plugins/avcodec/avcodec_compat.h 2014-02-27 18:38:22.000000000 +0100 +@@ -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 +@@ -21,47 +21,16 @@ + # include "avcodec.h" + #endif + +-/* Map avcodec_decode_audio2 into the deprecated version +- * avcodec_decode_audio in versions earlier than 51.28 */ +-#if LIBAVCODEC_VERSION_INT < 0x331c00 +-# define avcodec_decode_audio2 avcodec_decode_audio ++/* 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 + +-/* Handle API change that happened in libavcodec 52.00 */ +-#if LIBAVCODEC_VERSION_INT < 0x340000 +-# define CONTEXT_BPS(codecctx) (codecctx)->bits_per_sample +-#else +-# define CONTEXT_BPS(codecctx) (codecctx)->bits_per_coded_sample +-#endif +- +-/* Before 52.23 AVPacket was defined in avformat.h which we +- * do not want to depend on, so we define part of it manually +- * on versions smaller than 52.23 (this makes me cry) */ +-#if LIBAVCODEC_VERSION_INT < 0x341700 +-typedef struct AVPacket { +- uint8_t *data; +- int size; +-} AVPacket; +-#endif +- +-/* Same thing as above for av_init_packet and version 52.25 */ +-#if LIBAVCODEC_VERSION_INT < 0x341900 +-# define av_init_packet(pkt) do { \ +- (pkt)->data = NULL; \ +- (pkt)->size = 0; \ +- } while(0) ++/* 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 < 0x371c01 ++# define av_frame_alloc avcodec_alloc_frame ++# define av_frame_unref avcodec_get_frame_defaults ++# define av_frame_free avcodec_free_frame + #endif +- +-/* Map avcodec_decode_audio3 into the deprecated version +- * avcodec_decode_audio2 in versions earlier than 52.26 */ +-#if LIBAVCODEC_VERSION_INT < 0x341a00 +-# define avcodec_decode_audio3(avctx, samples, frame_size_ptr, avpkt) \ +- avcodec_decode_audio2(avctx, samples, frame_size_ptr, \ +- (avpkt)->data, (avpkt)->size) +-#endif +- +-/* Handle API change that happened in libavcodec 52.64 */ +-#if LIBAVCODEC_VERSION_INT < 0x344000 +-# define AVMEDIA_TYPE_AUDIO CODEC_TYPE_AUDIO +-#endif +-