diff options
author | Edgard Lima <edgard.lima@indt.org.br> | 2005-11-22 15:09:28 +0000 |
---|---|---|
committer | Edgard Lima <edgard.lima@indt.org.br> | 2005-11-22 15:09:28 +0000 |
commit | a5ef8aef56c1639abcc23b7ba19c00225a041e89 (patch) | |
tree | bc33c90323654be703b24750180402ae4dd35dca | |
parent | ee0e50b84d25f2886d41c9629c01edc376237fcd (diff) | |
download | gst-plugins-bad-a5ef8aef56c1639abcc23b7ba19c00225a041e89.tar.gz gst-plugins-bad-a5ef8aef56c1639abcc23b7ba19c00225a041e89.tar.bz2 gst-plugins-bad-a5ef8aef56c1639abcc23b7ba19c00225a041e89.zip |
Musepackdec ported to 0.9. There is still a small problem to be solved, after the end of file, the pipeline doens't s...
Original commit message from CVS:
Musepackdec ported to 0.9. There is still a small problem to be solved, after the end of file, the pipeline doens't stop.
-rw-r--r-- | ChangeLog | 11 | ||||
-rw-r--r-- | PORTED_09 | 29 | ||||
-rw-r--r-- | configure.ac | 13 | ||||
-rw-r--r-- | ext/Makefile.am | 9 | ||||
-rw-r--r-- | ext/musepack/gstmusepackdec.c | 313 | ||||
-rw-r--r-- | ext/musepack/gstmusepackdec.h | 15 | ||||
-rw-r--r-- | ext/musepack/gstmusepackreader.c | 156 | ||||
-rw-r--r-- | ext/musepack/gstmusepackreader.h | 7 |
8 files changed, 368 insertions, 185 deletions
@@ -1,3 +1,14 @@ +2005-11-22 Edgard Lima <edgard.lima@indt.org.br> + * configure.ac: + * PORTED_09: + * extt/Makefile.am: + * ext/musepack/gstmusepackdec.c: + * ext/musepack/gstmusepackdec.h: + * ext/musepack/gstmusepackreader.c: + * ext/musepack/gstmusepackreader.h: + Musepackdec ported to 0.9. There is still a small problem to be + solved, after the end of file, the pipeline doens't stop. + 2005-11-22 Andy Wingo <wingo@pobox.com> * ext/faad/gstfaad.c (gst_faad_event) @@ -1,21 +1,22 @@ When porting a plugin start with 0.8 CVS head, not the old code in this module. There are many bugfixes which have gone into 0.8 which you want to keep. List of ported plugins (update when you commit a ported plugin): -ivorbis (alima) -gsmdec (alima) -sdl (alima) -speed (fcarvalho) -gsmenc (fcarvalho) -faac (fcarvalho) -wavenc (fcarvalho) -effectv (wim) -mad (wim) +musepack (alima) +ivorbis (alima) +gsmdec (alima) +sdl (alima) +speed (fcarvalho) +gsmenc (fcarvalho) +faac (fcarvalho) +wavenc (fcarvalho) +effectv (wim) +mad (wim) videofilter (wim) -aalib (wim) -libcaca (zeeshan) -law (wim) -shout2 (zaheer) - not fully tested -esdsink (arwed) +aalib (wim) +libcaca (zeeshan) +law (wim) +shout2 (zaheer) - not fully tested +esdsink (arwed) osssink is partially done in the threaded branch (wim) diff --git a/configure.ac b/configure.ac index 8c581357..910af2e5 100644 --- a/configure.ac +++ b/configure.ac @@ -399,6 +399,18 @@ else AC_SUBST(X_LIBS) fi +dnl *** musepack *** +translit(dnm, m, l) AM_CONDITIONAL(USE_MUSEPACK, true) +GST_CHECK_FEATURE(MUSEPACK, [musepackdec], musepack, [ + AC_LANG_CPLUSPLUS + AC_CHECK_HEADER([mpcdec/mpcdec.h], [ + HAVE_MUSEPACK="yes" + MUSEPACK_LIBS="-lmpcdec" + AC_SUBST(MUSEPACK_LIBS) + ], [HAVE_MUSEPACK="no"]) + AC_LANG_C +]) + dnl *** SDL *** translit(dnm, m, l) AM_CONDITIONAL(USE_SDL, true) @@ -508,6 +520,7 @@ ext/faac/Makefile ext/faad/Makefile ext/ivorbis/Makefile ext/gsm/Makefile +ext/musepack/Makefile ext/sdl/Makefile docs/Makefile docs/plugins/Makefile diff --git a/ext/Makefile.am b/ext/Makefile.am index 40951be6..651664c8 100644 --- a/ext/Makefile.am +++ b/ext/Makefile.am @@ -118,11 +118,11 @@ MPEG2ENC_DIR= MPLEX_DIR= # endif -# if USE_MUSEPACK -# MUSEPACK_DIR=musepack -# else +if USE_MUSEPACK +MUSEPACK_DIR=musepack +else MUSEPACK_DIR= -# endif +endif # if USE_MUSICBRAINZ # MUSICBRAINZ_DIR=musicbrainz @@ -228,6 +228,7 @@ DIST_SUBDIRS= \ faac \ faad \ gsm \ + musepack \ sdl \ directfb \ ivorbis diff --git a/ext/musepack/gstmusepackdec.c b/ext/musepack/gstmusepackdec.c index 607cf960..f058bb4c 100644 --- a/ext/musepack/gstmusepackdec.c +++ b/ext/musepack/gstmusepackdec.c @@ -57,16 +57,15 @@ 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); -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 const GstQueryType *gst_musepackdec_get_src_query_types (GstPad * pad); +static gboolean gst_musepackdec_src_query (GstPad * pad, GstQuery * query); + +static gboolean gst_musepackdec_sink_event (GstPad * pad, GstEvent * event); +static gboolean gst_musepackdec_sink_activate (GstPad * sinkpad); +static gboolean +gst_musepackdec_sink_activate_pull (GstPad * sinkpad, gboolean active); + +static void gst_musepackdec_loop (GstPad * sinkpad); static GstStateChangeReturn gst_musepackdec_change_state (GstElement * element, GstStateChange transition); @@ -129,38 +128,41 @@ gst_musepackdec_class_init (GstMusepackDecClass * klass) static void gst_musepackdec_init (GstMusepackDec * musepackdec) { - GST_OBJECT_FLAG_SET (musepackdec, GST_ELEMENT_EVENT_AWARE); + musepackdec->offset = 0; musepackdec->r = g_new (mpc_reader, 1); musepackdec->d = g_new (mpc_decoder, 1); musepackdec->init = FALSE; musepackdec->seek_pending = FALSE; + musepackdec->flush_pending = FALSE; + musepackdec->eos = FALSE; musepackdec->sinkpad = gst_pad_new_from_template (gst_static_pad_template_get (&sink_template), "sink"); + gst_pad_set_event_function (musepackdec->sinkpad, + GST_DEBUG_FUNCPTR (gst_musepackdec_sink_event)); gst_element_add_pad (GST_ELEMENT (musepackdec), musepackdec->sinkpad); + gst_pad_set_activate_function (musepackdec->sinkpad, + gst_musepackdec_sink_activate); + gst_pad_set_activatepull_function (musepackdec->sinkpad, + gst_musepackdec_sink_activate_pull); + 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_DEBUG_FUNCPTR (gst_musepackdec_get_src_query_types)); + gst_pad_use_fixed_caps (musepackdec->srcpad); gst_element_add_pad (GST_ELEMENT (musepackdec), musepackdec->srcpad); - gst_element_set_loop_function (GST_ELEMENT (musepackdec), - gst_musepackdec_loop); + } static void @@ -177,6 +179,40 @@ gst_musepackdec_dispose (GObject * obj) } static gboolean +gst_musepackdec_sink_event (GstPad * pad, GstEvent * event) +{ + GstMusepackDec *musepackdec = GST_MUSEPACK_DEC (gst_pad_get_parent (pad)); + gboolean res = TRUE; + + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_FLUSH_START: + musepackdec->flush_pending = TRUE; + goto done; + break; + case GST_EVENT_NEWSEGMENT: + musepackdec->flush_pending = TRUE; + musepackdec->seek_pending = TRUE; + goto done; + break; + case GST_EVENT_EOS: + musepackdec->eos = TRUE; + /* fall through */ + default: + res = gst_pad_event_default (pad, event); + gst_object_unref (musepackdec); + return res; + break; + } + +done: + gst_event_unref (event); + gst_object_unref (musepackdec); + return res; + +} + + +static gboolean gst_musepackdec_src_event (GstPad * pad, GstEvent * event) { GstMusepackDec *musepackdec = GST_MUSEPACK_DEC (gst_pad_get_parent (pad)); @@ -184,31 +220,44 @@ gst_musepackdec_src_event (GstPad * pad, GstEvent * event) switch (GST_EVENT_TYPE (event)) { case GST_EVENT_SEEK:{ + + gdouble rate; + GstFormat format; + GstSeekFlags flags; + GstSeekType cur_type; + gint64 cur; + GstSeekType stop_type; + gint64 stop; + + gst_event_parse_seek (event, &rate, &format, &flags, + &cur_type, &cur, &stop_type, &stop); + + 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)) { + if (!gst_musepackdec_src_convert (pad, format, cur, &fmt, &offset)) { + + } + if (!gst_musepackdec_src_convert (pad, GST_FORMAT_DEFAULT, + musepackdec->len, &fmt, &len)) { + res = FALSE; + break; + } + if (!gst_musepackdec_src_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: + switch (cur_type) { + case GST_SEEK_TYPE_SET: break; - case GST_SEEK_METHOD_CUR: + case GST_SEEK_TYPE_CUR: offset += pos; break; - case GST_SEEK_METHOD_END: + case GST_SEEK_TYPE_END: offset = len - offset; break; default: @@ -224,54 +273,31 @@ gst_musepackdec_src_event (GstPad * pad, GstEvent * event) /* store */ musepackdec->seek_pending = TRUE; - musepackdec->flush_pending = - GST_EVENT_SEEK_FLAGS (event) & GST_SEEK_FLAG_FLUSH; + musepackdec->flush_pending = flags & GST_SEEK_FLAG_FLUSH; musepackdec->seek_time = offset; res = TRUE; break; } default: - res = FALSE; + res = gst_pad_event_default (pad, event); + gst_object_unref (musepackdec); + return res; break; } done: gst_event_unref (event); - + gst_object_unref (musepackdec); 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) +gst_musepackdec_get_src_query_types (GstPad * pad) { static const GstQueryType query_types[] = { - GST_QUERY_TOTAL, GST_QUERY_POSITION, + GST_QUERY_DURATION, + GST_QUERY_CONVERT, (GstQueryType) 0 }; @@ -279,41 +305,67 @@ gst_musepackdec_get_query_types (GstPad * pad) } static gboolean -gst_musepackdec_src_query (GstPad * pad, GstQueryType type, - GstFormat * format, gint64 * value) +gst_musepackdec_src_query (GstPad * pad, GstQuery * query) { GstMusepackDec *musepackdec = GST_MUSEPACK_DEC (gst_pad_get_parent (pad)); - gboolean res; + GstFormat format = GST_FORMAT_DEFAULT; + GstFormat dest_format; + gint64 value, dest_value; + gboolean res = TRUE; - if (!musepackdec->init) - return FALSE; + if (!musepackdec->init) { + res = FALSE; + goto done; + } - switch (type) { - case GST_QUERY_TOTAL: - res = gst_pad_convert (pad, - GST_FORMAT_DEFAULT, musepackdec->len, format, value); - break; + switch (GST_QUERY_TYPE (query)) { case GST_QUERY_POSITION: - res = gst_pad_convert (pad, - GST_FORMAT_DEFAULT, musepackdec->pos, format, value); + gst_query_parse_position (query, &dest_format, NULL); + if (!gst_musepackdec_src_convert (pad, format, musepackdec->pos, + &dest_format, &dest_value)) { + res = FALSE; + } + gst_query_set_position (query, dest_format, dest_value); + break; + case GST_QUERY_DURATION: + gst_query_parse_duration (query, &dest_format, NULL); + if (!gst_musepackdec_src_convert (pad, format, musepackdec->len, + &dest_format, &dest_value)) { + res = FALSE; + break; + } + gst_query_set_duration (query, dest_format, dest_value); + break; + case GST_QUERY_CONVERT: + gst_query_parse_convert (query, &format, &value, &dest_format, + &dest_value); + if (!gst_musepackdec_src_convert (pad, format, value, &dest_format, + &dest_value)) { + res = FALSE; + } + gst_query_set_convert (query, format, value, dest_format, dest_value); break; default: res = FALSE; break; } +done: + g_object_unref (musepackdec); return res; } -static gboolean +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->init) + if (!musepackdec->init) { + gst_object_unref (musepackdec); return FALSE; + } switch (src_format) { case GST_FORMAT_DEFAULT: @@ -365,6 +417,7 @@ gst_musepackdec_src_convert (GstPad * pad, GstFormat src_format, break; } + gst_object_unref (musepackdec); return TRUE; } @@ -375,7 +428,7 @@ gst_musepack_stream_init (GstMusepackDec * musepackdec) GstCaps *caps; /* set up reading */ - gst_musepack_init_reader (musepackdec->r, musepackdec->bs); + gst_musepack_init_reader (musepackdec->r, musepackdec); /* streaminfo */ mpc_streaminfo_init (&i); @@ -398,7 +451,8 @@ gst_musepack_stream_init (GstMusepackDec * musepackdec) "endianness", G_TYPE_INT, G_BYTE_ORDER, "channels", G_TYPE_INT, i.channels, "rate", G_TYPE_INT, i.sample_freq, NULL); - if (!gst_pad_set_explicit_caps (musepackdec->srcpad, caps)) { + gst_pad_use_fixed_caps (musepackdec->srcpad); + if (!gst_pad_set_caps (musepackdec->srcpad, caps)) { GST_ELEMENT_ERROR (musepackdec, CORE, NEGOTIATION, (NULL), (NULL)); return FALSE; } @@ -412,10 +466,38 @@ gst_musepack_stream_init (GstMusepackDec * musepackdec) return TRUE; } +static gboolean +gst_musepackdec_sink_activate (GstPad * sinkpad) +{ + + if (gst_pad_check_pull_range (sinkpad)) { + return gst_pad_activate_pull (sinkpad, TRUE); + } else { + return FALSE; + } +} + +static gboolean +gst_musepackdec_sink_activate_pull (GstPad * sinkpad, gboolean active) +{ + + gboolean result; + + if (active) { + + result = gst_pad_start_task (sinkpad, + (GstTaskFunction) gst_musepackdec_loop, sinkpad); + } else { + result = gst_pad_stop_task (sinkpad); + } + + return result; +} + static void -gst_musepackdec_loop (GstElement * element) +gst_musepackdec_loop (GstPad * sinkpad) { - GstMusepackDec *musepackdec = GST_MUSEPACK_DEC (element); + GstMusepackDec *musepackdec = GST_MUSEPACK_DEC (GST_PAD_PARENT (sinkpad)); GstBuffer *out; GstFormat fmt; gint ret; @@ -424,6 +506,9 @@ gst_musepackdec_loop (GstElement * element) if (!musepackdec->init) { if (!gst_musepack_stream_init (musepackdec)) return; + gst_pad_push_event (musepackdec->srcpad, + gst_event_new_newsegment (FALSE, 1.0, + GST_FORMAT_TIME, musepackdec->pos, GST_CLOCK_TIME_NONE, 0)); } if (musepackdec->seek_pending) { @@ -433,15 +518,13 @@ gst_musepackdec_loop (GstElement * element) if (mpc_decoder_seek_seconds (musepackdec->d, 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_event (musepackdec->srcpad, gst_event_new_flush_start ()); } - gst_pad_push (musepackdec->srcpad, - GST_DATA (gst_event_new_discontinuous (FALSE, - GST_FORMAT_TIME, musepackdec->seek_time, - GST_FORMAT_UNDEFINED))); + gst_pad_push_event (musepackdec->srcpad, + gst_event_new_newsegment (FALSE, 1.0, + GST_FORMAT_TIME, musepackdec->seek_time, GST_CLOCK_TIME_NONE, 0)); fmt = GST_FORMAT_DEFAULT; - gst_pad_convert (musepackdec->srcpad, + gst_musepackdec_src_convert (musepackdec->srcpad, GST_FORMAT_TIME, musepackdec->seek_time, &fmt, (gint64 *) & musepackdec->pos); } @@ -450,13 +533,12 @@ gst_musepackdec_loop (GstElement * element) 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 (ret == 0) { - gst_element_set_eos (element); - gst_pad_push (musepackdec->srcpad, - GST_DATA (gst_event_new (GST_EVENT_EOS))); - } else { + if (ret <= 0 || musepackdec->eos) { + if (ret < 0) { GST_ERROR_OBJECT (musepackdec, "Failed to decode sample"); + } else if (!musepackdec->eos) { + musepackdec->eos = TRUE; + gst_pad_push_event (musepackdec->sinkpad, gst_event_new_eos ()); } gst_buffer_unref (out); return; @@ -464,46 +546,49 @@ gst_musepackdec_loop (GstElement * element) 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_pad_convert (musepackdec->srcpad, - GST_FORMAT_BYTES, GST_BUFFER_SIZE (out), - &fmt, (gint64 *) & GST_BUFFER_DURATION (out)); + + gint64 value; + + gst_musepackdec_src_convert (musepackdec->srcpad, + GST_FORMAT_BYTES, GST_BUFFER_SIZE (out), &fmt, &value); + GST_BUFFER_DURATION (out) = value; + + gst_musepackdec_src_convert (musepackdec->srcpad, + GST_FORMAT_DEFAULT, musepackdec->pos, &fmt, &value); + GST_BUFFER_TIMESTAMP (out) = value; + musepackdec->pos += GST_BUFFER_SIZE (out) / musepackdec->bps; - gst_pad_push (musepackdec->srcpad, GST_DATA (out)); + gst_buffer_set_caps (out, GST_PAD_CAPS (musepackdec->srcpad)); + gst_pad_push (musepackdec->srcpad, out); } static GstStateChangeReturn gst_musepackdec_change_state (GstElement * element, GstStateChange transition) { GstMusepackDec *musepackdec = GST_MUSEPACK_DEC (element); + GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS; + + if (GST_ELEMENT_CLASS (parent_class)->change_state) + ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); + switch (transition) { - case GST_STATE_CHANGE_NULL_TO_READY: - musepackdec->bs = gst_bytestream_new (musepackdec->sinkpad); - break; case GST_STATE_CHANGE_PAUSED_TO_READY: musepackdec->seek_pending = FALSE; musepackdec->init = FALSE; break; - case GST_STATE_CHANGE_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, transition); + return ret; - return GST_STATE_CHANGE_SUCCESS; } static gboolean plugin_init (GstPlugin * plugin) { - return gst_library_load ("gstbytestream") && - gst_element_register (plugin, "musepackdec", + return gst_element_register (plugin, "musepackdec", GST_RANK_PRIMARY, GST_TYPE_MUSEPACK_DEC); } diff --git a/ext/musepack/gstmusepackdec.h b/ext/musepack/gstmusepackdec.h index a4493c4a..3b931cad 100644 --- a/ext/musepack/gstmusepackdec.h +++ b/ext/musepack/gstmusepackdec.h @@ -21,9 +21,9 @@ #define __GST_MUSEPACK_DEC_H__ #include <gst/gst.h> -#include <gst/bytestream/bytestream.h> -#include <musepack/musepack.h> -#include "gstmusepackreader.h" +//#include <gst/bytestream/bytestream.h> +#include <mpcdec/mpcdec.h> +//#include "gstmusepackreader.h" G_BEGIN_DECLS @@ -45,7 +45,8 @@ typedef struct _GstMusepackDec { /* pads */ GstPad *srcpad, *sinkpad; - GstByteStream *bs; + // GstByteStream *bs; + guint64 offset; /* MUSEPACK_DEC object */ mpc_decoder *d; @@ -59,7 +60,7 @@ typedef struct _GstMusepackDec { guint64 pos, len; /* seeks */ - gdouble flush_pending, seek_pending; + gdouble flush_pending, seek_pending, eos; guint64 seek_time; } GstMusepackDec; @@ -69,6 +70,10 @@ typedef struct _GstMusepackDecClass { GType gst_musepackdec_get_type (void); +extern gboolean gst_musepackdec_src_convert (GstPad * pad, + GstFormat src_format, + gint64 src_value, GstFormat * dest_format, gint64 * dest_value); + G_END_DECLS #endif /* __GST_MUSEPACK_DEC_H__ */ diff --git a/ext/musepack/gstmusepackreader.c b/ext/musepack/gstmusepackreader.c index 230d7a3c..6595c637 100644 --- a/ext/musepack/gstmusepackreader.c +++ b/ext/musepack/gstmusepackreader.c @@ -29,48 +29,68 @@ static mpc_int32_t gst_musepack_reader_peek (void *this, void *ptr, mpc_int32_t size) { - GstByteStream *bs = this; - guint8 *data; + GstMusepackDec *musepackdec = GST_MUSEPACK_DEC (this); + GstBuffer *buf = NULL; gint read; + if (musepackdec->eos) { + return 0; + } + do { - read = gst_bytestream_peek_bytes (bs, &data, size); + if (GST_FLOW_OK != gst_pad_pull_range (musepackdec->sinkpad, + musepackdec->offset, size, &buf)) { + return 0; + } - if (read != size) { - GstEvent *event; - guint32 remaining; + read = GST_BUFFER_SIZE (buf); - gst_bytestream_get_status (bs, &remaining, &event); - if (!event) { - GST_ELEMENT_ERROR (gst_pad_get_parent (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: - 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 (bs->pad, event); - break; - } + if (musepackdec->eos || + musepackdec->flush_pending || musepackdec->seek_pending) { + break; } + + + /* FIX ME: do i have to handle those event in sink_event? */ + /* we pipeline doesnt stop after receive EOS */ + /* + + if (read != size) { + GstEvent *event; + guint32 remaining; + + gst_bytestream_get_status (bs, &remaining, &event); + if (!event) { + GST_ELEMENT_ERROR (gst_pad_get_parent (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: + 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 (bs->pad, event); + break; + } + } + */ } while (read != size); -done: if (read != 0) { - memcpy (ptr, data, read); + memcpy (ptr, GST_BUFFER_DATA (buf), read); } + gst_buffer_unref (buf); return read; } @@ -78,21 +98,21 @@ done: static mpc_int32_t gst_musepack_reader_read (void *this, void *ptr, mpc_int32_t size) { - GstByteStream *bs = this; + GstMusepackDec *musepackdec = GST_MUSEPACK_DEC (this); gint read; /* read = peek + flush */ if ((read = gst_musepack_reader_peek (this, ptr, size)) > 0) { - gst_bytestream_flush_fast (bs, read); + musepackdec->offset += read; } return read; } -static BOOL +static mpc_bool_t gst_musepack_reader_seek (void *this, mpc_int32_t offset) { - GstByteStream *bs = this; + GstMusepackDec *musepackdec = GST_MUSEPACK_DEC (this); guint8 dummy; /* hacky hack - if we're after typefind, we'll fail because @@ -100,8 +120,7 @@ gst_musepack_reader_seek (void *this, mpc_int32_t offset) gst_musepack_reader_peek (this, &dummy, 1); /* seek */ - if (!gst_bytestream_seek (bs, offset, GST_SEEK_METHOD_SET)) - return FALSE; + musepackdec->offset = offset; /* get discont */ if (gst_musepack_reader_peek (this, &dummy, 1) != 1) @@ -113,29 +132,76 @@ gst_musepack_reader_seek (void *this, mpc_int32_t offset) static mpc_int32_t gst_musepack_reader_tell (void *this) { - GstByteStream *bs = this; + GstMusepackDec *musepackdec = GST_MUSEPACK_DEC (this); + GstQuery *query; + gint64 position; + GstFormat format = GST_FORMAT_BYTES; + + query = gst_query_new_position (GST_FORMAT_BYTES); + if (gst_pad_query (musepackdec->sinkpad, query)) { + + gst_query_parse_position (query, &format, &position); + + if (format != GST_FORMAT_BYTES) { + GstFormat dest_format = GST_FORMAT_BYTES; + + if (!gst_musepackdec_src_convert (musepackdec->srcpad, + format, position, &dest_format, &position)) { + position = -1; + } - return gst_bytestream_tell (bs); + } + + } else { + position = -1; + } + gst_query_unref (query); + + return position; } static mpc_int32_t gst_musepack_reader_get_size (void *this) { - GstByteStream *bs = this; + GstMusepackDec *musepackdec = GST_MUSEPACK_DEC (this); + GstQuery *query; + gint64 duration; + GstFormat format = GST_FORMAT_BYTES; + + query = gst_query_new_duration (GST_FORMAT_BYTES); + if (gst_pad_query (musepackdec->sinkpad, query)) { + + gst_query_parse_duration (query, &format, &duration); + + if (format != GST_FORMAT_BYTES) { + GstFormat dest_format = GST_FORMAT_BYTES; + + if (!gst_musepackdec_src_convert (musepackdec->srcpad, + format, duration, &dest_format, &duration)) { + duration = -1; + } + + } + + } else { + duration = -1; + } + gst_query_unref (query); + - return gst_bytestream_length (bs); + return duration; } -static BOOL +static mpc_bool_t gst_musepack_reader_canseek (void *this) { return TRUE; } void -gst_musepack_init_reader (mpc_reader * r, GstByteStream * bs) +gst_musepack_init_reader (mpc_reader * r, GstMusepackDec * musepackdec) { - r->data = bs; + r->data = musepackdec; r->read = gst_musepack_reader_read; r->seek = gst_musepack_reader_seek; diff --git a/ext/musepack/gstmusepackreader.h b/ext/musepack/gstmusepackreader.h index 2aa2edd2..d5a477cb 100644 --- a/ext/musepack/gstmusepackreader.h +++ b/ext/musepack/gstmusepackreader.h @@ -20,9 +20,10 @@ #ifndef __GST_MUSEPACK_READER_H__ #define __GST_MUSEPACK_READER_H__ -#include <musepack/musepack.h> -#include <gst/bytestream/bytestream.h> +#include <mpcdec/mpcdec.h> +//#include <gst/bytestream/bytestream.h> +#include "gstmusepackdec.h" -void gst_musepack_init_reader (mpc_reader * r, GstByteStream * bs); +void gst_musepack_init_reader (mpc_reader * r, GstMusepackDec * musepackdec); #endif /* __GST_MUSEPACK_READER_H__ */ |