identity: fixes to the eos-after and error-after properties
[platform/upstream/gstreamer.git] / plugins / elements / gstfakesink.c
index b3ad39b..b71f20f 100644 (file)
  *
  * You should have received a copy of the GNU Library General Public
  * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
  */
 /**
  * SECTION:element-fakesink
+ * @title: fakesink
  * @see_also: #GstFakeSrc
  *
  * Dummy sink that swallows everything.
- * 
- * <refsect2>
- * <title>Example launch line</title>
+ *
+ * ## Example launch line
  * |[
- * gst-launch audiotestsrc num-buffers=1000 ! fakesink sync=false
+ * gst-launch-1.0 audiotestsrc num-buffers=1000 ! fakesink sync=false
  * ]| Render 1000 audio buffers (of default size) as fast as possible.
- * </refsect2>
+ *
  */
 
 #ifdef HAVE_CONFIG_H
 #  include "config.h"
 #endif
 
+#include "gstelements_private.h"
 #include "gstfakesink.h"
-#include <gst/gstmarshal.h>
 #include <string.h>
 
 static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
@@ -59,9 +59,10 @@ enum
 };
 
 #define DEFAULT_SYNC FALSE
+#define DEFAULT_DROP_OUT_OF_SEGMENT TRUE
 
 #define DEFAULT_STATE_ERROR FAKE_SINK_STATE_ERROR_NONE
-#define DEFAULT_SILENT FALSE
+#define DEFAULT_SILENT TRUE
 #define DEFAULT_DUMP FALSE
 #define DEFAULT_SIGNAL_HANDOFFS FALSE
 #define DEFAULT_LAST_MESSAGE NULL
@@ -76,6 +77,7 @@ enum
   PROP_SILENT,
   PROP_DUMP,
   PROP_SIGNAL_HANDOFFS,
+  PROP_DROP_OUT_OF_SEGMENT,
   PROP_LAST_MESSAGE,
   PROP_CAN_ACTIVATE_PUSH,
   PROP_CAN_ACTIVATE_PULL,
@@ -131,40 +133,13 @@ static GstFlowReturn gst_fake_sink_preroll (GstBaseSink * bsink,
 static GstFlowReturn gst_fake_sink_render (GstBaseSink * bsink,
     GstBuffer * buffer);
 static gboolean gst_fake_sink_event (GstBaseSink * bsink, GstEvent * event);
+static gboolean gst_fake_sink_query (GstBaseSink * bsink, GstQuery * query);
 
 static guint gst_fake_sink_signals[LAST_SIGNAL] = { 0 };
 
 static GParamSpec *pspec_last_message = NULL;
 
 static void
-marshal_VOID__MINIOBJECT_OBJECT (GClosure * closure, GValue * return_value,
-    guint n_param_values, const GValue * param_values, gpointer invocation_hint,
-    gpointer marshal_data)
-{
-  typedef void (*marshalfunc_VOID__MINIOBJECT_OBJECT) (gpointer obj,
-      gpointer arg1, gpointer arg2, gpointer data2);
-  register marshalfunc_VOID__MINIOBJECT_OBJECT callback;
-  register GCClosure *cc = (GCClosure *) closure;
-  register gpointer data1, data2;
-
-  g_return_if_fail (n_param_values == 3);
-
-  if (G_CCLOSURE_SWAP_DATA (closure)) {
-    data1 = closure->data;
-    data2 = g_value_peek_pointer (param_values + 0);
-  } else {
-    data1 = g_value_peek_pointer (param_values + 0);
-    data2 = closure->data;
-  }
-  callback =
-      (marshalfunc_VOID__MINIOBJECT_OBJECT) (marshal_data ? marshal_data :
-      cc->callback);
-
-  callback (data1, g_value_get_boxed (param_values + 1),
-      g_value_get_object (param_values + 2), data2);
-}
-
-static void
 gst_fake_sink_class_init (GstFakeSinkClass * klass)
 {
   GObjectClass *gobject_class;
@@ -192,20 +167,27 @@ gst_fake_sink_class_init (GstFakeSinkClass * klass)
       g_param_spec_boolean ("signal-handoffs", "Signal handoffs",
           "Send a signal before unreffing the buffer", DEFAULT_SIGNAL_HANDOFFS,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+  g_object_class_install_property (gobject_class, PROP_DROP_OUT_OF_SEGMENT,
+      g_param_spec_boolean ("drop-out-of-segment",
+          "Drop out-of-segment buffers",
+          "Drop and don't render / hand off out-of-segment buffers",
+          DEFAULT_DROP_OUT_OF_SEGMENT,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
   g_object_class_install_property (gobject_class, PROP_SILENT,
       g_param_spec_boolean ("silent", "Silent",
           "Don't produce last_message events", DEFAULT_SILENT,
-          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+          G_PARAM_READWRITE | GST_PARAM_MUTABLE_PLAYING |
+          G_PARAM_STATIC_STRINGS));
   g_object_class_install_property (gobject_class, PROP_DUMP,
       g_param_spec_boolean ("dump", "Dump", "Dump buffer contents to stdout",
-          DEFAULT_DUMP, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-  g_object_class_install_property (gobject_class,
-      PROP_CAN_ACTIVATE_PUSH,
+          DEFAULT_DUMP,
+          G_PARAM_READWRITE | GST_PARAM_MUTABLE_PLAYING |
+          G_PARAM_STATIC_STRINGS));
+  g_object_class_install_property (gobject_class, PROP_CAN_ACTIVATE_PUSH,
       g_param_spec_boolean ("can-activate-push", "Can activate push",
           "Can activate in push mode", DEFAULT_CAN_ACTIVATE_PUSH,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-  g_object_class_install_property (gobject_class,
-      PROP_CAN_ACTIVATE_PULL,
+  g_object_class_install_property (gobject_class, PROP_CAN_ACTIVATE_PULL,
       g_param_spec_boolean ("can-activate-pull", "Can activate pull",
           "Can activate in pull mode", DEFAULT_CAN_ACTIVATE_PULL,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
@@ -225,8 +207,8 @@ gst_fake_sink_class_init (GstFakeSinkClass * klass)
   gst_fake_sink_signals[SIGNAL_HANDOFF] =
       g_signal_new ("handoff", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
       G_STRUCT_OFFSET (GstFakeSinkClass, handoff), NULL, NULL,
-      marshal_VOID__MINIOBJECT_OBJECT, G_TYPE_NONE, 2,
-      GST_TYPE_BUFFER, GST_TYPE_PAD);
+      g_cclosure_marshal_generic, G_TYPE_NONE, 2,
+      GST_TYPE_BUFFER | G_SIGNAL_TYPE_STATIC_SCOPE, GST_TYPE_PAD);
 
   /**
    * GstFakeSink::preroll-handoff:
@@ -235,24 +217,22 @@ gst_fake_sink_class_init (GstFakeSinkClass * klass)
    * @pad: the pad that received it
    *
    * This signal gets emitted before unreffing the buffer.
-   *
-   * Since: 0.10.7
    */
   gst_fake_sink_signals[SIGNAL_PREROLL_HANDOFF] =
       g_signal_new ("preroll-handoff", G_TYPE_FROM_CLASS (klass),
       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstFakeSinkClass, preroll_handoff),
-      NULL, NULL, marshal_VOID__MINIOBJECT_OBJECT, G_TYPE_NONE, 2,
-      GST_TYPE_BUFFER, GST_TYPE_PAD);
+      NULL, NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 2,
+      GST_TYPE_BUFFER | G_SIGNAL_TYPE_STATIC_SCOPE, GST_TYPE_PAD);
 
-  gst_element_class_set_details_simple (gstelement_class,
+  gst_element_class_set_static_metadata (gstelement_class,
       "Fake Sink",
       "Sink",
       "Black hole for data",
       "Erik Walthinsen <omega@cse.ogi.edu>, "
       "Wim Taymans <wim@fluendo.com>, "
       "Mr. 'frag-me-more' Vanderwingo <wingo@fluendo.com>");
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&sinktemplate));
+
+  gst_element_class_add_static_pad_template (gstelement_class, &sinktemplate);
 
   gstelement_class->change_state =
       GST_DEBUG_FUNCPTR (gst_fake_sink_change_state);
@@ -260,6 +240,7 @@ gst_fake_sink_class_init (GstFakeSinkClass * klass)
   gstbase_sink_class->event = GST_DEBUG_FUNCPTR (gst_fake_sink_event);
   gstbase_sink_class->preroll = GST_DEBUG_FUNCPTR (gst_fake_sink_preroll);
   gstbase_sink_class->render = GST_DEBUG_FUNCPTR (gst_fake_sink_render);
+  gstbase_sink_class->query = GST_DEBUG_FUNCPTR (gst_fake_sink_query);
 }
 
 static void
@@ -273,6 +254,8 @@ gst_fake_sink_init (GstFakeSink * fakesink)
   fakesink->num_buffers = DEFAULT_NUM_BUFFERS;
 
   gst_base_sink_set_sync (GST_BASE_SINK (fakesink), DEFAULT_SYNC);
+  gst_base_sink_set_drop_out_of_segment (GST_BASE_SINK (fakesink),
+      DEFAULT_DROP_OUT_OF_SEGMENT);
 }
 
 static void
@@ -291,7 +274,7 @@ gst_fake_sink_set_property (GObject * object, guint prop_id,
 
   switch (prop_id) {
     case PROP_STATE_ERROR:
-      sink->state_error = g_value_get_enum (value);
+      sink->state_error = (GstFakeSinkStateError) g_value_get_enum (value);
       break;
     case PROP_SILENT:
       sink->silent = g_value_get_boolean (value);
@@ -302,6 +285,10 @@ gst_fake_sink_set_property (GObject * object, guint prop_id,
     case PROP_SIGNAL_HANDOFFS:
       sink->signal_handoffs = g_value_get_boolean (value);
       break;
+    case PROP_DROP_OUT_OF_SEGMENT:
+      gst_base_sink_set_drop_out_of_segment (GST_BASE_SINK (object),
+          g_value_get_boolean (value));
+      break;
     case PROP_CAN_ACTIVATE_PUSH:
       GST_BASE_SINK (sink)->can_activate_push = g_value_get_boolean (value);
       break;
@@ -338,6 +325,10 @@ gst_fake_sink_get_property (GObject * object, guint prop_id, GValue * value,
     case PROP_SIGNAL_HANDOFFS:
       g_value_set_boolean (value, sink->signal_handoffs);
       break;
+    case PROP_DROP_OUT_OF_SEGMENT:
+      g_value_set_boolean (value,
+          gst_base_sink_get_drop_out_of_segment (GST_BASE_SINK (object)));
+      break;
     case PROP_LAST_MESSAGE:
       GST_OBJECT_LOCK (sink);
       g_value_set_string (value, sink->last_message);
@@ -456,17 +447,24 @@ gst_fake_sink_render (GstBaseSink * bsink, GstBuffer * buf)
     sink->num_buffers_left--;
 
   if (!sink->silent) {
-    gchar ts_str[64], dur_str[64];
-    gchar flag_str[100];
+    gchar dts_str[64], pts_str[64], dur_str[64];
+    gchar *flag_str, *meta_str;
 
     GST_OBJECT_LOCK (sink);
     g_free (sink->last_message);
 
-    if (GST_BUFFER_TIMESTAMP (buf) != GST_CLOCK_TIME_NONE) {
-      g_snprintf (ts_str, sizeof (ts_str), "%" GST_TIME_FORMAT,
-          GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)));
+    if (GST_BUFFER_DTS (buf) != GST_CLOCK_TIME_NONE) {
+      g_snprintf (dts_str, sizeof (dts_str), "%" GST_TIME_FORMAT,
+          GST_TIME_ARGS (GST_BUFFER_DTS (buf)));
+    } else {
+      g_strlcpy (dts_str, "none", sizeof (dts_str));
+    }
+
+    if (GST_BUFFER_PTS (buf) != GST_CLOCK_TIME_NONE) {
+      g_snprintf (pts_str, sizeof (pts_str), "%" GST_TIME_FORMAT,
+          GST_TIME_ARGS (GST_BUFFER_PTS (buf)));
     } else {
-      g_strlcpy (ts_str, "none", sizeof (ts_str));
+      g_strlcpy (pts_str, "none", sizeof (pts_str));
     }
 
     if (GST_BUFFER_DURATION (buf) != GST_CLOCK_TIME_NONE) {
@@ -476,33 +474,20 @@ gst_fake_sink_render (GstBaseSink * bsink, GstBuffer * buf)
       g_strlcpy (dur_str, "none", sizeof (dur_str));
     }
 
-    {
-      const char *flag_list[15] = {
-        "", "", "", "", "live", "decode-only", "discont", "resync", "corrupted",
-        "marker", "header", "gap", "droppable", "delta-unit", "in-caps"
-      };
-      int i;
-      char *end = flag_str;
-      end[0] = '\0';
-      for (i = 0; i < G_N_ELEMENTS (flag_list); i++) {
-        if (GST_MINI_OBJECT_CAST (buf)->flags & (1 << i)) {
-          strcpy (end, flag_list[i]);
-          end += strlen (end);
-          end[0] = ' ';
-          end[1] = '\0';
-          end++;
-        }
-      }
-    }
+    flag_str = gst_buffer_get_flags_string (buf);
+    meta_str = gst_buffer_get_meta_string (buf);
 
     sink->last_message =
-        g_strdup_printf ("chain   ******* (%s:%s) (%u bytes, timestamp: %s"
+        g_strdup_printf ("chain   ******* (%s:%s) (%u bytes, dts: %s, pts: %s"
         ", duration: %s, offset: %" G_GINT64_FORMAT ", offset_end: %"
-        G_GINT64_FORMAT ", flags: %d %s) %p",
+        G_GINT64_FORMAT ", flags: %08x %s, meta: %s) %p",
         GST_DEBUG_PAD_NAME (GST_BASE_SINK_CAST (sink)->sinkpad),
-        (guint) gst_buffer_get_size (buf), ts_str,
+        (guint) gst_buffer_get_size (buf), dts_str, pts_str,
         dur_str, GST_BUFFER_OFFSET (buf), GST_BUFFER_OFFSET_END (buf),
-        GST_MINI_OBJECT_CAST (buf)->flags, flag_str, buf);
+        GST_MINI_OBJECT_CAST (buf)->flags, flag_str,
+        meta_str ? meta_str : "none", buf);
+    g_free (flag_str);
+    g_free (meta_str);
     GST_OBJECT_UNLOCK (sink);
 
     gst_fake_sink_notify_last_message (sink);
@@ -514,9 +499,10 @@ gst_fake_sink_render (GstBaseSink * bsink, GstBuffer * buf)
   if (sink->dump) {
     GstMapInfo info;
 
-    gst_buffer_map (buf, &info, GST_MAP_READ);
-    gst_util_dump_mem (info.data, info.size);
-    gst_buffer_unmap (buf, &info);
+    if (gst_buffer_map (buf, &info, GST_MAP_READ)) {
+      gst_util_dump_mem (info.data, info.size);
+      gst_buffer_unmap (buf, &info);
+    }
   }
   if (sink->num_buffers_left == 0)
     goto eos;
@@ -531,6 +517,29 @@ eos:
   }
 }
 
+static gboolean
+gst_fake_sink_query (GstBaseSink * bsink, GstQuery * query)
+{
+  gboolean ret;
+
+  switch (GST_QUERY_TYPE (query)) {
+    case GST_QUERY_SEEKING:{
+      GstFormat fmt;
+
+      /* we don't supporting seeking */
+      gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
+      gst_query_set_seeking (query, fmt, FALSE, 0, -1);
+      ret = TRUE;
+      break;
+    }
+    default:
+      ret = GST_BASE_SINK_CLASS (parent_class)->query (bsink, query);
+      break;
+  }
+
+  return ret;
+}
+
 static GstStateChangeReturn
 gst_fake_sink_change_state (GstElement * element, GstStateChange transition)
 {