LCOV - code coverage report
Current view: top level - plugins/elements - gstfakesink.c (source / functions) Hit Total Coverage
Test: GStreamer 0.10.32.1 Lines: 175 221 79.2 %
Date: 2011-03-25 Functions: 14 15 93.3 %
Branches: 69 111 62.2 %

           Branch data     Line data    Source code
       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                 :            :  * @see_also: #GstFakeSrc
      25                 :            :  *
      26                 :            :  * Dummy sink that swallows everything.
      27                 :            :  * 
      28                 :            :  * <refsect2>
      29                 :            :  * <title>Example launch line</title>
      30                 :            :  * |[
      31                 :            :  * gst-launch audiotestsrc num-buffers=1000 ! fakesink sync=false
      32                 :            :  * ]| Render 1000 audio buffers (of default size) as fast as possible.
      33                 :            :  * </refsect2>
      34                 :            :  */
      35                 :            : 
      36                 :            : #ifdef HAVE_CONFIG_H
      37                 :            : #  include "config.h"
      38                 :            : #endif
      39                 :            : 
      40                 :            : #include "gstfakesink.h"
      41                 :            : #include <gst/gstmarshal.h>
      42                 :            : #include <string.h>
      43                 :            : 
      44                 :            : static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
      45                 :            :     GST_PAD_SINK,
      46                 :            :     GST_PAD_ALWAYS,
      47                 :            :     GST_STATIC_CAPS_ANY);
      48                 :            : 
      49                 :            : GST_DEBUG_CATEGORY_STATIC (gst_fake_sink_debug);
      50                 :            : #define GST_CAT_DEFAULT gst_fake_sink_debug
      51                 :            : 
      52                 :            : /* FakeSink signals and args */
      53                 :            : enum
      54                 :            : {
      55                 :            :   /* FILL ME */
      56                 :            :   SIGNAL_HANDOFF,
      57                 :            :   SIGNAL_PREROLL_HANDOFF,
      58                 :            :   LAST_SIGNAL
      59                 :            : };
      60                 :            : 
      61                 :            : #define DEFAULT_SYNC FALSE
      62                 :            : 
      63                 :            : #define DEFAULT_STATE_ERROR FAKE_SINK_STATE_ERROR_NONE
      64                 :            : #define DEFAULT_SILENT FALSE
      65                 :            : #define DEFAULT_DUMP FALSE
      66                 :            : #define DEFAULT_SIGNAL_HANDOFFS FALSE
      67                 :            : #define DEFAULT_LAST_MESSAGE NULL
      68                 :            : #define DEFAULT_CAN_ACTIVATE_PUSH TRUE
      69                 :            : #define DEFAULT_CAN_ACTIVATE_PULL FALSE
      70                 :            : #define DEFAULT_NUM_BUFFERS -1
      71                 :            : 
      72                 :            : enum
      73                 :            : {
      74                 :            :   PROP_0,
      75                 :            :   PROP_STATE_ERROR,
      76                 :            :   PROP_SILENT,
      77                 :            :   PROP_DUMP,
      78                 :            :   PROP_SIGNAL_HANDOFFS,
      79                 :            :   PROP_LAST_MESSAGE,
      80                 :            :   PROP_CAN_ACTIVATE_PUSH,
      81                 :            :   PROP_CAN_ACTIVATE_PULL,
      82                 :            :   PROP_NUM_BUFFERS
      83                 :            : };
      84                 :            : 
      85                 :            : #define GST_TYPE_FAKE_SINK_STATE_ERROR (gst_fake_sink_state_error_get_type())
      86                 :            : static GType
      87                 :         92 : gst_fake_sink_state_error_get_type (void)
      88                 :            : {
      89                 :            :   static GType fakesink_state_error_type = 0;
      90                 :            :   static const GEnumValue fakesink_state_error[] = {
      91                 :            :     {FAKE_SINK_STATE_ERROR_NONE, "No state change errors", "none"},
      92                 :            :     {FAKE_SINK_STATE_ERROR_NULL_READY,
      93                 :            :         "Fail state change from NULL to READY", "null-to-ready"},
      94                 :            :     {FAKE_SINK_STATE_ERROR_READY_PAUSED,
      95                 :            :         "Fail state change from READY to PAUSED", "ready-to-paused"},
      96                 :            :     {FAKE_SINK_STATE_ERROR_PAUSED_PLAYING,
      97                 :            :         "Fail state change from PAUSED to PLAYING", "paused-to-playing"},
      98                 :            :     {FAKE_SINK_STATE_ERROR_PLAYING_PAUSED,
      99                 :            :         "Fail state change from PLAYING to PAUSED", "playing-to-paused"},
     100                 :            :     {FAKE_SINK_STATE_ERROR_PAUSED_READY,
     101                 :            :         "Fail state change from PAUSED to READY", "paused-to-ready"},
     102                 :            :     {FAKE_SINK_STATE_ERROR_READY_NULL,
     103                 :            :         "Fail state change from READY to NULL", "ready-to-null"},
     104                 :            :     {0, NULL, NULL},
     105                 :            :   };
     106                 :            : 
     107         [ +  - ]:         92 :   if (!fakesink_state_error_type) {
     108                 :         92 :     fakesink_state_error_type =
     109                 :         92 :         g_enum_register_static ("GstFakeSinkStateError", fakesink_state_error);
     110                 :            :   }
     111                 :         92 :   return fakesink_state_error_type;
     112                 :            : }
     113                 :            : 
     114                 :            : #define _do_init(bla) \
     115                 :            :     GST_DEBUG_CATEGORY_INIT (gst_fake_sink_debug, "fakesink", 0, "fakesink element");
     116                 :            : 
     117 [ +  + ][ +  - ]:     149527 : GST_BOILERPLATE_FULL (GstFakeSink, gst_fake_sink, GstBaseSink,
     118                 :     149527 :     GST_TYPE_BASE_SINK, _do_init);
     119                 :            : 
     120                 :            : static void gst_fake_sink_set_property (GObject * object, guint prop_id,
     121                 :            :     const GValue * value, GParamSpec * pspec);
     122                 :            : static void gst_fake_sink_get_property (GObject * object, guint prop_id,
     123                 :            :     GValue * value, GParamSpec * pspec);
     124                 :            : static void gst_fake_sink_finalize (GObject * obj);
     125                 :            : 
     126                 :            : static GstStateChangeReturn gst_fake_sink_change_state (GstElement * element,
     127                 :            :     GstStateChange transition);
     128                 :            : 
     129                 :            : static GstFlowReturn gst_fake_sink_preroll (GstBaseSink * bsink,
     130                 :            :     GstBuffer * buffer);
     131                 :            : static GstFlowReturn gst_fake_sink_render (GstBaseSink * bsink,
     132                 :            :     GstBuffer * buffer);
     133                 :            : static gboolean gst_fake_sink_event (GstBaseSink * bsink, GstEvent * event);
     134                 :            : 
     135                 :            : static guint gst_fake_sink_signals[LAST_SIGNAL] = { 0 };
     136                 :            : 
     137                 :            : static GParamSpec *pspec_last_message = NULL;
     138                 :            : 
     139                 :            : static void
     140                 :         63 : marshal_VOID__MINIOBJECT_OBJECT (GClosure * closure, GValue * return_value,
     141                 :            :     guint n_param_values, const GValue * param_values, gpointer invocation_hint,
     142                 :            :     gpointer marshal_data)
     143                 :            : {
     144                 :            :   typedef void (*marshalfunc_VOID__MINIOBJECT_OBJECT) (gpointer obj,
     145                 :            :       gpointer arg1, gpointer arg2, gpointer data2);
     146                 :            :   register marshalfunc_VOID__MINIOBJECT_OBJECT callback;
     147                 :         63 :   register GCClosure *cc = (GCClosure *) closure;
     148                 :            :   register gpointer data1, data2;
     149                 :            : 
     150         [ -  + ]:        126 :   g_return_if_fail (n_param_values == 3);
     151                 :            : 
     152         [ -  + ]:         63 :   if (G_CCLOSURE_SWAP_DATA (closure)) {
     153                 :          0 :     data1 = closure->data;
     154                 :          0 :     data2 = g_value_peek_pointer (param_values + 0);
     155                 :            :   } else {
     156                 :         63 :     data1 = g_value_peek_pointer (param_values + 0);
     157                 :         63 :     data2 = closure->data;
     158                 :            :   }
     159                 :         63 :   callback =
     160         [ +  - ]:         63 :       (marshalfunc_VOID__MINIOBJECT_OBJECT) (marshal_data ? marshal_data :
     161                 :            :       cc->callback);
     162                 :            : 
     163                 :         63 :   callback (data1, gst_value_get_mini_object (param_values + 1),
     164                 :            :       g_value_get_object (param_values + 2), data2);
     165                 :            : }
     166                 :            : 
     167                 :            : static void
     168                 :         92 : gst_fake_sink_base_init (gpointer g_class)
     169                 :            : {
     170                 :         92 :   GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
     171                 :            : 
     172                 :         92 :   gst_element_class_set_details_simple (gstelement_class,
     173                 :            :       "Fake Sink",
     174                 :            :       "Sink",
     175                 :            :       "Black hole for data",
     176                 :            :       "Erik Walthinsen <omega@cse.ogi.edu>, "
     177                 :            :       "Wim Taymans <wim@fluendo.com>, "
     178                 :            :       "Mr. 'frag-me-more' Vanderwingo <wingo@fluendo.com>");
     179                 :         92 :   gst_element_class_add_pad_template (gstelement_class,
     180                 :            :       gst_static_pad_template_get (&sinktemplate));
     181                 :         92 : }
     182                 :            : 
     183                 :            : static void
     184                 :         92 : gst_fake_sink_class_init (GstFakeSinkClass * klass)
     185                 :            : {
     186                 :            :   GObjectClass *gobject_class;
     187                 :            :   GstElementClass *gstelement_class;
     188                 :            :   GstBaseSinkClass *gstbase_sink_class;
     189                 :            : 
     190                 :         92 :   gobject_class = G_OBJECT_CLASS (klass);
     191                 :         92 :   gstelement_class = GST_ELEMENT_CLASS (klass);
     192                 :         92 :   gstbase_sink_class = GST_BASE_SINK_CLASS (klass);
     193                 :            : 
     194                 :         92 :   gobject_class->set_property = gst_fake_sink_set_property;
     195                 :         92 :   gobject_class->get_property = gst_fake_sink_get_property;
     196                 :         92 :   gobject_class->finalize = gst_fake_sink_finalize;
     197                 :            : 
     198                 :         92 :   g_object_class_install_property (gobject_class, PROP_STATE_ERROR,
     199                 :            :       g_param_spec_enum ("state-error", "State Error",
     200                 :            :           "Generate a state change error", GST_TYPE_FAKE_SINK_STATE_ERROR,
     201                 :            :           DEFAULT_STATE_ERROR, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
     202                 :         92 :   pspec_last_message = g_param_spec_string ("last-message", "Last Message",
     203                 :            :       "The message describing current status", DEFAULT_LAST_MESSAGE,
     204                 :            :       G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
     205                 :         92 :   g_object_class_install_property (gobject_class, PROP_LAST_MESSAGE,
     206                 :            :       pspec_last_message);
     207                 :         92 :   g_object_class_install_property (gobject_class, PROP_SIGNAL_HANDOFFS,
     208                 :            :       g_param_spec_boolean ("signal-handoffs", "Signal handoffs",
     209                 :            :           "Send a signal before unreffing the buffer", DEFAULT_SIGNAL_HANDOFFS,
     210                 :            :           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
     211                 :         92 :   g_object_class_install_property (gobject_class, PROP_SILENT,
     212                 :            :       g_param_spec_boolean ("silent", "Silent",
     213                 :            :           "Don't produce last_message events", DEFAULT_SILENT,
     214                 :            :           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
     215                 :         92 :   g_object_class_install_property (gobject_class, PROP_DUMP,
     216                 :            :       g_param_spec_boolean ("dump", "Dump", "Dump buffer contents to stdout",
     217                 :            :           DEFAULT_DUMP, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
     218                 :         92 :   g_object_class_install_property (gobject_class,
     219                 :            :       PROP_CAN_ACTIVATE_PUSH,
     220                 :            :       g_param_spec_boolean ("can-activate-push", "Can activate push",
     221                 :            :           "Can activate in push mode", DEFAULT_CAN_ACTIVATE_PUSH,
     222                 :            :           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
     223                 :         92 :   g_object_class_install_property (gobject_class,
     224                 :            :       PROP_CAN_ACTIVATE_PULL,
     225                 :            :       g_param_spec_boolean ("can-activate-pull", "Can activate pull",
     226                 :            :           "Can activate in pull mode", DEFAULT_CAN_ACTIVATE_PULL,
     227                 :            :           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
     228                 :         92 :   g_object_class_install_property (gobject_class, PROP_NUM_BUFFERS,
     229                 :            :       g_param_spec_int ("num-buffers", "num-buffers",
     230                 :            :           "Number of buffers to accept going EOS", -1, G_MAXINT,
     231                 :            :           DEFAULT_NUM_BUFFERS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
     232                 :            : 
     233                 :            :   /**
     234                 :            :    * GstFakeSink::handoff:
     235                 :            :    * @fakesink: the fakesink instance
     236                 :            :    * @buffer: the buffer that just has been received
     237                 :            :    * @pad: the pad that received it
     238                 :            :    *
     239                 :            :    * This signal gets emitted before unreffing the buffer.
     240                 :            :    */
     241                 :         92 :   gst_fake_sink_signals[SIGNAL_HANDOFF] =
     242                 :         92 :       g_signal_new ("handoff", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
     243                 :            :       G_STRUCT_OFFSET (GstFakeSinkClass, handoff), NULL, NULL,
     244                 :            :       marshal_VOID__MINIOBJECT_OBJECT, G_TYPE_NONE, 2,
     245                 :            :       GST_TYPE_BUFFER, GST_TYPE_PAD);
     246                 :            : 
     247                 :            :   /**
     248                 :            :    * GstFakeSink::preroll-handoff:
     249                 :            :    * @fakesink: the fakesink instance
     250                 :            :    * @buffer: the buffer that just has been received
     251                 :            :    * @pad: the pad that received it
     252                 :            :    *
     253                 :            :    * This signal gets emitted before unreffing the buffer.
     254                 :            :    *
     255                 :            :    * Since: 0.10.7
     256                 :            :    */
     257                 :         92 :   gst_fake_sink_signals[SIGNAL_PREROLL_HANDOFF] =
     258                 :         92 :       g_signal_new ("preroll-handoff", G_TYPE_FROM_CLASS (klass),
     259                 :            :       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstFakeSinkClass, preroll_handoff),
     260                 :            :       NULL, NULL, marshal_VOID__MINIOBJECT_OBJECT, G_TYPE_NONE, 2,
     261                 :            :       GST_TYPE_BUFFER, GST_TYPE_PAD);
     262                 :            : 
     263                 :         92 :   gstelement_class->change_state =
     264                 :         92 :       GST_DEBUG_FUNCPTR (gst_fake_sink_change_state);
     265                 :            : 
     266                 :         92 :   gstbase_sink_class->event = GST_DEBUG_FUNCPTR (gst_fake_sink_event);
     267                 :         92 :   gstbase_sink_class->preroll = GST_DEBUG_FUNCPTR (gst_fake_sink_preroll);
     268                 :         92 :   gstbase_sink_class->render = GST_DEBUG_FUNCPTR (gst_fake_sink_render);
     269                 :         92 : }
     270                 :            : 
     271                 :            : static void
     272                 :        151 : gst_fake_sink_init (GstFakeSink * fakesink, GstFakeSinkClass * g_class)
     273                 :            : {
     274                 :        151 :   fakesink->silent = DEFAULT_SILENT;
     275                 :        151 :   fakesink->dump = DEFAULT_DUMP;
     276                 :        151 :   fakesink->last_message = g_strdup (DEFAULT_LAST_MESSAGE);
     277                 :        151 :   fakesink->state_error = DEFAULT_STATE_ERROR;
     278                 :        151 :   fakesink->signal_handoffs = DEFAULT_SIGNAL_HANDOFFS;
     279                 :        151 :   fakesink->num_buffers = DEFAULT_NUM_BUFFERS;
     280                 :            : #if !GLIB_CHECK_VERSION(2,26,0)
     281                 :            :   g_static_rec_mutex_init (&fakesink->notify_lock);
     282                 :            : #endif
     283                 :            : 
     284                 :        151 :   gst_base_sink_set_sync (GST_BASE_SINK (fakesink), DEFAULT_SYNC);
     285                 :        151 : }
     286                 :            : 
     287                 :            : static void
     288                 :        141 : gst_fake_sink_finalize (GObject * obj)
     289                 :            : {
     290                 :            : #if !GLIB_CHECK_VERSION(2,26,0)
     291                 :            :   GstFakeSink *sink = GST_FAKE_SINK (obj);
     292                 :            : 
     293                 :            :   g_static_rec_mutex_free (&sink->notify_lock);
     294                 :            : #endif
     295                 :            : 
     296                 :        141 :   G_OBJECT_CLASS (parent_class)->finalize (obj);
     297                 :        141 : }
     298                 :            : 
     299                 :            : static void
     300                 :         79 : gst_fake_sink_set_property (GObject * object, guint prop_id,
     301                 :            :     const GValue * value, GParamSpec * pspec)
     302                 :            : {
     303                 :            :   GstFakeSink *sink;
     304                 :            : 
     305                 :         79 :   sink = GST_FAKE_SINK (object);
     306                 :            : 
     307   [ +  +  -  +  :         79 :   switch (prop_id) {
             +  +  +  - ]
     308                 :            :     case PROP_STATE_ERROR:
     309                 :          1 :       sink->state_error = g_value_get_enum (value);
     310                 :          1 :       break;
     311                 :            :     case PROP_SILENT:
     312                 :         37 :       sink->silent = g_value_get_boolean (value);
     313                 :         37 :       break;
     314                 :            :     case PROP_DUMP:
     315                 :          0 :       sink->dump = g_value_get_boolean (value);
     316                 :          0 :       break;
     317                 :            :     case PROP_SIGNAL_HANDOFFS:
     318                 :         20 :       sink->signal_handoffs = g_value_get_boolean (value);
     319                 :         20 :       break;
     320                 :            :     case PROP_CAN_ACTIVATE_PUSH:
     321                 :          6 :       GST_BASE_SINK (sink)->can_activate_push = g_value_get_boolean (value);
     322                 :          6 :       break;
     323                 :            :     case PROP_CAN_ACTIVATE_PULL:
     324                 :         12 :       GST_BASE_SINK (sink)->can_activate_pull = g_value_get_boolean (value);
     325                 :         12 :       break;
     326                 :            :     case PROP_NUM_BUFFERS:
     327                 :          3 :       sink->num_buffers = g_value_get_int (value);
     328                 :          3 :       break;
     329                 :            :     default:
     330                 :          0 :       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
     331                 :          0 :       break;
     332                 :            :   }
     333                 :         79 : }
     334                 :            : 
     335                 :            : static void
     336                 :          0 : gst_fake_sink_get_property (GObject * object, guint prop_id, GValue * value,
     337                 :            :     GParamSpec * pspec)
     338                 :            : {
     339                 :            :   GstFakeSink *sink;
     340                 :            : 
     341                 :          0 :   sink = GST_FAKE_SINK (object);
     342                 :            : 
     343   [ #  #  #  #  :          0 :   switch (prop_id) {
             #  #  #  #  
                      # ]
     344                 :            :     case PROP_STATE_ERROR:
     345                 :          0 :       g_value_set_enum (value, sink->state_error);
     346                 :          0 :       break;
     347                 :            :     case PROP_SILENT:
     348                 :          0 :       g_value_set_boolean (value, sink->silent);
     349                 :          0 :       break;
     350                 :            :     case PROP_DUMP:
     351                 :          0 :       g_value_set_boolean (value, sink->dump);
     352                 :          0 :       break;
     353                 :            :     case PROP_SIGNAL_HANDOFFS:
     354                 :          0 :       g_value_set_boolean (value, sink->signal_handoffs);
     355                 :          0 :       break;
     356                 :            :     case PROP_LAST_MESSAGE:
     357                 :          0 :       GST_OBJECT_LOCK (sink);
     358                 :          0 :       g_value_set_string (value, sink->last_message);
     359                 :          0 :       GST_OBJECT_UNLOCK (sink);
     360                 :          0 :       break;
     361                 :            :     case PROP_CAN_ACTIVATE_PUSH:
     362                 :          0 :       g_value_set_boolean (value, GST_BASE_SINK (sink)->can_activate_push);
     363                 :          0 :       break;
     364                 :            :     case PROP_CAN_ACTIVATE_PULL:
     365                 :          0 :       g_value_set_boolean (value, GST_BASE_SINK (sink)->can_activate_pull);
     366                 :          0 :       break;
     367                 :            :     case PROP_NUM_BUFFERS:
     368                 :          0 :       g_value_set_int (value, sink->num_buffers);
     369                 :          0 :       break;
     370                 :            :     default:
     371                 :          0 :       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
     372                 :          0 :       break;
     373                 :            :   }
     374                 :          0 : }
     375                 :            : 
     376                 :            : static void
     377                 :     833388 : gst_fake_sink_notify_last_message (GstFakeSink * sink)
     378                 :            : {
     379                 :            :   /* FIXME: this hacks around a bug in GLib/GObject: doing concurrent
     380                 :            :    * g_object_notify() on the same object might lead to crashes, see
     381                 :            :    * http://bugzilla.gnome.org/show_bug.cgi?id=166020#c60 and follow-ups.
     382                 :            :    * So we really don't want to do a g_object_notify() here for out-of-band
     383                 :            :    * events with the streaming thread possibly also doing a g_object_notify()
     384                 :            :    * for an in-band buffer or event. This is fixed in GLib >= 2.26 */
     385                 :            : #if !GLIB_CHECK_VERSION(2,26,0)
     386                 :            :   g_static_rec_mutex_lock (&sink->notify_lock);
     387                 :            :   g_object_notify ((GObject *) sink, "last-message");
     388                 :            :   g_static_rec_mutex_unlock (&sink->notify_lock);
     389                 :            : #else
     390                 :     833388 :   g_object_notify_by_pspec ((GObject *) sink, pspec_last_message);
     391                 :            : #endif
     392                 :     833438 : }
     393                 :            : 
     394                 :            : static gboolean
     395                 :     147525 : gst_fake_sink_event (GstBaseSink * bsink, GstEvent * event)
     396                 :            : {
     397                 :     147525 :   GstFakeSink *sink = GST_FAKE_SINK (bsink);
     398                 :            : 
     399         [ +  + ]:     147528 :   if (!sink->silent) {
     400                 :            :     const GstStructure *s;
     401                 :            :     gchar *sstr;
     402                 :            : 
     403                 :     147513 :     GST_OBJECT_LOCK (sink);
     404                 :     147513 :     g_free (sink->last_message);
     405                 :            : 
     406         [ -  + ]:     147497 :     if (GST_EVENT_TYPE (event) == GST_EVENT_SINK_MESSAGE) {
     407                 :            :       GstMessage *msg;
     408                 :            : 
     409                 :          0 :       gst_event_parse_sink_message (event, &msg);
     410                 :          0 :       sstr = gst_structure_to_string (msg->structure);
     411                 :          0 :       sink->last_message =
     412                 :          0 :           g_strdup_printf ("message ******* M (type: %d, %s) %p",
     413                 :          0 :           GST_MESSAGE_TYPE (msg), sstr, msg);
     414                 :          0 :       gst_message_unref (msg);
     415                 :            :     } else {
     416         [ +  + ]:     147497 :       if ((s = gst_event_get_structure (event))) {
     417                 :        139 :         sstr = gst_structure_to_string (s);
     418                 :            :       } else {
     419                 :     147373 :         sstr = g_strdup ("");
     420                 :            :       }
     421                 :            : 
     422                 :     147476 :       sink->last_message =
     423                 :     147509 :           g_strdup_printf ("event   ******* E (type: %d, %s) %p",
     424                 :     147509 :           GST_EVENT_TYPE (event), sstr, event);
     425                 :            :     }
     426                 :     147476 :     g_free (sstr);
     427                 :     147500 :     GST_OBJECT_UNLOCK (sink);
     428                 :            : 
     429                 :     147509 :     gst_fake_sink_notify_last_message (sink);
     430                 :            :   }
     431                 :            : 
     432         [ -  + ]:     147528 :   if (GST_BASE_SINK_CLASS (parent_class)->event) {
     433                 :          0 :     return GST_BASE_SINK_CLASS (parent_class)->event (bsink, event);
     434                 :            :   } else {
     435                 :     147529 :     return TRUE;
     436                 :            :   }
     437                 :            : }
     438                 :            : 
     439                 :            : static GstFlowReturn
     440                 :        184 : gst_fake_sink_preroll (GstBaseSink * bsink, GstBuffer * buffer)
     441                 :            : {
     442                 :        184 :   GstFakeSink *sink = GST_FAKE_SINK (bsink);
     443                 :            : 
     444         [ -  + ]:        184 :   if (sink->num_buffers_left == 0)
     445                 :          0 :     goto eos;
     446                 :            : 
     447         [ +  + ]:        184 :   if (!sink->silent) {
     448                 :        163 :     GST_OBJECT_LOCK (sink);
     449                 :        163 :     g_free (sink->last_message);
     450                 :            : 
     451                 :        163 :     sink->last_message = g_strdup_printf ("preroll   ******* ");
     452                 :        163 :     GST_OBJECT_UNLOCK (sink);
     453                 :            : 
     454                 :        163 :     gst_fake_sink_notify_last_message (sink);
     455                 :            :   }
     456         [ +  + ]:        184 :   if (sink->signal_handoffs) {
     457                 :         25 :     g_signal_emit (sink,
     458                 :            :         gst_fake_sink_signals[SIGNAL_PREROLL_HANDOFF], 0, buffer,
     459                 :            :         bsink->sinkpad);
     460                 :            :   }
     461                 :        184 :   return GST_FLOW_OK;
     462                 :            : 
     463                 :            :   /* ERRORS */
     464                 :            : eos:
     465                 :            :   {
     466         [ #  # ]:          0 :     GST_DEBUG_OBJECT (sink, "we are EOS");
     467                 :        184 :     return GST_FLOW_UNEXPECTED;
     468                 :            :   }
     469                 :            : }
     470                 :            : 
     471                 :            : static GstFlowReturn
     472                 :     686005 : gst_fake_sink_render (GstBaseSink * bsink, GstBuffer * buf)
     473                 :            : {
     474                 :     686005 :   GstFakeSink *sink = GST_FAKE_SINK_CAST (bsink);
     475                 :            : 
     476         [ +  + ]:     686005 :   if (sink->num_buffers_left == 0)
     477                 :          1 :     goto eos;
     478                 :            : 
     479         [ +  + ]:     686004 :   if (sink->num_buffers_left != -1)
     480                 :          3 :     sink->num_buffers_left--;
     481                 :            : 
     482         [ +  + ]:     686004 :   if (!sink->silent) {
     483                 :            :     gchar ts_str[64], dur_str[64];
     484                 :            :     gchar flag_str[100];
     485                 :            : 
     486                 :     685765 :     GST_OBJECT_LOCK (sink);
     487                 :     685765 :     g_free (sink->last_message);
     488                 :            : 
     489         [ +  - ]:     685765 :     if (GST_BUFFER_TIMESTAMP (buf) != GST_CLOCK_TIME_NONE) {
     490 [ +  - ][ +  - ]:     685765 :       g_snprintf (ts_str, sizeof (ts_str), "%" GST_TIME_FORMAT,
         [ +  - ][ +  - ]
     491                 :    5486120 :           GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)));
     492                 :            :     } else {
     493                 :          0 :       g_strlcpy (ts_str, "none", sizeof (ts_str));
     494                 :            :     }
     495                 :            : 
     496         [ +  + ]:     685759 :     if (GST_BUFFER_DURATION (buf) != GST_CLOCK_TIME_NONE) {
     497 [ +  - ][ +  - ]:       5013 :       g_snprintf (dur_str, sizeof (dur_str), "%" GST_TIME_FORMAT,
         [ +  - ][ +  - ]
     498                 :      40104 :           GST_TIME_ARGS (GST_BUFFER_DURATION (buf)));
     499                 :            :     } else {
     500                 :     680746 :       g_strlcpy (dur_str, "none", sizeof (dur_str));
     501                 :            :     }
     502                 :            : 
     503                 :            :     {
     504                 :     685753 :       const char *flag_list[12] = {
     505                 :            :         "ro", "media4", "", "",
     506                 :            :         "preroll", "discont", "incaps", "gap",
     507                 :            :         "delta_unit", "media1", "media2", "media3"
     508                 :            :       };
     509                 :            :       int i;
     510                 :     685753 :       char *end = flag_str;
     511                 :     685753 :       end[0] = '\0';
     512         [ +  + ]:    8914692 :       for (i = 0; i < 12; i++) {
     513         [ +  + ]:    8228939 :         if (GST_MINI_OBJECT_CAST (buf)->flags & (1 << i)) {
     514                 :         90 :           strcpy (end, flag_list[i]);
     515                 :         90 :           end += strlen (end);
     516                 :         90 :           end[0] = ' ';
     517                 :         90 :           end[1] = '\0';
     518                 :         90 :           end++;
     519                 :            :         }
     520                 :            :       }
     521                 :            :     }
     522                 :            : 
     523                 :     685758 :     sink->last_message =
     524                 :     685753 :         g_strdup_printf ("chain   ******* < (%5d bytes, timestamp: %s"
     525                 :            :         ", duration: %s, offset: %" G_GINT64_FORMAT ", offset_end: %"
     526                 :            :         G_GINT64_FORMAT ", flags: %d %s) %p", GST_BUFFER_SIZE (buf), ts_str,
     527                 :            :         dur_str, GST_BUFFER_OFFSET (buf), GST_BUFFER_OFFSET_END (buf),
     528                 :            :         GST_MINI_OBJECT_CAST (buf)->flags, flag_str, buf);
     529                 :     685758 :     GST_OBJECT_UNLOCK (sink);
     530                 :            : 
     531                 :     685763 :     gst_fake_sink_notify_last_message (sink);
     532                 :            :   }
     533         [ +  + ]:     686004 :   if (sink->signal_handoffs)
     534                 :         62 :     g_signal_emit (sink, gst_fake_sink_signals[SIGNAL_HANDOFF], 0, buf,
     535                 :            :         bsink->sinkpad);
     536                 :            : 
     537         [ -  + ]:     686004 :   if (sink->dump) {
     538                 :          0 :     gst_util_dump_mem (GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
     539                 :            :   }
     540         [ +  + ]:     686004 :   if (sink->num_buffers_left == 0)
     541                 :          2 :     goto eos;
     542                 :            : 
     543                 :     686002 :   return GST_FLOW_OK;
     544                 :            : 
     545                 :            :   /* ERRORS */
     546                 :            : eos:
     547                 :            :   {
     548         [ -  + ]:          3 :     GST_DEBUG_OBJECT (sink, "we are EOS");
     549                 :     686005 :     return GST_FLOW_UNEXPECTED;
     550                 :            :   }
     551                 :            : }
     552                 :            : 
     553                 :            : static GstStateChangeReturn
     554                 :       1493 : gst_fake_sink_change_state (GstElement * element, GstStateChange transition)
     555                 :            : {
     556                 :       1493 :   GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
     557                 :       1493 :   GstFakeSink *fakesink = GST_FAKE_SINK (element);
     558                 :            : 
     559   [ +  +  +  + ]:       1493 :   switch (transition) {
     560                 :            :     case GST_STATE_CHANGE_NULL_TO_READY:
     561         [ +  + ]:        218 :       if (fakesink->state_error == FAKE_SINK_STATE_ERROR_NULL_READY)
     562                 :          1 :         goto error;
     563                 :        217 :       break;
     564                 :            :     case GST_STATE_CHANGE_READY_TO_PAUSED:
     565         [ -  + ]:        416 :       if (fakesink->state_error == FAKE_SINK_STATE_ERROR_READY_PAUSED)
     566                 :          0 :         goto error;
     567                 :        416 :       fakesink->num_buffers_left = fakesink->num_buffers;
     568                 :        416 :       break;
     569                 :            :     case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
     570         [ -  + ]:        114 :       if (fakesink->state_error == FAKE_SINK_STATE_ERROR_PAUSED_PLAYING)
     571                 :          0 :         goto error;
     572                 :        114 :       break;
     573                 :            :     default:
     574                 :        745 :       break;
     575                 :            :   }
     576                 :            : 
     577                 :       1492 :   ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
     578                 :            : 
     579   [ +  +  +  + ]:       1492 :   switch (transition) {
     580                 :            :     case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
     581         [ -  + ]:        113 :       if (fakesink->state_error == FAKE_SINK_STATE_ERROR_PLAYING_PAUSED)
     582                 :          0 :         goto error;
     583                 :        113 :       break;
     584                 :            :     case GST_STATE_CHANGE_PAUSED_TO_READY:
     585         [ -  + ]:        416 :       if (fakesink->state_error == FAKE_SINK_STATE_ERROR_PAUSED_READY)
     586                 :          0 :         goto error;
     587                 :        416 :       break;
     588                 :            :     case GST_STATE_CHANGE_READY_TO_NULL:
     589         [ -  + ]:        216 :       if (fakesink->state_error == FAKE_SINK_STATE_ERROR_READY_NULL)
     590                 :          0 :         goto error;
     591                 :        216 :       GST_OBJECT_LOCK (fakesink);
     592                 :        216 :       g_free (fakesink->last_message);
     593                 :        216 :       fakesink->last_message = NULL;
     594                 :        216 :       GST_OBJECT_UNLOCK (fakesink);
     595                 :        216 :       break;
     596                 :            :     default:
     597                 :        747 :       break;
     598                 :            :   }
     599                 :            : 
     600                 :       1492 :   return ret;
     601                 :            : 
     602                 :            :   /* ERROR */
     603                 :            : error:
     604 [ -  + ][ #  # ]:          1 :   GST_ELEMENT_ERROR (element, CORE, STATE_CHANGE, (NULL),
         [ +  - ][ -  + ]
     605                 :            :       ("Erroring out on state change as requested"));
     606                 :       1493 :   return GST_STATE_CHANGE_FAILURE;
     607                 :            : }

Generated by: LCOV version 1.9