From 9a2735a063036fc0146f66b73efb9be231c492b0 Mon Sep 17 00:00:00 2001 From: Nicolas Dufresne Date: Fri, 28 Sep 2012 11:59:57 -0400 Subject: frei0r: Port to 1.0 https://bugzilla.gnome.org/show_bug.cgi?id=681678 --- configure.ac | 2 +- gst/frei0r/gstfrei0r.c | 17 +-- gst/frei0r/gstfrei0rfilter.c | 25 ++-- gst/frei0r/gstfrei0rmixer.c | 329 ++++++++++++++++++------------------------- gst/frei0r/gstfrei0rmixer.h | 5 +- gst/frei0r/gstfrei0rsrc.c | 139 ++++++++---------- gst/frei0r/gstfrei0rsrc.h | 4 +- 7 files changed, 222 insertions(+), 299 deletions(-) diff --git a/configure.ac b/configure.ac index 562e915db..b53cac8fa 100644 --- a/configure.ac +++ b/configure.ac @@ -313,7 +313,7 @@ dnl Make sure you have a space before and after all plugins GST_PLUGINS_NONPORTED=" aiff \ cdxaparse \ dccp faceoverlay \ - fieldanalysis freeverb frei0r \ + fieldanalysis freeverb \ hdvparse ivfparse jp2kdecimator \ kate librfb \ mpegpsmux mve mxf mythtv nsf nuvdemux \ diff --git a/gst/frei0r/gstfrei0r.c b/gst/frei0r/gstfrei0r.c index 42d62c187..8cd8f1309 100644 --- a/gst/frei0r/gstfrei0r.c +++ b/gst/frei0r/gstfrei0r.c @@ -27,20 +27,17 @@ #include "gstfrei0rmixer.h" #include +#include GST_DEBUG_CATEGORY (frei0r_debug); #define GST_CAT_DEFAULT frei0r_debug -static GstStaticCaps bgra8888_caps = GST_STATIC_CAPS (GST_VIDEO_CAPS_BGRA); -static GstStaticCaps rgba8888_caps = GST_STATIC_CAPS (GST_VIDEO_CAPS_RGBA); -static GstStaticCaps packed32_caps = GST_STATIC_CAPS (GST_VIDEO_CAPS_BGRA " ; " - GST_VIDEO_CAPS_RGBA " ; " - GST_VIDEO_CAPS_ABGR " ; " - GST_VIDEO_CAPS_ARGB " ; " - GST_VIDEO_CAPS_BGRx " ; " - GST_VIDEO_CAPS_RGBx " ; " - GST_VIDEO_CAPS_xBGR " ; " - GST_VIDEO_CAPS_xRGB " ; " GST_VIDEO_CAPS_YUV ("AYUV")); +static GstStaticCaps bgra8888_caps = GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE + ("BGRA")); +static GstStaticCaps rgba8888_caps = GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE + ("RGBA")); +static GstStaticCaps packed32_caps = GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE + ("{ BGRA, RGBA, ABGR, ARGB, BGRx, RGBx, xBGR, xRGB, AYUV }")); GstCaps * gst_frei0r_caps_from_color_model (gint color_model) diff --git a/gst/frei0r/gstfrei0rfilter.c b/gst/frei0r/gstfrei0rfilter.c index c05c1c203..91d2fe484 100644 --- a/gst/frei0r/gstfrei0rfilter.c +++ b/gst/frei0r/gstfrei0rfilter.c @@ -26,8 +26,6 @@ #include "gstfrei0r.h" #include "gstfrei0rfilter.h" -#include - GST_DEBUG_CATEGORY_EXTERN (frei0r_debug); #define GST_CAT_DEFAULT frei0r_debug @@ -42,11 +40,15 @@ gst_frei0r_filter_set_caps (GstBaseTransform * trans, GstCaps * incaps, GstCaps * outcaps) { GstFrei0rFilter *self = GST_FREI0R_FILTER (trans); - GstVideoFormat fmt; + GstVideoInfo info; - if (!gst_video_format_parse_caps (incaps, &fmt, &self->width, &self->height)) + gst_video_info_init (&info); + if (!gst_video_info_from_caps (&info, incaps)) return FALSE; + self->width = info.width; + self->height = info.height; + return TRUE; } @@ -91,6 +93,7 @@ gst_frei0r_filter_transform (GstBaseTransform * trans, GstBuffer * inbuf, GstFrei0rFilter *self = GST_FREI0R_FILTER (trans); GstFrei0rFilterClass *klass = GST_FREI0R_FILTER_GET_CLASS (trans); gdouble time; + GstMapInfo inmap, outmap; if (G_UNLIKELY (self->width <= 0 || self->height <= 0)) return GST_FLOW_NOT_NEGOTIATED; @@ -106,14 +109,20 @@ gst_frei0r_filter_transform (GstBaseTransform * trans, GstBuffer * inbuf, time = ((gdouble) GST_BUFFER_TIMESTAMP (inbuf)) / GST_SECOND; GST_OBJECT_LOCK (self); + + gst_buffer_map (inbuf, &inmap, GST_MAP_READ); + gst_buffer_map (outbuf, &outmap, GST_MAP_WRITE); + if (klass->ftable->update2) klass->ftable->update2 (self->f0r_instance, time, - (const guint32 *) GST_BUFFER_DATA (inbuf), NULL, NULL, - (guint32 *) GST_BUFFER_DATA (outbuf)); + (const guint32 *) inmap.data, NULL, NULL, (guint32 *) outmap.data); else klass->ftable->update (self->f0r_instance, time, - (const guint32 *) GST_BUFFER_DATA (inbuf), - (guint32 *) GST_BUFFER_DATA (outbuf)); + (const guint32 *) inmap.data, (guint32 *) outmap.data); + + gst_buffer_unmap (outbuf, &outmap); + gst_buffer_unmap (inbuf, &inmap); + GST_OBJECT_UNLOCK (self); return GST_FLOW_OK; diff --git a/gst/frei0r/gstfrei0rmixer.c b/gst/frei0r/gstfrei0rmixer.c index 1c5662ed2..490e8edb5 100644 --- a/gst/frei0r/gstfrei0rmixer.c +++ b/gst/frei0r/gstfrei0rmixer.c @@ -26,8 +26,6 @@ #include "gstfrei0r.h" #include "gstfrei0rmixer.h" -#include - GST_DEBUG_CATEGORY_EXTERN (frei0r_debug); #define GST_CAT_DEFAULT frei0r_debug @@ -54,11 +52,10 @@ gst_frei0r_mixer_reset (GstFrei0rMixer * self) self->property_cache = NULL; gst_caps_replace (&self->caps, NULL); - p_ev = &self->newseg_event; + p_ev = &self->segment_event; gst_event_replace (p_ev, NULL); - self->fmt = GST_VIDEO_FORMAT_UNKNOWN; - self->width = self->height = 0; + gst_video_info_init (&self->info); } static void @@ -155,85 +152,74 @@ gst_frei0r_mixer_change_state (GstElement * element, GstStateChange transition) } static GstCaps * -gst_frei0r_mixer_get_caps (GstPad * pad) +gst_frei0r_mixer_query_pad_caps (GstPad * pad, GstPad * skip, GstCaps * filter) +{ + GstCaps *caps; + + if (pad == skip) + return filter; + + caps = gst_pad_peer_query_caps (pad, filter); + + if (caps) + gst_caps_unref (filter); + else + caps = filter; + + return caps; +} + +static GstCaps * +gst_frei0r_mixer_get_caps (GstFrei0rMixer * self, GstPad * pad, + GstCaps * filter) { - GstFrei0rMixer *self = GST_FREI0R_MIXER (gst_pad_get_parent (pad)); GstCaps *caps = NULL; if (self->caps) { caps = gst_caps_ref (self->caps); } else { - GstCaps *tmp, *tmp1; - - tmp = gst_caps_copy (gst_pad_get_pad_template_caps (self->src)); - tmp1 = gst_pad_peer_get_caps (pad); - if (tmp1) { - caps = gst_caps_intersect (tmp, tmp1); - gst_caps_unref (tmp1); - gst_caps_unref (tmp); - } else { - caps = tmp; - } + GstCaps *tmp; - tmp = caps; - tmp1 = gst_pad_peer_get_caps (self->sink0); - if (tmp1) { - caps = gst_caps_intersect (tmp, tmp1); - gst_caps_unref (tmp); - gst_caps_unref (tmp1); - } - - tmp = caps; - tmp1 = gst_pad_peer_get_caps (self->sink1); - if (tmp1) { - caps = gst_caps_intersect (tmp, tmp1); + caps = gst_pad_get_pad_template_caps (self->src); + if (filter) { + tmp = caps; + caps = gst_caps_intersect_full (tmp, filter, GST_CAPS_INTERSECT_FIRST); gst_caps_unref (tmp); - gst_caps_unref (tmp1); } - if (self->sink2) { - tmp = caps; - tmp1 = gst_pad_peer_get_caps (self->sink2); - if (tmp1) { - caps = gst_caps_intersect (tmp, tmp1); - gst_caps_unref (tmp); - gst_caps_unref (tmp1); - } - } + caps = gst_frei0r_mixer_query_pad_caps (self->src, pad, caps); + caps = gst_frei0r_mixer_query_pad_caps (self->sink0, pad, caps); + caps = gst_frei0r_mixer_query_pad_caps (self->sink1, pad, caps); + if (self->sink2) + caps = gst_frei0r_mixer_query_pad_caps (self->sink2, pad, caps); } - gst_object_unref (self); - return caps; } static gboolean -gst_frei0r_mixer_set_caps (GstPad * pad, GstCaps * caps) +gst_frei0r_mixer_set_caps (GstFrei0rMixer * self, GstPad * pad, GstCaps * caps) { - GstFrei0rMixer *self = GST_FREI0R_MIXER (gst_pad_get_parent (pad)); gboolean ret = TRUE; - gst_caps_replace (&self->caps, caps); + if (!self->caps) { + gst_caps_replace (&self->caps, caps); - if (pad != self->src) - ret &= gst_pad_set_caps (self->src, caps); - if (pad != self->sink0) - ret &= gst_pad_set_caps (self->sink0, caps); - if (pad != self->sink1) - ret &= gst_pad_set_caps (self->sink1, caps); - if (pad != self->sink2 && self->sink2) - ret &= gst_pad_set_caps (self->sink2, caps); + ret = gst_pad_set_caps (self->src, caps); - if (ret) { - if (!gst_video_format_parse_caps (caps, &self->fmt, &self->width, - &self->height)) { - ret = FALSE; - goto out; + if (ret) { + GstVideoInfo info; + + gst_video_info_init (&info); + if (!gst_video_info_from_caps (&self->info, caps)) { + ret = FALSE; + } } + } else if (!gst_caps_is_equal (caps, self->caps)) { + if (gst_pad_peer_query_accept_caps (pad, self->caps)) + gst_pad_push_event (pad, gst_event_new_reconfigure ()); + ret = FALSE; } -out: - - gst_object_unref (self); return ret; } @@ -258,7 +244,7 @@ gst_frei0r_mixer_src_query_duration (GstFrei0rMixer * self, GstQuery * query) it = gst_element_iterate_sink_pads (GST_ELEMENT_CAST (self)); while (!done) { GstIteratorResult ires; - gpointer item; + GValue item = { 0 }; ires = gst_iterator_next (it, &item); switch (ires) { @@ -267,11 +253,11 @@ gst_frei0r_mixer_src_query_duration (GstFrei0rMixer * self, GstQuery * query) break; case GST_ITERATOR_OK: { - GstPad *pad = GST_PAD_CAST (item); + GstPad *pad = g_value_get_object (&item); gint64 duration; /* ask sink peer for duration */ - res &= gst_pad_query_peer_duration (pad, &format, &duration); + res &= gst_pad_peer_query_duration (pad, format, &duration); /* take min from all valid return values */ if (res) { /* valid unknown length, stop searching */ @@ -283,7 +269,7 @@ gst_frei0r_mixer_src_query_duration (GstFrei0rMixer * self, GstQuery * query) else if (duration < min) min = duration; } - gst_object_unref (pad); + g_value_reset (&item); break; } case GST_ITERATOR_RESYNC: @@ -296,6 +282,8 @@ gst_frei0r_mixer_src_query_duration (GstFrei0rMixer * self, GstQuery * query) done = TRUE; break; } + + g_value_unset (&item); } gst_iterator_free (it); @@ -329,7 +317,7 @@ gst_frei0r_mixer_src_query_latency (GstFrei0rMixer * self, GstQuery * query) it = gst_element_iterate_sink_pads (GST_ELEMENT_CAST (self)); while (!done) { GstIteratorResult ires; - gpointer item; + GValue item = { 0 }; ires = gst_iterator_next (it, &item); switch (ires) { @@ -338,7 +326,7 @@ gst_frei0r_mixer_src_query_latency (GstFrei0rMixer * self, GstQuery * query) break; case GST_ITERATOR_OK: { - GstPad *pad = GST_PAD_CAST (item); + GstPad *pad = g_value_get_object (&item); GstQuery *peerquery; GstClockTime min_cur, max_cur; gboolean live_cur; @@ -364,7 +352,7 @@ gst_frei0r_mixer_src_query_latency (GstFrei0rMixer * self, GstQuery * query) } gst_query_unref (peerquery); - gst_object_unref (pad); + g_value_reset (&item); break; } case GST_ITERATOR_RESYNC: @@ -379,6 +367,8 @@ gst_frei0r_mixer_src_query_latency (GstFrei0rMixer * self, GstQuery * query) done = TRUE; break; } + + g_value_unset (&item); } gst_iterator_free (it); @@ -394,9 +384,9 @@ gst_frei0r_mixer_src_query_latency (GstFrei0rMixer * self, GstQuery * query) } static gboolean -gst_frei0r_mixer_src_query (GstPad * pad, GstQuery * query) +gst_frei0r_mixer_src_query (GstPad * pad, GstObject * object, GstQuery * query) { - GstFrei0rMixer *self = GST_FREI0R_MIXER (gst_pad_get_parent (pad)); + GstFrei0rMixer *self = GST_FREI0R_MIXER (object); gboolean ret = FALSE; switch (GST_QUERY_TYPE (query)) { @@ -409,68 +399,50 @@ gst_frei0r_mixer_src_query (GstPad * pad, GstQuery * query) case GST_QUERY_LATENCY: ret = gst_frei0r_mixer_src_query_latency (self, query); break; + case GST_QUERY_CAPS: + { + GstCaps *filter, *caps; + gst_query_parse_caps (query, &filter); + caps = gst_frei0r_mixer_get_caps (self, pad, filter); + gst_query_set_caps_result (query, caps); + gst_caps_unref (caps); + break; + } default: - ret = gst_pad_query_default (pad, query); + ret = gst_pad_query_default (pad, GST_OBJECT (self), query); break; } - gst_object_unref (self); - return ret; } static gboolean -gst_frei0r_mixer_sink_query (GstPad * pad, GstQuery * query) +gst_frei0r_mixer_sink_query (GstCollectPads * pads, GstCollectData * cdata, + GstQuery * query, GstFrei0rMixer * self) { - GstFrei0rMixer *self = GST_FREI0R_MIXER (gst_pad_get_parent (pad)); - gboolean ret = gst_pad_query (self->src, query); - - gst_object_unref (self); - - return ret; -} + gboolean ret = TRUE; -static gboolean -forward_event_func (GstPad * pad, GValue * ret, GstEvent * event) -{ - gst_event_ref (event); - GST_LOG_OBJECT (pad, "About to send event %s", GST_EVENT_TYPE_NAME (event)); - if (!gst_pad_push_event (pad, event)) { - g_value_set_boolean (ret, FALSE); - GST_WARNING_OBJECT (pad, "Sending event %p (%s) failed.", - event, GST_EVENT_TYPE_NAME (event)); - } else { - GST_LOG_OBJECT (pad, "Sent event %p (%s).", - event, GST_EVENT_TYPE_NAME (event)); + switch (GST_QUERY_TYPE (query)) { + case GST_QUERY_CAPS: + { + GstCaps *filter, *caps; + gst_query_parse_caps (query, &filter); + caps = gst_frei0r_mixer_get_caps (self, cdata->pad, filter); + gst_query_set_caps_result (query, caps); + gst_caps_unref (caps); + break; + } + default: + ret = gst_collect_pads_query_default (pads, cdata, query, FALSE); + break; } - gst_object_unref (pad); - return TRUE; -} - -static gboolean -forward_event (GstFrei0rMixer * self, GstEvent * event) -{ - GstIterator *it; - GValue vret = { 0 }; - - GST_LOG_OBJECT (self, "Forwarding event %p (%s)", event, - GST_EVENT_TYPE_NAME (event)); - - g_value_init (&vret, G_TYPE_BOOLEAN); - g_value_set_boolean (&vret, TRUE); - it = gst_element_iterate_sink_pads (GST_ELEMENT_CAST (self)); - gst_iterator_fold (it, (GstIteratorFoldFunction) forward_event_func, &vret, - event); - gst_iterator_free (it); - gst_event_unref (event); - - return g_value_get_boolean (&vret); + return ret; } static gboolean -gst_frei0r_mixer_src_event (GstPad * pad, GstEvent * event) +gst_frei0r_mixer_src_event (GstPad * pad, GstObject * object, GstEvent * event) { - GstFrei0rMixer *self = GST_FREI0R_MIXER (gst_pad_get_parent (pad)); + GstFrei0rMixer *self = GST_FREI0R_MIXER (object); gboolean ret = FALSE; switch (GST_EVENT_TYPE (event)) { @@ -495,48 +467,36 @@ gst_frei0r_mixer_src_event (GstPad * pad, GstEvent * event) gst_pad_push_event (self->src, gst_event_new_flush_start ()); } - ret = forward_event (self, event); + ret = gst_pad_event_default (pad, GST_OBJECT (self), event); break; } - case GST_EVENT_NAVIGATION: - /* navigation is rather pointless. */ - ret = FALSE; - break; default: - /* just forward the rest for now */ - ret = forward_event (self, event); + ret = gst_pad_event_default (pad, GST_OBJECT (self), event); break; } - gst_object_unref (self); - return ret; } static gboolean -gst_frei0r_mixer_sink0_event (GstPad * pad, GstEvent * event) +gst_frei0r_mixer_sink_event (GstCollectPads * pads, GstCollectData * cdata, + GstEvent * event, GstFrei0rMixer * self) { - GstFrei0rMixer *self = GST_FREI0R_MIXER (gst_pad_get_parent (pad)); - gboolean ret = FALSE; - GstEvent **p_ev; - - GST_DEBUG ("Got %s event on pad %s:%s", GST_EVENT_TYPE_NAME (event), - GST_DEBUG_PAD_NAME (pad)); + gboolean ret = TRUE; switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_NEWSEGMENT: - p_ev = &self->newseg_event; - gst_event_replace (p_ev, event); + case GST_EVENT_CAPS: + { + GstCaps *caps; + gst_event_parse_caps (event, &caps); + ret = gst_frei0r_mixer_set_caps (self, cdata->pad, caps); + gst_event_unref (event); break; + } default: + ret = gst_collect_pads_event_default (pads, cdata, event, FALSE); break; } - - /* now GstCollectPads can take care of the rest, e.g. EOS */ - ret = self->collect_event (pad, event); - - gst_object_unref (self); - return ret; } @@ -551,28 +511,27 @@ gst_frei0r_mixer_collected (GstCollectPads * pads, GstFrei0rMixer * self) GstClockTime timestamp; gdouble time; GstSegment *segment = NULL; + GstAllocationParams alloc_params = { 0, 31, 0, 0 }; + GstMapInfo outmap, inmap0, inmap1, inmap2; - if (G_UNLIKELY (self->width <= 0 || self->height <= 0)) + if (G_UNLIKELY (self->info.width <= 0 || self->info.height <= 0)) return GST_FLOW_NOT_NEGOTIATED; if (G_UNLIKELY (!self->f0r_instance)) { - self->f0r_instance = - gst_frei0r_instance_construct (klass->ftable, klass->properties, - klass->n_properties, self->property_cache, self->width, self->height); + self->f0r_instance = gst_frei0r_instance_construct (klass->ftable, + klass->properties, klass->n_properties, self->property_cache, + self->info.width, self->info.height); if (G_UNLIKELY (!self->f0r_instance)) return GST_FLOW_ERROR; } - if (self->newseg_event) { - gst_pad_push_event (self->src, self->newseg_event); - self->newseg_event = NULL; + if (self->segment_event) { + gst_pad_push_event (self->src, self->segment_event); + self->segment_event = NULL; } - if ((ret = - gst_pad_alloc_buffer_and_set_caps (self->src, GST_BUFFER_OFFSET_NONE, - gst_video_format_get_size (self->fmt, self->width, self->height), - GST_PAD_CAPS (self->src), &outbuf)) != GST_FLOW_OK) - return ret; + /* FIXME Request an allocator and/or pool */ + outbuf = gst_buffer_new_allocate (NULL, self->info.size, &alloc_params); for (l = pads->data; l; l = l->next) { GstCollectData *cdata = l->data; @@ -590,8 +549,14 @@ gst_frei0r_mixer_collected (GstCollectPads * pads, GstFrei0rMixer * self) if (!inbuf0 || !inbuf1 || (!inbuf2 && self->sink2)) goto eos; + gst_buffer_map (outbuf, &outmap, GST_MAP_READWRITE); + gst_buffer_map (inbuf0, &inmap0, GST_MAP_READ); + gst_buffer_map (inbuf1, &inmap1, GST_MAP_READ); + if (inbuf2) + gst_buffer_map (inbuf2, &inmap2, GST_MAP_READ); + g_assert (segment != NULL); - timestamp = GST_BUFFER_TIMESTAMP (inbuf0); + timestamp = GST_BUFFER_PTS (inbuf0); timestamp = gst_segment_to_stream_time (segment, GST_FORMAT_TIME, timestamp); GST_DEBUG_OBJECT (self, "sync to %" GST_TIME_FORMAT, @@ -600,22 +565,25 @@ gst_frei0r_mixer_collected (GstCollectPads * pads, GstFrei0rMixer * self) if (GST_CLOCK_TIME_IS_VALID (timestamp)) gst_object_sync_values (GST_OBJECT (self), timestamp); - gst_buffer_copy_metadata (outbuf, inbuf0, - GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS); - time = ((gdouble) GST_BUFFER_TIMESTAMP (outbuf)) / GST_SECOND; + gst_buffer_copy_into (outbuf, inbuf0, + GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS, 0, -1); + time = ((gdouble) GST_BUFFER_PTS (outbuf)) / GST_SECOND; GST_OBJECT_LOCK (self); klass->ftable->update2 (self->f0r_instance, time, - (const guint32 *) GST_BUFFER_DATA (inbuf0), - (const guint32 *) GST_BUFFER_DATA (inbuf1), - (inbuf2) ? (const guint32 *) GST_BUFFER_DATA (inbuf2) : NULL, - (guint32 *) GST_BUFFER_DATA (outbuf)); + (const guint32 *) inmap0.data, (const guint32 *) inmap1.data, + (inbuf2) ? (const guint32 *) inmap2.data : NULL, (guint32 *) outmap.data); GST_OBJECT_UNLOCK (self); + gst_buffer_unmap (outbuf, &outmap); gst_buffer_unref (inbuf0); + gst_buffer_unmap (inbuf0, &inmap0); gst_buffer_unref (inbuf1); - if (inbuf2) + gst_buffer_unmap (inbuf1, &inmap1); + if (inbuf2) { + gst_buffer_unmap (inbuf2, &inmap2); gst_buffer_unref (inbuf2); + } ret = gst_pad_push (self->src, outbuf); @@ -634,7 +602,7 @@ eos: gst_buffer_unref (inbuf2); gst_pad_push_event (self->src, gst_event_new_eos ()); - return GST_FLOW_UNEXPECTED; + return GST_FLOW_EOS; } } @@ -675,26 +643,22 @@ gst_frei0r_mixer_class_init (GstFrei0rMixerClass * klass, gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, gst_caps_ref (caps)); gst_element_class_add_pad_template (gstelement_class, templ); - gst_object_unref (templ); templ = gst_pad_template_new ("sink_0", GST_PAD_SINK, GST_PAD_ALWAYS, gst_caps_ref (caps)); gst_element_class_add_pad_template (gstelement_class, templ); - gst_object_unref (templ); templ = gst_pad_template_new ("sink_1", GST_PAD_SINK, GST_PAD_ALWAYS, gst_caps_ref (caps)); gst_element_class_add_pad_template (gstelement_class, templ); - gst_object_unref (templ); if (klass->info->plugin_type == F0R_PLUGIN_TYPE_MIXER3) { templ = gst_pad_template_new ("sink_2", GST_PAD_SINK, GST_PAD_ALWAYS, gst_caps_ref (caps)); gst_element_class_add_pad_template (gstelement_class, templ); - gst_object_unref (templ); } gst_caps_unref (caps); @@ -707,18 +671,19 @@ gst_frei0r_mixer_init (GstFrei0rMixer * self, GstFrei0rMixerClass * klass) { self->property_cache = gst_frei0r_property_cache_init (klass->properties, klass->n_properties); + gst_video_info_init (&self->info); self->collect = gst_collect_pads_new (); gst_collect_pads_set_function (self->collect, (GstCollectPadsFunction) gst_frei0r_mixer_collected, self); + gst_collect_pads_set_event_function (self->collect, + (GstCollectPadsEventFunction) gst_frei0r_mixer_sink_event, self); + gst_collect_pads_set_query_function (self->collect, + (GstCollectPadsQueryFunction) gst_frei0r_mixer_sink_query, self); self->src = gst_pad_new_from_template (gst_element_class_get_pad_template (GST_ELEMENT_CLASS (klass), "src"), "src"); - gst_pad_set_getcaps_function (self->src, - GST_DEBUG_FUNCPTR (gst_frei0r_mixer_get_caps)); - gst_pad_set_setcaps_function (self->src, - GST_DEBUG_FUNCPTR (gst_frei0r_mixer_set_caps)); gst_pad_set_query_function (self->src, GST_DEBUG_FUNCPTR (gst_frei0r_mixer_src_query)); gst_pad_set_event_function (self->src, @@ -728,28 +693,14 @@ gst_frei0r_mixer_init (GstFrei0rMixer * self, GstFrei0rMixerClass * klass) self->sink0 = gst_pad_new_from_template (gst_element_class_get_pad_template (GST_ELEMENT_CLASS (klass), "sink_0"), "sink_0"); - gst_pad_set_getcaps_function (self->sink0, - GST_DEBUG_FUNCPTR (gst_frei0r_mixer_get_caps)); - gst_pad_set_setcaps_function (self->sink0, - GST_DEBUG_FUNCPTR (gst_frei0r_mixer_set_caps)); - gst_pad_set_query_function (self->sink0, - GST_DEBUG_FUNCPTR (gst_frei0r_mixer_sink_query)); gst_collect_pads_add_pad (self->collect, self->sink0, sizeof (GstCollectData), NULL, TRUE); self->collect_event = (GstPadEventFunction) GST_PAD_EVENTFUNC (self->sink0); - gst_pad_set_event_function (self->sink0, - GST_DEBUG_FUNCPTR (gst_frei0r_mixer_sink0_event)); gst_element_add_pad (GST_ELEMENT_CAST (self), self->sink0); self->sink1 = gst_pad_new_from_template (gst_element_class_get_pad_template (GST_ELEMENT_CLASS (klass), "sink_1"), "sink_1"); - gst_pad_set_getcaps_function (self->sink1, - GST_DEBUG_FUNCPTR (gst_frei0r_mixer_get_caps)); - gst_pad_set_setcaps_function (self->sink1, - GST_DEBUG_FUNCPTR (gst_frei0r_mixer_set_caps)); - gst_pad_set_query_function (self->sink0, - GST_DEBUG_FUNCPTR (gst_frei0r_mixer_sink_query)); gst_collect_pads_add_pad (self->collect, self->sink1, sizeof (GstCollectData), NULL, TRUE); gst_element_add_pad (GST_ELEMENT_CAST (self), self->sink1); @@ -758,12 +709,6 @@ gst_frei0r_mixer_init (GstFrei0rMixer * self, GstFrei0rMixerClass * klass) self->sink2 = gst_pad_new_from_template (gst_element_class_get_pad_template (GST_ELEMENT_CLASS (klass), "sink_2"), "sink_2"); - gst_pad_set_getcaps_function (self->sink2, - GST_DEBUG_FUNCPTR (gst_frei0r_mixer_get_caps)); - gst_pad_set_setcaps_function (self->sink2, - GST_DEBUG_FUNCPTR (gst_frei0r_mixer_set_caps)); - gst_pad_set_query_function (self->sink0, - GST_DEBUG_FUNCPTR (gst_frei0r_mixer_sink_query)); gst_collect_pads_add_pad (self->collect, self->sink2, sizeof (GstCollectData), NULL, TRUE); gst_element_add_pad (GST_ELEMENT_CAST (self), self->sink2); diff --git a/gst/frei0r/gstfrei0rmixer.h b/gst/frei0r/gstfrei0rmixer.h index 7cb66005e..dc0ff6c8d 100644 --- a/gst/frei0r/gstfrei0rmixer.h +++ b/gst/frei0r/gstfrei0rmixer.h @@ -47,10 +47,9 @@ struct _GstFrei0rMixer { GstPad *sink0, *sink1, *sink2; GstCaps *caps; - GstVideoFormat fmt; - gint width, height; + GstVideoInfo info; - GstEvent *newseg_event; + GstEvent *segment_event; GstPadEventFunction collect_event; diff --git a/gst/frei0r/gstfrei0rsrc.c b/gst/frei0r/gstfrei0rsrc.c index 64bcc1147..c1d57a9b0 100644 --- a/gst/frei0r/gstfrei0rsrc.c +++ b/gst/frei0r/gstfrei0rsrc.c @@ -26,8 +26,6 @@ #include "gstfrei0r.h" #include "gstfrei0rsrc.h" -#include - GST_DEBUG_CATEGORY_EXTERN (frei0r_debug); #define GST_CAT_DEFAULT frei0r_debug @@ -42,77 +40,44 @@ gst_frei0r_src_set_caps (GstBaseSrc * src, GstCaps * caps) { GstFrei0rSrc *self = GST_FREI0R_SRC (src); - if (!gst_video_format_parse_caps (caps, &self->fmt, &self->width, - &self->height) - || !gst_video_parse_caps_framerate (caps, &self->fps_n, &self->fps_d)) + gst_video_info_init (&self->info); + if (!gst_video_info_from_caps (&self->info, caps)) return FALSE; - return TRUE; -} + gst_base_src_set_blocksize (src, self->info.size); -static GstCaps * -gst_frei0r_src_get_caps (GstBaseSrc * src) -{ - if (GST_PAD_CAPS (GST_BASE_SRC_PAD (src))) - return gst_caps_ref (GST_PAD_CAPS (GST_BASE_SRC_PAD (src))); - else - return - gst_caps_copy (gst_pad_get_pad_template_caps (GST_BASE_SRC_PAD (src))); + return TRUE; } static GstFlowReturn -gst_frei0r_src_create (GstPushSrc * src, GstBuffer ** buf) +gst_frei0r_src_fill (GstPushSrc * src, GstBuffer * buf) { GstFrei0rSrc *self = GST_FREI0R_SRC (src); GstFrei0rSrcClass *klass = GST_FREI0R_SRC_GET_CLASS (src); - guint size, newsize; - GstFlowReturn ret = GST_FLOW_OK; - GstBuffer *outbuf = NULL; GstClockTime timestamp; gdouble time; - - *buf = NULL; - - if (G_UNLIKELY (self->width <= 0 || self->height <= 0)) - return GST_FLOW_NOT_NEGOTIATED; + GstMapInfo map; if (G_UNLIKELY (!self->f0r_instance)) { self->f0r_instance = gst_frei0r_instance_construct (klass->ftable, klass->properties, - klass->n_properties, self->property_cache, self->width, self->height); + klass->n_properties, self->property_cache, self->info.width, + self->info.height); if (G_UNLIKELY (!self->f0r_instance)) return GST_FLOW_ERROR; } - newsize = gst_video_format_get_size (self->fmt, self->width, self->height); - - ret = - gst_pad_alloc_buffer_and_set_caps (GST_BASE_SRC_PAD (src), - GST_BUFFER_OFFSET_NONE, newsize, GST_PAD_CAPS (GST_BASE_SRC_PAD (src)), - &outbuf); - if (ret != GST_FLOW_OK) - return ret; - - /* Format might have changed */ - size = GST_BUFFER_SIZE (outbuf); - newsize = gst_video_format_get_size (self->fmt, self->width, self->height); - - if (size != newsize) { - gst_buffer_unref (outbuf); - outbuf = gst_buffer_new_and_alloc (newsize); - gst_buffer_set_caps (outbuf, GST_PAD_CAPS (GST_BASE_SRC_PAD (src))); - } - - GST_BUFFER_TIMESTAMP (outbuf) = timestamp = - gst_util_uint64_scale (self->n_frames, GST_SECOND * self->fps_d, - self->fps_n); - GST_BUFFER_OFFSET (outbuf) = self->n_frames; + timestamp = + gst_util_uint64_scale (self->n_frames, GST_SECOND * self->info.fps_d, + self->info.fps_n); + GST_BUFFER_PTS (buf) = GST_BUFFER_DTS (buf) = timestamp; + GST_BUFFER_OFFSET (buf) = self->n_frames; self->n_frames++; - GST_BUFFER_OFFSET_END (outbuf) = self->n_frames; - GST_BUFFER_DURATION (outbuf) = - gst_util_uint64_scale (self->n_frames, GST_SECOND * self->fps_d, - self->fps_n) - GST_BUFFER_TIMESTAMP (outbuf); + GST_BUFFER_OFFSET_END (buf) = self->n_frames; + GST_BUFFER_DURATION (buf) = + gst_util_uint64_scale (self->n_frames, GST_SECOND * self->info.fps_d, + self->info.fps_n) - GST_BUFFER_TIMESTAMP (buf); timestamp = gst_segment_to_stream_time (&GST_BASE_SRC_CAST (self)->segment, @@ -124,20 +89,31 @@ gst_frei0r_src_create (GstPushSrc * src, GstBuffer ** buf) if (GST_CLOCK_TIME_IS_VALID (timestamp)) gst_object_sync_values (GST_OBJECT (self), timestamp); - time = ((gdouble) GST_BUFFER_TIMESTAMP (outbuf)) / GST_SECOND; + time = ((gdouble) GST_BUFFER_TIMESTAMP (buf)) / GST_SECOND; GST_OBJECT_LOCK (self); + + if (!gst_buffer_map (buf, &map, GST_MAP_WRITE)) + goto map_error; + if (klass->ftable->update2) klass->ftable->update2 (self->f0r_instance, time, NULL, NULL, NULL, - (guint32 *) GST_BUFFER_DATA (outbuf)); + (guint32 *) map.data); else klass->ftable->update (self->f0r_instance, time, NULL, - (guint32 *) GST_BUFFER_DATA (outbuf)); - GST_OBJECT_UNLOCK (self); + (guint32 *) map.data); - *buf = outbuf; + gst_buffer_unmap (buf, &map); + + GST_OBJECT_UNLOCK (self); return GST_FLOW_OK; + +map_error: + GST_OBJECT_UNLOCK (self); + GST_ELEMENT_ERROR (GST_ELEMENT (src), RESOURCE, WRITE, (NULL), + ("Could not map buffer for writing")); + return GST_FLOW_ERROR; } static gboolean @@ -161,9 +137,7 @@ gst_frei0r_src_stop (GstBaseSrc * basesrc) self->f0r_instance = NULL; } - self->fmt = GST_VIDEO_FORMAT_UNKNOWN; - self->width = self->height = 0; - self->fps_n = self->fps_d = 0; + gst_video_info_init (&self->info); self->n_frames = 0; return TRUE; @@ -182,12 +156,12 @@ gst_frei0r_src_do_seek (GstBaseSrc * bsrc, GstSegment * segment) GstFrei0rSrc *self = GST_FREI0R_SRC (bsrc); segment->time = segment->start; - time = segment->last_stop; + time = segment->position; /* now move to the time indicated */ - if (self->fps_n) { + if (self->info.fps_n) { self->n_frames = gst_util_uint64_scale (time, - self->fps_n, self->fps_d * GST_SECOND); + self->info.fps_n, self->info.fps_d * GST_SECOND); } else { self->n_frames = 0; } @@ -219,9 +193,9 @@ gst_frei0r_src_query (GstBaseSrc * bsrc, GstQuery * query) switch (dest_fmt) { case GST_FORMAT_TIME: /* frames to time */ - if (self->fps_n) { + if (self->info.fps_n) { dest_val = gst_util_uint64_scale (src_val, - self->fps_d * GST_SECOND, self->fps_n); + self->info.fps_d * GST_SECOND, self->info.fps_n); } else { dest_val = 0; } @@ -234,9 +208,9 @@ gst_frei0r_src_query (GstBaseSrc * bsrc, GstQuery * query) switch (dest_fmt) { case GST_FORMAT_DEFAULT: /* time to frames */ - if (self->fps_n) { + if (self->info.fps_n) { dest_val = gst_util_uint64_scale (src_val, - self->fps_n, self->fps_d * GST_SECOND); + self->info.fps_n, self->info.fps_d * GST_SECOND); } else { dest_val = 0; } @@ -268,16 +242,20 @@ error: } } -static void -gst_frei0r_src_src_fixate (GstPad * pad, GstCaps * caps) +static GstCaps * +gst_frei0r_src_fixate (GstBaseSrc * src, GstCaps * caps) { GstStructure *structure; + caps = gst_caps_make_writable (caps); + structure = gst_caps_get_structure (caps, 0); gst_structure_fixate_field_nearest_int (structure, "width", 320); gst_structure_fixate_field_nearest_int (structure, "height", 240); gst_structure_fixate_field_nearest_fraction (structure, "framerate", 30, 1); + + return caps; } static void @@ -367,27 +345,24 @@ gst_frei0r_src_class_init (GstFrei0rSrcClass * klass, templ = gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, caps); gst_element_class_add_pad_template (gstelement_class, templ); - gstbasesrc_class->set_caps = gst_frei0r_src_set_caps; - gstbasesrc_class->get_caps = gst_frei0r_src_get_caps; - gstbasesrc_class->is_seekable = gst_frei0r_src_is_seekable; - gstbasesrc_class->do_seek = gst_frei0r_src_do_seek; - gstbasesrc_class->query = gst_frei0r_src_query; - gstbasesrc_class->start = gst_frei0r_src_start; - gstbasesrc_class->stop = gst_frei0r_src_stop; + gstbasesrc_class->set_caps = GST_DEBUG_FUNCPTR (gst_frei0r_src_set_caps); + gstbasesrc_class->is_seekable = + GST_DEBUG_FUNCPTR (gst_frei0r_src_is_seekable); + gstbasesrc_class->do_seek = GST_DEBUG_FUNCPTR (gst_frei0r_src_do_seek); + gstbasesrc_class->query = GST_DEBUG_FUNCPTR (gst_frei0r_src_query); + gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_frei0r_src_start); + gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_frei0r_src_stop); + gstbasesrc_class->fixate = GST_DEBUG_FUNCPTR (gst_frei0r_src_fixate); - gstpushsrc_class->create = GST_DEBUG_FUNCPTR (gst_frei0r_src_create); + gstpushsrc_class->fill = GST_DEBUG_FUNCPTR (gst_frei0r_src_fill); } static void gst_frei0r_src_init (GstFrei0rSrc * self, GstFrei0rSrcClass * klass) { - GstPad *pad = GST_BASE_SRC_PAD (self); - self->property_cache = gst_frei0r_property_cache_init (klass->properties, klass->n_properties); - - gst_pad_set_fixatecaps_function (pad, gst_frei0r_src_src_fixate); - + gst_video_info_init (&self->info); gst_base_src_set_format (GST_BASE_SRC_CAST (self), GST_FORMAT_TIME); } diff --git a/gst/frei0r/gstfrei0rsrc.h b/gst/frei0r/gstfrei0rsrc.h index cba620ae9..1773495e4 100644 --- a/gst/frei0r/gstfrei0rsrc.h +++ b/gst/frei0r/gstfrei0rsrc.h @@ -45,9 +45,7 @@ struct _GstFrei0rSrc { f0r_instance_t *f0r_instance; GstFrei0rPropertyValue *property_cache; - GstVideoFormat fmt; - gint width, height; - gint fps_n, fps_d; + GstVideoInfo info; guint64 n_frames; }; -- cgit v1.2.3