diff options
Diffstat (limited to 'src/libmusepack')
-rw-r--r-- | src/libmusepack/Makefile.am | 3 | ||||
-rw-r--r-- | src/libmusepack/xine_musepack_decoder.c | 206 |
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 }; |