[Tizen] Post FinishedSignal to UIThead 30/286430/1 accepted/tizen/7.0/unified/20230111.174850 accepted/tizen/7.0/unified/20230118.093800 accepted/tizen/7.0/unified/20230203.164145 accepted/tizen/7.0/unified/20230213.171734 accepted/tizen/7.0/unified/20230327.042631 accepted/tizen/7.0/unified/20230403.235601 accepted/tizen/7.0/unified/20230404.033734
authorDaekwang Ryu <dkdk.ryu@samsung.com>
Mon, 26 Dec 2022 06:34:56 +0000 (15:34 +0900)
committerDaekwang Ryu <dkdk.ryu@samsung.com>
Fri, 6 Jan 2023 01:20:20 +0000 (10:20 +0900)
When UI thread feature was enabled, there was a bug.
The signal was emitted on the main thread from the MMFW.
Then Dali caused an assertion because the timer was stopped on the main thread.
The signal has to be invoked on the same thread as the adaptor's

Change-Id: I421969181683cddcc15dc5ee37ab5c0daa0ea5d1

dali-extension/video-player/ecore-wl2/tizen-video-player-ecore-wl2.cpp

index db9ab94..a96ca8d 100755 (executable)
@@ -61,6 +61,22 @@ static void MediaPacketVideoDecodedCb(media_packet_h packet, void* user_data)
   player->PushPacket(packet);
 }
 
+static GMainContext* GetTizenGlibContext()
+{
+  static GMainContext* context = nullptr;
+
+  if(!context)
+  {
+    const char* env = getenv("TIZEN_GLIB_CONTEXT");
+    if(env)
+    {
+      context = (GMainContext*)strtoul(env, nullptr, 10);
+    }
+  }
+
+  return context;
+}
+
 static void EmitPlaybackFinishedSignal(void* user_data)
 {
   TizenVideoPlayer* player = static_cast<TizenVideoPlayer*>(user_data);
@@ -73,11 +89,36 @@ static void EmitPlaybackFinishedSignal(void* user_data)
 
   if(!player->mFinishedSignal.Empty())
   {
-    DALI_LOG_ERROR("EmitPlaybackFinishedSignal.3\n");
-    player->mFinishedSignal.Emit();
+    DALI_LOG_ERROR("EmitPlaybackFinishedSignal.\n");
+
+    // This function is invoked on the main thread from MMFW.
+    // So the FinishedSignal has to be posted to UIThread when UIThread is enabled.
+    // If not, it causes an assertion in the timer.
+    // The timer has to run on the same thread as the adaptor's
+    GMainContext* context = GetTizenGlibContext();
+    if(context)
+    {
+      GSource* source = g_idle_source_new();
+      g_source_set_callback(
+        source,
+        [](gpointer userData) -> gboolean
+        {
+          auto* player = static_cast<TizenVideoPlayer*>(userData);
+          player->mFinishedSignal.Emit();
+          player->Stop();
+          return G_SOURCE_REMOVE;
+        },
+        player,
+        nullptr);
+      g_source_attach(source, context);
+      g_source_unref(source);
+    }
+    else
+    {
+      player->mFinishedSignal.Emit();
+      player->Stop();
+    }
   }
-
-  player->Stop();
 }
 
 // ToDo: VD player_set_play_position() doesn't work when callback pointer is NULL.
@@ -794,7 +835,7 @@ void TizenVideoPlayer::InitializeEnableSyncMode(Ecore_Wl2_Window* ecoreWlWindow)
   if(mEcoreWlWindow != ecoreWlWindow)
   {
     mEcoreWlWindow = ecoreWlWindow;
-    //check previous video subsurface and destroy
+    // check previous video subsurface and destroy
     if(mEcoreSubVideoWindow)
     {
       ecore_wl2_subsurface_del(mEcoreSubVideoWindow);