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