gstreamer_core/plugins/elements/gstfakesrc.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  *                    2000 Wim Taymans <wim@fluendo.com>
       
     4  *
       
     5  * gstfakesrc.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-fakesrc
       
    24  * @short_description: Generate (meaningless) buffers
       
    25  * @see_also: #GstFakeSink
       
    26  *
       
    27  * <refsect2>
       
    28  * <para>
       
    29  * The fakesrc element is a multipurpose element that can generate
       
    30  * a wide range of buffers and can operate in various scheduling modes.
       
    31  * </para>
       
    32  * <para>
       
    33  * It is mostly used as a testing element, one trivial example for testing
       
    34  * basic <application>GStreamer</application> core functionality is:
       
    35  * </para>
       
    36  * <title>Example launch line</title>
       
    37  * <para>
       
    38  * <programlisting>
       
    39  * gst-launch -v fakesrc num-buffers=5 ! fakesink
       
    40  * </programlisting>
       
    41  * This pipeline will push 5 empty buffers to the fakesink element and then
       
    42  * sends an EOS.
       
    43  * </para>
       
    44  * <para>
       
    45  * Last reviewed on 2005-12-02 (0.9.7)
       
    46  * </para>
       
    47  * </refsect2>
       
    48  */
       
    49 
       
    50 #ifdef HAVE_CONFIG_H
       
    51 #  include "config.h"
       
    52 #endif
       
    53 #ifdef __SYMBIAN32__
       
    54 #include <gst_global.h>
       
    55 #endif
       
    56 
       
    57 #include <stdlib.h>
       
    58 #include <string.h>
       
    59 
       
    60 #include "gstfakesrc.h"
       
    61 #include <gst/gstmarshal.h>
       
    62 #ifdef __SYMBIAN32__
       
    63 #include <glib_global.h>
       
    64 #include <gobject_global.h>
       
    65 #include <gstelement.h>
       
    66 #endif
       
    67 
       
    68 static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
       
    69     GST_PAD_SRC,
       
    70     GST_PAD_ALWAYS,
       
    71     GST_STATIC_CAPS_ANY);
       
    72 
       
    73 GST_DEBUG_CATEGORY_STATIC (gst_fake_src_debug);
       
    74 #define GST_CAT_DEFAULT gst_fake_src_debug
       
    75 
       
    76 
       
    77 /* FakeSrc signals and args */
       
    78 enum
       
    79 {
       
    80   /* FILL ME */
       
    81   SIGNAL_HANDOFF,
       
    82   LAST_SIGNAL
       
    83 };
       
    84 
       
    85 #define DEFAULT_OUTPUT          FAKE_SRC_FIRST_LAST_LOOP
       
    86 #define DEFAULT_DATA            FAKE_SRC_DATA_ALLOCATE
       
    87 #define DEFAULT_SIZETYPE        FAKE_SRC_SIZETYPE_EMPTY
       
    88 #define DEFAULT_SIZEMIN         0
       
    89 #define DEFAULT_SIZEMAX         4096
       
    90 #define DEFAULT_FILLTYPE        FAKE_SRC_FILLTYPE_ZERO
       
    91 #define DEFAULT_DATARATE        0
       
    92 #define DEFAULT_SYNC            FALSE
       
    93 #define DEFAULT_PATTERN         NULL
       
    94 #define DEFAULT_EOS             FALSE
       
    95 #define DEFAULT_SIGNAL_HANDOFFS FALSE
       
    96 #define DEFAULT_SILENT          FALSE
       
    97 #define DEFAULT_DUMP            FALSE
       
    98 #define DEFAULT_PARENTSIZE      4096*10
       
    99 #define DEFAULT_CAN_ACTIVATE_PULL TRUE
       
   100 #define DEFAULT_CAN_ACTIVATE_PUSH TRUE
       
   101 
       
   102 enum
       
   103 {
       
   104   PROP_0,
       
   105   PROP_OUTPUT,
       
   106   PROP_DATA,
       
   107   PROP_SIZETYPE,
       
   108   PROP_SIZEMIN,
       
   109   PROP_SIZEMAX,
       
   110   PROP_FILLTYPE,
       
   111   PROP_DATARATE,
       
   112   PROP_SYNC,
       
   113   PROP_PATTERN,
       
   114   PROP_EOS,
       
   115   PROP_SIGNAL_HANDOFFS,
       
   116   PROP_SILENT,
       
   117   PROP_DUMP,
       
   118   PROP_PARENTSIZE,
       
   119   PROP_LAST_MESSAGE,
       
   120   PROP_CAN_ACTIVATE_PULL,
       
   121   PROP_CAN_ACTIVATE_PUSH,
       
   122   PROP_IS_LIVE
       
   123 };
       
   124 
       
   125 /* not implemented
       
   126 #define GST_TYPE_FAKE_SRC_OUTPUT (gst_fake_src_output_get_type())
       
   127 static GType
       
   128 gst_fake_src_output_get_type (void)
       
   129 {
       
   130   static GType fakesrc_output_type = 0;
       
   131   static const GEnumValue fakesrc_output[] = {
       
   132     {FAKE_SRC_FIRST_LAST_LOOP, "1", "First-Last loop"},
       
   133     {FAKE_SRC_LAST_FIRST_LOOP, "2", "Last-First loop"},
       
   134     {FAKE_SRC_PING_PONG, "3", "Ping-Pong"},
       
   135     {FAKE_SRC_ORDERED_RANDOM, "4", "Ordered Random"},
       
   136     {FAKE_SRC_RANDOM, "5", "Random"},
       
   137     {FAKE_SRC_PATTERN_LOOP, "6", "Patttern loop"},
       
   138     {FAKE_SRC_PING_PONG_PATTERN, "7", "Ping-Pong Pattern"},
       
   139     {FAKE_SRC_GET_ALWAYS_SUCEEDS, "8", "'_get' Always succeeds"},
       
   140     {0, NULL, NULL},
       
   141   };
       
   142 
       
   143   if (!fakesrc_output_type) {
       
   144     fakesrc_output_type =
       
   145         g_enum_register_static ("GstFakeSrcOutput", fakesrc_output);
       
   146   }
       
   147   return fakesrc_output_type;
       
   148 }
       
   149 */
       
   150 
       
   151 #define GST_TYPE_FAKE_SRC_DATA (gst_fake_src_data_get_type())
       
   152 static GType
       
   153 gst_fake_src_data_get_type (void)
       
   154 {
       
   155   static GType fakesrc_data_type = 0;
       
   156   static const GEnumValue fakesrc_data[] = {
       
   157     {FAKE_SRC_DATA_ALLOCATE, "Allocate data", "allocate"},
       
   158     {FAKE_SRC_DATA_SUBBUFFER, "Subbuffer data", "subbuffer"},
       
   159     {0, NULL, NULL},
       
   160   };
       
   161 
       
   162   if (!fakesrc_data_type) {
       
   163     fakesrc_data_type =
       
   164         g_enum_register_static ("GstFakeSrcDataType", fakesrc_data);
       
   165   }
       
   166   return fakesrc_data_type;
       
   167 }
       
   168 
       
   169 #define GST_TYPE_FAKE_SRC_SIZETYPE (gst_fake_src_sizetype_get_type())
       
   170 static GType
       
   171 gst_fake_src_sizetype_get_type (void)
       
   172 {
       
   173   static GType fakesrc_sizetype_type = 0;
       
   174   static const GEnumValue fakesrc_sizetype[] = {
       
   175     {FAKE_SRC_SIZETYPE_EMPTY, "Send empty buffers", "empty"},
       
   176     {FAKE_SRC_SIZETYPE_FIXED, "Fixed size buffers (sizemax sized)", "fixed"},
       
   177     {FAKE_SRC_SIZETYPE_RANDOM,
       
   178         "Random sized buffers (sizemin <= size <= sizemax)", "random"},
       
   179     {0, NULL, NULL},
       
   180   };
       
   181 
       
   182   if (!fakesrc_sizetype_type) {
       
   183     fakesrc_sizetype_type =
       
   184         g_enum_register_static ("GstFakeSrcSizeType", fakesrc_sizetype);
       
   185   }
       
   186   return fakesrc_sizetype_type;
       
   187 }
       
   188 
       
   189 #define GST_TYPE_FAKE_SRC_FILLTYPE (gst_fake_src_filltype_get_type())
       
   190 static GType
       
   191 gst_fake_src_filltype_get_type (void)
       
   192 {
       
   193   static GType fakesrc_filltype_type = 0;
       
   194   static const GEnumValue fakesrc_filltype[] = {
       
   195     {FAKE_SRC_FILLTYPE_NOTHING, "Leave data as malloced", "nothing"},
       
   196     {FAKE_SRC_FILLTYPE_ZERO, "Fill buffers with zeros", "zero"},
       
   197     {FAKE_SRC_FILLTYPE_RANDOM, "Fill buffers with random crap", "random"},
       
   198     {FAKE_SRC_FILLTYPE_PATTERN, "Fill buffers with pattern 0x00 -> 0xff",
       
   199         "pattern"},
       
   200     {FAKE_SRC_FILLTYPE_PATTERN_CONT,
       
   201           "Fill buffers with pattern 0x00 -> 0xff that spans buffers",
       
   202         "pattern-span"},
       
   203     {0, NULL, NULL},
       
   204   };
       
   205 
       
   206   if (!fakesrc_filltype_type) {
       
   207     fakesrc_filltype_type =
       
   208         g_enum_register_static ("GstFakeSrcFillType", fakesrc_filltype);
       
   209   }
       
   210   return fakesrc_filltype_type;
       
   211 }
       
   212 
       
   213 #define _do_init(bla) \
       
   214     GST_DEBUG_CATEGORY_INIT (gst_fake_src_debug, "fakesrc", 0, "fakesrc element");
       
   215 
       
   216 GST_BOILERPLATE_FULL (GstFakeSrc, gst_fake_src, GstBaseSrc, GST_TYPE_BASE_SRC,
       
   217     _do_init);
       
   218 
       
   219 static void gst_fake_src_finalize (GObject * object);
       
   220 static void gst_fake_src_set_property (GObject * object, guint prop_id,
       
   221     const GValue * value, GParamSpec * pspec);
       
   222 static void gst_fake_src_get_property (GObject * object, guint prop_id,
       
   223     GValue * value, GParamSpec * pspec);
       
   224 
       
   225 static gboolean gst_fake_src_start (GstBaseSrc * basesrc);
       
   226 static gboolean gst_fake_src_stop (GstBaseSrc * basesrc);
       
   227 static gboolean gst_fake_src_is_seekable (GstBaseSrc * basesrc);
       
   228 
       
   229 static gboolean gst_fake_src_event_handler (GstBaseSrc * src, GstEvent * event);
       
   230 static void gst_fake_src_get_times (GstBaseSrc * basesrc, GstBuffer * buffer,
       
   231     GstClockTime * start, GstClockTime * end);
       
   232 static GstFlowReturn gst_fake_src_create (GstBaseSrc * src, guint64 offset,
       
   233     guint length, GstBuffer ** buf);
       
   234 
       
   235 static guint gst_fake_src_signals[LAST_SIGNAL] = { 0 };
       
   236 
       
   237 static void
       
   238 gst_fake_src_base_init (gpointer g_class)
       
   239 {
       
   240   GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
       
   241 
       
   242   gst_element_class_set_details_simple (gstelement_class,
       
   243       "Fake Source",
       
   244       "Source",
       
   245       "Push empty (no data) buffers around",
       
   246       "Erik Walthinsen <omega@cse.ogi.edu>, " "Wim Taymans <wim@fluendo.com>");
       
   247   gst_element_class_add_pad_template (gstelement_class,
       
   248       gst_static_pad_template_get (&srctemplate));
       
   249 }
       
   250 
       
   251 static void
       
   252 gst_fake_src_class_init (GstFakeSrcClass * klass)
       
   253 {
       
   254   GObjectClass *gobject_class;
       
   255   GstElementClass *gstelement_class;
       
   256   GstBaseSrcClass *gstbase_src_class;
       
   257 
       
   258   gobject_class = G_OBJECT_CLASS (klass);
       
   259   gstelement_class = GST_ELEMENT_CLASS (klass);
       
   260   gstbase_src_class = GST_BASE_SRC_CLASS (klass);
       
   261 
       
   262   gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_fake_src_finalize);
       
   263 
       
   264   gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_fake_src_set_property);
       
   265   gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_fake_src_get_property);
       
   266 
       
   267 /*
       
   268   FIXME: this is not implemented; would make sense once basesrc and fakesrc
       
   269   support multiple pads
       
   270   g_object_class_install_property (gobject_class, PROP_OUTPUT,
       
   271       g_param_spec_enum ("output", "output", "Output method (currently unused)",
       
   272           GST_TYPE_FAKE_SRC_OUTPUT, DEFAULT_OUTPUT, G_PARAM_READWRITE));
       
   273 */
       
   274   g_object_class_install_property (gobject_class, PROP_DATA,
       
   275       g_param_spec_enum ("data", "data", "Data allocation method",
       
   276           GST_TYPE_FAKE_SRC_DATA, DEFAULT_DATA, G_PARAM_READWRITE));
       
   277   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_SIZETYPE,
       
   278       g_param_spec_enum ("sizetype", "sizetype",
       
   279           "How to determine buffer sizes", GST_TYPE_FAKE_SRC_SIZETYPE,
       
   280           DEFAULT_SIZETYPE, G_PARAM_READWRITE));
       
   281   g_object_class_install_property (gobject_class, PROP_SIZEMIN,
       
   282       g_param_spec_int ("sizemin", "sizemin", "Minimum buffer size", 0,
       
   283           G_MAXINT, DEFAULT_SIZEMIN, G_PARAM_READWRITE));
       
   284   g_object_class_install_property (gobject_class, PROP_SIZEMAX,
       
   285       g_param_spec_int ("sizemax", "sizemax", "Maximum buffer size", 0,
       
   286           G_MAXINT, DEFAULT_SIZEMAX, G_PARAM_READWRITE));
       
   287   g_object_class_install_property (gobject_class, PROP_PARENTSIZE,
       
   288       g_param_spec_int ("parentsize", "parentsize",
       
   289           "Size of parent buffer for sub-buffered allocation", 0, G_MAXINT,
       
   290           DEFAULT_PARENTSIZE, G_PARAM_READWRITE));
       
   291   g_object_class_install_property (gobject_class, PROP_FILLTYPE,
       
   292       g_param_spec_enum ("filltype", "filltype",
       
   293           "How to fill the buffer, if at all", GST_TYPE_FAKE_SRC_FILLTYPE,
       
   294           DEFAULT_FILLTYPE, G_PARAM_READWRITE));
       
   295   g_object_class_install_property (gobject_class, PROP_DATARATE,
       
   296       g_param_spec_int ("datarate", "Datarate",
       
   297           "Timestamps buffers with number of bytes per second (0 = none)", 0,
       
   298           G_MAXINT, DEFAULT_DATARATE, G_PARAM_READWRITE));
       
   299   g_object_class_install_property (gobject_class, PROP_SYNC,
       
   300       g_param_spec_boolean ("sync", "Sync", "Sync to the clock to the datarate",
       
   301           DEFAULT_SYNC, G_PARAM_READWRITE));
       
   302   g_object_class_install_property (gobject_class, PROP_PATTERN,
       
   303       g_param_spec_string ("pattern", "pattern", "pattern", DEFAULT_PATTERN,
       
   304           G_PARAM_READWRITE));
       
   305   g_object_class_install_property (gobject_class, PROP_LAST_MESSAGE,
       
   306       g_param_spec_string ("last-message", "last-message",
       
   307           "The last status message", NULL, G_PARAM_READABLE));
       
   308   g_object_class_install_property (gobject_class, PROP_SILENT,
       
   309       g_param_spec_boolean ("silent", "Silent",
       
   310           "Don't produce last_message events", DEFAULT_SILENT,
       
   311           G_PARAM_READWRITE));
       
   312   g_object_class_install_property (gobject_class, PROP_SIGNAL_HANDOFFS,
       
   313       g_param_spec_boolean ("signal-handoffs", "Signal handoffs",
       
   314           "Send a signal before pushing the buffer", DEFAULT_SIGNAL_HANDOFFS,
       
   315           G_PARAM_READWRITE));
       
   316   g_object_class_install_property (gobject_class, PROP_DUMP,
       
   317       g_param_spec_boolean ("dump", "Dump", "Dump buffer contents to stdout",
       
   318           DEFAULT_DUMP, G_PARAM_READWRITE));
       
   319   g_object_class_install_property (gobject_class,
       
   320       PROP_CAN_ACTIVATE_PUSH,
       
   321       g_param_spec_boolean ("can-activate-push", "Can activate push",
       
   322           "Can activate in push mode", DEFAULT_CAN_ACTIVATE_PUSH,
       
   323           G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
       
   324   g_object_class_install_property (gobject_class,
       
   325       PROP_CAN_ACTIVATE_PULL,
       
   326       g_param_spec_boolean ("can-activate-pull", "Can activate pull",
       
   327           "Can activate in pull mode", DEFAULT_CAN_ACTIVATE_PULL,
       
   328           G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
       
   329   g_object_class_install_property (gobject_class, PROP_IS_LIVE,
       
   330       g_param_spec_boolean ("is-live", "Is this a live source",
       
   331           "True if the element cannot produce data in PAUSED", FALSE,
       
   332           G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
       
   333 
       
   334   /**
       
   335    * GstFakeSrc::handoff:
       
   336    * @fakesrc: the fakesrc instance
       
   337    * @buffer: the buffer that will be pushed
       
   338    * @pad: the pad that will sent it
       
   339    *
       
   340    * This signal gets emitted before sending the buffer.
       
   341    */
       
   342   gst_fake_src_signals[SIGNAL_HANDOFF] =
       
   343       g_signal_new ("handoff", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
       
   344       G_STRUCT_OFFSET (GstFakeSrcClass, handoff), NULL, NULL,
       
   345       gst_marshal_VOID__OBJECT_OBJECT, G_TYPE_NONE, 2, GST_TYPE_BUFFER,
       
   346       GST_TYPE_PAD);
       
   347 
       
   348   gstbase_src_class->is_seekable = GST_DEBUG_FUNCPTR (gst_fake_src_is_seekable);
       
   349   gstbase_src_class->start = GST_DEBUG_FUNCPTR (gst_fake_src_start);
       
   350   gstbase_src_class->stop = GST_DEBUG_FUNCPTR (gst_fake_src_stop);
       
   351   gstbase_src_class->event = GST_DEBUG_FUNCPTR (gst_fake_src_event_handler);
       
   352   gstbase_src_class->get_times = GST_DEBUG_FUNCPTR (gst_fake_src_get_times);
       
   353   gstbase_src_class->create = GST_DEBUG_FUNCPTR (gst_fake_src_create);
       
   354 }
       
   355 
       
   356 static void
       
   357 gst_fake_src_init (GstFakeSrc * fakesrc, GstFakeSrcClass * g_class)
       
   358 {
       
   359   fakesrc->output = FAKE_SRC_FIRST_LAST_LOOP;
       
   360   fakesrc->buffer_count = 0;
       
   361   fakesrc->silent = DEFAULT_SILENT;
       
   362   fakesrc->signal_handoffs = DEFAULT_SIGNAL_HANDOFFS;
       
   363   fakesrc->dump = DEFAULT_DUMP;
       
   364   fakesrc->pattern_byte = 0x00;
       
   365   fakesrc->data = FAKE_SRC_DATA_ALLOCATE;
       
   366   fakesrc->sizetype = FAKE_SRC_SIZETYPE_EMPTY;
       
   367   fakesrc->filltype = FAKE_SRC_FILLTYPE_NOTHING;
       
   368   fakesrc->sizemin = DEFAULT_SIZEMIN;
       
   369   fakesrc->sizemax = DEFAULT_SIZEMAX;
       
   370   fakesrc->parent = NULL;
       
   371   fakesrc->parentsize = DEFAULT_PARENTSIZE;
       
   372   fakesrc->last_message = NULL;
       
   373   fakesrc->datarate = DEFAULT_DATARATE;
       
   374   fakesrc->sync = DEFAULT_SYNC;
       
   375 }
       
   376 
       
   377 static void
       
   378 gst_fake_src_finalize (GObject * object)
       
   379 {
       
   380   GstFakeSrc *src;
       
   381 
       
   382   src = GST_FAKE_SRC (object);
       
   383 
       
   384   g_free (src->last_message);
       
   385   if (src->parent) {
       
   386     gst_buffer_unref (src->parent);
       
   387     src->parent = NULL;
       
   388   }
       
   389 
       
   390   G_OBJECT_CLASS (parent_class)->finalize (object);
       
   391 }
       
   392 
       
   393 static gboolean
       
   394 gst_fake_src_event_handler (GstBaseSrc * basesrc, GstEvent * event)
       
   395 {
       
   396   GstFakeSrc *src;
       
   397 
       
   398   src = GST_FAKE_SRC (basesrc);
       
   399 
       
   400   if (!src->silent) {
       
   401     const GstStructure *s;
       
   402     gchar *sstr;
       
   403 
       
   404     GST_OBJECT_LOCK (src);
       
   405     g_free (src->last_message);
       
   406 
       
   407     if ((s = gst_event_get_structure (event)))
       
   408       sstr = gst_structure_to_string (s);
       
   409     else
       
   410       sstr = g_strdup ("");
       
   411 
       
   412     src->last_message =
       
   413         g_strdup_printf ("event   ******* E (type: %d, %s) %p",
       
   414         GST_EVENT_TYPE (event), sstr, event);
       
   415     g_free (sstr);
       
   416     GST_OBJECT_UNLOCK (src);
       
   417 
       
   418     g_object_notify (G_OBJECT (src), "last_message");
       
   419   }
       
   420 
       
   421 
       
   422   return TRUE;
       
   423 }
       
   424 
       
   425 static void
       
   426 gst_fake_src_alloc_parent (GstFakeSrc * src)
       
   427 {
       
   428   GstBuffer *buf;
       
   429 
       
   430   buf = gst_buffer_new ();
       
   431   GST_BUFFER_DATA (buf) = g_malloc (src->parentsize);
       
   432   GST_BUFFER_MALLOCDATA (buf) = GST_BUFFER_DATA (buf);
       
   433   GST_BUFFER_SIZE (buf) = src->parentsize;
       
   434 
       
   435   src->parent = buf;
       
   436   src->parentoffset = 0;
       
   437 }
       
   438 
       
   439 static void
       
   440 gst_fake_src_set_property (GObject * object, guint prop_id,
       
   441     const GValue * value, GParamSpec * pspec)
       
   442 {
       
   443   GstFakeSrc *src;
       
   444   GstBaseSrc *basesrc;
       
   445 
       
   446   src = GST_FAKE_SRC (object);
       
   447   basesrc = GST_BASE_SRC (object);
       
   448 
       
   449   switch (prop_id) {
       
   450     case PROP_OUTPUT:
       
   451       g_warning ("not yet implemented");
       
   452       break;
       
   453     case PROP_DATA:
       
   454       src->data = g_value_get_enum (value);
       
   455 
       
   456       if (src->data == FAKE_SRC_DATA_SUBBUFFER) {
       
   457         if (!src->parent)
       
   458           gst_fake_src_alloc_parent (src);
       
   459       } else {
       
   460         if (src->parent) {
       
   461           gst_buffer_unref (src->parent);
       
   462           src->parent = NULL;
       
   463         }
       
   464       }
       
   465       break;
       
   466     case PROP_SIZETYPE:
       
   467       src->sizetype = g_value_get_enum (value);
       
   468       break;
       
   469     case PROP_SIZEMIN:
       
   470       src->sizemin = g_value_get_int (value);
       
   471       break;
       
   472     case PROP_SIZEMAX:
       
   473       src->sizemax = g_value_get_int (value);
       
   474       break;
       
   475     case PROP_PARENTSIZE:
       
   476       src->parentsize = g_value_get_int (value);
       
   477       break;
       
   478     case PROP_FILLTYPE:
       
   479       src->filltype = g_value_get_enum (value);
       
   480       break;
       
   481     case PROP_DATARATE:
       
   482       src->datarate = g_value_get_int (value);
       
   483       break;
       
   484     case PROP_SYNC:
       
   485       src->sync = g_value_get_boolean (value);
       
   486       break;
       
   487     case PROP_PATTERN:
       
   488       break;
       
   489     case PROP_SILENT:
       
   490       src->silent = g_value_get_boolean (value);
       
   491       break;
       
   492     case PROP_SIGNAL_HANDOFFS:
       
   493       src->signal_handoffs = g_value_get_boolean (value);
       
   494       break;
       
   495     case PROP_DUMP:
       
   496       src->dump = g_value_get_boolean (value);
       
   497       break;
       
   498     case PROP_CAN_ACTIVATE_PUSH:
       
   499       g_return_if_fail (!GST_OBJECT_FLAG_IS_SET (object, GST_BASE_SRC_STARTED));
       
   500       GST_BASE_SRC (src)->can_activate_push = g_value_get_boolean (value);
       
   501       break;
       
   502     case PROP_CAN_ACTIVATE_PULL:
       
   503       g_return_if_fail (!GST_OBJECT_FLAG_IS_SET (object, GST_BASE_SRC_STARTED));
       
   504       src->can_activate_pull = g_value_get_boolean (value);
       
   505       break;
       
   506     case PROP_IS_LIVE:
       
   507       gst_base_src_set_live (basesrc, g_value_get_boolean (value));
       
   508       break;
       
   509     default:
       
   510       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       
   511       break;
       
   512   }
       
   513 }
       
   514 
       
   515 static void
       
   516 gst_fake_src_get_property (GObject * object, guint prop_id, GValue * value,
       
   517     GParamSpec * pspec)
       
   518 {
       
   519   GstFakeSrc *src;
       
   520   GstBaseSrc *basesrc;
       
   521 
       
   522   g_return_if_fail (GST_IS_FAKE_SRC (object));
       
   523 
       
   524   src = GST_FAKE_SRC (object);
       
   525   basesrc = GST_BASE_SRC (object);
       
   526 
       
   527   switch (prop_id) {
       
   528     case PROP_OUTPUT:
       
   529       g_value_set_enum (value, src->output);
       
   530       break;
       
   531     case PROP_DATA:
       
   532       g_value_set_enum (value, src->data);
       
   533       break;
       
   534     case PROP_SIZETYPE:
       
   535       g_value_set_enum (value, src->sizetype);
       
   536       break;
       
   537     case PROP_SIZEMIN:
       
   538       g_value_set_int (value, src->sizemin);
       
   539       break;
       
   540     case PROP_SIZEMAX:
       
   541       g_value_set_int (value, src->sizemax);
       
   542       break;
       
   543     case PROP_PARENTSIZE:
       
   544       g_value_set_int (value, src->parentsize);
       
   545       break;
       
   546     case PROP_FILLTYPE:
       
   547       g_value_set_enum (value, src->filltype);
       
   548       break;
       
   549     case PROP_DATARATE:
       
   550       g_value_set_int (value, src->datarate);
       
   551       break;
       
   552     case PROP_SYNC:
       
   553       g_value_set_boolean (value, src->sync);
       
   554       break;
       
   555     case PROP_PATTERN:
       
   556       g_value_set_string (value, src->pattern);
       
   557       break;
       
   558     case PROP_SILENT:
       
   559       g_value_set_boolean (value, src->silent);
       
   560       break;
       
   561     case PROP_SIGNAL_HANDOFFS:
       
   562       g_value_set_boolean (value, src->signal_handoffs);
       
   563       break;
       
   564     case PROP_DUMP:
       
   565       g_value_set_boolean (value, src->dump);
       
   566       break;
       
   567     case PROP_LAST_MESSAGE:
       
   568       GST_OBJECT_LOCK (src);
       
   569       g_value_set_string (value, src->last_message);
       
   570       GST_OBJECT_UNLOCK (src);
       
   571       break;
       
   572     case PROP_CAN_ACTIVATE_PUSH:
       
   573       g_value_set_boolean (value, GST_BASE_SRC (src)->can_activate_push);
       
   574       break;
       
   575     case PROP_CAN_ACTIVATE_PULL:
       
   576       g_value_set_boolean (value, src->can_activate_pull);
       
   577       break;
       
   578     case PROP_IS_LIVE:
       
   579       g_value_set_boolean (value, gst_base_src_is_live (basesrc));
       
   580       break;
       
   581     default:
       
   582       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       
   583       break;
       
   584   }
       
   585 }
       
   586 
       
   587 static void
       
   588 gst_fake_src_prepare_buffer (GstFakeSrc * src, GstBuffer * buf)
       
   589 {
       
   590   if (GST_BUFFER_SIZE (buf) == 0)
       
   591     return;
       
   592 
       
   593   switch (src->filltype) {
       
   594     case FAKE_SRC_FILLTYPE_ZERO:
       
   595       memset (GST_BUFFER_DATA (buf), 0, GST_BUFFER_SIZE (buf));
       
   596       break;
       
   597     case FAKE_SRC_FILLTYPE_RANDOM:
       
   598     {
       
   599       gint i;
       
   600       guint8 *ptr = GST_BUFFER_DATA (buf);
       
   601 
       
   602       for (i = GST_BUFFER_SIZE (buf); i; i--) {
       
   603         *ptr++ = g_random_int_range (0, 256);
       
   604       }
       
   605       break;
       
   606     }
       
   607     case FAKE_SRC_FILLTYPE_PATTERN:
       
   608       src->pattern_byte = 0x00;
       
   609     case FAKE_SRC_FILLTYPE_PATTERN_CONT:
       
   610     {
       
   611       gint i;
       
   612       guint8 *ptr = GST_BUFFER_DATA (buf);
       
   613 
       
   614       for (i = GST_BUFFER_SIZE (buf); i; i--) {
       
   615         *ptr++ = src->pattern_byte++;
       
   616       }
       
   617       break;
       
   618     }
       
   619     case FAKE_SRC_FILLTYPE_NOTHING:
       
   620     default:
       
   621       break;
       
   622   }
       
   623 }
       
   624 
       
   625 static GstBuffer *
       
   626 gst_fake_src_alloc_buffer (GstFakeSrc * src, guint size)
       
   627 {
       
   628   GstBuffer *buf;
       
   629 
       
   630   buf = gst_buffer_new ();
       
   631   GST_BUFFER_SIZE (buf) = size;
       
   632 
       
   633   if (size != 0) {
       
   634     switch (src->filltype) {
       
   635       case FAKE_SRC_FILLTYPE_NOTHING:
       
   636         GST_BUFFER_DATA (buf) = g_malloc (size);
       
   637         GST_BUFFER_MALLOCDATA (buf) = GST_BUFFER_DATA (buf);
       
   638         break;
       
   639       case FAKE_SRC_FILLTYPE_ZERO:
       
   640         GST_BUFFER_DATA (buf) = g_malloc0 (size);
       
   641         GST_BUFFER_MALLOCDATA (buf) = GST_BUFFER_DATA (buf);
       
   642         break;
       
   643       case FAKE_SRC_FILLTYPE_RANDOM:
       
   644       case FAKE_SRC_FILLTYPE_PATTERN:
       
   645       case FAKE_SRC_FILLTYPE_PATTERN_CONT:
       
   646       default:
       
   647         GST_BUFFER_DATA (buf) = g_malloc (size);
       
   648         GST_BUFFER_MALLOCDATA (buf) = GST_BUFFER_DATA (buf);
       
   649         gst_fake_src_prepare_buffer (src, buf);
       
   650         break;
       
   651     }
       
   652   }
       
   653 
       
   654   return buf;
       
   655 }
       
   656 
       
   657 static guint
       
   658 gst_fake_src_get_size (GstFakeSrc * src)
       
   659 {
       
   660   guint size;
       
   661 
       
   662   switch (src->sizetype) {
       
   663     case FAKE_SRC_SIZETYPE_FIXED:
       
   664       size = src->sizemax;
       
   665       break;
       
   666     case FAKE_SRC_SIZETYPE_RANDOM:
       
   667       size = g_random_int_range (src->sizemin, src->sizemax);
       
   668       break;
       
   669     case FAKE_SRC_SIZETYPE_EMPTY:
       
   670     default:
       
   671       size = 0;
       
   672       break;
       
   673   }
       
   674 
       
   675   return size;
       
   676 }
       
   677 
       
   678 static GstBuffer *
       
   679 gst_fake_src_create_buffer (GstFakeSrc * src)
       
   680 {
       
   681   GstBuffer *buf;
       
   682   guint size;
       
   683   gboolean dump = src->dump;
       
   684 
       
   685   size = gst_fake_src_get_size (src);
       
   686   if (size == 0)
       
   687     return gst_buffer_new ();
       
   688 
       
   689   switch (src->data) {
       
   690     case FAKE_SRC_DATA_ALLOCATE:
       
   691       buf = gst_fake_src_alloc_buffer (src, size);
       
   692       break;
       
   693     case FAKE_SRC_DATA_SUBBUFFER:
       
   694       /* see if we have a parent to subbuffer */
       
   695       if (!src->parent) {
       
   696         gst_fake_src_alloc_parent (src);
       
   697         g_assert (src->parent);
       
   698       }
       
   699       /* see if it's large enough */
       
   700       if ((GST_BUFFER_SIZE (src->parent) - src->parentoffset) >= size) {
       
   701         buf = gst_buffer_create_sub (src->parent, src->parentoffset, size);
       
   702         src->parentoffset += size;
       
   703       } else {
       
   704         /* the parent is useless now */
       
   705         gst_buffer_unref (src->parent);
       
   706         src->parent = NULL;
       
   707         /* try again (this will allocate a new parent) */
       
   708         return gst_fake_src_create_buffer (src);
       
   709       }
       
   710       gst_fake_src_prepare_buffer (src, buf);
       
   711       break;
       
   712     default:
       
   713       g_warning ("fakesrc: dunno how to allocate buffers !");
       
   714       buf = gst_buffer_new ();
       
   715       break;
       
   716   }
       
   717   if (dump) {
       
   718     gst_util_dump_mem (GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
       
   719   }
       
   720 
       
   721   return buf;
       
   722 }
       
   723 
       
   724 static void
       
   725 gst_fake_src_get_times (GstBaseSrc * basesrc, GstBuffer * buffer,
       
   726     GstClockTime * start, GstClockTime * end)
       
   727 {
       
   728   GstFakeSrc *src;
       
   729 
       
   730   src = GST_FAKE_SRC (basesrc);
       
   731 
       
   732   /* sync on the timestamp of the buffer if requested. */
       
   733   if (src->sync) {
       
   734     GstClockTime timestamp = GST_BUFFER_TIMESTAMP (buffer);
       
   735 
       
   736     if (GST_CLOCK_TIME_IS_VALID (timestamp)) {
       
   737       /* get duration to calculate end time */
       
   738       GstClockTime duration = GST_BUFFER_DURATION (buffer);
       
   739 
       
   740       if (GST_CLOCK_TIME_IS_VALID (duration)) {
       
   741         *end = timestamp + duration;
       
   742       }
       
   743       *start = timestamp;
       
   744     }
       
   745   } else {
       
   746     *start = -1;
       
   747     *end = -1;
       
   748   }
       
   749 }
       
   750 
       
   751 static GstFlowReturn
       
   752 gst_fake_src_create (GstBaseSrc * basesrc, guint64 offset, guint length,
       
   753     GstBuffer ** ret)
       
   754 {
       
   755   GstFakeSrc *src;
       
   756   GstBuffer *buf;
       
   757   GstClockTime time;
       
   758 
       
   759   src = GST_FAKE_SRC (basesrc);
       
   760 
       
   761   buf = gst_fake_src_create_buffer (src);
       
   762   GST_BUFFER_OFFSET (buf) = src->buffer_count++;
       
   763 
       
   764   if (src->datarate > 0) {
       
   765     time = (src->bytes_sent * GST_SECOND) / src->datarate;
       
   766 
       
   767     GST_BUFFER_DURATION (buf) =
       
   768         GST_BUFFER_SIZE (buf) * GST_SECOND / src->datarate;
       
   769   } else if (gst_base_src_is_live (basesrc)) {
       
   770     GstClock *clock;
       
   771 
       
   772     clock = gst_element_get_clock (GST_ELEMENT (src));
       
   773 
       
   774     if (clock) {
       
   775       time = gst_clock_get_time (clock);
       
   776       time -= gst_element_get_base_time (GST_ELEMENT (src));
       
   777       gst_object_unref (clock);
       
   778     } else {
       
   779       /* not an error not to have a clock */
       
   780       time = GST_CLOCK_TIME_NONE;
       
   781     }
       
   782   } else {
       
   783     time = GST_CLOCK_TIME_NONE;
       
   784   }
       
   785 
       
   786   GST_BUFFER_TIMESTAMP (buf) = time;
       
   787 
       
   788   if (!src->silent) {
       
   789     gchar ts_str[64], dur_str[64];
       
   790 
       
   791     GST_OBJECT_LOCK (src);
       
   792     g_free (src->last_message);
       
   793 
       
   794     if (GST_BUFFER_TIMESTAMP (buf) != GST_CLOCK_TIME_NONE) {
       
   795       g_snprintf (ts_str, sizeof (ts_str), "%" GST_TIME_FORMAT,
       
   796           GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)));
       
   797     } else {
       
   798       g_strlcpy (ts_str, "none", sizeof (ts_str));
       
   799     }
       
   800 
       
   801     if (GST_BUFFER_DURATION (buf) != GST_CLOCK_TIME_NONE) {
       
   802       g_snprintf (dur_str, sizeof (dur_str), "%" GST_TIME_FORMAT,
       
   803           GST_TIME_ARGS (GST_BUFFER_DURATION (buf)));
       
   804     } else {
       
   805       g_strlcpy (dur_str, "none", sizeof (dur_str));
       
   806     }
       
   807 
       
   808     src->last_message =
       
   809         g_strdup_printf ("get      ******* > (%5d bytes, timestamp: %s"
       
   810         ", duration: %s, offset: %" G_GINT64_FORMAT ", offset_end: %"
       
   811         G_GINT64_FORMAT ", flags: %d) %p", GST_BUFFER_SIZE (buf), ts_str,
       
   812         dur_str, GST_BUFFER_OFFSET (buf), GST_BUFFER_OFFSET_END (buf),
       
   813         GST_MINI_OBJECT (buf)->flags, buf);
       
   814     GST_OBJECT_UNLOCK (src);
       
   815 
       
   816     g_object_notify (G_OBJECT (src), "last_message");
       
   817   }
       
   818 
       
   819   if (src->signal_handoffs) {
       
   820     GST_LOG_OBJECT (src, "pre handoff emit");
       
   821     g_signal_emit (G_OBJECT (src), gst_fake_src_signals[SIGNAL_HANDOFF], 0,
       
   822         buf, basesrc->srcpad);
       
   823     GST_LOG_OBJECT (src, "post handoff emit");
       
   824   }
       
   825 
       
   826   src->bytes_sent += GST_BUFFER_SIZE (buf);
       
   827 
       
   828   *ret = buf;
       
   829   return GST_FLOW_OK;
       
   830 }
       
   831 
       
   832 static gboolean
       
   833 gst_fake_src_start (GstBaseSrc * basesrc)
       
   834 {
       
   835   GstFakeSrc *src;
       
   836 
       
   837   src = GST_FAKE_SRC (basesrc);
       
   838 
       
   839   src->buffer_count = 0;
       
   840   src->pattern_byte = 0x00;
       
   841   src->bytes_sent = 0;
       
   842 
       
   843   return TRUE;
       
   844 }
       
   845 
       
   846 static gboolean
       
   847 gst_fake_src_stop (GstBaseSrc * basesrc)
       
   848 {
       
   849   GstFakeSrc *src;
       
   850 
       
   851   src = GST_FAKE_SRC (basesrc);
       
   852 
       
   853   GST_OBJECT_LOCK (src);
       
   854   if (src->parent) {
       
   855     gst_buffer_unref (src->parent);
       
   856     src->parent = NULL;
       
   857   }
       
   858   g_free (src->last_message);
       
   859   src->last_message = NULL;
       
   860   GST_OBJECT_UNLOCK (src);
       
   861 
       
   862   return TRUE;
       
   863 }
       
   864 
       
   865 static gboolean
       
   866 gst_fake_src_is_seekable (GstBaseSrc * basesrc)
       
   867 {
       
   868   GstFakeSrc *src = GST_FAKE_SRC (basesrc);
       
   869 
       
   870   return src->can_activate_pull;
       
   871 }