diff options
Diffstat (limited to 'audio/xmms2/files/patch-src_plugins_avcodec_avcodec.c')
-rw-r--r-- | audio/xmms2/files/patch-src_plugins_avcodec_avcodec.c | 527 |
1 files changed, 0 insertions, 527 deletions
diff --git a/audio/xmms2/files/patch-src_plugins_avcodec_avcodec.c b/audio/xmms2/files/patch-src_plugins_avcodec_avcodec.c deleted file mode 100644 index da9bd420ba57..000000000000 --- a/audio/xmms2/files/patch-src_plugins_avcodec_avcodec.c +++ /dev/null @@ -1,527 +0,0 @@ ---- src/plugins/avcodec/avcodec.c.orig 2011-10-20 19:26:08 UTC -+++ src/plugins/avcodec/avcodec.c -@@ -1,7 +1,7 @@ - /** @file avcodec.c - * Decoder plugin for ffmpeg avcodec formats - * -- * Copyright (C) 2006-2011 XMMS2 Team -+ * Copyright (C) 2006-2014 XMMS2 Team - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public -@@ -14,15 +14,16 @@ - * Lesser General Public License for more details. - */ - --#include "xmms_configuration.h" --#include "xmms/xmms_xformplugin.h" --#include "xmms/xmms_sample.h" --#include "xmms/xmms_log.h" -+#include <xmms_configuration.h> -+#include <xmms/xmms_xformplugin.h> -+#include <xmms/xmms_sample.h> -+#include <xmms/xmms_log.h> - - #include <stdio.h> - #include <stdlib.h> - #include <string.h> - #include <glib.h> -+#include <libavutil/mem.h> - - #include "avcodec_compat.h" - -@@ -36,6 +37,8 @@ typedef struct { - guint buffer_size; - gboolean no_demuxer; - -+ AVFrame *read_out_frame; -+ - guint channels; - guint samplerate; - xmms_sample_format_t sampleformat; -@@ -53,10 +56,14 @@ typedef struct { - static gboolean xmms_avcodec_plugin_setup (xmms_xform_plugin_t *xform_plugin); - static gboolean xmms_avcodec_init (xmms_xform_t *xform); - static void xmms_avcodec_destroy (xmms_xform_t *xform); -+static gint xmms_avcodec_internal_read_some (xmms_xform_t *xform, xmms_avcodec_data_t *data, xmms_error_t *error); -+static gint xmms_avcodec_internal_decode_some (xmms_avcodec_data_t *data); -+static void xmms_avcodec_internal_append (xmms_avcodec_data_t *data); - static gint xmms_avcodec_read (xmms_xform_t *xform, xmms_sample_t *buf, gint len, - xmms_error_t *error); - static gint64 xmms_avcodec_seek (xmms_xform_t *xform, gint64 samples, - xmms_xform_seek_mode_t whence, xmms_error_t *err); -+static xmms_sample_format_t xmms_avcodec_translate_sample_format (enum AVSampleFormat av_sample_format); - - /* - * Plugin header -@@ -85,13 +92,23 @@ xmms_avcodec_plugin_setup (xmms_xform_pl - xmms_magic_add ("A/52 (AC-3) header", "audio/x-ffmpeg-ac3", - "0 beshort 0x0b77", NULL); - xmms_magic_add ("DTS header", "audio/x-ffmpeg-dca", -- "0 belong 0x7ffe8001", NULL); -+ "0 belong 0x7ffe8001", NULL); - - xmms_xform_plugin_indata_add (xform_plugin, - XMMS_STREAM_TYPE_MIMETYPE, - "audio/x-ffmpeg-*", - NULL); - -+ XMMS_DBG ("avcodec version at build time is %d.%d.%d", -+ (LIBAVCODEC_VERSION_INT >> 16), -+ (LIBAVCODEC_VERSION_INT >> 8) & 0xff, -+ LIBAVCODEC_VERSION_INT & 0xff); -+ XMMS_DBG ("avcodec version at run time is %d.%d.%d", -+ (avcodec_version() >> 16), -+ (avcodec_version() >> 8) & 0xff, -+ avcodec_version() & 0xff); -+ XMMS_DBG ("avcodec configuration is %s", avcodec_configuration()); -+ - return TRUE; - } - -@@ -107,6 +124,7 @@ xmms_avcodec_destroy (xmms_xform_t *xfor - - avcodec_close (data->codecctx); - av_free (data->codecctx); -+ av_frame_free (&data->read_out_frame); - - g_string_free (data->outbuf, TRUE); - g_free (data->buffer); -@@ -132,9 +150,10 @@ xmms_avcodec_init (xmms_xform_t *xform) - data->buffer_size = AVCODEC_BUFFER_SIZE; - data->codecctx = NULL; - -+ data->read_out_frame = av_frame_alloc (); -+ - xmms_xform_private_data_set (xform, data); - -- avcodec_init (); - avcodec_register_all (); - - mimetype = xmms_xform_indata_get_str (xform, -@@ -161,12 +180,12 @@ 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); -@@ -188,7 +207,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; -@@ -196,22 +216,22 @@ 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; - } - } - -- data->codecctx = avcodec_alloc_context (); -+ data->codecctx = avcodec_alloc_context3 (codec); - data->codecctx->sample_rate = data->samplerate; - data->codecctx->channels = data->channels; - data->codecctx->bit_rate = data->bitrate; -- CONTEXT_BPS (data->codecctx) = data->samplebits; -+ data->codecctx->bits_per_coded_sample = data->samplebits; - data->codecctx->block_align = data->block_align; - data->codecctx->extradata = data->extradata; - data->codecctx->extradata_size = data->extradata_size; - data->codecctx->codec_id = codec->id; - data->codecctx->codec_type = codec->type; - -- if (avcodec_open (data->codecctx, codec) < 0) { -+ if (avcodec_open2 (data->codecctx, codec, NULL) < 0) { - XMMS_DBG ("Opening decoder '%s' failed", codec->name); - goto err; - } else { -@@ -220,7 +240,7 @@ 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..."); -@@ -231,19 +251,27 @@ 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, - data->samplerate, - XMMS_STREAM_TYPE_END); - -- XMMS_DBG ("Decoder '%s' initialized successfully!", codec->name); -+ XMMS_DBG ("Decoder %s at rate %d with %d channels of format %s initialized", -+ codec->name, data->codecctx->sample_rate, -+ data->codecctx->channels, -+ av_get_sample_fmt_name (data->codecctx->sample_fmt)); - - return TRUE; - -@@ -251,6 +279,9 @@ err: - if (data->codecctx) { - av_free (data->codecctx); - } -+ if (data->read_out_frame) { -+ avcodec_free_frame (&data->read_out_frame); -+ } - g_string_free (data->outbuf, TRUE); - g_free (data->extradata); - g_free (data); -@@ -263,102 +294,24 @@ xmms_avcodec_read (xmms_xform_t *xform, - xmms_error_t *error) - { - xmms_avcodec_data_t *data; -- char outbuf[AVCODEC_MAX_AUDIO_FRAME_SIZE]; -- gint outbufsize, bytes_read = 0; - guint size; - - data = xmms_xform_private_data_get (xform); - g_return_val_if_fail (data, -1); - -- size = MIN (data->outbuf->len, len); -- while (size == 0) { -- AVPacket packet; -- av_init_packet (&packet); -+ while (0 == (size = MIN (data->outbuf->len, len))) { -+ gint res; - - if (data->no_demuxer || data->buffer_length == 0) { -- gint read_total; -- -- bytes_read = xmms_xform_read (xform, -- (gchar *) (data->buffer + data->buffer_length), -- data->buffer_size - data->buffer_length, -- error); -- -- if (bytes_read < 0) { -- XMMS_DBG ("Error while reading data"); -- return bytes_read; -- } else if (bytes_read == 0) { -- XMMS_DBG ("EOF"); -- return 0; -- } -- -- 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; -- -- outbufsize = sizeof (outbuf); -- bytes_read = avcodec_decode_audio3 (data->codecctx, (short *) outbuf, -- &outbufsize, &packet); -- -- /* The DTS decoder of ffmpeg is buggy and always returns -- * the input buffer length, get frame length from header */ -- if (!strcmp (data->codec_id, "dca") && bytes_read > 0) { -- bytes_read = ((int)data->buffer[5] << 12) | -- ((int)data->buffer[6] << 4) | -- ((int)data->buffer[7] >> 4); -- bytes_read = (bytes_read & 0x3fff) + 1; -- } -- -- if (bytes_read < 0 || bytes_read > data->buffer_length) { -- XMMS_DBG ("Error decoding data!"); -- return -1; -- } else if (bytes_read != data->buffer_length) { -- g_memmove (data->buffer, -- data->buffer + bytes_read, -- data->buffer_length - bytes_read); -- } -- -- data->buffer_length -= bytes_read; -+ gint bytes_read; - -- if (outbufsize > 0) { -- g_string_append_len (data->outbuf, outbuf, outbufsize); -+ bytes_read = xmms_avcodec_internal_read_some (xform, data, error); -+ if (bytes_read <= 0) { return bytes_read; } - } - -- size = MIN (data->outbuf->len, len); -+ res = xmms_avcodec_internal_decode_some (data); -+ if (res < 0) { return res; } -+ if (res > 0) { xmms_avcodec_internal_append (data); } - } - - memcpy (buf, data->outbuf->str, size); -@@ -371,8 +324,6 @@ 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; - gint64 ret = -1; - - g_return_val_if_fail (xform, -1); -@@ -390,23 +341,11 @@ xmms_avcodec_seek (xmms_xform_t *xform, - - /* The buggy ape decoder doesn't flush buffers, so we need to finish decoding - * the frame before seeking to avoid segfaults... this hack sucks */ -+ /* FIXME: Is ^^^ still true? */ - while (data->buffer_length > 0) { -- AVPacket packet; -- av_init_packet (&packet); -- packet.data = data->buffer; -- packet.size = data->buffer_length; -- -- outbufsize = sizeof (outbuf); -- bytes_read = avcodec_decode_audio3 (data->codecctx, (short *) outbuf, -- &outbufsize, &packet); -- -- if (bytes_read < 0 || bytes_read > data->buffer_length) { -- XMMS_DBG ("Error decoding data!"); -+ if (xmms_avcodec_internal_decode_some (data) < 0) { - return -1; - } -- -- data->buffer_length -= bytes_read; -- g_memmove (data->buffer, data->buffer + bytes_read, data->buffer_length); - } - - ret = xmms_xform_seek (xform, samples, whence, err); -@@ -420,3 +359,178 @@ xmms_avcodec_seek (xmms_xform_t *xform, - - return ret; - } -+ -+static xmms_sample_format_t -+xmms_avcodec_translate_sample_format (enum AVSampleFormat av_sample_format) -+{ -+ switch (av_sample_format) { -+ case AV_SAMPLE_FMT_U8: -+ case AV_SAMPLE_FMT_U8P: -+ return XMMS_SAMPLE_FORMAT_U8; -+ case AV_SAMPLE_FMT_S16: -+ case AV_SAMPLE_FMT_S16P: -+ return XMMS_SAMPLE_FORMAT_S16; -+ case AV_SAMPLE_FMT_S32: -+ case AV_SAMPLE_FMT_S32P: -+ return XMMS_SAMPLE_FORMAT_S32; -+ case AV_SAMPLE_FMT_FLT: -+ case AV_SAMPLE_FMT_FLTP: -+ return XMMS_SAMPLE_FORMAT_FLOAT; -+ case AV_SAMPLE_FMT_DBL: -+ case AV_SAMPLE_FMT_DBLP: -+ return XMMS_SAMPLE_FORMAT_DOUBLE; -+ default: -+ XMMS_DBG ("AVSampleFormat (%i: %s) not supported.", av_sample_format, -+ av_get_sample_fmt_name (av_sample_format)); -+ return XMMS_SAMPLE_FORMAT_UNKNOWN; -+ } -+} -+ -+/* -+Read some data from our source of data to data->buffer, updating buffer_length -+and buffer_size as needed. -+ -+Returns: on error: negative -+ on EOF: zero -+ otherwise: number of bytes read. -+*/ -+static gint -+xmms_avcodec_internal_read_some (xmms_xform_t *xform, -+ xmms_avcodec_data_t *data, -+ xmms_error_t *error) -+{ -+ gint bytes_read, read_total; -+ -+ bytes_read = xmms_xform_read (xform, -+ (gchar *) (data->buffer + data->buffer_length), -+ data->buffer_size - data->buffer_length, -+ error); -+ -+ if (bytes_read < 0) { -+ XMMS_DBG ("Error while reading data"); -+ return bytes_read; -+ } else if (bytes_read == 0) { -+ XMMS_DBG ("EOF"); -+ return 0; -+ } -+ -+ read_total = bytes_read; -+ -+ /* If we have a demuxer plugin, make sure we read the whole packet */ -+ while (read_total == data->buffer_size && !data->no_demuxer) { -+ /* multiply the buffer size and try to read again */ -+ data->buffer = g_realloc (data->buffer, data->buffer_size * 2); -+ bytes_read = xmms_xform_read (xform, -+ (gchar *) data->buffer + -+ data->buffer_size, -+ data->buffer_size, -+ error); -+ data->buffer_size *= 2; -+ -+ if (bytes_read < 0) { -+ XMMS_DBG ("Error while reading data"); -+ return bytes_read; -+ } -+ -+ read_total += bytes_read; -+ -+ if (read_total < data->buffer_size) { -+ /* finally double the buffer size for performance reasons, the -+ * hotspot handling likes to fit two frames in the buffer */ -+ data->buffer = g_realloc (data->buffer, data->buffer_size * 2); -+ data->buffer_size *= 2; -+ XMMS_DBG ("Reallocated avcodec internal buffer to be %d bytes", -+ data->buffer_size); -+ -+ break; -+ } -+ } -+ -+ /* Update the buffer length */ -+ data->buffer_length += read_total; -+ -+ return read_total; -+} -+ -+/* -+Decode some data from data->buffer[0..data->buffer_length-1] to -+data->read_out_frame -+ -+Returns: on error: negative -+ on no new data produced: zero -+ otherwise: positive -+ -+FIXME: data->buffer should be at least data->buffer_length + -+FF_INPUT_BUFFER_PADDING_SIZE long. -+*/ -+static gint -+xmms_avcodec_internal_decode_some (xmms_avcodec_data_t *data) -+{ -+ int got_frame = 0; -+ gint bytes_read = 0; -+ AVPacket packet; -+ -+ av_init_packet (&packet); -+ packet.data = data->buffer; -+ packet.size = data->buffer_length; -+ -+ /* clear buffers and reset fields to defaults */ -+ av_frame_unref (data->read_out_frame); -+ -+ bytes_read = avcodec_decode_audio4 ( -+ data->codecctx, data->read_out_frame, &got_frame, &packet); -+ -+ /* The DTS decoder of ffmpeg is buggy and always returns -+ * the input buffer length, get frame length from header */ -+ /* FIXME: Is ^^^^ still true? */ -+ if (!strcmp (data->codec_id, "dca") && bytes_read > 0) { -+ bytes_read = ((int)data->buffer[5] << 12) | -+ ((int)data->buffer[6] << 4) | -+ ((int)data->buffer[7] >> 4); -+ bytes_read = (bytes_read & 0x3fff) + 1; -+ } -+ -+ if (bytes_read < 0 || bytes_read > data->buffer_length) { -+ XMMS_DBG ("Error decoding data!"); -+ return -1; -+ } -+ -+ if (bytes_read < data->buffer_length) { -+ data->buffer_length -= bytes_read; -+ g_memmove (data->buffer, -+ data->buffer + bytes_read, -+ data->buffer_length); -+ } else { -+ data->buffer_length = 0; -+ } -+ -+ return got_frame ? 1 : 0; -+} -+ -+static void -+xmms_avcodec_internal_append (xmms_avcodec_data_t *data) -+{ -+ enum AVSampleFormat fmt = (enum AVSampleFormat) data->read_out_frame->format; -+ int samples = data->read_out_frame->nb_samples; -+ int channels = data->codecctx->channels; -+ int bps = av_get_bytes_per_sample (fmt); -+ -+ if (av_sample_fmt_is_planar (fmt)) { -+ /* Convert from planar to packed format */ -+ gint i, j; -+ -+ for (i = 0; i < samples; i++) { -+ for (j = 0; j < channels; j++) { -+ g_string_append_len ( -+ data->outbuf, -+ (gchar *) (data->read_out_frame->extended_data[j] + i*bps), -+ bps -+ ); -+ } -+ } -+ } else { -+ g_string_append_len (data->outbuf, -+ (gchar *) data->read_out_frame->extended_data[0], -+ samples * channels * bps); -+ } -+} |