Providing random access

In the previous section, we have talked about how elements (or pads) that are assigned to drive the pipeline using their own task, have random access over their sinkpads. This means that all elements linked to those pads (recursively) need to provide random access functions. Requesting random access is done using the function gst_pad_pull_range (), which requests a buffer of a specified size and offset. Source pads implementing and assigned to do random access will have a _get_range ()-function set using gst_pad_set_getrange_function (), and that function will be called when the peer pad requests some data. The element is then responsible for seeking to the right offset and providing the requested data. Several elements can implement random access:

The following example will show how a _get_range ()-function can be implemented in a source element:


#include "filter.h"
static GstFlowReturn
		gst_my_filter_get_range	(GstPad     * pad,
					 guint64      offset,
					 guint        length,
					 GstBuffer ** buf);

GST_BOILERPLATE (GstMyFilter, gst_my_filter, GstElement, GST_TYPE_ELEMENT);



static void
gst_my_filter_init (GstMyFilter * filter)
{
  GstElementClass *klass = GST_ELEMENT_GET_CLASS (filter);

  filter->srcpad = gst_pad_new_from_template (
        gst_element_class_get_pad_template (klass, "src"), "src");
  gst_pad_set_getrange_function (filter->srcpad,
      gst_my_filter_get_range);
  gst_element_add_pad (GST_ELEMENT (filter), filter->srcpad);

[..]
}

static gboolean
gst_my_filter_get_range (GstPad     * pad,
			 guint64      offset,
			 guint        length,
			 GstBuffer ** buf)
{

  GstMyFilter *filter = GST_MY_FILTER (GST_OBJECT_PARENT (pad));

  [.. here, you would fill *buf ..]

  return GST_FLOW_OK;
}

In practice, many elements that could theoretically do random access, may in practice often be assigned to do push-based scheduling anyway, since there is no downstream element able to start its own task. Therefore, in practice, those elements should implement both a _get_range ()-function and a _chain ()-function (for filters and parsers) or a _get_range ()-function and be prepared to start their own task by providing _activate_* ()-functions (for source elements), so that GStreamer can decide for the optimal scheduling mode and have it just work fine in practice.