[Tizen](ATSPI) squashed implementation
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / video-view / video-view-impl.cpp
1 /*
2  * Copyright (c) 2018 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include "video-view-impl.h"
20
21 // EXTERNAL INCLUDES
22 #include <cstring>
23 #include <dali/public-api/object/type-registry.h>
24 #include <dali/public-api/object/type-registry-helper.h>
25 #include <dali/public-api/common/stage.h>
26 #include <dali/devel-api/scripting/scripting.h>
27 #include <dali/public-api/adaptor-framework/native-image-source.h>
28 #include <dali/integration-api/adaptors/adaptor.h>
29 #include <dali/integration-api/debug.h>
30 #include <dali/public-api/animation/constraint.h>
31 #include <dali/devel-api/actors/actor-devel.h>
32
33 // INTERNAL INCLUDES
34 #include <dali-toolkit/public-api/controls/video-view/video-view.h>
35 #include <dali-toolkit/internal/visuals/visual-factory-cache.h>
36 #include <dali-toolkit/internal/controls/control/control-data-impl.h>
37
38 namespace Dali
39 {
40
41 namespace Toolkit
42 {
43
44 namespace Internal
45 {
46
47 namespace
48 {
49
50 BaseHandle Create()
51 {
52   return Toolkit::VideoView::New();
53 }
54
55 DALI_TYPE_REGISTRATION_BEGIN( Toolkit::VideoView, Toolkit::Control, Create );
56
57 DALI_PROPERTY_REGISTRATION( Toolkit, VideoView, "video", MAP, VIDEO )
58 DALI_PROPERTY_REGISTRATION( Toolkit, VideoView, "looping", BOOLEAN, LOOPING )
59 DALI_PROPERTY_REGISTRATION( Toolkit, VideoView, "muted", BOOLEAN, MUTED )
60 DALI_PROPERTY_REGISTRATION( Toolkit, VideoView, "volume", MAP, VOLUME )
61 DALI_PROPERTY_REGISTRATION( Toolkit, VideoView, "underlay", BOOLEAN, UNDERLAY )
62 DALI_PROPERTY_REGISTRATION( Toolkit, VideoView, "playPosition", INTEGER, PLAY_POSITION )
63 DALI_PROPERTY_REGISTRATION( Toolkit, VideoView, "displayMode", INTEGER, DISPLAY_MODE )
64
65 DALI_SIGNAL_REGISTRATION( Toolkit, VideoView, "finished", FINISHED_SIGNAL )
66
67 DALI_ACTION_REGISTRATION( Toolkit, VideoView, "play", ACTION_VIDEOVIEW_PLAY )
68 DALI_ACTION_REGISTRATION( Toolkit, VideoView, "pause", ACTION_VIDEOVIEW_PAUSE )
69 DALI_ACTION_REGISTRATION( Toolkit, VideoView, "stop", ACTION_VIDEOVIEW_STOP )
70 DALI_ACTION_REGISTRATION( Toolkit, VideoView, "forward", ACTION_VIDEOVIEW_FORWARD )
71 DALI_ACTION_REGISTRATION( Toolkit, VideoView, "backward", ACTION_VIDEOVIEW_BACKWARD )
72
73 DALI_TYPE_REGISTRATION_END()
74
75 const char* const VOLUME_LEFT( "volumeLeft" );
76 const char* const VOLUME_RIGHT( "volumeRight" );
77
78 // 3.0 TC uses RENDERING_TARGET. It should be removed in next release
79 const char* const RENDERING_TARGET( "renderingTarget" );
80 const char* const WINDOW_SURFACE_TARGET( "windowSurfaceTarget" );
81 const char* const NATIVE_IMAGE_TARGET( "nativeImageTarget" );
82
83 const char* const CUSTOM_SHADER( "shader" );
84 const char* const CUSTOM_VERTEX_SHADER( "vertexShader" );
85 const char* const CUSTOM_FRAGMENT_SHADER( "fragmentShader" );
86 const char* const DEFAULT_SAMPLER_TYPE_NAME( "sampler2D" );
87 const char* const CUSTOM_SAMPLER_TYPE_NAME( "samplerExternalOES" );
88
89 const char* VERTEX_SHADER = DALI_COMPOSE_SHADER(
90   attribute mediump vec2 aPosition;\n
91   uniform highp   mat4 uMvpMatrix;\n
92   uniform mediump vec3 uSize;\n
93   \n
94   void main()\n
95   {\n
96     mediump vec4 vertexPosition = vec4(aPosition, 0.0, 1.0);\n
97     vertexPosition.xyz *= uSize;\n
98     gl_Position = uMvpMatrix * vertexPosition;\n
99   }\n
100 );
101
102 const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER(
103   \n
104   void main()\n
105   {\n
106     gl_FragColor = vec4(0.0);\n
107   }\n
108 );
109
110 const char* VERTEX_SHADER_TEXTURE = DALI_COMPOSE_SHADER(
111   attribute mediump vec2 aPosition;\n
112   varying mediump vec2 vTexCoord;\n
113   uniform highp   mat4 uMvpMatrix;\n
114   uniform mediump vec3 uSize;\n
115   varying mediump vec2 sTexCoordRect;\n
116   void main()\n
117   {\n
118     gl_Position = uMvpMatrix * vec4(aPosition * uSize.xy, 0.0, 1.0);\n
119     vTexCoord = aPosition + vec2(0.5);\n
120   }\n
121 );
122
123 const char* FRAGMENT_SHADER_TEXTURE = DALI_COMPOSE_SHADER(
124   uniform lowp vec4 uColor;\n
125   varying mediump vec2 vTexCoord;\n
126   uniform samplerExternalOES sTexture;\n
127   void main()\n
128   {\n
129     gl_FragColor = texture2D( sTexture, vTexCoord ) * uColor;\n
130   }\n
131 );
132
133 } // anonymous namepsace
134
135 VideoView::VideoView()
136 : Control( ControlBehaviour( ACTOR_BEHAVIOUR_DEFAULT | DISABLE_STYLE_CHANGE_SIGNALS ) ),
137   mCurrentVideoPlayPosition( 0 ),
138   mIsPlay( false ),
139   mIsUnderlay( true )
140 {
141   mVideoPlayer = Dali::VideoPlayer::New();
142   DevelControl::SetAccessibilityConstructor( Self(), []( Dali::Actor actor )
143     {
144       return std::unique_ptr< Dali::Accessibility::Accessible >(
145         new Control::Impl::AccessibleImpl( actor, Dali::Accessibility::Role::VIDEO, true ) );
146     }
147   );
148 }
149
150 VideoView::~VideoView()
151 {
152 }
153
154 Toolkit::VideoView VideoView::New()
155 {
156   VideoView* impl = new VideoView();
157   Toolkit::VideoView handle = Toolkit::VideoView( *impl );
158
159   impl->Initialize();
160
161   return handle;
162 }
163
164 void VideoView::OnInitialize()
165 {
166   mVideoPlayer.FinishedSignal().Connect( this, &VideoView::EmitSignalFinish );
167 }
168
169 void VideoView::SetUrl( const std::string& url )
170 {
171     mUrl = url;
172     mPropertyMap.Clear();
173
174   mVideoPlayer.SetUrl( mUrl );
175 }
176
177 void VideoView::SetPropertyMap( Property::Map map )
178 {
179   mPropertyMap = map;
180
181   Property::Value* target = map.Find( RENDERING_TARGET );
182   std::string targetType;
183
184   if( target && target->Get( targetType ) && targetType == WINDOW_SURFACE_TARGET )
185   {
186     mIsUnderlay = true;
187     SetWindowSurfaceTarget();
188   }
189   else if( target && target->Get( targetType ) && targetType == NATIVE_IMAGE_TARGET )
190   {
191     mIsUnderlay = false;
192     SetNativeImageTarget();
193   }
194
195   // Custom shader
196   Property::Value* shaderValue;
197   if( !map.Empty() )
198   {
199     shaderValue = map.Find( CUSTOM_SHADER );
200
201     if( shaderValue )
202     {
203       Property::Map* shaderMap = shaderValue->GetMap();
204       if( shaderMap )
205       {
206         mEffectPropertyMap = *shaderMap;
207       }
208     }
209   }
210
211   if( mTextureRenderer && !mEffectPropertyMap.Empty() )
212   {
213     Dali::Shader shader = CreateShader();
214     mTextureRenderer.SetShader( shader );
215   }
216
217   RelayoutRequest();
218 }
219
220 std::string VideoView::GetUrl()
221 {
222   return mUrl;
223 }
224
225 void VideoView::SetLooping( bool looping )
226 {
227   mVideoPlayer.SetLooping( looping );
228 }
229
230 bool VideoView::IsLooping()
231 {
232   return mVideoPlayer.IsLooping();
233 }
234
235 void VideoView::Play()
236 {
237   if( mOverlayRenderer )
238   {
239     Self().AddRenderer( mOverlayRenderer );
240   }
241
242   mVideoPlayer.Play();
243   mIsPlay = true;
244 }
245
246 void VideoView::Pause()
247 {
248   mVideoPlayer.Pause();
249   mIsPlay = false;
250 }
251
252 void VideoView::Stop()
253 {
254   mVideoPlayer.Stop();
255   mIsPlay = false;
256 }
257
258 void VideoView::Forward( int millisecond )
259 {
260   int curPos = mVideoPlayer.GetPlayPosition();
261
262   int nextPos = curPos + millisecond;
263
264   mVideoPlayer.SetPlayPosition( nextPos );
265 }
266
267 void VideoView::Backward( int millisecond )
268 {
269   int curPos = mVideoPlayer.GetPlayPosition();
270
271   int nextPos = curPos - millisecond;
272   nextPos = ( nextPos < 0 )? 0: nextPos;
273
274   mVideoPlayer.SetPlayPosition( nextPos );
275 }
276
277 void VideoView::SetMute( bool mute )
278 {
279   mVideoPlayer.SetMute( mute );
280 }
281
282 bool VideoView::IsMuted()
283 {
284   return mVideoPlayer.IsMuted();
285 }
286
287 void VideoView::SetVolume( float left, float right )
288 {
289   mVideoPlayer.SetVolume( left, right );
290 }
291
292 void VideoView::GetVolume( float& left, float& right )
293 {
294   mVideoPlayer.GetVolume( left, right );
295 }
296
297 Dali::Toolkit::VideoView::VideoViewSignalType& VideoView::FinishedSignal()
298 {
299   return mFinishedSignal;
300 }
301
302 void VideoView::EmitSignalFinish()
303 {
304   if( mOverlayRenderer )
305   {
306     Self().RemoveRenderer( mOverlayRenderer );
307   }
308
309   if ( !mFinishedSignal.Empty() )
310   {
311     Dali::Toolkit::VideoView handle( GetOwner() );
312     mFinishedSignal.Emit( handle );
313   }
314 }
315
316 bool VideoView::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& attributes )
317 {
318   bool ret = false;
319
320   Dali::BaseHandle handle( object );
321   Toolkit::VideoView videoView = Toolkit::VideoView::DownCast( handle );
322
323   if( !videoView )
324   {
325     return ret;
326   }
327
328   VideoView& impl = GetImpl( videoView );
329
330   if( strcmp( actionName.c_str(), ACTION_VIDEOVIEW_PLAY ) == 0 )
331   {
332     impl.Play();
333     ret = true;
334   }
335   else if( strcmp( actionName.c_str(), ACTION_VIDEOVIEW_PAUSE ) == 0 )
336   {
337     impl.Pause();
338     ret = true;
339   }
340   else if( strcmp( actionName.c_str(), ACTION_VIDEOVIEW_STOP ) == 0 )
341   {
342     impl.Stop();
343     ret = true;
344   }
345   else if( strcmp( actionName.c_str(), ACTION_VIDEOVIEW_FORWARD ) == 0 )
346   {
347     int millisecond = 0;
348     if( attributes["videoForward"].Get( millisecond ) )
349     {
350       impl.Forward( millisecond );
351       ret = true;
352     }
353   }
354   else if( strcmp( actionName.c_str(), ACTION_VIDEOVIEW_BACKWARD ) == 0 )
355   {
356     int millisecond = 0;
357     if( attributes["videoBackward"].Get( millisecond ) )
358     {
359       impl.Backward( millisecond );
360       ret = true;
361     }
362   }
363
364   return ret;
365 }
366
367 bool VideoView::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
368 {
369   Dali::BaseHandle handle( object );
370
371   bool connected( true );
372   Toolkit::VideoView videoView = Toolkit::VideoView::DownCast( handle );
373
374   if( 0 == strcmp( signalName.c_str(), FINISHED_SIGNAL ) )
375   {
376     videoView.FinishedSignal().Connect( tracker, functor );
377   }
378   else
379   {
380     // signalName does not match any signal
381     connected = false;
382   }
383
384   return connected;
385 }
386
387 void VideoView::SetPropertyInternal( Property::Index index, const Property::Value& value )
388 {
389   switch( index )
390   {
391     case Toolkit::VideoView::Property::VIDEO:
392     {
393       std::string videoUrl;
394       Property::Map map;
395
396       if( value.Get( videoUrl ) )
397       {
398         SetUrl( videoUrl );
399       }
400       else if( value.Get( map ) )
401       {
402         SetPropertyMap( map );
403       }
404       break;
405     }
406     case Toolkit::VideoView::Property::LOOPING:
407     {
408       bool looping;
409       if( value.Get( looping ) )
410       {
411         SetLooping( looping );
412       }
413       break;
414     }
415     case Toolkit::VideoView::Property::MUTED:
416     {
417       bool mute;
418       if( value.Get( mute ) )
419       {
420         SetMute( mute );
421       }
422       break;
423     }
424     case Toolkit::VideoView::Property::VOLUME:
425     {
426       Property::Map map;
427       float left, right;
428       if( value.Get( map ) )
429       {
430         Property::Value* volumeLeft = map.Find( VOLUME_LEFT );
431         Property::Value* volumeRight = map.Find( VOLUME_RIGHT );
432         if( volumeLeft && volumeLeft->Get( left ) && volumeRight && volumeRight->Get( right ) )
433         {
434           SetVolume( left, right );
435         }
436       }
437       break;
438     }
439     case Toolkit::VideoView::Property::UNDERLAY:
440     {
441       bool underlay;
442       if( value.Get( underlay ) )
443       {
444         SetUnderlay( underlay );
445       }
446       break;
447     }
448     case Toolkit::VideoView::Property::PLAY_POSITION:
449     {
450       int pos;
451       if( value.Get( pos ) )
452       {
453         SetPlayPosition( pos );
454       }
455       break;
456     }
457     case Toolkit::VideoView::Property::DISPLAY_MODE:
458     {
459       int mode;
460       if( value.Get( mode ) )
461       {
462         SetDisplayMode( mode );
463       }
464       break;
465     }
466   }
467 }
468
469 void VideoView::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
470 {
471   Toolkit::VideoView videoView = Toolkit::VideoView::DownCast( Dali::BaseHandle( object ) );
472
473   if( videoView )
474   {
475     VideoView& impl = GetImpl( videoView );
476
477     impl.SetPropertyInternal( index, value );
478
479     if( index != Toolkit::VideoView::Property::UNDERLAY )
480     {
481       // Backup values.
482       // These values will be used when underlay mode is changed.
483       impl.mPropertyBackup[index] = value;
484     }
485   }
486 }
487
488 Property::Value VideoView::GetProperty( BaseObject* object, Property::Index propertyIndex )
489 {
490   Property::Value value;
491   Toolkit::VideoView videoView = Toolkit::VideoView::DownCast( Dali::BaseHandle( object ) );
492
493   if( videoView )
494   {
495     VideoView& impl = GetImpl( videoView );
496
497     switch( propertyIndex )
498     {
499       case Toolkit::VideoView::Property::VIDEO:
500       {
501         if( !impl.mUrl.empty() )
502         {
503           value = impl.mUrl;
504         }
505         else if( !impl.mPropertyMap.Empty() )
506         {
507           value = impl.mPropertyMap;
508         }
509         break;
510       }
511       case Toolkit::VideoView::Property::LOOPING:
512       {
513         value = impl.IsLooping();
514         break;
515       }
516       case Toolkit::VideoView::Property::MUTED:
517       {
518         value = impl.IsMuted();
519         break;
520       }
521       case Toolkit::VideoView::Property::VOLUME:
522       {
523         Property::Map map;
524         float left, right;
525
526         impl.GetVolume( left, right );
527         map.Insert( VOLUME_LEFT, left );
528         map.Insert( VOLUME_RIGHT, right );
529         value = map;
530         break;
531       }
532       case Toolkit::VideoView::Property::UNDERLAY:
533       {
534         value = impl.IsUnderlay();
535         break;
536       }
537       case Toolkit::VideoView::Property::PLAY_POSITION:
538       {
539         value = impl.GetPlayPosition();
540         break;
541       }
542       case Toolkit::VideoView::Property::DISPLAY_MODE:
543       {
544         value = impl.GetDisplayMode();
545         break;
546       }
547     }
548   }
549
550   return value;
551 }
552
553 void VideoView::SetDepthIndex( int depthIndex )
554 {
555   if( mTextureRenderer )
556   {
557     mTextureRenderer.SetProperty( Renderer::Property::DEPTH_INDEX, depthIndex );
558   }
559 }
560
561 void VideoView::OnStageConnection( int depth )
562 {
563   Control::OnStageConnection( depth );
564
565   if( mIsUnderlay )
566   {
567     SetWindowSurfaceTarget();
568   }
569 }
570
571 void VideoView::OnStageDisconnection()
572 {
573   Control::OnStageDisconnection();
574 }
575
576 Vector3 VideoView::GetNaturalSize()
577 {
578   Vector3 size;
579   size.x = mVideoSize.GetWidth();
580   size.y = mVideoSize.GetHeight();
581
582   if( size.x > 0 && size.y > 0 )
583   {
584     size.z = std::min( size.x, size.y );
585     return size;
586   }
587   else
588   {
589     return Control::GetNaturalSize();
590   }
591 }
592
593 float VideoView::GetHeightForWidth( float width )
594 {
595   if( mVideoSize.GetWidth() > 0 && mVideoSize.GetHeight() > 0 )
596   {
597     return GetHeightForWidthBase( width );
598   }
599   else
600   {
601     return Control::GetHeightForWidthBase( width );
602   }
603 }
604
605 float VideoView::GetWidthForHeight( float height )
606 {
607   if( mVideoSize.GetWidth() > 0 && mVideoSize.GetHeight() > 0 )
608   {
609     return GetWidthForHeightBase( height );
610   }
611   else
612   {
613     return Control::GetWidthForHeightBase( height );
614   }
615 }
616
617 void VideoView::SetWindowSurfaceTarget()
618 {
619   Actor self = Self();
620
621   if( !self.OnStage() )
622   {
623     // When the control is off the stage, it does not have Window.
624     return;
625   }
626
627   int curPos = mVideoPlayer.GetPlayPosition();
628
629   if( mIsPlay )
630   {
631     mVideoPlayer.Pause();
632   }
633
634   mPositionUpdateNotification = self.AddPropertyNotification( Actor::Property::WORLD_POSITION, StepCondition( 1.0f, 1.0f ) );
635   mSizeUpdateNotification = self.AddPropertyNotification( Actor::Property::SIZE, StepCondition( 1.0f, 1.0f ) );
636   mScaleUpdateNotification = self.AddPropertyNotification( Actor::Property::WORLD_SCALE, StepCondition( 0.1f, 1.0f ) );
637   mPositionUpdateNotification.NotifySignal().Connect( this, &VideoView::UpdateDisplayArea );
638   mSizeUpdateNotification.NotifySignal().Connect( this, &VideoView::UpdateDisplayArea );
639   mScaleUpdateNotification.NotifySignal().Connect( this, &VideoView::UpdateDisplayArea );
640
641   if( mTextureRenderer )
642   {
643     self.RemoveRenderer( mTextureRenderer );
644   }
645
646   // Note VideoPlayer::SetRenderingTarget resets all the options. (e.g. url, mute, looping)
647   mVideoPlayer.SetRenderingTarget( Dali::Adaptor::Get().GetNativeWindowHandle( self ) );
648
649   ApplyBackupProperties();
650
651   if( !mOverlayRenderer )
652   {
653     // For underlay rendering mode, video display area have to be transparent.
654     Geometry geometry = VisualFactoryCache::CreateQuadGeometry();
655     Shader shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER );
656     mOverlayRenderer = Renderer::New( geometry, shader );
657     mOverlayRenderer.SetProperty( Renderer::Property::BLEND_MODE, BlendMode::OFF );
658   }
659
660   if( mIsPlay )
661   {
662     Play();
663   }
664
665   if( curPos > 0 )
666   {
667     mVideoPlayer.SetPlayPosition( curPos );
668   }
669 }
670
671 void VideoView::SetNativeImageTarget()
672 {
673   if( mVideoPlayer.IsVideoTextureSupported() == false )
674   {
675     DALI_LOG_ERROR( "Platform doesn't support decoded video frame images\n" );
676     mIsUnderlay = true;
677     return;
678   }
679
680   if( mIsPlay )
681   {
682     mVideoPlayer.Pause();
683   }
684
685   Actor self( Self() );
686
687   if( mOverlayRenderer )
688   {
689     self.RemoveRenderer( mOverlayRenderer );
690
691     mOverlayRenderer.Reset();
692   }
693
694   self.RemovePropertyNotification( mPositionUpdateNotification );
695   self.RemovePropertyNotification( mSizeUpdateNotification );
696   self.RemovePropertyNotification( mScaleUpdateNotification );
697
698   int curPos = mVideoPlayer.GetPlayPosition();
699
700   Any source;
701   Dali::NativeImageSourcePtr nativeImageSourcePtr = Dali::NativeImageSource::New( source );
702   mNativeTexture = Dali::Texture::New( *nativeImageSourcePtr );
703
704   if( !mTextureRenderer )
705   {
706     Dali::Geometry geometry = VisualFactoryCache::CreateQuadGeometry();
707     Dali::Shader shader = CreateShader();
708     Dali::TextureSet textureSet = Dali::TextureSet::New();
709     textureSet.SetTexture( 0u, mNativeTexture );
710
711     mTextureRenderer = Renderer::New( geometry, shader );
712     mTextureRenderer.SetTextures( textureSet );
713   }
714   else
715   {
716     Dali::TextureSet textureSet = mTextureRenderer.GetTextures();
717     textureSet.SetTexture( 0u, mNativeTexture );
718   }
719   Self().AddRenderer( mTextureRenderer );
720
721   // Note VideoPlayer::SetRenderingTarget resets all the options. (e.g. url, mute, looping)
722   mVideoPlayer.SetRenderingTarget( nativeImageSourcePtr );
723
724   ApplyBackupProperties();
725
726   if( mIsPlay )
727   {
728     Play();
729   }
730
731   if( curPos > 0 )
732   {
733     mVideoPlayer.SetPlayPosition( curPos );
734   }
735 }
736
737 void VideoView::UpdateDisplayArea( Dali::PropertyNotification& source )
738 {
739   if( !mIsUnderlay )
740   {
741     return;
742   }
743
744   Actor self( Self() );
745
746   bool positionUsesAnchorPoint = self.GetProperty( DevelActor::Property::POSITION_USES_ANCHOR_POINT ).Get< bool >();
747   Vector3 actorSize = self.GetCurrentSize() * self.GetCurrentScale();
748   Vector3 anchorPointOffSet = actorSize * ( positionUsesAnchorPoint ? self.GetCurrentAnchorPoint() : AnchorPoint::TOP_LEFT );
749
750   Vector2 screenPosition = self.GetProperty( DevelActor::Property::SCREEN_POSITION ).Get< Vector2 >();
751
752   mDisplayArea.x = screenPosition.x - anchorPointOffSet.x;
753   mDisplayArea.y = screenPosition.y - anchorPointOffSet.y;
754   mDisplayArea.width = actorSize.x;
755   mDisplayArea.height = actorSize.y;
756
757   mVideoPlayer.SetDisplayArea( mDisplayArea );
758 }
759
760 void VideoView::SetUnderlay( bool set )
761 {
762   if( set != mIsUnderlay )
763   {
764     mIsUnderlay = set;
765
766     if( mIsUnderlay )
767     {
768       SetWindowSurfaceTarget();
769     }
770     else
771     {
772       SetNativeImageTarget();
773     }
774
775     RelayoutRequest();
776   }
777 }
778
779 bool VideoView::IsUnderlay()
780 {
781   return mIsUnderlay;
782 }
783
784 void VideoView::SetSWCodec( bool on )
785 {
786   // If setting SW or HW type is failed , video-view shows video by default codec type.
787   // The default codec type is selected by platform.
788   if( on )
789   {
790     mVideoPlayer.SetCodecType( Dali::VideoPlayerPlugin::CodecType::SW );
791   }
792   else
793   {
794     mVideoPlayer.SetCodecType( Dali::VideoPlayerPlugin::CodecType::HW );
795   }
796 }
797
798 int VideoView::GetPlayPosition()
799 {
800   return mVideoPlayer.GetPlayPosition();
801 }
802
803 void VideoView::SetPlayPosition( int pos )
804 {
805   mVideoPlayer.SetPlayPosition( pos );
806 }
807
808 void VideoView::SetDisplayMode( int mode )
809 {
810   mVideoPlayer.SetDisplayMode( static_cast< Dali::VideoPlayerPlugin::DisplayMode::Type >( mode ) );
811 }
812
813 int VideoView::GetDisplayMode() const
814 {
815   return static_cast< int >( mVideoPlayer.GetDisplayMode() );
816 }
817
818 Dali::Shader VideoView::CreateShader()
819 {
820   std::string fragmentShader = "#extension GL_OES_EGL_image_external:require\n";
821   std::string vertexShader;
822   std::string customFragmentShader;
823   bool checkShader = false;
824
825   if( !mEffectPropertyMap.Empty() )
826   {
827     Property::Value* vertexShaderValue = mEffectPropertyMap.Find( CUSTOM_VERTEX_SHADER );
828     if( vertexShaderValue )
829     {
830       checkShader = GetStringFromProperty( *vertexShaderValue, vertexShader );
831     }
832
833     if( !vertexShaderValue || !checkShader )
834     {
835       vertexShader = VERTEX_SHADER_TEXTURE;
836     }
837
838     Property::Value* fragmentShaderValue = mEffectPropertyMap.Find( CUSTOM_FRAGMENT_SHADER );
839     if( fragmentShaderValue )
840     {
841       checkShader = GetStringFromProperty( *fragmentShaderValue, customFragmentShader );
842
843       if( checkShader )
844       {
845         fragmentShader = customFragmentShader;
846       }
847     }
848
849     if( !fragmentShaderValue || !checkShader )
850     {
851       fragmentShader += FRAGMENT_SHADER_TEXTURE;
852     }
853   }
854   else
855   {
856     vertexShader = VERTEX_SHADER_TEXTURE;
857     fragmentShader += FRAGMENT_SHADER_TEXTURE;
858   }
859
860   return Dali::Shader::New( vertexShader, fragmentShader );
861 }
862
863 bool VideoView::GetStringFromProperty( const Dali::Property::Value& value, std::string& output )
864 {
865   bool extracted = false;
866   if( value.Get( output ) )
867   {
868     extracted = true;
869   }
870
871   return extracted;
872 }
873
874 void VideoView::ApplyBackupProperties()
875 {
876   Property::Map::SizeType pos = 0;
877   Property::Map::SizeType count = mPropertyBackup.Count();
878
879   for( ; pos < count; pos++ )
880   {
881     KeyValuePair property = mPropertyBackup.GetKeyValue( pos );
882
883     SetPropertyInternal( property.first.indexKey, property.second );
884   }
885 }
886
887 } // namespace Internal
888
889 } // namespace toolkit
890
891 } // namespace Dali