diff options
author | Sergei Trofimovich <slyfox@gentoo.org> | 2016-04-02 11:43:39 +0100 |
---|---|---|
committer | Sergei Trofimovich <slyfox@gentoo.org> | 2016-04-02 11:43:47 +0100 |
commit | 45fc303a416aa252542c49b9383ad148f9022974 (patch) | |
tree | ff4c5ee6ab5050b02ad2cd0f2d09ea421b911bcf /media-sound | |
parent | dev-libs/libplatform: Version bump (diff) | |
download | gentoo-45fc303a416aa252542c49b9383ad148f9022974.tar.gz gentoo-45fc303a416aa252542c49b9383ad148f9022974.tar.bz2 gentoo-45fc303a416aa252542c49b9383ad148f9022974.zip |
media-sound/xmms2: support stable API for libav, bug #540890
Latest stable media-video/ffmpeg-2.8.6 provides both functions:
avcodec_decode_audio3
avcodec_decode_audio4
While latest stable media-video/libav-11.3 provides only
avcodec_decode_audio4
Pulled large patchset from upstream to support audio4 API.
Builds fine on both stable virtual/ffmpeg implementations
and unstable libav.
Reported-by: Toralf Förster
Bug: https://bugs.gentoo.org/540890
Package-Manager: portage-2.2.28
Diffstat (limited to 'media-sound')
-rw-r--r-- | media-sound/xmms2/files/xmms2-0.8-audio4-p1.patch | 123 | ||||
-rw-r--r-- | media-sound/xmms2/files/xmms2-0.8-audio4-p2.patch | 171 | ||||
-rw-r--r-- | media-sound/xmms2/files/xmms2-0.8-audio4-p3.patch | 388 | ||||
-rw-r--r-- | media-sound/xmms2/files/xmms2-0.8-audio4-p4.patch | 296 | ||||
-rw-r--r-- | media-sound/xmms2/files/xmms2-0.8-audio4-p5.patch | 154 | ||||
-rw-r--r-- | media-sound/xmms2/files/xmms2-0.8-audio4-p6.patch | 106 | ||||
-rw-r--r-- | media-sound/xmms2/files/xmms2-0.8-audio4-p7.patch | 147 | ||||
-rw-r--r-- | media-sound/xmms2/xmms2-0.8-r2.ebuild | 7 |
8 files changed, 1392 insertions, 0 deletions
diff --git a/media-sound/xmms2/files/xmms2-0.8-audio4-p1.patch b/media-sound/xmms2/files/xmms2-0.8-audio4-p1.patch new file mode 100644 index 000000000000..21ed6492a44d --- /dev/null +++ b/media-sound/xmms2/files/xmms2-0.8-audio4-p1.patch @@ -0,0 +1,123 @@ +commit 8831bc77d705c03b3f8081de0520dd10afa85c69 +Author: Uli Franke <cls@nebadje.org> +Date: Tue Jan 17 23:23:46 2012 +0100 + + BUG(2509): Avoid unaligned reads in avcodec xform. + +diff --git a/src/plugins/avcodec/avcodec.c b/src/plugins/avcodec/avcodec.c +index fe58fc5..1b4a659 100644 +--- a/src/plugins/avcodec/avcodec.c ++++ b/src/plugins/avcodec/avcodec.c +@@ -36,6 +36,9 @@ typedef struct { + guint buffer_size; + gboolean no_demuxer; + ++ gchar *read_out_buffer; ++ gint read_out_buffer_size; ++ + guint channels; + guint samplerate; + xmms_sample_format_t sampleformat; +@@ -107,6 +110,7 @@ xmms_avcodec_destroy (xmms_xform_t *xform) + + avcodec_close (data->codecctx); + av_free (data->codecctx); ++ av_free (data->read_out_buffer); + + g_string_free (data->outbuf, TRUE); + g_free (data->buffer); +@@ -132,6 +136,9 @@ xmms_avcodec_init (xmms_xform_t *xform) + data->buffer_size = AVCODEC_BUFFER_SIZE; + data->codecctx = NULL; + ++ data->read_out_buffer = av_malloc (AVCODEC_MAX_AUDIO_FRAME_SIZE); ++ data->read_out_buffer_size = AVCODEC_MAX_AUDIO_FRAME_SIZE; ++ + xmms_xform_private_data_set (xform, data); + + avcodec_init (); +@@ -196,7 +203,7 @@ xmms_avcodec_init (xmms_xform_t *xform) + } else { + /* A demuxer plugin forgot to give decoder config? */ + xmms_log_error ("Decoder config data not found!"); +- return FALSE; ++ goto err; + } + } + +@@ -220,7 +227,7 @@ xmms_avcodec_init (xmms_xform_t *xform) + + /* 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..."); +@@ -251,6 +258,9 @@ err: + if (data->codecctx) { + av_free (data->codecctx); + } ++ if (data->read_out_buffer) { ++ av_free (data->read_out_buffer); ++ } + g_string_free (data->outbuf, TRUE); + g_free (data->extradata); + g_free (data); +@@ -263,8 +273,7 @@ xmms_avcodec_read (xmms_xform_t *xform, xmms_sample_t *buf, gint len, + xmms_error_t *error) + { + xmms_avcodec_data_t *data; +- char outbuf[AVCODEC_MAX_AUDIO_FRAME_SIZE]; +- gint outbufsize, bytes_read = 0; ++ gint bytes_read = 0; + guint size; + + data = xmms_xform_private_data_get (xform); +@@ -330,9 +339,9 @@ xmms_avcodec_read (xmms_xform_t *xform, xmms_sample_t *buf, gint len, + packet.data = data->buffer; + packet.size = data->buffer_length; + +- outbufsize = sizeof (outbuf); +- bytes_read = avcodec_decode_audio3 (data->codecctx, (short *) outbuf, +- &outbufsize, &packet); ++ data->read_out_buffer_size = AVCODEC_MAX_AUDIO_FRAME_SIZE; ++ bytes_read = avcodec_decode_audio3 (data->codecctx, (short *) data->read_out_buffer, ++ &data->read_out_buffer_size, &packet); + + /* The DTS decoder of ffmpeg is buggy and always returns + * the input buffer length, get frame length from header */ +@@ -354,8 +363,8 @@ xmms_avcodec_read (xmms_xform_t *xform, xmms_sample_t *buf, gint len, + + data->buffer_length -= bytes_read; + +- if (outbufsize > 0) { +- g_string_append_len (data->outbuf, outbuf, outbufsize); ++ if (data->read_out_buffer_size > 0) { ++ g_string_append_len (data->outbuf, data->read_out_buffer, data->read_out_buffer_size); + } + + size = MIN (data->outbuf->len, len); +@@ -371,8 +380,7 @@ static gint64 + 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; ++ gint bytes_read = 0; + gint64 ret = -1; + + g_return_val_if_fail (xform, -1); +@@ -396,9 +404,9 @@ xmms_avcodec_seek (xmms_xform_t *xform, gint64 samples, xmms_xform_seek_mode_t w + packet.data = data->buffer; + packet.size = data->buffer_length; + +- outbufsize = sizeof (outbuf); +- bytes_read = avcodec_decode_audio3 (data->codecctx, (short *) outbuf, +- &outbufsize, &packet); ++ data->read_out_buffer_size = AVCODEC_MAX_AUDIO_FRAME_SIZE; ++ bytes_read = avcodec_decode_audio3 (data->codecctx, (short *) data->read_out_buffer, ++ &data->read_out_buffer_size, &packet); + + if (bytes_read < 0 || bytes_read > data->buffer_length) { + XMMS_DBG ("Error decoding data!"); diff --git a/media-sound/xmms2/files/xmms2-0.8-audio4-p2.patch b/media-sound/xmms2/files/xmms2-0.8-audio4-p2.patch new file mode 100644 index 000000000000..46b5b1d3b926 --- /dev/null +++ b/media-sound/xmms2/files/xmms2-0.8-audio4-p2.patch @@ -0,0 +1,171 @@ +commit b614459dc1ea353d6c24b4a77c7f92a5577d5bc3 +Author: Uli Franke <cls@nebadje.org> +Date: Thu Jan 19 11:53:57 2012 +0100 + + BUG(2510): Add more bitrates/samplerates to AAC/ALAC. + +diff --git a/src/plugins/avcodec/avcodec.c b/src/plugins/avcodec/avcodec.c +index 1b4a659..b32de4d 100644 +--- a/src/plugins/avcodec/avcodec.c ++++ b/src/plugins/avcodec/avcodec.c +@@ -60,6 +60,7 @@ 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 +@@ -168,12 +169,12 @@ xmms_avcodec_init (xmms_xform_t *xform) + 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); +@@ -238,12 +239,17 @@ xmms_avcodec_init (xmms_xform_t *xform) + + 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, +@@ -428,3 +434,23 @@ xmms_avcodec_seek (xmms_xform_t *xform, gint64 samples, xmms_xform_seek_mode_t w + + 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: ++ return XMMS_SAMPLE_FORMAT_U8; ++ case AV_SAMPLE_FMT_S16: ++ return XMMS_SAMPLE_FORMAT_S16; ++ case AV_SAMPLE_FMT_S32: ++ return XMMS_SAMPLE_FORMAT_S32; ++ case AV_SAMPLE_FMT_FLT: ++ return XMMS_SAMPLE_FORMAT_FLOAT; ++ case AV_SAMPLE_FMT_DBL: ++ return XMMS_SAMPLE_FORMAT_DOUBLE; ++ default: ++ XMMS_DBG ("AVSampleFormat (%i) not supported.", av_sample_format); ++ return XMMS_SAMPLE_FORMAT_UNKNOWN; ++ } ++} +diff --git a/src/plugins/mp4/mp4.c b/src/plugins/mp4/mp4.c +index 7c915c4..3ee9357 100644 +--- a/src/plugins/mp4/mp4.c ++++ b/src/plugins/mp4/mp4.c +@@ -186,9 +186,6 @@ xmms_mp4_init (xmms_xform_t *xform) + xmms_xform_auxdata_set_bin (xform, "decoder_config", tmpbuf, tmpbuflen); + g_free (tmpbuf); + +- /* This is only for ALAC to set 16-bit samples, ignored for AAC */ +- xmms_xform_auxdata_set_int (xform, "samplebits", 16); +- + xmms_mp4_get_mediainfo (xform); + + XMMS_DBG ("MP4 demuxer inited successfully!"); +@@ -288,7 +285,7 @@ xmms_mp4_get_mediainfo (xmms_xform_t *xform) + data = xmms_xform_private_data_get (xform); + g_return_if_fail (data); + +- if ((temp = mp4ff_get_sample_rate (data->mp4ff, data->track)) >= 0) { ++ if ((temp = mp4ff_get_sample_rate (data->mp4ff, data->track)) > 0) { + glong srate = temp; + + if ((temp = mp4ff_get_track_duration_use_offsets (data->mp4ff, +@@ -492,7 +489,7 @@ xmms_mp4_get_track (xmms_xform_t *xform, mp4ff_t *infile) + case 0x69: /* MPEG-2 audio */ + case 0x6B: /* MPEG-1 audio */ + continue; +- case 0xff: ++ case 0xff: /* ALAC */ + chans = mp4ff_get_channel_count (infile, i); + rate = mp4ff_get_sample_rate (infile, i); + if (chans <= 0 || rate <= 0) { +diff --git a/src/plugins/mp4/mp4ff/README.xmms2 b/src/plugins/mp4/mp4ff/README.xmms2 +index c2737c5..8021618 100644 +--- a/src/plugins/mp4/mp4ff/README.xmms2 ++++ b/src/plugins/mp4/mp4ff/README.xmms2 +@@ -12,3 +12,4 @@ Changes: + * Add value_length variable to tag type and use it when adding new item-value pairs, + necessary for cover art since it's binary data and can't be handled as a string + * Add support for Apple Lossless audio files ++ * Add a workaround for supporting higher samplerates. +diff --git a/src/plugins/mp4/mp4ff/mp4ff.c b/src/plugins/mp4/mp4ff/mp4ff.c +index ee7f7fb..b6f0a37 100644 +--- a/src/plugins/mp4/mp4ff/mp4ff.c ++++ b/src/plugins/mp4/mp4ff/mp4ff.c +@@ -32,6 +32,8 @@ + #include <string.h> + #include "mp4ffint.h" + ++static uint32_t mp4ff_normalize_flawed_sample_rate (uint16_t samplerate); ++ + mp4ff_t *mp4ff_open_read(mp4ff_callback_t *f) + { + mp4ff_t *ff = malloc(sizeof(mp4ff_t)); +@@ -304,12 +306,39 @@ int32_t mp4ff_num_samples(const mp4ff_t *f, const int32_t track) + return total; + } + ++static uint32_t ++mp4ff_normalize_flawed_sample_rate (uint16_t samplerate) ++{ ++ /* A list of common rates can be found at ++ * http://en.wikipedia.org/wiki/Sampling_rate */ ++ uint32_t rates[] = {8000, 11025, 16000, 22050, 32000, 44056, 44100, ++ 47250, 48000, 50000, 50400, 88200, 96000, 176400, ++ 192000, 352800, 384000, 0}; ++ uint32_t* rate; ++ ++ /* First check standard rates. */ ++ for (rate = rates; *rate; rate++) { ++ if (*rate == samplerate) { ++ return *rate; ++ } ++ } ++ ++ /* No standard rates matching - check if sample rate got truncated when ++ * added to MP4 container */ ++ for (rate = rates; *rate; rate++) { ++ if ((*rate & 0x0000FFFF) == samplerate) { ++ return *rate; ++ } ++ } + ++ /* Failed to find a standard rate - we give up returning the original rate */ ++ return samplerate; ++} + + + uint32_t mp4ff_get_sample_rate(const mp4ff_t *f, const int32_t track) + { +- return f->track[track]->sampleRate; ++ return mp4ff_normalize_flawed_sample_rate (f->track[track]->sampleRate); + } + + uint32_t mp4ff_get_channel_count(const mp4ff_t * f,const int32_t track) diff --git a/media-sound/xmms2/files/xmms2-0.8-audio4-p3.patch b/media-sound/xmms2/files/xmms2-0.8-audio4-p3.patch new file mode 100644 index 000000000000..a9145c0d3d26 --- /dev/null +++ b/media-sound/xmms2/files/xmms2-0.8-audio4-p3.patch @@ -0,0 +1,388 @@ +commit 4d0682030e20a8ed218f4ff924554f93d276d9ee +Author: Anthony Garcia <lagg@lavabit.com> +Date: Thu Apr 22 16:59:37 2010 -0700 + + OTHER: Cleanup + + Re-enabled nellymoser (ffmpeg appears to be okay with it now) + + Fixed possible infinite loop in the code that handles the data (if any) + between the header and tag data. + +diff --git a/src/plugins/avcodec/avcodec.c b/src/plugins/avcodec/avcodec.c +index 6c9fea8..5554056 100644 +--- a/src/plugins/avcodec/avcodec.c ++++ b/src/plugins/avcodec/avcodec.c +@@ -90,7 +90,7 @@ xmms_avcodec_plugin_setup (xmms_xform_plugin_t *xform_plugin) + 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, +@@ -197,7 +197,8 @@ xmms_avcodec_init (xmms_xform_t *xform) + !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; +diff --git a/src/plugins/flv/flv.c b/src/plugins/flv/flv.c +index 440010c..266fea6 100644 +--- a/src/plugins/flv/flv.c ++++ b/src/plugins/flv/flv.c +@@ -25,29 +25,41 @@ + * and other info, then data + */ + #define FLV_TAG_SIZE 11 +-/* random constant */ + #define FLV_CHUNK_SIZE 4096 + +-/* let libavcodec take care of swapping sample bytes */ +-static const gchar *mime_pcm_s16le = "audio/x-ffmpeg-pcm_s16le"; +-static const gchar *fmt_mime[11] = { +- /* Supported when samples are 8 bit +- * (otherwise there's no way of knowing endianness) +- */ +- "audio/pcm", +- "audio/x-ffmpeg-adpcm_swf", +- "audio/mpeg", +- /* if bps is 8 bit u8 +- * if bps is 16 bit sle16 +- */ +- "audio/pcm", +- /* libavcodec can't handle nelly without dying yet */ +- /*"audio/x-ffmpeg-nellymoser", +- "audio/x-ffmpeg-nellymoser", +- "audio/x-ffmpeg-nellymoser",*/ +- "", "", "", +- "", "", "", +- "audio/aac" ++typedef enum { ++ /* Only u8 bit samples since ++ there's no way to determine endianness ++ */ ++ CODEC_PCM_HOST, ++ CODEC_ADPCM, ++ CODEC_MP3, ++ /* 8 bps: unsigned ++ 16 bps: signed ++ */ ++ CODEC_PCM_LE, ++ CODEC_NELLYMOSER_16K, ++ CODEC_NELLYMOSER_8K, ++ /* Uses the sample rate in ++ the tag as normal ++ */ ++ CODEC_NELLYMOSER, ++ CODEC_AAC = 10 ++} xmms_flv_codec_id; ++ ++struct xmms_flv_codec_table { ++ xmms_flv_codec_id id; ++ const gchar *mime; ++} static flv_codecs[] = { ++ {CODEC_PCM_HOST, "audio/pcm"}, ++ {CODEC_ADPCM, "audio/x-ffmpeg-adpcm_swf"}, ++ {CODEC_MP3, "audio/mpeg"}, ++ /* Will be audio/x-ffmpeg-pcm_s16le if bps is 16 */ ++ {CODEC_PCM_LE, "audio/pcm"}, ++ {CODEC_NELLYMOSER_16K, "audio/x-ffmpeg-nellymoser"}, ++ {CODEC_NELLYMOSER_8K, "audio/x-ffmpeg-nellymoser"}, ++ {CODEC_NELLYMOSER, "audio/x-ffmpeg-nellymoser"}, ++ {CODEC_AAC, "audio/aac"} + }; + + typedef struct { +@@ -111,23 +123,26 @@ static gboolean + xmms_flv_init (xmms_xform_t *xform) + { + xmms_sample_format_t bps; +- gint readret; ++ gint readret, i; + guint8 channels, flags, format; +- guint8 header[FLV_TAG_SIZE + 5]; +- const gchar *mime; ++ guint8 header[FLV_TAG_SIZE + 1]; + guint32 dataoffset, samplerate; + xmms_error_t err; + xmms_flv_data_t *flvdata; ++ struct xmms_flv_codec_table *codec = NULL; ++ ++ flvdata = g_new0 (xmms_flv_data_t, 1); ++ xmms_xform_private_data_set (xform, flvdata); + + readret = xmms_xform_read (xform, header, FLV_HDR_SIZE, &err); + if (readret != FLV_HDR_SIZE) { + xmms_log_error ("Header read error"); +- return FALSE; ++ goto init_err; + } + + if ((header[4] & HAS_AUDIO) != HAS_AUDIO) { + xmms_log_error ("FLV has no audio stream"); +- return FALSE; ++ goto init_err; + } + + dataoffset = get_be32 (&header[5]) - FLV_HDR_SIZE; +@@ -140,7 +155,7 @@ xmms_flv_init (xmms_xform_t *xform) + dataoffset : FLV_HDR_SIZE, &err); + if (readret <= 0) { + xmms_log_error ("Error reading header:tag body gap"); +- return FALSE; ++ goto init_err; + } + + dataoffset -= readret; +@@ -148,86 +163,99 @@ xmms_flv_init (xmms_xform_t *xform) + + if (next_audio_tag (xform) <= 0) { + xmms_log_error ("Can't find first audio tag"); +- return FALSE; ++ goto init_err; + } + +- if (xmms_xform_peek (xform, header, FLV_TAG_SIZE + 5, &err) < FLV_TAG_SIZE + 5) { ++ if (xmms_xform_read (xform, header, FLV_TAG_SIZE + 1, &err) < FLV_TAG_SIZE + 1) { + xmms_log_error ("Can't read first audio tag"); +- return FALSE; ++ goto init_err; + } + +- flags = header[FLV_TAG_SIZE + 4]; ++ flags = header[11]; + XMMS_DBG ("Audio flags: %X", flags); + +- switch (flags&12) { +- case 0: samplerate = 5512; break; +- case 4: samplerate = 11025; break; +- case 8: samplerate = 22050; break; +- case 12: samplerate = 44100; break; +- default: samplerate = 8000; break; ++ format = flags >> 4; ++ for (i = 0; i < G_N_ELEMENTS (flv_codecs); i++) { ++ if (flv_codecs[i].id == format) { ++ codec = &flv_codecs[i]; ++ break; ++ } + } + +- if (flags&2) { +- bps = XMMS_SAMPLE_FORMAT_S16; ++ if (flags & 1) { ++ channels = 2; + } else { +- bps = XMMS_SAMPLE_FORMAT_U8; ++ channels = 1; + } + +- if (flags&1) { +- channels = 2; ++ if (flags & 2) { ++ bps = XMMS_SAMPLE_FORMAT_S16; + } else { +- channels = 1; ++ bps = XMMS_SAMPLE_FORMAT_U8; + } + +- format = flags >> 4; +- mime = (format <= 10)? fmt_mime[format] : NULL; +- switch (format) { +- case 0: +- /* If the flv has an HE PCM audio stream, the +- * samples must be unsigned and 8 bits long +- */ +- if (bps != XMMS_SAMPLE_FORMAT_U8) { +- xmms_log_error ("Only u8 HE PCM is supported"); +- return FALSE; +- } +- break; +- case 3: +- if (bps == XMMS_SAMPLE_FORMAT_S16) { +- mime = mime_pcm_s16le; +- } +- break; ++ switch ((flags & 12) >> 2) { ++ case 0: samplerate = 5512; break; ++ case 1: samplerate = 11025; break; ++ case 2: samplerate = 22050; break; ++ case 3: samplerate = 44100; break; ++ default: samplerate = 8000; break; + } + +- if (mime && *mime) { +- flvdata = g_new0 (xmms_flv_data_t, 1); ++ if (codec) { ++ switch (codec->id) { ++ case CODEC_PCM_HOST: ++ if (bps != XMMS_SAMPLE_FORMAT_U8) { ++ xmms_log_error ("Only u8 HE PCM is supported"); ++ goto init_err; ++ } ++ break; ++ case CODEC_PCM_LE: ++ if (bps == XMMS_SAMPLE_FORMAT_S16) { ++ codec->mime = "audio/x-ffmpeg-pcm_s16le"; ++ } ++ break; ++ case CODEC_NELLYMOSER_16K: ++ samplerate = 16000; ++ break; ++ case CODEC_NELLYMOSER_8K: ++ samplerate = 8000; ++ break; ++ default: ++ break; ++ } ++ + flvdata->format = format; ++ flvdata->last_datasize = get_be24 (&header[1]) - 1; + + XMMS_DBG ("Rate: %d, bps: %d, channels: %d", samplerate, + bps, channels); + +- xmms_xform_private_data_set (xform, flvdata); + xmms_xform_outdata_type_add (xform, + XMMS_STREAM_TYPE_MIMETYPE, +- mime, +- XMMS_STREAM_TYPE_FMT_SAMPLERATE, +- samplerate, +- XMMS_STREAM_TYPE_FMT_FORMAT, +- bps, +- XMMS_STREAM_TYPE_FMT_CHANNELS, +- channels, +- XMMS_STREAM_TYPE_END); ++ codec->mime, ++ XMMS_STREAM_TYPE_FMT_SAMPLERATE, ++ samplerate, ++ XMMS_STREAM_TYPE_FMT_FORMAT, ++ bps, ++ XMMS_STREAM_TYPE_FMT_CHANNELS, ++ channels, ++ XMMS_STREAM_TYPE_END); + return TRUE; + } else { + xmms_log_error ("Unsupported audio format"); +- return FALSE; + } ++ ++init_err: ++ g_free (flvdata); ++ return FALSE; + } + + static gint + xmms_flv_read (xmms_xform_t *xform, xmms_sample_t *buf, gint len, xmms_error_t *err) + { +- gint ret = 0, thismuch = FLV_TAG_SIZE + 5; +- guint8 header[FLV_TAG_SIZE + 6], gap = 1; ++ gint ret = 0, thismuch = FLV_TAG_SIZE + 1; ++ guint8 header[FLV_TAG_SIZE + 1]; + xmms_flv_data_t *data = NULL; + + data = xmms_xform_private_data_get (xform); +@@ -236,12 +264,8 @@ xmms_flv_read (xmms_xform_t *xform, xmms_sample_t *buf, gint len, xmms_error_t * + xmms_xform_auxdata_barrier (xform); + ret = next_audio_tag (xform); + if (ret > 0) { +- if (data->format == 10) { +- thismuch++; +- gap++; +- } + if (xmms_xform_read (xform, header, thismuch, err) == thismuch) { +- data->last_datasize = get_be24 (&header[5]) - gap; ++ data->last_datasize = get_be24 (&header[1]) - 1; + } else { + xmms_log_error ("Need %d bytes", thismuch); + return -1; +@@ -280,40 +304,51 @@ xmms_flv_destroy (xmms_xform_t *xform) + static gint + next_audio_tag (xmms_xform_t *xform) + { +- guint8 header[FLV_TAG_SIZE + 4]; ++ guint8 header[FLV_TAG_SIZE]; + guint8 dumb[FLV_CHUNK_SIZE]; + gint ret = 0; + xmms_error_t err; +- guint32 datasize = 0; ++ xmms_flv_data_t *data; ++ ++ data = xmms_xform_private_data_get (xform); + + do { +- /* there's a last 4 bytes at the end of an FLV giving the final +- * tag's size, this isn't an error +- */ +- ret = xmms_xform_peek (xform, header, FLV_TAG_SIZE + 4, &err); +- if ((ret < FLV_TAG_SIZE) && (ret > -1)) { +- ret = 0; +- break; +- } else if (ret == -1) { +- xmms_log_error ("%s", xmms_error_message_get (&err)); +- break; +- } ++ /* If > 0 assume we're in the middle of a tag's data */ ++ if (!data->last_datasize) { ++ /* There are 4 bytes before an actual tag giving ++ the previous tag's size. The first size in an ++ flv is always 0. ++ */ ++ if (xmms_xform_read (xform, header, 4, &err) != 4) { ++ xmms_log_error ("Couldn't read last tag size"); ++ return -1; ++ } + +- if (header[4] == 8) { +- /* woo audio tag! */ +- break; +- } ++ ret = xmms_xform_peek (xform, header, FLV_TAG_SIZE, &err); ++ if ((ret < FLV_TAG_SIZE) && (ret > -1)) { ++ return 0; ++ } else if (ret == -1) { ++ xmms_log_error ("%s", xmms_error_message_get (&err)); ++ return ret; ++ } ++ ++ if (header[0] == 8) { ++ /* woo audio tag! */ ++ break; ++ } + +- ret = xmms_xform_read (xform, header, FLV_TAG_SIZE + 4, &err); +- if (ret <= 0) { return ret; } ++ if ((ret = xmms_xform_read (xform, header, FLV_TAG_SIZE, &err)) <= 0) { ++ return ret; ++ } + +- datasize = get_be24 (&header[5]); ++ data->last_datasize = get_be24 (&header[1]); ++ } + +- while (datasize) { ++ while (data->last_datasize) { + ret = xmms_xform_read (xform, dumb, +- (datasize < FLV_CHUNK_SIZE) ? +- datasize : FLV_CHUNK_SIZE, +- &err); ++ (data->last_datasize < FLV_CHUNK_SIZE) ? ++ data->last_datasize : FLV_CHUNK_SIZE, ++ &err); + if (ret == 0) { + xmms_log_error ("Data field short!"); + break; +@@ -323,7 +358,7 @@ next_audio_tag (xmms_xform_t *xform) + break; + } + +- datasize -= ret; ++ data->last_datasize -= ret; + } + + } while (ret); diff --git a/media-sound/xmms2/files/xmms2-0.8-audio4-p4.patch b/media-sound/xmms2/files/xmms2-0.8-audio4-p4.patch new file mode 100644 index 000000000000..552f202df19d --- /dev/null +++ b/media-sound/xmms2/files/xmms2-0.8-audio4-p4.patch @@ -0,0 +1,296 @@ +commit 4198d9bf5dff517740ed51b22313367f156107e1 +Author: Erik Massop <e.massop@hccnet.nl> +Date: Sun Dec 22 17:19:30 2013 +0100 + + OTHER: Split xmms_avcodec_read, remove some duplicate code + +diff --git a/src/plugins/avcodec/avcodec.c b/src/plugins/avcodec/avcodec.c +index 5b9b606..eed7964 100644 +--- a/src/plugins/avcodec/avcodec.c ++++ b/src/plugins/avcodec/avcodec.c +@@ -57,6 +57,9 @@ 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); ++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, +@@ -281,101 +284,24 @@ xmms_avcodec_read (xmms_xform_t *xform, xmms_sample_t *buf, gint len, + xmms_error_t *error) + { + xmms_avcodec_data_t *data; +- gint 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; +- } +- +- 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; +- } +- +- packet.data = data->buffer; +- packet.size = data->buffer_length; +- +- data->read_out_buffer_size = AVCODEC_MAX_AUDIO_FRAME_SIZE; +- bytes_read = avcodec_decode_audio3 (data->codecctx, (short *) data->read_out_buffer, +- &data->read_out_buffer_size, &packet); ++ gint bytes_read; + +- /* 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; ++ bytes_read = xmms_avcodec_internal_read_some (xform, data, error); ++ if (bytes_read <= 0) { return bytes_read; } + } + +- 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 (data->read_out_buffer_size > 0) { +- g_string_append_len (data->outbuf, data->read_out_buffer, data->read_out_buffer_size); +- } +- +- 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); +@@ -388,7 +314,6 @@ static gint64 + xmms_avcodec_seek (xmms_xform_t *xform, gint64 samples, xmms_xform_seek_mode_t whence, xmms_error_t *err) + { + xmms_avcodec_data_t *data; +- gint bytes_read = 0; + gint64 ret = -1; + + g_return_val_if_fail (xform, -1); +@@ -406,23 +331,11 @@ xmms_avcodec_seek (xmms_xform_t *xform, gint64 samples, xmms_xform_seek_mode_t w + + /* 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; +- +- data->read_out_buffer_size = AVCODEC_MAX_AUDIO_FRAME_SIZE; +- bytes_read = avcodec_decode_audio3 (data->codecctx, (short *) data->read_out_buffer, +- &data->read_out_buffer_size, &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); +@@ -456,3 +369,131 @@ xmms_avcodec_translate_sample_format (enum AVSampleFormat 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_buffer. Number of bytes in data->read_out_buffer ++is stored in data->read_out_buffer_size. ++ ++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) ++{ ++ gint bytes_read = 0; ++ AVPacket packet; ++ ++ av_init_packet (&packet); ++ packet.data = data->buffer; ++ packet.size = data->buffer_length; ++ ++ data->read_out_buffer_size = AVCODEC_MAX_AUDIO_FRAME_SIZE; ++ bytes_read = avcodec_decode_audio3 (data->codecctx, ++ (short *) data->read_out_buffer, ++ &data->read_out_buffer_size, &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 data->read_out_buffer_size; ++} ++ ++static void ++xmms_avcodec_internal_append (xmms_avcodec_data_t *data) ++{ ++ g_string_append_len (data->outbuf, ++ (gchar *) data->read_out_buffer, ++ data->read_out_buffer_size); ++} diff --git a/media-sound/xmms2/files/xmms2-0.8-audio4-p5.patch b/media-sound/xmms2/files/xmms2-0.8-audio4-p5.patch new file mode 100644 index 000000000000..8ed5bb4a24a5 --- /dev/null +++ b/media-sound/xmms2/files/xmms2-0.8-audio4-p5.patch @@ -0,0 +1,154 @@ +commit d44312fb14bde0ab47ee6de1b3fe7435d4a97c99 +Author: Erik Massop <e.massop@hccnet.nl> +Date: Sun Dec 22 20:01:18 2013 +0100 + + BUG(2572): Use avcodec_decode_audio4 + +diff --git a/src/plugins/avcodec/avcodec.c b/src/plugins/avcodec/avcodec.c +index 266a607..a41a675 100644 +--- a/src/plugins/avcodec/avcodec.c ++++ b/src/plugins/avcodec/avcodec.c +@@ -37,8 +37,7 @@ typedef struct { + guint buffer_size; + gboolean no_demuxer; + +- gchar *read_out_buffer; +- gint read_out_buffer_size; ++ AVFrame *read_out_frame; + + guint channels; + guint samplerate; +@@ -125,7 +124,7 @@ xmms_avcodec_destroy (xmms_xform_t *xform) + + avcodec_close (data->codecctx); + av_free (data->codecctx); +- av_free (data->read_out_buffer); ++ avcodec_free_frame (&data->read_out_frame); + + g_string_free (data->outbuf, TRUE); + g_free (data->buffer); +@@ -151,8 +150,7 @@ xmms_avcodec_init (xmms_xform_t *xform) + data->buffer_size = AVCODEC_BUFFER_SIZE; + data->codecctx = NULL; + +- data->read_out_buffer = av_malloc (AVCODEC_MAX_AUDIO_FRAME_SIZE); +- data->read_out_buffer_size = AVCODEC_MAX_AUDIO_FRAME_SIZE; ++ data->read_out_frame = avcodec_alloc_frame (); + + xmms_xform_private_data_set (xform, data); + +@@ -233,6 +231,7 @@ xmms_avcodec_init (xmms_xform_t *xform) + data->codecctx->extradata_size = data->extradata_size; + data->codecctx->codec_id = codec->id; + data->codecctx->codec_type = codec->type; ++ data->codecctx->refcounted_frames = 0; + + if (avcodec_open2 (data->codecctx, codec, NULL) < 0) { + XMMS_DBG ("Opening decoder '%s' failed", codec->name); +@@ -279,8 +278,8 @@ err: + if (data->codecctx) { + av_free (data->codecctx); + } +- if (data->read_out_buffer) { +- av_free (data->read_out_buffer); ++ if (data->read_out_frame) { ++ avcodec_free_frame (&data->read_out_frame); + } + g_string_free (data->outbuf, TRUE); + g_free (data->extradata); +@@ -365,17 +364,23 @@ 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) not supported.", av_sample_format); ++ XMMS_DBG ("AVSampleFormat (%i: %s) not supported.", av_sample_format, ++ av_get_sample_fmt_name (av_sample_format)); + return XMMS_SAMPLE_FORMAT_UNKNOWN; + } + } +@@ -448,8 +453,7 @@ xmms_avcodec_internal_read_some (xmms_xform_t *xform, + + /* + Decode some data from data->buffer[0..data->buffer_length-1] to +-data->read_out_buffer. Number of bytes in data->read_out_buffer +-is stored in data->read_out_buffer_size. ++data->read_out_frame + + Returns: on error: negative + on no new data produced: zero +@@ -461,6 +465,7 @@ 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; + +@@ -468,10 +473,10 @@ xmms_avcodec_internal_decode_some (xmms_avcodec_data_t *data) + packet.data = data->buffer; + packet.size = data->buffer_length; + +- data->read_out_buffer_size = AVCODEC_MAX_AUDIO_FRAME_SIZE; +- bytes_read = avcodec_decode_audio3 (data->codecctx, +- (short *) data->read_out_buffer, +- &data->read_out_buffer_size, &packet); ++ avcodec_get_frame_defaults (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 */ +@@ -497,13 +502,33 @@ xmms_avcodec_internal_decode_some (xmms_avcodec_data_t *data) + data->buffer_length = 0; + } + +- return data->read_out_buffer_size; ++ return got_frame ? 1 : 0; + } + + static void + xmms_avcodec_internal_append (xmms_avcodec_data_t *data) + { +- g_string_append_len (data->outbuf, +- (gchar *) data->read_out_buffer, +- data->read_out_buffer_size); ++ 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/media-sound/xmms2/files/xmms2-0.8-audio4-p6.patch b/media-sound/xmms2/files/xmms2-0.8-audio4-p6.patch new file mode 100644 index 000000000000..b1bc1c5d609b --- /dev/null +++ b/media-sound/xmms2/files/xmms2-0.8-audio4-p6.patch @@ -0,0 +1,106 @@ +commit fc66249e69f53eef709c5210546fdd92e1c89554 +Author: Erik Massop <e.massop@hccnet.nl> +Date: Sun Dec 22 23:04:08 2013 +0100 + + OTHER: Some compatibility with different avcodec versions + +diff --git a/src/plugins/avcodec/avcodec.c b/src/plugins/avcodec/avcodec.c +index a41a675..023833d 100644 +--- a/src/plugins/avcodec/avcodec.c ++++ b/src/plugins/avcodec/avcodec.c +@@ -124,7 +124,7 @@ xmms_avcodec_destroy (xmms_xform_t *xform) + + avcodec_close (data->codecctx); + av_free (data->codecctx); +- avcodec_free_frame (&data->read_out_frame); ++ av_frame_free (&data->read_out_frame); + + g_string_free (data->outbuf, TRUE); + g_free (data->buffer); +@@ -150,7 +150,7 @@ xmms_avcodec_init (xmms_xform_t *xform) + data->buffer_size = AVCODEC_BUFFER_SIZE; + data->codecctx = NULL; + +- data->read_out_frame = avcodec_alloc_frame (); ++ data->read_out_frame = av_frame_alloc (); + + xmms_xform_private_data_set (xform, data); + +@@ -231,7 +231,6 @@ xmms_avcodec_init (xmms_xform_t *xform) + data->codecctx->extradata_size = data->extradata_size; + data->codecctx->codec_id = codec->id; + data->codecctx->codec_type = codec->type; +- data->codecctx->refcounted_frames = 0; + + if (avcodec_open2 (data->codecctx, codec, NULL) < 0) { + XMMS_DBG ("Opening decoder '%s' failed", codec->name); +@@ -473,7 +472,8 @@ xmms_avcodec_internal_decode_some (xmms_avcodec_data_t *data) + packet.data = data->buffer; + packet.size = data->buffer_length; + +- avcodec_get_frame_defaults (data->read_out_frame); ++ /* 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); +diff --git a/src/plugins/avcodec/avcodec_compat.h b/src/plugins/avcodec/avcodec_compat.h +index 73ac2ab..e74b3f8 100644 +--- a/src/plugins/avcodec/avcodec_compat.h ++++ b/src/plugins/avcodec/avcodec_compat.h +@@ -83,3 +83,17 @@ typedef struct AVPacket { + # 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 < 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 --git a/src/plugins/avcodec/wscript b/src/plugins/avcodec/wscript +index 03ba7d8..d367816 100644 +--- a/src/plugins/avcodec/wscript ++++ b/src/plugins/avcodec/wscript +@@ -1,10 +1,33 @@ + from waftools.plugin import plugin + ++## Code fragments for configuration ++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) + ++ # 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"]) diff --git a/media-sound/xmms2/files/xmms2-0.8-audio4-p7.patch b/media-sound/xmms2/files/xmms2-0.8-audio4-p7.patch new file mode 100644 index 000000000000..2d4bafd95a7d --- /dev/null +++ b/media-sound/xmms2/files/xmms2-0.8-audio4-p7.patch @@ -0,0 +1,147 @@ +commit f460440b3f2a9db1a9deef3faf7dae6e626dd7b5 +Author: Erik Massop <e.massop@hccnet.nl> +Date: Sun Dec 22 23:34:12 2013 +0100 + + OTHER: Require avcodec_decode_audio4 + + This was introduced in versions 53.40.0 (ffmpeg) and 53.25.0 (libav) of + avcodec. Hence we drop compatibility for earlier versions. + +diff --git a/src/plugins/avcodec/avcodec.c b/src/plugins/avcodec/avcodec.c +index 023833d..6d0b667 100644 +--- a/src/plugins/avcodec/avcodec.c ++++ b/src/plugins/avcodec/avcodec.c +@@ -154,7 +154,6 @@ xmms_avcodec_init (xmms_xform_t *xform) + + xmms_xform_private_data_set (xform, data); + +- avcodec_init (); + avcodec_register_all (); + + mimetype = xmms_xform_indata_get_str (xform, +@@ -225,7 +224,7 @@ xmms_avcodec_init (xmms_xform_t *xform) + 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; +diff --git a/src/plugins/avcodec/avcodec_compat.h b/src/plugins/avcodec/avcodec_compat.h +index e74b3f8..b50fa4b 100644 +--- a/src/plugins/avcodec/avcodec_compat.h ++++ b/src/plugins/avcodec/avcodec_compat.h +@@ -21,69 +21,6 @@ + # 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 +-#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) +-#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 +- +-/* Calling avcodec_init is not necessary after 53.04 (ffmpeg 0.9) */ +-#if LIBAVCODEC_VERSION_INT >= 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 < 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 < 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 +diff --git a/src/plugins/avcodec/wscript b/src/plugins/avcodec/wscript +index d367816..00b182b 100644 +--- a/src/plugins/avcodec/wscript ++++ b/src/plugins/avcodec/wscript +@@ -1,6 +1,24 @@ + from waftools.plugin import plugin + + ## Code fragments for configuration ++avcodec_decode_audio4_fragment = """ ++#ifdef HAVE_LIBAVCODEC_AVCODEC_H ++# include "libavcodec/avcodec.h" ++#else ++# include "avcodec.h" ++#endif ++int main(void) { ++ AVCodecContext *ctx; ++ AVFrame *frame; ++ int got_frame; ++ AVPacket *pkt; ++ ++ avcodec_decode_audio4 (ctx, frame, &got_frame, pkt); ++ ++ return 0; ++} ++""" ++ + avcodec_free_frame_fragment = """ + #ifdef HAVE_LIBAVCODEC_AVCODEC_H + # include "libavcodec/avcodec.h" +@@ -22,6 +40,13 @@ 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) ++ + # 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 diff --git a/media-sound/xmms2/xmms2-0.8-r2.ebuild b/media-sound/xmms2/xmms2-0.8-r2.ebuild index 4661d2d4af6a..4500c37e84e4 100644 --- a/media-sound/xmms2/xmms2-0.8-r2.ebuild +++ b/media-sound/xmms2/xmms2-0.8-r2.ebuild @@ -116,6 +116,13 @@ src_prepare() { epatch "${FILESDIR}/${P}"-ffmpeg2.patch #536232 epatch "${FILESDIR}/${P}"-cpython.patch epatch "${FILESDIR}/${P}"-modpug.patch #536046 + epatch "${FILESDIR}/${P}"-audio4-p1.patch + epatch "${FILESDIR}/${P}"-audio4-p2.patch + epatch "${FILESDIR}/${P}"-audio4-p3.patch + epatch "${FILESDIR}/${P}"-audio4-p4.patch + epatch "${FILESDIR}/${P}"-audio4-p5.patch + epatch "${FILESDIR}/${P}"-audio4-p6.patch + epatch "${FILESDIR}/${P}"-audio4-p7.patch if has_version dev-libs/libcdio-paranoia; then sed -i -e 's:cdio/cdda.h:cdio/paranoia/cdda.h:' src/plugins/cdda/cdda.c || die |