[dali_1.3.21] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / video-view / video-view-impl.cpp
old mode 100644 (file)
new mode 100755 (executable)
index 2fdb70b..1e6da13
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2018 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.
@@ -62,6 +62,9 @@ DALI_PROPERTY_REGISTRATION( Toolkit, VideoView, "video", MAP, VIDEO )
 DALI_PROPERTY_REGISTRATION( Toolkit, VideoView, "looping", BOOLEAN, LOOPING )
 DALI_PROPERTY_REGISTRATION( Toolkit, VideoView, "muted", BOOLEAN, MUTED )
 DALI_PROPERTY_REGISTRATION( Toolkit, VideoView, "volume", MAP, VOLUME )
+DALI_PROPERTY_REGISTRATION( Toolkit, VideoView, "underlay", BOOLEAN, UNDERLAY )
+DALI_PROPERTY_REGISTRATION( Toolkit, VideoView, "playPosition", INTEGER, PLAY_POSITION )
+DALI_PROPERTY_REGISTRATION( Toolkit, VideoView, "displayMode", INTEGER, DISPLAY_MODE )
 
 DALI_SIGNAL_REGISTRATION( Toolkit, VideoView, "finished", FINISHED_SIGNAL )
 
@@ -75,6 +78,8 @@ DALI_TYPE_REGISTRATION_END()
 
 const char* const VOLUME_LEFT( "volumeLeft" );
 const char* const VOLUME_RIGHT( "volumeRight" );
+
+// 3.0 TC uses RENDERING_TARGET. It should be removed in next release
 const char* const RENDERING_TARGET( "renderingTarget" );
 const char* const WINDOW_SURFACE_TARGET( "windowSurfaceTarget" );
 const char* const NATIVE_IMAGE_TARGET( "nativeImageTarget" );
@@ -95,56 +100,26 @@ const char* VERTEX_SHADER = DALI_COMPOSE_SHADER(
 const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER(
   uniform lowp vec4 uColor;\n
   uniform lowp vec3 mixColor;\n
-  uniform lowp float opacity;\n
   \n
   void main()\n
   {\n
-    gl_FragColor = vec4(mixColor, opacity)*uColor;\n
+    gl_FragColor = vec4(mixColor, 1.0)*uColor;\n
   }\n
 );
 
-struct TriggerFunctor
-{
-  TriggerFunctor( TriggerEventInterface* notification )
-  : mNotification( notification )
-  {
-  }
-
-  void operator()( bool& current, const PropertyInputContainer& inputs )
-  {
-    if( mNotification != NULL )
-    {
-      mNotification->Trigger();
-    }
-  }
-
-  TriggerEventInterface* mNotification;
-};
-
 } // anonymous namepsace
 
 VideoView::VideoView()
 : Control( ControlBehaviour( ACTOR_BEHAVIOUR_DEFAULT | DISABLE_STYLE_CHANGE_SIGNALS ) ),
-  mUpdateTriggerPropertyIndex( Property::INVALID_INDEX),
-  mNotification( NULL ),
   mCurrentVideoPlayPosition( 0 ),
-  mIsNativeImageTarget( true ),
   mIsPlay( false ),
-  mIsPause( false )
+  mIsUnderlay( true )
 {
   mVideoPlayer = Dali::VideoPlayer::New();
-
-  TriggerEventFactory triggerEventFactory;
-  mNotification = triggerEventFactory.CreateTriggerEvent( MakeCallback(this, &VideoView::UpdateDisplayArea ),
-                                                               TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER);
 }
 
 VideoView::~VideoView()
 {
-  if( mNotification != NULL )
-  {
-    delete mNotification;
-  }
 }
 
 Toolkit::VideoView VideoView::New()
@@ -159,14 +134,8 @@ Toolkit::VideoView VideoView::New()
 
 void VideoView::OnInitialize()
 {
-  Any source;
-  Dali::NativeImageSourcePtr nativeImageSourcePtr = Dali::NativeImageSource::New( source );
-  mNativeImage = Dali::NativeImage::New( *nativeImageSourcePtr );
-
-  mVideoPlayer.SetRenderingTarget( nativeImageSourcePtr );
   mVideoPlayer.FinishedSignal().Connect( this, &VideoView::EmitSignalFinish );
-
-  mUpdateTriggerPropertyIndex = Self().RegisterProperty( "updateTrigger", true );
+  SetWindowSurfaceTarget();
 }
 
 void VideoView::SetUrl( const std::string& url )
@@ -177,7 +146,7 @@ void VideoView::SetUrl( const std::string& url )
     mPropertyMap.Clear();
   }
 
-  if( mIsNativeImageTarget )
+  if( !mIsUnderlay )
   {
     Actor self( Self() );
     Internal::InitializeVisual( self, mVisual, mNativeImage );
@@ -218,11 +187,13 @@ void VideoView::SetPropertyMap( Property::Map map )
 
   if( target && target->Get( targetType ) && targetType == WINDOW_SURFACE_TARGET )
   {
-    this->SetWindowSurfaceTarget();
+    mIsUnderlay = true;
+    SetWindowSurfaceTarget();
   }
   else if( target && target->Get( targetType ) && targetType == NATIVE_IMAGE_TARGET )
   {
-    this->SetNativeImageTarget();
+    mIsUnderlay = false;
+    SetNativeImageTarget();
   }
 
   RelayoutRequest();
@@ -245,23 +216,25 @@ bool VideoView::IsLooping()
 
 void VideoView::Play()
 {
+  if( mIsUnderlay )
+  {
+    Self().AddRenderer( mRenderer );
+  }
+
   mVideoPlayer.Play();
   mIsPlay = true;
-  mIsPause = false;
 }
 
 void VideoView::Pause()
 {
   mVideoPlayer.Pause();
   mIsPlay = false;
-  mIsPause = true;
 }
 
 void VideoView::Stop()
 {
   mVideoPlayer.Stop();
   mIsPlay = false;
-  mIsPause = false;
 }
 
 void VideoView::Forward( int millisecond )
@@ -310,6 +283,11 @@ Dali::Toolkit::VideoView::VideoViewSignalType& VideoView::FinishedSignal()
 
 void VideoView::EmitSignalFinish()
 {
+  if( mIsUnderlay )
+  {
+    Self().RemoveRenderer( mRenderer );
+  }
+
   if ( !mFinishedSignal.Empty() )
   {
     Dali::Toolkit::VideoView handle( GetOwner() );
@@ -465,6 +443,33 @@ void VideoView::SetProperty( BaseObject* object, Property::Index index, const Pr
         }
         break;
       }
+      case Toolkit::VideoView::Property::UNDERLAY:
+      {
+        bool underlay;
+        if( value.Get( underlay ) )
+        {
+          impl.SetUnderlay( underlay );
+        }
+        break;
+      }
+      case Toolkit::VideoView::Property::PLAY_POSITION:
+      {
+        int pos;
+        if( value.Get( pos ) )
+        {
+          impl.SetPlayPosition( pos );
+        }
+        break;
+      }
+      case Toolkit::VideoView::Property::DISPLAY_MODE:
+      {
+        int mode;
+        if( value.Get( mode ) )
+        {
+          impl.SetDisplayMode( mode );
+        }
+        break;
+      }
     }
   }
 }
@@ -513,6 +518,21 @@ Property::Value VideoView::GetProperty( BaseObject* object, Property::Index prop
         value = map;
         break;
       }
+      case Toolkit::VideoView::Property::UNDERLAY:
+      {
+        value = impl.IsUnderlay();
+        break;
+      }
+      case Toolkit::VideoView::Property::PLAY_POSITION:
+      {
+        value = impl.GetPlayPosition();
+        break;
+      }
+      case Toolkit::VideoView::Property::DISPLAY_MODE:
+      {
+        value = impl.GetDisplayMode();
+        break;
+      }
     }
   }
 
@@ -601,47 +621,68 @@ void VideoView::SetWindowSurfaceTarget()
     mVisual.Reset();
   }
 
-  Constraint constraint = Constraint::New<bool>( self, mUpdateTriggerPropertyIndex, TriggerFunctor( mNotification ) );
-  constraint.AddSource( Source( self, Actor::Property::POSITION ) );
-  constraint.AddSource( Source( self, Actor::Property::SIZE ) );
-  constraint.Apply();
+  if( mIsPlay )
+  {
+    mVideoPlayer.Pause();
+  }
+
+  mPositionUpdateNotification = self.AddPropertyNotification( Actor::Property::WORLD_POSITION, StepCondition( 1.0f, 1.0f ) );
+  mSizeUpdateNotification = self.AddPropertyNotification( Actor::Property::SIZE, StepCondition( 1.0f, 1.0f ) );
+  mScaleUpdateNotification = self.AddPropertyNotification( Actor::Property::WORLD_SCALE, StepCondition( 0.1f, 1.0f ) );
+  mPositionUpdateNotification.NotifySignal().Connect( this, &VideoView::UpdateDisplayArea );
+  mSizeUpdateNotification.NotifySignal().Connect( this, &VideoView::UpdateDisplayArea );
+  mScaleUpdateNotification.NotifySignal().Connect( this, &VideoView::UpdateDisplayArea );
 
   mVideoPlayer.SetRenderingTarget( Dali::Adaptor::Get().GetNativeWindowHandle() );
   mVideoPlayer.SetUrl( mUrl );
 
-  mIsNativeImageTarget = false;
-
-  if( mIsPlay )
+  if( !mRenderer )
   {
-    mVideoPlayer.Play();
+    // For underlay rendering mode, video display area have to be transparent.
+    Geometry geometry = VisualFactoryCache::CreateQuadGeometry();
+    Shader shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER );
+    mRenderer = Renderer::New( geometry, shader );
+
+    mRenderer.SetProperty( Renderer::Property::BLEND_MODE, BlendMode::ON );
+    mRenderer.SetProperty( Renderer::Property::BLEND_FACTOR_SRC_RGB, BlendFactor::ONE );
+    mRenderer.SetProperty( Renderer::Property::BLEND_FACTOR_DEST_RGB, BlendFactor::ZERO );
+    mRenderer.SetProperty( Renderer::Property::BLEND_FACTOR_SRC_ALPHA, BlendFactor::ONE );
+    mRenderer.SetProperty( Renderer::Property::BLEND_FACTOR_DEST_ALPHA, BlendFactor::ZERO );
   }
-  if( mIsPause )
+
+  if( mIsPlay )
   {
-    mVideoPlayer.Play();
-    mVideoPlayer.Pause();
+    Play();
   }
 
   if( curPos > 0 )
   {
     mVideoPlayer.SetPlayPosition( curPos );
   }
-
-  // For underlay rendering mode, video display area have to be transparent.
-  Geometry geometry = VisualFactoryCache::CreateQuadGeometry();
-  Shader shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER );
-  Renderer renderer = Renderer::New( geometry, shader );
-
-  renderer.SetProperty( Renderer::Property::BLEND_MODE, BlendMode::ON );
-  renderer.SetProperty( Renderer::Property::BLEND_FACTOR_SRC_RGB, BlendFactor::ONE );
-  renderer.SetProperty( Renderer::Property::BLEND_FACTOR_DEST_RGB, BlendFactor::ZERO );
-  renderer.SetProperty( Renderer::Property::BLEND_FACTOR_SRC_ALPHA, BlendFactor::ONE );
-  renderer.SetProperty( Renderer::Property::BLEND_FACTOR_DEST_ALPHA, BlendFactor::ZERO );
-  self.AddRenderer( renderer );
 }
 
 void VideoView::SetNativeImageTarget()
 {
+  if( mVideoPlayer.IsVideoTextureSupported() == false )
+  {
+    DALI_LOG_ERROR( "Platform doesn't support decoded video frame images\n" );
+    mIsUnderlay = true;
+    return;
+  }
+
+  if( mIsPlay )
+  {
+    mVideoPlayer.Pause();
+  }
+
   Actor self( Self() );
+  self.RemoveRenderer( mRenderer );
+  Dali::Stage::GetCurrent().KeepRendering( 0.0f );
+
+  self.RemovePropertyNotification( mPositionUpdateNotification );
+  self.RemovePropertyNotification( mSizeUpdateNotification );
+  self.RemovePropertyNotification( mScaleUpdateNotification );
+
   int curPos = mVideoPlayer.GetPlayPosition();
 
   Any source;
@@ -652,26 +693,26 @@ void VideoView::SetNativeImageTarget()
   mVideoPlayer.SetUrl( mUrl );
 
   Internal::InitializeVisual( self, mVisual, mNativeImage );
-  mIsNativeImageTarget = true;
+  Self().RemoveRenderer( mRenderer );
 
   if( mIsPlay )
   {
-    mVideoPlayer.Play();
+    Play();
   }
 
-  if( mIsPause )
-  {
-    mVideoPlayer.Play();
-    mVideoPlayer.Pause();
-  }
   if( curPos > 0 )
   {
     mVideoPlayer.SetPlayPosition( curPos );
   }
 }
 
-void VideoView::UpdateDisplayArea()
+void VideoView::UpdateDisplayArea( Dali::PropertyNotification& source )
 {
+  if( !mIsUnderlay )
+  {
+    return;
+  }
+
   Actor self( Self() );
 
   bool positionUsesAnchorPoint = self.GetProperty( DevelActor::Property::POSITION_USES_ANCHOR_POINT ).Get< bool >();
@@ -688,6 +729,64 @@ void VideoView::UpdateDisplayArea()
   mVideoPlayer.SetDisplayArea( mDisplayArea );
 }
 
+void VideoView::SetUnderlay( bool set )
+{
+  if( set != mIsUnderlay )
+  {
+    mIsUnderlay = set;
+
+    if( mIsUnderlay )
+    {
+      SetWindowSurfaceTarget();
+    }
+    else
+    {
+      SetNativeImageTarget();
+    }
+
+    RelayoutRequest();
+  }
+}
+
+bool VideoView::IsUnderlay()
+{
+  return mIsUnderlay;
+}
+
+void VideoView::SetSWCodec( bool on )
+{
+  // If setting SW or HW type is failed , video-view shows video by default codec type.
+  // The default codec type is selected by platform.
+  if( on )
+  {
+    mVideoPlayer.SetCodecType( Dali::VideoPlayerPlugin::CodecType::SW );
+  }
+  else
+  {
+    mVideoPlayer.SetCodecType( Dali::VideoPlayerPlugin::CodecType::HW );
+  }
+}
+
+int VideoView::GetPlayPosition()
+{
+  return mVideoPlayer.GetPlayPosition();
+}
+
+void VideoView::SetPlayPosition( int pos )
+{
+  mVideoPlayer.SetPlayPosition( pos );
+}
+
+void VideoView::SetDisplayMode( int mode )
+{
+  mVideoPlayer.SetDisplayMode( static_cast< Dali::VideoPlayerPlugin::DisplayMode::Type >( mode ) );
+}
+
+int VideoView::GetDisplayMode() const
+{
+  return static_cast< int >( mVideoPlayer.GetDisplayMode() );
+}
+
 } // namespace Internal
 
 } // namespace toolkit