playermgr: make event loop for getting player callback 00/45000/1 accepted/tizen/tv/20150731.005327 submit/tizen/20150730.133424
authorMinkyu Kang <mk7.kang@samsung.com>
Thu, 30 Jul 2015 09:37:30 +0000 (18:37 +0900)
committerMinkyu Kang <mk7.kang@samsung.com>
Thu, 30 Jul 2015 09:37:30 +0000 (18:37 +0900)
Since callback of player is called from another thread,
we can't use efl object that is made from main thread.
(EFL can't guarantee thread safe)
The main thread check the events list(for callback) periodically,
and call real callback when get the events.

Change-Id: Ia24754c78ad5dd751e174e6c69273ec35aaea652
Signed-off-by: Minkyu Kang <mk7.kang@samsung.com>
include/util/progressbar.h
src/util/playermgr.c
src/util/progressbar.c
src/view/mplayer.c
src/view/viewer.c

index b788a3c..884761e 100644 (file)
@@ -22,7 +22,6 @@ struct progressbar;
 struct progressbar_ops {
        int (*get_value)(void *data);
        int (*set_value)(void *data);
-       void (*complete_cb)(void *data);
 };
 
 enum progressbar_time_format {
index 4cd046a..320ceb7 100644 (file)
 
 #include "define.h"
 
+#define EVENT_INTERVAL 0.1
+
+struct _player_cb {
+       void (*func)(void *data);
+       void *data;
+};
+
 struct playermgr {
        Evas_Object *win;
+       Ecore_Timer *event_loop;
+       Eina_List *cb_list;
        player_h player;
        char *path;
+       struct _player_cb complete_cb;
 };
 
+static Eina_Bool _event_cb(void *data)
+{
+       struct playermgr *m;
+       struct _player_cb *cb;
+       Eina_List *l;
+
+       if (!data)
+               return ECORE_CALLBACK_CANCEL;
+
+       m = data;
+
+       if (!eina_list_count(m->cb_list))
+               return ECORE_CALLBACK_RENEW;
+
+       EINA_LIST_FOREACH(m->cb_list, l, cb) {
+               if (cb && cb->func)
+                       cb->func(cb->data);
+       }
+
+       m->cb_list = eina_list_free(m->cb_list);
+
+       return ECORE_CALLBACK_RENEW;
+}
+
+static void _event_loop_stop(struct playermgr *m)
+{
+       ecore_timer_del(m->event_loop);
+       m->event_loop = NULL;
+}
+
+static void _event_loop_start(struct playermgr *m)
+{
+       if (m->event_loop)
+               ecore_timer_reset(m->event_loop);
+       else
+               m->event_loop = ecore_timer_add(EVENT_INTERVAL, _event_cb, m);
+}
+
+static void _player_complete_cb(void *data)
+{
+       struct playermgr *m;
+
+       if (!data)
+               return;
+
+       m = data;
+
+       m->cb_list = eina_list_append(m->cb_list, &m->complete_cb);
+}
+
 static void _set_path(struct playermgr *m, const char *path)
 {
        free(m->path);
@@ -137,9 +197,12 @@ bool playermgr_pause(struct playermgr *m)
        r = player_pause(m->player);
        if (r != PLAYER_ERROR_NONE) {
                _ERR("player: pause error (%d)", r);
+               _event_loop_stop(m);
                return false;
        }
 
+       _event_loop_stop(m);
+
        return true;
 }
 
@@ -163,6 +226,8 @@ bool playermgr_resume(struct playermgr *m)
                return false;
        }
 
+       _event_loop_start(m);
+
        return true;
 }
 
@@ -178,6 +243,7 @@ void playermgr_stop(struct playermgr *m)
        player_unprepare(m->player);
 
        _set_path(m, NULL);
+       _event_loop_stop(m);
 }
 
 bool playermgr_play(struct playermgr *m, const char *path, int ms)
@@ -235,6 +301,8 @@ bool playermgr_play(struct playermgr *m, const char *path, int ms)
                }
        }
 
+       _event_loop_start(m);
+
        return true;
 }
 
@@ -243,12 +311,15 @@ bool playermgr_set_completed_cb(struct playermgr *m,
 {
        int r;
 
-       r = player_set_completed_cb(m->player, cb, data);
+       r = player_set_completed_cb(m->player, _player_complete_cb, m);
        if (r != PLAYER_ERROR_NONE) {
                _ERR("player: set callback error (%d)", r);
                return false;
        }
 
+       m->complete_cb.func = cb;
+       m->complete_cb.data = data;
+
        return true;
 }
 
@@ -272,6 +343,7 @@ struct playermgr *playermgr_create(Evas_Object *win)
 
        m->win = win;
        m->path = NULL;
+       m->event_loop = NULL;
 
        return m;
 }
@@ -283,6 +355,10 @@ void playermgr_destroy(struct playermgr *m)
                return;
        }
 
+       _event_loop_stop(m);
+
+       eina_list_free(m->cb_list);
+
        if (m->player) {
                playermgr_stop(m);
                player_destroy(m->player);
index ec1512c..ec38fda 100644 (file)
@@ -26,8 +26,6 @@
 #define SLIDER_STEP 0.03
 
 #define PROGRESSBAR_INTERVAL 0.1
-#define COMPLETE_INTERVAL 1.0
-#define COMPLETE_BUFFER 500
 
 struct progressbar {
        Evas_Object *base;
@@ -67,21 +65,6 @@ static void _update_time_info(struct progressbar *m, int position, int duration)
        _update_progress_info(m, position);
 }
 
-static Eina_Bool _complete_cb(void *data)
-{
-       struct progressbar *m;
-
-       if (!data)
-               return ECORE_CALLBACK_CANCEL;
-
-       m = data;
-
-       if (m->ops->complete_cb)
-               m->ops->complete_cb(m->ops_data);
-
-       return ECORE_CALLBACK_CANCEL;
-}
-
 static Eina_Bool _timer_cb(void *data)
 {
        struct progressbar *m;
@@ -97,13 +80,6 @@ static Eina_Bool _timer_cb(void *data)
        elm_slider_value_set(m->slider, position);
        _update_progress_info(m, position);
 
-       if (position + COMPLETE_BUFFER > m->duration) {
-               ecore_timer_add(COMPLETE_INTERVAL, _complete_cb, m);
-               m->timer = NULL;
-
-               return ECORE_CALLBACK_CANCEL;
-       }
-
        return ECORE_CALLBACK_RENEW;
 }
 
index 24f129d..3f3f9d5 100644 (file)
@@ -416,7 +416,6 @@ static void _player_complete_cb(void *data)
 
 static struct progressbar_ops _progressbar_ops = {
        .get_value = _player_get_position,
-       .complete_cb = _player_complete_cb,
 };
 
 static void _callback_music(void *data, const char *ev)
@@ -751,6 +750,13 @@ static Evas_Object *_create(Evas_Object *win, void *data)
                return NULL;
        }
 
+       r = playermgr_set_completed_cb(player, _player_complete_cb, priv);
+       if (!r) {
+               _ERR("failed to set callback");
+               playermgr_destroy(player);
+               return NULL;
+       }
+
        priv->player = player;
 
        r = _ui_init(priv);
index 351b82b..1d658fa 100644 (file)
@@ -768,7 +768,6 @@ static void _player_complete_cb(void *data)
 
 static struct progressbar_ops _progressbar_ops = {
        .get_value = _player_get_position,
-       .complete_cb = _player_complete_cb,
 };
 
 static void _callback_movie(void *data, const char *ev)
@@ -908,6 +907,13 @@ static Evas_Object *_create(Evas_Object *win, void *data)
                return NULL;
        }
 
+       r = playermgr_set_completed_cb(player, _player_complete_cb, priv);
+       if (!r) {
+               _ERR("failed to set callback");
+               playermgr_destroy(player);
+               return NULL;
+       }
+
        priv->player = player;
 
        r = _ui_init(priv);