emotion: use better infra for reading GstBus.
authorcedric <cedric@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Tue, 2 Aug 2011 14:04:08 +0000 (14:04 +0000)
committercedric <cedric@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Tue, 2 Aug 2011 14:04:08 +0000 (14:04 +0000)
git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/emotion@61999 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

src/modules/gstreamer/emotion_alloc.c
src/modules/gstreamer/emotion_gstreamer.c
src/modules/gstreamer/emotion_gstreamer.h

index da98ac9..2736fb1 100644 (file)
@@ -30,3 +30,25 @@ emotion_gstreamer_buffer_free(Emotion_Gstreamer_Buffer *send)
    gst_buffer_unref(send->frame);
    free(send);
 }
+
+Emotion_Gstreamer_Message *
+emotion_gstreamer_message_alloc(Emotion_Gstreamer_Video *ev,
+                               GstMessage *msg)
+{
+   Emotion_Gstreamer_Message *send;
+
+   send = malloc(sizeof (Emotion_Gstreamer_Message));
+   if (!send) return NULL;
+
+   send->ev = ev;
+   send->msg = gst_message_ref(msg);
+
+   return send;
+}
+
+void
+emotion_gstreamer_message_free(Emotion_Gstreamer_Message *send)
+{
+   gst_message_unref(send->msg);
+   free(send);
+}
index f398b7e..e58532b 100644 (file)
@@ -10,7 +10,6 @@
 int _emotion_gstreamer_log_domain = -1;
 
 /* Callbacks to get the eos */
-static Eina_Bool  _eos_timer_fct   (void *data);
 static void _for_each_tag    (GstTagList const* list, gchar const* tag, void *data);
 static void _free_metadata   (Emotion_Gstreamer_Metadata *m);
 
@@ -167,6 +166,10 @@ static int            em_eject                    (void             *video);
 static const char    *em_meta_get                 (void             *video,
                                                    int               meta);
 
+static GstBusSyncReply _eos_sync_fct(GstBus *bus,
+                                    GstMessage *message,
+                                    gpointer data);
+
 /* Module interface */
 
 static Emotion_Video_Module em_module =
@@ -418,6 +421,8 @@ em_file_open(const char   *file,
    if (!ev->pipeline)
      return EINA_FALSE;
 
+   eina_threads_init();
+
    start = ecore_time_get();
    ev->eos_bus = gst_pipeline_get_bus(GST_PIPELINE(ev->pipeline));
    if (!ev->eos_bus)
@@ -428,6 +433,8 @@ em_file_open(const char   *file,
    end = ecore_time_get();
    DBG("Get the bus: %f", end - start);
 
+   gst_bus_set_sync_handler(ev->eos_bus, _eos_sync_fct, ev);
+
    /* Evas Object */
    ev->obj = obj;
 
@@ -675,7 +682,12 @@ em_file_open(const char   *file,
    em_audio_channel_volume_set(ev, ev->volume);
    em_audio_channel_mute_set(ev, ev->audio_mute);
 
-   _eos_timer_fct(ev);
+   if (ev->play_started)
+     {
+        _emotion_playback_started(ev->obj);
+        ev->play_started = 0;
+     }
+
    _emotion_open_done(ev->obj);
    end = ecore_time_get();
    DBG("Last stuff: %f", end - start);
@@ -690,7 +702,6 @@ em_file_close(void *video)
    Emotion_Audio_Stream *astream;
    Emotion_Video_Stream *vstream;
 
-   fprintf(stderr, "close\n");
    ev = (Emotion_Gstreamer_Video *)video;
    if (!ev)
      return;
@@ -708,6 +719,8 @@ em_file_close(void *video)
         ev->pipeline = NULL;
      }
 
+   eina_threads_shutdown();
+
    /* we clear the stream lists */
    EINA_LIST_FREE(ev->audio_streams, astream)
      free(astream);
@@ -715,12 +728,6 @@ em_file_close(void *video)
      free(vstream);
 
    /* shutdown eos */
-   if (ev->eos_timer)
-     {
-        ecore_timer_del(ev->eos_timer);
-        ev->eos_timer = NULL;
-     }
-
    if (ev->metadata)
      {
         _free_metadata(ev->metadata);
@@ -740,9 +747,6 @@ em_play(void   *video,
    gst_element_set_state(ev->pipeline, GST_STATE_PLAYING);
    ev->play = 1;
    ev->play_started = 1;
-
-   /* eos */
-   ev->eos_timer = ecore_timer_add(0.1, _eos_timer_fct, ev);
 }
 
 static void
@@ -753,14 +757,7 @@ em_stop(void *video)
    ev = (Emotion_Gstreamer_Video *)video;
 
    if (!ev->pipeline) return ;
-
-   /* shutdown eos */
-   if (ev->eos_timer)
-     {
-        ecore_timer_del(ev->eos_timer);
-        ev->eos_timer = NULL;
-     }
-
    gst_element_set_state(ev->pipeline, GST_STATE_PAUSED);
    ev->play = 0;
 }
@@ -1601,66 +1598,93 @@ _free_metadata(Emotion_Gstreamer_Metadata *m)
   free(m);
 }
 
-static Eina_Bool
-_eos_timer_fct(void *data)
+static void
+_eos_main_fct(void *data)
 {
+   Emotion_Gstreamer_Message *send;
    Emotion_Gstreamer_Video *ev;
    GstMessage              *msg;
 
-   ev = (Emotion_Gstreamer_Video *)data;
+   send = data;
+   ev = send->ev;
+   msg = send->msg;
+
    if (ev->play_started)
      {
         _emotion_playback_started(ev->obj);
         ev->play_started = 0;
      }
-   while ((msg = gst_bus_poll(ev->eos_bus, GST_MESSAGE_ERROR | GST_MESSAGE_EOS | GST_MESSAGE_TAG | GST_MESSAGE_ASYNC_DONE, 0)))
+
+   switch (GST_MESSAGE_TYPE(msg))
      {
-        switch (GST_MESSAGE_TYPE(msg))
-          {
-           case GST_MESSAGE_ERROR:
-                {
-                   gchar *debug;
-                   GError *err;
-
-                   gst_message_parse_error(msg, &err, &debug);
-                   g_free(debug);
-
-                   ERR("Error: %s", err->message);
-                   g_error_free(err);
-
-                   break;
-                }
-           case GST_MESSAGE_EOS:
-              if (ev->eos_timer)
-                {
-                   ecore_timer_del(ev->eos_timer);
-                   ev->eos_timer = NULL;
-                }
-              ev->play = 0;
-              _emotion_decode_stop(ev->obj);
-              _emotion_playback_finished(ev->obj);
-              break;
-           case GST_MESSAGE_TAG:
-                {
-                   GstTagList *new_tags;
-                   gst_message_parse_tag(msg, &new_tags);
-                   if (new_tags)
-                     {
-                        gst_tag_list_foreach(new_tags, (GstTagForeachFunc)_for_each_tag, ev);
-                        gst_tag_list_free(new_tags);
-                     }
-                   break;
-                }
-           case GST_MESSAGE_ASYNC_DONE:
-              _emotion_seek_done(ev->obj);
-              break;
-           default:
-              ERR("bus say: %s [%i]",
-                  GST_MESSAGE_SRC_NAME(msg),
-                  GST_MESSAGE_TYPE(msg));
-              break;
-          }
-        gst_message_unref(msg);
+      case GST_MESSAGE_ERROR:
+        {
+           gchar *debug;
+           GError *err;
+
+           gst_message_parse_error(msg, &err, &debug);
+           g_free(debug);
+
+           ERR("Error: %s", err->message);
+           g_error_free(err);
+
+           break;
+        }
+      case GST_MESSAGE_EOS:
+         ev->play = 0;
+         _emotion_decode_stop(ev->obj);
+         _emotion_playback_finished(ev->obj);
+         break;
+      case GST_MESSAGE_TAG:
+        {
+           GstTagList *new_tags;
+           gst_message_parse_tag(msg, &new_tags);
+           if (new_tags)
+             {
+                gst_tag_list_foreach(new_tags,
+                                     (GstTagForeachFunc)_for_each_tag,
+                                     ev);
+                gst_tag_list_free(new_tags);
+             }
+           break;
+        }
+      case GST_MESSAGE_ASYNC_DONE:
+         _emotion_seek_done(ev->obj);
+         break;
+      default:
+         ERR("bus say: %s [%i]",
+             GST_MESSAGE_SRC_NAME(msg),
+             GST_MESSAGE_TYPE(msg));
+         break;
      }
-   return EINA_TRUE;
+
+   emotion_gstreamer_message_free(send);
+}
+
+static GstBusSyncReply
+_eos_sync_fct(GstBus *bus, GstMessage *msg, gpointer data)
+{
+   Emotion_Gstreamer_Video *ev = data;
+   Emotion_Gstreamer_Message *send;
+
+   switch (GST_MESSAGE_TYPE(msg))
+     {
+      case GST_MESSAGE_ERROR:
+      case GST_MESSAGE_EOS:
+      case GST_MESSAGE_TAG:
+      case GST_MESSAGE_ASYNC_DONE:
+         send = emotion_gstreamer_message_alloc(ev, msg);
+
+         if (send) ecore_main_loop_thread_safe_call(_eos_main_fct, send);
+
+         break;
+
+      default:
+         WRN("bus say: %s [%i]",
+             GST_MESSAGE_SRC_NAME(msg),
+             GST_MESSAGE_TYPE(msg));
+         break;
+     }
+
+   return GST_BUS_DROP;
 }
index edb34b4..bab3306 100644 (file)
@@ -22,6 +22,7 @@ typedef struct _Emotion_Gstreamer_Video Emotion_Gstreamer_Video;
 typedef struct _Emotion_Audio_Stream Emotion_Audio_Stream;
 typedef struct _Emotion_Gstreamer_Metadata Emotion_Gstreamer_Metadata;
 typedef struct _Emotion_Gstreamer_Buffer Emotion_Gstreamer_Buffer;
+typedef struct _Emotion_Gstreamer_Message Emotion_Gstreamer_Message;
 typedef struct _Emotion_Video_Stream Emotion_Video_Stream;
 
 struct _Emotion_Video_Stream
@@ -61,7 +62,6 @@ struct _Emotion_Gstreamer_Video
 
    /* eos */
    GstBus           *eos_bus;
-   Ecore_Timer      *eos_timer;
 
    /* Strams */
    Eina_List        *video_streams;
@@ -138,6 +138,13 @@ struct _Emotion_Gstreamer_Buffer
    Eina_Bool preroll : 1;
 };
 
+struct _Emotion_Gstreamer_Message
+{
+   Emotion_Gstreamer_Video *ev;
+
+   GstMessage *msg;
+};
+
 extern int _emotion_gstreamer_log_domain;
 #define DBG(...) EINA_LOG_DOM_DBG(_emotion_gstreamer_log_domain, __VA_ARGS__)
 #define INF(...) EINA_LOG_DOM_INFO(_emotion_gstreamer_log_domain, __VA_ARGS__)
@@ -177,4 +184,9 @@ Emotion_Gstreamer_Buffer *emotion_gstreamer_buffer_alloc(EvasVideoSinkPrivate *s
                                                          GstBuffer *buffer,
                                                          Eina_Bool preroll);
 void emotion_gstreamer_buffer_free(Emotion_Gstreamer_Buffer *send);
+
+Emotion_Gstreamer_Message *emotion_gstreamer_message_alloc(Emotion_Gstreamer_Video *ev,
+                                                           GstMessage *msg);
+void emotion_gstreamer_message_free(Emotion_Gstreamer_Message *send);
+
 #endif /* __EMOTION_GSTREAMER_H__ */