Added video-player plugin 21/146821/5
authortaeyoon0.lee <taeyoon0.lee@samsung.com>
Wed, 30 Aug 2017 16:00:34 +0000 (01:00 +0900)
committerHeeyong Song <heeyong.song@samsung.com>
Fri, 1 Sep 2017 05:14:12 +0000 (05:14 +0000)
Change-Id: I8607a015079e08d7a90d9f58fff48be16487c159

build/tizen/Makefile.am
build/tizen/configure.ac
dali-extension/file.list
dali-extension/key/key-extension.cpp [moved from dali-extension/key-extension.cpp with 100% similarity]
dali-extension/key/key-extension.h [moved from dali-extension/key-extension.h with 100% similarity]
dali-extension/video-player/tizen-video-player.cpp [new file with mode: 0644]
dali-extension/video-player/tizen-video-player.h [new file with mode: 0644]
packaging/dali-extension.spec

index fb2735f..4ad3df7 100644 (file)
@@ -29,6 +29,9 @@ if USE_KEY_EXTENSION
 lib_LTLIBRARIES += libdali-key-extension.la
 endif
 
+lib_LTLIBRARIES += libdali-video-player-plugin.la
+
+# key extension
 libdali_key_extension_la_SOURCES = \
                        $(key_extension_src_files)
 libdali_key_extension_la_DEPENDENCIES =
@@ -48,3 +51,28 @@ libdali_key_extension_la_LDFLAGS = \
 libdali_key_extensiondir = $(devincludepath)/dali-extension/
 
 libdali_key_extension_HEADERS = $(key_extension_header_files)
+
+# Todo Video player plugin separation
+libdali_video_player_plugin_la_SOURCES = \
+                     $(video_player_plugin_src_files)
+
+libdali_video_player_plugin_la_DEPENDENCIES =
+
+libdali_video_player_plugin_la_CXXFLAGS = -DDALI_COMPILATION \
+                      -DDALI_ADAPTOR_COMPILATION \
+                      $(DLOG_CFLAGS) \
+                      $(DALI_CFLAGS) \
+                      $(ECORE_WAYLAND_CFLAGS) \
+                      $(CAPI_MEDIA_PLAYER_CFLAGS) \
+                      -I../../dali-extension/video-player \
+                      -Werror -Wall
+
+libdali_video_player_plugin_la_LIBADD = \
+                      $(DLOG_LIBS) \
+                      $(DALI_LIBS) \
+                      $(ECORE_WAYLAND_LIBS) \
+                      $(CAPI_MEDIA_PLAYER_LIBS)
+
+libdali_video_player_plugin_la_LDFLAGS = \
+                      -rdynamic
+
index 1deaec6..d534bce 100644 (file)
@@ -1,4 +1,4 @@
-m4_define([dali_version],[0.1.0])
+4_define([dali_version],[0.1.0])
 AC_INIT([dali], [dali_version])
 AM_INIT_AUTOMAKE([-Wall foreign])
 
@@ -24,6 +24,10 @@ AM_CONDITIONAL([USE_KEY_EXTENSION], [test x$enable_keyextension = xyes])
 
 PKG_CHECK_MODULES([DALI], [dali-core dali-adaptor dali-toolkit])
 
+# ToDO Videoplayer plugin separation
+PKG_CHECK_MODULES(CAPI_MEDIA_PLAYER, capi-media-player)
+PKG_CHECK_MODULES(ECORE_WAYLAND, ecore-wayland)
+
 devincludepath=${includedir}
 AC_SUBST(devincludepath)
 
@@ -32,4 +36,4 @@ Makefile
 dali-extension.pc
 ])
 
-AC_OUTPUT()
+AC_OUTPUT
index a31a692..621a5bc 100644 (file)
@@ -1,5 +1,8 @@
 key_extension_src_files = \
-   $(extension_src_dir)/key-extension.cpp
+   $(extension_src_dir)/key/key-extension.cpp
 
 key_extension_header_files = \
-   $(extension_src_dir)/key-extension.h
+   $(extension_src_dir)/key/key-extension.h
+
+video_player_plugin_src_files = \
+   $(extension_src_dir)/video-player/tizen-video-player.cpp
diff --git a/dali-extension/video-player/tizen-video-player.cpp b/dali-extension/video-player/tizen-video-player.cpp
new file mode 100644 (file)
index 0000000..f7baa50
--- /dev/null
@@ -0,0 +1,736 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <tizen-video-player.h>
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/common/stage.h>
+#include <dali/devel-api/threading/mutex.h>
+#include <dali/integration-api/debug.h>
+
+// INTERNAL INCLUDES
+
+// The plugin factories
+extern "C" DALI_EXPORT_API Dali::VideoPlayerPlugin* CreateVideoPlayerPlugin( void )
+{
+  return new Dali::Plugin::TizenVideoPlayer;
+}
+
+extern "C" DALI_EXPORT_API void DestroyVideoPlayerPlugin( Dali::VideoPlayerPlugin* plugin )
+{
+  if( plugin != NULL )
+  {
+    delete plugin;
+  }
+}
+
+namespace Dali
+{
+
+namespace Plugin
+{
+
+namespace
+{
+
+const int TIMER_INTERVAL( 20 );
+
+static void MediaPacketVideoDecodedCb( media_packet_h packet, void* user_data )
+{
+  TizenVideoPlayer* player = static_cast< TizenVideoPlayer* >( user_data );
+
+  if( player == NULL )
+  {
+    DALI_LOG_ERROR( "Decoded callback got Null pointer as user_data.\n" );
+    return;
+  }
+
+  player->PushPacket( packet );
+}
+
+static void EmitPlaybackFinishedSignal( void* user_data )
+{
+  TizenVideoPlayer* player = static_cast< TizenVideoPlayer* >( user_data );
+  DALI_LOG_ERROR( "EmitPlaybackFinishedSignal.\n" );
+
+  if( player == NULL )
+  {
+    DALI_LOG_ERROR( "Decoded callback got Null pointer as user_data.\n" );
+    return;
+  }
+
+  DALI_LOG_ERROR( "EmitPlaybackFinishedSignal.\n" );
+
+  if( !player->mFinishedSignal.Empty() )
+  {
+    DALI_LOG_ERROR( "EmitPlaybackFinishedSignal.3\n" );
+    player->mFinishedSignal.Emit();
+  }
+
+  player->Stop();
+}
+
+// ToDo: VD player_set_play_position() doesn't work when callback pointer is NULL.
+// We should check whether this callback is needed in platform.
+static void PlayerSeekCompletedCb( void* data )
+{
+}
+
+void LogPlayerError( int error )
+{
+  if( error != PLAYER_ERROR_NONE )
+  {
+    switch( error )
+    {
+      case PLAYER_ERROR_OUT_OF_MEMORY:
+      {
+        DALI_LOG_ERROR( "Player error: Out of memory\n" );
+        return;
+      }
+      case PLAYER_ERROR_INVALID_PARAMETER:
+      {
+        DALI_LOG_ERROR( "Player error: Invalid parameter\n" );
+        return;
+      }
+      case PLAYER_ERROR_NO_SUCH_FILE:
+      {
+        DALI_LOG_ERROR( "Player error: No such file\n" );
+        return;
+      }
+      case PLAYER_ERROR_INVALID_OPERATION:
+      {
+        DALI_LOG_ERROR( "Player error: Invalid operation\n" );
+        return;
+      }
+      case PLAYER_ERROR_FILE_NO_SPACE_ON_DEVICE:
+      {
+        DALI_LOG_ERROR( "Player error: No space on device\n" );
+        return;
+      }
+      case PLAYER_ERROR_FEATURE_NOT_SUPPORTED_ON_DEVICE:
+      {
+        DALI_LOG_ERROR( "Player error: Not supported feature on device\n" );
+        return;
+      }
+      case PLAYER_ERROR_SEEK_FAILED:
+      {
+        DALI_LOG_ERROR( "Player error: Seek failed\n" );
+        return;
+      }
+      case PLAYER_ERROR_INVALID_STATE:
+      {
+        DALI_LOG_ERROR( "Player error: Invalid state\n" );
+        return;
+      }
+      case PLAYER_ERROR_NOT_SUPPORTED_FILE:
+      {
+        DALI_LOG_ERROR( "Player error: Not supported file\n" );
+        return;
+      }
+      case PLAYER_ERROR_INVALID_URI:
+      {
+        DALI_LOG_ERROR( "Player error: Invalid uri\n" );
+        return;
+      }
+      case PLAYER_ERROR_SOUND_POLICY:
+      {
+        DALI_LOG_ERROR( "Player error: Sound policy\n" );
+        return;
+      }
+      case PLAYER_ERROR_CONNECTION_FAILED:
+      {
+        DALI_LOG_ERROR( "Player error: Connection failed\n" );
+        return;
+      }
+      case PLAYER_ERROR_VIDEO_CAPTURE_FAILED:
+      {
+        DALI_LOG_ERROR( "Player error: Video capture failed\n" );
+        return;
+      }
+      case PLAYER_ERROR_DRM_EXPIRED:
+      {
+        DALI_LOG_ERROR( "Player error: DRM expired\n" );
+        return;
+      }
+      case PLAYER_ERROR_DRM_NO_LICENSE:
+      {
+        DALI_LOG_ERROR( "Player error: No license\n" );
+        return;
+      }
+      case PLAYER_ERROR_DRM_FUTURE_USE:
+      {
+        DALI_LOG_ERROR( "Player error: License for future use\n" );
+        return;
+      }
+      case PLAYER_ERROR_DRM_NOT_PERMITTED:
+      {
+        DALI_LOG_ERROR( "Player error: Format not permitted\n" );
+        return;
+      }
+      case PLAYER_ERROR_RESOURCE_LIMIT:
+      {
+        DALI_LOG_ERROR( "Player error: Resource limit\n" );
+        return;
+      }
+      case PLAYER_ERROR_PERMISSION_DENIED:
+      {
+        DALI_LOG_ERROR( "Player error: Permission denied\n" );
+        return;
+      }
+      case PLAYER_ERROR_SERVICE_DISCONNECTED:
+      {
+        DALI_LOG_ERROR( "Player error: Service disconnected\n" );
+        return;
+      }
+      case PLAYER_ERROR_BUFFER_SPACE:
+      {
+        DALI_LOG_ERROR( "Player error: Buffer space\n" );
+        return;
+      }
+    }
+  }
+}
+
+} // unnamed namespace
+
+TizenVideoPlayer::TizenVideoPlayer()
+: mPlayer( NULL ),
+  mPlayerState( PLAYER_STATE_NONE ),
+  mTbmSurface( NULL ),
+  mPacket( NULL ),
+  mTargetType( NativeImage ),
+  mAlphaBitChanged( false )
+{
+}
+
+TizenVideoPlayer::~TizenVideoPlayer()
+{
+}
+
+void TizenVideoPlayer::GetPlayerState( player_state_e* state )
+{
+  if( mPlayer != NULL && player_get_state( mPlayer, state ) != PLAYER_ERROR_NONE )
+  {
+    DALI_LOG_ERROR( "player_get_state error: Invalid parameter\n" );
+    *state = PLAYER_STATE_NONE;
+  }
+}
+
+void TizenVideoPlayer::SetUrl( const std::string& url )
+{
+  if( mUrl != url )
+  {
+    mUrl = url;
+
+    GetPlayerState( &mPlayerState );
+
+    if( mPlayerState != PLAYER_STATE_NONE && mPlayerState != PLAYER_STATE_IDLE )
+    {
+      Stop();
+      int error = player_unprepare( mPlayer );
+      LogPlayerError( error );
+    }
+
+    if( mPlayerState == PLAYER_STATE_IDLE )
+    {
+      int error = player_set_uri( mPlayer, mUrl.c_str() );
+      LogPlayerError( error );
+
+      error = player_prepare( mPlayer );
+      LogPlayerError( error );
+    }
+  }
+}
+
+std::string TizenVideoPlayer::GetUrl()
+{
+  return mUrl;
+}
+
+void TizenVideoPlayer::SetRenderingTarget( Any target )
+{
+  int error;
+  if( mPlayerState != PLAYER_STATE_NONE )
+  {
+    GetPlayerState( &mPlayerState );
+
+    if( mPlayerState != PLAYER_STATE_IDLE )
+    {
+      Stop();
+      error = player_unprepare( mPlayer );
+      LogPlayerError( error );
+    }
+
+    error = player_destroy( mPlayer );
+    LogPlayerError( error );
+    mPlayerState = PLAYER_STATE_NONE;
+    mPlayer = NULL;
+    mUrl = "";
+  }
+
+  mNativeImageSourcePtr = NULL;
+  mEcoreWlWindow = NULL;
+
+  if( target.GetType() == typeid( Dali::NativeImageSourcePtr ) )
+  {
+    mTargetType = TizenVideoPlayer::NativeImage;
+
+    Dali::NativeImageSourcePtr nativeImageSourcePtr = AnyCast< Dali::NativeImageSourcePtr >( target );
+
+    InitializeTextureStreamMode( nativeImageSourcePtr );
+  }
+  else if( target.GetType() == typeid( Ecore_Wl_Window* ) )
+  {
+    mTargetType = TizenVideoPlayer::WindowSurface;
+
+    Ecore_Wl_Window* nativeWindow = Dali::AnyCast< Ecore_Wl_Window* >( target );
+    InitializeUnderlayMode( nativeWindow );
+  }
+  else
+  {
+    DALI_LOG_ERROR( "Video rendering target is unknown\n" );
+  }
+}
+
+void TizenVideoPlayer::SetLooping( bool looping )
+{
+  GetPlayerState( &mPlayerState );
+
+  if( mPlayerState != PLAYER_STATE_NONE )
+  {
+    int error = player_set_looping( mPlayer, looping );
+    LogPlayerError( error );
+  }
+}
+
+bool TizenVideoPlayer::IsLooping()
+{
+  GetPlayerState( &mPlayerState );
+
+  bool looping = false;
+  if( mPlayerState != PLAYER_STATE_NONE )
+  {
+    int error = player_is_looping( mPlayer, &looping );
+    LogPlayerError( error );
+  }
+
+  return looping;
+}
+
+void TizenVideoPlayer::Play()
+{
+  GetPlayerState( &mPlayerState );
+
+  if( mPlayerState == PLAYER_STATE_READY || mPlayerState == PLAYER_STATE_PAUSED )
+  {
+    if( mNativeImageSourcePtr != NULL && mTimer )
+    {
+      mTimer.Start();
+    }
+
+    int error = player_start( mPlayer );
+    LogPlayerError( error );
+  }
+}
+
+void TizenVideoPlayer::Pause()
+{
+  GetPlayerState( &mPlayerState );
+
+  if( mPlayerState == PLAYER_STATE_PLAYING )
+  {
+    int error = player_pause( mPlayer );
+    LogPlayerError( error );
+
+    if( mNativeImageSourcePtr != NULL && mTimer )
+    {
+      mTimer.Stop();
+      DestroyPackets();
+    }
+  }
+}
+
+void TizenVideoPlayer::Stop()
+{
+  GetPlayerState( &mPlayerState );
+
+  if( mPlayerState == PLAYER_STATE_PLAYING || mPlayerState == PLAYER_STATE_PAUSED )
+  {
+    int error = player_stop( mPlayer );
+    LogPlayerError( error );
+  }
+
+  if( mNativeImageSourcePtr != NULL && mTimer )
+  {
+    mTimer.Stop();
+    DestroyPackets();
+  }
+}
+
+void TizenVideoPlayer::SetMute( bool muted )
+{
+  GetPlayerState( &mPlayerState );
+
+  if( mPlayerState == PLAYER_STATE_IDLE ||
+      mPlayerState == PLAYER_STATE_READY ||
+      mPlayerState == PLAYER_STATE_PLAYING ||
+      mPlayerState == PLAYER_STATE_PAUSED
+    )
+  {
+    int error = player_set_mute( mPlayer, muted );
+    LogPlayerError( error );
+  }
+}
+
+bool TizenVideoPlayer::IsMuted()
+{
+  GetPlayerState( &mPlayerState );
+  bool muted = false;
+
+   if( mPlayerState == PLAYER_STATE_IDLE ||
+      mPlayerState == PLAYER_STATE_READY ||
+      mPlayerState == PLAYER_STATE_PLAYING ||
+      mPlayerState == PLAYER_STATE_PAUSED
+    )
+  {
+    int error = player_is_muted( mPlayer, &muted );
+    LogPlayerError( error );
+  }
+
+  return muted;
+}
+
+void TizenVideoPlayer::SetVolume( float left, float right )
+{
+  GetPlayerState( &mPlayerState );
+
+  int error = player_set_volume( mPlayer, left, right );
+  LogPlayerError( error );
+}
+
+void TizenVideoPlayer::GetVolume( float& left, float& right )
+{
+  GetPlayerState( &mPlayerState );
+
+  int error = player_get_volume( mPlayer, &left, &right );
+  LogPlayerError( error );
+}
+
+void TizenVideoPlayer::SetPlayPosition( int millisecond )
+{
+  int error;
+
+  GetPlayerState( &mPlayerState );
+
+  if( mPlayerState == PLAYER_STATE_READY ||
+      mPlayerState == PLAYER_STATE_PLAYING ||
+      mPlayerState == PLAYER_STATE_PAUSED
+  )
+  {
+    error = player_set_play_position( mPlayer, millisecond, false, PlayerSeekCompletedCb, NULL );
+    LogPlayerError( error );
+  }
+}
+
+int TizenVideoPlayer::GetPlayPosition()
+{
+  int error;
+  int millisecond = 0;
+
+  GetPlayerState( &mPlayerState );
+
+  if( mPlayerState == PLAYER_STATE_IDLE ||
+      mPlayerState == PLAYER_STATE_READY ||
+      mPlayerState == PLAYER_STATE_PLAYING ||
+      mPlayerState == PLAYER_STATE_PAUSED
+  )
+  {
+    error = player_get_play_position( mPlayer, &millisecond );
+    LogPlayerError( error );
+  }
+
+  return millisecond;
+}
+
+void TizenVideoPlayer::SetDisplayRotation( Dali::VideoPlayerPlugin::DisplayRotation rotation )
+{
+  if( mNativeImageSourcePtr != NULL )
+  {
+    DALI_LOG_ERROR( "SetDisplayRotation is only for window rendering target.\n" );
+    return;
+  }
+
+  int error;
+  if( mPlayerState != PLAYER_STATE_NONE )
+  {
+    error = player_set_display_rotation( mPlayer, static_cast< player_display_rotation_e >( rotation ) );
+    LogPlayerError( error );
+  }
+}
+
+Dali::VideoPlayerPlugin::DisplayRotation TizenVideoPlayer::GetDisplayRotation()
+{
+  if( mNativeImageSourcePtr != NULL )
+  {
+    DALI_LOG_ERROR( "GetDisplayRotation is only for window rendering target.\n" );
+    return Dali::VideoPlayerPlugin::ROTATION_NONE;
+  }
+
+  int error;
+  player_display_rotation_e rotation = PLAYER_DISPLAY_ROTATION_NONE;
+  if( mPlayerState != PLAYER_STATE_NONE )
+  {
+    error = player_get_display_rotation( mPlayer, &rotation );
+    LogPlayerError( error );
+  }
+  return static_cast< Dali::VideoPlayerPlugin::DisplayRotation >( rotation );
+}
+
+Dali::VideoPlayerPlugin::VideoPlayerSignalType& TizenVideoPlayer::FinishedSignal()
+{
+  return mFinishedSignal;
+}
+
+void TizenVideoPlayer::InitializeTextureStreamMode( Dali::NativeImageSourcePtr nativeImageSourcePtr )
+{
+  int error;
+
+  mNativeImageSourcePtr = nativeImageSourcePtr;
+
+  if( mAlphaBitChanged )
+  {
+    ecore_wl_window_alpha_set( mEcoreWlWindow, false );
+    mAlphaBitChanged = false;
+  }
+
+  if( mPlayerState == PLAYER_STATE_NONE )
+  {
+    error = player_create( &mPlayer );
+    LogPlayerError( error );
+  }
+
+  GetPlayerState( &mPlayerState );
+
+  if( mPlayerState == PLAYER_STATE_IDLE )
+  {
+    error = player_set_completed_cb( mPlayer, EmitPlaybackFinishedSignal, this );
+    LogPlayerError( error );
+
+    error = player_set_media_packet_video_frame_decoded_cb( mPlayer, MediaPacketVideoDecodedCb, this );
+    LogPlayerError( error );
+
+    error = player_set_sound_type( mPlayer, SOUND_TYPE_MEDIA );
+    LogPlayerError( error );
+
+    error = player_set_display_mode( mPlayer, PLAYER_DISPLAY_MODE_FULL_SCREEN );
+    LogPlayerError( error );
+
+    error = player_set_display( mPlayer, PLAYER_DISPLAY_TYPE_NONE, NULL );
+    LogPlayerError( error );
+
+    error = player_set_display_visible( mPlayer, true );
+    LogPlayerError( error );
+
+    mTimer = Dali::Timer::New( TIMER_INTERVAL );
+    mTimer.TickSignal().Connect( this, &TizenVideoPlayer::Update );
+  }
+}
+
+void TizenVideoPlayer::InitializeUnderlayMode( Ecore_Wl_Window* ecoreWlWindow )
+{
+  int error;
+  if( mPlayerState == PLAYER_STATE_NONE )
+  {
+    error = player_create( &mPlayer );
+    LogPlayerError( error );
+  }
+
+  GetPlayerState( &mPlayerState );
+  mEcoreWlWindow = ecoreWlWindow;
+
+  if( mPlayerState == PLAYER_STATE_IDLE )
+  {
+    error = player_set_completed_cb( mPlayer, EmitPlaybackFinishedSignal, this );
+    LogPlayerError( error );
+
+    error = player_set_sound_type( mPlayer, SOUND_TYPE_MEDIA );
+    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 );
+
+    int width, height;
+    mAlphaBitChanged = ( ecore_wl_window_alpha_get( mEcoreWlWindow ) )? false: true;
+    ecore_wl_screen_size_get( &width, &height );
+
+    if( mAlphaBitChanged )
+    {
+      ecore_wl_window_alpha_set( mEcoreWlWindow, true );
+    }
+    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 );
+  }
+}
+
+bool TizenVideoPlayer::Update()
+{
+  Dali::Mutex::ScopedLock lock( mPacketMutex );
+
+  int error;
+
+  if( mPacket != NULL )
+  {
+    error = media_packet_destroy( mPacket );
+    if( error != MEDIA_PACKET_ERROR_NONE )
+    {
+      DALI_LOG_ERROR( "Media packet destroy error: %d\n", error );
+    }
+    mPacket = NULL;
+  }
+
+  if( !mPacketVector.Empty() )
+  {
+    mPacket = static_cast< media_packet_h >( mPacketVector[0] );
+    mPacketVector.Remove( mPacketVector.Begin() );
+  }
+
+  if( mPacket == NULL )
+  {
+    return true;
+  }
+
+  error = media_packet_get_tbm_surface( mPacket, &mTbmSurface );
+  if( error != MEDIA_PACKET_ERROR_NONE )
+  {
+    media_packet_destroy( mPacket );
+    mPacket = NULL;
+    DALI_LOG_ERROR( " error: %d\n", error );
+    return true;
+  }
+
+  Any source( mTbmSurface );
+  mNativeImageSourcePtr->SetSource( source );
+  Dali::Stage::GetCurrent().KeepRendering( 0.0f );
+
+  return true;
+}
+
+void TizenVideoPlayer::DestroyPackets()
+{
+  int error;
+  if( mPacket != NULL )
+  {
+    error = media_packet_destroy( mPacket );
+    DALI_LOG_ERROR( "Media packet destroy error: %d\n", error );
+    mPacket = NULL;
+  }
+
+  for(unsigned int i = 0; i < mPacketVector.Size(); ++i)
+  {
+    mPacket = static_cast< media_packet_h >( mPacketVector[i] );
+    error = media_packet_destroy( mPacket );
+    DALI_LOG_ERROR( "Media packet destroy error: %d\n", error );
+    mPacket = NULL;
+  }
+  mPacketVector.Clear();
+}
+
+void TizenVideoPlayer::PushPacket( media_packet_h packet )
+{
+  Dali::Mutex::ScopedLock lock( mPacketMutex );
+  mPacketVector.PushBack( packet );
+}
+
+void TizenVideoPlayer::SetDisplayArea( DisplayArea area )
+{
+  GetPlayerState( &mPlayerState );
+
+  if( mNativeImageSourcePtr != NULL )
+  {
+    DALI_LOG_ERROR( "SetDisplayArea is only for window surface target.\n" );
+    return;
+  }
+
+  if( mPlayerState == PLAYER_STATE_IDLE ||
+      mPlayerState == PLAYER_STATE_READY ||
+      mPlayerState == PLAYER_STATE_PLAYING ||
+      mPlayerState == PLAYER_STATE_PAUSED
+
+  )
+  {
+    int error = player_set_display_roi_area( mPlayer, area.x, area.y, area.width, area.height );
+    LogPlayerError( error );
+  }
+}
+
+void TizenVideoPlayer::Forward( int millisecond )
+{
+  int error;
+
+  GetPlayerState( &mPlayerState );
+
+  if( mPlayerState == PLAYER_STATE_READY ||
+      mPlayerState == PLAYER_STATE_PLAYING ||
+      mPlayerState == PLAYER_STATE_PAUSED
+  )
+  {
+    int currentPosition = 0;
+    int nextPosition = 0;
+
+    error = player_get_play_position( mPlayer, &currentPosition );
+    LogPlayerError( error );
+
+    nextPosition = currentPosition + millisecond;
+
+    error = player_set_play_position( mPlayer, nextPosition, false, PlayerSeekCompletedCb, NULL );
+    LogPlayerError( error );
+  }
+}
+
+void TizenVideoPlayer::Backward( int millisecond )
+{
+  int error;
+
+  GetPlayerState( &mPlayerState );
+
+  if( mPlayerState == PLAYER_STATE_READY ||
+      mPlayerState == PLAYER_STATE_PLAYING ||
+      mPlayerState == PLAYER_STATE_PAUSED
+  )
+  {
+    int currentPosition = 0;
+    int nextPosition = 0;
+
+    error = player_get_play_position( mPlayer, &currentPosition );
+    LogPlayerError( error );
+
+    nextPosition = currentPosition - millisecond;
+    nextPosition = ( nextPosition < 0 )? 0 : nextPosition;
+
+    error = player_set_play_position( mPlayer, nextPosition, false, PlayerSeekCompletedCb, NULL );
+    LogPlayerError( error );
+  }
+}
+
+} // namespace Plugin
+} // namespace Dali;
diff --git a/dali-extension/video-player/tizen-video-player.h b/dali-extension/video-player/tizen-video-player.h
new file mode 100644 (file)
index 0000000..9a03627
--- /dev/null
@@ -0,0 +1,229 @@
+#ifndef __DALI_TIZEN_VIDEO_PLAYER_PLUGIN_H__
+#define __DALI_TIZEN_VIDEO_PLAYER_PLUGIN_H__
+
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/devel-api/threading/mutex.h>
+#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 <player.h>
+#include <string>
+
+#ifndef HAVE_WAYLAND
+#define HAVE_WAYLAND
+#endif
+#include <player_internal.h>
+
+namespace Dali
+{
+
+namespace Plugin
+{
+
+/**
+ * @brief Implementation of the Tizen video player class which has Tizen platform dependency.
+ * @SINCE_1_1.38
+ */
+class TizenVideoPlayer : public Dali::VideoPlayerPlugin, public Dali::ConnectionTracker
+{
+public:
+
+  /**
+   * @brief Video rendering target type
+   * @SINCE_1_1.38
+   */
+  enum RenderingTargetType
+  {
+    WindowSurface, ///< HW underlay
+    NativeImage ///< texture stream
+  };
+
+  /**
+   * @brief Constructor.
+   * @SINCE_1_1.38
+   */
+  TizenVideoPlayer();
+
+  /**
+   * @brief Destructor.
+   * @SINCE_1_1.38
+   */
+  virtual ~TizenVideoPlayer();
+
+  /**
+   * @copydoc Dali::VideoPlayerPlugin::SetUrl()
+   */
+  virtual void SetUrl( const std::string& url );
+
+  /**
+   * @copydoc Dali::VideoPlayerPlugin::GetUrl()
+   */
+  virtual std::string GetUrl();
+
+  /**
+   * @copydoc Dali::VideoPlayerPlugin::SetLooping()
+   */
+  virtual void SetLooping(bool looping);
+
+  /**
+   * @copydoc Dali::VideoPlayerPlugin::IsLooping()
+   */
+  virtual bool IsLooping();
+
+  /**
+   * @copydoc Dali::VideoPlayerPlugin::Play()
+   */
+  virtual void Play();
+
+  /**
+   * @copydoc Dali::VideoPlayerPlugin::Pause()
+   */
+  virtual void Pause();
+
+  /**
+   * @copydoc Dali::VideoPlayerPlugin::Stop()
+   */
+  virtual void Stop();
+
+  /**
+   * @copydoc Dali::VideoPlayerPlugin::SetMute()
+   */
+  virtual void SetMute( bool mute );
+
+  /**
+   * @copydoc Dali::VideoPlayerPlugin::IsMute()
+   */
+  virtual bool IsMuted();
+
+  /**
+   * @copydoc Dali::VideoPlayerPlugin::SetVolume()
+   */
+  virtual void SetVolume( float left, float right );
+
+  /**
+   * @copydoc Dali::VideoPlayerPlugin::GetVolume()
+   */
+  virtual void GetVolume( float& left, float& right );
+
+  /**
+   * @copydoc Dali::VideoPlayerPlugin::SetRenderingTarget()
+   */
+  void SetRenderingTarget( Any target );
+
+  /**
+   * @copydoc Dali::VideoPlayerPlugin::SetPlayPosition()
+   */
+  virtual void SetPlayPosition( int millisecond );
+
+  /**
+   * @copydoc Dali::VideoPlayerPlugin::GetPlayPosition()
+   */
+  virtual int GetPlayPosition();
+
+  /**
+   * @copydoc Dali::VideoPlayerPlugin::SetDisplayArea()
+   */
+  virtual void SetDisplayArea( DisplayArea area );
+
+  /**
+   * @copydoc Dali::VideoPlayerPlugin::SetDisplayRotation()
+   */
+  virtual void SetDisplayRotation( Dali::VideoPlayerPlugin::DisplayRotation rotation );
+
+  /**
+   * @copydoc Dali::VideoPlayerPlugin::GetDisplayRotation()
+   */
+  virtual Dali::VideoPlayerPlugin::DisplayRotation GetDisplayRotation();
+
+  /**
+   * @copydoc Dali::VideoPlayerPlugin::FinishedSignal()
+   */
+  virtual Dali::VideoPlayerPlugin::VideoPlayerSignalType& FinishedSignal();
+
+  /**
+   * @brief Push media packet with video frame image
+   */
+  void PushPacket( media_packet_h packet );
+
+  /**
+   * @brief Dali::VideoPlayer::Forward()
+   */
+  void Forward( int millisecond );
+
+  /**
+   * @brief Dali::VideoPlayer::Backward()
+   */
+  void Backward( int millisecond );
+
+private:
+
+  /**
+   * @brief Updates video frame image by timer if rendering targe is native image source
+   */
+  bool Update();
+
+  /**
+   * @brief Gets current player state
+   */
+  void GetPlayerState( player_state_e* state );
+
+  /**
+   * @brief Destroy all packests, which this plugin stores
+   */
+  void DestroyPackets();
+
+  /**
+   * @brief Initializes player for video rendering using native image source
+   */
+  void InitializeTextureStreamMode( Dali::NativeImageSourcePtr nativeImageSourcePtr );
+
+  /**
+   * @brief Initializes player for video rendering using wayland window surface
+   */
+  void InitializeUnderlayMode( Ecore_Wl_Window* ecoreWlWindow );
+
+private:
+
+  std::string mUrl; ///< The video file path
+  player_h mPlayer; ///< Tizen player handle
+  player_state_e mPlayerState; ///< Tizen player state
+  tbm_surface_h mTbmSurface; ///< tbm surface handle
+  media_packet_h mPacket; ///< Media packet handle with tbm surface of current video frame image
+  Dali::NativeImageSourcePtr mNativeImageSourcePtr; ///< native image source for video rendering
+  Dali::Timer mTimer; ///< Timer for texture streaming rendering
+  Dali::Vector4 mBackgroundColor; ///< Current background color, which texturestream mode needs.
+  RenderingTargetType mTargetType; ///< Current rendering target type
+
+  Dali::Mutex mPacketMutex;
+  Dali::Vector< media_packet_h > mPacketVector; ///< Container for media packet handle from Tizen player callback
+
+  Ecore_Wl_Window* mEcoreWlWindow;
+
+  bool mAlphaBitChanged; ///< True if underlay rendering initialization changes window alpha
+
+public:
+
+  Dali::VideoPlayerPlugin::VideoPlayerSignalType mFinishedSignal;
+};
+
+} // namespace Plugin
+} // namespace Dali;
+
+#endif
index 8e799fa..efef6c3 100644 (file)
@@ -37,7 +37,7 @@ Requires:   %{name} = %{version}-%{release}
 %description devel
 Development components for the DALi Tizen Extensions - public headers and package configs
 
-V##############################
+##############################
 # Dali Key Extension
 ##############################
 
@@ -49,6 +49,19 @@ Group:      System/Libraries
 Plugin to support extension keys for Dali
 
 ##############################
+# Dali VideoPlayer Plugin
+##############################
+
+%package video-player-plugin
+Summary:    Plugin to play a video file for Dali
+Group:      System/Libraries
+BuildRequires: pkgconfig(ecore-wayland)
+BuildRequires: pkgconfig(capi-media-player)
+
+%description video-player-plugin
+VideoPlayer plugin to play a video file for Dali
+
+##############################
 # Preparation
 ##############################
 %prep
@@ -99,6 +112,10 @@ exit 0
 /sbin/ldconfig
 exit 0
 
+%post video-player-plugin
+/sbin/ldconfig
+exit 0
+
 ##############################
 #   Pre Uninstall old package
 ##############################
@@ -116,6 +133,10 @@ exit 0
 /sbin/ldconfig
 exit 0
 
+%postun video-player-plugin
+/sbin/ldconfig
+exit 0
+
 ##############################
 # Files in Binary Packages
 ##############################
@@ -135,3 +156,9 @@ exit 0
 %defattr(-,root,root,-)
 %{_libdir}/libdali-key-extension.so*
 %license LICENSE
+
+%files video-player-plugin
+%manifest dali-extension.manifest
+%defattr(-,root,root,-)
+%{_libdir}/libdali-video-player-plugin.so*
+%license LICENSE