ethumb: make plugin API fully assynchronous and use it in emotion backend.
authorCedric BAIL <cedric.bail@free.fr>
Wed, 28 Dec 2011 16:10:10 +0000 (16:10 +0000)
committerCedric BAIL <cedric.bail@free.fr>
Wed, 28 Dec 2011 16:10:10 +0000 (16:10 +0000)
NOTE: epdf isn't asynchronous at the moment, so no need to fix its ethumb plugin.

SVN revision: 66607

legacy/ethumb/src/lib/Ethumb_Plugin.h
legacy/ethumb/src/lib/ethumb.c
legacy/ethumb/src/lib/ethumb_private.h
legacy/ethumb/src/plugins/emotion/emotion.c
legacy/ethumb/src/plugins/epdf/epdf.c

index 6dda23b..3eb6f02 100644 (file)
@@ -10,7 +10,8 @@ typedef struct _Ethumb_Plugin Ethumb_Plugin;
 struct _Ethumb_Plugin
 {
    const char **extensions;
-   void (*generate_thumb)(Ethumb *);
+   void *(*thumb_generate)(Ethumb *);
+   void (*thumb_cancel)(Ethumb *, void *);
 };
 
 EAPI void ethumb_calculate_aspect_from_ratio(Ethumb *e, float ia, int *w, int *h);
index ecabe9c..c097fbe 100644 (file)
@@ -1185,7 +1185,8 @@ _ethumb_plugin_generate(Ethumb *e)
    else
      evas_object_hide(e->img);
 
-   plugin->generate_thumb(e);
+   e->plugin = plugin;
+   e->pdata = plugin->thumb_generate(e);
 
    return EINA_TRUE;
 }
@@ -1519,6 +1520,8 @@ ethumb_finished_callback_call(Ethumb *e, int result)
    if (e->finished_idler)
      ecore_idler_del(e->finished_idler);
    e->finished_idler = ecore_idler_add(_ethumb_finished_idler_cb, e);
+   e->plugin = NULL;
+   e->pdata = NULL;
 }
 
 EAPI Eina_Bool
@@ -1537,6 +1540,13 @@ ethumb_generate(Ethumb *e, Ethumb_Generate_Cb finished_cb, const void *data, Ein
        ERR("thumbnail generation already in progress.");
        return EINA_FALSE;
      }
+   if (e->pdata)
+     {
+        e->plugin->thumb_cancel(e, e->pdata);
+        e->pdata = NULL;
+        e->plugin = NULL;
+     }
+
    e->finished_cb = finished_cb;
    e->cb_data = (void *)data;
    e->cb_data_free = free_data;
@@ -1549,9 +1559,9 @@ ethumb_generate(Ethumb *e, Ethumb_Generate_Cb finished_cb, const void *data, Ein
      }
 
    r = _ethumb_plugin_generate(e);
+   fprintf(stderr, "ethumb generate: %i: %p\n", r, e->pdata);
    if (r)
      {
-        ethumb_finished_callback_call(e, r);
         return EINA_TRUE;
      }
 
@@ -1688,6 +1698,8 @@ ethumb_dup(const Ethumb *e)
    r->cb_data = NULL;
    r->cb_data_free = NULL;
    r->cb_result = 0;
+   r->plugin = NULL;
+   r->pdata = NULL;
 
    return r;
 }
index 25f2cd3..49e4de9 100644 (file)
@@ -2,6 +2,7 @@
 #define __ETHUMB_PRIVATE_H__ 1
 
 #include <Ethumb.h>
+#include <Ethumb_Plugin.h>
 
 typedef struct _Ethumb_Frame Ethumb_Frame;
 
@@ -48,6 +49,9 @@ struct _Ethumb
    void *cb_data;
    Eina_Free_Cb cb_data_free;
    int cb_result;
+
+   void *pdata;
+   Ethumb_Plugin *plugin;
 };
 
 #endif /* __ETHUMB_PRIVATE_H__ */
index 71918cc..560e661 100644 (file)
@@ -38,6 +38,9 @@ struct _emotion_plugin
    int w, h;
 };
 
+static Eina_Bool _frame_grab(void *data);
+static Eina_Bool _frame_grab_single(void *data);
+
 static void
 _resize_movie(struct _emotion_plugin *_plugin)
 {
@@ -62,6 +65,17 @@ _resize_movie(struct _emotion_plugin *_plugin)
 }
 
 static void
+_frame_decode_cb(void *data, Evas_Object *o __UNUSED__, void *event_info __UNUSED__)
+{
+   struct _emotion_plugin *_plugin = data;
+
+   if (_plugin->ef)
+     _frame_grab(data);
+   else
+     _frame_grab_single(data);
+}
+
+static void
 _frame_resized_cb(void *data, Evas_Object *o __UNUSED__, void *event_info __UNUSED__)
 {
    _resize_movie(data);
@@ -168,6 +182,8 @@ _finish_thumb_generation(struct _emotion_plugin *_plugin, int success)
    int r = 0;
    evas_object_smart_callback_del(_plugin->video, "frame_resize",
                                  _frame_resized_cb);
+   evas_object_smart_callback_del(_plugin->video, "frame_decode",
+                                 _frame_decode_cb);
    emotion_object_play_set(_plugin->video, 0);
    evas_object_del(_plugin->video);
    if (_plugin->ef)
@@ -207,7 +223,7 @@ _frame_grab_single(void *data)
    emotion_object_play_set(_plugin->video, 0);
    evas_object_del(_plugin->video);
    free(_plugin);
-   
+
    ethumb_finished_callback_call(e, 1);
 
    return EINA_FALSE;
@@ -294,12 +310,10 @@ _generate_animated_thumb(struct _emotion_plugin *_plugin)
        fprintf(stderr, "ERROR: could not open '%s'\n", thumb_path);
        _finish_thumb_generation(_plugin, 0);
      }
-
-   ecore_timer_add(1.0 / ethumb_video_fps_get(e), _frame_grab, _plugin);
 }
 
-static void
-_generate_thumb(Ethumb *e)
+static void *
+_thumb_generate(Ethumb *e)
 {
    Evas_Object *o;
    int r;
@@ -308,7 +322,7 @@ _generate_thumb(Ethumb *e)
    struct _emotion_plugin *_plugin = calloc(sizeof(struct _emotion_plugin), 1);
 
    o = emotion_object_add(ethumb_evas_get(e));
-   r = emotion_object_init(o, "xine");
+   r = emotion_object_init(o, NULL);
    if (!r)
      {
        fprintf(stderr, "ERROR: could not start emotion using gstreamer"
@@ -316,7 +330,7 @@ _generate_thumb(Ethumb *e)
        evas_object_del(o);
        ethumb_finished_callback_call(e, 0);
        free(_plugin);
-       return;
+       return NULL;
      }
 
    _plugin->video = o;
@@ -334,6 +348,8 @@ _generate_thumb(Ethumb *e)
    _plugin->pcount = 1;
 
    _resize_movie(_plugin);
+   evas_object_smart_callback_add(o, "frame_decode",
+                                 _frame_decode_cb, _plugin);
    evas_object_smart_callback_add(o, "frame_resize",
                                  _frame_resized_cb, _plugin);
    evas_object_smart_callback_add(o, "decode_stop",
@@ -343,14 +359,22 @@ _generate_thumb(Ethumb *e)
      {
        _generate_animated_thumb(_plugin);
      }
-   else
-     {
-       ecore_timer_add(0.1, _frame_grab_single, _plugin);
-     }
 
    _video_pos_set(_plugin);
    emotion_object_play_set(o, 1);
    evas_object_show(o);
+
+   return _plugin;
+}
+
+static void
+_thumb_cancel(Ethumb *e __UNUSED__, void *data)
+{
+   struct _emotion_plugin *_plugin = data;
+
+   if (_plugin->ef) eet_close(_plugin->ef);
+   evas_object_del(_plugin->video);
+   free(_plugin);
 }
 
 EAPI Ethumb_Plugin *
@@ -361,7 +385,8 @@ ethumb_plugin_get(void)
    static Ethumb_Plugin plugin =
      {
        extensions,
-       _generate_thumb,
+       _thumb_generate,
+       _thumb_cancel
      };
 
    _log_dom = eina_log_domain_register("ethumb_emotion", EINA_COLOR_GREEN);
index 82e3b8c..62234a9 100644 (file)
@@ -76,6 +76,7 @@ ethumb_plugin_get(void)
      {
        extensions,
        _generate_thumb,
+       NULL /* This plugin is not assynchronous so not possible to cancel it at all */
      };
 
    return &plugin;