gstreamer_core/plugins/elements/gstfakesink.c
changeset 0 0e761a78d257
child 8 4a7fac7dd34a
equal deleted inserted replaced
-1:000000000000 0:0e761a78d257
       
     1 /* GStreamer
       
     2  * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
       
     3  *                    2005 Wim Taymans <wim@fluendo.com>
       
     4  *
       
     5  * gstfakesink.c:
       
     6  *
       
     7  * This library is free software; you can redistribute it and/or
       
     8  * modify it under the terms of the GNU Library General Public
       
     9  * License as published by the Free Software Foundation; either
       
    10  * version 2 of the License, or (at your option) any later version.
       
    11  *
       
    12  * This library is distributed in the hope that it will be useful,
       
    13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    15  * Library General Public License for more details.
       
    16  *
       
    17  * You should have received a copy of the GNU Library General Public
       
    18  * License along with this library; if not, write to the
       
    19  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
       
    20  * Boston, MA 02111-1307, USA.
       
    21  */
       
    22 /**
       
    23  * SECTION:element-fakesink
       
    24  * @short_description: black hole for data
       
    25  * @see_also: #GstFakeSrc
       
    26  *
       
    27  * Dummy sink that swallows everything.
       
    28  */
       
    29 
       
    30 #ifdef HAVE_CONFIG_H
       
    31 #  include "config.h"
       
    32 #endif
       
    33 #ifdef __SYMBIAN32__
       
    34 #include <gst_global.h>
       
    35 #endif
       
    36 
       
    37 #include "gstfakesink.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
       
    45 
       
    46 static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
       
    47     GST_PAD_SINK,
       
    48     GST_PAD_ALWAYS,
       
    49     GST_STATIC_CAPS_ANY);
       
    50 
       
    51 GST_DEBUG_CATEGORY_STATIC (gst_fake_sink_debug);
       
    52 #define GST_CAT_DEFAULT gst_fake_sink_debug
       
    53 
       
    54 /* FakeSink signals and args */
       
    55 enum
       
    56 {
       
    57   /* FILL ME */
       
    58   SIGNAL_HANDOFF,
       
    59   SIGNAL_PREROLL_HANDOFF,
       
    60   LAST_SIGNAL
       
    61 };
       
    62 
       
    63 #define DEFAULT_SYNC FALSE
       
    64 
       
    65 #define DEFAULT_STATE_ERROR FAKE_SINK_STATE_ERROR_NONE
       
    66 #define DEFAULT_SILENT FALSE
       
    67 #define DEFAULT_DUMP FALSE
       
    68 #define DEFAULT_SIGNAL_HANDOFFS FALSE
       
    69 #define DEFAULT_LAST_MESSAGE NULL
       
    70 #define DEFAULT_CAN_ACTIVATE_PUSH TRUE
       
    71 #define DEFAULT_CAN_ACTIVATE_PULL FALSE
       
    72 #define DEFAULT_NUM_BUFFERS -1
       
    73 
       
    74 enum
       
    75 {
       
    76   PROP_0,
       
    77   PROP_STATE_ERROR,
       
    78   PROP_SILENT,
       
    79   PROP_DUMP,
       
    80   PROP_SIGNAL_HANDOFFS,
       
    81   PROP_LAST_MESSAGE,
       
    82   PROP_CAN_ACTIVATE_PUSH,
       
    83   PROP_CAN_ACTIVATE_PULL,
       
    84   PROP_NUM_BUFFERS
       
    85 };
       
    86 
       
    87 #define GST_TYPE_FAKE_SINK_STATE_ERROR (gst_fake_sink_state_error_get_type())
       
    88 static GType
       
    89 gst_fake_sink_state_error_get_type (void)
       
    90 {
       
    91   static GType fakesink_state_error_type = 0;
       
    92   static const GEnumValue fakesink_state_error[] = {
       
    93     {FAKE_SINK_STATE_ERROR_NONE, "No state change errors", "none"},
       
    94     {FAKE_SINK_STATE_ERROR_NULL_READY,
       
    95         "Fail state change from NULL to READY", "null-to-ready"},
       
    96     {FAKE_SINK_STATE_ERROR_READY_PAUSED,
       
    97         "Fail state change from READY to PAUSED", "ready-to-paused"},
       
    98     {FAKE_SINK_STATE_ERROR_PAUSED_PLAYING,
       
    99         "Fail state change from PAUSED to PLAYING", "paused-to-playing"},
       
   100     {FAKE_SINK_STATE_ERROR_PLAYING_PAUSED,
       
   101         "Fail state change from PLAYING to PAUSED", "playing-to-paused"},
       
   102     {FAKE_SINK_STATE_ERROR_PAUSED_READY,
       
   103         "Fail state change from PAUSED to READY", "paused-to-ready"},
       
   104     {FAKE_SINK_STATE_ERROR_READY_NULL,
       
   105         "Fail state change from READY to NULL", "ready-to-null"},
       
   106     {0, NULL, NULL},
       
   107   };
       
   108 
       
   109   if (!fakesink_state_error_type) {
       
   110     fakesink_state_error_type =
       
   111         g_enum_register_static ("GstFakeSinkStateError", fakesink_state_error);
       
   112   }
       
   113   return fakesink_state_error_type;
       
   114 }
       
   115 
       
   116 #define _do_init(bla) \
       
   117     GST_DEBUG_CATEGORY_INIT (gst_fake_sink_debug, "fakesink", 0, "fakesink element");
       
   118 
       
   119 GST_BOILERPLATE_FULL (GstFakeSink, gst_fake_sink, GstBaseSink,
       
   120     GST_TYPE_BASE_SINK, _do_init);
       
   121 
       
   122 static void gst_fake_sink_set_property (GObject * object, guint prop_id,
       
   123     const GValue * value, GParamSpec * pspec);
       
   124 static void gst_fake_sink_get_property (GObject * object, guint prop_id,
       
   125     GValue * value, GParamSpec * pspec);
       
   126 
       
   127 static GstStateChangeReturn gst_fake_sink_change_state (GstElement * element,
       
   128     GstStateChange transition);
       
   129 
       
   130 static GstFlowReturn gst_fake_sink_preroll (GstBaseSink * bsink,
       
   131     GstBuffer * buffer);
       
   132 static GstFlowReturn gst_fake_sink_render (GstBaseSink * bsink,
       
   133     GstBuffer * buffer);
       
   134 static gboolean gst_fake_sink_event (GstBaseSink * bsink, GstEvent * event);
       
   135 
       
   136 static guint gst_fake_sink_signals[LAST_SIGNAL] = { 0 };
       
   137 
       
   138 static void
       
   139 gst_fake_sink_base_init (gpointer g_class)
       
   140 {
       
   141   GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
       
   142 
       
   143   gst_element_class_set_details_simple (gstelement_class,
       
   144       "Fake Sink",
       
   145       "Sink",
       
   146       "Black hole for data",
       
   147       "Erik Walthinsen <omega@cse.ogi.edu>, "
       
   148       "Wim Taymans <wim@fluendo.com>, "
       
   149       "Mr. 'frag-me-more' Vanderwingo <wingo@fluendo.com>");
       
   150   gst_element_class_add_pad_template (gstelement_class,
       
   151       gst_static_pad_template_get (&sinktemplate));
       
   152 }
       
   153 
       
   154 static void
       
   155 gst_fake_sink_class_init (GstFakeSinkClass * klass)
       
   156 {
       
   157   GObjectClass *gobject_class;
       
   158   GstElementClass *gstelement_class;
       
   159   GstBaseSinkClass *gstbase_sink_class;
       
   160 
       
   161   gobject_class = G_OBJECT_CLASS (klass);
       
   162   gstelement_class = GST_ELEMENT_CLASS (klass);
       
   163   gstbase_sink_class = GST_BASE_SINK_CLASS (klass);
       
   164 
       
   165   gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_fake_sink_set_property);
       
   166   gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_fake_sink_get_property);
       
   167 
       
   168   g_object_class_install_property (gobject_class, PROP_STATE_ERROR,
       
   169       g_param_spec_enum ("state_error", "State Error",
       
   170           "Generate a state change error", GST_TYPE_FAKE_SINK_STATE_ERROR,
       
   171           DEFAULT_STATE_ERROR, G_PARAM_READWRITE));
       
   172   g_object_class_install_property (gobject_class, PROP_LAST_MESSAGE,
       
   173       g_param_spec_string ("last_message", "Last Message",
       
   174           "The message describing current status", DEFAULT_LAST_MESSAGE,
       
   175           G_PARAM_READABLE));
       
   176   g_object_class_install_property (gobject_class, PROP_SIGNAL_HANDOFFS,
       
   177       g_param_spec_boolean ("signal-handoffs", "Signal handoffs",
       
   178           "Send a signal before unreffing the buffer", DEFAULT_SIGNAL_HANDOFFS,
       
   179           G_PARAM_READWRITE));
       
   180   g_object_class_install_property (gobject_class, PROP_SILENT,
       
   181       g_param_spec_boolean ("silent", "Silent",
       
   182           "Don't produce last_message events", DEFAULT_SILENT,
       
   183           G_PARAM_READWRITE));
       
   184   g_object_class_install_property (gobject_class, PROP_DUMP,
       
   185       g_param_spec_boolean ("dump", "Dump", "Dump buffer contents to stdout",
       
   186           DEFAULT_DUMP, G_PARAM_READWRITE));
       
   187   g_object_class_install_property (gobject_class,
       
   188       PROP_CAN_ACTIVATE_PUSH,
       
   189       g_param_spec_boolean ("can-activate-push", "Can activate push",
       
   190           "Can activate in push mode", DEFAULT_CAN_ACTIVATE_PUSH,
       
   191           G_PARAM_READWRITE));
       
   192   g_object_class_install_property (gobject_class,
       
   193       PROP_CAN_ACTIVATE_PULL,
       
   194       g_param_spec_boolean ("can-activate-pull", "Can activate pull",
       
   195           "Can activate in pull mode", DEFAULT_CAN_ACTIVATE_PULL,
       
   196           G_PARAM_READWRITE));
       
   197   g_object_class_install_property (gobject_class, PROP_NUM_BUFFERS,
       
   198       g_param_spec_int ("num-buffers", "num-buffers",
       
   199           "Number of buffers to accept going EOS", -1, G_MAXINT,
       
   200           DEFAULT_NUM_BUFFERS, G_PARAM_READWRITE));
       
   201 
       
   202   /**
       
   203    * GstFakeSink::handoff:
       
   204    * @fakesink: the fakesink instance
       
   205    * @buffer: the buffer that just has been received
       
   206    * @pad: the pad that received it
       
   207    *
       
   208    * This signal gets emitted before unreffing the buffer.
       
   209    */
       
   210   gst_fake_sink_signals[SIGNAL_HANDOFF] =
       
   211       g_signal_new ("handoff", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
       
   212       G_STRUCT_OFFSET (GstFakeSinkClass, handoff), NULL, NULL,
       
   213       gst_marshal_VOID__OBJECT_OBJECT, G_TYPE_NONE, 2,
       
   214       GST_TYPE_BUFFER, GST_TYPE_PAD);
       
   215 
       
   216   /**
       
   217    * GstFakeSink::preroll-handoff:
       
   218    * @fakesink: the fakesink instance
       
   219    * @buffer: the buffer that just has been received
       
   220    * @pad: the pad that received it
       
   221    *
       
   222    * This signal gets emitted before unreffing the buffer.
       
   223    *
       
   224    * Since: 0.10.7
       
   225    */
       
   226   gst_fake_sink_signals[SIGNAL_PREROLL_HANDOFF] =
       
   227       g_signal_new ("preroll-handoff", G_TYPE_FROM_CLASS (klass),
       
   228       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstFakeSinkClass, preroll_handoff),
       
   229       NULL, NULL, gst_marshal_VOID__OBJECT_OBJECT, G_TYPE_NONE, 2,
       
   230       GST_TYPE_BUFFER, GST_TYPE_PAD);
       
   231 
       
   232   gstelement_class->change_state =
       
   233       GST_DEBUG_FUNCPTR (gst_fake_sink_change_state);
       
   234 
       
   235   gstbase_sink_class->event = GST_DEBUG_FUNCPTR (gst_fake_sink_event);
       
   236   gstbase_sink_class->preroll = GST_DEBUG_FUNCPTR (gst_fake_sink_preroll);
       
   237   gstbase_sink_class->render = GST_DEBUG_FUNCPTR (gst_fake_sink_render);
       
   238 }
       
   239 
       
   240 static void
       
   241 gst_fake_sink_init (GstFakeSink * fakesink, GstFakeSinkClass * g_class)
       
   242 {
       
   243   fakesink->silent = DEFAULT_SILENT;
       
   244   fakesink->dump = DEFAULT_DUMP;
       
   245   GST_BASE_SINK (fakesink)->sync = DEFAULT_SYNC;
       
   246   fakesink->last_message = g_strdup (DEFAULT_LAST_MESSAGE);
       
   247   fakesink->state_error = DEFAULT_STATE_ERROR;
       
   248   fakesink->signal_handoffs = DEFAULT_SIGNAL_HANDOFFS;
       
   249   fakesink->num_buffers = DEFAULT_NUM_BUFFERS;
       
   250 }
       
   251 
       
   252 static void
       
   253 gst_fake_sink_set_property (GObject * object, guint prop_id,
       
   254     const GValue * value, GParamSpec * pspec)
       
   255 {
       
   256   GstFakeSink *sink;
       
   257 
       
   258   sink = GST_FAKE_SINK (object);
       
   259 
       
   260   switch (prop_id) {
       
   261     case PROP_SILENT:
       
   262       sink->silent = g_value_get_boolean (value);
       
   263       break;
       
   264     case PROP_STATE_ERROR:
       
   265       sink->state_error = g_value_get_enum (value);
       
   266       break;
       
   267     case PROP_DUMP:
       
   268       sink->dump = g_value_get_boolean (value);
       
   269       break;
       
   270     case PROP_SIGNAL_HANDOFFS:
       
   271       sink->signal_handoffs = g_value_get_boolean (value);
       
   272       break;
       
   273     case PROP_CAN_ACTIVATE_PUSH:
       
   274       GST_BASE_SINK (sink)->can_activate_push = g_value_get_boolean (value);
       
   275       break;
       
   276     case PROP_CAN_ACTIVATE_PULL:
       
   277       GST_BASE_SINK (sink)->can_activate_pull = g_value_get_boolean (value);
       
   278       break;
       
   279     case PROP_NUM_BUFFERS:
       
   280       sink->num_buffers = g_value_get_int (value);
       
   281       break;
       
   282     default:
       
   283       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       
   284       break;
       
   285   }
       
   286 }
       
   287 
       
   288 static void
       
   289 gst_fake_sink_get_property (GObject * object, guint prop_id, GValue * value,
       
   290     GParamSpec * pspec)
       
   291 {
       
   292   GstFakeSink *sink;
       
   293 
       
   294   sink = GST_FAKE_SINK (object);
       
   295 
       
   296   switch (prop_id) {
       
   297     case PROP_STATE_ERROR:
       
   298       g_value_set_enum (value, sink->state_error);
       
   299       break;
       
   300     case PROP_SILENT:
       
   301       g_value_set_boolean (value, sink->silent);
       
   302       break;
       
   303     case PROP_DUMP:
       
   304       g_value_set_boolean (value, sink->dump);
       
   305       break;
       
   306     case PROP_SIGNAL_HANDOFFS:
       
   307       g_value_set_boolean (value, sink->signal_handoffs);
       
   308       break;
       
   309     case PROP_LAST_MESSAGE:
       
   310       GST_OBJECT_LOCK (sink);
       
   311       g_value_set_string (value, sink->last_message);
       
   312       GST_OBJECT_UNLOCK (sink);
       
   313       break;
       
   314     case PROP_CAN_ACTIVATE_PUSH:
       
   315       g_value_set_boolean (value, GST_BASE_SINK (sink)->can_activate_push);
       
   316       break;
       
   317     case PROP_CAN_ACTIVATE_PULL:
       
   318       g_value_set_boolean (value, GST_BASE_SINK (sink)->can_activate_pull);
       
   319       break;
       
   320     case PROP_NUM_BUFFERS:
       
   321       g_value_set_int (value, sink->num_buffers);
       
   322       break;
       
   323     default:
       
   324       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       
   325       break;
       
   326   }
       
   327 }
       
   328 
       
   329 static gboolean
       
   330 gst_fake_sink_event (GstBaseSink * bsink, GstEvent * event)
       
   331 {
       
   332   GstFakeSink *sink = GST_FAKE_SINK (bsink);
       
   333 
       
   334   if (!sink->silent) {
       
   335     const GstStructure *s;
       
   336     gchar *sstr;
       
   337 
       
   338     GST_OBJECT_LOCK (sink);
       
   339     g_free (sink->last_message);
       
   340 
       
   341     if ((s = gst_event_get_structure (event)))
       
   342       sstr = gst_structure_to_string (s);
       
   343     else
       
   344       sstr = g_strdup ("");
       
   345 
       
   346     sink->last_message =
       
   347         g_strdup_printf ("event   ******* E (type: %d, %s) %p",
       
   348         GST_EVENT_TYPE (event), sstr, event);
       
   349     g_free (sstr);
       
   350     GST_OBJECT_UNLOCK (sink);
       
   351 
       
   352     g_object_notify (G_OBJECT (sink), "last_message");
       
   353   }
       
   354 
       
   355   return TRUE;
       
   356 }
       
   357 
       
   358 static GstFlowReturn
       
   359 gst_fake_sink_preroll (GstBaseSink * bsink, GstBuffer * buffer)
       
   360 {
       
   361   GstFakeSink *sink = GST_FAKE_SINK (bsink);
       
   362 
       
   363   if (sink->num_buffers_left == 0)
       
   364     goto eos;
       
   365 
       
   366   if (!sink->silent) {
       
   367     GST_OBJECT_LOCK (sink);
       
   368     g_free (sink->last_message);
       
   369 
       
   370     sink->last_message = g_strdup_printf ("preroll   ******* ");
       
   371     GST_OBJECT_UNLOCK (sink);
       
   372 
       
   373     g_object_notify (G_OBJECT (sink), "last_message");
       
   374   }
       
   375   if (sink->signal_handoffs) {
       
   376     g_signal_emit (sink,
       
   377         gst_fake_sink_signals[SIGNAL_PREROLL_HANDOFF], 0, buffer,
       
   378         bsink->sinkpad);
       
   379   }
       
   380   return GST_FLOW_OK;
       
   381 
       
   382   /* ERRORS */
       
   383 eos:
       
   384   {
       
   385     GST_DEBUG_OBJECT (sink, "we are EOS");
       
   386     return GST_FLOW_UNEXPECTED;
       
   387   }
       
   388 }
       
   389 
       
   390 static GstFlowReturn
       
   391 gst_fake_sink_render (GstBaseSink * bsink, GstBuffer * buf)
       
   392 {
       
   393   GstFakeSink *sink = GST_FAKE_SINK_CAST (bsink);
       
   394 
       
   395   if (sink->num_buffers_left == 0)
       
   396     goto eos;
       
   397 
       
   398   if (sink->num_buffers_left != -1)
       
   399     sink->num_buffers_left--;
       
   400 
       
   401   if (!sink->silent) {
       
   402     gchar ts_str[64], dur_str[64];
       
   403 
       
   404     GST_OBJECT_LOCK (sink);
       
   405     g_free (sink->last_message);
       
   406 
       
   407     if (GST_BUFFER_TIMESTAMP (buf) != GST_CLOCK_TIME_NONE) {
       
   408       g_snprintf (ts_str, sizeof (ts_str), "%" GST_TIME_FORMAT,
       
   409           GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)));
       
   410     } else {
       
   411       g_strlcpy (ts_str, "none", sizeof (ts_str));
       
   412     }
       
   413 
       
   414     if (GST_BUFFER_DURATION (buf) != GST_CLOCK_TIME_NONE) {
       
   415       g_snprintf (dur_str, sizeof (dur_str), "%" GST_TIME_FORMAT,
       
   416           GST_TIME_ARGS (GST_BUFFER_DURATION (buf)));
       
   417     } else {
       
   418       g_strlcpy (dur_str, "none", sizeof (dur_str));
       
   419     }
       
   420 
       
   421     sink->last_message =
       
   422         g_strdup_printf ("chain   ******* < (%5d bytes, timestamp: %s"
       
   423         ", duration: %s, offset: %" G_GINT64_FORMAT ", offset_end: %"
       
   424         G_GINT64_FORMAT ", flags: %d) %p", GST_BUFFER_SIZE (buf), ts_str,
       
   425         dur_str, GST_BUFFER_OFFSET (buf), GST_BUFFER_OFFSET_END (buf),
       
   426         GST_MINI_OBJECT (buf)->flags, buf);
       
   427     GST_OBJECT_UNLOCK (sink);
       
   428 
       
   429     g_object_notify (G_OBJECT (sink), "last_message");
       
   430   }
       
   431   if (sink->signal_handoffs)
       
   432     g_signal_emit (G_OBJECT (sink), gst_fake_sink_signals[SIGNAL_HANDOFF], 0,
       
   433         buf, bsink->sinkpad);
       
   434 
       
   435   if (sink->dump) {
       
   436     gst_util_dump_mem (GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
       
   437   }
       
   438   if (sink->num_buffers_left == 0)
       
   439     goto eos;
       
   440 
       
   441   return GST_FLOW_OK;
       
   442 
       
   443   /* ERRORS */
       
   444 eos:
       
   445   {
       
   446     GST_DEBUG_OBJECT (sink, "we are EOS");
       
   447     return GST_FLOW_UNEXPECTED;
       
   448   }
       
   449 }
       
   450 
       
   451 static GstStateChangeReturn
       
   452 gst_fake_sink_change_state (GstElement * element, GstStateChange transition)
       
   453 {
       
   454   GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
       
   455   GstFakeSink *fakesink = GST_FAKE_SINK (element);
       
   456 
       
   457   switch (transition) {
       
   458     case GST_STATE_CHANGE_NULL_TO_READY:
       
   459       if (fakesink->state_error == FAKE_SINK_STATE_ERROR_NULL_READY)
       
   460         goto error;
       
   461       break;
       
   462     case GST_STATE_CHANGE_READY_TO_PAUSED:
       
   463       if (fakesink->state_error == FAKE_SINK_STATE_ERROR_READY_PAUSED)
       
   464         goto error;
       
   465       fakesink->num_buffers_left = fakesink->num_buffers;
       
   466       break;
       
   467     case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
       
   468       if (fakesink->state_error == FAKE_SINK_STATE_ERROR_PAUSED_PLAYING)
       
   469         goto error;
       
   470       break;
       
   471     default:
       
   472       break;
       
   473   }
       
   474 
       
   475   ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
       
   476 
       
   477   switch (transition) {
       
   478     case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
       
   479       if (fakesink->state_error == FAKE_SINK_STATE_ERROR_PLAYING_PAUSED)
       
   480         goto error;
       
   481       break;
       
   482     case GST_STATE_CHANGE_PAUSED_TO_READY:
       
   483       if (fakesink->state_error == FAKE_SINK_STATE_ERROR_PAUSED_READY)
       
   484         goto error;
       
   485       break;
       
   486     case GST_STATE_CHANGE_READY_TO_NULL:
       
   487       if (fakesink->state_error == FAKE_SINK_STATE_ERROR_READY_NULL)
       
   488         goto error;
       
   489       GST_OBJECT_LOCK (fakesink);
       
   490       g_free (fakesink->last_message);
       
   491       fakesink->last_message = NULL;
       
   492       GST_OBJECT_UNLOCK (fakesink);
       
   493       break;
       
   494     default:
       
   495       break;
       
   496   }
       
   497 
       
   498   return ret;
       
   499 
       
   500   /* ERROR */
       
   501 error:
       
   502   GST_ELEMENT_ERROR (element, CORE, STATE_CHANGE, (NULL),
       
   503       ("Erroring out on state change as requested"));
       
   504   return GST_STATE_CHANGE_FAILURE;
       
   505 }