mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-06-07 00:29:27 +00:00
Changes to gstreamer-config to include gtk+ libs manual changes: queues, threads, programs gsteditor does not crash a...
Original commit message from CVS: Changes to gstreamer-config to include gtk+ libs manual changes: queues, threads, programs gsteditor does not crash anymore. gstpipline new should return a GstElement * fixed ac3dec for new getbits fixes to gstreamer-launch more efficient startup for gstplay.
This commit is contained in:
parent
23540ccc52
commit
552b7f32aa
|
@ -51,7 +51,7 @@
|
||||||
</para>
|
</para>
|
||||||
</legalnotice>
|
</legalnotice>
|
||||||
|
|
||||||
<title>GStreamer Application Development Manual</title>
|
<title><application>GStreamer</application> Application Development Manual</title>
|
||||||
|
|
||||||
</bookinfo>
|
</bookinfo>
|
||||||
|
|
||||||
|
@ -60,10 +60,10 @@
|
||||||
<part id="overview"><title>Overview</title>
|
<part id="overview"><title>Overview</title>
|
||||||
<partintro>
|
<partintro>
|
||||||
<para>
|
<para>
|
||||||
The first chapter of the book gives you an overview of GStreamer
|
The first chapter of the book gives you an overview of <application>GStreamer</application>
|
||||||
design goals. Chapter 2 rapidly covers the basics of GStreamer
|
design goals. Chapter 2 rapidly covers the basics of <application>GStreamer</application>
|
||||||
programming. In chapter 3 we will move on to the examples.
|
programming. In chapter 3 we will move on to the examples.
|
||||||
Since GStreamer adheres to the GTK+ programming model, the reader is
|
Since <application>GStreamer</application> adheres to the GTK+ programming model, the reader is
|
||||||
assumed to understand the basics of GTK+.
|
assumed to understand the basics of GTK+.
|
||||||
For a gentle introduction to GTK+, you may wish to read the <emphasis>GTK+
|
For a gentle introduction to GTK+, you may wish to read the <emphasis>GTK+
|
||||||
Tutorial</emphasis> or Eric Harlow's book <emphasis>Developing Linux
|
Tutorial</emphasis> or Eric Harlow's book <emphasis>Developing Linux
|
||||||
|
@ -84,7 +84,7 @@
|
||||||
<part id="basic-concepts"><title>Basic concepts</title>
|
<part id="basic-concepts"><title>Basic concepts</title>
|
||||||
<partintro>
|
<partintro>
|
||||||
<para>
|
<para>
|
||||||
We will first describe the basics of the GStreamer programming by
|
We will first describe the basics of the <application>GStreamer</application> programming by
|
||||||
introducing the different objects needed to create a media pipeline.
|
introducing the different objects needed to create a media pipeline.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
|
@ -111,7 +111,7 @@
|
||||||
<partintro>
|
<partintro>
|
||||||
<para>
|
<para>
|
||||||
With the basic concepts out of the way, you're ready to start building a
|
With the basic concepts out of the way, you're ready to start building a
|
||||||
full-scale GStreamer application.
|
full-scale <application>GStreamer</application> application.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
We assume the reader is familiar with GTK+/GNOME programming.
|
We assume the reader is familiar with GTK+/GNOME programming.
|
||||||
|
@ -127,15 +127,15 @@
|
||||||
|
|
||||||
<!-- ############ Advanced GStreamer - part ############# -->
|
<!-- ############ Advanced GStreamer - part ############# -->
|
||||||
|
|
||||||
<part id="advanced"><title>Advanced GStreamer concepts</title>
|
<part id="advanced"><title>Advanced <application>GStreamer</application> concepts</title>
|
||||||
|
|
||||||
<partintro>
|
<partintro>
|
||||||
<para>
|
<para>
|
||||||
In this part we will cover the more advanced features of GStreamer.
|
In this part we will cover the more advanced features of <application>GStreamer</application>.
|
||||||
With the basics you learned in the prevous part you should be
|
With the basics you learned in the prevous part you should be
|
||||||
able to create a 'simple' pipeline. If you want more control over
|
able to create a 'simple' pipeline. If you want more control over
|
||||||
the media types and the pipeline you should use the more
|
the media types and the pipeline you should use the more
|
||||||
low-level features of GStreamer.
|
low-level features of <application>GStreamer</application>.
|
||||||
</para>
|
</para>
|
||||||
</partintro>
|
</partintro>
|
||||||
|
|
||||||
|
@ -156,11 +156,11 @@
|
||||||
|
|
||||||
<!-- ############ XML in GStreamer - part ############# -->
|
<!-- ############ XML in GStreamer - part ############# -->
|
||||||
|
|
||||||
<part id="xml-gstreamer"><title>XML in GStreamer</title>
|
<part id="xml-gstreamer"><title>XML in <application>GStreamer</application></title>
|
||||||
|
|
||||||
<partintro>
|
<partintro>
|
||||||
<para>
|
<para>
|
||||||
GStreamer has the posibility to externalize the pipelines
|
<application>GStreamer</application> has the posibility to externalize the pipelines
|
||||||
you create using an XML format. You can load a previously
|
you create using an XML format. You can load a previously
|
||||||
created pipeline by loading the XML file.
|
created pipeline by loading the XML file.
|
||||||
</para>
|
</para>
|
||||||
|
@ -171,12 +171,12 @@
|
||||||
|
|
||||||
<!-- ############ XML in GStreamer - part ############# -->
|
<!-- ############ XML in GStreamer - part ############# -->
|
||||||
|
|
||||||
<part id="plugins"><title>plugin development in GStreamer</title>
|
<part id="plugins"><title>plugin development in <application>GStreamer</application></title>
|
||||||
|
|
||||||
<partintro>
|
<partintro>
|
||||||
<para>
|
<para>
|
||||||
In this part we will describe how you create a new plugin
|
In this part we will describe how you create a new plugin
|
||||||
to be used in GStreamer.
|
to be used in <application>GStreamer</application>.
|
||||||
</para>
|
</para>
|
||||||
</partintro>
|
</partintro>
|
||||||
|
|
||||||
|
@ -190,7 +190,7 @@
|
||||||
|
|
||||||
<partintro>
|
<partintro>
|
||||||
<para>
|
<para>
|
||||||
GStreamer comes prepackaged with a few programs.
|
<application>GStreamer</application> comes prepackaged with a few programs.
|
||||||
</para>
|
</para>
|
||||||
</partintro>
|
</partintro>
|
||||||
|
|
||||||
|
|
|
@ -39,8 +39,6 @@ int main(int argc,char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_init(&argc,&argv);
|
gst_init(&argc,&argv);
|
||||||
gst_plugin_load_all();
|
|
||||||
g_print("\n");
|
|
||||||
|
|
||||||
/* create a new bin to hold the elements */
|
/* create a new bin to hold the elements */
|
||||||
bin = gst_bin_new("bin");
|
bin = gst_bin_new("bin");
|
||||||
|
@ -89,6 +87,7 @@ int main(int argc,char *argv[])
|
||||||
gst_element_set_state(bin, GST_STATE_NULL);
|
gst_element_set_state(bin, GST_STATE_NULL);
|
||||||
|
|
||||||
gst_object_destroy(GST_OBJECT(audiosink));
|
gst_object_destroy(GST_OBJECT(audiosink));
|
||||||
|
gst_object_destroy(GST_OBJECT(parse));
|
||||||
gst_object_destroy(GST_OBJECT(decoder));
|
gst_object_destroy(GST_OBJECT(decoder));
|
||||||
gst_object_destroy(GST_OBJECT(disksrc));
|
gst_object_destroy(GST_OBJECT(disksrc));
|
||||||
gst_object_destroy(GST_OBJECT(bin));
|
gst_object_destroy(GST_OBJECT(bin));
|
||||||
|
@ -120,16 +119,6 @@ int main(int argc,char *argv[])
|
||||||
|
|
||||||
</programlisting>
|
</programlisting>
|
||||||
|
|
||||||
<para>
|
|
||||||
For simplicity, we are going to load all known plugins. This has the effect
|
|
||||||
that all the codecs known to GStreamer are registered to the system.
|
|
||||||
</para>
|
|
||||||
<programlisting>
|
|
||||||
...
|
|
||||||
gst_plugin_load_all();
|
|
||||||
...
|
|
||||||
</programlisting>
|
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
We are going to create 4 elements and one bin. Since all objects are
|
We are going to create 4 elements and one bin. Since all objects are
|
||||||
in fact elements, we can define them as:
|
in fact elements, we can define them as:
|
||||||
|
@ -318,8 +307,8 @@ void eos(GstSrc *src)
|
||||||
To compile the helloworld example, use:
|
To compile the helloworld example, use:
|
||||||
</para>
|
</para>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
gcc -Wall `gstreamer-config --cflags` `gtk-config --cflags` helloworld.c \
|
gcc -Wall `gstreamer-config --cflags --libs` helloworld.c \
|
||||||
-o helloworld `gstreamer-config --libs` `gtk-config --libs`
|
-o helloworld
|
||||||
</programlisting>
|
</programlisting>
|
||||||
<para>
|
<para>
|
||||||
This uses the program gstreamer-config, which comes with GStreamer. This program "knows"
|
This uses the program gstreamer-config, which comes with GStreamer. This program "knows"
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
<para>
|
<para>
|
||||||
We will create a second version of the helloworld application using
|
We will create a second version of the helloworld application using
|
||||||
autoplugging. Its source code is considerably more easy to write and
|
autoplugging. Its source code is considerably more easy to write and
|
||||||
can also much more data types.
|
can also handle much more data types.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<programlisting>
|
<programlisting>
|
||||||
|
@ -25,7 +25,7 @@
|
||||||
|
|
||||||
static gboolean playing;
|
static gboolean playing;
|
||||||
|
|
||||||
/* eos will be called when the src element has an end os stream */
|
/* eos will be called when the src element has an end of stream */
|
||||||
void eos(GstSrc *src)
|
void eos(GstSrc *src)
|
||||||
{
|
{
|
||||||
g_print("have eos, quitting\n");
|
g_print("have eos, quitting\n");
|
||||||
|
@ -36,7 +36,7 @@ void eos(GstSrc *src)
|
||||||
int main(int argc,char *argv[])
|
int main(int argc,char *argv[])
|
||||||
{
|
{
|
||||||
GstElement *disksrc, *audiosink;
|
GstElement *disksrc, *audiosink;
|
||||||
GstPipeline *pipeline;
|
GstElement *pipeline;
|
||||||
|
|
||||||
if (argc != 2) {
|
if (argc != 2) {
|
||||||
g_print("usage: %s <filename>\n", argv[0]);
|
g_print("usage: %s <filename>\n", argv[0]);
|
||||||
|
@ -44,8 +44,6 @@ int main(int argc,char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_init(&argc,&argv);
|
gst_init(&argc,&argv);
|
||||||
gst_plugin_load_all();
|
|
||||||
g_print("\n");
|
|
||||||
|
|
||||||
/* create a new bin to hold the elements */
|
/* create a new bin to hold the elements */
|
||||||
pipeline = gst_pipeline_new("pipeline");
|
pipeline = gst_pipeline_new("pipeline");
|
||||||
|
@ -63,7 +61,7 @@ int main(int argc,char *argv[])
|
||||||
gst_bin_add(GST_BIN(pipeline), disksrc);
|
gst_bin_add(GST_BIN(pipeline), disksrc);
|
||||||
gst_bin_add(GST_BIN(pipeline), audiosink);
|
gst_bin_add(GST_BIN(pipeline), audiosink);
|
||||||
|
|
||||||
if (!gst_pipeline_autoplug(pipeline)) {
|
if (!gst_pipeline_autoplug(GST_PIPELINE(pipeline))) {
|
||||||
g_print("unable to handle stream\n");
|
g_print("unable to handle stream\n");
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
@ -159,8 +157,8 @@ int main(int argc,char *argv[])
|
||||||
To compile the helloworld2 example, use:
|
To compile the helloworld2 example, use:
|
||||||
</para>
|
</para>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
gcc -Wall `gstreamer-config --cflags` `gtk-config --cflags` helloworld2.c \
|
gcc -Wall `gstreamer-config --cflags --libs` helloworld2.c \
|
||||||
-o helloworld2 `gstreamer-config --libs` `gtk-config --libs`
|
-o helloworld2
|
||||||
</programlisting>
|
</programlisting>
|
||||||
<para>
|
<para>
|
||||||
You can run the example with (substitute helloworld.mp3 with you favorite MP3 file):
|
You can run the example with (substitute helloworld.mp3 with you favorite MP3 file):
|
||||||
|
@ -175,7 +173,7 @@ int main(int argc,char *argv[])
|
||||||
the pipeline.
|
the pipeline.
|
||||||
</para>
|
</para>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
./helloworld2 helloworld.mpeg
|
./helloworld2 mymovie.mpeg
|
||||||
</programlisting>
|
</programlisting>
|
||||||
|
|
||||||
</sect1>
|
</sect1>
|
||||||
|
|
|
@ -3,4 +3,104 @@
|
||||||
<para>
|
<para>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
<sect1>
|
||||||
|
<title><command>gstreamer-config</command></title>
|
||||||
|
<para>
|
||||||
|
<command>gstreamer-config</command> is a script to get information about the installed
|
||||||
|
version of <application>GStreamer</application>.
|
||||||
|
This program "knows" what compiler switches are needed to compile programs that use
|
||||||
|
<application>GStreamer</application>.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
<command>gstreamer-config</command> accepts the following options:
|
||||||
|
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<option>--version</option> Print the currently installed version of
|
||||||
|
<application>GStreamer</application> on the standard output.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<option>--libs</option> Print the linker flags that are necessary to link a
|
||||||
|
<application>GStreamer</application> program.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<option>--cflags</option> Print the compiler flags that are necessary to compile a
|
||||||
|
<application>GStreamer</application> program.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<option>--prefix=<replaceable>PREFIX</replaceable></option>
|
||||||
|
If specified, use <replaceable>PREFIX</replaceable> instead of the installation
|
||||||
|
prefix that <application>GStreamer</application> was built with when computing the
|
||||||
|
output for the <option>--cflags</option> and <option>--libs</option> options.
|
||||||
|
This option is also used for the exec prefix if
|
||||||
|
<option>--exec-prefix</option> was not specified. This option must be specified before any
|
||||||
|
<option>--libs</option> or <option>--cflags</option> options.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<option>--exec-prefix=<replaceable>PREFIX</replaceable></option>
|
||||||
|
If specified, use <replaceable>PREFIX</replaceable> instead of the installation exec
|
||||||
|
prefix that <application>GStreamer</application> was built with when computing the
|
||||||
|
output for the <option>--cflags</option> and <option>--libs</option> options. This option must be
|
||||||
|
specified before any <option>--libs</option> or <option>--cflags</option>
|
||||||
|
options.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
A simple <filename>Makefile</filename> will contain something like:
|
||||||
|
<programlisting>
|
||||||
|
CC = gcc
|
||||||
|
|
||||||
|
helloworld2: helloworld2.c
|
||||||
|
$(CC) -Wall `gstreamer-config --cflags --libs` helloworld2.c -o helloworld2
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f *.o helloworld2
|
||||||
|
</programlisting>
|
||||||
|
</para>
|
||||||
|
</sect1>
|
||||||
|
|
||||||
|
<sect1>
|
||||||
|
<title><command>gstreamer-register</command></title>
|
||||||
|
<para>
|
||||||
|
<command>gstreamer-register</command> is used to rebuild the database of plugins.
|
||||||
|
It is used after a new plugin has been added to the system. The plugin database
|
||||||
|
can be found in <filename>/etc/gstreamer/reg.xml</filename>.
|
||||||
|
</para>
|
||||||
|
</sect1>
|
||||||
|
|
||||||
|
<sect1>
|
||||||
|
<title><command>gstreamer-launch</command></title>
|
||||||
|
<para>
|
||||||
|
This is a tool that will construct pipelines based on a command-line
|
||||||
|
syntax.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
A simple commandline looks like:
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
gstreamer-launch disksrc hello.mp3 ! mp3parse ! mpg123 ! audiosink-oss
|
||||||
|
</screen>
|
||||||
|
|
||||||
|
A more complex pipeline looks like:
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
gstreamer-launch disksrc redpill.vob ! css-descramble ! private_stream_1.0 ! \
|
||||||
|
(ac3parse ! ac3dec ! audiosink) video_0 ! (mpeg2dec ! videosink)
|
||||||
|
</screen>
|
||||||
|
|
||||||
|
</para>
|
||||||
|
</sect1>
|
||||||
|
|
||||||
</chapter>
|
</chapter>
|
||||||
|
|
|
@ -1,6 +1,32 @@
|
||||||
<chapter id="cha-queues">
|
<chapter id="cha-queues">
|
||||||
<title>Queues</title>
|
<title>Queues</title>
|
||||||
<para>
|
<para>
|
||||||
|
A <classname>GstQueue</classname> is an implementation of a <classname>GstConnection</classname>.
|
||||||
|
Queues can be used to connect two elements in such way that the data can
|
||||||
|
be buffered.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
A buffer that is sinked to a Queue will not automatically be pushed to the
|
||||||
|
next connected element but will be buffered. It will be pushed to the next
|
||||||
|
element as soon as gst_connection_push() is called.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Queues are mostly used in conjunction with a <classname>GstThread</classname> to
|
||||||
|
provide an external connection for the thread elements. You could have one
|
||||||
|
thread feeding buffers into a <classname>GstQueue</classname> and another
|
||||||
|
thread repeadedly calling gst_connection_push() on the queue to feed its
|
||||||
|
internal elements.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Below is a figure of a two-threaded decoder. We have one thread (the main execution
|
||||||
|
thread) reading the data from a file, and another thread decoding the data.
|
||||||
|
</para>
|
||||||
|
<figure float="1" id="sec-queues-img">
|
||||||
|
<title>a two-threaded decoder with a queue</title>
|
||||||
|
<graphic fileref="images/queue" format="png"></graphic>
|
||||||
|
</figure>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</chapter>
|
</chapter>
|
||||||
|
|
|
@ -1,6 +1,142 @@
|
||||||
<chapter id="cha-threads">
|
<chapter id="cha-threads">
|
||||||
<title>Threads</title>
|
<title>Threads</title>
|
||||||
<para>
|
<para>
|
||||||
|
GStreamer has support for multithreading throught the use of
|
||||||
|
the <classname>GstThread</classname> object. This object is in fact
|
||||||
|
a special <classname>GstBin</classname> that will become a thread when started.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
To construct a new thread you will perform something like:
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<programlisting>
|
||||||
|
GstElement *my_thread;
|
||||||
|
|
||||||
|
// create the thread object
|
||||||
|
my_thread = gst_thread_new("my_thread");
|
||||||
|
g_return_if_fail(audio_thread != NULL);
|
||||||
|
|
||||||
|
// add some plugins
|
||||||
|
gst_bin_add(GST_BIN(my_thread),GST_ELEMENT(funky_src));
|
||||||
|
gst_bin_add(GST_BIN(my_thread),GST_ELEMENT(cool_effect));
|
||||||
|
|
||||||
|
// connect the elements here...
|
||||||
|
...
|
||||||
|
|
||||||
|
// prepare the thread
|
||||||
|
gst_element_set_state(GST_ELEMENT(my_thread),GST_STATE_READY);
|
||||||
|
|
||||||
|
// start playing
|
||||||
|
gst_element_set_state(GST_ELEMENT(my_thread),GST_STATE_PLAYING);
|
||||||
|
|
||||||
|
</programlisting>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The above program will create a thread with two elements in it. As soon
|
||||||
|
as it is set to the PLAYING state, the thread will start to iterate.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<note>
|
||||||
|
<para>
|
||||||
|
The thread must contain at least one element of type <classname>GstSrc</classname>
|
||||||
|
or <classname>GstConnection</classname> in order to work.
|
||||||
|
</para>
|
||||||
|
</note>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
A thread will be visualised as below
|
||||||
|
</para>
|
||||||
|
<figure float="1" id="sec-threads-img">
|
||||||
|
<title>a thread</title>
|
||||||
|
<graphic fileref="images/thread" format="png"></graphic>
|
||||||
|
</figure>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
As an example we show the helloworld program using a thread.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<programlisting>
|
||||||
|
#include <gst/gst.h>
|
||||||
|
|
||||||
|
/* eos will be called when the src element has an end os stream */
|
||||||
|
void eos(GstSrc *src, gpointer data)
|
||||||
|
{
|
||||||
|
GstThread *thread = GST_THREAD(data);
|
||||||
|
g_print("have eos, quitting\n");
|
||||||
|
|
||||||
|
/* stop the bin */
|
||||||
|
gst_element_set_state(GST_ELEMENT(thread), GST_STATE_NULL);
|
||||||
|
|
||||||
|
gst_main_quit();
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc,char *argv[])
|
||||||
|
{
|
||||||
|
GstElement *disksrc, *audiosink;
|
||||||
|
GstElement *pipeline;
|
||||||
|
GstElement *thread;
|
||||||
|
|
||||||
|
if (argc != 2) {
|
||||||
|
g_print("usage: %s <filename>\n", argv[0]);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
gst_init(&argc,&argv);
|
||||||
|
|
||||||
|
/* create a new thread to hold the elements */
|
||||||
|
thread = gst_thread_new("thread");
|
||||||
|
g_assert(thread != NULL);
|
||||||
|
|
||||||
|
/* create a new bin to hold the elements */
|
||||||
|
pipeline = gst_pipeline_new("pipeline");
|
||||||
|
g_assert(pipeline != NULL);
|
||||||
|
|
||||||
|
/* create a disk reader */
|
||||||
|
disksrc = gst_elementfactory_make("disksrc", "disk_source");
|
||||||
|
g_assert(disksrc != NULL);
|
||||||
|
gtk_object_set(GTK_OBJECT(disksrc),"location", argv[1],NULL);
|
||||||
|
gtk_signal_connect(GTK_OBJECT(disksrc),"eos",
|
||||||
|
GTK_SIGNAL_FUNC(eos), thread);
|
||||||
|
|
||||||
|
/* and an audio sink */
|
||||||
|
audiosink = gst_elementfactory_make("audiosink", "play_audio");
|
||||||
|
g_assert(audiosink != NULL);
|
||||||
|
|
||||||
|
/* add objects to the main pipeline */
|
||||||
|
gst_bin_add(GST_BIN(pipeline), disksrc);
|
||||||
|
gst_bin_add(GST_BIN(pipeline), audiosink);
|
||||||
|
|
||||||
|
/* automatically setup the pipeline */
|
||||||
|
if (!gst_pipeline_autoplug(GST_PIPELINE(pipeline))) {
|
||||||
|
g_print("unable to handle stream\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* remove the source element from the pipeline */
|
||||||
|
gst_bin_remove(GST_BIN(pipeline), disksrc);
|
||||||
|
|
||||||
|
/* insert the source element in the thread, remember a thread needs at
|
||||||
|
least one source or connection element */
|
||||||
|
gst_bin_add(GST_BIN(thread), disksrc);
|
||||||
|
|
||||||
|
/* add the pipeline to the thread too */
|
||||||
|
gst_bin_add(GST_BIN(thread), GST_ELEMENT(pipeline));
|
||||||
|
|
||||||
|
/* make it ready */
|
||||||
|
gst_element_set_state(GST_ELEMENT(thread), GST_STATE_READY);
|
||||||
|
/* start playing */
|
||||||
|
gst_element_set_state(GST_ELEMENT(thread), GST_STATE_PLAYING);
|
||||||
|
|
||||||
|
/* do whatever you want here, the thread will be playing */
|
||||||
|
...
|
||||||
|
|
||||||
|
gst_main();
|
||||||
|
|
||||||
|
gst_pipeline_destroy(thread);
|
||||||
|
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
</programlisting>
|
||||||
|
|
||||||
</chapter>
|
</chapter>
|
||||||
|
|
|
@ -37,6 +37,7 @@ int main(int argc,char *argv[]) {
|
||||||
_gst_plugin_spew = TRUE;
|
_gst_plugin_spew = TRUE;
|
||||||
gst_init(&argc,&argv);
|
gst_init(&argc,&argv);
|
||||||
gst_plugin_load_all();
|
gst_plugin_load_all();
|
||||||
|
gst_plugin_load("gstelements");
|
||||||
gnome_init("GST Graph Editor",VERSION,argc,argv);
|
gnome_init("GST Graph Editor",VERSION,argc,argv);
|
||||||
|
|
||||||
appwindow = gnome_app_new("gst-editor","GST Graph Editor");
|
appwindow = gnome_app_new("gst-editor","GST Graph Editor");
|
||||||
|
|
|
@ -120,7 +120,7 @@ static void gst_editor_set_arg(GtkObject *object,GtkArg *arg,guint id) {
|
||||||
switch (id) {
|
switch (id) {
|
||||||
case ARG_NAME:
|
case ARG_NAME:
|
||||||
gtk_object_set(GTK_OBJECT(editor),"label",GTK_VALUE_STRING(*arg),NULL);
|
gtk_object_set(GTK_OBJECT(editor),"label",GTK_VALUE_STRING(*arg),NULL);
|
||||||
gst_element_set_name(GST_OBJECT(editor->pipeline),
|
gst_element_set_name(GST_ELEMENT(editor->pipeline),
|
||||||
GTK_VALUE_STRING(*arg));
|
GTK_VALUE_STRING(*arg));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -135,7 +135,7 @@ static void gst_editor_get_arg(GtkObject *object,GtkArg *arg,guint id) {
|
||||||
switch (id) {
|
switch (id) {
|
||||||
case ARG_NAME:
|
case ARG_NAME:
|
||||||
GTK_VALUE_STRING(*arg) =
|
GTK_VALUE_STRING(*arg) =
|
||||||
gst_element_get_name(GST_OBJECT(editor->pipeline));
|
gst_element_get_name(GST_ELEMENT(editor->pipeline));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
arg->type = GTK_TYPE_INVALID;
|
arg->type = GTK_TYPE_INVALID;
|
||||||
|
|
|
@ -56,7 +56,7 @@ struct _GstEditor {
|
||||||
GtkFrame frame;
|
GtkFrame frame;
|
||||||
|
|
||||||
/* the actual pipeline to be associated with this thing */
|
/* the actual pipeline to be associated with this thing */
|
||||||
GstPipeline *pipeline;
|
GstElement *pipeline;
|
||||||
|
|
||||||
/* the editor canvas */
|
/* the editor canvas */
|
||||||
GstEditorCanvas *canvas;
|
GstEditorCanvas *canvas;
|
||||||
|
|
|
@ -201,6 +201,7 @@ GstElementFactory *element_select_dialog() {
|
||||||
elements = gst_elementfactory_get_list();
|
elements = gst_elementfactory_get_list();
|
||||||
while (elements) {
|
while (elements) {
|
||||||
element = (GstElementFactory *)(elements->data);
|
element = (GstElementFactory *)(elements->data);
|
||||||
|
printf("%s %s\n", element->name, element->details->class);
|
||||||
/* split up the factory's class */
|
/* split up the factory's class */
|
||||||
classes = g_strsplit(element->details->class,"/",0);
|
classes = g_strsplit(element->details->class,"/",0);
|
||||||
class = classes;
|
class = classes;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
CC = gcc
|
CC = gcc
|
||||||
|
|
||||||
helloworld: helloworld.c
|
helloworld: helloworld.c
|
||||||
$(CC) -Wall `gstreamer-config --cflags` `gtk-config --cflags` helloworld.c -o helloworld `gstreamer-config --libs` `gtk-config --libs`
|
$(CC) -Wall `gstreamer-config --cflags --libs` helloworld.c -o helloworld
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f *.o helloworld
|
rm -f *.o helloworld
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
gboolean playing;
|
gboolean playing;
|
||||||
|
|
||||||
/* eos will be called when the src element has an end os stream */
|
/* eos will be called when the src element has an end of stream */
|
||||||
void eos(GstSrc *src)
|
void eos(GstSrc *src)
|
||||||
{
|
{
|
||||||
g_print("have eos, quitting\n");
|
g_print("have eos, quitting\n");
|
||||||
|
@ -20,8 +20,6 @@ int main(int argc,char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_init(&argc,&argv);
|
gst_init(&argc,&argv);
|
||||||
gst_plugin_load_all();
|
|
||||||
g_print("\n");
|
|
||||||
|
|
||||||
/* create a new bin to hold the elements */
|
/* create a new bin to hold the elements */
|
||||||
bin = gst_bin_new("bin");
|
bin = gst_bin_new("bin");
|
||||||
|
@ -40,6 +38,7 @@ int main(int argc,char *argv[])
|
||||||
|
|
||||||
/* add objects to the main pipeline */
|
/* add objects to the main pipeline */
|
||||||
gst_bin_add(GST_BIN(bin), disksrc);
|
gst_bin_add(GST_BIN(bin), disksrc);
|
||||||
|
gst_bin_add(GST_BIN(bin), parse);
|
||||||
gst_bin_add(GST_BIN(bin), decoder);
|
gst_bin_add(GST_BIN(bin), decoder);
|
||||||
gst_bin_add(GST_BIN(bin), audiosink);
|
gst_bin_add(GST_BIN(bin), audiosink);
|
||||||
|
|
||||||
|
@ -69,6 +68,7 @@ int main(int argc,char *argv[])
|
||||||
gst_element_set_state(bin, GST_STATE_NULL);
|
gst_element_set_state(bin, GST_STATE_NULL);
|
||||||
|
|
||||||
gst_object_destroy(GST_OBJECT(audiosink));
|
gst_object_destroy(GST_OBJECT(audiosink));
|
||||||
|
gst_object_destroy(GST_OBJECT(parse));
|
||||||
gst_object_destroy(GST_OBJECT(decoder));
|
gst_object_destroy(GST_OBJECT(decoder));
|
||||||
gst_object_destroy(GST_OBJECT(disksrc));
|
gst_object_destroy(GST_OBJECT(disksrc));
|
||||||
gst_object_destroy(GST_OBJECT(bin));
|
gst_object_destroy(GST_OBJECT(bin));
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
CC = gcc
|
CC = gcc
|
||||||
|
|
||||||
helloworld2: helloworld2.c
|
helloworld2: helloworld2.c
|
||||||
$(CC) -Wall `gstreamer-config --cflags` `gtk-config --cflags` helloworld2.c -o helloworld2 `gstreamer-config --libs` `gtk-config --libs`
|
$(CC) -Wall `gstreamer-config --cflags --libs` helloworld2.c -o helloworld2
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f *.o helloworld2
|
rm -f *.o helloworld2
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
static gboolean playing;
|
static gboolean playing;
|
||||||
|
|
||||||
/* eos will be called when the src element has an end os stream */
|
/* eos will be called when the src element has an end of stream */
|
||||||
void eos(GstSrc *src)
|
void eos(GstSrc *src)
|
||||||
{
|
{
|
||||||
g_print("have eos, quitting\n");
|
g_print("have eos, quitting\n");
|
||||||
|
@ -13,7 +13,7 @@ void eos(GstSrc *src)
|
||||||
int main(int argc,char *argv[])
|
int main(int argc,char *argv[])
|
||||||
{
|
{
|
||||||
GstElement *disksrc, *audiosink;
|
GstElement *disksrc, *audiosink;
|
||||||
GstPipeline *pipeline;
|
GstElement *pipeline;
|
||||||
|
|
||||||
if (argc != 2) {
|
if (argc != 2) {
|
||||||
g_print("usage: %s <filename>\n", argv[0]);
|
g_print("usage: %s <filename>\n", argv[0]);
|
||||||
|
@ -41,7 +41,7 @@ int main(int argc,char *argv[])
|
||||||
gst_bin_add(GST_BIN(pipeline), disksrc);
|
gst_bin_add(GST_BIN(pipeline), disksrc);
|
||||||
gst_bin_add(GST_BIN(pipeline), audiosink);
|
gst_bin_add(GST_BIN(pipeline), audiosink);
|
||||||
|
|
||||||
if (!gst_pipeline_autoplug(pipeline)) {
|
if (!gst_pipeline_autoplug(GST_PIPELINE(pipeline))) {
|
||||||
g_print("unable to handle stream\n");
|
g_print("unable to handle stream\n");
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ extern "C" {
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
|
||||||
GstElementDetails gst_disksrc_details;
|
extern GstElementDetails gst_disksrc_details;
|
||||||
|
|
||||||
|
|
||||||
#define GST_TYPE_DISKSRC \
|
#define GST_TYPE_DISKSRC \
|
||||||
|
@ -43,7 +43,7 @@ GstElementDetails gst_disksrc_details;
|
||||||
#define GST_IS_DISKSRC(obj) \
|
#define GST_IS_DISKSRC(obj) \
|
||||||
(GTK_CHECK_TYPE((obj),GST_TYPE_DISKSRC))
|
(GTK_CHECK_TYPE((obj),GST_TYPE_DISKSRC))
|
||||||
#define GST_IS_DISKSRC_CLASS(obj) \
|
#define GST_IS_DISKSRC_CLASS(obj) \
|
||||||
(GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_DISKSRC)))
|
(GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_DISKSRC))
|
||||||
|
|
||||||
// NOTE: per-element flags start with 16 for now
|
// NOTE: per-element flags start with 16 for now
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
|
|
@ -70,8 +70,6 @@ GstPlugin *plugin_init(GModule *module) {
|
||||||
GstElementFactory *factory;
|
GstElementFactory *factory;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
if (gst_plugin_find("gstelements") != NULL) return NULL;
|
|
||||||
|
|
||||||
plugin = gst_plugin_new("gstelements");
|
plugin = gst_plugin_new("gstelements");
|
||||||
g_return_val_if_fail(plugin != NULL,NULL);
|
g_return_val_if_fail(plugin != NULL,NULL);
|
||||||
|
|
||||||
|
|
10
gst/gst.c
10
gst/gst.c
|
@ -57,3 +57,13 @@ void gst_init(int *argc,char **argv[]) {
|
||||||
gst_trace_set_default(gst_trace);
|
gst_trace_set_default(gst_trace);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void gst_main() {
|
||||||
|
gdk_threads_enter();
|
||||||
|
gtk_main();
|
||||||
|
gdk_threads_leave();
|
||||||
|
}
|
||||||
|
|
||||||
|
void gst_main_quit() {
|
||||||
|
gtk_main_quit();
|
||||||
|
}
|
||||||
|
|
|
@ -50,6 +50,9 @@
|
||||||
/* initialize GST */
|
/* initialize GST */
|
||||||
void gst_init(int *argc,char **argv[]);
|
void gst_init(int *argc,char **argv[]);
|
||||||
|
|
||||||
|
void gst_main();
|
||||||
|
void gst_main_quit();
|
||||||
|
|
||||||
/* debugging */
|
/* debugging */
|
||||||
#ifndef DEBUG
|
#ifndef DEBUG
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
GstElementDetails gst_bin_details;
|
extern GstElementDetails gst_bin_details;
|
||||||
|
|
||||||
|
|
||||||
#define GST_TYPE_BIN \
|
#define GST_TYPE_BIN \
|
||||||
|
|
|
@ -122,6 +122,7 @@ GstElement *gst_elementfactory_create(GstElementFactory *factory,
|
||||||
// create an instance of the element
|
// create an instance of the element
|
||||||
element = GST_ELEMENT(gtk_type_new(factory->type));
|
element = GST_ELEMENT(gtk_type_new(factory->type));
|
||||||
g_assert(element != NULL);
|
g_assert(element != NULL);
|
||||||
|
gst_object_ref(GST_OBJECT(element));
|
||||||
|
|
||||||
// attempt to set the elemenfactory class pointer if necessary
|
// attempt to set the elemenfactory class pointer if necessary
|
||||||
oclass = GST_ELEMENT_CLASS(GTK_OBJECT(element)->klass);
|
oclass = GST_ELEMENT_CLASS(GTK_OBJECT(element)->klass);
|
||||||
|
|
|
@ -102,12 +102,12 @@ static void gst_pipeline_init(GstPipeline *pipeline) {
|
||||||
*
|
*
|
||||||
* Returns: newly created GstPipeline
|
* Returns: newly created GstPipeline
|
||||||
*/
|
*/
|
||||||
GstPipeline *gst_pipeline_new(guchar *name) {
|
GstElement *gst_pipeline_new(guchar *name) {
|
||||||
GstPipeline *pipeline;
|
GstPipeline *pipeline;
|
||||||
|
|
||||||
pipeline = gtk_type_new(gst_pipeline_get_type());
|
pipeline = gtk_type_new(gst_pipeline_get_type());
|
||||||
gst_element_set_name(GST_ELEMENT(pipeline),name);
|
gst_element_set_name(GST_ELEMENT(pipeline),name);
|
||||||
return pipeline;
|
return GST_ELEMENT(pipeline);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gst_pipeline_prepare(GstPipeline *pipeline) {
|
static void gst_pipeline_prepare(GstPipeline *pipeline) {
|
||||||
|
@ -157,6 +157,7 @@ static guint16 gst_pipeline_typefind(GstPipeline *pipeline, GstElement *element)
|
||||||
gst_pad_disconnect(gst_element_get_pad(element,"src"),
|
gst_pad_disconnect(gst_element_get_pad(element,"src"),
|
||||||
gst_element_get_pad(typefind,"sink"));
|
gst_element_get_pad(typefind,"sink"));
|
||||||
gst_bin_remove(GST_BIN(pipeline), typefind);
|
gst_bin_remove(GST_BIN(pipeline), typefind);
|
||||||
|
gst_object_unref(GST_OBJECT(typefind));
|
||||||
|
|
||||||
return type_id;
|
return type_id;
|
||||||
}
|
}
|
||||||
|
@ -223,7 +224,7 @@ end:
|
||||||
|
|
||||||
gboolean gst_pipeline_autoplug(GstPipeline *pipeline) {
|
gboolean gst_pipeline_autoplug(GstPipeline *pipeline) {
|
||||||
GList *elements;
|
GList *elements;
|
||||||
GstElement *element, *srcelement, *sinkelement;
|
GstElement *element, *srcelement = NULL, *sinkelement= NULL;
|
||||||
GList *factories;
|
GList *factories;
|
||||||
GstElementFactory *factory;
|
GstElementFactory *factory;
|
||||||
GList *src_types, *sink_types;
|
GList *src_types, *sink_types;
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
GstElementDetails gst_pipeline_details;
|
extern GstElementDetails gst_pipeline_details;
|
||||||
|
|
||||||
|
|
||||||
#define GST_TYPE_PIPELINE \
|
#define GST_TYPE_PIPELINE \
|
||||||
|
@ -55,7 +55,7 @@ struct _GstPipelineClass {
|
||||||
};
|
};
|
||||||
|
|
||||||
GtkType gst_pipeline_get_type(void);
|
GtkType gst_pipeline_get_type(void);
|
||||||
GstPipeline *gst_pipeline_new(guchar *name);
|
GstElement *gst_pipeline_new(guchar *name);
|
||||||
#define gst_pipeline_destroy(pipeline) gst_object_destroy(GST_OBJECT(pipeline))
|
#define gst_pipeline_destroy(pipeline) gst_object_destroy(GST_OBJECT(pipeline))
|
||||||
|
|
||||||
gboolean gst_pipeline_autoplug(GstPipeline *pipeline);
|
gboolean gst_pipeline_autoplug(GstPipeline *pipeline);
|
||||||
|
|
|
@ -253,7 +253,7 @@ gboolean gst_plugin_load_absolute(gchar *name) {
|
||||||
return TRUE;
|
return TRUE;
|
||||||
} else if (_gst_plugin_spew) {
|
} else if (_gst_plugin_spew) {
|
||||||
// if (strstr(g_module_error(),"No such") == NULL)
|
// if (strstr(g_module_error(),"No such") == NULL)
|
||||||
gst_info("error loading plugin: %s\n",g_module_error());
|
gst_info("error loading plugin: %s, reasion: %s\n", name, g_module_error());
|
||||||
}
|
}
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
|
@ -70,7 +70,7 @@ gst_src_class_init(GstSrcClass *klass) {
|
||||||
gst_src_signals[EOS] =
|
gst_src_signals[EOS] =
|
||||||
gtk_signal_new("eos",GTK_RUN_LAST,gtkobject_class->type,
|
gtk_signal_new("eos",GTK_RUN_LAST,gtkobject_class->type,
|
||||||
GTK_SIGNAL_OFFSET(GstSrcClass,eos),
|
GTK_SIGNAL_OFFSET(GstSrcClass,eos),
|
||||||
gtk_marshal_NONE__POINTER,GTK_TYPE_NONE,1,
|
gtk_marshal_NONE__NONE,GTK_TYPE_NONE,0,
|
||||||
GST_TYPE_SRC);
|
GST_TYPE_SRC);
|
||||||
gtk_object_class_add_signals(gtkobject_class,gst_src_signals,LAST_SIGNAL);
|
gtk_object_class_add_signals(gtkobject_class,gst_src_signals,LAST_SIGNAL);
|
||||||
}
|
}
|
||||||
|
@ -90,7 +90,7 @@ void gst_src_signal_eos(GstSrc *src) {
|
||||||
g_return_if_fail(src != NULL);
|
g_return_if_fail(src != NULL);
|
||||||
g_return_if_fail(GST_IS_SRC(src));
|
g_return_if_fail(GST_IS_SRC(src));
|
||||||
|
|
||||||
gtk_signal_emit(GTK_OBJECT(src),gst_src_signals[EOS],src);
|
gtk_signal_emit(GTK_OBJECT(src),gst_src_signals[EOS]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -217,11 +217,17 @@ static GstElementStateReturn gst_thread_change_state(GstElement *element) {
|
||||||
gst_thread_signal_thread(thread);
|
gst_thread_signal_thread(thread);
|
||||||
break;
|
break;
|
||||||
case GST_STATE_PAUSED:
|
case GST_STATE_PAUSED:
|
||||||
gst_info("gstthread: stopping thread \"%s\"\n",
|
gst_info("gstthread: pausing thread \"%s\"\n",
|
||||||
gst_element_get_name(GST_ELEMENT(element)));
|
gst_element_get_name(GST_ELEMENT(element)));
|
||||||
GST_FLAG_UNSET(thread,GST_THREAD_STATE_SPINNING);
|
GST_FLAG_UNSET(thread,GST_THREAD_STATE_SPINNING);
|
||||||
gst_thread_signal_thread(thread);
|
gst_thread_signal_thread(thread);
|
||||||
break;
|
break;
|
||||||
|
case GST_STATE_NULL:
|
||||||
|
gst_info("gstthread: stopping thread \"%s\"\n",
|
||||||
|
gst_element_get_name(GST_ELEMENT(element)));
|
||||||
|
GST_FLAG_SET(thread,GST_THREAD_STATE_REAPING);
|
||||||
|
gst_thread_signal_thread(thread);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -253,7 +259,7 @@ void *gst_thread_main_loop(void *arg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_FLAG_UNSET(thread,GST_THREAD_STATE_REAPING);
|
GST_FLAG_UNSET(thread,GST_THREAD_STATE_REAPING);
|
||||||
//pthread_join(thread->thread_id,0);
|
pthread_join(thread->thread_id,0);
|
||||||
|
|
||||||
gst_info("gstthread: thread \"%s\" is stopped\n",
|
gst_info("gstthread: thread \"%s\" is stopped\n",
|
||||||
gst_element_get_name(GST_ELEMENT(thread)));
|
gst_element_get_name(GST_ELEMENT(thread)));
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
GstElementDetails gst_thread_details;
|
extern GstElementDetails gst_thread_details;
|
||||||
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
|
|
@ -20,17 +20,20 @@ void mpeg1_new_pad_created(GstElement *parse,GstPad *pad,GstElement *pipeline)
|
||||||
{
|
{
|
||||||
|
|
||||||
g_print("***** a new pad %s was created\n", gst_pad_get_name(pad));
|
g_print("***** a new pad %s was created\n", gst_pad_get_name(pad));
|
||||||
gst_element_set_state(GST_ELEMENT(pipeline),GST_STATE_PAUSED);
|
|
||||||
|
|
||||||
// connect to audio pad
|
// connect to audio pad
|
||||||
//if (0) {
|
//if (0) {
|
||||||
if (strncmp(gst_pad_get_name(pad), "audio_", 6) == 0 && audio_render_queue) {
|
if (strncmp(gst_pad_get_name(pad), "audio_", 6) == 0 && audio_render_queue) {
|
||||||
|
gst_element_set_state(GST_ELEMENT(pipeline),GST_STATE_PAUSED);
|
||||||
mpeg1_setup_audio_thread(pad, audio_render_queue, pipeline);
|
mpeg1_setup_audio_thread(pad, audio_render_queue, pipeline);
|
||||||
|
|
||||||
} else if (strncmp(gst_pad_get_name(pad), "video_", 6) == 0) {
|
} else if (strncmp(gst_pad_get_name(pad), "video_", 6) == 0) {
|
||||||
//} else if (0) {
|
//} else if (0) {
|
||||||
|
gst_element_set_state(GST_ELEMENT(pipeline),GST_STATE_PAUSED);
|
||||||
mpeg1_setup_video_thread(pad, video_render_queue, pipeline);
|
mpeg1_setup_video_thread(pad, video_render_queue, pipeline);
|
||||||
}
|
}
|
||||||
|
else return;
|
||||||
|
|
||||||
gst_element_set_state(GST_ELEMENT(pipeline),GST_STATE_PLAYING);
|
gst_element_set_state(GST_ELEMENT(pipeline),GST_STATE_PLAYING);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,15 +23,16 @@ void mpeg2_new_pad_created(GstElement *parse,GstPad *pad,GstElement *pipeline)
|
||||||
GstElement *audio_thread;
|
GstElement *audio_thread;
|
||||||
|
|
||||||
g_print("***** a new pad %s was created\n", gst_pad_get_name(pad));
|
g_print("***** a new pad %s was created\n", gst_pad_get_name(pad));
|
||||||
gst_element_set_state(GST_ELEMENT(pipeline),GST_STATE_PAUSED);
|
|
||||||
|
|
||||||
// connect to audio pad
|
// connect to audio pad
|
||||||
if (strncmp(gst_pad_get_name(pad), "video_", 6) == 0) {
|
if (strncmp(gst_pad_get_name(pad), "video_", 6) == 0) {
|
||||||
|
gst_element_set_state(GST_ELEMENT(pipeline),GST_STATE_PAUSED);
|
||||||
mpeg2_setup_video_thread(pad, video_render_queue, pipeline);
|
mpeg2_setup_video_thread(pad, video_render_queue, pipeline);
|
||||||
gst_element_set_state(GST_ELEMENT(pipeline),GST_STATE_PLAYING);
|
gst_element_set_state(GST_ELEMENT(pipeline),GST_STATE_PLAYING);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (strncmp(gst_pad_get_name(pad), "private_stream_1.0", 18) == 0) {
|
else if (strncmp(gst_pad_get_name(pad), "private_stream_1.0", 18) == 0) {
|
||||||
|
gst_element_set_state(GST_ELEMENT(pipeline),GST_STATE_PAUSED);
|
||||||
gst_plugin_load("ac3parse");
|
gst_plugin_load("ac3parse");
|
||||||
gst_plugin_load("ac3dec");
|
gst_plugin_load("ac3dec");
|
||||||
// construct internal pipeline elements
|
// construct internal pipeline elements
|
||||||
|
@ -40,12 +41,14 @@ void mpeg2_new_pad_created(GstElement *parse,GstPad *pad,GstElement *pipeline)
|
||||||
decode = gst_elementfactory_make("ac3dec","decode_audio");
|
decode = gst_elementfactory_make("ac3dec","decode_audio");
|
||||||
g_return_if_fail(decode != NULL);
|
g_return_if_fail(decode != NULL);
|
||||||
} else if (strncmp(gst_pad_get_name(pad), "subtitle_stream_4", 17) == 0) {
|
} else if (strncmp(gst_pad_get_name(pad), "subtitle_stream_4", 17) == 0) {
|
||||||
|
gst_element_set_state(GST_ELEMENT(pipeline),GST_STATE_PAUSED);
|
||||||
gst_pad_connect(pad,
|
gst_pad_connect(pad,
|
||||||
gst_element_get_pad(merge_subtitles,"subtitle"));
|
gst_element_get_pad(merge_subtitles,"subtitle"));
|
||||||
gst_element_set_state(GST_ELEMENT(pipeline),GST_STATE_PLAYING);
|
gst_element_set_state(GST_ELEMENT(pipeline),GST_STATE_PLAYING);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (strncmp(gst_pad_get_name(pad), "audio_", 6) == 0) {
|
else if (strncmp(gst_pad_get_name(pad), "audio_", 6) == 0) {
|
||||||
|
gst_element_set_state(GST_ELEMENT(pipeline),GST_STATE_PAUSED);
|
||||||
gst_plugin_load("mp3parse");
|
gst_plugin_load("mp3parse");
|
||||||
gst_plugin_load("mpg123");
|
gst_plugin_load("mpg123");
|
||||||
// construct internal pipeline elements
|
// construct internal pipeline elements
|
||||||
|
@ -55,7 +58,6 @@ void mpeg2_new_pad_created(GstElement *parse,GstPad *pad,GstElement *pipeline)
|
||||||
g_return_if_fail(decode != NULL);
|
g_return_if_fail(decode != NULL);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
gst_element_set_state(GST_ELEMENT(pipeline),GST_STATE_PLAYING);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,16 +45,16 @@ while test $# -gt 0; do
|
||||||
if test $prefix -ef @builddir@ ; then
|
if test $prefix -ef @builddir@ ; then
|
||||||
includes=-I@builddir@
|
includes=-I@builddir@
|
||||||
elif test @includedir@ != /usr/include ; then
|
elif test @includedir@ != /usr/include ; then
|
||||||
includes=-I@includedir@
|
includes=-I@includedir@
|
||||||
fi
|
fi
|
||||||
echo $includes
|
echo $includes `gtk-config --cflags`
|
||||||
;;
|
;;
|
||||||
--libs)
|
--libs)
|
||||||
if test $prefix -ef @builddir@ ; then
|
if test $prefix -ef @builddir@ ; then
|
||||||
echo @builddir@/libgst.la
|
echo @builddir@/libgst.la `gtk-config --libs`
|
||||||
else
|
else
|
||||||
libdirs=-L@libdir@
|
libdirs=-L@libdir@
|
||||||
echo $libdirs -lgst
|
echo $libdirs -lgst `gtk-config --libs`
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
|
|
|
@ -31,7 +31,7 @@ extern "C" {
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
|
||||||
GstElementDetails gst_disksrc_details;
|
extern GstElementDetails gst_disksrc_details;
|
||||||
|
|
||||||
|
|
||||||
#define GST_TYPE_DISKSRC \
|
#define GST_TYPE_DISKSRC \
|
||||||
|
@ -43,7 +43,7 @@ GstElementDetails gst_disksrc_details;
|
||||||
#define GST_IS_DISKSRC(obj) \
|
#define GST_IS_DISKSRC(obj) \
|
||||||
(GTK_CHECK_TYPE((obj),GST_TYPE_DISKSRC))
|
(GTK_CHECK_TYPE((obj),GST_TYPE_DISKSRC))
|
||||||
#define GST_IS_DISKSRC_CLASS(obj) \
|
#define GST_IS_DISKSRC_CLASS(obj) \
|
||||||
(GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_DISKSRC)))
|
(GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_DISKSRC))
|
||||||
|
|
||||||
// NOTE: per-element flags start with 16 for now
|
// NOTE: per-element flags start with 16 for now
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
|
|
@ -70,8 +70,6 @@ GstPlugin *plugin_init(GModule *module) {
|
||||||
GstElementFactory *factory;
|
GstElementFactory *factory;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
if (gst_plugin_find("gstelements") != NULL) return NULL;
|
|
||||||
|
|
||||||
plugin = gst_plugin_new("gstelements");
|
plugin = gst_plugin_new("gstelements");
|
||||||
g_return_val_if_fail(plugin != NULL,NULL);
|
g_return_val_if_fail(plugin != NULL,NULL);
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
CC = gcc
|
CC = gcc
|
||||||
|
|
||||||
helloworld: helloworld.c
|
helloworld: helloworld.c
|
||||||
$(CC) -Wall `gstreamer-config --cflags` `gtk-config --cflags` helloworld.c -o helloworld `gstreamer-config --libs` `gtk-config --libs`
|
$(CC) -Wall `gstreamer-config --cflags --libs` helloworld.c -o helloworld
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f *.o helloworld
|
rm -f *.o helloworld
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
gboolean playing;
|
gboolean playing;
|
||||||
|
|
||||||
/* eos will be called when the src element has an end os stream */
|
/* eos will be called when the src element has an end of stream */
|
||||||
void eos(GstSrc *src)
|
void eos(GstSrc *src)
|
||||||
{
|
{
|
||||||
g_print("have eos, quitting\n");
|
g_print("have eos, quitting\n");
|
||||||
|
@ -20,8 +20,6 @@ int main(int argc,char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_init(&argc,&argv);
|
gst_init(&argc,&argv);
|
||||||
gst_plugin_load_all();
|
|
||||||
g_print("\n");
|
|
||||||
|
|
||||||
/* create a new bin to hold the elements */
|
/* create a new bin to hold the elements */
|
||||||
bin = gst_bin_new("bin");
|
bin = gst_bin_new("bin");
|
||||||
|
@ -40,6 +38,7 @@ int main(int argc,char *argv[])
|
||||||
|
|
||||||
/* add objects to the main pipeline */
|
/* add objects to the main pipeline */
|
||||||
gst_bin_add(GST_BIN(bin), disksrc);
|
gst_bin_add(GST_BIN(bin), disksrc);
|
||||||
|
gst_bin_add(GST_BIN(bin), parse);
|
||||||
gst_bin_add(GST_BIN(bin), decoder);
|
gst_bin_add(GST_BIN(bin), decoder);
|
||||||
gst_bin_add(GST_BIN(bin), audiosink);
|
gst_bin_add(GST_BIN(bin), audiosink);
|
||||||
|
|
||||||
|
@ -69,6 +68,7 @@ int main(int argc,char *argv[])
|
||||||
gst_element_set_state(bin, GST_STATE_NULL);
|
gst_element_set_state(bin, GST_STATE_NULL);
|
||||||
|
|
||||||
gst_object_destroy(GST_OBJECT(audiosink));
|
gst_object_destroy(GST_OBJECT(audiosink));
|
||||||
|
gst_object_destroy(GST_OBJECT(parse));
|
||||||
gst_object_destroy(GST_OBJECT(decoder));
|
gst_object_destroy(GST_OBJECT(decoder));
|
||||||
gst_object_destroy(GST_OBJECT(disksrc));
|
gst_object_destroy(GST_OBJECT(disksrc));
|
||||||
gst_object_destroy(GST_OBJECT(bin));
|
gst_object_destroy(GST_OBJECT(bin));
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
CC = gcc
|
CC = gcc
|
||||||
|
|
||||||
helloworld2: helloworld2.c
|
helloworld2: helloworld2.c
|
||||||
$(CC) -Wall `gstreamer-config --cflags` `gtk-config --cflags` helloworld2.c -o helloworld2 `gstreamer-config --libs` `gtk-config --libs`
|
$(CC) -Wall `gstreamer-config --cflags --libs` helloworld2.c -o helloworld2
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f *.o helloworld2
|
rm -f *.o helloworld2
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
static gboolean playing;
|
static gboolean playing;
|
||||||
|
|
||||||
/* eos will be called when the src element has an end os stream */
|
/* eos will be called when the src element has an end of stream */
|
||||||
void eos(GstSrc *src)
|
void eos(GstSrc *src)
|
||||||
{
|
{
|
||||||
g_print("have eos, quitting\n");
|
g_print("have eos, quitting\n");
|
||||||
|
@ -13,7 +13,7 @@ void eos(GstSrc *src)
|
||||||
int main(int argc,char *argv[])
|
int main(int argc,char *argv[])
|
||||||
{
|
{
|
||||||
GstElement *disksrc, *audiosink;
|
GstElement *disksrc, *audiosink;
|
||||||
GstPipeline *pipeline;
|
GstElement *pipeline;
|
||||||
|
|
||||||
if (argc != 2) {
|
if (argc != 2) {
|
||||||
g_print("usage: %s <filename>\n", argv[0]);
|
g_print("usage: %s <filename>\n", argv[0]);
|
||||||
|
@ -41,7 +41,7 @@ int main(int argc,char *argv[])
|
||||||
gst_bin_add(GST_BIN(pipeline), disksrc);
|
gst_bin_add(GST_BIN(pipeline), disksrc);
|
||||||
gst_bin_add(GST_BIN(pipeline), audiosink);
|
gst_bin_add(GST_BIN(pipeline), audiosink);
|
||||||
|
|
||||||
if (!gst_pipeline_autoplug(pipeline)) {
|
if (!gst_pipeline_autoplug(GST_PIPELINE(pipeline))) {
|
||||||
g_print("unable to handle stream\n");
|
g_print("unable to handle stream\n");
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,7 +66,7 @@ void parse(int argc,char *argv[],GstElement *parent,gint offset,gchar endchar) {
|
||||||
// snag the length in advance;
|
// snag the length in advance;
|
||||||
len = strlen(argv[i]);
|
len = strlen(argv[i]);
|
||||||
// if it's just a connection, pick the 'src' pad and move on
|
// if it's just a connection, pick the 'src' pad and move on
|
||||||
if ((ptr = strchr(argv[i],'|')) != 0) {
|
if ((ptr = strchr(argv[i],'!')) != 0) {
|
||||||
// if there's a previous pad name
|
// if there's a previous pad name
|
||||||
if (ptr != argv[i]) {
|
if (ptr != argv[i]) {
|
||||||
ptr[0] = '\0';
|
ptr[0] = '\0';
|
||||||
|
@ -91,29 +91,18 @@ void parse(int argc,char *argv[],GstElement *parent,gint offset,gchar endchar) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc,char *argv[]) {
|
int main(int argc,char *argv[]) {
|
||||||
int t;
|
|
||||||
GstElement *pipeline;
|
GstElement *pipeline;
|
||||||
|
|
||||||
gst_init(&argc,&argv);
|
gst_init(&argc,&argv);
|
||||||
gst_plugin_load_all();
|
|
||||||
|
|
||||||
gst_info("\n\n");
|
pipeline = gst_thread_new("launch");
|
||||||
|
|
||||||
pipeline = gst_elementfactory_make("thread","launch");
|
parse(argc,argv,pipeline,1,0);
|
||||||
if ((t = atoi(argv[1])))
|
|
||||||
parse(argc,argv,pipeline,2,0);
|
|
||||||
else
|
|
||||||
parse(argc,argv,pipeline,1,0);
|
|
||||||
|
|
||||||
xmlSaveFile("launch.xml",gst_xml_write(pipeline));
|
|
||||||
|
|
||||||
gst_element_set_state(pipeline,GST_STATE_READY);
|
gst_element_set_state(pipeline,GST_STATE_READY);
|
||||||
gst_element_set_state(pipeline,GST_STATE_PLAYING);
|
gst_element_set_state(pipeline,GST_STATE_PLAYING);
|
||||||
|
|
||||||
if (t)
|
gst_main();
|
||||||
sleep(t);
|
|
||||||
else
|
|
||||||
sleep(5);
|
|
||||||
|
|
||||||
return 1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue