diff options
-rw-r--r-- | ChangeLog | 19 | ||||
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | ext/musepack/Makefile.am | 6 | ||||
-rw-r--r-- | ext/musepack/gstmusepackdec.c | 159 | ||||
-rw-r--r-- | ext/musepack/gstmusepackdec.cpp | 514 | ||||
-rw-r--r-- | ext/musepack/gstmusepackdec.h | 7 | ||||
-rw-r--r-- | ext/musepack/gstmusepackreader.c | 124 | ||||
-rw-r--r-- | ext/musepack/gstmusepackreader.cpp | 151 | ||||
-rw-r--r-- | ext/musepack/gstmusepackreader.h | 19 |
9 files changed, 167 insertions, 834 deletions
@@ -1,3 +1,22 @@ +2005-01-29 Ronald S. Bultje <rbultje@ronald.bitfreak.net> + + * configure.ac: + * ext/musepack/Makefile.am: + * ext/musepack/gstmusepackdec.c: (gst_musepackdec_class_init), + (gst_musepackdec_init), (gst_musepackdec_dispose), + (gst_musepackdec_src_query), (gst_musepackdec_src_convert), + (gst_musepack_stream_init), (gst_musepackdec_loop), + (gst_musepackdec_change_state): + * ext/musepack/gstmusepackdec.cpp: + * ext/musepack/gstmusepackdec.h: + * ext/musepack/gstmusepackreader.c: (gst_musepack_reader_peek), + (gst_musepack_reader_read), (gst_musepack_reader_seek), + (gst_musepack_reader_tell), (gst_musepack_reader_get_size), + (gst_musepack_reader_canseek), (gst_musepack_init_reader): + * ext/musepack/gstmusepackreader.cpp: + * ext/musepack/gstmusepackreader.h: + Update to 1.1 API (#165446). + 2005-01-28 Ronald S. Bultje <rbultje@ronald.bitfreak.net> * ext/Makefile.am: diff --git a/configure.ac b/configure.ac index c6e16470..4938d32a 100644 --- a/configure.ac +++ b/configure.ac @@ -1469,7 +1469,7 @@ dnl *** musepack *** translit(dnm, m, l) AM_CONDITIONAL(USE_MUSEPACK, true) GST_CHECK_FEATURE(MUSEPACK, [musepackdec], musepack, [ AC_LANG_CPLUSPLUS - AC_CHECK_HEADER([musepack/mpc_dec.h], [ + AC_CHECK_HEADER([musepack/musepack.h], [ HAVE_MUSEPACK="yes" MUSEPACK_LIBS="-lmusepack" AC_SUBST(MUSEPACK_LIBS) diff --git a/ext/musepack/Makefile.am b/ext/musepack/Makefile.am index 3c3b1bfa..21cd31e8 100644 --- a/ext/musepack/Makefile.am +++ b/ext/musepack/Makefile.am @@ -1,9 +1,9 @@ plugin_LTLIBRARIES = libgstmusepack.la libgstmusepack_la_SOURCES = \ - gstmusepackdec.cpp \ - gstmusepackreader.cpp -libgstmusepack_la_CXXFLAGS = $(MUSEPACK_CFLAGS) $(GST_CFLAGS) + gstmusepackdec.c \ + gstmusepackreader.c +libgstmusepack_la_CFLAGS = $(MUSEPACK_CFLAGS) $(GST_CFLAGS) libgstmusepack_la_LIBADD = $(MUSEPACK_LIBS) libgstmusepack_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) diff --git a/ext/musepack/gstmusepackdec.c b/ext/musepack/gstmusepackdec.c index 7917a346..656360a6 100644 --- a/ext/musepack/gstmusepackdec.c +++ b/ext/musepack/gstmusepackdec.c @@ -48,13 +48,13 @@ static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_ALWAYS, GST_STATIC_CAPS (BASE_CAPS ", " "endianness = (int) BYTE_ORDER, " - "rate = (int) [ 8000, 96000 ], " - "channels = (int) [ 1, 2 ]") + "rate = (int) [ 8000, 96000 ], " "channels = (int) [ 1, 2 ]") ); static void gst_musepackdec_base_init (GstMusepackDecClass * klass); static void gst_musepackdec_class_init (GstMusepackDecClass * klass); static void gst_musepackdec_init (GstMusepackDec * musepackdec); +static void gst_musepackdec_dispose (GObject * obj); static gboolean gst_musepackdec_src_event (GstPad * pad, GstEvent * event); static const GstFormat *gst_musepackdec_get_formats (GstPad * pad); @@ -68,7 +68,7 @@ static gboolean gst_musepackdec_src_convert (GstPad * pad, static void gst_musepackdec_loop (GstElement * element); static GstElementStateReturn - gst_musepackdec_change_state (GstElement * element); +gst_musepackdec_change_state (GstElement * element); static GstElementClass *parent_class = NULL; @@ -102,12 +102,11 @@ gst_musepackdec_get_type (void) static void gst_musepackdec_base_init (GstMusepackDecClass * klass) { - static GstElementDetails gst_musepackdec_details = GST_ELEMENT_DETAILS ( - "Musepack decoder", - "Codec/Decoder/Audio", - "Musepack decoder", - "Ronald Bultje <rbultje@ronald.bitfreak.net>" - ); + static GstElementDetails gst_musepackdec_details = + GST_ELEMENT_DETAILS ("Musepack decoder", + "Codec/Decoder/Audio", + "Musepack decoder", + "Ronald Bultje <rbultje@ronald.bitfreak.net>"); GstElementClass *element_class = GST_ELEMENT_CLASS (klass); gst_element_class_add_pad_template (element_class, @@ -121,11 +120,10 @@ gst_musepackdec_base_init (GstMusepackDecClass * klass) static void gst_musepackdec_class_init (GstMusepackDecClass * klass) { - GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass); - parent_class = GST_ELEMENT_CLASS (g_type_class_ref (GST_TYPE_ELEMENT)); - gstelement_class->change_state = gst_musepackdec_change_state; + GST_ELEMENT_CLASS (klass)->change_state = gst_musepackdec_change_state; + G_OBJECT_CLASS (klass)->dispose = gst_musepackdec_dispose; } static void @@ -133,7 +131,9 @@ gst_musepackdec_init (GstMusepackDec * musepackdec) { GST_FLAG_SET (musepackdec, GST_ELEMENT_EVENT_AWARE); - musepackdec->dec = NULL; + musepackdec->r = g_new (mpc_reader, 1); + musepackdec->d = g_new (mpc_decoder, 1); + musepackdec->init = FALSE; musepackdec->seek_pending = FALSE; musepackdec->sinkpad = @@ -163,6 +163,19 @@ gst_musepackdec_init (GstMusepackDec * musepackdec) gst_musepackdec_loop); } +static void +gst_musepackdec_dispose (GObject * obj) +{ + GstMusepackDec *musepackdec = GST_MUSEPACK_DEC (obj); + + g_free (musepackdec->r); + musepackdec->r = NULL; + g_free (musepackdec->d); + musepackdec->d = NULL; + + G_OBJECT_CLASS (parent_class)->dispose (obj); +} + static gboolean gst_musepackdec_src_event (GstPad * pad, GstEvent * event) { @@ -170,21 +183,20 @@ gst_musepackdec_src_event (GstPad * pad, GstEvent * event) gboolean res; switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_SEEK: { + case GST_EVENT_SEEK:{ gint64 offset, len, pos; GstFormat fmt = GST_FORMAT_TIME; /* in time */ if (!gst_pad_convert (pad, - (GstFormat) GST_EVENT_SEEK_FORMAT (event), - GST_EVENT_SEEK_OFFSET (event), - &fmt, &offset) || + (GstFormat) GST_EVENT_SEEK_FORMAT (event), + GST_EVENT_SEEK_OFFSET (event), + &fmt, &offset) || !gst_pad_convert (pad, - GST_FORMAT_DEFAULT, musepackdec->len, - &fmt, &len) || + GST_FORMAT_DEFAULT, musepackdec->len, + &fmt, &len) || !gst_pad_convert (pad, - GST_FORMAT_DEFAULT, musepackdec->pos, - &fmt, &pos)) { + GST_FORMAT_DEFAULT, musepackdec->pos, &fmt, &pos)) { res = FALSE; break; } @@ -246,9 +258,9 @@ static const GstEventMask * gst_musepackdec_get_event_masks (GstPad * pad) { static const GstEventMask event_masks[] = { - { GST_EVENT_SEEK, - (GstEventFlag) (GST_SEEK_METHOD_SET | GST_SEEK_FLAG_FLUSH) }, - { (GstEventType) 0, (GstEventFlag) 0 } + {GST_EVENT_SEEK, + (GstEventFlag) (GST_SEEK_METHOD_SET | GST_SEEK_FLAG_FLUSH)}, + {(GstEventType) 0, (GstEventFlag) 0} }; return event_masks; @@ -273,19 +285,17 @@ gst_musepackdec_src_query (GstPad * pad, GstQueryType type, GstMusepackDec *musepackdec = GST_MUSEPACK_DEC (gst_pad_get_parent (pad)); gboolean res; - if (!musepackdec->dec) + if (!musepackdec->init) return FALSE; switch (type) { case GST_QUERY_TOTAL: res = gst_pad_convert (pad, - GST_FORMAT_DEFAULT, musepackdec->len, - format, value); + GST_FORMAT_DEFAULT, musepackdec->len, format, value); break; case GST_QUERY_POSITION: res = gst_pad_convert (pad, - GST_FORMAT_DEFAULT, musepackdec->pos, - format, value); + GST_FORMAT_DEFAULT, musepackdec->pos, format, value); break; default: res = FALSE; @@ -302,7 +312,7 @@ gst_musepackdec_src_convert (GstPad * pad, GstFormat src_format, GstMusepackDec *musepackdec = GST_MUSEPACK_DEC (gst_pad_get_parent (pad)); gboolean res = TRUE; - if (!musepackdec->dec) + if (!musepackdec->init) return FALSE; switch (src_format) { @@ -361,51 +371,43 @@ gst_musepackdec_src_convert (GstPad * pad, GstFormat src_format, static gboolean gst_musepack_stream_init (GstMusepackDec * musepackdec) { - StreamInfo si = StreamInfo (); + mpc_streaminfo i; GstCaps *caps; - if (musepackdec->dec) - delete musepackdec->dec; + /* set up reading */ + gst_musepack_init_reader (musepackdec->r, musepackdec->bs); - musepackdec->reader = new GstMusepackReader (musepackdec->bs); - if (si.ReadStreamInfo (musepackdec->reader) != ERROR_CODE_OK) { + /* streaminfo */ + mpc_streaminfo_init (&i); + if (mpc_streaminfo_read (&i, musepackdec->r) < 0) { GST_ELEMENT_ERROR (musepackdec, STREAM, WRONG_TYPE, (NULL), (NULL)); - delete musepackdec->reader; return FALSE; } - musepackdec->dec = new MPC_decoder (musepackdec->reader); - if (!musepackdec->dec) { - GST_ELEMENT_ERROR (musepackdec, LIBRARY, INIT, (NULL), - ("Creating decoder object failed")); - delete musepackdec->reader; - return FALSE; - } - - if (!musepackdec->dec->Initialize (&si)) { - GST_ELEMENT_ERROR (musepackdec, LIBRARY, INIT, (NULL), - ("Initializating stream failed")); - delete musepackdec->dec; - musepackdec->dec = NULL; + /* decoding */ + mpc_decoder_setup (musepackdec->d, musepackdec->r); + mpc_decoder_scale_output (musepackdec->d, 1.0); + if (!mpc_decoder_initialize (musepackdec->d, &i)) { + GST_ELEMENT_ERROR (musepackdec, STREAM, WRONG_TYPE, (NULL), (NULL)); return FALSE; } + /* capsnego */ caps = gst_caps_from_string (BASE_CAPS); gst_caps_set_simple (caps, "endianness", G_TYPE_INT, G_BYTE_ORDER, - "channels", G_TYPE_INT, si.simple.Channels, - "rate", G_TYPE_INT, si.simple.SampleFreq, NULL); + "channels", G_TYPE_INT, i.channels, + "rate", G_TYPE_INT, i.sample_freq, NULL); if (!gst_pad_set_explicit_caps (musepackdec->srcpad, caps)) { GST_ELEMENT_ERROR (musepackdec, CORE, NEGOTIATION, (NULL), (NULL)); - delete musepackdec->dec; - musepackdec->dec = NULL; return FALSE; } - musepackdec->bps = 4 * si.simple.Channels; - musepackdec->rate = si.simple.SampleFreq; + musepackdec->bps = 4 * i.channels;; + musepackdec->rate = i.sample_freq; musepackdec->pos = 0; - musepackdec->len = si.simple.PCMSamples; + musepackdec->len = mpc_streaminfo_get_length_samples (&i); + musepackdec->init = TRUE; return TRUE; } @@ -417,8 +419,9 @@ gst_musepackdec_loop (GstElement * element) GstBuffer *out; GstFormat fmt; gint ret; + guint32 update_acc, update_bits; - if (!musepackdec->dec) { + if (!musepackdec->init) { if (!gst_musepack_stream_init (musepackdec)) return; } @@ -427,7 +430,7 @@ gst_musepackdec_loop (GstElement * element) gdouble seek_time = (gdouble) musepackdec->seek_time / GST_SECOND; musepackdec->seek_pending = FALSE; - if (musepackdec->dec->SeekSeconds (seek_time)) { + if (mpc_decoder_seek_seconds (musepackdec->d, seek_time)) { if (musepackdec->flush_pending) { musepackdec->flush_pending = FALSE; gst_pad_push (musepackdec->srcpad, @@ -435,37 +438,38 @@ gst_musepackdec_loop (GstElement * element) } gst_pad_push (musepackdec->srcpad, GST_DATA (gst_event_new_discontinuous (FALSE, - GST_FORMAT_TIME, musepackdec->seek_time, - GST_FORMAT_UNDEFINED))); + GST_FORMAT_TIME, musepackdec->seek_time, + GST_FORMAT_UNDEFINED))); fmt = GST_FORMAT_DEFAULT; gst_pad_convert (musepackdec->srcpad, GST_FORMAT_TIME, musepackdec->seek_time, - &fmt, (gint64 *) &musepackdec->pos); + &fmt, (gint64 *) & musepackdec->pos); } } - out = gst_buffer_new_and_alloc (MPC_decoder::DecodeBufferLength * 4); - ret = musepackdec->dec->Decode ((MPC_SAMPLE_FORMAT *) GST_BUFFER_DATA (out)); + out = gst_buffer_new_and_alloc (MPC_DECODER_BUFFER_LENGTH * 4); + ret = mpc_decoder_decode (musepackdec->d, + (MPC_SAMPLE_FORMAT *) GST_BUFFER_DATA (out), &update_acc, &update_bits); if (ret <= 0) { - if (musepackdec->reader->eos == true) { + if (ret == 0) { gst_element_set_eos (element); gst_pad_push (musepackdec->srcpad, GST_DATA (gst_event_new (GST_EVENT_EOS))); + } else { + GST_ERROR_OBJECT (musepackdec, "Failed to decode sample"); } gst_buffer_unref (out); return; } - GST_BUFFER_SIZE (out) = ret; - /* note that the size is still in samples */ + + GST_BUFFER_SIZE (out) = ret * musepackdec->bps; fmt = GST_FORMAT_TIME; gst_pad_query (musepackdec->srcpad, - GST_QUERY_POSITION, &fmt, (gint64 *) &GST_BUFFER_TIMESTAMP (out)); + GST_QUERY_POSITION, &fmt, (gint64 *) & GST_BUFFER_TIMESTAMP (out)); gst_pad_convert (musepackdec->srcpad, - GST_FORMAT_DEFAULT, GST_BUFFER_SIZE (out), - &fmt, (gint64 *) &GST_BUFFER_DURATION (out)); - musepackdec->pos += GST_BUFFER_SIZE (out); - /* convert to bytes */ - GST_BUFFER_SIZE (out) *= musepackdec->bps; + GST_FORMAT_BYTES, GST_BUFFER_SIZE (out), + &fmt, (gint64 *) & GST_BUFFER_DURATION (out)); + musepackdec->pos += GST_BUFFER_SIZE (out) / musepackdec->bps; gst_pad_push (musepackdec->srcpad, GST_DATA (out)); } @@ -480,11 +484,7 @@ gst_musepackdec_change_state (GstElement * element) break; case GST_STATE_PAUSED_TO_READY: musepackdec->seek_pending = FALSE; - if (musepackdec->dec != NULL) { - delete musepackdec->reader; - delete musepackdec->dec; - musepackdec->dec = NULL; - } + musepackdec->init = FALSE; break; case GST_STATE_READY_TO_NULL: gst_bytestream_destroy (musepackdec->bs); @@ -504,11 +504,10 @@ plugin_init (GstPlugin * plugin) { return gst_library_load ("gstbytestream") && gst_element_register (plugin, "musepackdec", - GST_RANK_PRIMARY, GST_TYPE_MUSEPACK_DEC); + GST_RANK_PRIMARY, GST_TYPE_MUSEPACK_DEC); } GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, GST_VERSION_MINOR, "musepack", - "Musepack decoder", - plugin_init, VERSION, "LGPL", GST_PACKAGE, GST_ORIGIN) + "Musepack decoder", plugin_init, VERSION, "LGPL", GST_PACKAGE, GST_ORIGIN) diff --git a/ext/musepack/gstmusepackdec.cpp b/ext/musepack/gstmusepackdec.cpp deleted file mode 100644 index 7917a346..00000000 --- a/ext/musepack/gstmusepackdec.cpp +++ /dev/null @@ -1,514 +0,0 @@ -/* GStreamer Musepack decoder plugin - * Copyright (C) 2004 Ronald Bultje <rbultje@ronald.bitfreak.net> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "gstmusepackdec.h" -#include "gstmusepackreader.h" - -static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("audio/x-musepack") - ); - -#ifdef MPC_FIXED_POINT -#define BASE_CAPS \ - "audio/x-raw-int, " \ - "signed = (bool) TRUE, " \ - "width = (int) 32, " \ - "depth = (int) 32" -#else -#define BASE_CAPS \ - "audio/x-raw-float, " \ - "width = (int) 32, " \ - "buffer-frames = (int) 0" -#endif - -static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS (BASE_CAPS ", " - "endianness = (int) BYTE_ORDER, " - "rate = (int) [ 8000, 96000 ], " - "channels = (int) [ 1, 2 ]") - ); - -static void gst_musepackdec_base_init (GstMusepackDecClass * klass); -static void gst_musepackdec_class_init (GstMusepackDecClass * klass); -static void gst_musepackdec_init (GstMusepackDec * musepackdec); - -static gboolean gst_musepackdec_src_event (GstPad * pad, GstEvent * event); -static const GstFormat *gst_musepackdec_get_formats (GstPad * pad); -static const GstEventMask *gst_musepackdec_get_event_masks (GstPad * pad); -static const GstQueryType *gst_musepackdec_get_query_types (GstPad * pad); -static gboolean gst_musepackdec_src_query (GstPad * pad, GstQueryType type, - GstFormat * format, gint64 * value); -static gboolean gst_musepackdec_src_convert (GstPad * pad, - GstFormat src_format, - gint64 src_value, GstFormat * dest_format, gint64 * dest_value); - -static void gst_musepackdec_loop (GstElement * element); -static GstElementStateReturn - gst_musepackdec_change_state (GstElement * element); - -static GstElementClass *parent_class = NULL; - -/* static guint gst_musepackdec_signals[LAST_SIGNAL] = { 0 }; */ - -GType -gst_musepackdec_get_type (void) -{ - static GType gst_musepackdec_type = 0; - - if (!gst_musepackdec_type) { - static const GTypeInfo gst_musepackdec_info = { - sizeof (GstMusepackDecClass), - (GBaseInitFunc) gst_musepackdec_base_init, - NULL, - (GClassInitFunc) gst_musepackdec_class_init, - NULL, - NULL, - sizeof (GstMusepackDec), - 0, - (GInstanceInitFunc) gst_musepackdec_init, - }; - - gst_musepackdec_type = g_type_register_static (GST_TYPE_ELEMENT, - "GstMusepackDec", &gst_musepackdec_info, (GTypeFlags) 0); - } - - return gst_musepackdec_type; -} - -static void -gst_musepackdec_base_init (GstMusepackDecClass * klass) -{ - static GstElementDetails gst_musepackdec_details = GST_ELEMENT_DETAILS ( - "Musepack decoder", - "Codec/Decoder/Audio", - "Musepack decoder", - "Ronald Bultje <rbultje@ronald.bitfreak.net>" - ); - GstElementClass *element_class = GST_ELEMENT_CLASS (klass); - - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&src_template)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&sink_template)); - - gst_element_class_set_details (element_class, &gst_musepackdec_details); -} - -static void -gst_musepackdec_class_init (GstMusepackDecClass * klass) -{ - GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass); - - parent_class = GST_ELEMENT_CLASS (g_type_class_ref (GST_TYPE_ELEMENT)); - - gstelement_class->change_state = gst_musepackdec_change_state; -} - -static void -gst_musepackdec_init (GstMusepackDec * musepackdec) -{ - GST_FLAG_SET (musepackdec, GST_ELEMENT_EVENT_AWARE); - - musepackdec->dec = NULL; - musepackdec->seek_pending = FALSE; - - musepackdec->sinkpad = - gst_pad_new_from_template (gst_static_pad_template_get (&sink_template), - "sink"); - gst_element_add_pad (GST_ELEMENT (musepackdec), musepackdec->sinkpad); - - musepackdec->srcpad = - gst_pad_new_from_template (gst_static_pad_template_get (&src_template), - "src"); - gst_pad_set_event_function (musepackdec->srcpad, - GST_DEBUG_FUNCPTR (gst_musepackdec_src_event)); - gst_pad_set_event_mask_function (musepackdec->srcpad, - GST_DEBUG_FUNCPTR (gst_musepackdec_get_event_masks)); - gst_pad_set_query_function (musepackdec->srcpad, - GST_DEBUG_FUNCPTR (gst_musepackdec_src_query)); - gst_pad_set_query_type_function (musepackdec->srcpad, - GST_DEBUG_FUNCPTR (gst_musepackdec_get_query_types)); - gst_pad_set_convert_function (musepackdec->srcpad, - GST_DEBUG_FUNCPTR (gst_musepackdec_src_convert)); - gst_pad_set_formats_function (musepackdec->srcpad, - GST_DEBUG_FUNCPTR (gst_musepackdec_get_formats)); - gst_pad_use_explicit_caps (musepackdec->srcpad); - gst_element_add_pad (GST_ELEMENT (musepackdec), musepackdec->srcpad); - - gst_element_set_loop_function (GST_ELEMENT (musepackdec), - gst_musepackdec_loop); -} - -static gboolean -gst_musepackdec_src_event (GstPad * pad, GstEvent * event) -{ - GstMusepackDec *musepackdec = GST_MUSEPACK_DEC (gst_pad_get_parent (pad)); - gboolean res; - - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_SEEK: { - gint64 offset, len, pos; - GstFormat fmt = GST_FORMAT_TIME; - - /* in time */ - if (!gst_pad_convert (pad, - (GstFormat) GST_EVENT_SEEK_FORMAT (event), - GST_EVENT_SEEK_OFFSET (event), - &fmt, &offset) || - !gst_pad_convert (pad, - GST_FORMAT_DEFAULT, musepackdec->len, - &fmt, &len) || - !gst_pad_convert (pad, - GST_FORMAT_DEFAULT, musepackdec->pos, - &fmt, &pos)) { - res = FALSE; - break; - } - - /* offset from start */ - switch (GST_EVENT_SEEK_METHOD (event)) { - case GST_SEEK_METHOD_SET: - break; - case GST_SEEK_METHOD_CUR: - offset += pos; - break; - case GST_SEEK_METHOD_END: - offset = len - offset; - break; - default: - res = FALSE; - goto done; - } - - /* only valid seeks */ - if (offset >= len || offset < 0) { - res = FALSE; - break; - } - - /* store */ - musepackdec->seek_pending = TRUE; - musepackdec->flush_pending = - GST_EVENT_SEEK_FLAGS (event) & GST_SEEK_FLAG_FLUSH; - musepackdec->seek_time = offset; - res = TRUE; - break; - } - default: - res = FALSE; - break; - } - -done: - gst_event_unref (event); - - return res; -} - -static const GstFormat * -gst_musepackdec_get_formats (GstPad * pad) -{ - static const GstFormat formats[] = { - GST_FORMAT_BYTES, - GST_FORMAT_DEFAULT, - GST_FORMAT_TIME, - (GstFormat) 0 - }; - - return formats; -} - -static const GstEventMask * -gst_musepackdec_get_event_masks (GstPad * pad) -{ - static const GstEventMask event_masks[] = { - { GST_EVENT_SEEK, - (GstEventFlag) (GST_SEEK_METHOD_SET | GST_SEEK_FLAG_FLUSH) }, - { (GstEventType) 0, (GstEventFlag) 0 } - }; - - return event_masks; -} - -static const GstQueryType * -gst_musepackdec_get_query_types (GstPad * pad) -{ - static const GstQueryType query_types[] = { - GST_QUERY_TOTAL, - GST_QUERY_POSITION, - (GstQueryType) 0 - }; - - return query_types; -} - -static gboolean -gst_musepackdec_src_query (GstPad * pad, GstQueryType type, - GstFormat * format, gint64 * value) -{ - GstMusepackDec *musepackdec = GST_MUSEPACK_DEC (gst_pad_get_parent (pad)); - gboolean res; - - if (!musepackdec->dec) - return FALSE; - - switch (type) { - case GST_QUERY_TOTAL: - res = gst_pad_convert (pad, - GST_FORMAT_DEFAULT, musepackdec->len, - format, value); - break; - case GST_QUERY_POSITION: - res = gst_pad_convert (pad, - GST_FORMAT_DEFAULT, musepackdec->pos, - format, value); - break; - default: - res = FALSE; - break; - } - - return res; -} - -static gboolean -gst_musepackdec_src_convert (GstPad * pad, GstFormat src_format, - gint64 src_value, GstFormat * dest_format, gint64 * dest_value) -{ - GstMusepackDec *musepackdec = GST_MUSEPACK_DEC (gst_pad_get_parent (pad)); - gboolean res = TRUE; - - if (!musepackdec->dec) - return FALSE; - - switch (src_format) { - case GST_FORMAT_DEFAULT: - switch (*dest_format) { - case GST_FORMAT_TIME: - *dest_value = src_value * GST_SECOND / musepackdec->rate; - break; - case GST_FORMAT_BYTES: - *dest_value = src_value * musepackdec->bps; - break; - default: - res = FALSE; - break; - } - break; - - case GST_FORMAT_TIME: - switch (*dest_format) { - case GST_FORMAT_DEFAULT: - *dest_value = src_value * musepackdec->rate / GST_SECOND; - break; - case GST_FORMAT_BYTES: - *dest_value = src_value * musepackdec->rate * - musepackdec->bps / GST_SECOND; - break; - default: - res = FALSE; - break; - } - break; - - case GST_FORMAT_BYTES: - switch (*dest_format) { - case GST_FORMAT_DEFAULT: - *dest_value = src_value / musepackdec->bps; - break; - case GST_FORMAT_TIME: - *dest_value = src_value * GST_SECOND / - (musepackdec->bps * musepackdec->rate); - break; - default: - res = FALSE; - break; - } - break; - - default: - res = FALSE; - break; - } - - return TRUE; -} - -static gboolean -gst_musepack_stream_init (GstMusepackDec * musepackdec) -{ - StreamInfo si = StreamInfo (); - GstCaps *caps; - - if (musepackdec->dec) - delete musepackdec->dec; - - musepackdec->reader = new GstMusepackReader (musepackdec->bs); - if (si.ReadStreamInfo (musepackdec->reader) != ERROR_CODE_OK) { - GST_ELEMENT_ERROR (musepackdec, STREAM, WRONG_TYPE, (NULL), (NULL)); - delete musepackdec->reader; - return FALSE; - } - - musepackdec->dec = new MPC_decoder (musepackdec->reader); - if (!musepackdec->dec) { - GST_ELEMENT_ERROR (musepackdec, LIBRARY, INIT, (NULL), - ("Creating decoder object failed")); - delete musepackdec->reader; - return FALSE; - } - - if (!musepackdec->dec->Initialize (&si)) { - GST_ELEMENT_ERROR (musepackdec, LIBRARY, INIT, (NULL), - ("Initializating stream failed")); - delete musepackdec->dec; - musepackdec->dec = NULL; - return FALSE; - } - - caps = gst_caps_from_string (BASE_CAPS); - gst_caps_set_simple (caps, - "endianness", G_TYPE_INT, G_BYTE_ORDER, - "channels", G_TYPE_INT, si.simple.Channels, - "rate", G_TYPE_INT, si.simple.SampleFreq, NULL); - if (!gst_pad_set_explicit_caps (musepackdec->srcpad, caps)) { - GST_ELEMENT_ERROR (musepackdec, CORE, NEGOTIATION, (NULL), (NULL)); - delete musepackdec->dec; - musepackdec->dec = NULL; - return FALSE; - } - - musepackdec->bps = 4 * si.simple.Channels; - musepackdec->rate = si.simple.SampleFreq; - musepackdec->pos = 0; - musepackdec->len = si.simple.PCMSamples; - - return TRUE; -} - -static void -gst_musepackdec_loop (GstElement * element) -{ - GstMusepackDec *musepackdec = GST_MUSEPACK_DEC (element); - GstBuffer *out; - GstFormat fmt; - gint ret; - - if (!musepackdec->dec) { - if (!gst_musepack_stream_init (musepackdec)) - return; - } - - if (musepackdec->seek_pending) { - gdouble seek_time = (gdouble) musepackdec->seek_time / GST_SECOND; - - musepackdec->seek_pending = FALSE; - if (musepackdec->dec->SeekSeconds (seek_time)) { - if (musepackdec->flush_pending) { - musepackdec->flush_pending = FALSE; - gst_pad_push (musepackdec->srcpad, - GST_DATA (gst_event_new (GST_EVENT_FLUSH))); - } - gst_pad_push (musepackdec->srcpad, - GST_DATA (gst_event_new_discontinuous (FALSE, - GST_FORMAT_TIME, musepackdec->seek_time, - GST_FORMAT_UNDEFINED))); - fmt = GST_FORMAT_DEFAULT; - gst_pad_convert (musepackdec->srcpad, - GST_FORMAT_TIME, musepackdec->seek_time, - &fmt, (gint64 *) &musepackdec->pos); - } - } - - out = gst_buffer_new_and_alloc (MPC_decoder::DecodeBufferLength * 4); - ret = musepackdec->dec->Decode ((MPC_SAMPLE_FORMAT *) GST_BUFFER_DATA (out)); - if (ret <= 0) { - if (musepackdec->reader->eos == true) { - gst_element_set_eos (element); - gst_pad_push (musepackdec->srcpad, - GST_DATA (gst_event_new (GST_EVENT_EOS))); - } - gst_buffer_unref (out); - return; - } - GST_BUFFER_SIZE (out) = ret; - /* note that the size is still in samples */ - fmt = GST_FORMAT_TIME; - gst_pad_query (musepackdec->srcpad, - GST_QUERY_POSITION, &fmt, (gint64 *) &GST_BUFFER_TIMESTAMP (out)); - gst_pad_convert (musepackdec->srcpad, - GST_FORMAT_DEFAULT, GST_BUFFER_SIZE (out), - &fmt, (gint64 *) &GST_BUFFER_DURATION (out)); - musepackdec->pos += GST_BUFFER_SIZE (out); - /* convert to bytes */ - GST_BUFFER_SIZE (out) *= musepackdec->bps; - gst_pad_push (musepackdec->srcpad, GST_DATA (out)); -} - -static GstElementStateReturn -gst_musepackdec_change_state (GstElement * element) -{ - GstMusepackDec *musepackdec = GST_MUSEPACK_DEC (element); - - switch (GST_STATE_TRANSITION (element)) { - case GST_STATE_NULL_TO_READY: - musepackdec->bs = gst_bytestream_new (musepackdec->sinkpad); - break; - case GST_STATE_PAUSED_TO_READY: - musepackdec->seek_pending = FALSE; - if (musepackdec->dec != NULL) { - delete musepackdec->reader; - delete musepackdec->dec; - musepackdec->dec = NULL; - } - break; - case GST_STATE_READY_TO_NULL: - gst_bytestream_destroy (musepackdec->bs); - break; - default: - break; - } - - if (GST_ELEMENT_CLASS (parent_class)->change_state) - return GST_ELEMENT_CLASS (parent_class)->change_state (element); - - return GST_STATE_SUCCESS; -} - -static gboolean -plugin_init (GstPlugin * plugin) -{ - return gst_library_load ("gstbytestream") && - gst_element_register (plugin, "musepackdec", - GST_RANK_PRIMARY, GST_TYPE_MUSEPACK_DEC); -} - -GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, - GST_VERSION_MINOR, - "musepack", - "Musepack decoder", - plugin_init, VERSION, "LGPL", GST_PACKAGE, GST_ORIGIN) diff --git a/ext/musepack/gstmusepackdec.h b/ext/musepack/gstmusepackdec.h index 8f2f59f6..a4493c4a 100644 --- a/ext/musepack/gstmusepackdec.h +++ b/ext/musepack/gstmusepackdec.h @@ -22,7 +22,7 @@ #include <gst/gst.h> #include <gst/bytestream/bytestream.h> -#include <musepack/mpc_dec.h> +#include <musepack/musepack.h> #include "gstmusepackreader.h" G_BEGIN_DECLS @@ -48,8 +48,9 @@ typedef struct _GstMusepackDec { GstByteStream *bs; /* MUSEPACK_DEC object */ - MPC_decoder *dec; - GstMusepackReader *reader; + mpc_decoder *d; + mpc_reader *r; + gboolean init; /* bytes-per-sample */ int bps, rate; diff --git a/ext/musepack/gstmusepackreader.c b/ext/musepack/gstmusepackreader.c index 07fbcf3d..230d7a3c 100644 --- a/ext/musepack/gstmusepackreader.c +++ b/ext/musepack/gstmusepackreader.c @@ -26,32 +26,23 @@ #include "gstmusepackreader.h" -GstMusepackReader::GstMusepackReader (GstByteStream *bs) -{ - this->bs = bs; - this->eos = false; -} - -GstMusepackReader::~GstMusepackReader (void) -{ -} - -mpc_int32_t -GstMusepackReader::read (void * ptr, mpc_int32_t size) +static mpc_int32_t +gst_musepack_reader_peek (void *this, void *ptr, mpc_int32_t size) { + GstByteStream *bs = this; guint8 *data; gint read; do { - read = gst_bytestream_peek_bytes (this->bs, &data, size); + read = gst_bytestream_peek_bytes (bs, &data, size); if (read != size) { GstEvent *event; guint32 remaining; - gst_bytestream_get_status (this->bs, &remaining, &event); + gst_bytestream_get_status (bs, &remaining, &event); if (!event) { - GST_ELEMENT_ERROR (gst_pad_get_parent (this->bs->pad), + GST_ELEMENT_ERROR (gst_pad_get_parent (bs->pad), RESOURCE, READ, (NULL), (NULL)); goto done; } @@ -61,14 +52,16 @@ GstMusepackReader::read (void * ptr, mpc_int32_t size) gst_event_unref (event); goto done; case GST_EVENT_EOS: - this->eos = true; gst_event_unref (event); goto done; case GST_EVENT_FLUSH: gst_event_unref (event); break; + case GST_EVENT_DISCONTINUOUS: + gst_event_unref (event); + break; default: - gst_pad_event_default (this->bs->pad, event); + gst_pad_event_default (bs->pad, event); break; } } @@ -77,75 +70,76 @@ GstMusepackReader::read (void * ptr, mpc_int32_t size) done: if (read != 0) { memcpy (ptr, data, read); - gst_bytestream_flush_fast (this->bs, read); } return read; } -bool -GstMusepackReader::seek (mpc_int32_t offset) +static mpc_int32_t +gst_musepack_reader_read (void *this, void *ptr, mpc_int32_t size) { - guint8 *dummy; + GstByteStream *bs = this; + gint read; + + /* read = peek + flush */ + if ((read = gst_musepack_reader_peek (this, ptr, size)) > 0) { + gst_bytestream_flush_fast (bs, read); + } + + return read; +} + +static BOOL +gst_musepack_reader_seek (void *this, mpc_int32_t offset) +{ + GstByteStream *bs = this; + guint8 dummy; /* hacky hack - if we're after typefind, we'll fail because * typefind is still typefinding (heh :) ). So read first. */ - if (this->tell () != this->get_size ()) { - guint8 dummy2[1]; - this->read (dummy2, 1); - } + gst_musepack_reader_peek (this, &dummy, 1); - if (!gst_bytestream_seek (this->bs, offset, GST_SEEK_METHOD_SET)) + /* seek */ + if (!gst_bytestream_seek (bs, offset, GST_SEEK_METHOD_SET)) return FALSE; /* get discont */ - while (gst_bytestream_peek_bytes (this->bs, &dummy, 1) != 1) { - GstEvent *event; - guint32 remaining; - - gst_bytestream_get_status (this->bs, &remaining, &event); - if (!event) { - GST_ELEMENT_ERROR (gst_pad_get_parent (this->bs->pad), - RESOURCE, SEEK, (NULL), (NULL)); - return false; - } - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_EOS: - g_warning ("EOS!"); - gst_event_unref (event); - return false; - case GST_EVENT_DISCONTINUOUS: - gst_event_unref (event); - return true; - case GST_EVENT_INTERRUPT: - g_warning ("interrupt!"); - return false; - case GST_EVENT_FLUSH: - gst_event_unref (event); - break; - default: - gst_pad_event_default (this->bs->pad, event); - break; - } - } + if (gst_musepack_reader_peek (this, &dummy, 1) != 1) + return FALSE; - return false; + return TRUE; } -mpc_int32_t -GstMusepackReader::tell (void) +static mpc_int32_t +gst_musepack_reader_tell (void *this) { - return gst_bytestream_tell (this->bs); + GstByteStream *bs = this; + + return gst_bytestream_tell (bs); +} + +static mpc_int32_t +gst_musepack_reader_get_size (void *this) +{ + GstByteStream *bs = this; + + return gst_bytestream_length (bs); } -mpc_int32_t -GstMusepackReader::get_size (void) +static BOOL +gst_musepack_reader_canseek (void *this) { - return gst_bytestream_length (this->bs); + return TRUE; } -bool -GstMusepackReader::canseek (void) +void +gst_musepack_init_reader (mpc_reader * r, GstByteStream * bs) { - return true; + r->data = bs; + + r->read = gst_musepack_reader_read; + r->seek = gst_musepack_reader_seek; + r->tell = gst_musepack_reader_tell; + r->get_size = gst_musepack_reader_get_size; + r->canseek = gst_musepack_reader_canseek; } diff --git a/ext/musepack/gstmusepackreader.cpp b/ext/musepack/gstmusepackreader.cpp deleted file mode 100644 index 07fbcf3d..00000000 --- a/ext/musepack/gstmusepackreader.cpp +++ /dev/null @@ -1,151 +0,0 @@ -/* GStreamer Musepack decoder plugin - * Copyright (C) 2004 Ronald Bultje <rbultje@ronald.bitfreak.net> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <gst/gst.h> -#include <string.h> - -#include "gstmusepackreader.h" - -GstMusepackReader::GstMusepackReader (GstByteStream *bs) -{ - this->bs = bs; - this->eos = false; -} - -GstMusepackReader::~GstMusepackReader (void) -{ -} - -mpc_int32_t -GstMusepackReader::read (void * ptr, mpc_int32_t size) -{ - guint8 *data; - gint read; - - do { - read = gst_bytestream_peek_bytes (this->bs, &data, size); - - if (read != size) { - GstEvent *event; - guint32 remaining; - - gst_bytestream_get_status (this->bs, &remaining, &event); - if (!event) { - GST_ELEMENT_ERROR (gst_pad_get_parent (this->bs->pad), - RESOURCE, READ, (NULL), (NULL)); - goto done; - } - - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_INTERRUPT: - gst_event_unref (event); - goto done; - case GST_EVENT_EOS: - this->eos = true; - gst_event_unref (event); - goto done; - case GST_EVENT_FLUSH: - gst_event_unref (event); - break; - default: - gst_pad_event_default (this->bs->pad, event); - break; - } - } - } while (read != size); - -done: - if (read != 0) { - memcpy (ptr, data, read); - gst_bytestream_flush_fast (this->bs, read); - } - - return read; -} - -bool -GstMusepackReader::seek (mpc_int32_t offset) -{ - guint8 *dummy; - - /* hacky hack - if we're after typefind, we'll fail because - * typefind is still typefinding (heh :) ). So read first. */ - if (this->tell () != this->get_size ()) { - guint8 dummy2[1]; - this->read (dummy2, 1); - } - - if (!gst_bytestream_seek (this->bs, offset, GST_SEEK_METHOD_SET)) - return FALSE; - - /* get discont */ - while (gst_bytestream_peek_bytes (this->bs, &dummy, 1) != 1) { - GstEvent *event; - guint32 remaining; - - gst_bytestream_get_status (this->bs, &remaining, &event); - if (!event) { - GST_ELEMENT_ERROR (gst_pad_get_parent (this->bs->pad), - RESOURCE, SEEK, (NULL), (NULL)); - return false; - } - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_EOS: - g_warning ("EOS!"); - gst_event_unref (event); - return false; - case GST_EVENT_DISCONTINUOUS: - gst_event_unref (event); - return true; - case GST_EVENT_INTERRUPT: - g_warning ("interrupt!"); - return false; - case GST_EVENT_FLUSH: - gst_event_unref (event); - break; - default: - gst_pad_event_default (this->bs->pad, event); - break; - } - } - - return false; -} - -mpc_int32_t -GstMusepackReader::tell (void) -{ - return gst_bytestream_tell (this->bs); -} - -mpc_int32_t -GstMusepackReader::get_size (void) -{ - return gst_bytestream_length (this->bs); -} - -bool -GstMusepackReader::canseek (void) -{ - return true; -} diff --git a/ext/musepack/gstmusepackreader.h b/ext/musepack/gstmusepackreader.h index 9010dc47..2aa2edd2 100644 --- a/ext/musepack/gstmusepackreader.h +++ b/ext/musepack/gstmusepackreader.h @@ -20,24 +20,9 @@ #ifndef __GST_MUSEPACK_READER_H__ #define __GST_MUSEPACK_READER_H__ -#include <musepack/mpc_dec.h> +#include <musepack/musepack.h> #include <gst/bytestream/bytestream.h> -class GstMusepackReader : public MPC_reader { -public: - GstMusepackReader (GstByteStream *bs); - virtual ~GstMusepackReader (void); - - mpc_int32_t read (void * ptr, mpc_int32_t size); - bool seek (mpc_int32_t offset); - mpc_int32_t tell (void); - mpc_int32_t get_size (void); - bool canseek (void); - - bool eos; - -private: - GstByteStream *bs; -}; +void gst_musepack_init_reader (mpc_reader * r, GstByteStream * bs); #endif /* __GST_MUSEPACK_READER_H__ */ |