From: Wim Taymans Date: Fri, 6 May 2005 17:24:44 +0000 (+0000) Subject: Ported sidplay. X-Git-Tag: 1.19.3~505^2~2402 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=9c1aaafba425434822d18be71a19eb1a862a3279;p=platform%2Fupstream%2Fgstreamer.git Ported sidplay. Original commit message from CVS: * configure.ac: * ext/sidplay/gstsiddec.cc: * ext/sidplay/gstsiddec.h: Ported sidplay. --- diff --git a/ChangeLog b/ChangeLog index e24c0e1..8a5bfbc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2005-05-06 Wim Taymans + + * configure.ac: + * ext/sidplay/gstsiddec.cc: + * ext/sidplay/gstsiddec.h: + Ported sidplay. + 2005-05-06 Christian Schaller * configure.ac: diff --git a/configure.ac b/configure.ac index cac2e30..9ce7b32 100644 --- a/configure.ac +++ b/configure.ac @@ -295,7 +295,8 @@ dnl these are all the gst plug-ins, compilable without additional libs GST_PLUGINS_ALL="\ videofilter \ effectv \ - law" + law \ + sidplay" dnl see if we can build C++ plug-ins if test "x$HAVE_CXX" = "xyes"; then @@ -348,6 +349,12 @@ dnl ]) dnl ]) dnl ]) +dnl *** sidplay : works with libsidplay 1.36.x (not 2.x.x) *** +translit(dnm, m, l) AM_CONDITIONAL(USE_SIDPLAY, true) +GST_CHECK_FEATURE(SIDPLAY, [sidplay plug-in], sidplay, [ + GST_PATH_SIDPLAY() + ]) + dnl *** mad *** dnl FIXME: we could use header checks here as well IMO translit(dnm, m, l) AM_CONDITIONAL(USE_MAD, true) @@ -431,6 +438,7 @@ gst/videofilter/Makefile sys/Makefile ext/Makefile ext/mad/Makefile +ext/sidplay/Makefile common/Makefile common/m4/Makefile m4/Makefile diff --git a/ext/sidplay/gstsiddec.cc b/ext/sidplay/gstsiddec.cc index b07e906..98fac6f 100644 --- a/ext/sidplay/gstsiddec.cc +++ b/ext/sidplay/gstsiddec.cc @@ -68,12 +68,6 @@ static GstStaticPadTemplate src_templ = GST_STATIC_PAD_TEMPLATE ("src", "rate = (int) [ 8000, 48000 ], " "channels = (int) [ 1, 2 ]") ); -enum -{ - SID_STATE_NEED_TUNE = 1, - SID_STATE_LOAD_TUNE = 2, - SID_STATE_PLAY_TUNE = 3 -}; #define GST_TYPE_SID_CLOCK (gst_sid_clock_get_type()) static GType @@ -114,7 +108,8 @@ static void gst_siddec_base_init (gpointer g_class); static void gst_siddec_class_init (GstSidDec * klass); static void gst_siddec_init (GstSidDec * siddec); -static void gst_siddec_loop (GstElement * element); +static GstFlowReturn gst_siddec_chain (GstPad * pad, GstBuffer * buffer); +static gboolean gst_siddec_sink_event (GstPad * pad, GstEvent * event); static gboolean gst_siddec_src_convert (GstPad * pad, GstFormat src_format, gint64 src_value, GstFormat * dest_format, gint64 * dest_value); @@ -187,6 +182,9 @@ gst_siddec_class_init (GstSidDec * klass) parent_class = GST_ELEMENT_CLASS (g_type_class_ref (GST_TYPE_ELEMENT)); + gobject_class->set_property = gst_siddec_set_property; + gobject_class->get_property = gst_siddec_get_property; + g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_TUNE, g_param_spec_int ("tune", "tune", "tune", 1, 100, 1, (GParamFlags) G_PARAM_READWRITE)); @@ -216,9 +214,6 @@ gst_siddec_class_init (GstSidDec * klass) g_object_class_install_property (gobject_class, ARG_METADATA, g_param_spec_boxed ("metadata", "Metadata", "Metadata", GST_TYPE_CAPS, (GParamFlags) G_PARAM_READABLE)); - - gobject_class->set_property = gst_siddec_set_property; - gobject_class->get_property = gst_siddec_get_property; } static void @@ -227,9 +222,11 @@ gst_siddec_init (GstSidDec * siddec) siddec->sinkpad = gst_pad_new_from_template (gst_static_pad_template_get (&sink_templ), "sink"); - gst_element_add_pad (GST_ELEMENT (siddec), siddec->sinkpad); gst_pad_set_query_function (siddec->sinkpad, NULL); gst_pad_set_convert_function (siddec->sinkpad, NULL); + gst_pad_set_event_function (siddec->sinkpad, gst_siddec_sink_event); + gst_pad_set_chain_function (siddec->sinkpad, gst_siddec_chain); + gst_element_add_pad (GST_ELEMENT (siddec), siddec->sinkpad); siddec->srcpad = gst_pad_new_from_template (gst_static_pad_template_get (&src_templ), @@ -239,8 +236,6 @@ gst_siddec_init (GstSidDec * siddec) gst_pad_set_query_function (siddec->srcpad, gst_siddec_src_query); gst_element_add_pad (GST_ELEMENT (siddec), siddec->srcpad); - gst_element_set_loop_function (GST_ELEMENT (siddec), gst_siddec_loop); - siddec->engine = new emuEngine (); siddec->tune = new sidTune (0); siddec->config = (emuConfig *) g_malloc (sizeof (emuConfig)); @@ -267,7 +262,6 @@ gst_siddec_init (GstSidDec * siddec) siddec->engine->setConfig (*siddec->config); siddec->engine->setDefaultFilterStrength (); - siddec->state = SID_STATE_NEED_TUNE; siddec->tune_buffer = (guchar *) g_malloc (maxSidtuneFileLen); siddec->tune_len = 0; siddec->tune_number = 1; @@ -358,16 +352,14 @@ siddec_negotiate (GstSidDec * siddec) siddec->config->sampleFormat = (sign ? SIDEMU_SIGNED_PCM : SIDEMU_UNSIGNED_PCM); - if (!gst_pad_try_set_caps (siddec->srcpad, - gst_caps_new_simple ("audio/x-raw-int", - "endianness", G_TYPE_INT, G_BYTE_ORDER, - "signed", G_TYPE_BOOLEAN, sign, - "width", G_TYPE_INT, siddec->config->bitsPerSample, - "depth", G_TYPE_INT, siddec->config->bitsPerSample, - "rate", G_TYPE_INT, siddec->config->frequency, - "channels", G_TYPE_INT, siddec->config->channels, NULL))) { - return FALSE; - } + gst_pad_set_caps (siddec->srcpad, + gst_caps_new_simple ("audio/x-raw-int", + "endianness", G_TYPE_INT, G_BYTE_ORDER, + "signed", G_TYPE_BOOLEAN, sign, + "width", G_TYPE_INT, siddec->config->bitsPerSample, + "depth", G_TYPE_INT, siddec->config->bitsPerSample, + "rate", G_TYPE_INT, siddec->config->frequency, + "channels", G_TYPE_INT, siddec->config->channels, NULL)); siddec->engine->setConfig (*siddec->config); @@ -375,97 +367,159 @@ siddec_negotiate (GstSidDec * siddec) } static void -gst_siddec_loop (GstElement * element) +play_loop (GstPad * pad) { + GstFlowReturn ret; GstSidDec *siddec; + GstBuffer *out; + GstFormat format; + gint64 value, offset, time; - siddec = GST_SIDDEC (element); + siddec = GST_SIDDEC (GST_PAD_PARENT (pad)); - if (siddec->state == SID_STATE_NEED_TUNE) { - GstData *data = gst_pad_pull (siddec->sinkpad); + GST_STREAM_LOCK (pad); + out = gst_buffer_new_and_alloc (siddec->blocksize); + gst_buffer_set_caps (out, GST_PAD_CAPS (pad)); - g_assert (data != NULL); + sidEmuFillBuffer (*siddec->engine, *siddec->tune, + GST_BUFFER_DATA (out), GST_BUFFER_SIZE (out)); - if (GST_IS_EVENT (data)) { - GstEvent *event = GST_EVENT (data); + /* get offset in samples */ + format = GST_FORMAT_DEFAULT; + gst_siddec_src_query (siddec->srcpad, GST_QUERY_POSITION, &format, &offset); + GST_BUFFER_OFFSET (out) = offset; - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_EOS: - siddec->state = SID_STATE_LOAD_TUNE; - break; - case GST_EVENT_DISCONTINUOUS: - break; - default: - // bail out, we're not going to do anything - gst_event_unref (event); - gst_pad_send_event (siddec->srcpad, gst_event_new (GST_EVENT_EOS)); - gst_element_set_eos (element); - return; - } - gst_event_unref (event); - } else { - GstBuffer *buf = GST_BUFFER (data); + /* get current timestamp */ + format = GST_FORMAT_TIME; + gst_siddec_src_query (siddec->srcpad, GST_QUERY_POSITION, &format, &time); + GST_BUFFER_TIMESTAMP (out) = time; - memcpy (siddec->tune_buffer + siddec->tune_len, GST_BUFFER_DATA (buf), - GST_BUFFER_SIZE (buf)); - siddec->tune_len += GST_BUFFER_SIZE (buf); + /* update position and get new timestamp to calculate duration */ + siddec->total_bytes += siddec->blocksize; - gst_buffer_unref (buf); - } + /* get offset in samples */ + format = GST_FORMAT_DEFAULT; + gst_siddec_src_query (siddec->srcpad, GST_QUERY_POSITION, &format, &value); + GST_BUFFER_OFFSET_END (out) = value; + + format = GST_FORMAT_TIME; + gst_siddec_src_query (siddec->srcpad, GST_QUERY_POSITION, &format, &value); + GST_BUFFER_DURATION (out) = value - time; + + if ((ret = gst_pad_push (siddec->srcpad, out)) != GST_FLOW_OK) + goto pause; + + GST_STREAM_UNLOCK (pad); + + return; + +pause: + { + gst_task_pause (GST_RPAD_TASK (pad)); + GST_STREAM_UNLOCK (pad); } - if (siddec->state == SID_STATE_LOAD_TUNE) { - if (!siddec->tune->load (siddec->tune_buffer, siddec->tune_len)) { - GST_ELEMENT_ERROR (siddec, LIBRARY, TOO_LAZY, (NULL), (NULL)); - return; - } - //update_metadata (siddec); +} - if (!siddec_negotiate (siddec)) { - GST_ELEMENT_ERROR (siddec, CORE, NEGOTIATION, (NULL), (NULL)); - return; - } +static gboolean +start_play_tune (GstSidDec * siddec) +{ + gboolean res; - if (!sidEmuInitializeSong (*siddec->engine, *siddec->tune, - siddec->tune_number)) { - GST_ELEMENT_ERROR (siddec, LIBRARY, TOO_LAZY, (NULL), (NULL)); - return; - } + if (!siddec->tune->load (siddec->tune_buffer, siddec->tune_len)) + goto could_not_load; - siddec->state = SID_STATE_PLAY_TUNE; + //update_metadata (siddec); + + if (!siddec_negotiate (siddec)) + goto could_not_negotiate; + + if (!sidEmuInitializeSong (*siddec->engine, *siddec->tune, + siddec->tune_number)) + goto could_not_init; + + if (GST_ELEMENT_SCHEDULER (siddec)) { + GST_STREAM_LOCK (siddec->srcpad); + GST_RPAD_TASK (siddec->srcpad) = + gst_scheduler_create_task (GST_ELEMENT_SCHEDULER (siddec), + (GstTaskFunction) play_loop, siddec->srcpad); + + gst_task_start (GST_RPAD_TASK (siddec->srcpad)); + GST_STREAM_UNLOCK (siddec->srcpad); + res = TRUE; + } + return res; + + /* ERRORS */ +could_not_load: + { + GST_ELEMENT_ERROR (siddec, LIBRARY, TOO_LAZY, (NULL), (NULL)); + return FALSE; + } +could_not_negotiate: + { + GST_ELEMENT_ERROR (siddec, CORE, NEGOTIATION, (NULL), (NULL)); + return FALSE; + } +could_not_init: + { + GST_ELEMENT_ERROR (siddec, LIBRARY, TOO_LAZY, (NULL), (NULL)); + return FALSE; + } +} + +static gboolean +gst_siddec_sink_event (GstPad * pad, GstEvent * event) +{ + GstSidDec *siddec; + gboolean res; + + siddec = GST_SIDDEC (GST_PAD_PARENT (pad)); + + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_EOS: + GST_STREAM_LOCK (pad); + res = start_play_tune (siddec); + GST_STREAM_UNLOCK (pad); + break; + case GST_EVENT_DISCONTINUOUS: + res = FALSE; + break; + default: + res = FALSE; + break; } - if (siddec->state == SID_STATE_PLAY_TUNE) { - GstBuffer *out; - GstFormat format; - gint64 value, offset, time; + gst_event_unref (event); + + return res; +} + +static GstFlowReturn +gst_siddec_chain (GstPad * pad, GstBuffer * buffer) +{ + GstSidDec *siddec; + guint64 size; - out = gst_buffer_new_and_alloc (siddec->blocksize); + siddec = GST_SIDDEC (GST_PAD_PARENT (pad)); - sidEmuFillBuffer (*siddec->engine, *siddec->tune, - GST_BUFFER_DATA (out), GST_BUFFER_SIZE (out)); + size = GST_BUFFER_SIZE (buffer); + if (siddec->tune_len + size > maxSidtuneFileLen) + goto overflow; - /* get offset in samples */ - format = GST_FORMAT_DEFAULT; - gst_siddec_src_query (siddec->srcpad, GST_QUERY_POSITION, &format, &offset); - GST_BUFFER_OFFSET (out) = offset; + GST_STREAM_LOCK (pad); - /* get current timestamp */ - format = GST_FORMAT_TIME; - gst_siddec_src_query (siddec->srcpad, GST_QUERY_POSITION, &format, &time); - GST_BUFFER_TIMESTAMP (out) = time; + memcpy (siddec->tune_buffer + siddec->tune_len, GST_BUFFER_DATA (buffer), + size); + siddec->tune_len += size; - /* update position and get new timestamp to calculate duration */ - siddec->total_bytes += siddec->blocksize; + GST_STREAM_UNLOCK (pad); - /* get offset in samples */ - format = GST_FORMAT_DEFAULT; - gst_siddec_src_query (siddec->srcpad, GST_QUERY_POSITION, &format, &value); - GST_BUFFER_OFFSET_END (out) = value; + gst_buffer_unref (buffer); - format = GST_FORMAT_TIME; - gst_siddec_src_query (siddec->srcpad, GST_QUERY_POSITION, &format, &value); - GST_BUFFER_DURATION (out) = value - time; + return GST_FLOW_OK; - gst_pad_push (siddec->srcpad, GST_DATA (out)); +overflow: + { + return GST_FLOW_ERROR; } } @@ -478,7 +532,7 @@ gst_siddec_src_convert (GstPad * pad, GstFormat src_format, gint64 src_value, GstSidDec *siddec; gint bytes_per_sample; - siddec = GST_SIDDEC (gst_pad_get_parent (pad)); + siddec = GST_SIDDEC (GST_PAD_PARENT (pad)); bytes_per_sample = (siddec->config->bitsPerSample >> 3) * siddec->config->channels; @@ -545,7 +599,7 @@ gst_siddec_src_query (GstPad * pad, GstQueryType type, gboolean res = TRUE; GstSidDec *siddec; - siddec = GST_SIDDEC (gst_pad_get_parent (pad)); + siddec = GST_SIDDEC (GST_PAD_PARENT (pad)); switch (type) { case GST_QUERY_POSITION: diff --git a/ext/sidplay/gstsiddec.h b/ext/sidplay/gstsiddec.h index a878909..1492591 100644 --- a/ext/sidplay/gstsiddec.h +++ b/ext/sidplay/gstsiddec.h @@ -50,7 +50,6 @@ struct _GstSidDec { GstPad *sinkpad, *srcpad; - gint state; guchar *tune_buffer; gint tune_len; gint tune_number;