gstreamer_core/plugins/elements/gstfakesink.c
branchRCL_3
changeset 30 7e817e7e631c
parent 29 567bb019e3e3
equal deleted inserted replaced
29:567bb019e3e3 30:7e817e7e631c
    19  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    19  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    20  * Boston, MA 02111-1307, USA.
    20  * Boston, MA 02111-1307, USA.
    21  */
    21  */
    22 /**
    22 /**
    23  * SECTION:element-fakesink
    23  * SECTION:element-fakesink
       
    24  * @short_description: black hole for data
    24  * @see_also: #GstFakeSrc
    25  * @see_also: #GstFakeSrc
    25  *
    26  *
    26  * Dummy sink that swallows everything.
    27  * Dummy sink that swallows everything.
    27  */
    28  */
    28 
    29 
    29 #ifdef HAVE_CONFIG_H
    30 #ifdef HAVE_CONFIG_H
    30 #  include "config.h"
    31 #  include "config.h"
    31 #endif
    32 #endif
       
    33 #ifdef __SYMBIAN32__
       
    34 #include <gst_global.h>
       
    35 #endif
    32 
    36 
    33 #include "gstfakesink.h"
    37 #include "gstfakesink.h"
    34 #include <gst/gstmarshal.h>
    38 #include <gst/gstmarshal.h>
       
    39 #ifdef __SYMBIAN32__
       
    40 #include <glib_global.h>
       
    41 #include <gobject_global.h>
       
    42 
       
    43 #include <gstelement.h>
       
    44 #endif
    35 
    45 
    36 static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
    46 static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
    37     GST_PAD_SINK,
    47     GST_PAD_SINK,
    38     GST_PAD_ALWAYS,
    48     GST_PAD_ALWAYS,
    39     GST_STATIC_CAPS_ANY);
    49     GST_STATIC_CAPS_ANY);
   111 
   121 
   112 static void gst_fake_sink_set_property (GObject * object, guint prop_id,
   122 static void gst_fake_sink_set_property (GObject * object, guint prop_id,
   113     const GValue * value, GParamSpec * pspec);
   123     const GValue * value, GParamSpec * pspec);
   114 static void gst_fake_sink_get_property (GObject * object, guint prop_id,
   124 static void gst_fake_sink_get_property (GObject * object, guint prop_id,
   115     GValue * value, GParamSpec * pspec);
   125     GValue * value, GParamSpec * pspec);
   116 static void gst_fake_sink_finalize (GObject * obj);
       
   117 
   126 
   118 static GstStateChangeReturn gst_fake_sink_change_state (GstElement * element,
   127 static GstStateChangeReturn gst_fake_sink_change_state (GstElement * element,
   119     GstStateChange transition);
   128     GstStateChange transition);
   120 
   129 
   121 static GstFlowReturn gst_fake_sink_preroll (GstBaseSink * bsink,
   130 static GstFlowReturn gst_fake_sink_preroll (GstBaseSink * bsink,
   123 static GstFlowReturn gst_fake_sink_render (GstBaseSink * bsink,
   132 static GstFlowReturn gst_fake_sink_render (GstBaseSink * bsink,
   124     GstBuffer * buffer);
   133     GstBuffer * buffer);
   125 static gboolean gst_fake_sink_event (GstBaseSink * bsink, GstEvent * event);
   134 static gboolean gst_fake_sink_event (GstBaseSink * bsink, GstEvent * event);
   126 
   135 
   127 static guint gst_fake_sink_signals[LAST_SIGNAL] = { 0 };
   136 static guint gst_fake_sink_signals[LAST_SIGNAL] = { 0 };
   128 
       
   129 static void
       
   130 marshal_VOID__MINIOBJECT_OBJECT (GClosure * closure, GValue * return_value,
       
   131     guint n_param_values, const GValue * param_values, gpointer invocation_hint,
       
   132     gpointer marshal_data)
       
   133 {
       
   134   typedef void (*marshalfunc_VOID__MINIOBJECT_OBJECT) (gpointer obj,
       
   135       gpointer arg1, gpointer arg2, gpointer data2);
       
   136   register marshalfunc_VOID__MINIOBJECT_OBJECT callback;
       
   137   register GCClosure *cc = (GCClosure *) closure;
       
   138   register gpointer data1, data2;
       
   139 
       
   140   g_return_if_fail (n_param_values == 3);
       
   141 
       
   142   if (G_CCLOSURE_SWAP_DATA (closure)) {
       
   143     data1 = closure->data;
       
   144     data2 = g_value_peek_pointer (param_values + 0);
       
   145   } else {
       
   146     data1 = g_value_peek_pointer (param_values + 0);
       
   147     data2 = closure->data;
       
   148   }
       
   149   callback =
       
   150       (marshalfunc_VOID__MINIOBJECT_OBJECT) (marshal_data ? marshal_data :
       
   151       cc->callback);
       
   152 
       
   153   callback (data1, gst_value_get_mini_object (param_values + 1),
       
   154       g_value_get_object (param_values + 2), data2);
       
   155 }
       
   156 
   137 
   157 static void
   138 static void
   158 gst_fake_sink_base_init (gpointer g_class)
   139 gst_fake_sink_base_init (gpointer g_class)
   159 {
   140 {
   160   GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
   141   GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
   181   gstelement_class = GST_ELEMENT_CLASS (klass);
   162   gstelement_class = GST_ELEMENT_CLASS (klass);
   182   gstbase_sink_class = GST_BASE_SINK_CLASS (klass);
   163   gstbase_sink_class = GST_BASE_SINK_CLASS (klass);
   183 
   164 
   184   gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_fake_sink_set_property);
   165   gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_fake_sink_set_property);
   185   gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_fake_sink_get_property);
   166   gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_fake_sink_get_property);
   186   gobject_class->finalize = gst_fake_sink_finalize;
       
   187 
   167 
   188   g_object_class_install_property (gobject_class, PROP_STATE_ERROR,
   168   g_object_class_install_property (gobject_class, PROP_STATE_ERROR,
   189       g_param_spec_enum ("state-error", "State Error",
   169       g_param_spec_enum ("state_error", "State Error",
   190           "Generate a state change error", GST_TYPE_FAKE_SINK_STATE_ERROR,
   170           "Generate a state change error", GST_TYPE_FAKE_SINK_STATE_ERROR,
   191           DEFAULT_STATE_ERROR, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
   171           DEFAULT_STATE_ERROR, G_PARAM_READWRITE));
   192   g_object_class_install_property (gobject_class, PROP_LAST_MESSAGE,
   172   g_object_class_install_property (gobject_class, PROP_LAST_MESSAGE,
   193       g_param_spec_string ("last-message", "Last Message",
   173       g_param_spec_string ("last_message", "Last Message",
   194           "The message describing current status", DEFAULT_LAST_MESSAGE,
   174           "The message describing current status", DEFAULT_LAST_MESSAGE,
   195           G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
   175           G_PARAM_READABLE));
   196   g_object_class_install_property (gobject_class, PROP_SIGNAL_HANDOFFS,
   176   g_object_class_install_property (gobject_class, PROP_SIGNAL_HANDOFFS,
   197       g_param_spec_boolean ("signal-handoffs", "Signal handoffs",
   177       g_param_spec_boolean ("signal-handoffs", "Signal handoffs",
   198           "Send a signal before unreffing the buffer", DEFAULT_SIGNAL_HANDOFFS,
   178           "Send a signal before unreffing the buffer", DEFAULT_SIGNAL_HANDOFFS,
   199           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
   179           G_PARAM_READWRITE));
   200   g_object_class_install_property (gobject_class, PROP_SILENT,
   180   g_object_class_install_property (gobject_class, PROP_SILENT,
   201       g_param_spec_boolean ("silent", "Silent",
   181       g_param_spec_boolean ("silent", "Silent",
   202           "Don't produce last_message events", DEFAULT_SILENT,
   182           "Don't produce last_message events", DEFAULT_SILENT,
   203           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
   183           G_PARAM_READWRITE));
   204   g_object_class_install_property (gobject_class, PROP_DUMP,
   184   g_object_class_install_property (gobject_class, PROP_DUMP,
   205       g_param_spec_boolean ("dump", "Dump", "Dump buffer contents to stdout",
   185       g_param_spec_boolean ("dump", "Dump", "Dump buffer contents to stdout",
   206           DEFAULT_DUMP, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
   186           DEFAULT_DUMP, G_PARAM_READWRITE));
   207   g_object_class_install_property (gobject_class,
   187   g_object_class_install_property (gobject_class,
   208       PROP_CAN_ACTIVATE_PUSH,
   188       PROP_CAN_ACTIVATE_PUSH,
   209       g_param_spec_boolean ("can-activate-push", "Can activate push",
   189       g_param_spec_boolean ("can-activate-push", "Can activate push",
   210           "Can activate in push mode", DEFAULT_CAN_ACTIVATE_PUSH,
   190           "Can activate in push mode", DEFAULT_CAN_ACTIVATE_PUSH,
   211           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
   191           G_PARAM_READWRITE));
   212   g_object_class_install_property (gobject_class,
   192   g_object_class_install_property (gobject_class,
   213       PROP_CAN_ACTIVATE_PULL,
   193       PROP_CAN_ACTIVATE_PULL,
   214       g_param_spec_boolean ("can-activate-pull", "Can activate pull",
   194       g_param_spec_boolean ("can-activate-pull", "Can activate pull",
   215           "Can activate in pull mode", DEFAULT_CAN_ACTIVATE_PULL,
   195           "Can activate in pull mode", DEFAULT_CAN_ACTIVATE_PULL,
   216           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
   196           G_PARAM_READWRITE));
   217   g_object_class_install_property (gobject_class, PROP_NUM_BUFFERS,
   197   g_object_class_install_property (gobject_class, PROP_NUM_BUFFERS,
   218       g_param_spec_int ("num-buffers", "num-buffers",
   198       g_param_spec_int ("num-buffers", "num-buffers",
   219           "Number of buffers to accept going EOS", -1, G_MAXINT,
   199           "Number of buffers to accept going EOS", -1, G_MAXINT,
   220           DEFAULT_NUM_BUFFERS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
   200           DEFAULT_NUM_BUFFERS, G_PARAM_READWRITE));
   221 
   201 
   222   /**
   202   /**
   223    * GstFakeSink::handoff:
   203    * GstFakeSink::handoff:
   224    * @fakesink: the fakesink instance
   204    * @fakesink: the fakesink instance
   225    * @buffer: the buffer that just has been received
   205    * @buffer: the buffer that just has been received
   228    * This signal gets emitted before unreffing the buffer.
   208    * This signal gets emitted before unreffing the buffer.
   229    */
   209    */
   230   gst_fake_sink_signals[SIGNAL_HANDOFF] =
   210   gst_fake_sink_signals[SIGNAL_HANDOFF] =
   231       g_signal_new ("handoff", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
   211       g_signal_new ("handoff", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
   232       G_STRUCT_OFFSET (GstFakeSinkClass, handoff), NULL, NULL,
   212       G_STRUCT_OFFSET (GstFakeSinkClass, handoff), NULL, NULL,
   233       marshal_VOID__MINIOBJECT_OBJECT, G_TYPE_NONE, 2,
   213       gst_marshal_VOID__OBJECT_OBJECT, G_TYPE_NONE, 2,
   234       GST_TYPE_BUFFER, GST_TYPE_PAD);
   214       GST_TYPE_BUFFER, GST_TYPE_PAD);
   235 
   215 
   236   /**
   216   /**
   237    * GstFakeSink::preroll-handoff:
   217    * GstFakeSink::preroll-handoff:
   238    * @fakesink: the fakesink instance
   218    * @fakesink: the fakesink instance
   244    * Since: 0.10.7
   224    * Since: 0.10.7
   245    */
   225    */
   246   gst_fake_sink_signals[SIGNAL_PREROLL_HANDOFF] =
   226   gst_fake_sink_signals[SIGNAL_PREROLL_HANDOFF] =
   247       g_signal_new ("preroll-handoff", G_TYPE_FROM_CLASS (klass),
   227       g_signal_new ("preroll-handoff", G_TYPE_FROM_CLASS (klass),
   248       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstFakeSinkClass, preroll_handoff),
   228       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstFakeSinkClass, preroll_handoff),
   249       NULL, NULL, marshal_VOID__MINIOBJECT_OBJECT, G_TYPE_NONE, 2,
   229       NULL, NULL, gst_marshal_VOID__OBJECT_OBJECT, G_TYPE_NONE, 2,
   250       GST_TYPE_BUFFER, GST_TYPE_PAD);
   230       GST_TYPE_BUFFER, GST_TYPE_PAD);
   251 
   231 
   252   gstelement_class->change_state =
   232   gstelement_class->change_state =
   253       GST_DEBUG_FUNCPTR (gst_fake_sink_change_state);
   233       GST_DEBUG_FUNCPTR (gst_fake_sink_change_state);
   254 
   234 
   265   GST_BASE_SINK (fakesink)->sync = DEFAULT_SYNC;
   245   GST_BASE_SINK (fakesink)->sync = DEFAULT_SYNC;
   266   fakesink->last_message = g_strdup (DEFAULT_LAST_MESSAGE);
   246   fakesink->last_message = g_strdup (DEFAULT_LAST_MESSAGE);
   267   fakesink->state_error = DEFAULT_STATE_ERROR;
   247   fakesink->state_error = DEFAULT_STATE_ERROR;
   268   fakesink->signal_handoffs = DEFAULT_SIGNAL_HANDOFFS;
   248   fakesink->signal_handoffs = DEFAULT_SIGNAL_HANDOFFS;
   269   fakesink->num_buffers = DEFAULT_NUM_BUFFERS;
   249   fakesink->num_buffers = DEFAULT_NUM_BUFFERS;
   270   g_static_rec_mutex_init (&fakesink->notify_lock);
       
   271 }
       
   272 
       
   273 static void
       
   274 gst_fake_sink_finalize (GObject * obj)
       
   275 {
       
   276   GstFakeSink *sink = GST_FAKE_SINK (obj);
       
   277 
       
   278   g_static_rec_mutex_free (&sink->notify_lock);
       
   279 
       
   280   G_OBJECT_CLASS (parent_class)->finalize (obj);
       
   281 }
   250 }
   282 
   251 
   283 static void
   252 static void
   284 gst_fake_sink_set_property (GObject * object, guint prop_id,
   253 gst_fake_sink_set_property (GObject * object, guint prop_id,
   285     const GValue * value, GParamSpec * pspec)
   254     const GValue * value, GParamSpec * pspec)
   353       break;
   322       break;
   354     default:
   323     default:
   355       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
   324       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
   356       break;
   325       break;
   357   }
   326   }
   358 }
       
   359 
       
   360 static void
       
   361 gst_fake_sink_notify_last_message (GstFakeSink * sink)
       
   362 {
       
   363   /* FIXME: this hacks around a bug in GLib/GObject: doing concurrent
       
   364    * g_object_notify() on the same object might lead to crashes, see
       
   365    * http://bugzilla.gnome.org/show_bug.cgi?id=166020#c60 and follow-ups.
       
   366    * So we really don't want to do a g_object_notify() here for out-of-band
       
   367    * events with the streaming thread possibly also doing a g_object_notify()
       
   368    * for an in-band buffer or event. */
       
   369   g_static_rec_mutex_lock (&sink->notify_lock);
       
   370   g_object_notify ((GObject *) sink, "last_message");
       
   371   g_static_rec_mutex_unlock (&sink->notify_lock);
       
   372 }
   327 }
   373 
   328 
   374 static gboolean
   329 static gboolean
   375 gst_fake_sink_event (GstBaseSink * bsink, GstEvent * event)
   330 gst_fake_sink_event (GstBaseSink * bsink, GstEvent * event)
   376 {
   331 {
   392         g_strdup_printf ("event   ******* E (type: %d, %s) %p",
   347         g_strdup_printf ("event   ******* E (type: %d, %s) %p",
   393         GST_EVENT_TYPE (event), sstr, event);
   348         GST_EVENT_TYPE (event), sstr, event);
   394     g_free (sstr);
   349     g_free (sstr);
   395     GST_OBJECT_UNLOCK (sink);
   350     GST_OBJECT_UNLOCK (sink);
   396 
   351 
   397     gst_fake_sink_notify_last_message (sink);
   352     g_object_notify (G_OBJECT (sink), "last_message");
   398   }
   353   }
   399 
   354 
   400   if (GST_BASE_SINK_CLASS (parent_class)->event) {
   355   return TRUE;
   401     return GST_BASE_SINK_CLASS (parent_class)->event (bsink, event);
       
   402   } else {
       
   403     return TRUE;
       
   404   }
       
   405 }
   356 }
   406 
   357 
   407 static GstFlowReturn
   358 static GstFlowReturn
   408 gst_fake_sink_preroll (GstBaseSink * bsink, GstBuffer * buffer)
   359 gst_fake_sink_preroll (GstBaseSink * bsink, GstBuffer * buffer)
   409 {
   360 {
   417     g_free (sink->last_message);
   368     g_free (sink->last_message);
   418 
   369 
   419     sink->last_message = g_strdup_printf ("preroll   ******* ");
   370     sink->last_message = g_strdup_printf ("preroll   ******* ");
   420     GST_OBJECT_UNLOCK (sink);
   371     GST_OBJECT_UNLOCK (sink);
   421 
   372 
   422     gst_fake_sink_notify_last_message (sink);
   373     g_object_notify (G_OBJECT (sink), "last_message");
   423   }
   374   }
   424   if (sink->signal_handoffs) {
   375   if (sink->signal_handoffs) {
   425     g_signal_emit (sink,
   376     g_signal_emit (sink,
   426         gst_fake_sink_signals[SIGNAL_PREROLL_HANDOFF], 0, buffer,
   377         gst_fake_sink_signals[SIGNAL_PREROLL_HANDOFF], 0, buffer,
   427         bsink->sinkpad);
   378         bsink->sinkpad);
   470     sink->last_message =
   421     sink->last_message =
   471         g_strdup_printf ("chain   ******* < (%5d bytes, timestamp: %s"
   422         g_strdup_printf ("chain   ******* < (%5d bytes, timestamp: %s"
   472         ", duration: %s, offset: %" G_GINT64_FORMAT ", offset_end: %"
   423         ", duration: %s, offset: %" G_GINT64_FORMAT ", offset_end: %"
   473         G_GINT64_FORMAT ", flags: %d) %p", GST_BUFFER_SIZE (buf), ts_str,
   424         G_GINT64_FORMAT ", flags: %d) %p", GST_BUFFER_SIZE (buf), ts_str,
   474         dur_str, GST_BUFFER_OFFSET (buf), GST_BUFFER_OFFSET_END (buf),
   425         dur_str, GST_BUFFER_OFFSET (buf), GST_BUFFER_OFFSET_END (buf),
   475         GST_MINI_OBJECT_CAST (buf)->flags, buf);
   426         GST_MINI_OBJECT (buf)->flags, buf);
   476     GST_OBJECT_UNLOCK (sink);
   427     GST_OBJECT_UNLOCK (sink);
   477 
   428 
   478     gst_fake_sink_notify_last_message (sink);
   429     g_object_notify (G_OBJECT (sink), "last_message");
   479   }
   430   }
   480   if (sink->signal_handoffs)
   431   if (sink->signal_handoffs)
   481     g_signal_emit (G_OBJECT (sink), gst_fake_sink_signals[SIGNAL_HANDOFF], 0,
   432     g_signal_emit (G_OBJECT (sink), gst_fake_sink_signals[SIGNAL_HANDOFF], 0,
   482         buf, bsink->sinkpad);
   433         buf, bsink->sinkpad);
   483 
   434