mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-02 06:09:59 +00:00
Add probe example.
Original commit message from CVS: * docs/manual/advanced-dataaccess.xml: * examples/manual/Makefile.am: Add probe example. * gst/gstpad.c: (_gst_do_pass_data_accumulator): Make work (??).
This commit is contained in:
parent
faf3c9d652
commit
af3acddad9
5 changed files with 109 additions and 15 deletions
|
@ -1,3 +1,11 @@
|
|||
2005-06-29 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
|
||||
|
||||
* docs/manual/advanced-dataaccess.xml:
|
||||
* examples/manual/Makefile.am:
|
||||
Add probe example.
|
||||
* gst/gstpad.c: (_gst_do_pass_data_accumulator):
|
||||
Make work (??).
|
||||
|
||||
2005-06-29 Tim-Philipp Müller <tim at centricular dot net>
|
||||
|
||||
* gst/elements/gstfilesink.c: (gst_filesink_render):
|
||||
|
|
|
@ -14,16 +14,100 @@
|
|||
</para>
|
||||
|
||||
<sect1 id="section-data-probe">
|
||||
<title>Data probes</title>
|
||||
<title>Data probing</title>
|
||||
<para>
|
||||
Probes are best envisioned as pad listeners. They are attached to a
|
||||
pad in a pipeline, and you can add callback functions to this probe.
|
||||
Those callback functions will be called whenever data is being sent
|
||||
over this pad. The callback can then decide whether the data should
|
||||
be discarded or it can replace the piece of data with another piece
|
||||
of data. In this callback, it can also trigger actions in the
|
||||
application itself. For pipeline manipulation, probes are rather
|
||||
limited, but for pipeline tracking, they can be very useful.
|
||||
Probing is best envisioned as a pad listener. Technically, a probe is
|
||||
nothing more than a signal callback that can be attached to a pad.
|
||||
Those signals are by default not fired at all (since that may have a
|
||||
negative impact on performance), but can be enabled by attaching a
|
||||
probe using <function>gst_pad_add_data_probe ()</function> or one of
|
||||
the similar functions. Those functions attach the signal handler and
|
||||
enable the actual signal emission. Similarly, one can use the
|
||||
<function>gst_pad_remove_data_probe ()</function> or related functions
|
||||
to remove the signal handlers again. It is also possible to only listen
|
||||
to events or only to buffers (and ignore the other).
|
||||
</para>
|
||||
<para>
|
||||
Probes run in pipeline threading context, so callbacks should try to
|
||||
not block and generally not do any weird stuff, since this could
|
||||
have a negative impact on pipeline performance or, in case of bugs,
|
||||
cause deadlocks or crashes. However, most common buffer operations
|
||||
that elements can do in <function>_chain ()</function> functions, can
|
||||
be done in probe callbacks as well. The example below gives a short
|
||||
impression on how to use them.
|
||||
</para>
|
||||
<programlisting><!-- example-begin probe.c -->
|
||||
#include <gst/gst.h>
|
||||
|
||||
static gboolean
|
||||
cb_have_data (GstPad *pad,
|
||||
GstBuffer *buffer,
|
||||
gpointer u_data)
|
||||
{
|
||||
gint x, y;
|
||||
guint16 *data = (guint16 *) GST_BUFFER_DATA (buffer), t;
|
||||
|
||||
/* invert data */
|
||||
for (y = 0; y < 288; y++) {
|
||||
for (x = 0; x < 384 / 2; x++) {
|
||||
t = data[384 - 1 - x];
|
||||
data[384 - 1 - x] = data[x];
|
||||
data[x] = t;
|
||||
}
|
||||
data += 384;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gint
|
||||
main (gint argc,
|
||||
gchar *argv[])
|
||||
{
|
||||
GMainLoop *loop;
|
||||
GstElement *pipeline, *src, *sink, *filter, *csp;
|
||||
GstPad *pad;
|
||||
|
||||
/* init GStreamer */
|
||||
gst_init (&argc, &argv);
|
||||
loop = g_main_loop_new (NULL, FALSE);
|
||||
|
||||
/* build */
|
||||
pipeline = gst_pipeline_new ("my-pipeline");
|
||||
src = gst_element_factory_make ("videotestsrc", "src");
|
||||
filter = gst_element_factory_make ("capsfilter", "filter");
|
||||
csp = gst_element_factory_make ("ffmpegcolorspace", "csp");
|
||||
sink = gst_element_factory_make ("xvimagesink", "sink");
|
||||
gst_element_link_many (src, filter, csp, sink, NULL);
|
||||
gst_bin_add_many (GST_BIN (pipeline), src, filter, csp, sink, NULL);
|
||||
g_object_set (G_OBJECT (filter), "filter-caps",
|
||||
gst_caps_new_simple ("video/x-raw-rgb",
|
||||
"width", G_TYPE_INT, 384,
|
||||
"height", G_TYPE_INT, 288,
|
||||
"framerate", G_TYPE_DOUBLE, (gdouble) 25.0,
|
||||
"bpp", G_TYPE_INT, 16,
|
||||
"depth", G_TYPE_INT, 16,
|
||||
"endianness", G_TYPE_INT, G_BYTE_ORDER,
|
||||
NULL), NULL);
|
||||
pad = gst_element_get_pad (src, "src");
|
||||
gst_pad_add_buffer_probe (pad, G_CALLBACK (cb_have_data), NULL);
|
||||
gst_object_unref (pad);
|
||||
|
||||
/* run */
|
||||
gst_element_set_state (pipeline, GST_STATE_PLAYING);
|
||||
g_main_loop_run (loop);
|
||||
|
||||
/* exit */
|
||||
gst_element_set_state (pipeline, GST_STATE_NULL);
|
||||
gst_object_unref (pipeline);
|
||||
|
||||
return 0;
|
||||
}
|
||||
<!-- example-end probe.c --></programlisting>
|
||||
<para>
|
||||
Compare that output with the output of <quote>gst-launch-0.9
|
||||
videotestsrc ! xvimagesink</quote>, just so you know what you're
|
||||
looking for.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@ EXAMPLES = \
|
|||
popt \
|
||||
query \
|
||||
typefind \
|
||||
probe \
|
||||
fakesrc \
|
||||
playbin \
|
||||
decodebin \
|
||||
|
@ -77,7 +78,7 @@ typefind.c dynamic.c: $(top_srcdir)/docs/manual/advanced-autoplugging.xml
|
|||
$(PERL_PATH) $(srcdir)/extract.pl $@ \
|
||||
$(top_srcdir)/docs/manual/advanced-autoplugging.xml
|
||||
|
||||
fakesrc.c: $(top_srcdir)/docs/manual/advanced-dataaccess.xml
|
||||
probe.c fakesrc.c: $(top_srcdir)/docs/manual/advanced-dataaccess.xml
|
||||
$(PERL_PATH) $(srcdir)/extract.pl $@ \
|
||||
$(top_srcdir)/docs/manual/advanced-dataaccess.xml
|
||||
|
||||
|
|
|
@ -125,11 +125,11 @@ static gboolean
|
|||
_gst_do_pass_data_accumulator (GSignalInvocationHint * ihint,
|
||||
GValue * return_accu, const GValue * handler_return, gpointer dummy)
|
||||
{
|
||||
if (!g_value_get_boolean (handler_return)) {
|
||||
g_value_set_boolean (return_accu, FALSE);
|
||||
if (ihint->run_type == G_SIGNAL_RUN_FIRST) {
|
||||
gboolean ret = g_value_get_boolean (handler_return);
|
||||
|
||||
/* stop emission here */
|
||||
return FALSE;
|
||||
g_value_set_boolean (return_accu, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
|
|
@ -36,6 +36,7 @@ EXAMPLES = \
|
|||
popt \
|
||||
query \
|
||||
typefind \
|
||||
probe \
|
||||
fakesrc \
|
||||
playbin \
|
||||
decodebin \
|
||||
|
@ -77,7 +78,7 @@ typefind.c dynamic.c: $(top_srcdir)/docs/manual/advanced-autoplugging.xml
|
|||
$(PERL_PATH) $(srcdir)/extract.pl $@ \
|
||||
$(top_srcdir)/docs/manual/advanced-autoplugging.xml
|
||||
|
||||
fakesrc.c: $(top_srcdir)/docs/manual/advanced-dataaccess.xml
|
||||
probe.c fakesrc.c: $(top_srcdir)/docs/manual/advanced-dataaccess.xml
|
||||
$(PERL_PATH) $(srcdir)/extract.pl $@ \
|
||||
$(top_srcdir)/docs/manual/advanced-dataaccess.xml
|
||||
|
||||
|
|
Loading…
Reference in a new issue