GStreamer Plugin Writer's Guide (0.8.12) | ||
---|---|---|
<<< Previous | Writing a Source | Next >>> |
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 appliations 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 _get_event_mask () function. Elements supporting query operations should list the supported operations in a _get_query_types () function. Elements supporting either conversion or query operations should also implement a _get_formats () function.
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:
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; } |
Be sure to increase src->total_bytes after each call to your _get () function.
Event handling has already been explained previously in the events chapter.
<<< Previous | Home | Next >>> |
Writing a Source | Up | Time, clocking and synchronization |