From 9a43a5236ccbbcb0b73466aba91aa2a0ac5d9897 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Wed, 18 May 2005 09:58:13 +0000 Subject: [PATCH] Ported goom. Original commit message from CVS: * configure.ac: * gst/goom/Makefile.am: * gst/goom/gstgoom.c: (gst_goom_init), (gst_goom_sink_setcaps), (gst_goom_src_setcaps), (gst_goom_src_negotiate), (gst_goom_event), (gst_goom_chain), (gst_goom_change_state), (plugin_init): Ported goom. Added goom and alpha to build. --- ChangeLog | 10 ++ configure.ac | 4 + gst/goom/Makefile.am | 4 +- gst/goom/gstgoom.c | 229 +++++++++++++++++++++++++------------------ 4 files changed, 152 insertions(+), 95 deletions(-) diff --git a/ChangeLog b/ChangeLog index c257fd0c65..b2ecd3a8e3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2005-05-18 Wim Taymans + + * configure.ac: + * gst/goom/Makefile.am: + * gst/goom/gstgoom.c: (gst_goom_init), (gst_goom_sink_setcaps), + (gst_goom_src_setcaps), (gst_goom_src_negotiate), (gst_goom_event), + (gst_goom_chain), (gst_goom_change_state), (plugin_init): + Ported goom. + Added goom and alpha to build. + 2005-05-17 Wim Taymans * configure.ac: diff --git a/configure.ac b/configure.ac index 2a88128523..4d38af192a 100644 --- a/configure.ac +++ b/configure.ac @@ -305,8 +305,10 @@ AC_SUBST(GST_PLUGIN_LDFLAGS) dnl these are all the gst plug-ins, compilable without additional libs GST_PLUGINS_ALL="\ + alpha \ videofilter \ effectv \ + goom \ law \ rtp \ rtsp \ @@ -489,7 +491,9 @@ AC_CONFIG_FILES( Makefile gst-plugins.spec gst/Makefile +gst/alpha/Makefile gst/effectv/Makefile +gst/goom/Makefile gst/law/Makefile gst/rtp/Makefile gst/rtsp/Makefile diff --git a/gst/goom/Makefile.am b/gst/goom/Makefile.am index d71229f87d..8ddb8b8aa3 100644 --- a/gst/goom/Makefile.am +++ b/gst/goom/Makefile.am @@ -8,9 +8,9 @@ libgstgoom_la_SOURCES = gstgoom.c goom_core.c $(GOOM_FILTER_FILES) graphic.c lin noinst_HEADERS = filters.h goom_core.h goom_tools.h graphic.h lines.h -libgstgoom_la_CFLAGS = $(GST_CFLAGS) $(GOOM_FILTER_CFLAGS) +libgstgoom_la_CFLAGS = $(GST_CFLAGS) $(GOOM_FILTER_CFLAGS) $(GST_PLUGINS_LIBS_CFLAGS) libgstgoom_la_LIBADD = -libgstgoom_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) +libgstgoom_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) $(GST_BASE_LIBS) EXTRA_DIST = filters.c diff --git a/gst/goom/gstgoom.c b/gst/goom/gstgoom.c index e645161da3..619859079c 100644 --- a/gst/goom/gstgoom.c +++ b/gst/goom/gstgoom.c @@ -62,7 +62,6 @@ struct _GstGOOM gint width; gint height; gint channels; - gboolean srcnegotiated; gboolean disposed; }; @@ -121,13 +120,10 @@ static void gst_goom_dispose (GObject * object); static GstElementStateReturn gst_goom_change_state (GstElement * element); -static void gst_goom_chain (GstPad * pad, GstData * _data); +static GstFlowReturn gst_goom_chain (GstPad * pad, GstBuffer * buffer); -static GstPadLinkReturn gst_goom_sinkconnect (GstPad * pad, - const GstCaps * caps); -static GstPadLinkReturn gst_goom_srcconnect (GstPad * pad, - const GstCaps * caps); -static GstCaps *gst_goom_src_fixate (GstPad * pad, const GstCaps * caps); +static GstPadLinkReturn gst_goom_sink_setcaps (GstPad * pad, GstCaps * caps); +static GstPadLinkReturn gst_goom_src_setcaps (GstPad * pad, GstCaps * caps); static GstElementClass *parent_class = NULL; @@ -197,13 +193,9 @@ gst_goom_init (GstGOOM * goom) gst_element_add_pad (GST_ELEMENT (goom), goom->sinkpad); gst_element_add_pad (GST_ELEMENT (goom), goom->srcpad); - GST_FLAG_SET (goom, GST_ELEMENT_EVENT_AWARE); - gst_pad_set_chain_function (goom->sinkpad, gst_goom_chain); - gst_pad_set_link_function (goom->sinkpad, gst_goom_sinkconnect); - - gst_pad_set_link_function (goom->srcpad, gst_goom_srcconnect); - gst_pad_set_fixate_function (goom->srcpad, gst_goom_src_fixate); + gst_pad_set_setcaps_function (goom->sinkpad, gst_goom_sink_setcaps); + gst_pad_set_setcaps_function (goom->srcpad, gst_goom_src_setcaps); goom->adapter = gst_adapter_new (); @@ -216,8 +208,7 @@ gst_goom_init (GstGOOM * goom) goom->samples_consumed = 0; goom->disposed = FALSE; - /* set to something */ - goom_init (50, 50); + goom_init (goom->width, goom->height); } static void @@ -236,28 +227,29 @@ gst_goom_dispose (GObject * object) G_OBJECT_CLASS (parent_class)->dispose (object); } -static GstPadLinkReturn -gst_goom_sinkconnect (GstPad * pad, const GstCaps * caps) +static gboolean +gst_goom_sink_setcaps (GstPad * pad, GstCaps * caps) { GstGOOM *goom; GstStructure *structure; - goom = GST_GOOM (gst_pad_get_parent (pad)); + goom = GST_GOOM (GST_PAD_PARENT (pad)); structure = gst_caps_get_structure (caps, 0); gst_structure_get_int (structure, "channels", &goom->channels); gst_structure_get_int (structure, "rate", &goom->sample_rate); - return GST_PAD_LINK_OK; + + return TRUE; } -static GstPadLinkReturn -gst_goom_srcconnect (GstPad * pad, const GstCaps * caps) +static gboolean +gst_goom_src_setcaps (GstPad * pad, GstCaps * caps) { GstGOOM *goom; GstStructure *structure; - goom = GST_GOOM (gst_pad_get_parent (pad)); + goom = GST_GOOM (GST_PAD_PARENT (pad)); structure = gst_caps_get_structure (caps, 0); @@ -266,81 +258,93 @@ gst_goom_srcconnect (GstPad * pad, const GstCaps * caps) gst_structure_get_double (structure, "framerate", &goom->fps); goom_set_resolution (goom->width, goom->height); - goom->srcnegotiated = TRUE; - return GST_PAD_LINK_OK; + return TRUE; } -static GstCaps * -gst_goom_src_fixate (GstPad * pad, const GstCaps * caps) +static gboolean +gst_goom_src_negotiate (GstGOOM * goom) { - GstCaps *newcaps; + GstCaps *othercaps, *target, *intersect; GstStructure *structure; + const GstCaps *templ; - if (!gst_caps_is_simple (caps)) - return NULL; + templ = gst_pad_get_pad_template_caps (goom->srcpad); - newcaps = gst_caps_copy (caps); - structure = gst_caps_get_structure (newcaps, 0); + /* see what the peer can do */ + othercaps = gst_pad_peer_get_caps (goom->srcpad); + if (othercaps) { + intersect = gst_caps_intersect (othercaps, templ); + gst_caps_unref (othercaps); - if (gst_caps_structure_fixate_field_nearest_int (structure, "width", 320)) { - return newcaps; - } - if (gst_caps_structure_fixate_field_nearest_int (structure, "height", 240)) { - return newcaps; - } - if (gst_caps_structure_fixate_field_nearest_double (structure, "framerate", - 30.0)) { - return newcaps; + if (gst_caps_is_empty (intersect)) + goto no_format; + + target = gst_caps_copy_nth (intersect, 0); + gst_caps_unref (intersect); + } else { + target = gst_caps_ref ((GstCaps *) templ); } - /* failed to fixate */ - gst_caps_free (newcaps); - return NULL; + structure = gst_caps_get_structure (target, 0); + gst_caps_structure_fixate_field_nearest_int (structure, "width", 320); + gst_caps_structure_fixate_field_nearest_int (structure, "height", 240); + gst_caps_structure_fixate_field_nearest_double (structure, "framerate", 30.0); + + gst_pad_set_caps (goom->srcpad, target); + gst_caps_unref (target); + + return TRUE; + +no_format: + { + gst_caps_unref (intersect); + gst_caps_unref (othercaps); + return FALSE; + } } -static void -gst_goom_chain (GstPad * pad, GstData * _data) +static gboolean +gst_goom_event (GstPad * pad, GstEvent * event) +{ + gboolean res; + GstGOOM *goom; + + goom = GST_GOOM (GST_PAD_PARENT (pad)); + + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_DISCONTINUOUS: + { + gint64 start = 0, stop = 0; + + gst_event_discont_get_value (event, GST_FORMAT_TIME, &start, &stop); + gst_adapter_clear (goom->adapter); + goom->audio_basetime = start; + goom->samples_consumed = 0; + GST_DEBUG ("Got discont. Adjusting time to=%" G_GUINT64_FORMAT, start); + } + default: + res = gst_pad_event_default (pad, event); + break; + } + return res; +} + +static GstFlowReturn +gst_goom_chain (GstPad * pad, GstBuffer * bufin) { - GstBuffer *bufin = GST_BUFFER (_data); GstGOOM *goom; guint32 bytesperread; gint16 *data; gint samples_per_frame; + GstFlowReturn ret; - goom = GST_GOOM (gst_pad_get_parent (pad)); - if (GST_IS_EVENT (bufin)) { - GstEvent *event = GST_EVENT (bufin); + goom = GST_GOOM (GST_PAD_PARENT (pad)); - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_DISCONTINUOUS: - { - gint64 value = 0; + GST_STREAM_LOCK (pad); - gst_event_discont_get_value (event, GST_FORMAT_TIME, &value); - gst_adapter_clear (goom->adapter); - goom->audio_basetime = value; - goom->samples_consumed = 0; - GST_DEBUG ("Got discont. Adjusting time to=%" G_GUINT64_FORMAT, value); - } - default: - gst_pad_event_default (pad, event); - break; - } - return; - } - - if (goom->channels == 0) { - GST_ELEMENT_ERROR (goom, CORE, NEGOTIATION, (NULL), - ("Format wasn't negotiated before chain function")); - gst_buffer_unref (bufin); - return; - } - - if (!GST_PAD_IS_USABLE (goom->srcpad)) { - gst_buffer_unref (bufin); - return; - } + if (goom->channels == 0) + goto not_negotiated; if (goom->audio_basetime == GST_CLOCK_TIME_NONE) goom->audio_basetime = GST_BUFFER_TIMESTAMP (bufin); @@ -358,16 +362,25 @@ gst_goom_chain (GstPad * pad, GstData * _data) GST_BUFFER_SIZE (bufin) * sizeof (gint16) * goom->channels, GST_BUFFER_TIMESTAMP (bufin)); + ret = GST_FLOW_OK; + + if (GST_RPAD_CAPS (goom->srcpad) == NULL) { + if (!gst_goom_src_negotiate (goom)) + goto no_format; + } + /* Collect samples until we have enough for an output frame */ while (gst_adapter_available (goom->adapter) > MAX (bytesperread, samples_per_frame * goom->channels * sizeof (gint16))) { - const guint16 *data = - (const guint16 *) gst_adapter_peek (goom->adapter, bytesperread); + const guint16 *data; GstBuffer *bufout; guchar *out_frame; - GstClockTimeDiff frame_duration = GST_SECOND / goom->fps; + GstClockTimeDiff frame_duration; gint i; + frame_duration = GST_SECOND / goom->fps; + data = (const guint16 *) gst_adapter_peek (goom->adapter, bytesperread); + if (goom->channels == 2) { for (i = 0; i < GOOM_SAMPLES; i++) { goom->datain[0][i] = *data++; @@ -380,7 +393,8 @@ gst_goom_chain (GstPad * pad, GstData * _data) } } - bufout = gst_buffer_new_and_alloc (goom->width * goom->height * 4); + bufout = gst_pad_alloc_buffer (goom->srcpad, GST_BUFFER_OFFSET_NONE, + goom->width * goom->height * 4, GST_RPAD_CAPS (goom->srcpad)); GST_BUFFER_TIMESTAMP (bufout) = goom->audio_basetime + (GST_SECOND * goom->samples_consumed / goom->sample_rate); @@ -393,11 +407,35 @@ gst_goom_chain (GstPad * pad, GstData * _data) GST_DEBUG ("Pushing frame with time=%" G_GUINT64_FORMAT ", duration=%" G_GUINT64_FORMAT, GST_BUFFER_TIMESTAMP (bufout), GST_BUFFER_DURATION (bufout)); - gst_pad_push (goom->srcpad, GST_DATA (bufout)); + ret = gst_pad_push (goom->srcpad, bufout); goom->samples_consumed += samples_per_frame; gst_adapter_flush (goom->adapter, samples_per_frame * goom->channels * sizeof (gint16)); + + if (ret != GST_FLOW_OK) + break; + } + GST_STREAM_UNLOCK (pad); + + return ret; + + /* ERRORS */ +not_negotiated: + { + GST_ELEMENT_ERROR (goom, CORE, NEGOTIATION, (NULL), + ("Format wasn't negotiated before chain function")); + gst_buffer_unref (bufin); + GST_STREAM_UNLOCK (pad); + return GST_FLOW_NOT_NEGOTIATED; + } +no_format: + { + GST_ELEMENT_ERROR (goom, CORE, NEGOTIATION, (NULL), + ("Could not negotiate format")); + gst_buffer_unref (bufin); + GST_STREAM_UNLOCK (pad); + return GST_FLOW_ERROR; } } @@ -405,35 +443,40 @@ static GstElementStateReturn gst_goom_change_state (GstElement * element) { GstGOOM *goom = GST_GOOM (element); + gint transition; + GstElementStateReturn ret; - switch (GST_STATE_TRANSITION (element)) { + transition = GST_STATE_TRANSITION (element); + + switch (transition) { case GST_STATE_NULL_TO_READY: break; - case GST_STATE_READY_TO_NULL: - break; case GST_STATE_READY_TO_PAUSED: goom->audio_basetime = GST_CLOCK_TIME_NONE; - goom->srcnegotiated = FALSE; gst_adapter_clear (goom->adapter); - break; - case GST_STATE_PAUSED_TO_READY: goom->channels = 0; break; default: break; } - if (GST_ELEMENT_CLASS (parent_class)->change_state) - return GST_ELEMENT_CLASS (parent_class)->change_state (element); + ret = GST_ELEMENT_CLASS (parent_class)->change_state (element); - return GST_STATE_SUCCESS; + switch (transition) { + case GST_STATE_PAUSED_TO_READY: + break; + case GST_STATE_READY_TO_NULL: + break; + default: + break; + } + + return ret; } static gboolean plugin_init (GstPlugin * plugin) { - if (!gst_library_load ("gstbytestream")) - return FALSE; return gst_element_register (plugin, "goom", GST_RANK_NONE, GST_TYPE_GOOM); }