Gentoo Archives: gentoo-commits

From: Sergei Trofimovich <slyfox@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] repo/gentoo:master commit in: media-sound/xmms2/files/, media-sound/xmms2/
Date: Sat, 02 Apr 2016 10:44:07
Message-Id: 1459593827.45fc303a416aa252542c49b9383ad148f9022974.slyfox@gentoo
1 commit: 45fc303a416aa252542c49b9383ad148f9022974
2 Author: Sergei Trofimovich <slyfox <AT> gentoo <DOT> org>
3 AuthorDate: Sat Apr 2 10:43:39 2016 +0000
4 Commit: Sergei Trofimovich <slyfox <AT> gentoo <DOT> org>
5 CommitDate: Sat Apr 2 10:43:47 2016 +0000
6 URL: https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=45fc303a
7
8 media-sound/xmms2: support stable API for libav, bug #540890
9
10 Latest stable media-video/ffmpeg-2.8.6 provides both functions:
11 avcodec_decode_audio3
12 avcodec_decode_audio4
13
14 While latest stable media-video/libav-11.3 provides only
15 avcodec_decode_audio4
16
17 Pulled large patchset from upstream to support audio4 API.
18
19 Builds fine on both stable virtual/ffmpeg implementations
20 and unstable libav.
21
22 Reported-by: Toralf Förster
23 Bug: https://bugs.gentoo.org/540890
24
25 Package-Manager: portage-2.2.28
26
27 media-sound/xmms2/files/xmms2-0.8-audio4-p1.patch | 123 +++++++
28 media-sound/xmms2/files/xmms2-0.8-audio4-p2.patch | 171 ++++++++++
29 media-sound/xmms2/files/xmms2-0.8-audio4-p3.patch | 388 ++++++++++++++++++++++
30 media-sound/xmms2/files/xmms2-0.8-audio4-p4.patch | 296 +++++++++++++++++
31 media-sound/xmms2/files/xmms2-0.8-audio4-p5.patch | 154 +++++++++
32 media-sound/xmms2/files/xmms2-0.8-audio4-p6.patch | 106 ++++++
33 media-sound/xmms2/files/xmms2-0.8-audio4-p7.patch | 147 ++++++++
34 media-sound/xmms2/xmms2-0.8-r2.ebuild | 7 +
35 8 files changed, 1392 insertions(+)
36
37 diff --git a/media-sound/xmms2/files/xmms2-0.8-audio4-p1.patch b/media-sound/xmms2/files/xmms2-0.8-audio4-p1.patch
38 new file mode 100644
39 index 0000000..21ed649
40 --- /dev/null
41 +++ b/media-sound/xmms2/files/xmms2-0.8-audio4-p1.patch
42 @@ -0,0 +1,123 @@
43 +commit 8831bc77d705c03b3f8081de0520dd10afa85c69
44 +Author: Uli Franke <cls@×××××××.org>
45 +Date: Tue Jan 17 23:23:46 2012 +0100
46 +
47 + BUG(2509): Avoid unaligned reads in avcodec xform.
48 +
49 +diff --git a/src/plugins/avcodec/avcodec.c b/src/plugins/avcodec/avcodec.c
50 +index fe58fc5..1b4a659 100644
51 +--- a/src/plugins/avcodec/avcodec.c
52 ++++ b/src/plugins/avcodec/avcodec.c
53 +@@ -36,6 +36,9 @@ typedef struct {
54 + guint buffer_size;
55 + gboolean no_demuxer;
56 +
57 ++ gchar *read_out_buffer;
58 ++ gint read_out_buffer_size;
59 ++
60 + guint channels;
61 + guint samplerate;
62 + xmms_sample_format_t sampleformat;
63 +@@ -107,6 +110,7 @@ xmms_avcodec_destroy (xmms_xform_t *xform)
64 +
65 + avcodec_close (data->codecctx);
66 + av_free (data->codecctx);
67 ++ av_free (data->read_out_buffer);
68 +
69 + g_string_free (data->outbuf, TRUE);
70 + g_free (data->buffer);
71 +@@ -132,6 +136,9 @@ xmms_avcodec_init (xmms_xform_t *xform)
72 + data->buffer_size = AVCODEC_BUFFER_SIZE;
73 + data->codecctx = NULL;
74 +
75 ++ data->read_out_buffer = av_malloc (AVCODEC_MAX_AUDIO_FRAME_SIZE);
76 ++ data->read_out_buffer_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
77 ++
78 + xmms_xform_private_data_set (xform, data);
79 +
80 + avcodec_init ();
81 +@@ -196,7 +203,7 @@ xmms_avcodec_init (xmms_xform_t *xform)
82 + } else {
83 + /* A demuxer plugin forgot to give decoder config? */
84 + xmms_log_error ("Decoder config data not found!");
85 +- return FALSE;
86 ++ goto err;
87 + }
88 + }
89 +
90 +@@ -220,7 +227,7 @@ xmms_avcodec_init (xmms_xform_t *xform)
91 +
92 + /* some codecs need to have something read before they set
93 + * the samplerate and channels correctly, unfortunately... */
94 +- if ((ret = xmms_avcodec_read (xform, buf, 42, &error)) > 0) {
95 ++ if ((ret = xmms_avcodec_read (xform, buf, sizeof (buf), &error)) > 0) {
96 + g_string_insert_len (data->outbuf, 0, buf, ret);
97 + } else {
98 + XMMS_DBG ("First read failed, codec is not working...");
99 +@@ -251,6 +258,9 @@ err:
100 + if (data->codecctx) {
101 + av_free (data->codecctx);
102 + }
103 ++ if (data->read_out_buffer) {
104 ++ av_free (data->read_out_buffer);
105 ++ }
106 + g_string_free (data->outbuf, TRUE);
107 + g_free (data->extradata);
108 + g_free (data);
109 +@@ -263,8 +273,7 @@ xmms_avcodec_read (xmms_xform_t *xform, xmms_sample_t *buf, gint len,
110 + xmms_error_t *error)
111 + {
112 + xmms_avcodec_data_t *data;
113 +- char outbuf[AVCODEC_MAX_AUDIO_FRAME_SIZE];
114 +- gint outbufsize, bytes_read = 0;
115 ++ gint bytes_read = 0;
116 + guint size;
117 +
118 + data = xmms_xform_private_data_get (xform);
119 +@@ -330,9 +339,9 @@ xmms_avcodec_read (xmms_xform_t *xform, xmms_sample_t *buf, gint len,
120 + packet.data = data->buffer;
121 + packet.size = data->buffer_length;
122 +
123 +- outbufsize = sizeof (outbuf);
124 +- bytes_read = avcodec_decode_audio3 (data->codecctx, (short *) outbuf,
125 +- &outbufsize, &packet);
126 ++ data->read_out_buffer_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
127 ++ bytes_read = avcodec_decode_audio3 (data->codecctx, (short *) data->read_out_buffer,
128 ++ &data->read_out_buffer_size, &packet);
129 +
130 + /* The DTS decoder of ffmpeg is buggy and always returns
131 + * the input buffer length, get frame length from header */
132 +@@ -354,8 +363,8 @@ xmms_avcodec_read (xmms_xform_t *xform, xmms_sample_t *buf, gint len,
133 +
134 + data->buffer_length -= bytes_read;
135 +
136 +- if (outbufsize > 0) {
137 +- g_string_append_len (data->outbuf, outbuf, outbufsize);
138 ++ if (data->read_out_buffer_size > 0) {
139 ++ g_string_append_len (data->outbuf, data->read_out_buffer, data->read_out_buffer_size);
140 + }
141 +
142 + size = MIN (data->outbuf->len, len);
143 +@@ -371,8 +380,7 @@ static gint64
144 + xmms_avcodec_seek (xmms_xform_t *xform, gint64 samples, xmms_xform_seek_mode_t whence, xmms_error_t *err)
145 + {
146 + xmms_avcodec_data_t *data;
147 +- char outbuf[AVCODEC_MAX_AUDIO_FRAME_SIZE];
148 +- gint outbufsize, bytes_read = 0;
149 ++ gint bytes_read = 0;
150 + gint64 ret = -1;
151 +
152 + g_return_val_if_fail (xform, -1);
153 +@@ -396,9 +404,9 @@ xmms_avcodec_seek (xmms_xform_t *xform, gint64 samples, xmms_xform_seek_mode_t w
154 + packet.data = data->buffer;
155 + packet.size = data->buffer_length;
156 +
157 +- outbufsize = sizeof (outbuf);
158 +- bytes_read = avcodec_decode_audio3 (data->codecctx, (short *) outbuf,
159 +- &outbufsize, &packet);
160 ++ data->read_out_buffer_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
161 ++ bytes_read = avcodec_decode_audio3 (data->codecctx, (short *) data->read_out_buffer,
162 ++ &data->read_out_buffer_size, &packet);
163 +
164 + if (bytes_read < 0 || bytes_read > data->buffer_length) {
165 + XMMS_DBG ("Error decoding data!");
166
167 diff --git a/media-sound/xmms2/files/xmms2-0.8-audio4-p2.patch b/media-sound/xmms2/files/xmms2-0.8-audio4-p2.patch
168 new file mode 100644
169 index 0000000..46b5b1d
170 --- /dev/null
171 +++ b/media-sound/xmms2/files/xmms2-0.8-audio4-p2.patch
172 @@ -0,0 +1,171 @@
173 +commit b614459dc1ea353d6c24b4a77c7f92a5577d5bc3
174 +Author: Uli Franke <cls@×××××××.org>
175 +Date: Thu Jan 19 11:53:57 2012 +0100
176 +
177 + BUG(2510): Add more bitrates/samplerates to AAC/ALAC.
178 +
179 +diff --git a/src/plugins/avcodec/avcodec.c b/src/plugins/avcodec/avcodec.c
180 +index 1b4a659..b32de4d 100644
181 +--- a/src/plugins/avcodec/avcodec.c
182 ++++ b/src/plugins/avcodec/avcodec.c
183 +@@ -60,6 +60,7 @@ static gint xmms_avcodec_read (xmms_xform_t *xform, xmms_sample_t *buf, gint len
184 + xmms_error_t *error);
185 + static gint64 xmms_avcodec_seek (xmms_xform_t *xform, gint64 samples,
186 + xmms_xform_seek_mode_t whence, xmms_error_t *err);
187 ++static xmms_sample_format_t xmms_avcodec_translate_sample_format (enum AVSampleFormat av_sample_format);
188 +
189 + /*
190 + * Plugin header
191 +@@ -168,12 +169,12 @@ xmms_avcodec_init (xmms_xform_t *xform)
192 + data->channels = ret;
193 + }
194 +
195 +- /* bitrate required for WMA files */
196 ++ /* Required by WMA xform. */
197 + xmms_xform_auxdata_get_int (xform,
198 + "bitrate",
199 + &data->bitrate);
200 +
201 +- /* ALAC and MAC require bits per sample field to be 16 */
202 ++ /* Required by tta and apefile xforms. */
203 + xmms_xform_auxdata_get_int (xform,
204 + "samplebits",
205 + &data->samplebits);
206 +@@ -238,12 +239,17 @@ xmms_avcodec_init (xmms_xform_t *xform)
207 +
208 + data->samplerate = data->codecctx->sample_rate;
209 + data->channels = data->codecctx->channels;
210 ++ data->sampleformat = xmms_avcodec_translate_sample_format (data->codecctx->sample_fmt);
211 ++ if (data->sampleformat == XMMS_SAMPLE_FORMAT_UNKNOWN) {
212 ++ avcodec_close (data->codecctx);
213 ++ goto err;
214 ++ }
215 +
216 + xmms_xform_outdata_type_add (xform,
217 + XMMS_STREAM_TYPE_MIMETYPE,
218 + "audio/pcm",
219 + XMMS_STREAM_TYPE_FMT_FORMAT,
220 +- XMMS_SAMPLE_FORMAT_S16,
221 ++ data->sampleformat,
222 + XMMS_STREAM_TYPE_FMT_CHANNELS,
223 + data->channels,
224 + XMMS_STREAM_TYPE_FMT_SAMPLERATE,
225 +@@ -428,3 +434,23 @@ xmms_avcodec_seek (xmms_xform_t *xform, gint64 samples, xmms_xform_seek_mode_t w
226 +
227 + return ret;
228 + }
229 ++
230 ++static xmms_sample_format_t
231 ++xmms_avcodec_translate_sample_format (enum AVSampleFormat av_sample_format)
232 ++{
233 ++ switch (av_sample_format) {
234 ++ case AV_SAMPLE_FMT_U8:
235 ++ return XMMS_SAMPLE_FORMAT_U8;
236 ++ case AV_SAMPLE_FMT_S16:
237 ++ return XMMS_SAMPLE_FORMAT_S16;
238 ++ case AV_SAMPLE_FMT_S32:
239 ++ return XMMS_SAMPLE_FORMAT_S32;
240 ++ case AV_SAMPLE_FMT_FLT:
241 ++ return XMMS_SAMPLE_FORMAT_FLOAT;
242 ++ case AV_SAMPLE_FMT_DBL:
243 ++ return XMMS_SAMPLE_FORMAT_DOUBLE;
244 ++ default:
245 ++ XMMS_DBG ("AVSampleFormat (%i) not supported.", av_sample_format);
246 ++ return XMMS_SAMPLE_FORMAT_UNKNOWN;
247 ++ }
248 ++}
249 +diff --git a/src/plugins/mp4/mp4.c b/src/plugins/mp4/mp4.c
250 +index 7c915c4..3ee9357 100644
251 +--- a/src/plugins/mp4/mp4.c
252 ++++ b/src/plugins/mp4/mp4.c
253 +@@ -186,9 +186,6 @@ xmms_mp4_init (xmms_xform_t *xform)
254 + xmms_xform_auxdata_set_bin (xform, "decoder_config", tmpbuf, tmpbuflen);
255 + g_free (tmpbuf);
256 +
257 +- /* This is only for ALAC to set 16-bit samples, ignored for AAC */
258 +- xmms_xform_auxdata_set_int (xform, "samplebits", 16);
259 +-
260 + xmms_mp4_get_mediainfo (xform);
261 +
262 + XMMS_DBG ("MP4 demuxer inited successfully!");
263 +@@ -288,7 +285,7 @@ xmms_mp4_get_mediainfo (xmms_xform_t *xform)
264 + data = xmms_xform_private_data_get (xform);
265 + g_return_if_fail (data);
266 +
267 +- if ((temp = mp4ff_get_sample_rate (data->mp4ff, data->track)) >= 0) {
268 ++ if ((temp = mp4ff_get_sample_rate (data->mp4ff, data->track)) > 0) {
269 + glong srate = temp;
270 +
271 + if ((temp = mp4ff_get_track_duration_use_offsets (data->mp4ff,
272 +@@ -492,7 +489,7 @@ xmms_mp4_get_track (xmms_xform_t *xform, mp4ff_t *infile)
273 + case 0x69: /* MPEG-2 audio */
274 + case 0x6B: /* MPEG-1 audio */
275 + continue;
276 +- case 0xff:
277 ++ case 0xff: /* ALAC */
278 + chans = mp4ff_get_channel_count (infile, i);
279 + rate = mp4ff_get_sample_rate (infile, i);
280 + if (chans <= 0 || rate <= 0) {
281 +diff --git a/src/plugins/mp4/mp4ff/README.xmms2 b/src/plugins/mp4/mp4ff/README.xmms2
282 +index c2737c5..8021618 100644
283 +--- a/src/plugins/mp4/mp4ff/README.xmms2
284 ++++ b/src/plugins/mp4/mp4ff/README.xmms2
285 +@@ -12,3 +12,4 @@ Changes:
286 + * Add value_length variable to tag type and use it when adding new item-value pairs,
287 + necessary for cover art since it's binary data and can't be handled as a string
288 + * Add support for Apple Lossless audio files
289 ++ * Add a workaround for supporting higher samplerates.
290 +diff --git a/src/plugins/mp4/mp4ff/mp4ff.c b/src/plugins/mp4/mp4ff/mp4ff.c
291 +index ee7f7fb..b6f0a37 100644
292 +--- a/src/plugins/mp4/mp4ff/mp4ff.c
293 ++++ b/src/plugins/mp4/mp4ff/mp4ff.c
294 +@@ -32,6 +32,8 @@
295 + #include <string.h>
296 + #include "mp4ffint.h"
297 +
298 ++static uint32_t mp4ff_normalize_flawed_sample_rate (uint16_t samplerate);
299 ++
300 + mp4ff_t *mp4ff_open_read(mp4ff_callback_t *f)
301 + {
302 + mp4ff_t *ff = malloc(sizeof(mp4ff_t));
303 +@@ -304,12 +306,39 @@ int32_t mp4ff_num_samples(const mp4ff_t *f, const int32_t track)
304 + return total;
305 + }
306 +
307 ++static uint32_t
308 ++mp4ff_normalize_flawed_sample_rate (uint16_t samplerate)
309 ++{
310 ++ /* A list of common rates can be found at
311 ++ * http://en.wikipedia.org/wiki/Sampling_rate */
312 ++ uint32_t rates[] = {8000, 11025, 16000, 22050, 32000, 44056, 44100,
313 ++ 47250, 48000, 50000, 50400, 88200, 96000, 176400,
314 ++ 192000, 352800, 384000, 0};
315 ++ uint32_t* rate;
316 ++
317 ++ /* First check standard rates. */
318 ++ for (rate = rates; *rate; rate++) {
319 ++ if (*rate == samplerate) {
320 ++ return *rate;
321 ++ }
322 ++ }
323 ++
324 ++ /* No standard rates matching - check if sample rate got truncated when
325 ++ * added to MP4 container */
326 ++ for (rate = rates; *rate; rate++) {
327 ++ if ((*rate & 0x0000FFFF) == samplerate) {
328 ++ return *rate;
329 ++ }
330 ++ }
331 +
332 ++ /* Failed to find a standard rate - we give up returning the original rate */
333 ++ return samplerate;
334 ++}
335 +
336 +
337 + uint32_t mp4ff_get_sample_rate(const mp4ff_t *f, const int32_t track)
338 + {
339 +- return f->track[track]->sampleRate;
340 ++ return mp4ff_normalize_flawed_sample_rate (f->track[track]->sampleRate);
341 + }
342 +
343 + uint32_t mp4ff_get_channel_count(const mp4ff_t * f,const int32_t track)
344
345 diff --git a/media-sound/xmms2/files/xmms2-0.8-audio4-p3.patch b/media-sound/xmms2/files/xmms2-0.8-audio4-p3.patch
346 new file mode 100644
347 index 0000000..a9145c0
348 --- /dev/null
349 +++ b/media-sound/xmms2/files/xmms2-0.8-audio4-p3.patch
350 @@ -0,0 +1,388 @@
351 +commit 4d0682030e20a8ed218f4ff924554f93d276d9ee
352 +Author: Anthony Garcia <lagg@×××××××.com>
353 +Date: Thu Apr 22 16:59:37 2010 -0700
354 +
355 + OTHER: Cleanup
356 +
357 + Re-enabled nellymoser (ffmpeg appears to be okay with it now)
358 +
359 + Fixed possible infinite loop in the code that handles the data (if any)
360 + between the header and tag data.
361 +
362 +diff --git a/src/plugins/avcodec/avcodec.c b/src/plugins/avcodec/avcodec.c
363 +index 6c9fea8..5554056 100644
364 +--- a/src/plugins/avcodec/avcodec.c
365 ++++ b/src/plugins/avcodec/avcodec.c
366 +@@ -90,7 +90,7 @@ xmms_avcodec_plugin_setup (xmms_xform_plugin_t *xform_plugin)
367 + xmms_magic_add ("A/52 (AC-3) header", "audio/x-ffmpeg-ac3",
368 + "0 beshort 0x0b77", NULL);
369 + xmms_magic_add ("DTS header", "audio/x-ffmpeg-dca",
370 +- "0 belong 0x7ffe8001", NULL);
371 ++ "0 belong 0x7ffe8001", NULL);
372 +
373 + xmms_xform_plugin_indata_add (xform_plugin,
374 + XMMS_STREAM_TYPE_MIMETYPE,
375 +@@ -197,7 +197,8 @@ xmms_avcodec_init (xmms_xform_t *xform)
376 + !strcmp (data->codec_id, "adpcm_swf") ||
377 + !strcmp (data->codec_id, "pcm_s16le") ||
378 + !strcmp (data->codec_id, "ac3") ||
379 +- !strcmp (data->codec_id, "dca")) {
380 ++ !strcmp (data->codec_id, "dca") ||
381 ++ !strcmp (data->codec_id, "nellymoser")) {
382 + /* number 1024 taken from libavformat raw.c RAW_PACKET_SIZE */
383 + data->extradata = g_malloc0 (1024);
384 + data->extradata_size = 1024;
385 +diff --git a/src/plugins/flv/flv.c b/src/plugins/flv/flv.c
386 +index 440010c..266fea6 100644
387 +--- a/src/plugins/flv/flv.c
388 ++++ b/src/plugins/flv/flv.c
389 +@@ -25,29 +25,41 @@
390 + * and other info, then data
391 + */
392 + #define FLV_TAG_SIZE 11
393 +-/* random constant */
394 + #define FLV_CHUNK_SIZE 4096
395 +
396 +-/* let libavcodec take care of swapping sample bytes */
397 +-static const gchar *mime_pcm_s16le = "audio/x-ffmpeg-pcm_s16le";
398 +-static const gchar *fmt_mime[11] = {
399 +- /* Supported when samples are 8 bit
400 +- * (otherwise there's no way of knowing endianness)
401 +- */
402 +- "audio/pcm",
403 +- "audio/x-ffmpeg-adpcm_swf",
404 +- "audio/mpeg",
405 +- /* if bps is 8 bit u8
406 +- * if bps is 16 bit sle16
407 +- */
408 +- "audio/pcm",
409 +- /* libavcodec can't handle nelly without dying yet */
410 +- /*"audio/x-ffmpeg-nellymoser",
411 +- "audio/x-ffmpeg-nellymoser",
412 +- "audio/x-ffmpeg-nellymoser",*/
413 +- "", "", "",
414 +- "", "", "",
415 +- "audio/aac"
416 ++typedef enum {
417 ++ /* Only u8 bit samples since
418 ++ there's no way to determine endianness
419 ++ */
420 ++ CODEC_PCM_HOST,
421 ++ CODEC_ADPCM,
422 ++ CODEC_MP3,
423 ++ /* 8 bps: unsigned
424 ++ 16 bps: signed
425 ++ */
426 ++ CODEC_PCM_LE,
427 ++ CODEC_NELLYMOSER_16K,
428 ++ CODEC_NELLYMOSER_8K,
429 ++ /* Uses the sample rate in
430 ++ the tag as normal
431 ++ */
432 ++ CODEC_NELLYMOSER,
433 ++ CODEC_AAC = 10
434 ++} xmms_flv_codec_id;
435 ++
436 ++struct xmms_flv_codec_table {
437 ++ xmms_flv_codec_id id;
438 ++ const gchar *mime;
439 ++} static flv_codecs[] = {
440 ++ {CODEC_PCM_HOST, "audio/pcm"},
441 ++ {CODEC_ADPCM, "audio/x-ffmpeg-adpcm_swf"},
442 ++ {CODEC_MP3, "audio/mpeg"},
443 ++ /* Will be audio/x-ffmpeg-pcm_s16le if bps is 16 */
444 ++ {CODEC_PCM_LE, "audio/pcm"},
445 ++ {CODEC_NELLYMOSER_16K, "audio/x-ffmpeg-nellymoser"},
446 ++ {CODEC_NELLYMOSER_8K, "audio/x-ffmpeg-nellymoser"},
447 ++ {CODEC_NELLYMOSER, "audio/x-ffmpeg-nellymoser"},
448 ++ {CODEC_AAC, "audio/aac"}
449 + };
450 +
451 + typedef struct {
452 +@@ -111,23 +123,26 @@ static gboolean
453 + xmms_flv_init (xmms_xform_t *xform)
454 + {
455 + xmms_sample_format_t bps;
456 +- gint readret;
457 ++ gint readret, i;
458 + guint8 channels, flags, format;
459 +- guint8 header[FLV_TAG_SIZE + 5];
460 +- const gchar *mime;
461 ++ guint8 header[FLV_TAG_SIZE + 1];
462 + guint32 dataoffset, samplerate;
463 + xmms_error_t err;
464 + xmms_flv_data_t *flvdata;
465 ++ struct xmms_flv_codec_table *codec = NULL;
466 ++
467 ++ flvdata = g_new0 (xmms_flv_data_t, 1);
468 ++ xmms_xform_private_data_set (xform, flvdata);
469 +
470 + readret = xmms_xform_read (xform, header, FLV_HDR_SIZE, &err);
471 + if (readret != FLV_HDR_SIZE) {
472 + xmms_log_error ("Header read error");
473 +- return FALSE;
474 ++ goto init_err;
475 + }
476 +
477 + if ((header[4] & HAS_AUDIO) != HAS_AUDIO) {
478 + xmms_log_error ("FLV has no audio stream");
479 +- return FALSE;
480 ++ goto init_err;
481 + }
482 +
483 + dataoffset = get_be32 (&header[5]) - FLV_HDR_SIZE;
484 +@@ -140,7 +155,7 @@ xmms_flv_init (xmms_xform_t *xform)
485 + dataoffset : FLV_HDR_SIZE, &err);
486 + if (readret <= 0) {
487 + xmms_log_error ("Error reading header:tag body gap");
488 +- return FALSE;
489 ++ goto init_err;
490 + }
491 +
492 + dataoffset -= readret;
493 +@@ -148,86 +163,99 @@ xmms_flv_init (xmms_xform_t *xform)
494 +
495 + if (next_audio_tag (xform) <= 0) {
496 + xmms_log_error ("Can't find first audio tag");
497 +- return FALSE;
498 ++ goto init_err;
499 + }
500 +
501 +- if (xmms_xform_peek (xform, header, FLV_TAG_SIZE + 5, &err) < FLV_TAG_SIZE + 5) {
502 ++ if (xmms_xform_read (xform, header, FLV_TAG_SIZE + 1, &err) < FLV_TAG_SIZE + 1) {
503 + xmms_log_error ("Can't read first audio tag");
504 +- return FALSE;
505 ++ goto init_err;
506 + }
507 +
508 +- flags = header[FLV_TAG_SIZE + 4];
509 ++ flags = header[11];
510 + XMMS_DBG ("Audio flags: %X", flags);
511 +
512 +- switch (flags&12) {
513 +- case 0: samplerate = 5512; break;
514 +- case 4: samplerate = 11025; break;
515 +- case 8: samplerate = 22050; break;
516 +- case 12: samplerate = 44100; break;
517 +- default: samplerate = 8000; break;
518 ++ format = flags >> 4;
519 ++ for (i = 0; i < G_N_ELEMENTS (flv_codecs); i++) {
520 ++ if (flv_codecs[i].id == format) {
521 ++ codec = &flv_codecs[i];
522 ++ break;
523 ++ }
524 + }
525 +
526 +- if (flags&2) {
527 +- bps = XMMS_SAMPLE_FORMAT_S16;
528 ++ if (flags & 1) {
529 ++ channels = 2;
530 + } else {
531 +- bps = XMMS_SAMPLE_FORMAT_U8;
532 ++ channels = 1;
533 + }
534 +
535 +- if (flags&1) {
536 +- channels = 2;
537 ++ if (flags & 2) {
538 ++ bps = XMMS_SAMPLE_FORMAT_S16;
539 + } else {
540 +- channels = 1;
541 ++ bps = XMMS_SAMPLE_FORMAT_U8;
542 + }
543 +
544 +- format = flags >> 4;
545 +- mime = (format <= 10)? fmt_mime[format] : NULL;
546 +- switch (format) {
547 +- case 0:
548 +- /* If the flv has an HE PCM audio stream, the
549 +- * samples must be unsigned and 8 bits long
550 +- */
551 +- if (bps != XMMS_SAMPLE_FORMAT_U8) {
552 +- xmms_log_error ("Only u8 HE PCM is supported");
553 +- return FALSE;
554 +- }
555 +- break;
556 +- case 3:
557 +- if (bps == XMMS_SAMPLE_FORMAT_S16) {
558 +- mime = mime_pcm_s16le;
559 +- }
560 +- break;
561 ++ switch ((flags & 12) >> 2) {
562 ++ case 0: samplerate = 5512; break;
563 ++ case 1: samplerate = 11025; break;
564 ++ case 2: samplerate = 22050; break;
565 ++ case 3: samplerate = 44100; break;
566 ++ default: samplerate = 8000; break;
567 + }
568 +
569 +- if (mime && *mime) {
570 +- flvdata = g_new0 (xmms_flv_data_t, 1);
571 ++ if (codec) {
572 ++ switch (codec->id) {
573 ++ case CODEC_PCM_HOST:
574 ++ if (bps != XMMS_SAMPLE_FORMAT_U8) {
575 ++ xmms_log_error ("Only u8 HE PCM is supported");
576 ++ goto init_err;
577 ++ }
578 ++ break;
579 ++ case CODEC_PCM_LE:
580 ++ if (bps == XMMS_SAMPLE_FORMAT_S16) {
581 ++ codec->mime = "audio/x-ffmpeg-pcm_s16le";
582 ++ }
583 ++ break;
584 ++ case CODEC_NELLYMOSER_16K:
585 ++ samplerate = 16000;
586 ++ break;
587 ++ case CODEC_NELLYMOSER_8K:
588 ++ samplerate = 8000;
589 ++ break;
590 ++ default:
591 ++ break;
592 ++ }
593 ++
594 + flvdata->format = format;
595 ++ flvdata->last_datasize = get_be24 (&header[1]) - 1;
596 +
597 + XMMS_DBG ("Rate: %d, bps: %d, channels: %d", samplerate,
598 + bps, channels);
599 +
600 +- xmms_xform_private_data_set (xform, flvdata);
601 + xmms_xform_outdata_type_add (xform,
602 + XMMS_STREAM_TYPE_MIMETYPE,
603 +- mime,
604 +- XMMS_STREAM_TYPE_FMT_SAMPLERATE,
605 +- samplerate,
606 +- XMMS_STREAM_TYPE_FMT_FORMAT,
607 +- bps,
608 +- XMMS_STREAM_TYPE_FMT_CHANNELS,
609 +- channels,
610 +- XMMS_STREAM_TYPE_END);
611 ++ codec->mime,
612 ++ XMMS_STREAM_TYPE_FMT_SAMPLERATE,
613 ++ samplerate,
614 ++ XMMS_STREAM_TYPE_FMT_FORMAT,
615 ++ bps,
616 ++ XMMS_STREAM_TYPE_FMT_CHANNELS,
617 ++ channels,
618 ++ XMMS_STREAM_TYPE_END);
619 + return TRUE;
620 + } else {
621 + xmms_log_error ("Unsupported audio format");
622 +- return FALSE;
623 + }
624 ++
625 ++init_err:
626 ++ g_free (flvdata);
627 ++ return FALSE;
628 + }
629 +
630 + static gint
631 + xmms_flv_read (xmms_xform_t *xform, xmms_sample_t *buf, gint len, xmms_error_t *err)
632 + {
633 +- gint ret = 0, thismuch = FLV_TAG_SIZE + 5;
634 +- guint8 header[FLV_TAG_SIZE + 6], gap = 1;
635 ++ gint ret = 0, thismuch = FLV_TAG_SIZE + 1;
636 ++ guint8 header[FLV_TAG_SIZE + 1];
637 + xmms_flv_data_t *data = NULL;
638 +
639 + data = xmms_xform_private_data_get (xform);
640 +@@ -236,12 +264,8 @@ xmms_flv_read (xmms_xform_t *xform, xmms_sample_t *buf, gint len, xmms_error_t *
641 + xmms_xform_auxdata_barrier (xform);
642 + ret = next_audio_tag (xform);
643 + if (ret > 0) {
644 +- if (data->format == 10) {
645 +- thismuch++;
646 +- gap++;
647 +- }
648 + if (xmms_xform_read (xform, header, thismuch, err) == thismuch) {
649 +- data->last_datasize = get_be24 (&header[5]) - gap;
650 ++ data->last_datasize = get_be24 (&header[1]) - 1;
651 + } else {
652 + xmms_log_error ("Need %d bytes", thismuch);
653 + return -1;
654 +@@ -280,40 +304,51 @@ xmms_flv_destroy (xmms_xform_t *xform)
655 + static gint
656 + next_audio_tag (xmms_xform_t *xform)
657 + {
658 +- guint8 header[FLV_TAG_SIZE + 4];
659 ++ guint8 header[FLV_TAG_SIZE];
660 + guint8 dumb[FLV_CHUNK_SIZE];
661 + gint ret = 0;
662 + xmms_error_t err;
663 +- guint32 datasize = 0;
664 ++ xmms_flv_data_t *data;
665 ++
666 ++ data = xmms_xform_private_data_get (xform);
667 +
668 + do {
669 +- /* there's a last 4 bytes at the end of an FLV giving the final
670 +- * tag's size, this isn't an error
671 +- */
672 +- ret = xmms_xform_peek (xform, header, FLV_TAG_SIZE + 4, &err);
673 +- if ((ret < FLV_TAG_SIZE) && (ret > -1)) {
674 +- ret = 0;
675 +- break;
676 +- } else if (ret == -1) {
677 +- xmms_log_error ("%s", xmms_error_message_get (&err));
678 +- break;
679 +- }
680 ++ /* If > 0 assume we're in the middle of a tag's data */
681 ++ if (!data->last_datasize) {
682 ++ /* There are 4 bytes before an actual tag giving
683 ++ the previous tag's size. The first size in an
684 ++ flv is always 0.
685 ++ */
686 ++ if (xmms_xform_read (xform, header, 4, &err) != 4) {
687 ++ xmms_log_error ("Couldn't read last tag size");
688 ++ return -1;
689 ++ }
690 +
691 +- if (header[4] == 8) {
692 +- /* woo audio tag! */
693 +- break;
694 +- }
695 ++ ret = xmms_xform_peek (xform, header, FLV_TAG_SIZE, &err);
696 ++ if ((ret < FLV_TAG_SIZE) && (ret > -1)) {
697 ++ return 0;
698 ++ } else if (ret == -1) {
699 ++ xmms_log_error ("%s", xmms_error_message_get (&err));
700 ++ return ret;
701 ++ }
702 ++
703 ++ if (header[0] == 8) {
704 ++ /* woo audio tag! */
705 ++ break;
706 ++ }
707 +
708 +- ret = xmms_xform_read (xform, header, FLV_TAG_SIZE + 4, &err);
709 +- if (ret <= 0) { return ret; }
710 ++ if ((ret = xmms_xform_read (xform, header, FLV_TAG_SIZE, &err)) <= 0) {
711 ++ return ret;
712 ++ }
713 +
714 +- datasize = get_be24 (&header[5]);
715 ++ data->last_datasize = get_be24 (&header[1]);
716 ++ }
717 +
718 +- while (datasize) {
719 ++ while (data->last_datasize) {
720 + ret = xmms_xform_read (xform, dumb,
721 +- (datasize < FLV_CHUNK_SIZE) ?
722 +- datasize : FLV_CHUNK_SIZE,
723 +- &err);
724 ++ (data->last_datasize < FLV_CHUNK_SIZE) ?
725 ++ data->last_datasize : FLV_CHUNK_SIZE,
726 ++ &err);
727 + if (ret == 0) {
728 + xmms_log_error ("Data field short!");
729 + break;
730 +@@ -323,7 +358,7 @@ next_audio_tag (xmms_xform_t *xform)
731 + break;
732 + }
733 +
734 +- datasize -= ret;
735 ++ data->last_datasize -= ret;
736 + }
737 +
738 + } while (ret);
739
740 diff --git a/media-sound/xmms2/files/xmms2-0.8-audio4-p4.patch b/media-sound/xmms2/files/xmms2-0.8-audio4-p4.patch
741 new file mode 100644
742 index 0000000..552f202
743 --- /dev/null
744 +++ b/media-sound/xmms2/files/xmms2-0.8-audio4-p4.patch
745 @@ -0,0 +1,296 @@
746 +commit 4198d9bf5dff517740ed51b22313367f156107e1
747 +Author: Erik Massop <e.massop@××××××.nl>
748 +Date: Sun Dec 22 17:19:30 2013 +0100
749 +
750 + OTHER: Split xmms_avcodec_read, remove some duplicate code
751 +
752 +diff --git a/src/plugins/avcodec/avcodec.c b/src/plugins/avcodec/avcodec.c
753 +index 5b9b606..eed7964 100644
754 +--- a/src/plugins/avcodec/avcodec.c
755 ++++ b/src/plugins/avcodec/avcodec.c
756 +@@ -57,6 +57,9 @@ typedef struct {
757 + static gboolean xmms_avcodec_plugin_setup (xmms_xform_plugin_t *xform_plugin);
758 + static gboolean xmms_avcodec_init (xmms_xform_t *xform);
759 + static void xmms_avcodec_destroy (xmms_xform_t *xform);
760 ++static gint xmms_avcodec_internal_read_some (xmms_xform_t *xform, xmms_avcodec_data_t *data, xmms_error_t *error);
761 ++static gint xmms_avcodec_internal_decode_some (xmms_avcodec_data_t *data);
762 ++static void xmms_avcodec_internal_append (xmms_avcodec_data_t *data);
763 + static gint xmms_avcodec_read (xmms_xform_t *xform, xmms_sample_t *buf, gint len,
764 + xmms_error_t *error);
765 + static gint64 xmms_avcodec_seek (xmms_xform_t *xform, gint64 samples,
766 +@@ -281,101 +284,24 @@ xmms_avcodec_read (xmms_xform_t *xform, xmms_sample_t *buf, gint len,
767 + xmms_error_t *error)
768 + {
769 + xmms_avcodec_data_t *data;
770 +- gint bytes_read = 0;
771 + guint size;
772 +
773 + data = xmms_xform_private_data_get (xform);
774 + g_return_val_if_fail (data, -1);
775 +
776 +- size = MIN (data->outbuf->len, len);
777 +- while (size == 0) {
778 +- AVPacket packet;
779 +- av_init_packet (&packet);
780 ++ while (0 == (size = MIN (data->outbuf->len, len))) {
781 ++ gint res;
782 +
783 + if (data->no_demuxer || data->buffer_length == 0) {
784 +- gint read_total;
785 +-
786 +- bytes_read = xmms_xform_read (xform,
787 +- (gchar *) (data->buffer + data->buffer_length),
788 +- data->buffer_size - data->buffer_length,
789 +- error);
790 +-
791 +- if (bytes_read < 0) {
792 +- XMMS_DBG ("Error while reading data");
793 +- return bytes_read;
794 +- } else if (bytes_read == 0) {
795 +- XMMS_DBG ("EOF");
796 +- return 0;
797 +- }
798 +-
799 +- read_total = bytes_read;
800 +-
801 +- /* If we have a demuxer plugin, make sure we read the whole packet */
802 +- while (read_total == data->buffer_size && !data->no_demuxer) {
803 +- /* multiply the buffer size and try to read again */
804 +- data->buffer = g_realloc (data->buffer, data->buffer_size * 2);
805 +- bytes_read = xmms_xform_read (xform,
806 +- (gchar *) data->buffer +
807 +- data->buffer_size,
808 +- data->buffer_size,
809 +- error);
810 +- data->buffer_size *= 2;
811 +-
812 +- if (bytes_read < 0) {
813 +- XMMS_DBG ("Error while reading data");
814 +- return bytes_read;
815 +- }
816 +-
817 +- read_total += bytes_read;
818 +-
819 +- if (read_total < data->buffer_size) {
820 +- /* finally double the buffer size for performance reasons, the
821 +- * hotspot handling likes to fit two frames in the buffer */
822 +- data->buffer = g_realloc (data->buffer, data->buffer_size * 2);
823 +- data->buffer_size *= 2;
824 +- XMMS_DBG ("Reallocated avcodec internal buffer to be %d bytes",
825 +- data->buffer_size);
826 +-
827 +- break;
828 +- }
829 +- }
830 +-
831 +- /* Update the buffer length */
832 +- data->buffer_length += read_total;
833 +- }
834 +-
835 +- packet.data = data->buffer;
836 +- packet.size = data->buffer_length;
837 +-
838 +- data->read_out_buffer_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
839 +- bytes_read = avcodec_decode_audio3 (data->codecctx, (short *) data->read_out_buffer,
840 +- &data->read_out_buffer_size, &packet);
841 ++ gint bytes_read;
842 +
843 +- /* The DTS decoder of ffmpeg is buggy and always returns
844 +- * the input buffer length, get frame length from header */
845 +- if (!strcmp (data->codec_id, "dca") && bytes_read > 0) {
846 +- bytes_read = ((int)data->buffer[5] << 12) |
847 +- ((int)data->buffer[6] << 4) |
848 +- ((int)data->buffer[7] >> 4);
849 +- bytes_read = (bytes_read & 0x3fff) + 1;
850 ++ bytes_read = xmms_avcodec_internal_read_some (xform, data, error);
851 ++ if (bytes_read <= 0) { return bytes_read; }
852 + }
853 +
854 +- if (bytes_read < 0 || bytes_read > data->buffer_length) {
855 +- XMMS_DBG ("Error decoding data!");
856 +- return -1;
857 +- } else if (bytes_read != data->buffer_length) {
858 +- g_memmove (data->buffer,
859 +- data->buffer + bytes_read,
860 +- data->buffer_length - bytes_read);
861 +- }
862 +-
863 +- data->buffer_length -= bytes_read;
864 +-
865 +- if (data->read_out_buffer_size > 0) {
866 +- g_string_append_len (data->outbuf, data->read_out_buffer, data->read_out_buffer_size);
867 +- }
868 +-
869 +- size = MIN (data->outbuf->len, len);
870 ++ res = xmms_avcodec_internal_decode_some (data);
871 ++ if (res < 0) { return res; }
872 ++ if (res > 0) { xmms_avcodec_internal_append (data); }
873 + }
874 +
875 + memcpy (buf, data->outbuf->str, size);
876 +@@ -388,7 +314,6 @@ static gint64
877 + xmms_avcodec_seek (xmms_xform_t *xform, gint64 samples, xmms_xform_seek_mode_t whence, xmms_error_t *err)
878 + {
879 + xmms_avcodec_data_t *data;
880 +- gint bytes_read = 0;
881 + gint64 ret = -1;
882 +
883 + g_return_val_if_fail (xform, -1);
884 +@@ -406,23 +331,11 @@ xmms_avcodec_seek (xmms_xform_t *xform, gint64 samples, xmms_xform_seek_mode_t w
885 +
886 + /* The buggy ape decoder doesn't flush buffers, so we need to finish decoding
887 + * the frame before seeking to avoid segfaults... this hack sucks */
888 ++ /* FIXME: Is ^^^ still true? */
889 + while (data->buffer_length > 0) {
890 +- AVPacket packet;
891 +- av_init_packet (&packet);
892 +- packet.data = data->buffer;
893 +- packet.size = data->buffer_length;
894 +-
895 +- data->read_out_buffer_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
896 +- bytes_read = avcodec_decode_audio3 (data->codecctx, (short *) data->read_out_buffer,
897 +- &data->read_out_buffer_size, &packet);
898 +-
899 +- if (bytes_read < 0 || bytes_read > data->buffer_length) {
900 +- XMMS_DBG ("Error decoding data!");
901 ++ if (xmms_avcodec_internal_decode_some (data) < 0) {
902 + return -1;
903 + }
904 +-
905 +- data->buffer_length -= bytes_read;
906 +- g_memmove (data->buffer, data->buffer + bytes_read, data->buffer_length);
907 + }
908 +
909 + ret = xmms_xform_seek (xform, samples, whence, err);
910 +@@ -456,3 +369,131 @@ xmms_avcodec_translate_sample_format (enum AVSampleFormat av_sample_format)
911 + return XMMS_SAMPLE_FORMAT_UNKNOWN;
912 + }
913 + }
914 ++
915 ++/*
916 ++Read some data from our source of data to data->buffer, updating buffer_length
917 ++and buffer_size as needed.
918 ++
919 ++Returns: on error: negative
920 ++ on EOF: zero
921 ++ otherwise: number of bytes read.
922 ++*/
923 ++static gint
924 ++xmms_avcodec_internal_read_some (xmms_xform_t *xform,
925 ++ xmms_avcodec_data_t *data,
926 ++ xmms_error_t *error)
927 ++{
928 ++ gint bytes_read, read_total;
929 ++
930 ++ bytes_read = xmms_xform_read (xform,
931 ++ (gchar *) (data->buffer + data->buffer_length),
932 ++ data->buffer_size - data->buffer_length,
933 ++ error);
934 ++
935 ++ if (bytes_read < 0) {
936 ++ XMMS_DBG ("Error while reading data");
937 ++ return bytes_read;
938 ++ } else if (bytes_read == 0) {
939 ++ XMMS_DBG ("EOF");
940 ++ return 0;
941 ++ }
942 ++
943 ++ read_total = bytes_read;
944 ++
945 ++ /* If we have a demuxer plugin, make sure we read the whole packet */
946 ++ while (read_total == data->buffer_size && !data->no_demuxer) {
947 ++ /* multiply the buffer size and try to read again */
948 ++ data->buffer = g_realloc (data->buffer, data->buffer_size * 2);
949 ++ bytes_read = xmms_xform_read (xform,
950 ++ (gchar *) data->buffer +
951 ++ data->buffer_size,
952 ++ data->buffer_size,
953 ++ error);
954 ++ data->buffer_size *= 2;
955 ++
956 ++ if (bytes_read < 0) {
957 ++ XMMS_DBG ("Error while reading data");
958 ++ return bytes_read;
959 ++ }
960 ++
961 ++ read_total += bytes_read;
962 ++
963 ++ if (read_total < data->buffer_size) {
964 ++ /* finally double the buffer size for performance reasons, the
965 ++ * hotspot handling likes to fit two frames in the buffer */
966 ++ data->buffer = g_realloc (data->buffer, data->buffer_size * 2);
967 ++ data->buffer_size *= 2;
968 ++ XMMS_DBG ("Reallocated avcodec internal buffer to be %d bytes",
969 ++ data->buffer_size);
970 ++
971 ++ break;
972 ++ }
973 ++ }
974 ++
975 ++ /* Update the buffer length */
976 ++ data->buffer_length += read_total;
977 ++
978 ++ return read_total;
979 ++}
980 ++
981 ++/*
982 ++Decode some data from data->buffer[0..data->buffer_length-1] to
983 ++data->read_out_buffer. Number of bytes in data->read_out_buffer
984 ++is stored in data->read_out_buffer_size.
985 ++
986 ++Returns: on error: negative
987 ++ on no new data produced: zero
988 ++ otherwise: positive
989 ++
990 ++FIXME: data->buffer should be at least data->buffer_length +
991 ++FF_INPUT_BUFFER_PADDING_SIZE long.
992 ++*/
993 ++static gint
994 ++xmms_avcodec_internal_decode_some (xmms_avcodec_data_t *data)
995 ++{
996 ++ gint bytes_read = 0;
997 ++ AVPacket packet;
998 ++
999 ++ av_init_packet (&packet);
1000 ++ packet.data = data->buffer;
1001 ++ packet.size = data->buffer_length;
1002 ++
1003 ++ data->read_out_buffer_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
1004 ++ bytes_read = avcodec_decode_audio3 (data->codecctx,
1005 ++ (short *) data->read_out_buffer,
1006 ++ &data->read_out_buffer_size, &packet);
1007 ++
1008 ++ /* The DTS decoder of ffmpeg is buggy and always returns
1009 ++ * the input buffer length, get frame length from header */
1010 ++ /* FIXME: Is ^^^^ still true? */
1011 ++ if (!strcmp (data->codec_id, "dca") && bytes_read > 0) {
1012 ++ bytes_read = ((int)data->buffer[5] << 12) |
1013 ++ ((int)data->buffer[6] << 4) |
1014 ++ ((int)data->buffer[7] >> 4);
1015 ++ bytes_read = (bytes_read & 0x3fff) + 1;
1016 ++ }
1017 ++
1018 ++ if (bytes_read < 0 || bytes_read > data->buffer_length) {
1019 ++ XMMS_DBG ("Error decoding data!");
1020 ++ return -1;
1021 ++ }
1022 ++
1023 ++ if (bytes_read < data->buffer_length) {
1024 ++ data->buffer_length -= bytes_read;
1025 ++ g_memmove (data->buffer,
1026 ++ data->buffer + bytes_read,
1027 ++ data->buffer_length);
1028 ++ } else {
1029 ++ data->buffer_length = 0;
1030 ++ }
1031 ++
1032 ++ return data->read_out_buffer_size;
1033 ++}
1034 ++
1035 ++static void
1036 ++xmms_avcodec_internal_append (xmms_avcodec_data_t *data)
1037 ++{
1038 ++ g_string_append_len (data->outbuf,
1039 ++ (gchar *) data->read_out_buffer,
1040 ++ data->read_out_buffer_size);
1041 ++}
1042
1043 diff --git a/media-sound/xmms2/files/xmms2-0.8-audio4-p5.patch b/media-sound/xmms2/files/xmms2-0.8-audio4-p5.patch
1044 new file mode 100644
1045 index 0000000..8ed5bb4
1046 --- /dev/null
1047 +++ b/media-sound/xmms2/files/xmms2-0.8-audio4-p5.patch
1048 @@ -0,0 +1,154 @@
1049 +commit d44312fb14bde0ab47ee6de1b3fe7435d4a97c99
1050 +Author: Erik Massop <e.massop@××××××.nl>
1051 +Date: Sun Dec 22 20:01:18 2013 +0100
1052 +
1053 + BUG(2572): Use avcodec_decode_audio4
1054 +
1055 +diff --git a/src/plugins/avcodec/avcodec.c b/src/plugins/avcodec/avcodec.c
1056 +index 266a607..a41a675 100644
1057 +--- a/src/plugins/avcodec/avcodec.c
1058 ++++ b/src/plugins/avcodec/avcodec.c
1059 +@@ -37,8 +37,7 @@ typedef struct {
1060 + guint buffer_size;
1061 + gboolean no_demuxer;
1062 +
1063 +- gchar *read_out_buffer;
1064 +- gint read_out_buffer_size;
1065 ++ AVFrame *read_out_frame;
1066 +
1067 + guint channels;
1068 + guint samplerate;
1069 +@@ -125,7 +124,7 @@ xmms_avcodec_destroy (xmms_xform_t *xform)
1070 +
1071 + avcodec_close (data->codecctx);
1072 + av_free (data->codecctx);
1073 +- av_free (data->read_out_buffer);
1074 ++ avcodec_free_frame (&data->read_out_frame);
1075 +
1076 + g_string_free (data->outbuf, TRUE);
1077 + g_free (data->buffer);
1078 +@@ -151,8 +150,7 @@ xmms_avcodec_init (xmms_xform_t *xform)
1079 + data->buffer_size = AVCODEC_BUFFER_SIZE;
1080 + data->codecctx = NULL;
1081 +
1082 +- data->read_out_buffer = av_malloc (AVCODEC_MAX_AUDIO_FRAME_SIZE);
1083 +- data->read_out_buffer_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
1084 ++ data->read_out_frame = avcodec_alloc_frame ();
1085 +
1086 + xmms_xform_private_data_set (xform, data);
1087 +
1088 +@@ -233,6 +231,7 @@ xmms_avcodec_init (xmms_xform_t *xform)
1089 + data->codecctx->extradata_size = data->extradata_size;
1090 + data->codecctx->codec_id = codec->id;
1091 + data->codecctx->codec_type = codec->type;
1092 ++ data->codecctx->refcounted_frames = 0;
1093 +
1094 + if (avcodec_open2 (data->codecctx, codec, NULL) < 0) {
1095 + XMMS_DBG ("Opening decoder '%s' failed", codec->name);
1096 +@@ -279,8 +278,8 @@ err:
1097 + if (data->codecctx) {
1098 + av_free (data->codecctx);
1099 + }
1100 +- if (data->read_out_buffer) {
1101 +- av_free (data->read_out_buffer);
1102 ++ if (data->read_out_frame) {
1103 ++ avcodec_free_frame (&data->read_out_frame);
1104 + }
1105 + g_string_free (data->outbuf, TRUE);
1106 + g_free (data->extradata);
1107 +@@ -365,17 +364,23 @@ xmms_avcodec_translate_sample_format (enum AVSampleFormat av_sample_format)
1108 + {
1109 + switch (av_sample_format) {
1110 + case AV_SAMPLE_FMT_U8:
1111 ++ case AV_SAMPLE_FMT_U8P:
1112 + return XMMS_SAMPLE_FORMAT_U8;
1113 + case AV_SAMPLE_FMT_S16:
1114 ++ case AV_SAMPLE_FMT_S16P:
1115 + return XMMS_SAMPLE_FORMAT_S16;
1116 + case AV_SAMPLE_FMT_S32:
1117 ++ case AV_SAMPLE_FMT_S32P:
1118 + return XMMS_SAMPLE_FORMAT_S32;
1119 + case AV_SAMPLE_FMT_FLT:
1120 ++ case AV_SAMPLE_FMT_FLTP:
1121 + return XMMS_SAMPLE_FORMAT_FLOAT;
1122 + case AV_SAMPLE_FMT_DBL:
1123 ++ case AV_SAMPLE_FMT_DBLP:
1124 + return XMMS_SAMPLE_FORMAT_DOUBLE;
1125 + default:
1126 +- XMMS_DBG ("AVSampleFormat (%i) not supported.", av_sample_format);
1127 ++ XMMS_DBG ("AVSampleFormat (%i: %s) not supported.", av_sample_format,
1128 ++ av_get_sample_fmt_name (av_sample_format));
1129 + return XMMS_SAMPLE_FORMAT_UNKNOWN;
1130 + }
1131 + }
1132 +@@ -448,8 +453,7 @@ xmms_avcodec_internal_read_some (xmms_xform_t *xform,
1133 +
1134 + /*
1135 + Decode some data from data->buffer[0..data->buffer_length-1] to
1136 +-data->read_out_buffer. Number of bytes in data->read_out_buffer
1137 +-is stored in data->read_out_buffer_size.
1138 ++data->read_out_frame
1139 +
1140 + Returns: on error: negative
1141 + on no new data produced: zero
1142 +@@ -461,6 +465,7 @@ FF_INPUT_BUFFER_PADDING_SIZE long.
1143 + static gint
1144 + xmms_avcodec_internal_decode_some (xmms_avcodec_data_t *data)
1145 + {
1146 ++ int got_frame = 0;
1147 + gint bytes_read = 0;
1148 + AVPacket packet;
1149 +
1150 +@@ -468,10 +473,10 @@ xmms_avcodec_internal_decode_some (xmms_avcodec_data_t *data)
1151 + packet.data = data->buffer;
1152 + packet.size = data->buffer_length;
1153 +
1154 +- data->read_out_buffer_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
1155 +- bytes_read = avcodec_decode_audio3 (data->codecctx,
1156 +- (short *) data->read_out_buffer,
1157 +- &data->read_out_buffer_size, &packet);
1158 ++ avcodec_get_frame_defaults (data->read_out_frame);
1159 ++
1160 ++ bytes_read = avcodec_decode_audio4 (
1161 ++ data->codecctx, data->read_out_frame, &got_frame, &packet);
1162 +
1163 + /* The DTS decoder of ffmpeg is buggy and always returns
1164 + * the input buffer length, get frame length from header */
1165 +@@ -497,13 +502,33 @@ xmms_avcodec_internal_decode_some (xmms_avcodec_data_t *data)
1166 + data->buffer_length = 0;
1167 + }
1168 +
1169 +- return data->read_out_buffer_size;
1170 ++ return got_frame ? 1 : 0;
1171 + }
1172 +
1173 + static void
1174 + xmms_avcodec_internal_append (xmms_avcodec_data_t *data)
1175 + {
1176 +- g_string_append_len (data->outbuf,
1177 +- (gchar *) data->read_out_buffer,
1178 +- data->read_out_buffer_size);
1179 ++ enum AVSampleFormat fmt = (enum AVSampleFormat) data->read_out_frame->format;
1180 ++ int samples = data->read_out_frame->nb_samples;
1181 ++ int channels = data->codecctx->channels;
1182 ++ int bps = av_get_bytes_per_sample (fmt);
1183 ++
1184 ++ if (av_sample_fmt_is_planar (fmt)) {
1185 ++ /* Convert from planar to packed format */
1186 ++ gint i, j;
1187 ++
1188 ++ for (i = 0; i < samples; i++) {
1189 ++ for (j = 0; j < channels; j++) {
1190 ++ g_string_append_len (
1191 ++ data->outbuf,
1192 ++ (gchar *) (data->read_out_frame->extended_data[j] + i*bps),
1193 ++ bps
1194 ++ );
1195 ++ }
1196 ++ }
1197 ++ } else {
1198 ++ g_string_append_len (data->outbuf,
1199 ++ (gchar *) data->read_out_frame->extended_data[0],
1200 ++ samples * channels * bps);
1201 ++ }
1202 + }
1203
1204 diff --git a/media-sound/xmms2/files/xmms2-0.8-audio4-p6.patch b/media-sound/xmms2/files/xmms2-0.8-audio4-p6.patch
1205 new file mode 100644
1206 index 0000000..b1bc1c5
1207 --- /dev/null
1208 +++ b/media-sound/xmms2/files/xmms2-0.8-audio4-p6.patch
1209 @@ -0,0 +1,106 @@
1210 +commit fc66249e69f53eef709c5210546fdd92e1c89554
1211 +Author: Erik Massop <e.massop@××××××.nl>
1212 +Date: Sun Dec 22 23:04:08 2013 +0100
1213 +
1214 + OTHER: Some compatibility with different avcodec versions
1215 +
1216 +diff --git a/src/plugins/avcodec/avcodec.c b/src/plugins/avcodec/avcodec.c
1217 +index a41a675..023833d 100644
1218 +--- a/src/plugins/avcodec/avcodec.c
1219 ++++ b/src/plugins/avcodec/avcodec.c
1220 +@@ -124,7 +124,7 @@ xmms_avcodec_destroy (xmms_xform_t *xform)
1221 +
1222 + avcodec_close (data->codecctx);
1223 + av_free (data->codecctx);
1224 +- avcodec_free_frame (&data->read_out_frame);
1225 ++ av_frame_free (&data->read_out_frame);
1226 +
1227 + g_string_free (data->outbuf, TRUE);
1228 + g_free (data->buffer);
1229 +@@ -150,7 +150,7 @@ xmms_avcodec_init (xmms_xform_t *xform)
1230 + data->buffer_size = AVCODEC_BUFFER_SIZE;
1231 + data->codecctx = NULL;
1232 +
1233 +- data->read_out_frame = avcodec_alloc_frame ();
1234 ++ data->read_out_frame = av_frame_alloc ();
1235 +
1236 + xmms_xform_private_data_set (xform, data);
1237 +
1238 +@@ -231,7 +231,6 @@ xmms_avcodec_init (xmms_xform_t *xform)
1239 + data->codecctx->extradata_size = data->extradata_size;
1240 + data->codecctx->codec_id = codec->id;
1241 + data->codecctx->codec_type = codec->type;
1242 +- data->codecctx->refcounted_frames = 0;
1243 +
1244 + if (avcodec_open2 (data->codecctx, codec, NULL) < 0) {
1245 + XMMS_DBG ("Opening decoder '%s' failed", codec->name);
1246 +@@ -473,7 +472,8 @@ xmms_avcodec_internal_decode_some (xmms_avcodec_data_t *data)
1247 + packet.data = data->buffer;
1248 + packet.size = data->buffer_length;
1249 +
1250 +- avcodec_get_frame_defaults (data->read_out_frame);
1251 ++ /* clear buffers and reset fields to defaults */
1252 ++ av_frame_unref (data->read_out_frame);
1253 +
1254 + bytes_read = avcodec_decode_audio4 (
1255 + data->codecctx, data->read_out_frame, &got_frame, &packet);
1256 +diff --git a/src/plugins/avcodec/avcodec_compat.h b/src/plugins/avcodec/avcodec_compat.h
1257 +index 73ac2ab..e74b3f8 100644
1258 +--- a/src/plugins/avcodec/avcodec_compat.h
1259 ++++ b/src/plugins/avcodec/avcodec_compat.h
1260 +@@ -83,3 +83,17 @@ typedef struct AVPacket {
1261 + # define avcodec_open2(avctx, codec, options) \
1262 + avcodec_open(avctx, codec)
1263 + #endif
1264 ++
1265 ++/* Map avcodec_free_frame to av_freep if the former doesn't exist.
1266 ++ * (This is in versions earlier than 54.28.0 (libav) or 54.59.100 (ffmpeg)) */
1267 ++#if ! HAVE_AVCODEC_FREE_FRAME
1268 ++# define avcodec_free_frame av_freep
1269 ++#endif
1270 ++
1271 ++/* Map av_frame_alloc, av_frame_unref, av_frame_free into their
1272 ++ * deprecated versions in versions earlier than 55.28.1 */
1273 ++#if LIBAVCODEC_VERSION_INT < 0x371c01
1274 ++# define av_frame_alloc avcodec_alloc_frame
1275 ++# define av_frame_unref avcodec_get_frame_defaults
1276 ++# define av_frame_free avcodec_free_frame
1277 ++#endif
1278 +diff --git a/src/plugins/avcodec/wscript b/src/plugins/avcodec/wscript
1279 +index 03ba7d8..d367816 100644
1280 +--- a/src/plugins/avcodec/wscript
1281 ++++ b/src/plugins/avcodec/wscript
1282 +@@ -1,10 +1,33 @@
1283 + from waftools.plugin import plugin
1284 +
1285 ++## Code fragments for configuration
1286 ++avcodec_free_frame_fragment = """
1287 ++#ifdef HAVE_LIBAVCODEC_AVCODEC_H
1288 ++# include "libavcodec/avcodec.h"
1289 ++#else
1290 ++# include "avcodec.h"
1291 ++#endif
1292 ++int main(void) {
1293 ++ AVFrame *frame;
1294 ++
1295 ++ avcodec_free_frame (&frame);
1296 ++
1297 ++ return 0;
1298 ++}
1299 ++"""
1300 ++
1301 + def plugin_configure(conf):
1302 + conf.check_cfg(package="libavcodec", uselib_store="avcodec",
1303 + args="--cflags --libs")
1304 + conf.check_cc(header_name="avcodec.h", uselib="avcodec", type="cshlib", mandatory=False)
1305 + conf.check_cc(header_name="libavcodec/avcodec.h", uselib="avcodec", type="cshlib", mandatory=False)
1306 +
1307 ++ # non-mandatory function avcodec_free_frame since
1308 ++ # * ffmpeg: commit 46a3595, lavc 54.59.100, release 1.0
1309 ++ # * libav: commit a42aada, lavc 54.28.0, release 9
1310 ++ conf.check_cc(fragment=avcodec_free_frame_fragment, uselib="avcodec",
1311 ++ uselib_store="avcodec_free_frame",
1312 ++ msg="Checking for function avcodec_free_frame", mandatory=False)
1313 ++
1314 + configure, build = plugin('avcodec', configure=plugin_configure,
1315 + libs=["avcodec"])
1316
1317 diff --git a/media-sound/xmms2/files/xmms2-0.8-audio4-p7.patch b/media-sound/xmms2/files/xmms2-0.8-audio4-p7.patch
1318 new file mode 100644
1319 index 0000000..2d4bafd
1320 --- /dev/null
1321 +++ b/media-sound/xmms2/files/xmms2-0.8-audio4-p7.patch
1322 @@ -0,0 +1,147 @@
1323 +commit f460440b3f2a9db1a9deef3faf7dae6e626dd7b5
1324 +Author: Erik Massop <e.massop@××××××.nl>
1325 +Date: Sun Dec 22 23:34:12 2013 +0100
1326 +
1327 + OTHER: Require avcodec_decode_audio4
1328 +
1329 + This was introduced in versions 53.40.0 (ffmpeg) and 53.25.0 (libav) of
1330 + avcodec. Hence we drop compatibility for earlier versions.
1331 +
1332 +diff --git a/src/plugins/avcodec/avcodec.c b/src/plugins/avcodec/avcodec.c
1333 +index 023833d..6d0b667 100644
1334 +--- a/src/plugins/avcodec/avcodec.c
1335 ++++ b/src/plugins/avcodec/avcodec.c
1336 +@@ -154,7 +154,6 @@ xmms_avcodec_init (xmms_xform_t *xform)
1337 +
1338 + xmms_xform_private_data_set (xform, data);
1339 +
1340 +- avcodec_init ();
1341 + avcodec_register_all ();
1342 +
1343 + mimetype = xmms_xform_indata_get_str (xform,
1344 +@@ -225,7 +224,7 @@ xmms_avcodec_init (xmms_xform_t *xform)
1345 + data->codecctx->sample_rate = data->samplerate;
1346 + data->codecctx->channels = data->channels;
1347 + data->codecctx->bit_rate = data->bitrate;
1348 +- CONTEXT_BPS (data->codecctx) = data->samplebits;
1349 ++ data->codecctx->bits_per_coded_sample = data->samplebits;
1350 + data->codecctx->block_align = data->block_align;
1351 + data->codecctx->extradata = data->extradata;
1352 + data->codecctx->extradata_size = data->extradata_size;
1353 +diff --git a/src/plugins/avcodec/avcodec_compat.h b/src/plugins/avcodec/avcodec_compat.h
1354 +index e74b3f8..b50fa4b 100644
1355 +--- a/src/plugins/avcodec/avcodec_compat.h
1356 ++++ b/src/plugins/avcodec/avcodec_compat.h
1357 +@@ -21,69 +21,6 @@
1358 + # include "avcodec.h"
1359 + #endif
1360 +
1361 +-/* Map avcodec_decode_audio2 into the deprecated version
1362 +- * avcodec_decode_audio in versions earlier than 51.28 */
1363 +-#if LIBAVCODEC_VERSION_INT < 0x331c00
1364 +-# define avcodec_decode_audio2 avcodec_decode_audio
1365 +-#endif
1366 +-
1367 +-/* Handle API change that happened in libavcodec 52.00 */
1368 +-#if LIBAVCODEC_VERSION_INT < 0x340000
1369 +-# define CONTEXT_BPS(codecctx) (codecctx)->bits_per_sample
1370 +-#else
1371 +-# define CONTEXT_BPS(codecctx) (codecctx)->bits_per_coded_sample
1372 +-#endif
1373 +-
1374 +-/* Before 52.23 AVPacket was defined in avformat.h which we
1375 +- * do not want to depend on, so we define part of it manually
1376 +- * on versions smaller than 52.23 (this makes me cry) */
1377 +-#if LIBAVCODEC_VERSION_INT < 0x341700
1378 +-typedef struct AVPacket {
1379 +- uint8_t *data;
1380 +- int size;
1381 +-} AVPacket;
1382 +-#endif
1383 +-
1384 +-/* Same thing as above for av_init_packet and version 52.25 */
1385 +-#if LIBAVCODEC_VERSION_INT < 0x341900
1386 +-# define av_init_packet(pkt) do { \
1387 +- (pkt)->data = NULL; \
1388 +- (pkt)->size = 0; \
1389 +- } while(0)
1390 +-#endif
1391 +-
1392 +-/* Map avcodec_decode_audio3 into the deprecated version
1393 +- * avcodec_decode_audio2 in versions earlier than 52.26 */
1394 +-#if LIBAVCODEC_VERSION_INT < 0x341a00
1395 +-# define avcodec_decode_audio3(avctx, samples, frame_size_ptr, avpkt) \
1396 +- avcodec_decode_audio2(avctx, samples, frame_size_ptr, \
1397 +- (avpkt)->data, (avpkt)->size)
1398 +-#endif
1399 +-
1400 +-/* Handle API change that happened in libavcodec 52.64 */
1401 +-#if LIBAVCODEC_VERSION_INT < 0x344000
1402 +-# define AVMEDIA_TYPE_AUDIO CODEC_TYPE_AUDIO
1403 +-#endif
1404 +-
1405 +-/* Calling avcodec_init is not necessary after 53.04 (ffmpeg 0.9) */
1406 +-#if LIBAVCODEC_VERSION_INT >= 0x350400
1407 +-# define avcodec_init()
1408 +-#endif
1409 +-
1410 +-/* Map avcodec_alloc_context3 into the deprecated version
1411 +- * avcodec_alloc_context in versions earlier than 53.04 (ffmpeg 0.9) */
1412 +-#if LIBAVCODEC_VERSION_INT < 0x350400
1413 +-# define avcodec_alloc_context3(codec) \
1414 +- avcodec_alloc_context()
1415 +-#endif
1416 +-
1417 +-/* Map avcodec_open2 into the deprecated version
1418 +- * avcodec_open in versions earlier than 53.04 (ffmpeg 0.9) */
1419 +-#if LIBAVCODEC_VERSION_INT < 0x350400
1420 +-# define avcodec_open2(avctx, codec, options) \
1421 +- avcodec_open(avctx, codec)
1422 +-#endif
1423 +-
1424 + /* Map avcodec_free_frame to av_freep if the former doesn't exist.
1425 + * (This is in versions earlier than 54.28.0 (libav) or 54.59.100 (ffmpeg)) */
1426 + #if ! HAVE_AVCODEC_FREE_FRAME
1427 +diff --git a/src/plugins/avcodec/wscript b/src/plugins/avcodec/wscript
1428 +index d367816..00b182b 100644
1429 +--- a/src/plugins/avcodec/wscript
1430 ++++ b/src/plugins/avcodec/wscript
1431 +@@ -1,6 +1,24 @@
1432 + from waftools.plugin import plugin
1433 +
1434 + ## Code fragments for configuration
1435 ++avcodec_decode_audio4_fragment = """
1436 ++#ifdef HAVE_LIBAVCODEC_AVCODEC_H
1437 ++# include "libavcodec/avcodec.h"
1438 ++#else
1439 ++# include "avcodec.h"
1440 ++#endif
1441 ++int main(void) {
1442 ++ AVCodecContext *ctx;
1443 ++ AVFrame *frame;
1444 ++ int got_frame;
1445 ++ AVPacket *pkt;
1446 ++
1447 ++ avcodec_decode_audio4 (ctx, frame, &got_frame, pkt);
1448 ++
1449 ++ return 0;
1450 ++}
1451 ++"""
1452 ++
1453 + avcodec_free_frame_fragment = """
1454 + #ifdef HAVE_LIBAVCODEC_AVCODEC_H
1455 + # include "libavcodec/avcodec.h"
1456 +@@ -22,6 +40,13 @@ def plugin_configure(conf):
1457 + conf.check_cc(header_name="avcodec.h", uselib="avcodec", type="cshlib", mandatory=False)
1458 + conf.check_cc(header_name="libavcodec/avcodec.h", uselib="avcodec", type="cshlib", mandatory=False)
1459 +
1460 ++ # mandatory function avcodec_decode_audio4 available since
1461 ++ # * ffmpeg: commit e4de716, lavc 53.40.0, release 0.9
1462 ++ # * libav: commit 0eea212, lavc 53.25.0, release 0.8
1463 ++ conf.check_cc(fragment=avcodec_decode_audio4_fragment, uselib="avcodec",
1464 ++ uselib_store="avcodec_decode_audio4",
1465 ++ msg="Checking for function avcodec_decode_audio4", mandatory=True)
1466 ++
1467 + # non-mandatory function avcodec_free_frame since
1468 + # * ffmpeg: commit 46a3595, lavc 54.59.100, release 1.0
1469 + # * libav: commit a42aada, lavc 54.28.0, release 9
1470
1471 diff --git a/media-sound/xmms2/xmms2-0.8-r2.ebuild b/media-sound/xmms2/xmms2-0.8-r2.ebuild
1472 index 4661d2d4..4500c37 100644
1473 --- a/media-sound/xmms2/xmms2-0.8-r2.ebuild
1474 +++ b/media-sound/xmms2/xmms2-0.8-r2.ebuild
1475 @@ -116,6 +116,13 @@ src_prepare() {
1476 epatch "${FILESDIR}/${P}"-ffmpeg2.patch #536232
1477 epatch "${FILESDIR}/${P}"-cpython.patch
1478 epatch "${FILESDIR}/${P}"-modpug.patch #536046
1479 + epatch "${FILESDIR}/${P}"-audio4-p1.patch
1480 + epatch "${FILESDIR}/${P}"-audio4-p2.patch
1481 + epatch "${FILESDIR}/${P}"-audio4-p3.patch
1482 + epatch "${FILESDIR}/${P}"-audio4-p4.patch
1483 + epatch "${FILESDIR}/${P}"-audio4-p5.patch
1484 + epatch "${FILESDIR}/${P}"-audio4-p6.patch
1485 + epatch "${FILESDIR}/${P}"-audio4-p7.patch
1486
1487 if has_version dev-libs/libcdio-paranoia; then
1488 sed -i -e 's:cdio/cdda.h:cdio/paranoia/cdda.h:' src/plugins/cdda/cdda.c || die