2000-08-22 21:18:18 +00:00
|
|
|
<chapter id="cha-typedetection">
|
|
|
|
<title>Typedetection</title>
|
|
|
|
<para>
|
2001-01-16 23:35:22 +00:00
|
|
|
Sometimes the capabilities of a pad are not specificied. The disksrc, for
|
|
|
|
example, does not know what type of file it is reading. Before you can attach
|
2001-03-20 23:12:24 +00:00
|
|
|
an element to the pad of the disksrc, you need to determine the media type in
|
2001-01-16 23:35:22 +00:00
|
|
|
order to be able to choose a compatible element.
|
|
|
|
</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[])
|
|
|
|
{
|
|
|
|
GstElement *bin, *disksrc, *typefind;
|
|
|
|
|
2001-07-07 11:34:54 +00:00
|
|
|
gst_init (&argc, &argv);
|
2001-01-16 23:35:22 +00:00
|
|
|
|
|
|
|
if (argc != 2) {
|
2001-07-07 11:34:54 +00:00
|
|
|
g_print ("usage: %s <filename>\n", argv[0]);
|
|
|
|
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 */
|
2001-07-07 11:34:54 +00:00
|
|
|
disksrc = gst_elementfactory_make ("disksrc", "disk_source");
|
|
|
|
g_assert (disksrc != NULL);
|
|
|
|
g_object_set (G_OBJECT (disksrc), "location", argv[1], NULL);
|
2001-01-16 23:35:22 +00:00
|
|
|
|
|
|
|
/* create the typefind element */
|
2001-07-07 11:34:54 +00:00
|
|
|
typefind = gst_elementfactory_make ("typefind", "typefind");
|
|
|
|
g_assert (typefind != NULL);
|
2001-01-16 23:35:22 +00:00
|
|
|
|
|
|
|
/* add objects to the main pipeline */
|
2001-07-07 11:34:54 +00:00
|
|
|
gst_bin_add (GST_BIN (bin), disksrc);
|
|
|
|
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
|
|
|
|
2001-07-07 11:34:54 +00:00
|
|
|
gst_pad_connect (gst_element_get_pad (disksrc, "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>
|
|
|
|
We create a very simple pipeline with only a disksrc and the typefind element
|
|
|
|
in it. The sinkpad of the typefind element has been connected to the src pad
|
|
|
|
of the disksrc.
|
|
|
|
</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>
|
|
|
|
the typefind function will loop over all the registered types and will execute
|
|
|
|
each of the typefind functions. As soon as a function returns a GstCaps pointer,
|
|
|
|
the type_found function will be called:
|
|
|
|
</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>
|
|
|
|
A more usefull option would be to use the registry to look up an element
|
|
|
|
that can handle this particular caps structure, or we can also use the
|
|
|
|
autoplugger to connect this caps structure to, for example, a videosink.
|
2000-08-22 21:18:18 +00:00
|
|
|
</para>
|
|
|
|
|
|
|
|
</chapter>
|