frei0r: Port to 1.0
authorNicolas Dufresne <nicolas.dufresne@collabora.com>
Fri, 28 Sep 2012 15:59:57 +0000 (11:59 -0400)
committerOlivier CrĂȘte <olivier.crete@collabora.com>
Fri, 28 Sep 2012 19:24:45 +0000 (15:24 -0400)
https://bugzilla.gnome.org/show_bug.cgi?id=681678

configure.ac
gst/frei0r/gstfrei0r.c
gst/frei0r/gstfrei0rfilter.c
gst/frei0r/gstfrei0rmixer.c
gst/frei0r/gstfrei0rmixer.h
gst/frei0r/gstfrei0rsrc.c
gst/frei0r/gstfrei0rsrc.h

index 562e915..b53cac8 100644 (file)
@@ -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 \
index 42d62c1..8cd8f13 100644 (file)
 #include "gstfrei0rmixer.h"
 
 #include <string.h>
+#include <gmodule.h>
 
 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)
index c05c1c2..91d2fe4 100644 (file)
@@ -26,8 +26,6 @@
 #include "gstfrei0r.h"
 #include "gstfrei0rfilter.h"
 
-#include <gst/controller/gstcontroller.h>
-
 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;
index 1c5662e..490e8ed 100644 (file)
@@ -26,8 +26,6 @@
 #include "gstfrei0r.h"
 #include "gstfrei0rmixer.h"
 
-#include <gst/controller/gstcontroller.h>
-
 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);
index 7cb6600..dc0ff6c 100644 (file)
@@ -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;
 
index 64bcc11..c1d57a9 100644 (file)
@@ -26,8 +26,6 @@
 #include "gstfrei0r.h"
 #include "gstfrei0rsrc.h"
 
-#include <gst/controller/gstcontroller.h>
-
 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);
 }
 
index cba620a..1773495 100644 (file)
@@ -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;
 };