Add the synchronization between Ui and Video player 72/236672/22
authorWonsik Jung <sidein@samsung.com>
Fri, 19 Jun 2020 07:37:02 +0000 (16:37 +0900)
committerWonsik Jung <sidein@samsung.com>
Thu, 23 Jul 2020 10:58:02 +0000 (19:58 +0900)
This patch is to support the synchronization between video player and UI.
To do that, video player's changing function as resize/move should be called before calling eglSwapBuffers.

Change-Id: I46f050339d0bdf4512f0983f6f0166511c08d272

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

index 7081f2d..54d6cad 100755 (executable)
@@ -27,7 +27,7 @@
 // INTERNAL INCLUDES
 
 // The plugin factories
-extern "C" DALI_EXPORT_API Dali::VideoPlayerPlugin* CreateVideoPlayerPlugin( void )
+extern "C" DALI_EXPORT_API Dali::VideoPlayerPlugin* CreateVideoPlayerPlugin( Dali::Actor actor, Dali::VideoSyncMode syncMode )
 {
   return new Dali::Plugin::TizenVideoPlayer;
 }
@@ -216,7 +216,7 @@ void LogPlayerError( int error )
 
 } // unnamed namespace
 
-TizenVideoPlayer::TizenVideoPlayer()
+TizenVideoPlayer::TizenVideoPlayer( Dali::Actor actor, Dali::VideoSyncMode syncMode )
 : mUrl(),
   mPlayer( NULL ),
   mPlayerState( PLAYER_STATE_NONE ),
@@ -229,7 +229,6 @@ TizenVideoPlayer::TizenVideoPlayer()
   mPacketMutex(),
   mPacketVector(),
   mEcoreWlWindow( NULL ),
-  mAlphaBitChanged( false ),
   mStreamInfo( NULL ),
   mStreamType( SOUND_STREAM_TYPE_MEDIA ),
   mCodecType( PLAYER_VIDEO_CODEC_TYPE_EX_DEFAULT )
@@ -548,12 +547,6 @@ void TizenVideoPlayer::InitializeTextureStreamMode( Dali::NativeImageSourcePtr n
 
   mNativeImageSourcePtr = nativeImageSourcePtr;
 
-  if( mAlphaBitChanged )
-  {
-    ecore_wl_window_alpha_set( mEcoreWlWindow, false );
-    mAlphaBitChanged = false;
-  }
-
   if( mPlayerState == PLAYER_STATE_NONE )
   {
     error = player_create( &mPlayer );
index e50c464..a02e4da 100755 (executable)
@@ -23,6 +23,7 @@
 #include <dali/public-api/adaptor-framework/timer.h>
 #include <dali/public-api/adaptor-framework/native-image-source.h>
 #include <dali/devel-api/adaptor-framework/video-player-plugin.h>
+#include <dali/devel-api/adaptor-framework/video-sync-mode.h>
 #include <player.h>
 #include <string>
 
@@ -58,9 +59,8 @@ public:
 
   /**
    * @brief Constructor.
-   * @SINCE_1_1.38
    */
-  TizenVideoPlayer();
+  TizenVideoPlayer( Dali::Actor actor, Dali::VideoSyncMode syncMode );
 
   /**
    * @brief Destructor.
@@ -252,8 +252,6 @@ private:
 
   Ecore_Wl_Window* mEcoreWlWindow;
 
-  bool mAlphaBitChanged; ///< True if underlay rendering initialization changes window alpha
-
   sound_stream_info_h mStreamInfo;
   sound_stream_type_e mStreamType;
 
index 8f01d8b..9fa07ca 100755 (executable)
@@ -27,9 +27,9 @@
 // INTERNAL INCLUDES
 
 // The plugin factories
-extern "C" DALI_EXPORT_API Dali::VideoPlayerPlugin* CreateVideoPlayerPlugin( void )
+extern "C" DALI_EXPORT_API Dali::VideoPlayerPlugin* CreateVideoPlayerPlugin( Dali::Actor actor, Dali::VideoSyncMode syncMode )
 {
-  return new Dali::Plugin::TizenVideoPlayer;
+  return new Dali::Plugin::TizenVideoPlayer( actor, syncMode );
 }
 
 extern "C" DALI_EXPORT_API void DestroyVideoPlayerPlugin( Dali::VideoPlayerPlugin* plugin )
@@ -39,7 +39,6 @@ extern "C" DALI_EXPORT_API void DestroyVideoPlayerPlugin( Dali::VideoPlayerPlugi
     delete plugin;
   }
 }
-
 namespace Dali
 {
 
@@ -214,9 +213,47 @@ void LogPlayerError( int error )
   }
 }
 
+const char* const VIDEO_PLAYER_SIZE_NAME("videoPlayerSize");
+
+struct VideoPlayerSyncConstraint
+{
+public :
+  VideoPlayerSyncConstraint( Ecore_Wl2_Window* ecoreWlWindow, int screenWidth, int screenHeight )
+  {
+    mEcoreWlWindow = ecoreWlWindow;
+    mHalfScreenWidth = static_cast< float >( screenWidth )/2;
+    mHalfScreenHeight = static_cast< float >( screenHeight )/2;
+  }
+
+  void operator()( Vector3& current, const PropertyInputContainer& inputs )
+  {
+   const Vector3& size = inputs[0]->GetVector3();
+   const Vector3& worldScale = inputs[1]->GetVector3();
+   const Vector3& worldPosition = inputs[2]->GetVector3();
+
+   Vector3 actorSize = size * worldScale;
+   Vector2 screenPosition( mHalfScreenWidth + worldPosition.x, mHalfScreenHeight + worldPosition.y);
+
+   DisplayArea area;
+   area.x = screenPosition.x - actorSize.x/2;
+   area.y = screenPosition.y - actorSize.y/2;
+   area.width = actorSize.x;
+   area.height = actorSize.y;
+
+   if( mEcoreWlWindow )
+   {
+     ecore_wl2_window_video_surface_destination_set( mEcoreWlWindow, area.x, area.y, area.width, area.height );
+   }
+  }
+private :
+  Ecore_Wl2_Window*  mEcoreWlWindow;
+  float              mHalfScreenWidth;
+  float              mHalfScreenHeight;
+};
+
 } // unnamed namespace
 
-TizenVideoPlayer::TizenVideoPlayer()
+TizenVideoPlayer::TizenVideoPlayer( Dali::Actor actor, Dali::VideoSyncMode syncMode )
 : mUrl(),
   mPlayer( NULL ),
   mPlayerState( PLAYER_STATE_NONE ),
@@ -228,16 +265,27 @@ TizenVideoPlayer::TizenVideoPlayer()
   mTargetType( NativeImage ),
   mPacketMutex(),
   mPacketVector(),
-  mEcoreWlWindow( NULL ),
-  mAlphaBitChanged( false ),
   mStreamInfo( NULL ),
   mStreamType( SOUND_STREAM_TYPE_MEDIA ),
-  mCodecType( PLAYER_VIDEO_CODEC_TYPE_EX_DEFAULT )
+  mCodecType( PLAYER_VIDEO_CODEC_TYPE_EX_DEFAULT ),
+  mEcoreWlWindow( nullptr ),
+  mSyncActor( actor ),
+  mVideoSizePropertyIndex( Property::INVALID_INDEX ),
+  mSyncMode( syncMode )
 {
 }
 
 TizenVideoPlayer::~TizenVideoPlayer()
 {
+  DestroyConstraint();
+  if( mEcoreWlWindow )
+  {
+    if( ecore_wl2_window_video_surface_get( mEcoreWlWindow) )
+    {
+      ecore_wl2_window_video_surface_destroy( mEcoreWlWindow );
+    }
+  }
+
   DestroyPlayer();
 }
 
@@ -283,8 +331,25 @@ void TizenVideoPlayer::SetUrl( const std::string& url )
         Ecore_Wl2_Display *wl2_display = ecore_wl2_connected_display_get(NULL);
         ecore_wl2_display_screen_size_get( wl2_display, &width, &height );
 
-        error = player_set_ecore_wl_display( mPlayer, PLAYER_DISPLAY_TYPE_OVERLAY, mEcoreWlWindow, 0, 0, width, height );
-        LogPlayerError( error );
+        if( mSyncMode == Dali::VideoSyncMode::ENABLED )
+        {
+          DALI_LOG_RELEASE_INFO(" SetUrl: desync VideoPlayer\n" );
+          if( !ecore_wl2_window_video_surface_sync_set( mEcoreWlWindow, EINA_FALSE ) )
+          {
+            DALI_LOG_ERROR("SetUrl, fail to ecore_wl2_window_video_surface_sync_set\n");
+          }
+          if( !ecore_wl2_window_video_surface_destination_set( mEcoreWlWindow, 0, 0, width, height ) )
+          {
+            DALI_LOG_ERROR("SetUrl, fail to ecore_wl2_window_video_surface_destination_set()\n");
+          }
+          error = player_set_display( mPlayer, PLAYER_DISPLAY_TYPE_OVERLAY, mEcoreWlWindow );
+          LogPlayerError( error );
+        }
+        else
+        {
+          error = player_set_ecore_wl_display( mPlayer, PLAYER_DISPLAY_TYPE_OVERLAY, mEcoreWlWindow, 0, 0, width, height );
+          LogPlayerError( error );
+        }
       }
       GetPlayerState( &mPlayerState );
       LogPlayerError( error );
@@ -311,10 +376,13 @@ void TizenVideoPlayer::SetRenderingTarget( Any target )
   DestroyPlayer();
 
   mNativeImageSourcePtr = NULL;
-  mEcoreWlWindow = NULL;
 
   if( target.GetType() == typeid( Dali::NativeImageSourcePtr ) )
   {
+    if( mSyncMode == Dali::VideoSyncMode::ENABLED )
+    {
+      DestroyConstraint();
+    }
     mTargetType = TizenVideoPlayer::NativeImage;
 
     Dali::NativeImageSourcePtr nativeImageSourcePtr = AnyCast< Dali::NativeImageSourcePtr >( target );
@@ -325,8 +393,12 @@ void TizenVideoPlayer::SetRenderingTarget( Any target )
   {
     mTargetType = TizenVideoPlayer::WindowSurface;
 
-    Ecore_Wl2_Window* nativeWindow = Dali::AnyCast< Ecore_Wl2_Window* >( target );
-    InitializeUnderlayMode( nativeWindow );
+    InitializeUnderlayMode( Dali::AnyCast< Ecore_Wl2_Window* >( target ) );
+
+    if( mSyncMode == Dali::VideoSyncMode::ENABLED )
+    {
+      CreateConstraint();
+    }
   }
   else
   {
@@ -547,12 +619,6 @@ void TizenVideoPlayer::InitializeTextureStreamMode( Dali::NativeImageSourcePtr n
 
   mNativeImageSourcePtr = nativeImageSourcePtr;
 
-  if( mAlphaBitChanged )
-  {
-    ecore_wl2_window_alpha_set( mEcoreWlWindow, false );
-    mAlphaBitChanged = false;
-  }
-
   if( mPlayerState == PLAYER_STATE_NONE )
   {
     error = player_create( &mPlayer );
@@ -602,7 +668,31 @@ void TizenVideoPlayer::InitializeUnderlayMode( Ecore_Wl2_Window* ecoreWlWindow )
   }
 
   GetPlayerState( &mPlayerState );
-  mEcoreWlWindow = ecoreWlWindow;
+  if( mSyncMode == Dali::VideoSyncMode::ENABLED )
+  {
+    if( mEcoreWlWindow != ecoreWlWindow )
+    {
+      //check previous video subsurface and destroy
+      if( mEcoreWlWindow )
+      {
+        if( ecore_wl2_window_video_surface_get( mEcoreWlWindow) )
+        {
+          ecore_wl2_window_video_surface_destroy( mEcoreWlWindow );
+        }
+      }
+      mEcoreWlWindow = ecoreWlWindow;
+      // create video subsurface
+      if( !ecore_wl2_window_video_surface_create( mEcoreWlWindow ) )
+      {
+        DALI_LOG_ERROR("InitializeUnderlayMode : fail to ecore_wl2_window_video_surface_create()\n");
+        return;
+      }
+    }
+  }
+  else
+  {
+    mEcoreWlWindow = ecoreWlWindow;
+  }
 
   if( mPlayerState == PLAYER_STATE_IDLE )
   {
@@ -615,21 +705,40 @@ void TizenVideoPlayer::InitializeUnderlayMode( Ecore_Wl2_Window* ecoreWlWindow )
     error = player_set_sound_stream_info( mPlayer, mStreamInfo );
     LogPlayerError( error );
 
-    error = player_set_display_mode( mPlayer, PLAYER_DISPLAY_MODE_DST_ROI );
-    LogPlayerError( error );
-
-    error = player_set_display_roi_area( mPlayer, 0, 0, 1, 1 );
-    LogPlayerError( error );
-
     error = player_set_video_codec_type_ex( mPlayer, mCodecType );
     LogPlayerError( error );
 
     int width, height;
-    Ecore_Wl2_Display *wl2_display = ecore_wl2_connected_display_get(NULL);
+    Ecore_Wl2_Display *wl2_display = ecore_wl2_connected_display_get( NULL );
     ecore_wl2_display_screen_size_get( wl2_display, &width, &height );
     ecore_wl2_window_alpha_set( mEcoreWlWindow, false );
-    error = player_set_ecore_wl_display( mPlayer, PLAYER_DISPLAY_TYPE_OVERLAY, mEcoreWlWindow, 0, 0, width, height );
-    LogPlayerError( error );
+
+    if( mSyncMode == Dali::VideoSyncMode::ENABLED )
+    {
+      DALI_LOG_RELEASE_INFO( "InitializeUnderlayMode, desync VideoPlayer\n" );
+      if( !ecore_wl2_window_video_surface_sync_set( mEcoreWlWindow, EINA_FALSE ) )
+      {
+        DALI_LOG_ERROR("InitializeUnderlayMode, fail to ecore_wl2_window_video_surface_sync_set\n");
+      }
+
+      if( !ecore_wl2_window_video_surface_destination_set( mEcoreWlWindow, 0, 0, width, height ) )
+      {
+        DALI_LOG_ERROR("InitializeUnderlayMode, fail to ecore_wl2_window_video_surface_destination_set()\n");
+      }
+      error = player_set_display( mPlayer, PLAYER_DISPLAY_TYPE_OVERLAY, mEcoreWlWindow );
+      LogPlayerError( error );
+    }
+    else
+    {
+      error = player_set_display_mode( mPlayer, PLAYER_DISPLAY_MODE_DST_ROI );
+      LogPlayerError( error );
+
+      error = player_set_display_roi_area( mPlayer, 0, 0, 1, 1 );
+      LogPlayerError( error );
+
+      error = player_set_ecore_wl_display( mPlayer, PLAYER_DISPLAY_TYPE_OVERLAY, mEcoreWlWindow, 0, 0, width, height );
+      LogPlayerError( error );
+    }
 
     error = player_set_display_visible( mPlayer, true );
     LogPlayerError( error );
@@ -718,14 +827,22 @@ void TizenVideoPlayer::SetDisplayArea( DisplayArea area )
   if( mPlayerState == PLAYER_STATE_IDLE ||
       mPlayerState == PLAYER_STATE_READY ||
       mPlayerState == PLAYER_STATE_PLAYING ||
-      mPlayerState == PLAYER_STATE_PAUSED
-
-  )
+      mPlayerState == PLAYER_STATE_PAUSED  )
   {
     area.x = ( area.x < 0 ) ? 0: area.x;
     area.y = ( area.y < 0 ) ? 0: area.y;
-    int error = player_set_display_roi_area( mPlayer, area.x, area.y, area.width, area.height );
-    LogPlayerError( error );
+    if( mSyncMode == Dali::VideoSyncMode::ENABLED )
+    {
+      if( !ecore_wl2_window_video_surface_destination_set( mEcoreWlWindow, area.x, area.y, area.width, area.height) )
+      {
+        DALI_LOG_ERROR("SetDisplayArea, fail to ecore_wl2_window_video_surface_destination_set()\n");
+      }
+    }
+    else
+    {
+      int error = player_set_display_roi_area( mPlayer, area.x, area.y, area.width, area.height );
+      LogPlayerError( error );
+    }
   }
 }
 
@@ -909,5 +1026,60 @@ Any TizenVideoPlayer::GetMediaPlayer()
    return Any( ( void* ) mPlayer );
 }
 
+void TizenVideoPlayer::StartSynchronization()
+{
+  DALI_LOG_RELEASE_INFO( "sync VideoPlayer\n" );
+  if( !ecore_wl2_window_video_surface_sync_set( mEcoreWlWindow, EINA_TRUE ) )
+  {
+    DALI_LOG_ERROR("StartSynchronization, fail to ecore_wl2_window_video_surface_sync_set\n");
+  }
+}
+
+void TizenVideoPlayer::FinishSynchronization()
+{
+  // Finish
+  DALI_LOG_RELEASE_INFO( "desync VideoPlayer\n" );
+  if( !ecore_wl2_window_video_surface_sync_set( mEcoreWlWindow, EINA_FALSE ) )
+  {
+    DALI_LOG_ERROR("FinishSynchronization, fail to ecore_wl2_window_video_surface_sync_set\n");
+  }
+}
+
+void TizenVideoPlayer::CreateConstraint()
+{
+  if( mVideoSizePropertyIndex == Property::INVALID_INDEX )
+  {
+    if( mVideoSizePropertyConstraint )
+    {
+      mVideoSizePropertyConstraint.Remove();
+    }
+
+    mVideoSizePropertyIndex = mSyncActor.RegisterProperty( VIDEO_PLAYER_SIZE_NAME, Vector3::ZERO );
+
+    int width, height;
+    Ecore_Wl2_Display *wl2_display = ecore_wl2_connected_display_get( NULL );
+    ecore_wl2_display_screen_size_get( wl2_display, &width, &height );
+
+    mVideoSizePropertyConstraint = Constraint::New< Vector3 >( mSyncActor,
+                                                               mVideoSizePropertyIndex,
+                                                               VideoPlayerSyncConstraint( mEcoreWlWindow, width, height ) );
+
+    mVideoSizePropertyConstraint.AddSource( LocalSource( Actor::Property::SIZE ) );
+    mVideoSizePropertyConstraint.AddSource( LocalSource( Actor::Property::WORLD_SCALE ) );
+    mVideoSizePropertyConstraint.AddSource( LocalSource( Actor::Property::WORLD_POSITION ) );
+
+    mVideoSizePropertyConstraint.Apply();
+  }
+}
+
+void TizenVideoPlayer::DestroyConstraint()
+{
+  if( mVideoSizePropertyIndex != Property::INVALID_INDEX  )
+  {
+    mVideoSizePropertyConstraint.Remove();
+    mVideoSizePropertyIndex = Property::INVALID_INDEX;
+  }
+}
+
 } // namespace Plugin
 } // namespace Dali;
index 04cc00f..b66d830 100755 (executable)
 // EXTERNAL INCLUDES
 #include <dali/devel-api/threading/mutex.h>
 #include <dali/public-api/adaptor-framework/timer.h>
+#include <dali/public-api/animation/constraints.h>
 #include <dali/public-api/adaptor-framework/native-image-source.h>
 #include <dali/devel-api/adaptor-framework/video-player-plugin.h>
+#include <dali/devel-api/adaptor-framework/video-sync-mode.h>
 #include <player.h>
 #include <string>
 
@@ -58,9 +60,8 @@ public:
 
   /**
    * @brief Constructor.
-   * @SINCE_1_1.38
    */
-  TizenVideoPlayer();
+  TizenVideoPlayer( Dali::Actor actor, Dali::VideoSyncMode syncMode );
 
   /**
    * @brief Destructor.
@@ -203,6 +204,16 @@ public:
    */
   Any GetMediaPlayer();
 
+  /**
+   * @copydoc Dali::VideoPlayerPlugin::StartSynchronization()
+   */
+  void StartSynchronization();
+
+  /**
+   * @copydoc Dali::VideoPlayerPlugin::FinishSynchronization()
+   */
+  void FinishSynchronization();
+
 private:
 
   /**
@@ -235,6 +246,16 @@ private:
    */
   void DestroyPlayer();
 
+  /**
+   * @brief Create Constraint for synchronization
+   */
+  void CreateConstraint();
+
+  /**
+   * @brief Destroy Constraint for synchronization
+   */
+  void DestroyConstraint();
+
 private:
 
   std::string mUrl; ///< The video file path
@@ -250,14 +271,17 @@ private:
   Dali::Mutex mPacketMutex;
   Dali::Vector< media_packet_h > mPacketVector; ///< Container for media packet handle from Tizen player callback
 
-  Ecore_Wl2_Window* mEcoreWlWindow;
-
-  bool mAlphaBitChanged; ///< True if underlay rendering initialization changes window alpha
-
   sound_stream_info_h mStreamInfo;
   sound_stream_type_e mStreamType;
 
   player_video_codec_type_ex_e mCodecType;
+
+  Ecore_Wl2_Window*                              mEcoreWlWindow;
+  Actor                                          mSyncActor;
+  Constraint                                     mVideoSizePropertyConstraint;
+  Property::Index                                mVideoSizePropertyIndex;
+  Dali::VideoSyncMode                            mSyncMode;
+
 public:
 
   Dali::VideoPlayerPlugin::VideoPlayerSignalType mFinishedSignal;