mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-25 19:21:06 +00:00
Added gst_pipeline_add_sink/src to allow multiple sink cases and more complex autoplugging. Update docs too.
Original commit message from CVS: Added gst_pipeline_add_sink/src to allow multiple sink cases and more complex autoplugging. Update docs too. Simplified the pipeline autoplugging code. Changed the cothread case: One iteration is now a push from the src element. The disk source does not change its state anymore on eof. Better type setting for the ac3 parser/decoder and mpeg2parse.
This commit is contained in:
parent
f7bace76aa
commit
cab1728fa5
16 changed files with 217 additions and 79 deletions
|
@ -1328,6 +1328,9 @@ extern GstElementDetails gst_pipeline_details;
|
||||||
<NAME>GstPipeline</NAME>
|
<NAME>GstPipeline</NAME>
|
||||||
struct GstPipeline {
|
struct GstPipeline {
|
||||||
GstBin bin;
|
GstBin bin;
|
||||||
|
|
||||||
|
GstElement *src; // we only allow one src element
|
||||||
|
GList *sinks; // and multiple sinks
|
||||||
};
|
};
|
||||||
</STRUCT>
|
</STRUCT>
|
||||||
<STRUCT>
|
<STRUCT>
|
||||||
|
@ -1356,6 +1359,16 @@ guchar *name
|
||||||
GstPipeline *pipeline
|
GstPipeline *pipeline
|
||||||
</FUNCTION>
|
</FUNCTION>
|
||||||
<FUNCTION>
|
<FUNCTION>
|
||||||
|
<NAME>gst_pipeline_add_src</NAME>
|
||||||
|
<RETURNS>void </RETURNS>
|
||||||
|
GstPipeline *pipeline, GstElement *src
|
||||||
|
</FUNCTION>
|
||||||
|
<FUNCTION>
|
||||||
|
<NAME>gst_pipeline_add_sink</NAME>
|
||||||
|
<RETURNS>void </RETURNS>
|
||||||
|
GstPipeline *pipeline, GstElement *sink
|
||||||
|
</FUNCTION>
|
||||||
|
<FUNCTION>
|
||||||
<NAME>gst_pipeline_iterate</NAME>
|
<NAME>gst_pipeline_iterate</NAME>
|
||||||
<RETURNS>void </RETURNS>
|
<RETURNS>void </RETURNS>
|
||||||
GstPipeline *pipeline
|
GstPipeline *pipeline
|
||||||
|
@ -2067,6 +2080,36 @@ GstBufferPool *pool
|
||||||
|
|
||||||
</FUNCTION>
|
</FUNCTION>
|
||||||
<MACRO>
|
<MACRO>
|
||||||
|
<NAME>GET_SP</NAME>
|
||||||
|
#define GET_SP(target) \
|
||||||
|
__asm__("movl %%esp, %0" : "=m"(target) : : "esp", "ebp");
|
||||||
|
</MACRO>
|
||||||
|
<MACRO>
|
||||||
|
<NAME>SET_SP</NAME>
|
||||||
|
#define SET_SP(source) \
|
||||||
|
__asm__("movl %0, %%esp\n" : "=m"(thread->sp));
|
||||||
|
</MACRO>
|
||||||
|
<MACRO>
|
||||||
|
<NAME>JUMP</NAME>
|
||||||
|
#define JUMP(target) \
|
||||||
|
__asm__("jmp " SYMBOL_NAME_STR(cothread_stub))
|
||||||
|
</MACRO>
|
||||||
|
<MACRO>
|
||||||
|
<NAME>GET_SP</NAME>
|
||||||
|
#define GET_SP(target) \
|
||||||
|
__asm__("stw 1,%0" : "=m"(target) : : "r1");
|
||||||
|
</MACRO>
|
||||||
|
<MACRO>
|
||||||
|
<NAME>SET_SP</NAME>
|
||||||
|
#define SET_SP(source) \
|
||||||
|
__asm__("lwz 1,%0" : "=m"(source))
|
||||||
|
</MACRO>
|
||||||
|
<MACRO>
|
||||||
|
<NAME>JUMP</NAME>
|
||||||
|
#define JUMP(target) \
|
||||||
|
__asm__("b " SYMBOL_NAME_STR(cothread_stub))
|
||||||
|
</MACRO>
|
||||||
|
<MACRO>
|
||||||
<NAME>GST_TYPE_ASYNCDISKSRC</NAME>
|
<NAME>GST_TYPE_ASYNCDISKSRC</NAME>
|
||||||
#define GST_TYPE_ASYNCDISKSRC \
|
#define GST_TYPE_ASYNCDISKSRC \
|
||||||
(gst_asyncdisksrc_get_type())
|
(gst_asyncdisksrc_get_type())
|
||||||
|
|
|
@ -16,6 +16,9 @@ cothread_setfunc
|
||||||
cothread_switch
|
cothread_switch
|
||||||
cothread_main
|
cothread_main
|
||||||
<SUBSECTION Standard>
|
<SUBSECTION Standard>
|
||||||
|
GET_SP
|
||||||
|
JUMP
|
||||||
|
SET_SP
|
||||||
</SECTION>
|
</SECTION>
|
||||||
|
|
||||||
<SECTION>
|
<SECTION>
|
||||||
|
@ -297,6 +300,8 @@ gst_pad_get_type
|
||||||
<TITLE>GstPipeline</TITLE>
|
<TITLE>GstPipeline</TITLE>
|
||||||
GstPipeline
|
GstPipeline
|
||||||
gst_pipeline_new
|
gst_pipeline_new
|
||||||
|
gst_pipeline_add_sink
|
||||||
|
gst_pipeline_add_src
|
||||||
gst_pipeline_autoplug
|
gst_pipeline_autoplug
|
||||||
gst_pipeline_destroy
|
gst_pipeline_destroy
|
||||||
gst_pipeline_iterate
|
gst_pipeline_iterate
|
||||||
|
|
|
@ -36,6 +36,24 @@ pipeline figure out what plugins to use.</para>
|
||||||
@Returns:
|
@Returns:
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ##### FUNCTION gst_pipeline_add_sink ##### -->
|
||||||
|
<para>
|
||||||
|
|
||||||
|
</para>
|
||||||
|
|
||||||
|
@pipeline:
|
||||||
|
@sink:
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ##### FUNCTION gst_pipeline_add_src ##### -->
|
||||||
|
<para>
|
||||||
|
|
||||||
|
</para>
|
||||||
|
|
||||||
|
@pipeline:
|
||||||
|
@src:
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### FUNCTION gst_pipeline_autoplug ##### -->
|
<!-- ##### FUNCTION gst_pipeline_autoplug ##### -->
|
||||||
<para>
|
<para>
|
||||||
|
|
||||||
|
|
|
@ -58,8 +58,8 @@ int main(int argc,char *argv[])
|
||||||
audiosink = gst_elementfactory_make("audiosink", "play_audio");
|
audiosink = gst_elementfactory_make("audiosink", "play_audio");
|
||||||
|
|
||||||
/* add objects to the main pipeline */
|
/* add objects to the main pipeline */
|
||||||
gst_bin_add(GST_BIN(pipeline), disksrc);
|
gst_pipeline_add_src(GST_PIPELINE(pipeline), disksrc);
|
||||||
gst_bin_add(GST_BIN(pipeline), audiosink);
|
gst_pipeline_add_sink(GST_PIPELINE(pipeline), audiosink);
|
||||||
|
|
||||||
if (!gst_pipeline_autoplug(GST_PIPELINE(pipeline))) {
|
if (!gst_pipeline_autoplug(GST_PIPELINE(pipeline))) {
|
||||||
g_print("unable to handle stream\n");
|
g_print("unable to handle stream\n");
|
||||||
|
@ -118,7 +118,7 @@ int main(int argc,char *argv[])
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
The source and the sink elements will be found inside the pipeline
|
The pipeline will try to connect the src and the sink element.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
|
|
|
@ -38,8 +38,8 @@ int main(int argc,char *argv[])
|
||||||
g_assert(audiosink != NULL);
|
g_assert(audiosink != NULL);
|
||||||
|
|
||||||
/* add objects to the main pipeline */
|
/* add objects to the main pipeline */
|
||||||
gst_bin_add(GST_BIN(pipeline), disksrc);
|
gst_pipeline_add_src(GST_PIPELINE(pipeline), disksrc);
|
||||||
gst_bin_add(GST_BIN(pipeline), audiosink);
|
gst_pipeline_add_sink(GST_PIPELINE(pipeline), audiosink);
|
||||||
|
|
||||||
if (!gst_pipeline_autoplug(GST_PIPELINE(pipeline))) {
|
if (!gst_pipeline_autoplug(GST_PIPELINE(pipeline))) {
|
||||||
g_print("unable to handle stream\n");
|
g_print("unable to handle stream\n");
|
||||||
|
|
|
@ -45,8 +45,8 @@ int main(int argc,char *argv[])
|
||||||
g_assert(audiosink != NULL);
|
g_assert(audiosink != NULL);
|
||||||
|
|
||||||
/* add objects to the main pipeline */
|
/* add objects to the main pipeline */
|
||||||
gst_bin_add(GST_BIN(pipeline), disksrc);
|
gst_pipeline_add_src(GST_PIPELINE(pipeline), disksrc);
|
||||||
gst_bin_add(GST_BIN(pipeline), audiosink);
|
gst_pipeline_add_sink(GST_PIPELINE(pipeline), audiosink);
|
||||||
|
|
||||||
if (!gst_pipeline_autoplug(GST_PIPELINE(pipeline))) {
|
if (!gst_pipeline_autoplug(GST_PIPELINE(pipeline))) {
|
||||||
g_print("unable to handle stream\n");
|
g_print("unable to handle stream\n");
|
||||||
|
|
|
@ -55,9 +55,6 @@ libgstinclude_HEADERS = \
|
||||||
gstbufferpool.h \
|
gstbufferpool.h \
|
||||||
gstclock.h \
|
gstclock.h \
|
||||||
gstcpu.h \
|
gstcpu.h \
|
||||||
gstarch.h \
|
|
||||||
gsti386.h \
|
|
||||||
gstppc.h \
|
|
||||||
gstelement.h \
|
gstelement.h \
|
||||||
gstbin.h \
|
gstbin.h \
|
||||||
gstpipeline.h \
|
gstpipeline.h \
|
||||||
|
@ -75,6 +72,11 @@ libgstinclude_HEADERS = \
|
||||||
gstxml.h \
|
gstxml.h \
|
||||||
cothreads.h
|
cothreads.h
|
||||||
|
|
||||||
|
noinst_HEADERS = \
|
||||||
|
gstarch.h \
|
||||||
|
gsti386.h \
|
||||||
|
gstppc.h
|
||||||
|
|
||||||
CFLAGS += -O2 -Wall
|
CFLAGS += -O2 -Wall
|
||||||
|
|
||||||
libgst_la_LIBADD = $(GLIB_LIBS) $(GTK_LIBS) $(XML_LIBS)
|
libgst_la_LIBADD = $(GLIB_LIBS) $(GTK_LIBS) $(XML_LIBS)
|
||||||
|
|
|
@ -124,10 +124,12 @@ void cothread_switch(cothread_state *thread) {
|
||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
if (current == thread) {
|
if (current == thread) {
|
||||||
g_print("cothread: trying to switch to same thread, legal but not necessary\n");
|
g_print("cothread: trying to switch to same thread, legal but not necessary\n");
|
||||||
return;
|
//return;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// find the number of the thread to switch to
|
// find the number of the thread to switch to
|
||||||
ctx->current = thread->threadnum;
|
ctx->current = thread->threadnum;
|
||||||
|
@ -150,10 +152,10 @@ void cothread_switch(cothread_state *thread) {
|
||||||
// switch to it
|
// switch to it
|
||||||
longjmp(thread->jmp,1);
|
longjmp(thread->jmp,1);
|
||||||
} else {
|
} else {
|
||||||
DEBUG("cothread: exit thread \n");
|
|
||||||
SET_SP(thread->sp);
|
SET_SP(thread->sp);
|
||||||
// start it
|
// start it
|
||||||
//JUMP(cothread_stub);
|
//JUMP(cothread_stub);
|
||||||
cothread_stub();
|
cothread_stub();
|
||||||
|
DEBUG("cothread: exit thread \n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -221,7 +221,6 @@ void gst_disksrc_push(GstSrc *src) {
|
||||||
else if (readbytes == 0) {
|
else if (readbytes == 0) {
|
||||||
gst_src_signal_eos(GST_SRC(disksrc));
|
gst_src_signal_eos(GST_SRC(disksrc));
|
||||||
gst_buffer_unref(buf);
|
gst_buffer_unref(buf);
|
||||||
GST_STATE(src) = GST_STATE_PAUSED;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -441,10 +441,9 @@ static int gst_bin_loopfunc_wrapper(int argc,char *argv[]) {
|
||||||
DEBUG("** gst_bin_loopfunc_wrapper(): element is chain-based, calling in infinite loop\n");
|
DEBUG("** gst_bin_loopfunc_wrapper(): element is chain-based, calling in infinite loop\n");
|
||||||
if (GST_IS_SRC(element)) {
|
if (GST_IS_SRC(element)) {
|
||||||
//while (1) {
|
//while (1) {
|
||||||
while (GST_STATE(element) == GST_STATE_PLAYING) {
|
|
||||||
DEBUG("** gst_bin_loopfunc_wrapper(): calling push function of source\n");
|
DEBUG("** gst_bin_loopfunc_wrapper(): calling push function of source\n");
|
||||||
gst_src_push(GST_SRC(element));
|
gst_src_push(GST_SRC(element));
|
||||||
}
|
//}
|
||||||
} else {
|
} else {
|
||||||
while (1) {
|
while (1) {
|
||||||
pads = element->pads;
|
pads = element->pads;
|
||||||
|
@ -625,8 +624,8 @@ void gst_bin_iterate_func(GstBin *bin) {
|
||||||
if (bin->need_cothreads) {
|
if (bin->need_cothreads) {
|
||||||
// all we really have to do is switch to the first child
|
// all we really have to do is switch to the first child
|
||||||
// FIXME this should be lots more intelligent about where to start
|
// FIXME this should be lots more intelligent about where to start
|
||||||
//g_print("** in gst_bin_iterate_func()==================================%s\n",
|
DEBUG("** in gst_bin_iterate_func()==================================%s\n",
|
||||||
// gst_element_get_name(GST_ELEMENT(bin->children->data)));
|
gst_element_get_name(GST_ELEMENT(bin->children->data)));
|
||||||
cothread_switch(GST_ELEMENT(bin->children->data)->threadstate);
|
cothread_switch(GST_ELEMENT(bin->children->data)->threadstate);
|
||||||
} else {
|
} else {
|
||||||
entries = bin->entries;
|
entries = bin->entries;
|
||||||
|
|
|
@ -91,6 +91,8 @@ gst_pipeline_class_init(GstPipelineClass *klass) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gst_pipeline_init(GstPipeline *pipeline) {
|
static void gst_pipeline_init(GstPipeline *pipeline) {
|
||||||
|
pipeline->src = NULL;
|
||||||
|
pipeline->sinks = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -111,7 +113,8 @@ GstElement *gst_pipeline_new(guchar *name) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gst_pipeline_prepare(GstPipeline *pipeline) {
|
static void gst_pipeline_prepare(GstPipeline *pipeline) {
|
||||||
g_print("GstPipeline: preparing pipeline \"%s\" for playing\n", gst_element_get_name(GST_ELEMENT(pipeline)));
|
g_print("GstPipeline: preparing pipeline \"%s\" for playing\n",
|
||||||
|
gst_element_get_name(GST_ELEMENT(pipeline)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gst_pipeline_have_type(GstSink *sink, GstSink *sink2, gpointer data) {
|
static void gst_pipeline_have_type(GstSink *sink, GstSink *sink2, gpointer data) {
|
||||||
|
@ -125,7 +128,8 @@ static guint16 gst_pipeline_typefind(GstPipeline *pipeline, GstElement *element)
|
||||||
GstElement *typefind;
|
GstElement *typefind;
|
||||||
guint16 type_id = 0;
|
guint16 type_id = 0;
|
||||||
|
|
||||||
g_print("GstPipeline: typefind for element \"%s\" %p\n", gst_element_get_name(element), &found);
|
g_print("GstPipeline: typefind for element \"%s\" %p\n",
|
||||||
|
gst_element_get_name(element), &found);
|
||||||
|
|
||||||
typefind = gst_elementfactory_make("typefind","typefind");
|
typefind = gst_elementfactory_make("typefind","typefind");
|
||||||
g_return_val_if_fail(typefind != NULL, FALSE);
|
g_return_val_if_fail(typefind != NULL, FALSE);
|
||||||
|
@ -142,6 +146,7 @@ static guint16 gst_pipeline_typefind(GstPipeline *pipeline, GstElement *element)
|
||||||
gst_element_set_state(GST_ELEMENT(element),GST_STATE_READY);
|
gst_element_set_state(GST_ELEMENT(element),GST_STATE_READY);
|
||||||
gst_element_set_state(GST_ELEMENT(element),GST_STATE_PLAYING);
|
gst_element_set_state(GST_ELEMENT(element),GST_STATE_PLAYING);
|
||||||
|
|
||||||
|
// keep pushing buffers... the have_type signal handler will set the found flag
|
||||||
while (!found) {
|
while (!found) {
|
||||||
gst_src_push(GST_SRC(element));
|
gst_src_push(GST_SRC(element));
|
||||||
}
|
}
|
||||||
|
@ -150,9 +155,8 @@ static guint16 gst_pipeline_typefind(GstPipeline *pipeline, GstElement *element)
|
||||||
|
|
||||||
if (found) {
|
if (found) {
|
||||||
type_id = gst_util_get_int_arg(GTK_OBJECT(typefind),"type");
|
type_id = gst_util_get_int_arg(GTK_OBJECT(typefind),"type");
|
||||||
}
|
|
||||||
|
|
||||||
gst_pad_set_type_id(gst_element_get_pad(element, "src"), type_id);
|
gst_pad_set_type_id(gst_element_get_pad(element, "src"), type_id);
|
||||||
|
}
|
||||||
|
|
||||||
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"));
|
||||||
|
@ -165,6 +169,7 @@ static guint16 gst_pipeline_typefind(GstPipeline *pipeline, GstElement *element)
|
||||||
static void gst_pipeline_pads_autoplug_func(GstElement *src, GstPad *pad, GstElement *sink) {
|
static void gst_pipeline_pads_autoplug_func(GstElement *src, GstPad *pad, GstElement *sink) {
|
||||||
GList *sinkpads;
|
GList *sinkpads;
|
||||||
GstPad *sinkpad;
|
GstPad *sinkpad;
|
||||||
|
gboolean connected = FALSE;
|
||||||
|
|
||||||
g_print("gstpipeline: autoplug pad connect function type %d\n", pad->type);
|
g_print("gstpipeline: autoplug pad connect function type %d\n", pad->type);
|
||||||
|
|
||||||
|
@ -173,14 +178,24 @@ static void gst_pipeline_pads_autoplug_func(GstElement *src, GstPad *pad, GstEle
|
||||||
sinkpad = (GstPad *)sinkpads->data;
|
sinkpad = (GstPad *)sinkpads->data;
|
||||||
|
|
||||||
// if we have a match, connect the pads
|
// if we have a match, connect the pads
|
||||||
if (sinkpad->type == pad->type && sinkpad->direction == GST_PAD_SINK && !GST_PAD_CONNECTED(sinkpad)) {
|
if (sinkpad->type == pad->type &&
|
||||||
|
sinkpad->direction == GST_PAD_SINK &&
|
||||||
|
!GST_PAD_CONNECTED(sinkpad))
|
||||||
|
{
|
||||||
gst_pad_connect(pad, sinkpad);
|
gst_pad_connect(pad, sinkpad);
|
||||||
g_print("gstpipeline: autoconnect pad \"%s\" (%d) in element %s <-> ", pad->name, pad->type, gst_element_get_name(src));
|
g_print("gstpipeline: autoconnect pad \"%s\" (%d) in element %s <-> ", pad->name,
|
||||||
g_print("pad \"%s\" (%d) in element %s\n", sinkpad->name, sinkpad->type, gst_element_get_name(sink));
|
pad->type, gst_element_get_name(src));
|
||||||
|
g_print("pad \"%s\" (%d) in element %s\n", sinkpad->name, sinkpad->type,
|
||||||
|
gst_element_get_name(sink));
|
||||||
|
connected = TRUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
sinkpads = g_list_next(sinkpads);
|
sinkpads = g_list_next(sinkpads);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!connected) {
|
||||||
|
g_print("gstpipeline: no path to sinks for type %d\n", pad->type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gst_pipeline_pads_autoplug(GstElement *src, GstElement *sink) {
|
static void gst_pipeline_pads_autoplug(GstElement *src, GstElement *sink) {
|
||||||
|
@ -201,10 +216,14 @@ static void gst_pipeline_pads_autoplug(GstElement *src, GstElement *sink) {
|
||||||
sinkpad = (GstPad *)sinkpads->data;
|
sinkpad = (GstPad *)sinkpads->data;
|
||||||
|
|
||||||
// if we have a match, connect the pads
|
// if we have a match, connect the pads
|
||||||
if (sinkpad->type == srcpad->type && sinkpad->direction == GST_PAD_SINK && !GST_PAD_CONNECTED(sinkpad)) {
|
if (sinkpad->type == srcpad->type &&
|
||||||
|
sinkpad->direction == GST_PAD_SINK &&
|
||||||
|
!GST_PAD_CONNECTED(sinkpad)) {
|
||||||
gst_pad_connect(srcpad, sinkpad);
|
gst_pad_connect(srcpad, sinkpad);
|
||||||
g_print("gstpipeline: autoconnect pad \"%s\" (%d) in element %s <-> ", srcpad->name, srcpad->type, gst_element_get_name(src));
|
g_print("gstpipeline: autoconnect pad \"%s\" (%d) in element %s <-> ",
|
||||||
g_print("pad \"%s\" (%d) in element %s\n", sinkpad->name, sinkpad->type, gst_element_get_name(sink));
|
srcpad->name, srcpad->type, gst_element_get_name(src));
|
||||||
|
g_print("pad \"%s\" (%d) in element %s\n", sinkpad->name,
|
||||||
|
sinkpad->type, gst_element_get_name(sink));
|
||||||
connected = TRUE;
|
connected = TRUE;
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
@ -222,6 +241,51 @@ end:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_pipeline_add_src:
|
||||||
|
* @pipeline: the pipeline to add the src to
|
||||||
|
* @src: the src to add to the pipeline
|
||||||
|
*
|
||||||
|
* Adds a src element to the pipeline. This element
|
||||||
|
* will be used as a src for autoplugging. If you add more
|
||||||
|
* than one src element, the previously added element will
|
||||||
|
* be removed.
|
||||||
|
*/
|
||||||
|
void gst_pipeline_add_src(GstPipeline *pipeline, GstElement *src)
|
||||||
|
{
|
||||||
|
g_return_if_fail(pipeline != NULL);
|
||||||
|
g_return_if_fail(GST_IS_PIPELINE(pipeline));
|
||||||
|
g_return_if_fail(src != NULL);
|
||||||
|
g_return_if_fail(GST_IS_ELEMENT(src));
|
||||||
|
|
||||||
|
if (pipeline->src) {
|
||||||
|
printf("gstpipeline: *WARNING* removing previously added element \"%s\"\n",
|
||||||
|
gst_element_get_name(pipeline->src));
|
||||||
|
gst_bin_remove(GST_BIN(pipeline), pipeline->src);
|
||||||
|
}
|
||||||
|
pipeline->src = src;
|
||||||
|
gst_bin_add(GST_BIN(pipeline), src);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_pipeline_add_sink:
|
||||||
|
* @pipeline: the pipeline to add the sink to
|
||||||
|
* @sink: the sink to add to the pipeline
|
||||||
|
*
|
||||||
|
* Adds a sink element to the pipeline. This element
|
||||||
|
* will be used as a sink for autoplugging
|
||||||
|
*/
|
||||||
|
void gst_pipeline_add_sink(GstPipeline *pipeline, GstElement *sink)
|
||||||
|
{
|
||||||
|
g_return_if_fail(pipeline != NULL);
|
||||||
|
g_return_if_fail(GST_IS_PIPELINE(pipeline));
|
||||||
|
g_return_if_fail(sink != NULL);
|
||||||
|
g_return_if_fail(GST_IS_ELEMENT(sink));
|
||||||
|
|
||||||
|
pipeline->sinks = g_list_prepend(pipeline->sinks, sink);
|
||||||
|
gst_bin_add(GST_BIN(pipeline), sink);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_pipeline_autoplug:
|
* gst_pipeline_autoplug:
|
||||||
* @pipeline: the pipeline to autoplug
|
* @pipeline: the pipeline to autoplug
|
||||||
|
@ -240,71 +304,71 @@ gboolean gst_pipeline_autoplug(GstPipeline *pipeline) {
|
||||||
guint16 src_type = 0, sink_type = 0;
|
guint16 src_type = 0, sink_type = 0;
|
||||||
gboolean complete = FALSE;
|
gboolean complete = FALSE;
|
||||||
|
|
||||||
|
g_return_val_if_fail(pipeline != NULL, FALSE);
|
||||||
g_return_val_if_fail(GST_IS_PIPELINE(pipeline), FALSE);
|
g_return_val_if_fail(GST_IS_PIPELINE(pipeline), FALSE);
|
||||||
|
|
||||||
g_print("GstPipeline: autopluging pipeline \"%s\"\n", gst_element_get_name(GST_ELEMENT(pipeline)));
|
g_print("GstPipeline: autopluging pipeline \"%s\"\n",
|
||||||
|
gst_element_get_name(GST_ELEMENT(pipeline)));
|
||||||
|
|
||||||
elements = gst_bin_get_list(GST_BIN(pipeline));
|
|
||||||
|
|
||||||
// fase 1, find all the sinks and sources... FIXME need better way to do this...
|
// fase 1, run typedetect on the source if needed...
|
||||||
|
if (!pipeline->src) {
|
||||||
|
g_print("GstPipeline: no source detected, can't autoplug pipeline \"%s\"\n",
|
||||||
|
gst_element_get_name(GST_ELEMENT(pipeline)));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
factory = gst_element_get_factory(pipeline->src);
|
||||||
|
|
||||||
|
src_types = factory->src_types;
|
||||||
|
if (src_types == NULL) {
|
||||||
|
g_print("GstPipeline: source \"%s\" has no MIME type, running typefind...\n",
|
||||||
|
gst_element_get_name(pipeline->src));
|
||||||
|
|
||||||
|
src_type = gst_pipeline_typefind(pipeline, pipeline->src);
|
||||||
|
|
||||||
|
if (src_type) {
|
||||||
|
g_print("GstPipeline: source \"%s\" type found %d\n", gst_element_get_name(pipeline->src),
|
||||||
|
src_type);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
g_print("GstPipeline: source \"%s\" has no type\n", gst_element_get_name(pipeline->src));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
while (src_types) {
|
||||||
|
// FIXME loop over types and find paths...
|
||||||
|
src_types = g_list_next(src_types);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
srcelement = pipeline->src;
|
||||||
|
|
||||||
|
elements = pipeline->sinks;
|
||||||
|
|
||||||
|
// fase 2, find all the sinks..
|
||||||
while (elements) {
|
while (elements) {
|
||||||
element = GST_ELEMENT(elements->data);
|
element = GST_ELEMENT(elements->data);
|
||||||
|
|
||||||
if (GST_IS_SINK(element)) {
|
if (GST_IS_SINK(element)) {
|
||||||
g_print("GstPipeline: found sink \"%s\"\n", gst_element_get_name(element));
|
g_print("GstPipeline: found sink \"%s\"\n", gst_element_get_name(element));
|
||||||
|
|
||||||
if (sink_type) {
|
|
||||||
g_print("GstPipeline: multiple sinks detected, can't autoplug pipeline \"%s\"\n", gst_element_get_name(GST_ELEMENT(pipeline)));
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
sinkelement = element;
|
sinkelement = element;
|
||||||
factory = gst_element_get_factory(element);
|
factory = gst_element_get_factory(element);
|
||||||
|
|
||||||
sink_types = factory->sink_types;
|
sink_types = factory->sink_types;
|
||||||
if (sink_types == NULL) {
|
if (sink_types == NULL) {
|
||||||
g_print("GstPipeline: sink \"%s\" has no MIME type, can't autoplug \n", gst_element_get_name(element));
|
g_print("GstPipeline: sink \"%s\" has no MIME type, can't autoplug \n",
|
||||||
|
gst_element_get_name(element));
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
sink_type = GPOINTER_TO_UINT(sink_types->data);
|
sink_type = GPOINTER_TO_UINT(sink_types->data);
|
||||||
g_print("GstPipeline: sink \"%s\" has MIME type %d \n", gst_element_get_name(element), sink_type);
|
g_print("GstPipeline: sink \"%s\" has MIME type %d \n",
|
||||||
|
gst_element_get_name(element), sink_type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (GST_IS_SRC(element)) {
|
|
||||||
g_print("GstPipeline: found source \"%s\"\n", gst_element_get_name(element));
|
|
||||||
|
|
||||||
if (src_type) {
|
|
||||||
g_print("GstPipeline: multiple sources detected, can't autoplug pipeline \"%s\"\n", gst_element_get_name(GST_ELEMENT(pipeline)));
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
srcelement = element;
|
|
||||||
|
|
||||||
factory = gst_element_get_factory(element);
|
|
||||||
|
|
||||||
src_types = factory->src_types;
|
|
||||||
if (src_types == NULL) {
|
|
||||||
g_print("GstPipeline: source \"%s\" has no MIME type, running typefind...\n", gst_element_get_name(element));
|
|
||||||
|
|
||||||
src_type = gst_pipeline_typefind(pipeline, element);
|
|
||||||
|
|
||||||
if (src_type) {
|
|
||||||
g_print("GstPipeline: source \"%s\" type found %d\n", gst_element_get_name(element), src_type);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
g_print("GstPipeline: source \"%s\" has no type\n", gst_element_get_name(element));
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
while (src_types) {
|
|
||||||
src_types = g_list_next(src_types);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
g_print("GstPipeline: found invalid element \"%s\", not source or sink\n", gst_element_get_name(element));
|
|
||||||
}
|
|
||||||
|
|
||||||
elements = g_list_next(elements);
|
elements = g_list_next(elements);
|
||||||
}
|
}
|
||||||
|
@ -312,7 +376,7 @@ gboolean gst_pipeline_autoplug(GstPipeline *pipeline) {
|
||||||
factories = gst_type_get_sink_to_src(src_type, sink_type);
|
factories = gst_type_get_sink_to_src(src_type, sink_type);
|
||||||
|
|
||||||
while (factories) {
|
while (factories) {
|
||||||
// fase 2: find elements to form a pad
|
// fase 3: find elements to form a pad
|
||||||
|
|
||||||
factory = (GstElementFactory *)(factories->data);
|
factory = (GstElementFactory *)(factories->data);
|
||||||
|
|
||||||
|
@ -335,7 +399,8 @@ gboolean gst_pipeline_autoplug(GstPipeline *pipeline) {
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_print("GstPipeline: unable to autoplug pipeline \"%s\"\n", gst_element_get_name(GST_ELEMENT(pipeline)));
|
g_print("GstPipeline: unable to autoplug pipeline \"%s\"\n",
|
||||||
|
gst_element_get_name(GST_ELEMENT(pipeline)));
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,9 @@ typedef struct _GstPipelineClass GstPipelineClass;
|
||||||
|
|
||||||
struct _GstPipeline {
|
struct _GstPipeline {
|
||||||
GstBin bin;
|
GstBin bin;
|
||||||
|
|
||||||
|
GstElement *src; // we only allow one src element
|
||||||
|
GList *sinks; // and multiple sinks
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstPipelineClass {
|
struct _GstPipelineClass {
|
||||||
|
@ -60,6 +63,9 @@ GstElement *gst_pipeline_new(guchar *name);
|
||||||
|
|
||||||
gboolean gst_pipeline_autoplug(GstPipeline *pipeline);
|
gboolean gst_pipeline_autoplug(GstPipeline *pipeline);
|
||||||
|
|
||||||
|
void gst_pipeline_add_src(GstPipeline *pipeline, GstElement *src);
|
||||||
|
void gst_pipeline_add_sink(GstPipeline *pipeline, GstElement *sink);
|
||||||
|
|
||||||
void gst_pipeline_iterate(GstPipeline *pipeline);
|
void gst_pipeline_iterate(GstPipeline *pipeline);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -184,7 +184,7 @@ void gst_getbits_init(gst_getbits_t *gb, GstGetbitsCallback callback, void *data
|
||||||
gb->showbits = _gst_showbits_i386;
|
gb->showbits = _gst_showbits_i386;
|
||||||
gb->flushbits = _gst_flushbits_i386;
|
gb->flushbits = _gst_flushbits_i386;
|
||||||
gb->backbits = _gst_getbits_back_i386;
|
gb->backbits = _gst_getbits_back_i386;
|
||||||
printf("gstgetbits: using intel optimized versions\n");
|
printf("gstgetbits: using i386 optimized versions\n");
|
||||||
#else
|
#else
|
||||||
gb->get1bit = _gst_get1bit_int;
|
gb->get1bit = _gst_get1bit_int;
|
||||||
gb->getbits = _gst_getbits_int;
|
gb->getbits = _gst_getbits_int;
|
||||||
|
|
|
@ -221,7 +221,6 @@ void gst_disksrc_push(GstSrc *src) {
|
||||||
else if (readbytes == 0) {
|
else if (readbytes == 0) {
|
||||||
gst_src_signal_eos(GST_SRC(disksrc));
|
gst_src_signal_eos(GST_SRC(disksrc));
|
||||||
gst_buffer_unref(buf);
|
gst_buffer_unref(buf);
|
||||||
GST_STATE(src) = GST_STATE_PAUSED;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,8 +38,8 @@ int main(int argc,char *argv[])
|
||||||
g_assert(audiosink != NULL);
|
g_assert(audiosink != NULL);
|
||||||
|
|
||||||
/* add objects to the main pipeline */
|
/* add objects to the main pipeline */
|
||||||
gst_bin_add(GST_BIN(pipeline), disksrc);
|
gst_pipeline_add_src(GST_PIPELINE(pipeline), disksrc);
|
||||||
gst_bin_add(GST_BIN(pipeline), audiosink);
|
gst_pipeline_add_sink(GST_PIPELINE(pipeline), audiosink);
|
||||||
|
|
||||||
if (!gst_pipeline_autoplug(GST_PIPELINE(pipeline))) {
|
if (!gst_pipeline_autoplug(GST_PIPELINE(pipeline))) {
|
||||||
g_print("unable to handle stream\n");
|
g_print("unable to handle stream\n");
|
||||||
|
|
|
@ -45,8 +45,8 @@ int main(int argc,char *argv[])
|
||||||
g_assert(audiosink != NULL);
|
g_assert(audiosink != NULL);
|
||||||
|
|
||||||
/* add objects to the main pipeline */
|
/* add objects to the main pipeline */
|
||||||
gst_bin_add(GST_BIN(pipeline), disksrc);
|
gst_pipeline_add_src(GST_PIPELINE(pipeline), disksrc);
|
||||||
gst_bin_add(GST_BIN(pipeline), audiosink);
|
gst_pipeline_add_sink(GST_PIPELINE(pipeline), audiosink);
|
||||||
|
|
||||||
if (!gst_pipeline_autoplug(GST_PIPELINE(pipeline))) {
|
if (!gst_pipeline_autoplug(GST_PIPELINE(pipeline))) {
|
||||||
g_print("unable to handle stream\n");
|
g_print("unable to handle stream\n");
|
||||||
|
|
Loading…
Reference in a new issue