summaryrefslogtreecommitdiff
path: root/src/libmusepack
diff options
context:
space:
mode:
Diffstat (limited to 'src/libmusepack')
-rw-r--r--src/libmusepack/Makefile.am3
-rw-r--r--src/libmusepack/xine_musepack_decoder.c206
2 files changed, 144 insertions, 65 deletions
diff --git a/src/libmusepack/Makefile.am b/src/libmusepack/Makefile.am
index 01875bdad..252e3d6ad 100644
--- a/src/libmusepack/Makefile.am
+++ b/src/libmusepack/Makefile.am
@@ -1,3 +1,4 @@
+include $(top_builddir)/misc/Makefile.plugins
include $(top_srcdir)/misc/Makefile.common
SUBDIRS = musepack
@@ -9,7 +10,7 @@ xineplug_LTLIBRARIES = xineplug_decode_mpc.la
endif
if EXTERNAL_MPCDEC
-internal_sources =
+internal_sources =
else
internal_sources = huffsv46.c huffsv7.c idtag.c mpc_decoder.c \
mpc_reader.c requant.c streaminfo.c synth_filter.c
diff --git a/src/libmusepack/xine_musepack_decoder.c b/src/libmusepack/xine_musepack_decoder.c
index 7a2d30a06..41b90b080 100644
--- a/src/libmusepack/xine_musepack_decoder.c
+++ b/src/libmusepack/xine_musepack_decoder.c
@@ -24,6 +24,10 @@
* Seeking??
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -43,6 +47,8 @@
#ifdef HAVE_MPCDEC_MPCDEC_H
# include <mpcdec/mpcdec.h>
+#elif defined(HAVE_MPC_MPCDEC_H)
+# include <mpc/mpcdec.h>
#else
# include "musepack/musepack.h"
#endif
@@ -74,11 +80,15 @@ typedef struct mpc_decoder_s {
mpc_reader reader;
mpc_streaminfo streaminfo;
+#ifndef HAVE_MPC_MPCDEC_H
mpc_decoder decoder;
-
+#else
+ mpc_demux *decoder;
+#endif
+
int decoder_ok;
unsigned int current_frame;
-
+
int32_t file_size;
} mpc_decoder_t;
@@ -87,61 +97,91 @@ typedef struct mpc_decoder_s {
/**************************************************************************
* musepack specific functions
*************************************************************************/
-
+
/* Reads size bytes of data into buffer at ptr. */
+#ifndef HAVE_MPC_MPCDEC_H
static int32_t mpc_reader_read(void *data, void *ptr, int size) {
mpc_decoder_t *this = (mpc_decoder_t *) data;
-
+#else
+static int32_t mpc_reader_read(mpc_reader *data, void *ptr, int size) {
+ mpc_decoder_t *this = (mpc_decoder_t *) data->data;
+#endif
+
lprintf("mpc_reader_read: size=%d\n", size);
-
+
/* Don't try to read more data than we have */
if (size > (this->size - this->read))
size = this->size - this->read;
/* Copy the data */
xine_fast_memcpy(ptr, &this->buf[this->read], size);
-
+
/* Update our position in the data buffer */
this->read += size;
-
+
return size;
}
-
+
/* Seeks to byte position offset. */
+#ifndef HAVE_MPC_MPCDEC_H
static mpc_bool_t mpc_reader_seek(void *data, int32_t offset) {
mpc_decoder_t *this = (mpc_decoder_t *) data;
-
+#else
+static mpc_bool_t mpc_reader_seek(mpc_reader *data, int32_t offset) {
+ mpc_decoder_t *this = (mpc_decoder_t *) data->data;
+#endif
+
lprintf("mpc_reader_seek: offset=%d\n", offset);
-
+
/* seek is only called when reading the header so we can assume
* that the buffer starts at the start of the file */
this->read = offset;
-
+
+#ifndef HAVE_MPC_MPCDEC_H
return TRUE;
+#else
+ return MPC_TRUE;
+#endif
}
/* Returns the current byte offset in the stream. */
+#ifndef HAVE_MPC_MPCDEC_H
static int32_t mpc_reader_tell(void *data) {
+#else
+static int32_t mpc_reader_tell(mpc_reader *data) {
+#endif
lprintf("mpc_reader_tell\n");
-
+
/* Tell isn't used so just return 0 */
return 0;
}
/* Returns the total length of the source stream, in bytes. */
+#ifndef HAVE_MPC_MPCDEC_H
static int32_t mpc_reader_get_size(void *data) {
mpc_decoder_t *this = (mpc_decoder_t *) data;
-
+#else
+static int32_t mpc_reader_get_size(mpc_reader *data) {
+ mpc_decoder_t *this = (mpc_decoder_t *) data->data;
+#endif
+
lprintf("mpc_reader_get_size\n");
-
+
return this->file_size;
}
/* True if the stream is a seekable stream. */
+#ifndef HAVE_MPC_MPCDEC_H
static mpc_bool_t mpc_reader_canseek(void *data) {
lprintf("mpc_reader_canseek\n");
-
+
return TRUE;
+#else
+static mpc_bool_t mpc_reader_canseek(mpc_reader *data) {
+
+ lprintf("mpc_reader_canseek\n");
+ return MPC_TRUE;
+#endif
}
/* Convert 32bit float samples into 16bit int samples */
@@ -161,30 +201,39 @@ static inline void float_to_int(float *_f, int16_t *s16, int samples) {
static int mpc_decode_frame (mpc_decoder_t *this) {
float buffer[MPC_DECODER_BUFFER_LENGTH];
uint32_t frames;
-
+#ifdef HAVE_MPC_MPCDEC_H
+ mpc_frame_info frame;
+#endif
+
lprintf("mpd_decode_frame\n");
-
+
+#ifndef HAVE_MPC_MPCDEC_H
frames = mpc_decoder_decode(&this->decoder, buffer, 0, 0);
-
+#else
+ frame.buffer = buffer;
+ mpc_demux_decode(this->decoder, &frame);
+ frames = frame.samples;
+#endif
+
if (frames > 0) {
- audio_buffer_t *audio_buffer;
+ audio_buffer_t *audio_buffer;
int16_t *int_samples;
-
+
lprintf("got %d samples\n", frames);
-
+
/* Get audio buffer */
audio_buffer = this->stream->audio_out->get_buffer (this->stream->audio_out);
audio_buffer->vpts = 0;
audio_buffer->num_frames = frames;
-
+
/* Convert samples */
int_samples = (int16_t *) audio_buffer->mem;
float_to_int(buffer, int_samples, frames*this->channels);
-
+
/* Output converted samples */
this->stream->audio_out->put_buffer (this->stream->audio_out, audio_buffer, this->stream);
}
-
+
return frames;
}
@@ -197,28 +246,28 @@ static void mpc_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
int err;
lprintf("mpc_decode_data\n");
-
+
if (!_x_stream_info_get(this->stream, XINE_STREAM_INFO_AUDIO_HANDLED))
return;
-
+
/* We don't handle special buffers */
if (buf->decoder_flags & BUF_FLAG_SPECIAL)
return;
-
+
/* Read header */
if (buf->decoder_flags & BUF_FLAG_HEADER) {
-
+
lprintf("header\n");
-
+
/* File size is in decoder_info[0] */
this->file_size = buf->decoder_info[0];
-
+
/* Initialise the data accumulation buffer */
- this->buf = xine_xmalloc(INIT_BUFSIZE);
+ this->buf = calloc(1, INIT_BUFSIZE);
this->buf_max = INIT_BUFSIZE;
this->read = 0;
this->size = 0;
-
+
/* Initialise the reader */
this->reader.read = mpc_reader_read;
this->reader.seek = mpc_reader_seek;
@@ -226,49 +275,62 @@ static void mpc_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
this->reader.get_size = mpc_reader_get_size;
this->reader.canseek = mpc_reader_canseek;
this->reader.data = this;
-
+
/* Copy header to buffer */
xine_fast_memcpy(this->buf, buf->content, buf->size);
this->size = buf->size;
-
+
+#ifdef HAVE_MPC_MPCDEC_H
+ this->decoder = mpc_demux_init(&this->reader);
+ if (!this->decoder) {
+ xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
+ _("libmusepack: mpc_demux_init failed.\n"));
+ _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_HANDLED, 0);
+ return;
+ }
+ mpc_demux_get_info(this->decoder, &this->streaminfo);
+#else
/* Initialise and read stream info */
mpc_streaminfo_init(&this->streaminfo);
-
+
if ((err = mpc_streaminfo_read(&this->streaminfo, &this->reader))) {
xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
_("libmusepack: mpc_streaminfo_read failed: %d\n"), err);
-
+
_x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_HANDLED, 0);
return;
}
-
+#endif
+
this->sample_rate = this->streaminfo.sample_freq;
this->channels = this->streaminfo.channels;
this->bits_per_sample = 16;
-
+
/* After the header the demuxer starts sending data from an offset
* of 28 bytes */
this->size = 28;
-
+
/* We need to keep track of the current frame so we now when we've
* reached the end of the stream */
this->current_frame = 0;
-
+
/* Setup the decoder */
+#ifndef HAVE_MPC_MPCDEC_H
mpc_decoder_setup(&this->decoder, &this->reader);
+#endif
this->decoder_ok = 0;
/* Take this opportunity to initialize stream/meta information */
- _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC,
+ _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC,
"Musepack (libmusepack)");
- _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITRATE,
+ _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITRATE,
(int) this->streaminfo.average_bitrate);
return;
}
lprintf("data: %u size=%u read=%u\n", buf->size, this->size, this->read);
-
+
/* if the audio output is not open yet, open the audio output */
if (!this->output_open) {
this->output_open = (this->stream->audio_out->open) (
@@ -282,7 +344,7 @@ static void mpc_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
/* if the audio still isn't open, do not go any further with the decode */
if (!this->output_open)
return;
-
+
/* If we run out of space in our internal buffer we discard what's
* already been read */
if (((this->size + buf->size) > this->buf_max) && this->read) {
@@ -291,7 +353,7 @@ static void mpc_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
memmove(this->buf, &this->buf[this->read], this->size);
this->read = 0;
}
-
+
/* If there still isn't space we have to increase the size of the
* internal buffer */
if ((this->size + buf->size) > this->buf_max) {
@@ -300,66 +362,78 @@ static void mpc_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
this->buf_max += 2*buf->size;
this->buf = realloc(this->buf, this->buf_max);
}
-
+
/* Copy data */
xine_fast_memcpy(&this->buf[this->size], buf->content, buf->size);
this->size += buf->size;
-
+
/* Time to decode */
if (buf->decoder_flags & BUF_FLAG_FRAME_END) {
/* Increment frame count */
+#ifndef HAVE_MPC_MPCDEC_H
if (this->current_frame++ == this->streaminfo.frames) {
+#else
+ if (this->current_frame++ == this->streaminfo.samples) {
+#endif
xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
_("libmusepack: data after last frame ignored\n"));
return;
}
-
+
if (!this->decoder_ok) {
/* We require MPC_DECODER_MEMSIZE bytes to initialise the decoder */
if ((this->size - this->read) >= MPC_DECODER_MEMSIZE) {
lprintf("initialise");
-
+
+#ifndef HAVE_MPC_MPCDEC_H
if (!mpc_decoder_initialize(&this->decoder, &this->streaminfo)) {
+#else
+ if (!this->decoder) {
+#endif
xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
- _("libmusepack: mpc_decoder_initialise failed\n"));
-
+ _("libmusepack: mpc_decoder_initialise failed\n"));
+
_x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_HANDLED, 0);
return;
}
-
+
this->decoder_ok = 1;
} else {
/* Not enough data yet */
return;
}
}
-
+
/* mpc_decoder_decode may cause a read of MPC_DECODER_MEMSIZE/2 bytes so
* make sure we have enough data available */
if ((this->size - this->read) >= MPC_DECODER_MEMSIZE2) {
lprintf("decoding\n");
-
+
if ((err = mpc_decode_frame(this)) < 0) {
xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
- _("libmusepack: mpc_decoder_decode failed: %d\n"), err);
-
+ _("libmusepack: mpc_decoder_decode failed: %d\n"), err);
+
_x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_HANDLED, 0);
return;
}
}
-
+
/* If we are at the end of the stream we decode the remaining frames as we
* know we'll have enough data */
+#ifndef HAVE_MPC_MPCDEC_H
if (this->current_frame == this->streaminfo.frames) {
+#else
+ if (this->current_frame == this->streaminfo.samples) {
+#endif
lprintf("flushing buffers\n");
-
+
do {
if ((err = mpc_decode_frame(this)) < 0) {
xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
_("libmusepack: mpc_decoder_decode failed: %d\n"), err);
}
} while (err > 0);
-
+
lprintf("buffers flushed\n");
}
}
@@ -388,7 +462,11 @@ static void mpc_dispose (audio_decoder_t *this_gen) {
/* free anything that was allocated during operation */
if (this->buf)
free(this->buf);
-
+#ifdef HAVE_MPC_MPCDEC_H
+ if (this->decoder)
+ mpc_demux_exit(this->decoder);
+#endif
+
free(this);
}
@@ -396,7 +474,7 @@ static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen, xine_stre
mpc_decoder_t *this ;
- this = (mpc_decoder_t *) xine_xmalloc (sizeof (mpc_decoder_t));
+ this = (mpc_decoder_t *) calloc(1, sizeof(mpc_decoder_t));
/* connect the member functions */
this->audio_decoder.decode_data = mpc_decode_data;
@@ -409,7 +487,7 @@ static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen, xine_stre
/* audio output is not open at the start */
this->output_open = 0;
-
+
/* no buffer yet */
this->buf = NULL;
@@ -441,7 +519,7 @@ static void *init_plugin (xine_t *xine, void *data) {
mpc_class_t *this ;
- this = (mpc_class_t *) xine_xmalloc (sizeof (mpc_class_t));
+ this = (mpc_class_t *) calloc(1, sizeof(mpc_class_t));
this->decoder_class.open_plugin = open_plugin;
this->decoder_class.get_identifier = get_identifier;
@@ -451,7 +529,7 @@ static void *init_plugin (xine_t *xine, void *data) {
return this;
}
-static uint32_t audio_types[] = {
+static uint32_t audio_types[] = {
BUF_AUDIO_MPC,
0
};