2000-08-22 21:18:18 +00:00
|
|
|
<chapter id="cha-typedetection">
|
|
|
|
<title>Typedetection</title>
|
|
|
|
<para>
|
2002-09-14 14:13:34 +00:00
|
|
|
Sometimes the capabilities of a pad are not specificied. The filesrc
|
|
|
|
element, for example, does not know what type of file it is reading. Before
|
|
|
|
you can attach an element to the pad of the filesrc, you need to determine
|
2002-09-08 21:17:16 +00:00
|
|
|
the media type in order to be able to choose a compatible element.
|
2001-01-16 23:35:22 +00:00
|
|
|
</para>
|
|
|
|
<para>
|
|
|
|
To solve this problem, a plugin can provide the <application>GStreamer</application>
|
|
|
|
core library with a typedefinition library with a typedefinition. The typedefinition
|
|
|
|
will contain the following information:
|
|
|
|
<itemizedlist>
|
|
|
|
<listitem>
|
|
|
|
<para>
|
|
|
|
The MIME type we are going to define.
|
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
<listitem>
|
|
|
|
<para>
|
|
|
|
An optional string with a list of possible file extensions this
|
|
|
|
type usually is associated with. the list entries are separated with
|
|
|
|
a space. eg, ".mp3 .mpa .mpg".
|
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
<listitem>
|
|
|
|
<para>
|
|
|
|
An optional typefind function.
|
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
</itemizedlist>
|
|
|
|
</para>
|
|
|
|
<para>
|
|
|
|
The typefind functions give a meaning to the MIME types that are used
|
|
|
|
in GStreamer. The typefind function is a function with the following definition:
|
|
|
|
</para>
|
|
|
|
<programlisting>
|
|
|
|
typedef GstCaps *(*GstTypeFindFunc) (GstBuffer *buf, gpointer priv);
|
|
|
|
</programlisting>
|
|
|
|
<para>
|
|
|
|
This typefind function will inspect a GstBuffer with data and will output
|
|
|
|
a GstCaps structure describing the type. If the typefind function does not
|
|
|
|
understand the buffer contents, it will return NULL.
|
|
|
|
</para>
|
|
|
|
<para>
|
|
|
|
<application>GStreamer</application> has a typefind element in its core elements
|
|
|
|
that can be used to determine the type of a given pad.
|
|
|
|
</para>
|
|
|
|
<para>
|
|
|
|
The next example will show how a typefind element can be inserted into a pipeline
|
|
|
|
to detect the media type of a file. It will output the capabilities of the pad into
|
|
|
|
an XML representation.
|
|
|
|
</para>
|
|
|
|
<programlisting>
|
|
|
|
#include <gst/gst.h>
|
|
|
|
|
|
|
|
void type_found (GstElement *typefind, GstCaps* caps);
|
|
|
|
|
|
|
|
int
|
|
|
|
main(int argc, char *argv[])
|
|
|
|
{
|
2002-01-06 04:26:37 +00:00
|
|
|
GstElement *bin, *filesrc, *typefind;
|
2001-01-16 23:35:22 +00:00
|
|
|
|
2001-07-07 11:34:54 +00:00
|
|
|
gst_init (&argc, &argv);
|
2001-01-16 23:35:22 +00:00
|
|
|
|
|
|
|
if (argc != 2) {
|
2002-07-09 18:43:13 +00:00
|
|
|
g_print ("usage: %s <filename>\n", argv[0]);
|
2001-07-07 11:34:54 +00:00
|
|
|
exit (-1);
|
2001-01-16 23:35:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* create a new bin to hold the elements */
|
2001-07-07 11:34:54 +00:00
|
|
|
bin = gst_bin_new ("bin");
|
|
|
|
g_assert (bin != NULL);
|
2001-01-16 23:35:22 +00:00
|
|
|
|
|
|
|
/* create a disk reader */
|
2002-04-11 20:35:18 +00:00
|
|
|
filesrc = gst_element_factory_make ("filesrc", "disk_source");
|
2002-01-06 04:26:37 +00:00
|
|
|
g_assert (filesrc != NULL);
|
|
|
|
g_object_set (G_OBJECT (filesrc), "location", argv[1], NULL);
|
2001-01-16 23:35:22 +00:00
|
|
|
|
|
|
|
/* create the typefind element */
|
2002-04-11 20:35:18 +00:00
|
|
|
typefind = gst_element_factory_make ("typefind", "typefind");
|
2001-07-07 11:34:54 +00:00
|
|
|
g_assert (typefind != NULL);
|
2001-01-16 23:35:22 +00:00
|
|
|
|
|
|
|
/* add objects to the main pipeline */
|
2002-01-06 04:26:37 +00:00
|
|
|
gst_bin_add (GST_BIN (bin), filesrc);
|
2001-07-07 11:34:54 +00:00
|
|
|
gst_bin_add (GST_BIN (bin), typefind);
|
2001-01-16 23:35:22 +00:00
|
|
|
|
2001-08-13 19:00:13 +00:00
|
|
|
g_signal_connect (G_OBJECT (typefind), "have_type",
|
|
|
|
G_CALLBACK (type_found), NULL);
|
2001-01-16 23:35:22 +00:00
|
|
|
|
2003-01-09 14:15:37 +00:00
|
|
|
gst_pad_link (gst_element_get_pad (filesrc, "src"),
|
|
|
|
gst_element_get_pad (typefind, "sink"));
|
2001-01-16 23:35:22 +00:00
|
|
|
|
|
|
|
/* start playing */
|
2001-07-07 11:34:54 +00:00
|
|
|
gst_element_set_state (GST_ELEMENT (bin), GST_STATE_PLAYING);
|
2001-01-16 23:35:22 +00:00
|
|
|
|
2001-07-07 11:34:54 +00:00
|
|
|
gst_bin_iterate (GST_BIN (bin));
|
2001-01-16 23:35:22 +00:00
|
|
|
|
2001-07-07 11:34:54 +00:00
|
|
|
gst_element_set_state (GST_ELEMENT (bin), GST_STATE_NULL);
|
2001-01-16 23:35:22 +00:00
|
|
|
|
2001-07-07 11:34:54 +00:00
|
|
|
exit (0);
|
2001-01-16 23:35:22 +00:00
|
|
|
}
|
|
|
|
</programlisting>
|
|
|
|
<para>
|
2002-09-08 21:17:16 +00:00
|
|
|
We create a very simple pipeline with only a filesrc and the typefind
|
2003-01-24 18:08:39 +00:00
|
|
|
element in it. The sinkpad of the typefind element has been linked
|
2002-09-14 14:13:34 +00:00
|
|
|
to the source pad of the filesrc.
|
2001-01-16 23:35:22 +00:00
|
|
|
</para>
|
|
|
|
<para>
|
|
|
|
We attached a signal 'have_type' to the typefind element which will be called
|
|
|
|
when the type of the media stream as been detected.
|
|
|
|
</para>
|
|
|
|
<para>
|
2002-09-14 14:13:34 +00:00
|
|
|
The typefind function will loop over all the registered types and will
|
2002-09-08 21:17:16 +00:00
|
|
|
execute each of the typefind functions. As soon as a function returns
|
|
|
|
a GstCaps pointer, the type_found function will be called:
|
2001-01-16 23:35:22 +00:00
|
|
|
</para>
|
|
|
|
|
|
|
|
<programlisting>
|
|
|
|
void
|
|
|
|
type_found (GstElement *typefind, GstCaps* caps)
|
|
|
|
{
|
|
|
|
xmlDocPtr doc;
|
|
|
|
xmlNodePtr parent;
|
|
|
|
|
|
|
|
doc = xmlNewDoc ("1.0");
|
|
|
|
doc->root = xmlNewDocNode (doc, NULL, "Capabilities", NULL);
|
|
|
|
|
|
|
|
parent = xmlNewChild (doc->root, NULL, "Caps1", NULL);
|
|
|
|
gst_caps_save_thyself (caps, parent);
|
|
|
|
|
|
|
|
xmlDocDump (stdout, doc);
|
|
|
|
}
|
|
|
|
</programlisting>
|
|
|
|
<para>
|
|
|
|
In the type_found function we can print or inspect the type that has been
|
|
|
|
detected using the GstCaps APIs. In this example, we just print out the
|
|
|
|
XML representation of the caps structure to stdout.
|
|
|
|
</para>
|
|
|
|
<para>
|
2002-09-14 14:13:34 +00:00
|
|
|
A more useful option would be to use the registry to look up an element
|
2001-01-16 23:35:22 +00:00
|
|
|
that can handle this particular caps structure, or we can also use the
|
2003-01-24 18:08:39 +00:00
|
|
|
autoplugger to link this caps structure to, for example, a videosink.
|
2000-08-22 21:18:18 +00:00
|
|
|
</para>
|
|
|
|
|
|
|
|
</chapter>
|