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:
Wim Taymans 2000-09-09 16:36:10 +00:00
parent 23540ccc52
commit 552b7f32aa
36 changed files with 361 additions and 99 deletions

View file

@ -51,7 +51,7 @@
</para>
</legalnotice>
<title>GStreamer Application Development Manual</title>
<title><application>GStreamer</application> Application Development Manual</title>
</bookinfo>
@ -60,10 +60,10 @@
<part id="overview"><title>Overview</title>
<partintro>
<para>
The first chapter of the book gives you an overview of GStreamer
design goals. Chapter 2 rapidly covers the basics 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 <application>GStreamer</application>
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+.
For a gentle introduction to GTK+, you may wish to read the <emphasis>GTK+
Tutorial</emphasis> or Eric Harlow's book <emphasis>Developing Linux
@ -84,7 +84,7 @@
<part id="basic-concepts"><title>Basic concepts</title>
<partintro>
<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.
</para>
<para>
@ -111,7 +111,7 @@
<partintro>
<para>
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>
We assume the reader is familiar with GTK+/GNOME programming.
@ -127,15 +127,15 @@
<!-- ############ Advanced GStreamer - part ############# -->
<part id="advanced"><title>Advanced GStreamer concepts</title>
<part id="advanced"><title>Advanced <application>GStreamer</application> concepts</title>
<partintro>
<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
able to create a 'simple' pipeline. If you want more control over
the media types and the pipeline you should use the more
low-level features of GStreamer.
low-level features of <application>GStreamer</application>.
</para>
</partintro>
@ -156,11 +156,11 @@
<!-- ############ 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>
<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
created pipeline by loading the XML file.
</para>
@ -171,12 +171,12 @@
<!-- ############ 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>
<para>
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>
</partintro>
@ -190,7 +190,7 @@
<partintro>
<para>
GStreamer comes prepackaged with a few programs.
<application>GStreamer</application> comes prepackaged with a few programs.
</para>
</partintro>

View file

@ -39,8 +39,6 @@ int main(int argc,char *argv[])
}
gst_init(&amp;argc,&amp;argv);
gst_plugin_load_all();
g_print("\n");
/* create a new bin to hold the elements */
bin = gst_bin_new("bin");
@ -89,6 +87,7 @@ int main(int argc,char *argv[])
gst_element_set_state(bin, GST_STATE_NULL);
gst_object_destroy(GST_OBJECT(audiosink));
gst_object_destroy(GST_OBJECT(parse));
gst_object_destroy(GST_OBJECT(decoder));
gst_object_destroy(GST_OBJECT(disksrc));
gst_object_destroy(GST_OBJECT(bin));
@ -120,16 +119,6 @@ int main(int argc,char *argv[])
</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>
We are going to create 4 elements and one bin. Since all objects are
in fact elements, we can define them as:
@ -318,8 +307,8 @@ void eos(GstSrc *src)
To compile the helloworld example, use:
</para>
<programlisting>
gcc -Wall `gstreamer-config --cflags` `gtk-config --cflags` helloworld.c \
-o helloworld `gstreamer-config --libs` `gtk-config --libs`
gcc -Wall `gstreamer-config --cflags --libs` helloworld.c \
-o helloworld
</programlisting>
<para>
This uses the program gstreamer-config, which comes with GStreamer. This program "knows"

View file

@ -16,7 +16,7 @@
<para>
We will create a second version of the helloworld application using
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>
<programlisting>
@ -25,7 +25,7 @@
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)
{
g_print("have eos, quitting\n");
@ -36,7 +36,7 @@ void eos(GstSrc *src)
int main(int argc,char *argv[])
{
GstElement *disksrc, *audiosink;
GstPipeline *pipeline;
GstElement *pipeline;
if (argc != 2) {
g_print("usage: %s &lt;filename&gt;\n", argv[0]);
@ -44,8 +44,6 @@ int main(int argc,char *argv[])
}
gst_init(&amp;argc,&amp;argv);
gst_plugin_load_all();
g_print("\n");
/* create a new bin to hold the elements */
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), audiosink);
if (!gst_pipeline_autoplug(pipeline)) {
if (!gst_pipeline_autoplug(GST_PIPELINE(pipeline))) {
g_print("unable to handle stream\n");
exit(-1);
}
@ -159,8 +157,8 @@ int main(int argc,char *argv[])
To compile the helloworld2 example, use:
</para>
<programlisting>
gcc -Wall `gstreamer-config --cflags` `gtk-config --cflags` helloworld2.c \
-o helloworld2 `gstreamer-config --libs` `gtk-config --libs`
gcc -Wall `gstreamer-config --cflags --libs` helloworld2.c \
-o helloworld2
</programlisting>
<para>
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.
</para>
<programlisting>
./helloworld2 helloworld.mpeg
./helloworld2 mymovie.mpeg
</programlisting>
</sect1>

View file

@ -3,4 +3,104 @@
<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>

View file

@ -1,6 +1,32 @@
<chapter id="cha-queues">
<title>Queues</title>
<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>
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>

View file

@ -1,6 +1,142 @@
<chapter id="cha-threads">
<title>Threads</title>
<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>
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 &lt;gst/gst.h&gt;
/* 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 &lt;filename&gt;\n", argv[0]);
exit(-1);
}
gst_init(&amp;argc,&amp;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>

View file

@ -37,6 +37,7 @@ int main(int argc,char *argv[]) {
_gst_plugin_spew = TRUE;
gst_init(&argc,&argv);
gst_plugin_load_all();
gst_plugin_load("gstelements");
gnome_init("GST Graph Editor",VERSION,argc,argv);
appwindow = gnome_app_new("gst-editor","GST Graph Editor");

View file

@ -120,7 +120,7 @@ static void gst_editor_set_arg(GtkObject *object,GtkArg *arg,guint id) {
switch (id) {
case ARG_NAME:
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));
break;
default:
@ -135,7 +135,7 @@ static void gst_editor_get_arg(GtkObject *object,GtkArg *arg,guint id) {
switch (id) {
case ARG_NAME:
GTK_VALUE_STRING(*arg) =
gst_element_get_name(GST_OBJECT(editor->pipeline));
gst_element_get_name(GST_ELEMENT(editor->pipeline));
break;
default:
arg->type = GTK_TYPE_INVALID;

View file

@ -56,7 +56,7 @@ struct _GstEditor {
GtkFrame frame;
/* the actual pipeline to be associated with this thing */
GstPipeline *pipeline;
GstElement *pipeline;
/* the editor canvas */
GstEditorCanvas *canvas;

View file

@ -201,6 +201,7 @@ GstElementFactory *element_select_dialog() {
elements = gst_elementfactory_get_list();
while (elements) {
element = (GstElementFactory *)(elements->data);
printf("%s %s\n", element->name, element->details->class);
/* split up the factory's class */
classes = g_strsplit(element->details->class,"/",0);
class = classes;

View file

@ -2,7 +2,7 @@
CC = gcc
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:
rm -f *.o helloworld

View file

@ -2,7 +2,7 @@
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)
{
g_print("have eos, quitting\n");
@ -20,8 +20,6 @@ int main(int argc,char *argv[])
}
gst_init(&argc,&argv);
gst_plugin_load_all();
g_print("\n");
/* create a new bin to hold the elements */
bin = gst_bin_new("bin");
@ -40,6 +38,7 @@ int main(int argc,char *argv[])
/* add objects to the main pipeline */
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), audiosink);
@ -69,6 +68,7 @@ int main(int argc,char *argv[])
gst_element_set_state(bin, GST_STATE_NULL);
gst_object_destroy(GST_OBJECT(audiosink));
gst_object_destroy(GST_OBJECT(parse));
gst_object_destroy(GST_OBJECT(decoder));
gst_object_destroy(GST_OBJECT(disksrc));
gst_object_destroy(GST_OBJECT(bin));

View file

@ -2,7 +2,7 @@
CC = gcc
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:
rm -f *.o helloworld2

View file

@ -2,7 +2,7 @@
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)
{
g_print("have eos, quitting\n");
@ -13,7 +13,7 @@ void eos(GstSrc *src)
int main(int argc,char *argv[])
{
GstElement *disksrc, *audiosink;
GstPipeline *pipeline;
GstElement *pipeline;
if (argc != 2) {
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), audiosink);
if (!gst_pipeline_autoplug(pipeline)) {
if (!gst_pipeline_autoplug(GST_PIPELINE(pipeline))) {
g_print("unable to handle stream\n");
exit(-1);
}

View file

@ -31,7 +31,7 @@ extern "C" {
#endif /* __cplusplus */
GstElementDetails gst_disksrc_details;
extern GstElementDetails gst_disksrc_details;
#define GST_TYPE_DISKSRC \
@ -43,7 +43,7 @@ GstElementDetails gst_disksrc_details;
#define GST_IS_DISKSRC(obj) \
(GTK_CHECK_TYPE((obj),GST_TYPE_DISKSRC))
#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
typedef enum {

View file

@ -70,8 +70,6 @@ GstPlugin *plugin_init(GModule *module) {
GstElementFactory *factory;
int i = 0;
if (gst_plugin_find("gstelements") != NULL) return NULL;
plugin = gst_plugin_new("gstelements");
g_return_val_if_fail(plugin != NULL,NULL);

View file

@ -57,3 +57,13 @@ void gst_init(int *argc,char **argv[]) {
gst_trace_set_default(gst_trace);
}
}
void gst_main() {
gdk_threads_enter();
gtk_main();
gdk_threads_leave();
}
void gst_main_quit() {
gtk_main_quit();
}

View file

@ -50,6 +50,9 @@
/* initialize GST */
void gst_init(int *argc,char **argv[]);
void gst_main();
void gst_main_quit();
/* debugging */
#ifndef DEBUG
#ifdef DEBUG_ENABLED

View file

@ -32,7 +32,7 @@
extern "C" {
#endif /* __cplusplus */
GstElementDetails gst_bin_details;
extern GstElementDetails gst_bin_details;
#define GST_TYPE_BIN \

View file

@ -122,6 +122,7 @@ GstElement *gst_elementfactory_create(GstElementFactory *factory,
// create an instance of the element
element = GST_ELEMENT(gtk_type_new(factory->type));
g_assert(element != NULL);
gst_object_ref(GST_OBJECT(element));
// attempt to set the elemenfactory class pointer if necessary
oclass = GST_ELEMENT_CLASS(GTK_OBJECT(element)->klass);

View file

@ -102,12 +102,12 @@ static void gst_pipeline_init(GstPipeline *pipeline) {
*
* Returns: newly created GstPipeline
*/
GstPipeline *gst_pipeline_new(guchar *name) {
GstElement *gst_pipeline_new(guchar *name) {
GstPipeline *pipeline;
pipeline = gtk_type_new(gst_pipeline_get_type());
gst_element_set_name(GST_ELEMENT(pipeline),name);
return pipeline;
return GST_ELEMENT(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_element_get_pad(typefind,"sink"));
gst_bin_remove(GST_BIN(pipeline), typefind);
gst_object_unref(GST_OBJECT(typefind));
return type_id;
}
@ -223,7 +224,7 @@ end:
gboolean gst_pipeline_autoplug(GstPipeline *pipeline) {
GList *elements;
GstElement *element, *srcelement, *sinkelement;
GstElement *element, *srcelement = NULL, *sinkelement= NULL;
GList *factories;
GstElementFactory *factory;
GList *src_types, *sink_types;

View file

@ -29,7 +29,7 @@
extern "C" {
#endif /* __cplusplus */
GstElementDetails gst_pipeline_details;
extern GstElementDetails gst_pipeline_details;
#define GST_TYPE_PIPELINE \
@ -55,7 +55,7 @@ struct _GstPipelineClass {
};
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))
gboolean gst_pipeline_autoplug(GstPipeline *pipeline);

View file

@ -253,7 +253,7 @@ gboolean gst_plugin_load_absolute(gchar *name) {
return TRUE;
} else if (_gst_plugin_spew) {
// 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;

View file

@ -70,7 +70,7 @@ gst_src_class_init(GstSrcClass *klass) {
gst_src_signals[EOS] =
gtk_signal_new("eos",GTK_RUN_LAST,gtkobject_class->type,
GTK_SIGNAL_OFFSET(GstSrcClass,eos),
gtk_marshal_NONE__POINTER,GTK_TYPE_NONE,1,
gtk_marshal_NONE__NONE,GTK_TYPE_NONE,0,
GST_TYPE_SRC);
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(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]);
}
/**

View file

@ -217,11 +217,17 @@ static GstElementStateReturn gst_thread_change_state(GstElement *element) {
gst_thread_signal_thread(thread);
break;
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_FLAG_UNSET(thread,GST_THREAD_STATE_SPINNING);
gst_thread_signal_thread(thread);
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:
break;
}
@ -253,7 +259,7 @@ void *gst_thread_main_loop(void *arg) {
}
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_element_get_name(GST_ELEMENT(thread)));

View file

@ -30,7 +30,7 @@
extern "C" {
#endif /* __cplusplus */
GstElementDetails gst_thread_details;
extern GstElementDetails gst_thread_details;
typedef enum {

View file

@ -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));
gst_element_set_state(GST_ELEMENT(pipeline),GST_STATE_PAUSED);
// connect to audio pad
//if (0) {
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);
} else if (strncmp(gst_pad_get_name(pad), "video_", 6) == 0) {
//} else if (0) {
gst_element_set_state(GST_ELEMENT(pipeline),GST_STATE_PAUSED);
mpeg1_setup_video_thread(pad, video_render_queue, pipeline);
}
else return;
gst_element_set_state(GST_ELEMENT(pipeline),GST_STATE_PLAYING);
}

View file

@ -23,15 +23,16 @@ void mpeg2_new_pad_created(GstElement *parse,GstPad *pad,GstElement *pipeline)
GstElement *audio_thread;
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
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);
gst_element_set_state(GST_ELEMENT(pipeline),GST_STATE_PLAYING);
return;
}
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("ac3dec");
// 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");
g_return_if_fail(decode != NULL);
} 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_element_get_pad(merge_subtitles,"subtitle"));
gst_element_set_state(GST_ELEMENT(pipeline),GST_STATE_PLAYING);
return;
}
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("mpg123");
// 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);
}
else {
gst_element_set_state(GST_ELEMENT(pipeline),GST_STATE_PLAYING);
return;
}

View file

@ -45,16 +45,16 @@ while test $# -gt 0; do
if test $prefix -ef @builddir@ ; then
includes=-I@builddir@
elif test @includedir@ != /usr/include ; then
includes=-I@includedir@
includes=-I@includedir@
fi
echo $includes
echo $includes `gtk-config --cflags`
;;
--libs)
if test $prefix -ef @builddir@ ; then
echo @builddir@/libgst.la
echo @builddir@/libgst.la `gtk-config --libs`
else
libdirs=-L@libdir@
echo $libdirs -lgst
echo $libdirs -lgst `gtk-config --libs`
fi
;;
*)

View file

@ -31,7 +31,7 @@ extern "C" {
#endif /* __cplusplus */
GstElementDetails gst_disksrc_details;
extern GstElementDetails gst_disksrc_details;
#define GST_TYPE_DISKSRC \
@ -43,7 +43,7 @@ GstElementDetails gst_disksrc_details;
#define GST_IS_DISKSRC(obj) \
(GTK_CHECK_TYPE((obj),GST_TYPE_DISKSRC))
#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
typedef enum {

View file

@ -70,8 +70,6 @@ GstPlugin *plugin_init(GModule *module) {
GstElementFactory *factory;
int i = 0;
if (gst_plugin_find("gstelements") != NULL) return NULL;
plugin = gst_plugin_new("gstelements");
g_return_val_if_fail(plugin != NULL,NULL);

View file

@ -2,7 +2,7 @@
CC = gcc
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:
rm -f *.o helloworld

View file

@ -2,7 +2,7 @@
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)
{
g_print("have eos, quitting\n");
@ -20,8 +20,6 @@ int main(int argc,char *argv[])
}
gst_init(&argc,&argv);
gst_plugin_load_all();
g_print("\n");
/* create a new bin to hold the elements */
bin = gst_bin_new("bin");
@ -40,6 +38,7 @@ int main(int argc,char *argv[])
/* add objects to the main pipeline */
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), audiosink);
@ -69,6 +68,7 @@ int main(int argc,char *argv[])
gst_element_set_state(bin, GST_STATE_NULL);
gst_object_destroy(GST_OBJECT(audiosink));
gst_object_destroy(GST_OBJECT(parse));
gst_object_destroy(GST_OBJECT(decoder));
gst_object_destroy(GST_OBJECT(disksrc));
gst_object_destroy(GST_OBJECT(bin));

View file

@ -2,7 +2,7 @@
CC = gcc
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:
rm -f *.o helloworld2

View file

@ -2,7 +2,7 @@
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)
{
g_print("have eos, quitting\n");
@ -13,7 +13,7 @@ void eos(GstSrc *src)
int main(int argc,char *argv[])
{
GstElement *disksrc, *audiosink;
GstPipeline *pipeline;
GstElement *pipeline;
if (argc != 2) {
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), audiosink);
if (!gst_pipeline_autoplug(pipeline)) {
if (!gst_pipeline_autoplug(GST_PIPELINE(pipeline))) {
g_print("unable to handle stream\n");
exit(-1);
}

View file

@ -66,7 +66,7 @@ void parse(int argc,char *argv[],GstElement *parent,gint offset,gchar endchar) {
// snag the length in advance;
len = strlen(argv[i]);
// 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 (ptr != argv[i]) {
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 t;
GstElement *pipeline;
gst_init(&argc,&argv);
gst_plugin_load_all();
gst_info("\n\n");
pipeline = gst_thread_new("launch");
pipeline = gst_elementfactory_make("thread","launch");
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));
parse(argc,argv,pipeline,1,0);
gst_element_set_state(pipeline,GST_STATE_READY);
gst_element_set_state(pipeline,GST_STATE_PLAYING);
if (t)
sleep(t);
else
sleep(5);
gst_main();
return 1;
return 0;
}