From 10ebda80419e3ae1d90fc253b7823d9602d284e5 Mon Sep 17 00:00:00 2001 From: Cedric BAIL Date: Wed, 27 Feb 2013 12:12:43 +0000 Subject: emotion_generic_players: improve portability by using EFL infrastructure. SVN revision: 84391 --- src/vlc/emotion_generic_vlc.c | 950 ++++++++++++++++++------------------------ 1 file changed, 394 insertions(+), 556 deletions(-) (limited to 'src') diff --git a/src/vlc/emotion_generic_vlc.c b/src/vlc/emotion_generic_vlc.c index 2bf441e..fb0c900 100644 --- a/src/vlc/emotion_generic_vlc.c +++ b/src/vlc/emotion_generic_vlc.c @@ -21,6 +21,7 @@ #include #include +#include static int _em_vlc_log_dom = -1; #define ERR(...) EINA_LOG_DOM_ERR(_em_vlc_log_dom, __VA_ARGS__) @@ -30,317 +31,236 @@ static int _em_vlc_log_dom = -1; #define CRIT(...) EINA_LOG_DOM_CRIT(_em_vlc_log_dom, __VA_ARGS__) enum _Thread_Events { - EM_THREAD_POSITION_CHANGED, - EM_THREAD_PLAYBACK_STARTED, - EM_THREAD_PLAYBACK_STOPPED, - EM_THREAD_LAST + EM_THREAD_POSITION_CHANGED, + EM_THREAD_PLAYBACK_STARTED, + EM_THREAD_PLAYBACK_STOPPED, + EM_THREAD_LAST }; +typedef struct _App App; struct _App { - Emotion_Generic_Video_Shared *vs; - Emotion_Generic_Video_Frame vf; - libvlc_instance_t *libvlc; - libvlc_media_t *m; - libvlc_media_player_t *mp; - libvlc_event_manager_t *event_mgr; - libvlc_event_manager_t *mevent_mgr; - char *filename; - char *subtitle_path; - char *shmname; - void *tmpbuffer; - int w, h; - 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; - int playing; + Emotion_Generic_Video_Shared *vs; + Emotion_Generic_Video_Frame vf; + libvlc_instance_t *libvlc; + libvlc_media_t *m; + libvlc_media_player_t *mp; + libvlc_event_manager_t *event_mgr; + libvlc_event_manager_t *mevent_mgr; + char *filename; + char *subtitle_path; + char *shmname; + void *tmpbuffer; + int w, h; + // Use Ecore infra for that instead + Ecore_Pipe *fd_read; // read commands from theads here + Ecore_Pipe *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; + int playing; + + int last_order; + + Eina_Bool inited; }; -static pthread_mutex_t _mutex_fd = PTHREAD_MUTEX_INITIALIZER; - -int -_em_read_safe(int fd, void *buf, ssize_t size) -{ - ssize_t todo; - char *p; - - todo = size; - p = buf; - - 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; -} - -int -_em_write_safe(int fd, const void *buf, ssize_t size) +Eina_Bool +exit_func(void *data EINA_UNUSED, int ev_type EINA_UNUSED, void *ev EINA_UNUSED) { - ssize_t todo; - const char *p; - - todo = size; - p = buf; - - while (todo > 0) - { - ssize_t r; - - r = write(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 write to fd %d: %s", fd, strerror(errno)); - return 0; - } - } - } - - return 1; + ecore_main_loop_quit(); + return EINA_TRUE; } -static int -_em_str_read(int fd, char **str) -{ - int size; - int r; - char buf[PATH_MAX]; - - r = _em_read_safe(fd, &size, sizeof(size)); - if (!r) - { - *str = NULL; - return 0; - } - - if (!size) - { - *str = NULL; - return 1; - } - - r = _em_read_safe(fd, buf, size); - if (!r) - { - *str = NULL; - return 0; - } - - *str = strdup(buf); - return 1; -} - -static int -_em_cmd_read(struct _App *app) -{ - int cmd; - _em_read_safe(app->em_read, &cmd, sizeof(cmd)); - - return cmd; -} +#define SEND_CMD_PARAM(app, i) \ + if ((app)->fd_write) \ + if (!ecore_pipe_write((app)->fd_write, &(i), sizeof((i)))) \ + ecore_main_loop_quit(); static void -_send_cmd_start(struct _App *app, int cmd) +_send_cmd(App *app, int cmd) { - pthread_mutex_lock(&_mutex_fd); - _em_write_safe(app->em_write, &cmd, sizeof(cmd)); + if (app->fd_write) + if (!ecore_pipe_write(app->fd_write, &cmd, sizeof(cmd))) + ecore_main_loop_quit(); } static void -_send_cmd_finish(struct _App *app EINA_UNUSED) +_send_cmd_str(App *app, const char *str) { - pthread_mutex_unlock(&_mutex_fd); + int len; + + len = str ? strlen(str) + 1 : 0; + if (app->fd_write) + if (!ecore_pipe_write(app->fd_write, &len, sizeof(len))) + ecore_main_loop_quit(); + if (app->fd_write) + if (!ecore_pipe_write(app->fd_write, str, len)) + ecore_main_loop_quit(); } static void -_send_cmd(struct _App *app, int cmd) +_send_file_closed(App *app) { - _send_cmd_start(app, cmd); - _send_cmd_finish(app); + app->closing = 0; + emotion_generic_shm_free(app->vs); + _send_cmd(app, EM_RESULT_FILE_CLOSE); } static void -_send_cmd_str(struct _App *app, const char *str) +_send_time_changed(struct _App *app, const struct libvlc_event_t *ev) { - int len; - if (str) - len = strlen(str) + 1; - else - len = 0; - _em_write_safe(app->em_write, &len, sizeof(len)); - _em_write_safe(app->em_write, str, len); -} + float new_time = ev->u.media_player_time_changed.new_time; -#define SEND_CMD_PARAM(app, i) \ - _em_write_safe((app)->em_write, &(i), sizeof((i))); + new_time /= 1000; + if (app->vs->frame_drop > 1) + return; + _send_cmd(app, EM_RESULT_POSITION_CHANGED); + SEND_CMD_PARAM(app, new_time); +} static void _send_resize(struct _App *app, int width, int height) { - _send_cmd_start(app, EM_RESULT_FRAME_SIZE); + _send_cmd(app, EM_RESULT_FRAME_SIZE); SEND_CMD_PARAM(app, width); SEND_CMD_PARAM(app, height); - _send_cmd_finish(app); } static void -_send_length_changed(struct _App *app, const struct libvlc_event_t *ev) +_send_track_info(struct _App *app, int cmd, int current, int count, libvlc_track_description_t *desc) { - float length = ev->u.media_player_length_changed.new_length; - length /= 1000; - - _send_cmd_start(app, EM_RESULT_LENGTH_CHANGED); - SEND_CMD_PARAM(app, length); - _send_cmd_finish(app); + _send_cmd(app, cmd); + SEND_CMD_PARAM(app, current); + SEND_CMD_PARAM(app, count); + while (desc) + { + int tid = desc->i_id; + const char *name = desc->psz_name; + SEND_CMD_PARAM(app, tid); + _send_cmd_str(app, name); + desc = desc->p_next; + } } static void -_send_time_changed(struct _App *app, const struct libvlc_event_t *ev) +_send_all_track_info(struct _App *app) { - float new_time = ev->u.media_player_time_changed.new_time; - new_time /= 1000; - if (app->vs->frame_drop > 1) - return; - _send_cmd_start(app, EM_RESULT_POSITION_CHANGED); - SEND_CMD_PARAM(app, new_time); - _send_cmd_finish(app); -} + int track_count, current; + libvlc_track_description_t *desc; -static void -_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(app, EM_RESULT_SEEKABLE_CHANGED); - SEND_CMD_PARAM(app, seekable); - _send_cmd_finish(app); -} + current = libvlc_audio_get_track(app->mp); + track_count = libvlc_audio_get_track_count(app->mp); + desc = libvlc_audio_get_track_description(app->mp); -static void * -_lock(void *data, void **pixels) -{ - struct _App *app = data; + _send_track_info(app, EM_RESULT_AUDIO_TRACK_INFO, + current, track_count, desc); - if (app->playing) - *pixels = app->vf.frames[app->vs->frame.player]; - else - *pixels = NULL; + current = libvlc_video_get_track(app->mp); + track_count = libvlc_video_get_track_count(app->mp); + desc = libvlc_video_get_track_description(app->mp); - return NULL; // picture identifier, not needed here -} + _send_track_info(app, EM_RESULT_VIDEO_TRACK_INFO, + current, track_count, desc); -static void -_unlock(void *data EINA_UNUSED, void *id EINA_UNUSED, void *const *pixels EINA_UNUSED) -{ + current = libvlc_video_get_spu(app->mp); + track_count = libvlc_video_get_spu_count(app->mp); + desc = libvlc_video_get_spu_description(app->mp); + + _send_track_info(app, EM_RESULT_SPU_TRACK_INFO, + current, track_count, desc); } static void -_display(void *data, void *id EINA_UNUSED) +_send_all_meta_info(struct _App *app) { - struct _App *app = data; - if (!app->playing) - return; + const char *meta; - sem_wait(&app->vs->lock); - app->vs->frame.last = app->vs->frame.player; - app->vs->frame.player = app->vs->frame.next; - app->vs->frame.next = app->vs->frame.last; - if (!app->vs->frame_drop++) - _send_cmd(app, EM_RESULT_FRAME_NEW); - sem_post(&app->vs->lock); -} + _send_cmd(app, EM_RESULT_META_INFO); -static void * -_tmp_lock(void *data, void **pixels) -{ - struct _App *app = data; - *pixels = app->tmpbuffer; - return NULL; + /* + * Will send in this order: title, artist, album, year, + * genre, comments, disc id and track count. + */ + meta = libvlc_media_get_meta(app->m, libvlc_meta_Title); + _send_cmd_str(app, meta); + meta = libvlc_media_get_meta(app->m, libvlc_meta_Artist); + _send_cmd_str(app, meta); + meta = libvlc_media_get_meta(app->m, libvlc_meta_Album); + _send_cmd_str(app, meta); + meta = libvlc_media_get_meta(app->m, libvlc_meta_Date); + _send_cmd_str(app, meta); + meta = libvlc_media_get_meta(app->m, libvlc_meta_Genre); + _send_cmd_str(app, meta); + meta = NULL; // sending empty comments + _send_cmd_str(app, meta); + meta = NULL; // sending empty disc id + _send_cmd_str(app, meta); + meta = libvlc_media_get_meta(app->m, libvlc_meta_TrackNumber); + _send_cmd_str(app, meta); } -static void -_tmp_unlock(void *data EINA_UNUSED, void *id EINA_UNUSED, void *const *pixels EINA_UNUSED) +static Eina_Bool +_loaded_idler(void *data) { -} + App *app = data; -static void -_tmp_display(void *data EINA_UNUSED, void *id EINA_UNUSED) -{ + if (app->mp) + libvlc_media_player_stop(app->mp); + + return EINA_FALSE; } static void -_play(struct _App *app) +_position_changed(App *app) { - float pos; + int r; + unsigned int w, h; - if (!app->mp) + if (!app->opening) return; - _em_read_safe(app->em_read, &pos, sizeof(pos)); - - if (app->playing) + /* sending size info only once */ + r = libvlc_video_get_size(app->mp, 0, &w, &h); + if (r < 0) { - libvlc_media_player_set_pause(app->mp, 0); + w = 1; + h = 1; } - else + + if (w > 0 || h > 0) { - libvlc_time_t new_time = pos * 1000; - libvlc_media_player_set_time(app->mp, new_time); - libvlc_media_player_play(app->mp); + _send_resize(app, w, h); + app->size_sent = 1; + } - if (app->subtitle_path) - libvlc_video_set_subtitle_file(app->mp, app->subtitle_path); + /* sending audio track info */ + _send_all_track_info(app); - app->playing = 1; - } + /* sending meta info */ + _send_all_meta_info(app); + + ecore_idler_add(_loaded_idler, app); } static void -_stop(struct _App *app) +_send_length_changed(struct _App *app, const struct libvlc_event_t *ev) { - if (app->mp) - libvlc_media_player_set_pause(app->mp, 1); + float length = ev->u.media_player_length_changed.new_length; + length /= 1000; + + _send_cmd(app, EM_RESULT_LENGTH_CHANGED); + SEND_CMD_PARAM(app, length); } static void -_send_file_closed(struct _App *app) +_send_seekable_changed(struct _App *app, const struct libvlc_event_t *ev) { - app->closing = 0; - emotion_generic_shm_free(app->vs); - _send_cmd(app, EM_RESULT_FILE_CLOSE); + int seekable = ev->u.media_player_seekable_changed.new_seekable; + + _send_cmd(app, EM_RESULT_SEEKABLE_CHANGED); + SEND_CMD_PARAM(app, seekable); } static void @@ -356,16 +276,15 @@ _send_file_set(struct _App *app) static void _event_cb(const struct libvlc_event_t *ev, void *data) { - struct _App *app = data; - int thread_event; + App *app = data; + ecore_thread_main_loop_begin(); switch (ev->type) { case libvlc_MediaPlayerTimeChanged: - _send_time_changed(app, 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)); + _position_changed(app); break; case libvlc_MediaPlayerLengthChanged: _send_length_changed(app, ev); @@ -375,37 +294,40 @@ _event_cb(const struct libvlc_event_t *ev, void *data) break; case libvlc_MediaPlayerPlaying: _send_resize(app, app->w, app->h); - thread_event = EM_THREAD_PLAYBACK_STARTED; - write(app->fd_write, &thread_event, sizeof(thread_event)); + _send_cmd(app, EM_RESULT_PLAYBACK_STARTED); break; case libvlc_MediaPlayerStopped: _send_file_set(app); break; case libvlc_MediaPlayerEndReached: - thread_event = EM_THREAD_PLAYBACK_STOPPED; - write(app->fd_write, &thread_event, sizeof(thread_event)); + app->playing = 0; + _send_cmd(app, EM_RESULT_PLAYBACK_STOPPED); break; } + ecore_thread_main_loop_end(); } -static void -_subtitle_set(struct _App *app) +static void * +_tmp_lock(void *data, void **pixels) { - _em_str_read(app->em_read, &app->subtitle_path); + App *app = data; + *pixels = app->tmpbuffer; + return NULL; } static void -_file_set(struct _App *app) +_tmp_unlock(void *data EINA_UNUSED, void *id EINA_UNUSED, void *const *pixels EINA_UNUSED) { - if (app->opening) - { - libvlc_media_release(app->m); - libvlc_media_player_release(app->mp); - free(app->filename); - } +} - _em_str_read(app->em_read, &app->filename); +static void +_tmp_display(void *data EINA_UNUSED, void *id EINA_UNUSED) +{ +} +static void +_file_set(App *app) +{ app->m = libvlc_media_new_path(app->libvlc, app->filename); if (!app->m) { @@ -436,92 +358,43 @@ _file_set(struct _App *app) libvlc_media_player_play(app->mp); } -static void -_position_set(struct _App *app) -{ - if (!app->mp) - return; - - float 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); -} - -static void -_speed_set(struct _App *app) +static void * +_lock(void *data, void **pixels) { - float rate; + App *app = data; - if (!app->mp) - return; - - _em_read_safe(app->em_read, &rate, sizeof(rate)); + if (app->playing) + *pixels = app->vf.frames[app->vs->frame.player]; + else + *pixels = NULL; - libvlc_media_player_set_rate(app->mp, rate); + return NULL; // picture identifier, not needed here } static void -_mute_set(struct _App *app) +_unlock(void *data EINA_UNUSED, void *id EINA_UNUSED, void *const *pixels EINA_UNUSED) { - int mute; - - if (!app->mp) - return; - - _em_read_safe(app->em_read, &mute, sizeof(mute)); - - libvlc_audio_set_mute(app->mp, mute); } static void -_volume_set(struct _App *app) +_display(void *data, void *id EINA_UNUSED) { - float volume; - int vol; + App *app = data; - if (!app->mp) + if (!app->playing) return; - _em_read_safe(app->em_read, &volume, sizeof(volume)); - vol = volume * 100; - - libvlc_audio_set_volume(app->mp, vol); -} - -static void -_spu_track_set(struct _App *app) -{ - int track; - - _em_read_safe(app->em_read, &track, sizeof(track)); - - libvlc_video_set_spu(app->mp, track); -} - -static void -_audio_track_set(struct _App *app) -{ - int track; - - _em_read_safe(app->em_read, &track, sizeof(track)); - - libvlc_audio_set_track(app->mp, track); -} - -static void -_video_track_set(struct _App *app) -{ - int track; - - _em_read_safe(app->em_read, &track, sizeof(track)); - - libvlc_video_set_track(app->mp, track); + eina_semaphore_lock(&app->vs->lock); + app->vs->frame.last = app->vs->frame.player; + app->vs->frame.player = app->vs->frame.next; + app->vs->frame.next = app->vs->frame.last; + if (!app->vs->frame_drop++) + _send_cmd(app, EM_RESULT_FRAME_NEW); + eina_semaphore_release(&app->vs->lock, 1); } static void -_file_set_done(struct _App *app) +_file_set_done(App *app) { int r; @@ -536,9 +409,9 @@ _file_set_done(struct _App *app) app->filename = NULL; app->m = NULL; app->mp = NULL; - _send_cmd_start(app, EM_RESULT_FILE_SET_DONE); + + _send_cmd(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; @@ -559,13 +432,12 @@ _file_set_done(struct _App *app) libvlc_audio_set_mute(app->mp, 0); - _send_cmd_start(app, EM_RESULT_FILE_SET_DONE); + _send_cmd(app, EM_RESULT_FILE_SET_DONE); SEND_CMD_PARAM(app, r); - _send_cmd_finish(app); } static void -_file_close(struct _App *app) +_file_close(App *app) { app->playing = 0; if (app->opening) @@ -592,194 +464,225 @@ release_resources: } static void -_process_emotion_commands(struct _App *app) +_stop(App *app) { - int cmd = _em_cmd_read(app); - switch (cmd) { - case EM_CMD_FILE_SET: - _file_set(app); - break; - case EM_CMD_FILE_SET_DONE: - _file_set_done(app); - break; - case EM_CMD_SUBTITLE_SET: - _subtitle_set(app); - break; - case EM_CMD_FILE_CLOSE: - _file_close(app); - break; - case EM_CMD_PLAY: - _play(app); - break; - case EM_CMD_STOP: - _stop(app); - break; - case EM_CMD_POSITION_SET: - _position_set(app); - break; - case EM_CMD_SPEED_SET: - _speed_set(app); - break; - case EM_CMD_AUDIO_MUTE_SET: - _mute_set(app); - break; - case EM_CMD_VOLUME_SET: - _volume_set(app); - break; - case EM_CMD_SPU_TRACK_SET: - _spu_track_set(app); - break; - case EM_CMD_AUDIO_TRACK_SET: - _audio_track_set(app); - break; - case EM_CMD_VIDEO_TRACK_SET: - _video_track_set(app); - break; - }; + if (app->mp) + libvlc_media_player_set_pause(app->mp, 1); } static void -_send_track_info(struct _App *app, int cmd, int current, int count, libvlc_track_description_t *desc) +_play(App *app, float pos) { - _send_cmd_start(app, cmd); - SEND_CMD_PARAM(app, current); - SEND_CMD_PARAM(app, count); - while (desc) + if (!app->mp) + return; + + if (app->playing) { - int tid = desc->i_id; - const char *name = desc->psz_name; - SEND_CMD_PARAM(app, tid); - _send_cmd_str(app, name); - desc = desc->p_next; + libvlc_media_player_set_pause(app->mp, 0); + } + else + { + libvlc_time_t new_time = pos * 1000; + libvlc_media_player_set_time(app->mp, new_time); + libvlc_media_player_play(app->mp); + + if (app->subtitle_path) + libvlc_video_set_subtitle_file(app->mp, app->subtitle_path); + + app->playing = 1; } - _send_cmd_finish(app); } static void -_send_all_track_info(struct _App *app) +_position_set(struct _App *app, float position) { - int track_count, current; - libvlc_track_description_t *desc; + libvlc_time_t new_time; - 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_track_info(app, EM_RESULT_AUDIO_TRACK_INFO, - current, track_count, desc); - - current = libvlc_video_get_track(app->mp); - track_count = libvlc_video_get_track_count(app->mp); - desc = libvlc_video_get_track_description(app->mp); + if (!app->mp) + return; - _send_track_info(app, EM_RESULT_VIDEO_TRACK_INFO, - current, track_count, desc); + new_time = position * 1000; + libvlc_media_player_set_time(app->mp, new_time); +} - current = libvlc_video_get_spu(app->mp); - track_count = libvlc_video_get_spu_count(app->mp); - desc = libvlc_video_get_spu_description(app->mp); +static void +_speed_set(App *app, float rate) +{ + if (!app->mp) + return; - _send_track_info(app, EM_RESULT_SPU_TRACK_INFO, - current, track_count, desc); + libvlc_media_player_set_rate(app->mp, rate); } static void -_send_all_meta_info(struct _App *app) +_mute_set(App *app, int mute) { - const char *meta; - - _send_cmd_start(app, EM_RESULT_META_INFO); + if (!app->mp) + return; - /* - * Will send in this order: title, artist, album, year, - * genre, comments, disc id and track count. - */ - meta = libvlc_media_get_meta(app->m, libvlc_meta_Title); - _send_cmd_str(app, meta); - meta = libvlc_media_get_meta(app->m, libvlc_meta_Artist); - _send_cmd_str(app, meta); - meta = libvlc_media_get_meta(app->m, libvlc_meta_Album); - _send_cmd_str(app, meta); - meta = libvlc_media_get_meta(app->m, libvlc_meta_Date); - _send_cmd_str(app, meta); - meta = libvlc_media_get_meta(app->m, libvlc_meta_Genre); - _send_cmd_str(app, meta); - meta = NULL; // sending empty comments - _send_cmd_str(app, meta); - meta = NULL; // sending empty disc id - _send_cmd_str(app, meta); - meta = libvlc_media_get_meta(app->m, libvlc_meta_TrackNumber); - _send_cmd_str(app, meta); - _send_cmd_finish(app); + libvlc_audio_set_mute(app->mp, mute); } static void -_position_changed(struct _App *app) +_volume_set(App *app, float volume) { - if (!app->opening) + int vol; + + if (!app->mp) return; - /* sending size info only once */ - int r; - unsigned int w, h; - r = libvlc_video_get_size(app->mp, 0, &w, &h); - if (r < 0) - { - w = 1; - h = 1; - } + vol = volume * 100; - if (w > 0 || h > 0) - { - _send_resize(app, w, h); - app->size_sent = 1; - } + libvlc_audio_set_volume(app->mp, vol); +} - /* sending audio track info */ - _send_all_track_info(app); +static void +_spu_track_set(App *app, int track) +{ + libvlc_video_set_spu(app->mp, track); +} - /* sending meta info */ - _send_all_meta_info(app); +static void +_audio_track_set(App *app, int track) +{ + libvlc_audio_set_track(app->mp, track); +} - if (app->size_sent) - libvlc_media_player_stop(app->mp); +static void +_video_track_set(App *app, int track) +{ + libvlc_video_set_track(app->mp, track); } static void -_process_thread_events(struct _App *app) +_remote_command(void *data, void *buffer, unsigned int nbyte) { - int event; - size_t size; + App *app = data; - size = read(app->fd_read, &event, sizeof(event)); - if (size != sizeof(event)) + if (nbyte == 0) { - ERR("player: problem when reading thread event. size = %zd", size); - return; + fprintf(stderr, "death is comming\n"); + ecore_main_loop_quit(); + return ; } - switch (event) { - case EM_THREAD_POSITION_CHANGED: - _position_changed(app); - break; - case EM_THREAD_PLAYBACK_STARTED: - _send_cmd(app, EM_RESULT_PLAYBACK_STARTED); - break; - case EM_THREAD_PLAYBACK_STOPPED: - app->playing = 0; - _send_cmd(app, EM_RESULT_PLAYBACK_STOPPED); - break; - } + if (app->last_order == EM_CMD_LAST) + { + if (nbyte != sizeof (int)) + { + ERR("didn't receive a valid command from emotion (%i) !", nbyte); + ecore_main_loop_quit(); + return ; + } + + app->last_order = *((int*) buffer); + + if (!app->inited && + app->last_order != EM_CMD_INIT) + { + ERR("wrong init command!"); + ecore_main_loop_quit(); + return ; + } + + switch (app->last_order) + { + case EM_CMD_FILE_SET: + if (app->opening) + { + libvlc_media_release(app->m); + libvlc_media_player_release(app->mp); + free(app->filename); + app->opening = 0; + } + break; + case EM_CMD_FILE_SET_DONE: + _file_set_done(app); + app->last_order = EM_CMD_LAST; + break; + case EM_CMD_FILE_CLOSE: + _file_close(app); + app->last_order = EM_CMD_LAST; + break; + } + } + else + { + switch (app->last_order) + { + case EM_CMD_INIT: + app->shmname = strdup(buffer); + app->inited = EINA_TRUE; + _send_cmd(app, EM_RESULT_INIT); + break; + case EM_CMD_FILE_SET: + app->filename = strdup(buffer); + _file_set(app); + break; + case EM_CMD_SUBTITLE_SET: + app->subtitle_path = strdup(buffer); + break; + case EM_CMD_PLAY: + _play(app, *(float*) buffer); + break; + case EM_CMD_STOP: + _stop(app); + break; + case EM_CMD_POSITION_SET: + _position_set(app, *(float*) buffer); + break; + case EM_CMD_SPEED_SET: + _speed_set(app, *(float*) buffer); + break; + case EM_CMD_AUDIO_MUTE_SET: + _mute_set(app, *(int*) buffer); + break; + case EM_CMD_VOLUME_SET: + _volume_set(app, *(float*) buffer); + break; + case EM_CMD_SPU_TRACK_SET: + _spu_track_set(app, *(int*) buffer); + break; + case EM_CMD_AUDIO_TRACK_SET: + _audio_track_set(app, *(int*) buffer); + break; + case EM_CMD_VIDEO_TRACK_SET: + _video_track_set(app, *(int*) buffer); + break; + } + app->last_order = EM_CMD_LAST; + } +} + +void +_dummy(void *data EINA_UNUSED, void *buffer EINA_UNUSED, unsigned int nbyte EINA_UNUSED) +{ + /* This function is useless for the pipe we use to send message back to emotion, + but still needed */ } int main(int argc, const char *argv[]) { - struct _App app; - struct pollfd fds[3]; - int tpipe[2]; // pipe for comunicating events from threads + App app; + Ecore_Event_Handler *hld; char cwidth[64], cheight[64], cpitch[64], chroma[64]; - char buf[64]; + int vlc_argc; + + const char *vlc_argv[] = + { + "--quiet", + "--vout", + "vmem", + "--vmem-width", + cwidth, + "--vmem-height", + cheight, + "--vmem-pitch", + cpitch, + "--vmem-chroma", + chroma + }; if (!eina_init()) { @@ -798,21 +701,6 @@ main(int argc, const char *argv[]) if (!eina_log_domain_level_check(_em_vlc_log_dom, EINA_LOG_LEVEL_WARN)) eina_log_domain_level_set("emotion_generic_vlc", EINA_LOG_LEVEL_WARN); - const char *vlc_argv[] = - { - "--quiet", - "--vout", - "vmem", - "--vmem-width", - cwidth, - "--vmem-height", - cheight, - "--vmem-pitch", - cpitch, - "--vmem-chroma", - chroma - }; - if (argc < 3) { ERR("missing parameters."); @@ -820,25 +708,20 @@ main(int argc, const char *argv[]) goto error; } - app.em_read = atoi(argv[1]); - app.em_write = atoi(argv[2]); + ecore_init(); - int vlc_argc = sizeof(vlc_argv) / sizeof(*vlc_argv); + app.fd_read = ecore_pipe_full_add(_remote_command, &app, + atoi(argv[1]), -1, EINA_FALSE, EINA_FALSE); + app.fd_write = ecore_pipe_full_add(_dummy, NULL, + -1, atoi(argv[2]), EINA_FALSE, EINA_FALSE); + + vlc_argc = sizeof(vlc_argv) / sizeof(*vlc_argv); snprintf(cwidth, sizeof(cwidth), "%d", DEFAULTWIDTH); snprintf(cheight, sizeof(cheight), "%d", DEFAULTHEIGHT); snprintf(cpitch, sizeof(cpitch), "%d", DEFAULTWIDTH * 4); snprintf(chroma, sizeof(chroma), "RV32"); - /* - * Naughty xattr in emotion uses ecore_thread to run its thing, this - * may leave emotion's reference count high and it won't kill us... - * letting us play the video in the background. not good. - * - * prctl(PR_SET_PDEATHSIG) is a linux only thing. Need to find ways - * to do it on other platforms. Until then leave it breaking on - * such platforms so people port it instead of ignoring. - */ - prctl(PR_SET_PDEATHSIG, SIGHUP); + hld = ecore_event_handler_add(ECORE_EVENT_SIGNAL_HUP, exit_func, NULL); app.libvlc = libvlc_new(vlc_argc, vlc_argv); app.mp = NULL; @@ -850,63 +733,18 @@ main(int argc, const char *argv[]) app.opening = 0; app.playing = 0; app.closing = 0; + app.last_order = EM_CMD_LAST; + app.inited = EINA_FALSE; - if (_em_cmd_read(&app) != EM_CMD_INIT) - { - ERR("wrong init command!"); - goto error; - } - - int size; - _em_read_safe(app.em_read, &size, sizeof(size)); - _em_read_safe(app.em_read, buf, size); - app.shmname = strdup(buf); + ecore_main_loop_begin(); - _send_cmd(&app, EM_RESULT_INIT); + libvlc_release(app.libvlc); - pipe(tpipe); - app.fd_read = tpipe[0]; - app.fd_write = tpipe[1]; - fds[0].fd = app.em_read; - fds[0].events = POLLIN; - fds[1].fd = app.fd_read; - fds[1].events = POLLIN; - fds[2].fd = STDERR_FILENO; - fds[2].events = 0; + ecore_event_handler_del(hld); - while (1) - { - int r; - - r = poll(fds, 3, -1); - if (r == 0) - continue; - else if (r < 0) - { - ERR("an error ocurred on poll(): %s", strerror(errno)); - break; - } - - if (fds[0].revents & (POLLERR | POLLHUP | POLLNVAL)) - { - ERR("error communicating with stdin"); - break; - } - if (fds[1].revents & (POLLERR | POLLHUP | POLLNVAL)) - { - ERR("error communicating with thread"); - break; - } - - if (fds[0].revents & POLLIN) - _process_emotion_commands(&app); - if (fds[1].revents & POLLIN) - _process_thread_events(&app); - if (fds[2].revents & (POLLERR | POLLHUP | POLLNVAL)) - break; - } + ecore_shutdown(); + eina_shutdown(); - libvlc_release(app.libvlc); return 0; error: -- cgit v1.2.1