
<!-- ############ chapter ############# -->

<chapter id="chapter-other-source" xreflabel="Writing a Source">
  <title>Writing a Source</title>
  <para>
    Source elements are the start of a data streaming pipeline. Source
    elements have no sink pads and have one or more source pads. We will
    focus on single-sourcepad elements here, but the concepts apply equally
    well to multi-sourcepad elements. This chapter will explain the essentials
    of source elements, which features it should implement and which it
    doesn't have to, and how source elements will interact with other
    elements in a pipeline.
  </para>

  <sect1 id="section-source-getfn" xreflabel="The get()-function">
    <title>The get()-function</title>
    <para>
      Source elements have the special option of having a
      <function>_get ()</function>-function rather than a
      <function>_loop ()</function>- or <function>_chain
      ()</function>-function. A <function>_get ()</function>-function is
      called by the scheduler every time the next elements needs data. Apart
      from corner cases, every source element will want to be <function>_get
      ()</function>-based.
    </para>
    <programlisting>
static GstData *	gst_my_source_get	(GstPad *pad);

static void
gst_my_source_init (GstMySource *src)
{
[..]
  gst_pad_set_get_function (src->srcpad, gst_my_source_get);
}

static GstData *
gst_my_source_get (GstPad *pad)
{
  GstBuffer *buffer;

  buffer = gst_buffer_new ();
  GST_BUFFER_DATA (buf) = g_strdup ("hello pipeline!");
  GST_BUFFER_SIZE (buf) = strlen (GST_BUFFER_DATA (buf));
  /* terminating '/0' */
  GST_BUFFER_MAZSIZE (buf) = GST_BUFFER_SIZE (buf) + 1;

  return GST_DATA (buffer);
}
    </programlisting>
  </sect1>

  <sect1 id="section-source-padfn" xreflabel="Events, querying and converting">
    <title>Events, querying and converting</title>
    <para>
      One of the most important functions of source elements is to
      implement correct query, convert and event handling functions.
      Those will continuously describe the current state of the stream.
      Query functions can be used to get stream properties such as current
      position and length. This can be used by fellow elements to convert
      this same value into a different unit, or by applications to provide
      information about the length/position of the stream to the user.
      Conversion functions are used to convert such values from one unit
      to another. Lastly, events are mostly used to seek to positions
      inside the stream. Any function is essentially optional, but the
      element should try to provide as much information as it knows. Note
      that elements providing an event function should also list their
      supported events in an <function>_get_event_mask ()</function>
      function. Elements supporting query operations should list the
      supported operations in a <function>_get_query_types
      ()</function> function. Elements supporting either conversion
      or query operations should also implement a <function>_get_formats
      ()</function> function.
    </para>
    <para>
      An example source element could, for example, be an element that
      continuously generates a wave tone at 44,1 kHz, mono, 16-bit. This
      element will generate 44100 audio samples per second or 88,2 kB/s.
      This information can be used to implement such functions:
    </para>
    <programlisting>
static GstFormat *	gst_my_source_format_list	(GstPad      *pad);
static GstQueryType *	gst_my_source_query_list	(GstPad      *pad);

static gboolean		gst_my_source_convert		(GstPad      *pad,
							 GstFormat    from_fmt,
							 gint64       from_val,
							 GstFormat   *to_fmt,
							 gint64      *to_val);
static gboolean		gst_my_source_query		(GstPad      *pad,
							 GstQueryType type,
							 GstFormat   *to_fmt,
							 gint64      *to_val);

static void
gst_my_source_init (GstMySource *src)
{
[..]
  gst_pad_set_convert_function (src->srcpad, gst_my_source_convert);
  gst_pad_set_formats_function (src->srcpad, gst_my_source_format_list);
  gst_pad_set_query_function (src->srcpad, gst_my_source_query);
  gst_pad_set_query_type_function (src->srcpad, gst_my_source_query_list);
}

/*
 * This function returns an enumeration of supported GstFormat
 * types in the query() or convert() functions. See gst/gstformat.h
 * for a full list.
 */

static GstFormat *
gst_my_source_format_list (GstPad *pad)
{
  static const GstFormat formats[] = {
    GST_FORMAT_TIME,
    GST_FORMAT_DEFAULT, /* means "audio samples" */
    GST_FORMAT_BYTES,
    0
  };

  return formats;
}

/*
 * This function returns an enumeration of the supported query()
 * operations. Since we generate audio internally, we only provide
 * an indication of how many samples we've played so far. File sources
 * or such elements could also provide GST_QUERY_TOTAL for the total
 * stream length, or other things. See gst/gstquery.h for details.
 */

static GstQueryType *
gst_my_source_query_list (GstPad *pad)
{
  static const GstQueryType query_types[] = {
    GST_QUERY_POSITION,
    0,
  };

  return query_types;
}

/*
 * And below are the logical implementations.
 */

static gboolean
gst_my_source_convert (GstPad    *pad,
		       GstFormat  from_fmt,
		       gint64     from_val,
		       GstFormat *to_fmt,
		       gint64    *to_val)
{
  gboolean res = TRUE;
  GstMySource *src = GST_MY_SOURCE (gst_pad_get_parent (pad));

  switch (from_fmt) {
    case GST_FORMAT_TIME:
      switch (*to_fmt) {
        case GST_FORMAT_TIME:
          /* nothing */
          break;

        case GST_FORMAT_BYTES:
          *to_val = from_val / (GST_SECOND / (44100 * 2));
          break;

        case GST_FORMAT_DEFAULT:
          *to_val = from_val / (GST_SECOND / 44100);
          break;

        default:
          res = FALSE;
          break;
      }
      break;

    case GST_FORMAT_BYTES:
      switch (*to_fmt) {
        case GST_FORMAT_TIME:
          *to_val = from_val * (GST_SECOND / (44100 * 2));
          break;

        case GST_FORMAT_BYTES:
          /* nothing */
          break;

        case GST_FORMAT_DEFAULT:
          *to_val = from_val / 2;
          break;

        default:
          res = FALSE;
          break;
      }
      break;

    case GST_FORMAT_DEFAULT:
      switch (*to_fmt) {
        case GST_FORMAT_TIME:
          *to_val = from_val * (GST_SECOND / 44100);
          break;

        case GST_FORMAT_BYTES:
          *to_val = from_val * 2;
          break;

        case GST_FORMAT_DEFAULT:
          /* nothing */
          break;

        default:
          res = FALSE;
          break;
      }
      break;

    default:
      res = FALSE;
      break;
  }

  return res;
}

static gboolean
gst_my_source_query (GstPad      *pad,
		     GstQueryType type,
		     GstFormat   *to_fmt,
		     gint64      *to_val)
{
  GstMySource *src = GST_MY_SOURCE (gst_pad_get_parent (pad));
  gboolean res = TRUE;

  switch (type) {
    case GST_QUERY_POSITION:
      res = gst_pad_convert (pad, GST_FORMAT_BYTES, src->total_bytes,
                             to_fmt, to_val);
      break;

    default:
      res = FALSE;
      break;
  }

  return res;
}
    </programlisting>
    <para>
      Be sure to increase src->total_bytes after each call to your
      <function>_get ()</function> function.
    </para>
    <para>
      Event handling has already been explained previously in the events
      chapter.
    </para>
  </sect1>

  <sect1 id="section-source-sync" xreflabel="Time, clocking and synchronization">
    <title>Time, clocking and synchronization</title>
    <para>
      The above example does not provide any timing info, but will suffice
      for elementary data sources such as a file source or network data
      source element. Things become slightly more complicated, but still
      very simple, if we create artificial video or audio data sources,
      such as a video test image source or an artificial audio source (e.g.
      <classname>audiotestsrc</classname>).
      It will become more complicated if we want the element to be a
      realtime capture source, such as a video4linux source (for reading
      video frames from a TV card) or an ALSA source (for reading data
      from soundcards supported by an ALSA-driver). Here, we will need to
      make the element aware of timing and clocking.
    </para>
    <para>
      Timestamps can essentially be generated from all the information
      given above without any difficulty. We could add a very small amount
      of code to generate perfectly timestamped buffers from our
      <function>_get ()</function>-function:
    </para>
    <programlisting>
static void
gst_my_source_init (GstMySource *src)
{
[..]
  src->total_bytes = 0;
}

static GstData *
gst_my_source_get (GstPad *pad)
{
  GstMySource *src = GST_MY_SOURCE (gst_pad_get_parent (pad));
  GstBuffer *buf;
  GstFormat fmt = GST_FORMAT_TIME;
[..]
  GST_BUFFER_DURATION (buf) = GST_BUFFER_SIZE (buf) * (GST_SECOND / (44100 * 2));
  GST_BUFFER_TIMESTAMP (buf) = src->total_bytes * (GST_SECOND / (44100 * 2));
  src->total_bytes += GST_BUFFER_SIZE (buf);

  return GST_DATA (buf);
}

static GstStateChangeReturn
gst_my_source_change_state (GstElement *element, GstStateChange transition)
{
  GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
  GstMySource *src = GST_MY_SOURCE (element);

  /* First, handle upwards state changes */
  switch (transition) {
    case GST_STATE_READY_TO_PAUSED:
      /* do something */
      break;
    default:
      break;
  }

  ret = GST_ELEMENT_CLASS (parent_class)-&gt;change_state (element, transition);
  if (ret == GST_STATE_CHANGE_FAILURE)
    return ret;

  /* Now handle downwards state changes after chaining up */
  switch (transition) {
    case GST_STATE_PAUSED_TO_READY:
      src->total_bytes = 0;
      break;
    default:
      break;
  }

  return ret;
}
    </programlisting>
    <para>
      That wasn't too hard. Now, let's assume real-time elements. Those
      can either have hardware-timing, in which case we can rely on backends
      to provide sync for us (in which case you probably want to provide a
      clock), or we will have to emulate that internally (e.g. to acquire
      sync in artificial data elements such as
      <classname>audiotestsrc</classname>).
      Let's first look at the second option (software sync). The first option
      (hardware sync + providing a clock) does not require any special code
      with respect to timing, and the clocking section already explained how
      to provide a clock.
    </para>
    <programlisting>
enum {
  ARG_0,
[..]
  ARG_SYNC,
[..]
};

static void
gst_my_source_class_init (GstMySourceClass *klass)
{
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
[..]
  g_object_class_install_property (object_class, ARG_SYNC,
      g_param_spec_boolean ("sync", "Sync", "Synchronize to clock",
                            FALSE, G_PARAM_READWRITE |
                                G_PARAM_STATIC_STRINGS));
[..]
}

static void
gst_my_source_init (GstMySource *src)
{
[..]
  src->sync = FALSE;
}

static GstData *
gst_my_source_get (GstPad *pad)
{
  GstMySource *src = GST_MY_SOURCE (gst_pad_get_parent (pad));
  GstBuffer *buf;
[..]
  if (src->sync) {
    /* wait on clock */
    gst_element_wait (GST_ELEMENT (src), GST_BUFFER_TIMESTAMP (buf));
  }

  return GST_DATA (buf);
}

static void
gst_my_source_get_property (GObject    *object,
			    guint       prop_id,
			    GParamSpec *pspec,
			    GValue     *value)
{
  GstMySource *src = GST_MY_SOURCE (gst_pad_get_parent (pad));

  switch (prop_id) {
[..]
    case ARG_SYNC:
      g_value_set_boolean (value, src->sync);
      break;
[..]
  }
}

static void
gst_my_source_get_property (GObject      *object,
			    guint         prop_id,
			    GParamSpec   *pspec,
			    const GValue *value)
{
  GstMySource *src = GST_MY_SOURCE (gst_pad_get_parent (pad));

  switch (prop_id) {
[..]
    case ARG_SYNC:
      src->sync = g_value_get_boolean (value);
      break;
[..]
  }
}
    </programlisting>
    <para>
      Most of this is GObject wrapping code. The actual code to do
      software-sync (in the <function>_get ()</function>-function)
      is relatively small.
    </para>
  </sect1>
  <sect1 id="section-source-buffers" xreflabel="Using special memory">
    <title>Using special memory</title>
    <para>
      In some cases, it might be useful to use specially allocated memory
      (e.g. <function>mmap ()</function>'ed DMA'able memory) in
      your buffers, and those will require special handling when they are
      being dereferenced. For this, &GStreamer; uses the concept of
      buffer-free functions. Those are special functions pointers that an
      element can set on buffers that it created itself. The given function
      will be called when the buffer has been dereferenced, so that the
      element can clean up or re-use memory internally rather than using
      the default implementation (which simply calls
      <function>g_free ()</function> on the data pointer).
    </para>
    <programlisting>
static void
gst_my_source_buffer_free (GstBuffer *buf)
{
  GstMySource *src = GST_MY_SOURCE (GST_BUFFER_PRIVATE (buf));

  /* do useful things here, like re-queueing the buffer which
   * makes it available for DMA again. The default handler will
   * not free this buffer because of the GST_BUFFER_DONTFREE
   * flag. */
}

static GstData *
gst_my_source_get (GstPad *pad)
{
  GstMySource *src = GST_MY_SOURCE (gst_pad_get_parent (pad));
  GstBuffer *buf;
[..]
  buf = gst_buffer_new ();
  GST_BUFFER_FREE_DATA_FUNC (buf) = gst_my_source_buffer_free;
  GST_BUFFER_PRIVATE (buf) = src;
  GST_BUFFER_FLAG_SET (buf, GST_BUFFER_READONLY | GST_BUFFER_DONTFREE);
[..]

  return GST_DATA (buf);
}
    </programlisting>
    <para>
      Note that this concept should <emphasis>not</emphasis> be used to
      decrease the number of calls made to functions such as
      <function>g_malloc ()</function> inside your element. We
      have better ways of doing that elsewhere (&GStreamer; core, Glib,
      Glibc, Linux kernel, etc.).
    </para>
  </sect1>
</chapter>
