Ecore_Pipe_Group

Langue: en

Version: 380270 (fedora - 01/12/10)

Section: 3 (Bibliothèques de fonctions)

NAME

Pipe wrapper -

These functions wrap the pipe / write / read functions to easily integrate a loop that is in its own thread to the ecore main loop.

Functions


EAPI Ecore_Pipe * ecore_pipe_add (void(*handler)(void *data, void *buffer, unsigned int nbyte), const void *data)
Create two file descriptors (sockets on Windows).
EAPI void * ecore_pipe_del (Ecore_Pipe *p)
Free an Ecore_Pipe object created with ecore_pipe_add().
EAPI void ecore_pipe_read_close (Ecore_Pipe *p)
Close the read end of an Ecore_Pipe object created with ecore_pipe_add().
EAPI void ecore_pipe_write_close (Ecore_Pipe *p)
Close the write end of an Ecore_Pipe object created with ecore_pipe_add().
EAPI Eina_Bool ecore_pipe_write (Ecore_Pipe *p, const void *buffer, unsigned int nbytes)
Write on the file descriptor the data passed as parameter.

Detailed Description

These functions wrap the pipe / write / read functions to easily integrate a loop that is in its own thread to the ecore main loop.

The ecore_pipe_add() function creates file descriptors (sockets on Windows) and attach an handle to the ecore main loop. That handle is called when data is read in the pipe. To write data in the pipe, just call ecore_pipe_write(). When you are done, just call ecore_pipe_del().

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 <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, buffer);
    printf ('frame  : %d %p %lld %p, 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, 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, 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);
      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;
  }
 


 

Function Documentation

EAPI Ecore_Pipe* ecore_pipe_add (void(*)(void *data, void *buffer, unsigned int nbyte) handler, const void * data)

Create two file descriptors (sockets on Windows). Add a callback that will be called when the file descriptor that is listened receives data. An event is also put in the event queue when data is received.

Parameters:

handler The handler called when data is received.
data Data to pass to handler when it is called.

Returns:

A newly created Ecore_Pipe object if successful. NULL otherwise.

References ECORE_FD_READ, and ecore_main_fd_handler_add().

EAPI void* ecore_pipe_del (Ecore_Pipe * p)

Free an Ecore_Pipe object created with ecore_pipe_add(). Parameters:

p The Ecore_Pipe object to be freed.

Returns:

The pointer to the private data

References ecore_main_fd_handler_del().

EAPI void ecore_pipe_read_close (Ecore_Pipe * p)

Close the read end of an Ecore_Pipe object created with ecore_pipe_add(). Parameters:

p The Ecore_Pipe object.

References ecore_main_fd_handler_del().

EAPI Eina_Bool ecore_pipe_write (Ecore_Pipe * p, const void * buffer, unsigned int nbytes)

Write on the file descriptor the data passed as parameter. Parameters:

p The Ecore_Pipe object.
buffer The data to write into the pipe.
nbytes The size of the buffer in bytes

Returns:

Returns EINA_TRUE on a successful write, EINA_FALSE on an error

EAPI void ecore_pipe_write_close (Ecore_Pipe * p)

Close the write end of an Ecore_Pipe object created with ecore_pipe_add(). Parameters:

p The Ecore_Pipe object.

Author

Generated automatically by Doxygen for Ecore from the source code.