X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=blobdiff_plain;f=dali-toolkit%2Finternal%2Fcontrols%2Fvideo-view%2Fvideo-view-impl.cpp;h=181a47e8519d4ddc95a9a08d452b18851bca19e1;hp=d85be9ab9987831c5e76dcdf5521a2b03e095fa6;hb=2e42ad28cef7d57f759a489710d1f46016fbe3da;hpb=5e937a6322849b76d49d5b3f41cb5d91c94acd3e diff --git a/dali-toolkit/internal/controls/video-view/video-view-impl.cpp b/dali-toolkit/internal/controls/video-view/video-view-impl.cpp old mode 100755 new mode 100644 index d85be9a..181a47e --- a/dali-toolkit/internal/controls/video-view/video-view-impl.cpp +++ b/dali-toolkit/internal/controls/video-view/video-view-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Samsung Electronics Co., Ltd. + * Copyright (c) 2021 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. @@ -19,167 +19,138 @@ #include "video-view-impl.h" // EXTERNAL INCLUDES -#include -#include -#include -#include +#include +#include +#include #include -#include #include +#include #include -#include +#include +#include +#include // INTERNAL INCLUDES -#include +#include +#include #include +#include #include namespace Dali { - namespace Toolkit { - namespace Internal { - namespace { - BaseHandle Create() { return Toolkit::VideoView::New(); } -DALI_TYPE_REGISTRATION_BEGIN( Toolkit::VideoView, Toolkit::Control, Create ); +DALI_TYPE_REGISTRATION_BEGIN(Toolkit::VideoView, Toolkit::Control, Create); -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_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 ) +DALI_SIGNAL_REGISTRATION(Toolkit, VideoView, "finished", FINISHED_SIGNAL) -DALI_ACTION_REGISTRATION( Toolkit, VideoView, "play", ACTION_VIDEOVIEW_PLAY ) -DALI_ACTION_REGISTRATION( Toolkit, VideoView, "pause", ACTION_VIDEOVIEW_PAUSE ) -DALI_ACTION_REGISTRATION( Toolkit, VideoView, "stop", ACTION_VIDEOVIEW_STOP ) -DALI_ACTION_REGISTRATION( Toolkit, VideoView, "forward", ACTION_VIDEOVIEW_FORWARD ) -DALI_ACTION_REGISTRATION( Toolkit, VideoView, "backward", ACTION_VIDEOVIEW_BACKWARD ) +DALI_ACTION_REGISTRATION(Toolkit, VideoView, "play", ACTION_VIDEOVIEW_PLAY) +DALI_ACTION_REGISTRATION(Toolkit, VideoView, "pause", ACTION_VIDEOVIEW_PAUSE) +DALI_ACTION_REGISTRATION(Toolkit, VideoView, "stop", ACTION_VIDEOVIEW_STOP) +DALI_ACTION_REGISTRATION(Toolkit, VideoView, "forward", ACTION_VIDEOVIEW_FORWARD) +DALI_ACTION_REGISTRATION(Toolkit, VideoView, "backward", ACTION_VIDEOVIEW_BACKWARD) DALI_TYPE_REGISTRATION_END() -const char* const VOLUME_LEFT( "volumeLeft" ); -const char* const VOLUME_RIGHT( "volumeRight" ); +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" ); - -const char* const CUSTOM_SHADER( "shader" ); -const char* const CUSTOM_VERTEX_SHADER( "vertexShader" ); -const char* const CUSTOM_FRAGMENT_SHADER( "fragmentShader" ); -const char* const DEFAULT_SAMPLER_TYPE_NAME( "sampler2D" ); -const char* const CUSTOM_SAMPLER_TYPE_NAME( "samplerExternalOES" ); - -const char* VERTEX_SHADER = DALI_COMPOSE_SHADER( - attribute mediump vec2 aPosition;\n - uniform highp mat4 uMvpMatrix;\n - uniform mediump vec3 uSize;\n - \n - void main()\n - {\n - mediump vec4 vertexPosition = vec4(aPosition, 0.0, 1.0);\n - vertexPosition.xyz *= uSize;\n - gl_Position = uMvpMatrix * vertexPosition;\n - }\n -); - -const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER( - \n - void main()\n - {\n - gl_FragColor = vec4(0.0);\n - }\n -); - -const char* VERTEX_SHADER_TEXTURE = DALI_COMPOSE_SHADER( - attribute mediump vec2 aPosition;\n - varying mediump vec2 vTexCoord;\n - uniform highp mat4 uMvpMatrix;\n - uniform mediump vec3 uSize;\n - varying mediump vec2 sTexCoordRect;\n - void main()\n - {\n - gl_Position = uMvpMatrix * vec4(aPosition * uSize.xy, 0.0, 1.0);\n - vTexCoord = aPosition + vec2(0.5);\n - }\n -); - -const char* FRAGMENT_SHADER_TEXTURE = DALI_COMPOSE_SHADER( - uniform lowp vec4 uColor;\n - varying mediump vec2 vTexCoord;\n - uniform samplerExternalOES sTexture;\n - void main()\n - {\n - gl_FragColor = texture2D( sTexture, vTexCoord ) * uColor;\n - }\n -); - -} // anonymous namepsace - -VideoView::VideoView() -: Control( ControlBehaviour( ACTOR_BEHAVIOUR_DEFAULT | DISABLE_STYLE_CHANGE_SIGNALS ) ), - mCurrentVideoPlayPosition( 0 ), - mIsPlay( false ), - mIsUnderlay( true ) -{ - mVideoPlayer = Dali::VideoPlayer::New(); +const char* const RENDERING_TARGET("renderingTarget"); +const char* const WINDOW_SURFACE_TARGET("windowSurfaceTarget"); +const char* const NATIVE_IMAGE_TARGET("nativeImageTarget"); + +const char* const CUSTOM_SHADER("shader"); +const char* const CUSTOM_VERTEX_SHADER("vertexShader"); +const char* const CUSTOM_FRAGMENT_SHADER("fragmentShader"); +const char* const DEFAULT_SAMPLER_TYPE_NAME("sampler2D"); +const char* const CUSTOM_SAMPLER_TYPE_NAME("samplerExternalOES"); + +const char* const IS_VIDEO_VIEW_PROPERTY_NAME = "isVideoView"; + +} // namespace + +VideoView::VideoView(Dali::VideoSyncMode syncMode) +: Control(ControlBehaviour(ACTOR_BEHAVIOUR_DEFAULT | DISABLE_STYLE_CHANGE_SIGNALS)), + mCurrentVideoPlayPosition(0), + mFrameID(0), + mIsPlay(false), + mIsUnderlay(true), + mSyncMode(syncMode), + mSiblingOrder(0) +{ } VideoView::~VideoView() { } -Toolkit::VideoView VideoView::New() +Toolkit::VideoView VideoView::New(VideoSyncMode syncMode) { - VideoView* impl = new VideoView(); - Toolkit::VideoView handle = Toolkit::VideoView( *impl ); + VideoView* impl = new VideoView(syncMode); + Toolkit::VideoView handle = Toolkit::VideoView(*impl); + impl->mVideoPlayer = Dali::VideoPlayer::New(impl->Self(), syncMode); impl->Initialize(); - return handle; } void VideoView::OnInitialize() { - mVideoPlayer.FinishedSignal().Connect( this, &VideoView::EmitSignalFinish ); + Actor self = Self(); + mVideoPlayer.FinishedSignal().Connect(this, &VideoView::EmitSignalFinish); + + DevelControl::SetAccessibilityConstructor(self, [](Dali::Actor actor) { + return std::unique_ptr( + new DevelControl::AccessibleImpl(actor, Dali::Accessibility::Role::VIDEO)); + }); + + //Enable highightability + Self().SetProperty(Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, true); + + //update self property + self.RegisterProperty(IS_VIDEO_VIEW_PROPERTY_NAME, true, Property::READ_WRITE); } -void VideoView::SetUrl( const std::string& url ) +void VideoView::SetUrl(const std::string& url) { - mUrl = url; - mPropertyMap.Clear(); + mUrl = url; + mPropertyMap.Clear(); - mVideoPlayer.SetUrl( mUrl ); + mVideoPlayer.SetUrl(mUrl); } -void VideoView::SetPropertyMap( Property::Map map ) +void VideoView::SetPropertyMap(Property::Map map) { mPropertyMap = map; - Property::Value* target = map.Find( RENDERING_TARGET ); - std::string targetType; + Property::Value* target = map.Find(RENDERING_TARGET); + std::string targetType; - if( target && target->Get( targetType ) && targetType == WINDOW_SURFACE_TARGET ) + if(target && target->Get(targetType) && targetType == WINDOW_SURFACE_TARGET) { mIsUnderlay = true; SetWindowSurfaceTarget(); } - else if( target && target->Get( targetType ) && targetType == NATIVE_IMAGE_TARGET ) + else if(target && target->Get(targetType) && targetType == NATIVE_IMAGE_TARGET) { mIsUnderlay = false; SetNativeImageTarget(); @@ -187,24 +158,24 @@ void VideoView::SetPropertyMap( Property::Map map ) // Custom shader Property::Value* shaderValue; - if( !map.Empty() ) + if(!map.Empty()) { - shaderValue = map.Find( CUSTOM_SHADER ); + shaderValue = map.Find(CUSTOM_SHADER); - if( shaderValue ) + if(shaderValue) { Property::Map* shaderMap = shaderValue->GetMap(); - if( shaderMap ) + if(shaderMap) { mEffectPropertyMap = *shaderMap; } } } - if( mTextureRenderer && !mEffectPropertyMap.Empty() ) + if(mTextureRenderer && !mEffectPropertyMap.Empty()) { Dali::Shader shader = CreateShader(); - mTextureRenderer.SetShader( shader ); + mTextureRenderer.SetShader(shader); } RelayoutRequest(); @@ -215,9 +186,9 @@ std::string VideoView::GetUrl() return mUrl; } -void VideoView::SetLooping( bool looping ) +void VideoView::SetLooping(bool looping) { - mVideoPlayer.SetLooping( looping ); + mVideoPlayer.SetLooping(looping); } bool VideoView::IsLooping() @@ -227,11 +198,6 @@ bool VideoView::IsLooping() void VideoView::Play() { - if( mOverlayRenderer ) - { - Self().AddRenderer( mOverlayRenderer ); - } - mVideoPlayer.Play(); mIsPlay = true; } @@ -248,28 +214,28 @@ void VideoView::Stop() mIsPlay = false; } -void VideoView::Forward( int millisecond ) +void VideoView::Forward(int millisecond) { int curPos = mVideoPlayer.GetPlayPosition(); int nextPos = curPos + millisecond; - mVideoPlayer.SetPlayPosition( nextPos ); + mVideoPlayer.SetPlayPosition(nextPos); } -void VideoView::Backward( int millisecond ) +void VideoView::Backward(int millisecond) { int curPos = mVideoPlayer.GetPlayPosition(); int nextPos = curPos - millisecond; - nextPos = ( nextPos < 0 )? 0: nextPos; + nextPos = (nextPos < 0) ? 0 : nextPos; - mVideoPlayer.SetPlayPosition( nextPos ); + mVideoPlayer.SetPlayPosition(nextPos); } -void VideoView::SetMute( bool mute ) +void VideoView::SetMute(bool mute) { - mVideoPlayer.SetMute( mute ); + mVideoPlayer.SetMute(mute); } bool VideoView::IsMuted() @@ -277,14 +243,14 @@ bool VideoView::IsMuted() return mVideoPlayer.IsMuted(); } -void VideoView::SetVolume( float left, float right ) +void VideoView::SetVolume(float left, float right) { - mVideoPlayer.SetVolume( left, right ); + mVideoPlayer.SetVolume(left, right); } -void VideoView::GetVolume( float& left, float& right ) +void VideoView::GetVolume(float& left, float& right) { - mVideoPlayer.GetVolume( left, right ); + mVideoPlayer.GetVolume(left, right); } Dali::Toolkit::VideoView::VideoViewSignalType& VideoView::FinishedSignal() @@ -294,62 +260,57 @@ Dali::Toolkit::VideoView::VideoViewSignalType& VideoView::FinishedSignal() void VideoView::EmitSignalFinish() { - if( mOverlayRenderer ) + if(!mFinishedSignal.Empty()) { - Self().RemoveRenderer( mOverlayRenderer ); - } - - if ( !mFinishedSignal.Empty() ) - { - Dali::Toolkit::VideoView handle( GetOwner() ); - mFinishedSignal.Emit( handle ); + Dali::Toolkit::VideoView handle(GetOwner()); + mFinishedSignal.Emit(handle); } } -bool VideoView::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& attributes ) +bool VideoView::DoAction(BaseObject* object, const std::string& actionName, const Property::Map& attributes) { bool ret = false; - Dali::BaseHandle handle( object ); - Toolkit::VideoView videoView = Toolkit::VideoView::DownCast( handle ); + Dali::BaseHandle handle(object); + Toolkit::VideoView videoView = Toolkit::VideoView::DownCast(handle); - if( !videoView ) + if(!videoView) { return ret; } - VideoView& impl = GetImpl( videoView ); + VideoView& impl = GetImpl(videoView); - if( strcmp( actionName.c_str(), ACTION_VIDEOVIEW_PLAY ) == 0 ) + if(strcmp(actionName.c_str(), ACTION_VIDEOVIEW_PLAY) == 0) { impl.Play(); ret = true; } - else if( strcmp( actionName.c_str(), ACTION_VIDEOVIEW_PAUSE ) == 0 ) + else if(strcmp(actionName.c_str(), ACTION_VIDEOVIEW_PAUSE) == 0) { impl.Pause(); ret = true; } - else if( strcmp( actionName.c_str(), ACTION_VIDEOVIEW_STOP ) == 0 ) + else if(strcmp(actionName.c_str(), ACTION_VIDEOVIEW_STOP) == 0) { impl.Stop(); ret = true; } - else if( strcmp( actionName.c_str(), ACTION_VIDEOVIEW_FORWARD ) == 0 ) + else if(strcmp(actionName.c_str(), ACTION_VIDEOVIEW_FORWARD) == 0) { int millisecond = 0; - if( attributes["videoForward"].Get( millisecond ) ) + if(attributes["videoForward"].Get(millisecond)) { - impl.Forward( millisecond ); + impl.Forward(millisecond); ret = true; } } - else if( strcmp( actionName.c_str(), ACTION_VIDEOVIEW_BACKWARD ) == 0 ) + else if(strcmp(actionName.c_str(), ACTION_VIDEOVIEW_BACKWARD) == 0) { int millisecond = 0; - if( attributes["videoBackward"].Get( millisecond ) ) + if(attributes["videoBackward"].Get(millisecond)) { - impl.Backward( millisecond ); + impl.Backward(millisecond); ret = true; } } @@ -357,16 +318,16 @@ bool VideoView::DoAction( BaseObject* object, const std::string& actionName, con return ret; } -bool VideoView::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor ) +bool VideoView::DoConnectSignal(BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor) { - Dali::BaseHandle handle( object ); + Dali::BaseHandle handle(object); - bool connected( true ); - Toolkit::VideoView videoView = Toolkit::VideoView::DownCast( handle ); + bool connected(true); + Toolkit::VideoView videoView = Toolkit::VideoView::DownCast(handle); - if( 0 == strcmp( signalName.c_str(), FINISHED_SIGNAL ) ) + if(0 == strcmp(signalName.c_str(), FINISHED_SIGNAL)) { - videoView.FinishedSignal().Connect( tracker, functor ); + videoView.FinishedSignal().Connect(tracker, functor); } else { @@ -377,54 +338,54 @@ bool VideoView::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* return connected; } -void VideoView::SetPropertyInternal( Property::Index index, const Property::Value& value ) +void VideoView::SetPropertyInternal(Property::Index index, const Property::Value& value) { - switch( index ) + switch(index) { case Toolkit::VideoView::Property::VIDEO: { - std::string videoUrl; + std::string videoUrl; Property::Map map; - if( value.Get( videoUrl ) ) + if(value.Get(videoUrl)) { - SetUrl( videoUrl ); + SetUrl(videoUrl); } - else if( value.Get( map ) ) + else if(value.Get(map)) { - SetPropertyMap( map ); + SetPropertyMap(map); } break; } case Toolkit::VideoView::Property::LOOPING: { bool looping; - if( value.Get( looping ) ) + if(value.Get(looping)) { - SetLooping( looping ); + SetLooping(looping); } break; } case Toolkit::VideoView::Property::MUTED: { bool mute; - if( value.Get( mute ) ) + if(value.Get(mute)) { - SetMute( mute ); + SetMute(mute); } break; } case Toolkit::VideoView::Property::VOLUME: { Property::Map map; - float left, right; - if( value.Get( map ) ) + float left, right; + if(value.Get(map)) { - Property::Value* volumeLeft = map.Find( VOLUME_LEFT ); - Property::Value* volumeRight = map.Find( VOLUME_RIGHT ); - if( volumeLeft && volumeLeft->Get( left ) && volumeRight && volumeRight->Get( right ) ) + Property::Value* volumeLeft = map.Find(VOLUME_LEFT); + Property::Value* volumeRight = map.Find(VOLUME_RIGHT); + if(volumeLeft && volumeLeft->Get(left) && volumeRight && volumeRight->Get(right)) { - SetVolume( left, right ); + SetVolume(left, right); } } break; @@ -432,44 +393,44 @@ void VideoView::SetPropertyInternal( Property::Index index, const Property::Valu case Toolkit::VideoView::Property::UNDERLAY: { bool underlay; - if( value.Get( underlay ) ) + if(value.Get(underlay)) { - SetUnderlay( underlay ); + SetUnderlay(underlay); } break; } case Toolkit::VideoView::Property::PLAY_POSITION: { int pos; - if( value.Get( pos ) ) + if(value.Get(pos)) { - SetPlayPosition( pos ); + SetPlayPosition(pos); } break; } case Toolkit::VideoView::Property::DISPLAY_MODE: { int mode; - if( value.Get( mode ) ) + if(value.Get(mode)) { - SetDisplayMode( mode ); + SetDisplayMode(mode); } break; } } } -void VideoView::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value ) +void VideoView::SetProperty(BaseObject* object, Property::Index index, const Property::Value& value) { - Toolkit::VideoView videoView = Toolkit::VideoView::DownCast( Dali::BaseHandle( object ) ); + Toolkit::VideoView videoView = Toolkit::VideoView::DownCast(Dali::BaseHandle(object)); - if( videoView ) + if(videoView) { - VideoView& impl = GetImpl( videoView ); + VideoView& impl = GetImpl(videoView); - impl.SetPropertyInternal( index, value ); + impl.SetPropertyInternal(index, value); - if( index != Toolkit::VideoView::Property::UNDERLAY ) + if(index != Toolkit::VideoView::Property::UNDERLAY) { // Backup values. // These values will be used when underlay mode is changed. @@ -478,24 +439,24 @@ void VideoView::SetProperty( BaseObject* object, Property::Index index, const Pr } } -Property::Value VideoView::GetProperty( BaseObject* object, Property::Index propertyIndex ) +Property::Value VideoView::GetProperty(BaseObject* object, Property::Index propertyIndex) { - Property::Value value; - Toolkit::VideoView videoView = Toolkit::VideoView::DownCast( Dali::BaseHandle( object ) ); + Property::Value value; + Toolkit::VideoView videoView = Toolkit::VideoView::DownCast(Dali::BaseHandle(object)); - if( videoView ) + if(videoView) { - VideoView& impl = GetImpl( videoView ); + VideoView& impl = GetImpl(videoView); - switch( propertyIndex ) + switch(propertyIndex) { case Toolkit::VideoView::Property::VIDEO: { - if( !impl.mUrl.empty() ) + if(!impl.mUrl.empty()) { value = impl.mUrl; } - else if( !impl.mPropertyMap.Empty() ) + else if(!impl.mPropertyMap.Empty()) { value = impl.mPropertyMap; } @@ -514,11 +475,11 @@ Property::Value VideoView::GetProperty( BaseObject* object, Property::Index prop case Toolkit::VideoView::Property::VOLUME: { Property::Map map; - float left, right; + float left, right; - impl.GetVolume( left, right ); - map.Insert( VOLUME_LEFT, left ); - map.Insert( VOLUME_RIGHT, right ); + impl.GetVolume(left, right); + map.Insert(VOLUME_LEFT, left); + map.Insert(VOLUME_RIGHT, right); value = map; break; } @@ -543,27 +504,91 @@ Property::Value VideoView::GetProperty( BaseObject* object, Property::Index prop return value; } -void VideoView::SetDepthIndex( int depthIndex ) +void VideoView::SetDepthIndex(int depthIndex) { - if( mTextureRenderer ) + if(mTextureRenderer) { - mTextureRenderer.SetProperty( Renderer::Property::DEPTH_INDEX, depthIndex ); + mTextureRenderer.SetProperty(Renderer::Property::DEPTH_INDEX, depthIndex); } } -void VideoView::OnStageConnection( int depth ) +void VideoView::OnSceneConnection(int depth) { - Control::OnStageConnection( depth ); - - if( mIsUnderlay ) + Actor self = Self(); + if(mIsUnderlay) { + mSiblingOrder = self.GetProperty(Dali::DevelActor::Property::SIBLING_ORDER); + DevelActor::ChildOrderChangedSignal(self.GetParent()).Connect(this, &VideoView::OnChildOrderChanged); SetWindowSurfaceTarget(); } + + Control::OnSceneConnection(depth); } -void VideoView::OnStageDisconnection() +void VideoView::OnSceneDisconnection() { - Control::OnStageDisconnection(); + Control::OnSceneDisconnection(); +} + +void VideoView::OnSizeSet(const Vector3& targetSize) +{ + if(mIsUnderlay && mSyncMode == Dali::VideoSyncMode::ENABLED) + { + SetFrameRenderCallback(); + mVideoPlayer.StartSynchronization(); + } + Control::OnSizeSet(targetSize); +} + +void VideoView::OnChildOrderChanged(Actor actor) +{ + Actor self = Self(); + int currentSiblingOrder = self.GetProperty(Dali::DevelActor::Property::SIBLING_ORDER); + if(currentSiblingOrder != mSiblingOrder) + { + Actor parent = self.GetParent(); + Actor child; + Actor upper; + Actor lower; + + int numChildren = static_cast(parent.GetChildCount()); + for(int i = 0; i < numChildren; i++) + { + child = parent.GetChildAt(i); + if(!IsVideoView(child)) + { + continue; + } + + if(child == self) + { + continue; + } + + if(i < currentSiblingOrder) + { + lower = child; + } + else if(i > currentSiblingOrder) + { + upper = child; + break; + } + } + + if(lower) + { + Toolkit::VideoView lowerView = Toolkit::VideoView::DownCast(lower); + mVideoPlayer.RaiseAbove(GetImpl(lowerView).GetVideoPlayer()); + } + + if(upper) + { + Toolkit::VideoView upperView = Toolkit::VideoView::DownCast(upper); + mVideoPlayer.LowerBelow(GetImpl(upperView).GetVideoPlayer()); + } + mSiblingOrder = currentSiblingOrder; + } } Vector3 VideoView::GetNaturalSize() @@ -572,9 +597,9 @@ Vector3 VideoView::GetNaturalSize() size.x = mVideoSize.GetWidth(); size.y = mVideoSize.GetHeight(); - if( size.x > 0 && size.y > 0 ) + if(size.x > 0 && size.y > 0) { - size.z = std::min( size.x, size.y ); + size.z = std::min(size.x, size.y); return size; } else @@ -583,27 +608,27 @@ Vector3 VideoView::GetNaturalSize() } } -float VideoView::GetHeightForWidth( float width ) +float VideoView::GetHeightForWidth(float width) { - if( mVideoSize.GetWidth() > 0 && mVideoSize.GetHeight() > 0 ) + if(mVideoSize.GetWidth() > 0 && mVideoSize.GetHeight() > 0) { - return GetHeightForWidthBase( width ); + return GetHeightForWidthBase(width); } else { - return Control::GetHeightForWidthBase( width ); + return Control::GetHeightForWidthBase(width); } } -float VideoView::GetWidthForHeight( float height ) +float VideoView::GetWidthForHeight(float height) { - if( mVideoSize.GetWidth() > 0 && mVideoSize.GetHeight() > 0 ) + if(mVideoSize.GetWidth() > 0 && mVideoSize.GetHeight() > 0) { - return GetWidthForHeightBase( height ); + return GetWidthForHeightBase(height); } else { - return Control::GetWidthForHeightBase( height ); + return Control::GetWidthForHeightBase(height); } } @@ -611,152 +636,158 @@ void VideoView::SetWindowSurfaceTarget() { Actor self = Self(); - if( !self.OnStage() ) + if(!self.GetProperty(Actor::Property::CONNECTED_TO_SCENE)) { // When the control is off the stage, it does not have Window. return; } + Dali::Window window = DevelWindow::Get(self); + window.ResizeSignal().Connect(this, &VideoView::OnWindowResized); + int curPos = mVideoPlayer.GetPlayPosition(); - if( mIsPlay ) + 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 ); + 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); - if( mTextureRenderer ) + if(mTextureRenderer) { - self.RemoveRenderer( mTextureRenderer ); + self.RemoveRenderer(mTextureRenderer); } // Note VideoPlayer::SetRenderingTarget resets all the options. (e.g. url, mute, looping) - mVideoPlayer.SetRenderingTarget( Dali::Adaptor::Get().GetNativeWindowHandle( self ) ); + mVideoPlayer.SetRenderingTarget(Dali::Adaptor::Get().GetNativeWindowHandle(self)); ApplyBackupProperties(); - if( !mOverlayRenderer ) + if(!mOverlayRenderer) { // For underlay rendering mode, video display area have to be transparent. Geometry geometry = VisualFactoryCache::CreateQuadGeometry(); - Shader shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER ); - mOverlayRenderer = Renderer::New( geometry, shader ); - mOverlayRenderer.SetProperty( Renderer::Property::BLEND_MODE, BlendMode::OFF ); + Shader shader = Shader::New(SHADER_VIDEO_VIEW_VERT, SHADER_VIDEO_VIEW_FRAG); + mOverlayRenderer = Renderer::New(geometry, shader); + mOverlayRenderer.SetProperty(Renderer::Property::BLEND_MODE, BlendMode::OFF); } + Self().AddRenderer(mOverlayRenderer); - if( mIsPlay ) + if(mIsPlay) { Play(); } - if( curPos > 0 ) + if(curPos > 0) { - mVideoPlayer.SetPlayPosition( curPos ); + mVideoPlayer.SetPlayPosition(curPos); } } void VideoView::SetNativeImageTarget() { - if( mVideoPlayer.IsVideoTextureSupported() == false ) + if(mVideoPlayer.IsVideoTextureSupported() == false) { - DALI_LOG_ERROR( "Platform doesn't support decoded video frame images\n" ); + DALI_LOG_ERROR("Platform doesn't support decoded video frame images\n"); mIsUnderlay = true; return; } - if( mIsPlay ) + if(mIsPlay) { mVideoPlayer.Pause(); } - Actor self( Self() ); + Actor self(Self()); - if( mOverlayRenderer ) + if(mOverlayRenderer) { - self.RemoveRenderer( mOverlayRenderer ); + self.RemoveRenderer(mOverlayRenderer); mOverlayRenderer.Reset(); } - self.RemovePropertyNotification( mPositionUpdateNotification ); - self.RemovePropertyNotification( mSizeUpdateNotification ); - self.RemovePropertyNotification( mScaleUpdateNotification ); + self.RemovePropertyNotification(mPositionUpdateNotification); + self.RemovePropertyNotification(mSizeUpdateNotification); + self.RemovePropertyNotification(mScaleUpdateNotification); int curPos = mVideoPlayer.GetPlayPosition(); - Any source; - Dali::NativeImageSourcePtr nativeImageSourcePtr = Dali::NativeImageSource::New( source ); - mNativeTexture = Dali::Texture::New( *nativeImageSourcePtr ); + Any source; + Dali::NativeImageSourcePtr nativeImageSourcePtr = Dali::NativeImageSource::New(source); + mNativeTexture = Dali::Texture::New(*nativeImageSourcePtr); - if( !mTextureRenderer ) + if(!mTextureRenderer) { - Dali::Geometry geometry = VisualFactoryCache::CreateQuadGeometry(); - Dali::Shader shader = CreateShader(); + Dali::Geometry geometry = VisualFactoryCache::CreateQuadGeometry(); + Dali::Shader shader = CreateShader(); Dali::TextureSet textureSet = Dali::TextureSet::New(); - textureSet.SetTexture( 0u, mNativeTexture ); + textureSet.SetTexture(0u, mNativeTexture); - mTextureRenderer = Renderer::New( geometry, shader ); - mTextureRenderer.SetTextures( textureSet ); + mTextureRenderer = Renderer::New(geometry, shader); + mTextureRenderer.SetTextures(textureSet); } else { Dali::TextureSet textureSet = mTextureRenderer.GetTextures(); - textureSet.SetTexture( 0u, mNativeTexture ); + textureSet.SetTexture(0u, mNativeTexture); } - Self().AddRenderer( mTextureRenderer ); + Self().AddRenderer(mTextureRenderer); // Note VideoPlayer::SetRenderingTarget resets all the options. (e.g. url, mute, looping) - mVideoPlayer.SetRenderingTarget( nativeImageSourcePtr ); + mVideoPlayer.SetRenderingTarget(nativeImageSourcePtr); ApplyBackupProperties(); - if( mIsPlay ) + if(mIsPlay) { Play(); } - if( curPos > 0 ) + if(curPos > 0) { - mVideoPlayer.SetPlayPosition( curPos ); + mVideoPlayer.SetPlayPosition(curPos); } } -void VideoView::UpdateDisplayArea( Dali::PropertyNotification& source ) +void VideoView::UpdateDisplayArea(Dali::PropertyNotification& source) { - if( !mIsUnderlay ) + // If mSyncMode is enabled, Video player's size and poistion is updated in Video player's constraint. + // Because video view and player should be work syncronization. + if(!mIsUnderlay || mSyncMode == Dali::VideoSyncMode::ENABLED) { return; } - Actor self( Self() ); + Actor self(Self()); - bool positionUsesAnchorPoint = self.GetProperty( DevelActor::Property::POSITION_USES_ANCHOR_POINT ).Get< bool >(); - Vector3 actorSize = self.GetCurrentProperty< Vector3 >( Actor::Property::SIZE ) * self.GetCurrentProperty< Vector3 >( Actor::Property::SCALE ); - Vector3 anchorPointOffSet = actorSize * ( positionUsesAnchorPoint ? self.GetCurrentProperty< Vector3 >( Actor::Property::ANCHOR_POINT ) : AnchorPoint::TOP_LEFT ); + bool positionUsesAnchorPoint = self.GetProperty(Actor::Property::POSITION_USES_ANCHOR_POINT).Get(); + Vector3 actorSize = self.GetCurrentProperty(Actor::Property::SIZE) * self.GetCurrentProperty(Actor::Property::SCALE); + Vector3 anchorPointOffSet = actorSize * (positionUsesAnchorPoint ? self.GetCurrentProperty(Actor::Property::ANCHOR_POINT) : AnchorPoint::TOP_LEFT); - Vector2 screenPosition = self.GetProperty( DevelActor::Property::SCREEN_POSITION ).Get< Vector2 >(); + Vector2 screenPosition = self.GetProperty(Actor::Property::SCREEN_POSITION).Get(); - mDisplayArea.x = screenPosition.x - anchorPointOffSet.x; - mDisplayArea.y = screenPosition.y - anchorPointOffSet.y; - mDisplayArea.width = actorSize.x; + mDisplayArea.x = screenPosition.x - anchorPointOffSet.x; + mDisplayArea.y = screenPosition.y - anchorPointOffSet.y; + mDisplayArea.width = actorSize.x; mDisplayArea.height = actorSize.y; - mVideoPlayer.SetDisplayArea( mDisplayArea ); + mVideoPlayer.SetDisplayArea(mDisplayArea); } -void VideoView::SetUnderlay( bool set ) +void VideoView::SetUnderlay(bool set) { - if( set != mIsUnderlay ) + if(set != mIsUnderlay) { mIsUnderlay = set; - if( mIsUnderlay ) + if(mIsUnderlay) { SetWindowSurfaceTarget(); } @@ -774,17 +805,17 @@ bool VideoView::IsUnderlay() return mIsUnderlay; } -void VideoView::SetSWCodec( bool on ) +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 ) + if(on) { - mVideoPlayer.SetCodecType( Dali::VideoPlayerPlugin::CodecType::SW ); + mVideoPlayer.SetCodecType(Dali::VideoPlayerPlugin::CodecType::SW); } else { - mVideoPlayer.SetCodecType( Dali::VideoPlayerPlugin::CodecType::HW ); + mVideoPlayer.SetCodecType(Dali::VideoPlayerPlugin::CodecType::HW); } } @@ -793,19 +824,19 @@ int VideoView::GetPlayPosition() return mVideoPlayer.GetPlayPosition(); } -void VideoView::SetPlayPosition( int pos ) +void VideoView::SetPlayPosition(int pos) { - mVideoPlayer.SetPlayPosition( pos ); + mVideoPlayer.SetPlayPosition(pos); } -void VideoView::SetDisplayMode( int mode ) +void VideoView::SetDisplayMode(int mode) { - mVideoPlayer.SetDisplayMode( static_cast< Dali::VideoPlayerPlugin::DisplayMode::Type >( mode ) ); + mVideoPlayer.SetDisplayMode(static_cast(mode)); } int VideoView::GetDisplayMode() const { - return static_cast< int >( mVideoPlayer.GetDisplayMode() ); + return static_cast(mVideoPlayer.GetDisplayMode()); } Any VideoView::GetMediaPlayer() @@ -813,55 +844,84 @@ Any VideoView::GetMediaPlayer() return mVideoPlayer.GetMediaPlayer(); } +void VideoView::OnAnimationFinished(Animation& animation) +{ + // send desync + SetFrameRenderCallback(); +} + +void VideoView::OnWindowResized(Dali::Window winHandle, Dali::Window::WindowSize size) +{ + Dali::VideoPlayerPlugin::DisplayRotation videoAngle = mVideoPlayer.GetDisplayRotation(); + int windowAngle = (DevelWindow::GetPhysicalOrientation(winHandle) / 90); + + if(windowAngle != videoAngle) + { + mVideoPlayer.SetDisplayRotation(static_cast(windowAngle)); + } +} + +void VideoView::PlayAnimation(Dali::Animation animation) +{ + if(mIsUnderlay && mSyncMode == Dali::VideoSyncMode::ENABLED) + { + mVideoPlayer.StartSynchronization(); + animation.FinishedSignal().Connect(this, &VideoView::OnAnimationFinished); + } + animation.Play(); +} + Dali::Shader VideoView::CreateShader() { - std::string fragmentShader = "#extension GL_OES_EGL_image_external:require\n"; + std::string fragmentShader; std::string vertexShader; std::string customFragmentShader; - bool checkShader = false; + bool checkShader = false; - if( !mEffectPropertyMap.Empty() ) + if(!mEffectPropertyMap.Empty()) { - Property::Value* vertexShaderValue = mEffectPropertyMap.Find( CUSTOM_VERTEX_SHADER ); - if( vertexShaderValue ) + Property::Value* vertexShaderValue = mEffectPropertyMap.Find(CUSTOM_VERTEX_SHADER); + if(vertexShaderValue) { - checkShader = GetStringFromProperty( *vertexShaderValue, vertexShader ); + checkShader = GetStringFromProperty(*vertexShaderValue, vertexShader); } - if( !vertexShaderValue || !checkShader ) + if(!vertexShaderValue || !checkShader) { - vertexShader = VERTEX_SHADER_TEXTURE; + vertexShader = SHADER_VIDEO_VIEW_TEXTURE_VERT.data(); } - Property::Value* fragmentShaderValue = mEffectPropertyMap.Find( CUSTOM_FRAGMENT_SHADER ); - if( fragmentShaderValue ) + Property::Value* fragmentShaderValue = mEffectPropertyMap.Find(CUSTOM_FRAGMENT_SHADER); + if(fragmentShaderValue) { - checkShader = GetStringFromProperty( *fragmentShaderValue, customFragmentShader ); + checkShader = GetStringFromProperty(*fragmentShaderValue, customFragmentShader); - if( checkShader ) + if(checkShader) { fragmentShader = customFragmentShader; } } - if( !fragmentShaderValue || !checkShader ) + if(!fragmentShaderValue || !checkShader) { - fragmentShader += FRAGMENT_SHADER_TEXTURE; + fragmentShader = SHADER_VIDEO_VIEW_TEXTURE_FRAG.data(); + DevelTexture::ApplyNativeFragmentShader(mNativeTexture, fragmentShader); } } else { - vertexShader = VERTEX_SHADER_TEXTURE; - fragmentShader += FRAGMENT_SHADER_TEXTURE; + vertexShader = SHADER_VIDEO_VIEW_TEXTURE_VERT.data(); + fragmentShader = SHADER_VIDEO_VIEW_TEXTURE_FRAG.data(); + DevelTexture::ApplyNativeFragmentShader(mNativeTexture, fragmentShader); } - return Dali::Shader::New( vertexShader, fragmentShader ); + return Dali::Shader::New(vertexShader, fragmentShader); } -bool VideoView::GetStringFromProperty( const Dali::Property::Value& value, std::string& output ) +bool VideoView::GetStringFromProperty(const Dali::Property::Value& value, std::string& output) { bool extracted = false; - if( value.Get( output ) ) + if(value.Get(output)) { extracted = true; } @@ -871,19 +931,59 @@ bool VideoView::GetStringFromProperty( const Dali::Property::Value& value, std:: void VideoView::ApplyBackupProperties() { - Property::Map::SizeType pos = 0; + Property::Map::SizeType pos = 0; Property::Map::SizeType count = mPropertyBackup.Count(); - for( ; pos < count; pos++ ) + for(; pos < count; pos++) { - KeyValuePair property = mPropertyBackup.GetKeyValue( pos ); + KeyValuePair property = mPropertyBackup.GetKeyValue(pos); - SetPropertyInternal( property.first.indexKey, property.second ); + SetPropertyInternal(property.first.indexKey, property.second); } } +void VideoView::FrameRenderCallback(int frameID) +{ + // send desync + if(frameID == mFrameID) + { + mVideoPlayer.FinishSynchronization(); + mFrameID = 0; + } +} + +void VideoView::SetFrameRenderCallback() +{ + mFrameID++; + DevelWindow::AddFrameRenderedCallback(DevelWindow::Get(Self()), + std::unique_ptr(MakeCallback(this, &VideoView::FrameRenderCallback)), + mFrameID); +} + +bool VideoView::IsVideoView(Actor actor) const +{ + // Check whether the actor is a VideoView + bool isVideoView = false; + + if(actor) + { + Property::Index propertyIsVideoView = actor.GetPropertyIndex(IS_VIDEO_VIEW_PROPERTY_NAME); + if(propertyIsVideoView != Property::INVALID_INDEX) + { + isVideoView = actor.GetProperty(propertyIsVideoView); + } + } + + return isVideoView; +} + +VideoPlayer VideoView::GetVideoPlayer() +{ + return mVideoPlayer; +} + } // namespace Internal -} // namespace toolkit +} // namespace Toolkit } // namespace Dali