cedric pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=ca2f9571abf16670ac7c0d7c34d2221d97d5fffd

commit ca2f9571abf16670ac7c0d7c34d2221d97d5fffd
Author: Cedric BAIL <cedric.b...@samsung.com>
Date:   Fri Dec 13 12:44:19 2013 +0900

    emotion: make webcam initialization lazy and non blocking.
    
    This should fix T648.
---
 src/lib/emotion/emotion_webcam.c | 88 +++++++++++++++++++++++++++++++---------
 1 file changed, 68 insertions(+), 20 deletions(-)

diff --git a/src/lib/emotion/emotion_webcam.c b/src/lib/emotion/emotion_webcam.c
index 974a9a8..9a673d9 100644
--- a/src/lib/emotion/emotion_webcam.c
+++ b/src/lib/emotion/emotion_webcam.c
@@ -27,6 +27,11 @@ typedef struct _Emotion_Webcams Emotion_Webcams;
 struct _Emotion_Webcams
 {
    Eina_List *webcams;
+
+   Ecore_Idler *idler;
+   Eina_List *check_list;
+
+   Eina_Bool init;
 };
 
 struct _Emotion_Webcam
@@ -62,6 +67,7 @@ _emotion_webcams_edds_new(void)
    EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Emotion_Webcams);
    _webcams_edd = eet_data_descriptor_file_new(&eddc);
    EET_DATA_DESCRIPTOR_ADD_LIST(_webcams_edd, Emotion_Webcams, "webcams", 
webcams, _webcam_edd);
+   EET_DATA_DESCRIPTOR_ADD_BASIC(_webcam_edd, Emotion_Webcams, "init", init, 
EET_T_CHAR);
 
    return _webcams_edd;
 }
@@ -167,37 +173,64 @@ _emotion_webcam_new(const char *syspath)
 }
 
 static void
-_emotion_enumerate_all_webcams(void)
+_emotion_webcam_remove_cb(void *user_data, void *func_data EINA_UNUSED)
 {
-   Eina_List *devices;
-   const char *syspath;
+   Emotion_Webcam *webcam;
 
-   devices = eeze_udev_find_by_type(EEZE_UDEV_TYPE_V4L, NULL);
+   /* called at the end of EMOTION_WEBCAM_ADD event, to prevent the free */
+   if (!user_data)
+     return;
 
-   EINA_LIST_FREE(devices, syspath)
+   webcam = user_data;
+
+   EINA_REFCOUNT_UNREF(webcam)
+      emotion_webcam_destroy(webcam);
+}
+
+static Eina_Bool
+_emotion_process_webcam(void *data)
+{
+   Emotion_Webcams *webcams;
+   Emotion_Webcam *test;
+   const char *syspath;
+
+   webcams = data;
+   syspath = eina_list_data_get(webcams->check_list);
+   if (!syspath)
      {
-        Emotion_Webcam *test;
+       webcams->idler = NULL;
+       webcams->init = EINA_TRUE;
+       return EINA_FALSE;
+     }
 
-        test = _emotion_webcam_new(syspath);
-        if (test) _emotion_check_device(test);
+   webcams->check_list = eina_list_remove_list(webcams->check_list,
+                                              webcams->check_list);
 
-        eina_stringshare_del(syspath);
+   test = _emotion_webcam_new(syspath);
+   if (test)
+     {
+       if (_emotion_check_device(test))
+         ecore_event_add(EMOTION_WEBCAM_ADD, test, NULL, NULL);
+       else
+         _emotion_webcam_remove_cb(test, NULL);
      }
+
+   eina_stringshare_del(syspath);
+
+   return EINA_TRUE;
 }
 
 static void
-_emotion_webcam_remove_cb(void *user_data, void *func_data EINA_UNUSED)
+_emotion_enumerate_all_webcams(void)
 {
-   Emotion_Webcam *webcam;
-
-   /* called at the end of EMOTION_WEBCAM_ADD event, to prevent the free */
-   if (!user_data)
-     return;
+   Eina_List *devices;
 
-   webcam = user_data;
+   if (_emotion_webcams->init) return ;
+   devices = eeze_udev_find_by_type(EEZE_UDEV_TYPE_V4L, NULL);
 
-   EINA_REFCOUNT_UNREF(webcam)
-      emotion_webcam_destroy(webcam);
+   _emotion_webcams->check_list = devices;
+   _emotion_webcams->idler = ecore_idler_add(_emotion_process_webcam,
+                                            _emotion_webcams);
 }
 
 static void
@@ -257,8 +290,6 @@ Eina_Bool emotion_webcam_init(void)
 #ifdef HAVE_EEZE
    eeze_init();
 
-   _emotion_enumerate_all_webcams();
-
    eeze_watcher = eeze_udev_watch_add(EEZE_UDEV_TYPE_V4L,
                                       (EEZE_UDEV_EVENT_ADD | 
EEZE_UDEV_EVENT_REMOVE),
                                       _emotion_eeze_events, NULL);
@@ -271,6 +302,18 @@ void
 emotion_webcam_shutdown(void)
 {
    Emotion_Webcam *ew;
+   const char *syspath;
+
+   if (_emotion_webcams->idler)
+     {
+       ecore_idler_del(_emotion_webcams->idler);
+       _emotion_webcams->idler = NULL;
+     }
+
+   EINA_LIST_FREE(_emotion_webcams->check_list, syspath)
+     eina_stringshare_del(syspath);
+
+   _emotion_webcams->init = EINA_FALSE;
 
    EINA_LIST_FREE(_emotion_webcams->webcams, ew)
      {
@@ -329,6 +372,9 @@ EAPI const Eina_List *
 emotion_webcams_get(void)
 {
    EINA_SAFETY_ON_NULL_RETURN_VAL(_emotion_webcams, NULL);
+
+   _emotion_enumerate_all_webcams();
+
    return _emotion_webcams->webcams;
 }
 
@@ -354,6 +400,8 @@ emotion_webcam_custom_get(const char *device)
 
    EINA_SAFETY_ON_NULL_RETURN_VAL(_emotion_webcams, NULL);
 
+   _emotion_enumerate_all_webcams();
+
    EINA_LIST_FOREACH(_emotion_webcams->webcams, l, ew)
      if (ew->device && strcmp(device, ew->device) == 0)
        return ew->custom;

-- 


Reply via email to