forked from enlightenment/efl
parent
4ecb2fccad
commit
df2d739a35
|
@ -508,3 +508,68 @@
|
||||||
* Shows how to use fd handlers.
|
* Shows how to use fd handlers.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @page tutorial_ecore_pipe_gstreamer_example
|
||||||
|
*
|
||||||
|
* Here is an example that uses the pipe wrapper with a Gstreamer
|
||||||
|
* pipeline. For each decoded frame in the Gstreamer thread, a handle
|
||||||
|
* is called in the ecore thread.
|
||||||
|
*
|
||||||
|
* @include ecore_pipe_gstreamer_example.c
|
||||||
|
* @example ecore_pipe_gstreamer_example.c
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @page tutorial_ecore_pipe_simple_example
|
||||||
|
* @dontinclude ecore_pipe_simple_example.c
|
||||||
|
*
|
||||||
|
* This example shows some simple usage of ecore_pipe. We are going to create a
|
||||||
|
* pipe, fork our process, and then the child is going to comunicate to the
|
||||||
|
* parent the result of its processing through the pipe.
|
||||||
|
*
|
||||||
|
* As always we start with our includes, nothing especial:
|
||||||
|
* @skip #include
|
||||||
|
* @until Ecore.h
|
||||||
|
*
|
||||||
|
* The first thing we are going to define in our example is the function we are
|
||||||
|
* going to run on the child process, which, as mentioned, will do some
|
||||||
|
* processing and then will write the result to the pipe:
|
||||||
|
* @until }
|
||||||
|
* @until }
|
||||||
|
* @note The sleep was added so the parent process would think the child process
|
||||||
|
* was doing something interesting...
|
||||||
|
*
|
||||||
|
* Next up is our function for handling data arriving in the pipe. It copies the
|
||||||
|
* data to another buffer, adds a terminating NULL and prints it. Also if it
|
||||||
|
* receives a certain string it stops the main loop(efectvely ending the
|
||||||
|
* program):
|
||||||
|
* @until }
|
||||||
|
* @until }
|
||||||
|
*
|
||||||
|
* And now on to our main function, we start by declaring some variables and
|
||||||
|
* initializing ecore:
|
||||||
|
* @until ecore_init
|
||||||
|
*
|
||||||
|
* And since we are talking about pipes let's create one:
|
||||||
|
* @until pipe_add
|
||||||
|
*
|
||||||
|
* Now we are going to fork:
|
||||||
|
* @until fork
|
||||||
|
* @note duh...
|
||||||
|
*
|
||||||
|
* The child process is going to do the our fancy processing:
|
||||||
|
* @until }
|
||||||
|
* @note It's very important to call ecore_pipe_read_close() here so that the
|
||||||
|
* child process won't read what it is writing to the pipe itself.
|
||||||
|
*
|
||||||
|
* And the parent is going to run ecore's main loop waiting for some data:
|
||||||
|
* @until }
|
||||||
|
* @note Calling ecore_pipe_write_close() here isn't important but since we
|
||||||
|
* aren't going to write in the pipe it is good practice.
|
||||||
|
*
|
||||||
|
* And finally when done processing(the child) or done receiving(the parent) we
|
||||||
|
* delete the pipe and shutdown ecore:
|
||||||
|
* @until }
|
||||||
|
*
|
||||||
|
* @example ecore_pipe_simple_example.c
|
||||||
|
*/
|
|
@ -24,7 +24,9 @@ SRCS = \
|
||||||
ecore_con_client_example.c \
|
ecore_con_client_example.c \
|
||||||
ecore_con_server_example.c \
|
ecore_con_server_example.c \
|
||||||
ecore_fd_handler_gnutls_example.c \
|
ecore_fd_handler_gnutls_example.c \
|
||||||
ecore_file_download_example.c
|
ecore_file_download_example.c \
|
||||||
|
ecore_pipe_simple_example.c \
|
||||||
|
ecore_pipe_gstreamer_example.c
|
||||||
|
|
||||||
EXTRA_DIST = $(SRCS)
|
EXTRA_DIST = $(SRCS)
|
||||||
|
|
||||||
|
@ -43,6 +45,7 @@ pkglib_PROGRAMS += \
|
||||||
ecore_idler_example \
|
ecore_idler_example \
|
||||||
ecore_job_example \
|
ecore_job_example \
|
||||||
ecore_timer_example \
|
ecore_timer_example \
|
||||||
ecore_time_functions_example
|
ecore_time_functions_example \
|
||||||
|
ecore_pipe_simple_example
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,180 @@
|
||||||
|
#include <gst/gst.h>
|
||||||
|
#include <Ecore.h>
|
||||||
|
|
||||||
|
static int nbr = 0;
|
||||||
|
|
||||||
|
static GstElement *_buid_pipeline (gchar *filename, Ecore_Pipe *pipe);
|
||||||
|
|
||||||
|
static void new_decoded_pad_cb (GstElement *demuxer,
|
||||||
|
GstPad *new_pad,
|
||||||
|
gpointer user_data);
|
||||||
|
|
||||||
|
static void handler(void *data, void *buf, unsigned int len)
|
||||||
|
{
|
||||||
|
GstBuffer *buffer = *((GstBuffer **)buf);
|
||||||
|
|
||||||
|
printf ("handler : %p\n", buffer);
|
||||||
|
printf ("frame : %d %p %lld %p\n", nbr++, data, (long long)GST_BUFFER_DURATION(buffer), buffer);
|
||||||
|
gst_buffer_unref (buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void handoff (GstElement* object,
|
||||||
|
GstBuffer* arg0,
|
||||||
|
GstPad* arg1,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
Ecore_Pipe *pipe;
|
||||||
|
|
||||||
|
pipe = (Ecore_Pipe *)user_data;
|
||||||
|
printf ("handoff : %p\n", arg0);
|
||||||
|
gst_buffer_ref (arg0);
|
||||||
|
ecore_pipe_write(pipe, &arg0, sizeof(arg0));
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc, char *argv[])
|
||||||
|
{
|
||||||
|
GstElement *pipeline;
|
||||||
|
char *filename;
|
||||||
|
Ecore_Pipe *pipe;
|
||||||
|
|
||||||
|
gst_init (&argc, &argv);
|
||||||
|
|
||||||
|
if (!ecore_init ())
|
||||||
|
{
|
||||||
|
gst_deinit ();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pipe = ecore_pipe_add (handler);
|
||||||
|
if (!pipe)
|
||||||
|
{
|
||||||
|
ecore_shutdown ();
|
||||||
|
gst_deinit ();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argc < 2) {
|
||||||
|
g_print ("usage: %s file.avi\n", argv[0]);
|
||||||
|
ecore_pipe_del (pipe);
|
||||||
|
ecore_shutdown ();
|
||||||
|
gst_deinit ();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
filename = argv[1];
|
||||||
|
|
||||||
|
pipeline = _buid_pipeline (filename, pipe);
|
||||||
|
if (!pipeline) {
|
||||||
|
g_print ("Error during the pipeline building\n");
|
||||||
|
ecore_pipe_del (pipe);
|
||||||
|
ecore_shutdown ();
|
||||||
|
gst_deinit ();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
gst_element_set_state (pipeline, GST_STATE_PLAYING);
|
||||||
|
|
||||||
|
ecore_main_loop_begin();
|
||||||
|
|
||||||
|
ecore_pipe_del (pipe);
|
||||||
|
ecore_shutdown ();
|
||||||
|
gst_deinit ();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
new_decoded_pad_cb (GstElement *demuxer,
|
||||||
|
GstPad *new_pad,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GstElement *decoder;
|
||||||
|
GstPad *pad;
|
||||||
|
GstCaps *caps;
|
||||||
|
gchar *str;
|
||||||
|
|
||||||
|
caps = gst_pad_get_caps (new_pad);
|
||||||
|
str = gst_caps_to_string (caps);
|
||||||
|
|
||||||
|
if (g_str_has_prefix (str, "video/")) {
|
||||||
|
decoder = GST_ELEMENT (user_data);
|
||||||
|
|
||||||
|
pad = gst_element_get_pad (decoder, "sink");
|
||||||
|
if (GST_PAD_LINK_FAILED (gst_pad_link (new_pad, pad))) {
|
||||||
|
g_warning ("Failed to link %s:%s to %s:%s", GST_DEBUG_PAD_NAME (new_pad),
|
||||||
|
GST_DEBUG_PAD_NAME (pad));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g_free (str);
|
||||||
|
gst_caps_unref (caps);
|
||||||
|
}
|
||||||
|
|
||||||
|
static GstElement
|
||||||
|
_buid_pipeline (gchar *filename, Ecore_Pipe *pipe)
|
||||||
|
{
|
||||||
|
GstElement *pipeline;
|
||||||
|
GstElement *filesrc;
|
||||||
|
GstElement *demuxer;
|
||||||
|
GstElement *decoder;
|
||||||
|
GstElement *sink;
|
||||||
|
GstStateChangeReturn res;
|
||||||
|
|
||||||
|
pipeline = gst_pipeline_new ("pipeline");
|
||||||
|
if (!pipeline)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
filesrc = gst_element_factory_make ("filesrc", "filesrc");
|
||||||
|
if (!filesrc) {
|
||||||
|
printf ("no filesrc");
|
||||||
|
goto failure;
|
||||||
|
}
|
||||||
|
g_object_set (G_OBJECT (filesrc), "location", filename, NULL);
|
||||||
|
|
||||||
|
demuxer = gst_element_factory_make ("oggdemux", "demuxer");
|
||||||
|
if (!demuxer) {
|
||||||
|
printf ("no demux");
|
||||||
|
goto failure;
|
||||||
|
}
|
||||||
|
|
||||||
|
decoder = gst_element_factory_make ("theoradec", "decoder");
|
||||||
|
if (!decoder) {
|
||||||
|
printf ("no dec");
|
||||||
|
goto failure;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_signal_connect (demuxer, "pad-added",
|
||||||
|
G_CALLBACK (new_decoded_pad_cb), decoder);
|
||||||
|
|
||||||
|
sink = gst_element_factory_make ("fakesink", "sink");
|
||||||
|
if (!sink) {
|
||||||
|
printf ("no sink");
|
||||||
|
goto failure;
|
||||||
|
}
|
||||||
|
g_object_set (G_OBJECT (sink), "sync", EINA_TRUE, NULL);
|
||||||
|
g_object_set (G_OBJECT (sink), "signal-handoffs", EINA_TRUE, NULL);
|
||||||
|
g_signal_connect (sink, "handoff",
|
||||||
|
G_CALLBACK (handoff), pipe);
|
||||||
|
|
||||||
|
gst_bin_add_many (GST_BIN (pipeline),
|
||||||
|
filesrc, demuxer, decoder, sink, NULL);
|
||||||
|
|
||||||
|
if (!gst_element_link (filesrc, demuxer))
|
||||||
|
goto failure;
|
||||||
|
if (!gst_element_link (decoder, sink))
|
||||||
|
goto failure;
|
||||||
|
|
||||||
|
res = gst_element_set_state (pipeline, GST_STATE_PAUSED);
|
||||||
|
if (res == GST_STATE_CHANGE_FAILURE)
|
||||||
|
goto failure;
|
||||||
|
|
||||||
|
res = gst_element_get_state( pipeline, NULL, NULL, GST_CLOCK_TIME_NONE );
|
||||||
|
if (res != GST_STATE_CHANGE_SUCCESS)
|
||||||
|
goto failure;
|
||||||
|
|
||||||
|
return pipeline;
|
||||||
|
|
||||||
|
failure:
|
||||||
|
gst_object_unref (GST_OBJECT (pipeline));
|
||||||
|
return NULL;
|
||||||
|
}
|
|
@ -0,0 +1,66 @@
|
||||||
|
//Compile with:
|
||||||
|
//gcc -g -Wall `pkg-config --cflags --libs ecore` -o ecore_pipe_simple_example ecore_pipe_simple_example.c
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <Ecore.h>
|
||||||
|
|
||||||
|
static void
|
||||||
|
do_lengthy_task(Ecore_Pipe *pipe)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
char *buffer;
|
||||||
|
for (i = 0; i < 20; i++)
|
||||||
|
{
|
||||||
|
sleep(1);
|
||||||
|
buffer = malloc(sizeof(char) * i);
|
||||||
|
for (j = 0; j < i; j++)
|
||||||
|
buffer[j] = 'a' + j;
|
||||||
|
ecore_pipe_write(pipe, buffer, i);
|
||||||
|
free(buffer);
|
||||||
|
}
|
||||||
|
ecore_pipe_write(pipe, "close", 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
handler(void *data, void *buf, unsigned int len)
|
||||||
|
{
|
||||||
|
char *str = malloc(sizeof(char) * len + 1);
|
||||||
|
memcpy(str, buf, len);
|
||||||
|
str[len] = '\0';
|
||||||
|
printf("received %d bytes\n", len);
|
||||||
|
printf("content: %s\n", (const char*)str);
|
||||||
|
free(str);
|
||||||
|
if (len && !strncmp(buf, "close", len < 5 ? len : 5))
|
||||||
|
{
|
||||||
|
printf("close requested\n");
|
||||||
|
ecore_main_loop_quit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc, char *argv[])
|
||||||
|
{
|
||||||
|
Ecore_Pipe *pipe;
|
||||||
|
pid_t child_pid;
|
||||||
|
|
||||||
|
ecore_init();
|
||||||
|
|
||||||
|
pipe = ecore_pipe_add(handler, NULL);
|
||||||
|
|
||||||
|
child_pid = fork();
|
||||||
|
if(!child_pid)
|
||||||
|
{
|
||||||
|
ecore_pipe_read_close(pipe);
|
||||||
|
do_lengthy_task(pipe);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ecore_pipe_write_close(pipe);
|
||||||
|
ecore_main_loop_begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
ecore_pipe_del(pipe);
|
||||||
|
ecore_shutdown();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -98,9 +98,8 @@ static Eina_Bool _ecore_pipe_read(void *data, Ecore_Fd_Handler *fd_handler);
|
||||||
/**
|
/**
|
||||||
* @addtogroup Ecore_Pipe_Group Pipe wrapper
|
* @addtogroup Ecore_Pipe_Group Pipe wrapper
|
||||||
*
|
*
|
||||||
* These functions wrap the pipe / write / read functions to
|
* These functions wrap the pipe / write / read functions to easily integrate
|
||||||
* easily integrate a loop that is in its own thread to the ecore
|
* its use into ecore's main loop.
|
||||||
* main loop.
|
|
||||||
*
|
*
|
||||||
* The ecore_pipe_add() function creates file descriptors (sockets on
|
* The ecore_pipe_add() function creates file descriptors (sockets on
|
||||||
* Windows) and attach an handle to the ecore main loop. That handle is
|
* Windows) and attach an handle to the ecore main loop. That handle is
|
||||||
|
@ -108,191 +107,9 @@ static Eina_Bool _ecore_pipe_read(void *data, Ecore_Fd_Handler *fd_handler);
|
||||||
* just call ecore_pipe_write(). When you are done, just call
|
* just call ecore_pipe_write(). When you are done, just call
|
||||||
* ecore_pipe_del().
|
* ecore_pipe_del().
|
||||||
*
|
*
|
||||||
* Here is an example that uses the pipe wrapper with a Gstreamer
|
* For examples see here:
|
||||||
* pipeline. For each decoded frame in the Gstreamer thread, a handle
|
* @li @ref tutorial_ecore_pipe_gstreamer_example
|
||||||
* is called in the ecore thread.
|
* @li @ref tutorial_ecore_pipe_simple_example
|
||||||
*
|
|
||||||
* @code#include <gst/gst.h>
|
|
||||||
* #include <Ecore.h>
|
|
||||||
*
|
|
||||||
* static int nbr = 0;
|
|
||||||
*
|
|
||||||
* static GstElement *_buid_pipeline (gchar *filename, Ecore_Pipe *pipe);
|
|
||||||
*
|
|
||||||
* static void new_decoded_pad_cb (GstElement *demuxer,
|
|
||||||
* GstPad *new_pad,
|
|
||||||
* gpointer user_data);
|
|
||||||
*
|
|
||||||
* static void handler(void *data, void *buf, unsigned int len)
|
|
||||||
* {
|
|
||||||
* GstBuffer *buffer = *((GstBuffer **)buf);
|
|
||||||
*
|
|
||||||
* printf ("handler : %p\n", buffer);
|
|
||||||
* printf ("frame : %d %p %lld %p\n", nbr++, data, (long long)GST_BUFFER_DURATION(buffer), buffer);
|
|
||||||
* gst_buffer_unref (buffer);
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* static void handoff (GstElement* object,
|
|
||||||
* GstBuffer* arg0,
|
|
||||||
* GstPad* arg1,
|
|
||||||
* gpointer user_data)
|
|
||||||
* {
|
|
||||||
* Ecore_Pipe *pipe;
|
|
||||||
*
|
|
||||||
* pipe = (Ecore_Pipe *)user_data;
|
|
||||||
* printf ("handoff : %p\n", arg0);
|
|
||||||
* gst_buffer_ref (arg0);
|
|
||||||
* ecore_pipe_write(pipe, &arg0, sizeof(arg0));
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* int
|
|
||||||
* main (int argc, char *argv[])
|
|
||||||
* {
|
|
||||||
* GstElement *pipeline;
|
|
||||||
* char *filename;
|
|
||||||
* Ecore_Pipe *pipe;
|
|
||||||
*
|
|
||||||
* gst_init (&argc, &argv);
|
|
||||||
*
|
|
||||||
* if (!ecore_init ())
|
|
||||||
* {
|
|
||||||
* gst_deinit ();
|
|
||||||
* return 0;
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* pipe = ecore_pipe_add (handler);
|
|
||||||
* if (!pipe)
|
|
||||||
* {
|
|
||||||
* ecore_shutdown ();
|
|
||||||
* gst_deinit ();
|
|
||||||
* return 0;
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* if (argc < 2) {
|
|
||||||
* g_print ("usage: %s file.avi\n", argv[0]);
|
|
||||||
* ecore_pipe_del (pipe);
|
|
||||||
* ecore_shutdown ();
|
|
||||||
* gst_deinit ();
|
|
||||||
* return 0;
|
|
||||||
* }
|
|
||||||
* filename = argv[1];
|
|
||||||
*
|
|
||||||
* pipeline = _buid_pipeline (filename, pipe);
|
|
||||||
* if (!pipeline) {
|
|
||||||
* g_print ("Error during the pipeline building\n");
|
|
||||||
* ecore_pipe_del (pipe);
|
|
||||||
* ecore_shutdown ();
|
|
||||||
* gst_deinit ();
|
|
||||||
* return -1;
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* gst_element_set_state (pipeline, GST_STATE_PLAYING);
|
|
||||||
*
|
|
||||||
* ecore_main_loop_begin();
|
|
||||||
*
|
|
||||||
* ecore_pipe_del (pipe);
|
|
||||||
* ecore_shutdown ();
|
|
||||||
* gst_deinit ();
|
|
||||||
*
|
|
||||||
* return 0;
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* static void
|
|
||||||
* new_decoded_pad_cb (GstElement *demuxer,
|
|
||||||
* GstPad *new_pad,
|
|
||||||
* gpointer user_data)
|
|
||||||
* {
|
|
||||||
* GstElement *decoder;
|
|
||||||
* GstPad *pad;
|
|
||||||
* GstCaps *caps;
|
|
||||||
* gchar *str;
|
|
||||||
*
|
|
||||||
* caps = gst_pad_get_caps (new_pad);
|
|
||||||
* str = gst_caps_to_string (caps);
|
|
||||||
*
|
|
||||||
* if (g_str_has_prefix (str, "video/")) {
|
|
||||||
* decoder = GST_ELEMENT (user_data);
|
|
||||||
*
|
|
||||||
* pad = gst_element_get_pad (decoder, "sink");
|
|
||||||
* if (GST_PAD_LINK_FAILED (gst_pad_link (new_pad, pad))) {
|
|
||||||
* g_warning ("Failed to link %s:%s to %s:%s", GST_DEBUG_PAD_NAME (new_pad),
|
|
||||||
* GST_DEBUG_PAD_NAME (pad));
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
* g_free (str);
|
|
||||||
* gst_caps_unref (caps);
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* static GstElement *
|
|
||||||
* _buid_pipeline (gchar *filename, Ecore_Pipe *pipe)
|
|
||||||
* {
|
|
||||||
* GstElement *pipeline;
|
|
||||||
* GstElement *filesrc;
|
|
||||||
* GstElement *demuxer;
|
|
||||||
* GstElement *decoder;
|
|
||||||
* GstElement *sink;
|
|
||||||
GstStateChangeReturn res;
|
|
||||||
*
|
|
||||||
* pipeline = gst_pipeline_new ("pipeline");
|
|
||||||
* if (!pipeline)
|
|
||||||
* return NULL;
|
|
||||||
*
|
|
||||||
* filesrc = gst_element_factory_make ("filesrc", "filesrc");
|
|
||||||
* if (!filesrc) {
|
|
||||||
* printf ("no filesrc");
|
|
||||||
* goto failure;
|
|
||||||
* }
|
|
||||||
* g_object_set (G_OBJECT (filesrc), "location", filename, NULL);
|
|
||||||
*
|
|
||||||
* demuxer = gst_element_factory_make ("oggdemux", "demuxer");
|
|
||||||
* if (!demuxer) {
|
|
||||||
* printf ("no demux");
|
|
||||||
* goto failure;
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* decoder = gst_element_factory_make ("theoradec", "decoder");
|
|
||||||
* if (!decoder) {
|
|
||||||
* printf ("no dec");
|
|
||||||
* goto failure;
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* g_signal_connect (demuxer, "pad-added",
|
|
||||||
* G_CALLBACK (new_decoded_pad_cb), decoder);
|
|
||||||
*
|
|
||||||
* sink = gst_element_factory_make ("fakesink", "sink");
|
|
||||||
* if (!sink) {
|
|
||||||
* printf ("no sink");
|
|
||||||
* goto failure;
|
|
||||||
* }
|
|
||||||
* g_object_set (G_OBJECT (sink), "sync", EINA_TRUE, NULL);
|
|
||||||
* g_object_set (G_OBJECT (sink), "signal-handoffs", EINA_TRUE, NULL);
|
|
||||||
* g_signal_connect (sink, "handoff",
|
|
||||||
* G_CALLBACK (handoff), pipe);
|
|
||||||
*
|
|
||||||
* gst_bin_add_many (GST_BIN (pipeline),
|
|
||||||
* filesrc, demuxer, decoder, sink, NULL);
|
|
||||||
*
|
|
||||||
* if (!gst_element_link (filesrc, demuxer))
|
|
||||||
* goto failure;
|
|
||||||
* if (!gst_element_link (decoder, sink))
|
|
||||||
* goto failure;
|
|
||||||
*
|
|
||||||
* res = gst_element_set_state (pipeline, GST_STATE_PAUSED);
|
|
||||||
* if (res == GST_STATE_CHANGE_FAILURE)
|
|
||||||
* goto failure;
|
|
||||||
*
|
|
||||||
* res = gst_element_get_state( pipeline, NULL, NULL, GST_CLOCK_TIME_NONE );
|
|
||||||
* if (res != GST_STATE_CHANGE_SUCCESS)
|
|
||||||
* goto failure;
|
|
||||||
*
|
|
||||||
* return pipeline;
|
|
||||||
*
|
|
||||||
* failure:
|
|
||||||
* gst_object_unref (GST_OBJECT (pipeline));
|
|
||||||
* return NULL;
|
|
||||||
* }
|
|
||||||
* @endcode
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue