You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
gentoo-overlay/media-sound/xmms2/files/xmms2-0.8-audio4-p4.patch

297 lines
9.9 KiB

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);
+}