emotion/generic - Use pipes instead of stdin/stdout for communication.
authorantognolli <antognolli@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Mon, 5 Sep 2011 13:12:17 +0000 (13:12 +0000)
committerantognolli <antognolli@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Mon, 5 Sep 2011 13:12:17 +0000 (13:12 +0000)
Now the player will have the stdin and stdout available for anything
else, and there's no need to make line-buffering with ecore_exe anymore.

git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/emotion@63198 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

src/generic_players/vlc/emotion_generic_vlc.c
src/modules/generic/emotion_generic.c
src/modules/generic/emotion_generic.h

index 0df7c00..425aeb4 100644 (file)
@@ -36,8 +36,10 @@ struct _App {
      char *filename;
      char *shmname;
      int w, h;
-     int fd_read;
-     int fd_write;
+     int fd_read; // read commands from theads here
+     int fd_write; // write commands from threads here
+     int em_read; // read commands from emotion here
+     int em_write; // write commands to emotion here
      int size_sent;
      int opening;
      int closing;
@@ -121,13 +123,13 @@ _em_write_safe(int fd, const void *buf, ssize_t size)
 }
 
 static int
-_em_str_read(char **str)
+_em_str_read(int fd, char **str)
 {
    int size;
    int r;
    char buf[PATH_MAX];
 
-   r = _em_read_safe(STDIN_FILENO, &size, sizeof(size));
+   r = _em_read_safe(fd, &size, sizeof(size));
    if (!r)
      {
         *str = NULL;
@@ -140,7 +142,7 @@ _em_str_read(char **str)
         return 1;
      }
 
-   r = _em_read_safe(STDIN_FILENO, buf, size);
+   r = _em_read_safe(fd, buf, size);
    if (!r)
      {
         *str = NULL;
@@ -152,86 +154,84 @@ _em_str_read(char **str)
 }
 
 static int
-_em_cmd_read(void)
+_em_cmd_read(struct _App *app)
 {
    int cmd;
-   _em_read_safe(STDIN_FILENO, &cmd, sizeof(cmd));
+   _em_read_safe(app->em_read, &cmd, sizeof(cmd));
 
    return cmd;
 }
 
 static void
-_send_cmd_start(int cmd)
+_send_cmd_start(struct _App *app, int cmd)
 {
    pthread_mutex_lock(&_mutex_fd);
-   _em_write_safe(STDOUT_FILENO, &cmd, sizeof(cmd));
+   _em_write_safe(app->em_write, &cmd, sizeof(cmd));
 }
 
 static void
-_send_cmd_finish(void)
+_send_cmd_finish(struct _App *app)
 {
-   static const char c = '\n';
-   _em_write_safe(STDOUT_FILENO, &c, sizeof(c));
    pthread_mutex_unlock(&_mutex_fd);
 }
 
 static void
-_send_cmd(int cmd)
+_send_cmd(struct _App *app, int cmd)
 {
-   _send_cmd_start(cmd);
-   _send_cmd_finish();
+   _send_cmd_start(app, cmd);
+   _send_cmd_finish(app);
 }
 
 static void
-_send_cmd_str(const char *str)
+_send_cmd_str(struct _App *app, const char *str)
 {
    int len;
    len = strlen(str) + 1;
-   _em_write_safe(STDOUT_FILENO, &len, sizeof(len));
-   _em_write_safe(STDOUT_FILENO, str, len);
+   _em_write_safe(app->em_write, &len, sizeof(len));
+   _em_write_safe(app->em_write, str, len);
 }
 
-#define SEND_CMD_PARAM(i) \
-   _em_write_safe(STDOUT_FILENO, &(i), sizeof((i)));
+#define SEND_CMD_PARAM(app, i) \
+   _em_write_safe((app)->em_write, &(i), sizeof((i)));
 
 static void
-_send_resize(int width, int height)
+_send_resize(struct _App *app, int width, int height)
 {
-   _send_cmd_start(EM_RESULT_FRAME_SIZE);
-   SEND_CMD_PARAM(width);
-   SEND_CMD_PARAM(height);
-   _send_cmd_finish();
+   _send_cmd_start(app, EM_RESULT_FRAME_SIZE);
+   SEND_CMD_PARAM(app, width);
+   SEND_CMD_PARAM(app, height);
+   _send_cmd_finish(app);
 }
 
 static void
-_send_length_changed(const struct libvlc_event_t *ev)
+_send_length_changed(struct _App *app, const struct libvlc_event_t *ev)
 {
    float length = ev->u.media_player_length_changed.new_length;
    length /= 1000;
 
    fprintf(stderr, "length changed: %0.3f\n", length);
-   _send_cmd_start(EM_RESULT_LENGTH_CHANGED);
-   SEND_CMD_PARAM(length);
-   _send_cmd_finish();
+   _send_cmd_start(app, EM_RESULT_LENGTH_CHANGED);
+   SEND_CMD_PARAM(app, length);
+   _send_cmd_finish(app);
 }
 
 static void
-_send_time_changed(const struct libvlc_event_t *ev)
+_send_time_changed(struct _App *app, const struct libvlc_event_t *ev)
 {
    float new_time = ev->u.media_player_time_changed.new_time;
    new_time /= 1000;
-   _send_cmd_start(EM_RESULT_POSITION_CHANGED);
-   SEND_CMD_PARAM(new_time);
-   _send_cmd_finish();
+   _send_cmd_start(app, EM_RESULT_POSITION_CHANGED);
+   SEND_CMD_PARAM(app, new_time);
+   _send_cmd_finish(app);
 }
 
 static void
-_send_seekable_changed(const struct libvlc_event_t *ev)
+_send_seekable_changed(struct _App *app, const struct libvlc_event_t *ev)
 {
    int seekable = ev->u.media_player_seekable_changed.new_seekable;
-   _send_cmd_start(EM_RESULT_SEEKABLE_CHANGED);
-   SEND_CMD_PARAM(seekable);
-   _send_cmd_finish();
+   _send_cmd_start(app, EM_RESULT_SEEKABLE_CHANGED);
+   SEND_CMD_PARAM(app, seekable);
+   _send_cmd_finish(app);
 }
 
 static void *
@@ -270,7 +270,7 @@ _display(void *data, void *id)
    if (!app->playing)
      return;
 
-   _send_cmd(EM_RESULT_FRAME_NEW);
+   _send_cmd(app, EM_RESULT_FRAME_NEW);
 }
 
 static void *
@@ -298,7 +298,7 @@ _play(struct _App *app)
    if (!app->mp)
      return;
 
-   _em_read_safe(STDIN_FILENO, &pos, sizeof(pos));
+   _em_read_safe(app->em_read, &pos, sizeof(pos));
 
    if (app->playing)
      {
@@ -325,14 +325,14 @@ _send_file_closed(struct _App *app)
 {
    app->closing = 0;
    emotion_generic_shm_free(app->vs);
-   _send_cmd(EM_RESULT_FILE_CLOSE);
+   _send_cmd(app, EM_RESULT_FILE_CLOSE);
 }
 
 static void
 _send_file_set(struct _App *app)
 {
    if (app->opening)
-      _send_cmd(EM_RESULT_FILE_SET);
+      _send_cmd(app, EM_RESULT_FILE_SET);
 
    if (app->closing)
      _send_file_closed(app);
@@ -346,26 +346,26 @@ _event_cb(const struct libvlc_event_t *ev, void *data)
 
    switch (ev->type) {
       case libvlc_MediaPlayerTimeChanged:
-        _send_time_changed(ev);
+        _send_time_changed(app, ev);
         break;
       case libvlc_MediaPlayerPositionChanged:
         thread_event = EM_THREAD_POSITION_CHANGED;
         write(app->fd_write, &thread_event, sizeof(thread_event));
         break;
       case libvlc_MediaPlayerLengthChanged:
-        _send_length_changed(ev);
+        _send_length_changed(app, ev);
         break;
       case libvlc_MediaPlayerSeekableChanged:
-        _send_seekable_changed(ev);
+        _send_seekable_changed(app, ev);
         break;
       case libvlc_MediaPlayerPlaying:
-        _send_resize(app->w, app->h);
+        _send_resize(app, app->w, app->h);
         break;
       case libvlc_MediaPlayerStopped:
         _send_file_set(app);
         break;
       case libvlc_MediaPlayerEndReached:
-        _send_cmd(EM_RESULT_PLAYBACK_STOPPED);
+        _send_cmd(app, EM_RESULT_PLAYBACK_STOPPED);
         break;
    }
 }
@@ -373,7 +373,7 @@ _event_cb(const struct libvlc_event_t *ev, void *data)
 static void
 _file_set(struct _App *app)
 {
-   _em_str_read(&app->filename);
+   _em_str_read(app->em_read, &app->filename);
 
    app->m = libvlc_media_new_path(app->libvlc, app->filename);
    if (!app->m)
@@ -411,7 +411,7 @@ _position_set(struct _App *app)
      return;
 
    float position;
-   _em_read_safe(STDIN_FILENO, &position, sizeof(position));
+   _em_read_safe(app->em_read, &position, sizeof(position));
 
    libvlc_time_t new_time = position * 1000;
    libvlc_media_player_set_time(app->mp, new_time);
@@ -425,7 +425,7 @@ _speed_set(struct _App *app)
    if (!app->mp)
      return;
 
-   _em_read_safe(STDIN_FILENO, &rate, sizeof(rate));
+   _em_read_safe(app->em_read, &rate, sizeof(rate));
 
    libvlc_media_player_set_rate(app->mp, rate);
 }
@@ -438,7 +438,7 @@ _mute_set(struct _App *app)
    if (!app->mp)
      return;
 
-   _em_read_safe(STDIN_FILENO, &mute, sizeof(mute));
+   _em_read_safe(app->em_read, &mute, sizeof(mute));
 
    libvlc_audio_set_mute(app->mp, mute);
 }
@@ -452,7 +452,7 @@ _volume_set(struct _App *app)
    if (!app->mp)
      return;
 
-   _em_read_safe(STDIN_FILENO, &volume, sizeof(volume));
+   _em_read_safe(app->em_read, &volume, sizeof(volume));
    vol = volume * 100;
 
    libvlc_audio_set_volume(app->mp, vol);
@@ -463,7 +463,7 @@ _audio_track_set(struct _App *app)
 {
    int track;
 
-   _em_read_safe(STDIN_FILENO, &track, sizeof(track));
+   _em_read_safe(app->em_read, &track, sizeof(track));
 
    libvlc_audio_set_track(app->mp, track);
 }
@@ -484,9 +484,9 @@ _file_set_done(struct _App *app)
        app->filename = NULL;
        app->m = NULL;
        app->mp = NULL;
-       _send_cmd_start(EM_RESULT_FILE_SET_DONE);
-       SEND_CMD_PARAM(r);
-       _send_cmd_finish();
+       _send_cmd_start(app, EM_RESULT_FILE_SET_DONE);
+       SEND_CMD_PARAM(app, r);
+       _send_cmd_finish(app);
      }
    app->w = app->vs->width;
    app->h = app->vs->height;
@@ -505,9 +505,9 @@ _file_set_done(struct _App *app)
 
    libvlc_audio_set_mute(app->mp, 0);
 
-   _send_cmd_start(EM_RESULT_FILE_SET_DONE);
-   SEND_CMD_PARAM(r);
-   _send_cmd_finish();
+   _send_cmd_start(app, EM_RESULT_FILE_SET_DONE);
+   SEND_CMD_PARAM(app, r);
+   _send_cmd_finish(app);
 }
 
 static void
@@ -534,7 +534,7 @@ _file_close(struct _App *app)
 static void
 _process_emotion_commands(struct _App *app)
 {
-   int cmd = _em_cmd_read();
+   int cmd = _em_cmd_read(app);
    switch (cmd) {
       case EM_CMD_FILE_SET:
         _file_set(app);
@@ -570,27 +570,27 @@ _process_emotion_commands(struct _App *app)
 }
 
 static void
-_send_track_info(libvlc_media_player_t *mp)
+_send_track_info(struct _App *app)
 {
    int track_count, current;
    libvlc_track_description_t *desc;
 
-   current = libvlc_audio_get_track(mp);
-   track_count = libvlc_audio_get_track_count(mp);
-   desc = libvlc_audio_get_track_description(mp);
+   current = libvlc_audio_get_track(app->mp);
+   track_count = libvlc_audio_get_track_count(app->mp);
+   desc = libvlc_audio_get_track_description(app->mp);
 
-   _send_cmd_start(EM_RESULT_AUDIO_TRACK_INFO);
-   SEND_CMD_PARAM(current);
-   SEND_CMD_PARAM(track_count);
+   _send_cmd_start(app, EM_RESULT_AUDIO_TRACK_INFO);
+   SEND_CMD_PARAM(app, current);
+   SEND_CMD_PARAM(app, track_count);
    while (desc)
      {
        int tid = desc->i_id;
        const char *name = desc->psz_name;
-       SEND_CMD_PARAM(tid);
-       _send_cmd_str(name);
+       SEND_CMD_PARAM(app, tid);
+       _send_cmd_str(app, name);
        desc = desc->p_next;
      }
-   _send_cmd_finish();
+   _send_cmd_finish(app);
 }
 
 static void
@@ -604,10 +604,10 @@ _position_changed(struct _App *app)
    r = libvlc_video_get_size(app->mp, 0, &w, &h);
    if (r < 0)
      return;
-   _send_resize(w, h);
+   _send_resize(app, w, h);
 
    /* sending audio track info */
-   // _send_track_info(app->mp);
+   // _send_track_info(app);
 
    libvlc_media_player_stop(app->mp);
 }
@@ -657,6 +657,18 @@ main(int argc, const char *argv[])
        chroma
      };
 
+   if (argc < 3)
+     {
+       fprintf(stderr, "player: missing paramters.\n");
+       fprintf(stderr, "syntax:\n\t%s <fd read> <fd write>\n", argv[0]);
+       return -1;
+     }
+
+   app.em_read = atoi(argv[1]);
+   app.em_write = atoi(argv[2]);
+
+   fprintf(stderr, "reading commands from fd: %d, writing on fd: %d\n", app.em_read, app.em_write);
+
    int vlc_argc = sizeof(vlc_argv) / sizeof(*vlc_argv);
    snprintf(cwidth, sizeof(cwidth), "%d", DEFAULTWIDTH);
    snprintf(cheight, sizeof(cheight), "%d", DEFAULTHEIGHT);
@@ -684,23 +696,23 @@ main(int argc, const char *argv[])
    app.playing = 0;
    app.closing = 0;
 
-   if (_em_cmd_read() != EM_CMD_INIT)
+   if (_em_cmd_read(&app) != EM_CMD_INIT)
      {
        fprintf(stderr, "player: wrong init command!\n");
        return -1;
      }
 
    int size;
-   _em_read_safe(STDIN_FILENO, &size, sizeof(size));
-   _em_read_safe(STDIN_FILENO, buf, size);
+   _em_read_safe(app.em_read, &size, sizeof(size));
+   _em_read_safe(app.em_read, buf, size);
    app.shmname = strdup(buf);
 
-   _send_cmd(EM_RESULT_INIT);
+   _send_cmd(&app, EM_RESULT_INIT);
 
    pipe(tpipe);
    app.fd_read = tpipe[0];
    app.fd_write = tpipe[1];
-   fds[0].fd = STDIN_FILENO;
+   fds[0].fd = app.em_read;
    fds[0].events = POLLIN;
    fds[1].fd = app.fd_read;
    fds[1].events = POLLIN;
index 2e1204a..3d8f1f0 100644 (file)
@@ -103,19 +103,19 @@ _player_send_cmd(Emotion_Generic_Video *ev, int cmd)
        ERR("invalid command to player.");
        return;
      }
-   ecore_exe_send(ev->player.exe, &cmd, sizeof(cmd));
+   write(ev->fd_write, &cmd, sizeof(cmd));
 }
 
 static void
 _player_send_int(Emotion_Generic_Video *ev, int number)
 {
-   ecore_exe_send(ev->player.exe, &number, sizeof(number));
+   write(ev->fd_write, &number, sizeof(number));
 }
 
 static void
 _player_send_float(Emotion_Generic_Video *ev, float number)
 {
-   ecore_exe_send(ev->player.exe, &number, sizeof(number));
+   write(ev->fd_write, &number, sizeof(number));
 }
 
 static void
@@ -127,8 +127,8 @@ _player_send_str(Emotion_Generic_Video *ev, const char *str, Eina_Bool stringsha
      len = eina_stringshare_strlen(str) + 1;
    else
      len = strlen(str) + 1;
-   ecore_exe_send(ev->player.exe, &len, sizeof(len));
-   ecore_exe_send(ev->player.exe, str, len);
+   write(ev->fd_write, &len, sizeof(len));
+   write(ev->fd_write, str, len);
 }
 
 static Eina_Bool
@@ -234,31 +234,94 @@ _player_ready(Emotion_Generic_Video *ev)
    _file_open(ev);
 }
 
-#define RCV_CMD_PARAM(src, param) \
-   memcpy(&(param), (src), sizeof((param))); \
-   (src) = (char *)(src) + sizeof((param));
+static int
+_em_read_safe(int fd, void *buf, ssize_t size)
+{
+   ssize_t todo;
+   char *p;
 
-#define RCV_CMD_STR(src, buf, len) \
-   RCV_CMD_PARAM((src), (len)); \
-   memcpy((buf), (src), (len)); \
-   (src) = (char *)(src) + len;
+   todo = size;
+   p = buf;
 
-static int
-_player_int_read(Emotion_Generic_Video *ev __UNUSED__, void **data)
+   while (todo > 0)
+     {
+        ssize_t r;
+
+        r = read(fd, p, todo);
+        if (r > 0)
+          {
+             todo -= r;
+             p += r;
+          }
+        else if (r == 0)
+          return 0;
+        else
+          {
+             if (errno == EINTR || errno == EAGAIN)
+               continue;
+             else
+               {
+                  ERR("could not read from fd %d: %s", fd, strerror(errno));
+                  return 0;
+               }
+          }
+     }
+
+   return 1;
+}
+
+static Eina_Bool
+_player_int_read(Emotion_Generic_Video *ev, int *i)
+{
+   int n;
+   n = _em_read_safe(ev->fd_read, i, sizeof(*i));
+   if (n <= 0)
+     {
+       ERR("could not read int from fd_read %d\n", ev->fd_read);
+       return EINA_FALSE;
+     }
+
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_player_float_read(Emotion_Generic_Video *ev, float *f)
+{
+   int n;
+   n = _em_read_safe(ev->fd_read, f, sizeof(*f));
+   if (n <= 0)
+     {
+       ERR("could not read float from fd_read %d\n", ev->fd_read);
+       return EINA_FALSE;
+     }
+
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_player_str_read(Emotion_Generic_Video *ev, char *str, int *len)
 {
-   int number;
-   memcpy(&number, *data, sizeof(number));
-   *data = (char *)(*data) + sizeof(number);
+   int n;
 
-   return number;
+   if (!_player_int_read(ev, len))
+     return EINA_FALSE;
+
+   n = _em_read_safe(ev->fd_read, str, *len);
+   if (n <= 0)
+     {
+       ERR("could not read string from fd_read %d\n", ev->fd_read);
+       return EINA_FALSE;
+     }
+
+   return EINA_TRUE;
 }
 
 static void
-_player_frame_resize(Emotion_Generic_Video *ev, void *line)
+_player_frame_resize(Emotion_Generic_Video *ev)
 {
    int w, h;
-   RCV_CMD_PARAM(line, w);
-   RCV_CMD_PARAM(line, h);
+   _player_int_read(ev, &w);
+   _player_int_read(ev, &h);
 
    INF("received frame resize: %dx%d", w, h);
    ev->w = w;
@@ -272,10 +335,10 @@ _player_frame_resize(Emotion_Generic_Video *ev, void *line)
 }
 
 static void
-_player_length_changed(Emotion_Generic_Video *ev, void *line)
+_player_length_changed(Emotion_Generic_Video *ev)
 {
    float length;
-   RCV_CMD_PARAM(line, length);
+   _player_float_read(ev, &length);
 
    INF("received length changed: %0.3f", length);
 
@@ -284,10 +347,10 @@ _player_length_changed(Emotion_Generic_Video *ev, void *line)
 }
 
 static void
-_player_position_changed(Emotion_Generic_Video *ev, void *line)
+_player_position_changed(Emotion_Generic_Video *ev)
 {
    float position;
-   RCV_CMD_PARAM(line, position);
+   _player_float_read(ev, &position);
 
    INF("received position changed: %0.3f", position);
 
@@ -305,10 +368,10 @@ _player_position_changed(Emotion_Generic_Video *ev, void *line)
 }
 
 static void
-_player_seekable_changed(Emotion_Generic_Video *ev, void *line)
+_player_seekable_changed(Emotion_Generic_Video *ev)
 {
    int seekable;
-   RCV_CMD_PARAM(line, seekable);
+   _player_int_read(ev, &seekable);
 
    INF("received seekable changed: %d", seekable);
 
@@ -318,10 +381,10 @@ _player_seekable_changed(Emotion_Generic_Video *ev, void *line)
 }
 
 static void
-_player_volume(Emotion_Generic_Video *ev, void *line)
+_player_volume(Emotion_Generic_Video *ev)
 {
    float vol, oldvol;
-   RCV_CMD_PARAM(line, vol);
+   _player_float_read(ev, &vol);
 
    INF("received volume: %0.3f", vol);
 
@@ -332,10 +395,10 @@ _player_volume(Emotion_Generic_Video *ev, void *line)
 }
 
 static void
-_player_audio_mute(Emotion_Generic_Video *ev, void *line)
+_player_audio_mute(Emotion_Generic_Video *ev)
 {
    int mute;
-   RCV_CMD_PARAM(line, mute);
+   _player_int_read(ev, &mute);
 
    INF("received audio mute: %d", mute);
 
@@ -353,7 +416,7 @@ _audio_channels_free(Emotion_Generic_Video *ev)
 }
 
 static void
-_player_audio_tracks_info(Emotion_Generic_Video *ev, void *line)
+_player_audio_tracks_info(Emotion_Generic_Video *ev)
 {
    int track_current, tracks_count;
    int i;
@@ -361,8 +424,8 @@ _player_audio_tracks_info(Emotion_Generic_Video *ev, void *line)
    if (ev->audio_channels_count)
      _audio_channels_free(ev);
 
-   RCV_CMD_PARAM(line, track_current);
-   RCV_CMD_PARAM(line, tracks_count);
+   _player_int_read(ev, &track_current);
+   _player_int_read(ev, &tracks_count);
    INF("video with %d audio tracks (current = %d):", tracks_count, track_current);
    ev->audio_channels = calloc(
       tracks_count, sizeof(Emotion_Generic_Audio_Channel));
@@ -372,8 +435,8 @@ _player_audio_tracks_info(Emotion_Generic_Video *ev, void *line)
      {
        int tid, len;
        char buf[PATH_MAX];
-       RCV_CMD_PARAM(line, tid);
-       RCV_CMD_STR(line, buf, len);
+       _player_int_read(ev, &tid);
+       _player_str_read(ev, buf, &len);
        ev->audio_channels[i].id = tid;
        ev->audio_channels[i].name = eina_stringshare_add_length(buf, len);
        INF("\t%d: %s", tid, buf);
@@ -393,12 +456,12 @@ _player_file_closed(Emotion_Generic_Video *ev)
 }
 
 static void
-_player_open_done(Emotion_Generic_Video *ev, void *line)
+_player_open_done(Emotion_Generic_Video *ev)
 {
    int success;
 
    ev->opening = EINA_FALSE;
-   RCV_CMD_PARAM(line, success);
+   _player_int_read(ev, &success);
 
    shm_unlink(ev->shmname);
    if (!success)
@@ -419,10 +482,15 @@ _player_open_done(Emotion_Generic_Video *ev, void *line)
 }
 
 static void
-_player_read_cmd(Emotion_Generic_Video *ev, void *line, int size __UNUSED__)
+_player_read_cmd(Emotion_Generic_Video *ev)
 {
    int type;
-   RCV_CMD_PARAM(line, type);
+
+   if (!_player_int_read(ev, &type))
+     {
+       ERR("could not read command\n");
+       return;
+     }
 
    switch (type) {
       case EM_RESULT_INIT:
@@ -435,7 +503,7 @@ _player_read_cmd(Emotion_Generic_Video *ev, void *line, int size __UNUSED__)
         _player_file_set_done(ev);
         break;
       case EM_RESULT_FILE_SET_DONE:
-        _player_open_done(ev, line);
+        _player_open_done(ev);
         break;
       case EM_RESULT_FILE_CLOSE:
         _player_file_closed(ev);
@@ -444,26 +512,40 @@ _player_read_cmd(Emotion_Generic_Video *ev, void *line, int size __UNUSED__)
         _emotion_playback_finished(ev->obj);
         break;
       case EM_RESULT_FRAME_SIZE:
-        _player_frame_resize(ev, line);
+        _player_frame_resize(ev);
         break;
       case EM_RESULT_LENGTH_CHANGED:
-        _player_length_changed(ev, line);
+        _player_length_changed(ev);
         break;
       case EM_RESULT_POSITION_CHANGED:
-        _player_position_changed(ev, line);
+        _player_position_changed(ev);
         break;
       case EM_RESULT_SEEKABLE_CHANGED:
-        _player_seekable_changed(ev, line);
+        _player_seekable_changed(ev);
         break;
       case EM_RESULT_AUDIO_TRACK_INFO:
-        _player_audio_tracks_info(ev, line);
+        _player_audio_tracks_info(ev);
         break;
       default:
         WRN("received wrong command: %d", type);
    };
 }
 
-#undef RCV_CMD_PARAM
+static Eina_Bool
+_player_cmd_handler_cb(void *data, Ecore_Fd_Handler *fd_handler)
+{
+   Emotion_Generic_Video *ev = data;
+
+   if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_ERROR))
+     {
+       ERR("an error occurred on fd_read %d.", ev->fd_read);
+       return ECORE_CALLBACK_CANCEL;
+     }
+
+   _player_read_cmd(ev);
+
+   return ECORE_CALLBACK_RENEW;
+}
 
 static Eina_Bool
 _player_data_cb(void *data, int type __UNUSED__, void *event)
@@ -485,7 +567,7 @@ _player_data_cb(void *data, int type __UNUSED__, void *event)
      }
 
    for (i = 0; ev->lines[i].line; i++)
-     _player_read_cmd(evideo, ev->lines[i].line, ev->lines[i].size);
+     INF("received input from player: \"%s\"", ev->lines[i].line);
 
    return ECORE_CALLBACK_DONE;
 }
@@ -517,13 +599,70 @@ _player_del_cb(void *data, int type __UNUSED__, void *event __UNUSED__)
 
    ev->player.exe = NULL;
    ev->ready = EINA_FALSE;
+   ecore_main_fd_handler_del(ev->fd_handler);
+   close(ev->fd_read);
+   close(ev->fd_write);
+   ev->fd_read = -1;
+   ev->fd_write = -1;
    _emotion_decode_stop(ev->obj);
 
    return ECORE_CALLBACK_DONE;
 }
 
 static Eina_Bool
-_fork_and_exec(Evas_Object *obj __UNUSED__, Emotion_Generic_Video *ev)
+_player_exec(Emotion_Generic_Video *ev)
+{
+   int pipe_out[2];
+   int pipe_in[2];
+   char buf[PATH_MAX];
+
+   if (pipe(pipe_out) == -1)
+     {
+       ERR("could not create pipe for communication emotion -> player: %s", strerror(errno));
+       return EINA_FALSE;
+     }
+
+   if (pipe(pipe_in) == -1)
+     {
+       ERR("could not create pipe for communication player -> emotion: %s", strerror(errno));
+       close(pipe_out[0]);
+       close(pipe_out[1]);
+       return EINA_FALSE;
+     }
+
+   snprintf(buf, sizeof(buf), "%s %d %d\n", ev->cmdline, pipe_out[0], pipe_in[1]);
+
+   ev->player.exe = ecore_exe_pipe_run(
+      buf,
+      ECORE_EXE_PIPE_READ | ECORE_EXE_PIPE_WRITE |
+      ECORE_EXE_PIPE_READ_LINE_BUFFERED | ECORE_EXE_NOT_LEADER,
+      ev);
+
+   INF("created pipe emotion -> player: %d -> %d\n", pipe_out[1], pipe_out[0]);
+   INF("created pipe player -> emotion: %d -> %d\n", pipe_in[1], pipe_in[0]);
+
+   close(pipe_in[1]);
+   close(pipe_out[0]);
+
+   if (!ev->player.exe)
+     {
+       close(pipe_in[0]);
+       close(pipe_out[1]);
+       return EINA_FALSE;
+     }
+
+   ev->fd_read = pipe_in[0];
+   ev->fd_write = pipe_out[1];
+
+   ev->fd_handler = ecore_main_fd_handler_add(
+      ev->fd_read, ECORE_FD_READ | ECORE_FD_ERROR, _player_cmd_handler_cb, ev,
+      NULL, NULL);
+
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_fork_and_exec(Evas_Object *obj, Emotion_Generic_Video *ev)
 {
    char shmname[256];
    struct timeval tv;
@@ -541,13 +680,8 @@ _fork_and_exec(Evas_Object *obj __UNUSED__, Emotion_Generic_Video *ev)
    ev->player_data = ecore_event_handler_add(
       ECORE_EXE_EVENT_DATA, _player_data_cb, ev);
 
-   ev->player.exe = ecore_exe_pipe_run(
-      ev->cmdline,
-      ECORE_EXE_PIPE_READ | ECORE_EXE_PIPE_WRITE |
-      ECORE_EXE_PIPE_READ_LINE_BUFFERED | ECORE_EXE_NOT_LEADER,
-      ev);
 
-   if (!ev->player.exe)
+   if (!_player_exec(ev))
      {
         ERR("could not start player.");
         return EINA_FALSE;
@@ -571,6 +705,8 @@ em_init(Evas_Object *obj, void **emotion_video, Emotion_Module_Options *opt)
    ev = (Emotion_Generic_Video *)calloc(1, sizeof(*ev));
    if (!ev) return 0;
 
+   ev->fd_read = -1;
+   ev->fd_write = -1;
    ev->speed = 1.0;
    ev->volume = 0.5;
    ev->audio_mute = EINA_FALSE;
@@ -599,6 +735,13 @@ em_shutdown(void *data)
    if (ev->shared)
      munmap(ev->shared, ev->shared->size);
 
+   if (ev->fd_read >= 0)
+     close(ev->fd_read);
+   if (ev->fd_write >= 0)
+     close(ev->fd_write);
+   if (ev->fd_handler)
+     ecore_main_fd_handler_del(ev->fd_handler);
+
    _audio_channels_free(ev);
 
    eina_stringshare_del(ev->cmdline);
@@ -681,13 +824,7 @@ em_play(void *data, double pos)
        return;
      }
 
-   ev->player.exe = ecore_exe_pipe_run(
-      ev->cmdline,
-      ECORE_EXE_PIPE_READ | ECORE_EXE_PIPE_WRITE |
-      ECORE_EXE_PIPE_READ_LINE_BUFFERED | ECORE_EXE_NOT_LEADER,
-      ev);
-
-   if (!ev->player.exe)
+   if (!_player_exec(ev))
      ERR("could not start player.");
 }
 
index 62d6044..08084a5 100644 (file)
@@ -29,6 +29,8 @@ struct _Emotion_Generic_Video
    Emotion_Generic_Player    player;
    Ecore_Event_Handler      *player_add, *player_del, *player_data;
    int                      drop;
+   int                      fd_read, fd_write;
+   Ecore_Fd_Handler         *fd_handler;
 
    const char               *filename;
    volatile double          len;