[Tizen][Legacy][Svace] Remove useless API at VideoView - WidthForHeight / HeightForWidth
[platform/core/uifw/dali-toolkit-legacy.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 void VideoView::SetWindowSurfaceTarget()
587 {
588   Actor self = Self();
589
590   if( !self.OnStage() )
591   {
592     // When the control is off the stage, it does not have Window.
593     return;
594   }
595
596   int curPos = mVideoPlayer.GetPlayPosition();
597
598   if( mIsPlay )
599   {
600     mVideoPlayer.Pause();
601   }
602
603   mPositionUpdateNotification = self.AddPropertyNotification( Actor::Property::WORLD_POSITION, StepCondition( 1.0f, 1.0f ) );
604   mSizeUpdateNotification = self.AddPropertyNotification( Actor::Property::SIZE, StepCondition( 1.0f, 1.0f ) );
605   mScaleUpdateNotification = self.AddPropertyNotification( Actor::Property::WORLD_SCALE, StepCondition( 0.1f, 1.0f ) );
606   mPositionUpdateNotification.NotifySignal().Connect( this, &VideoView::UpdateDisplayArea );
607   mSizeUpdateNotification.NotifySignal().Connect( this, &VideoView::UpdateDisplayArea );
608   mScaleUpdateNotification.NotifySignal().Connect( this, &VideoView::UpdateDisplayArea );
609
610   if( mTextureRenderer )
611   {
612     self.RemoveRenderer( mTextureRenderer );
613   }
614
615   // Note VideoPlayer::SetRenderingTarget resets all the options. (e.g. url, mute, looping)
616   mVideoPlayer.SetRenderingTarget( Dali::Adaptor::Get().GetNativeWindowHandle( self ) );
617
618   ApplyBackupProperties();
619
620   if( !mOverlayRenderer )
621   {
622     // For underlay rendering mode, video display area have to be transparent.
623     Geometry geometry = VisualFactoryCache::CreateQuadGeometry();
624     Shader shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER );
625     mOverlayRenderer = Renderer::New( geometry, shader );
626     mOverlayRenderer.SetProperty( Renderer::Property::BLEND_MODE, BlendMode::OFF );
627   }
628
629   if( mIsPlay )
630   {
631     Play();
632   }
633
634   if( curPos > 0 )
635   {
636     mVideoPlayer.SetPlayPosition( curPos );
637   }
638 }
639
640 void VideoView::SetNativeImageTarget()
641 {
642   if( mVideoPlayer.IsVideoTextureSupported() == false )
643   {
644     DALI_LOG_ERROR( "Platform doesn't support decoded video frame images\n" );
645     mIsUnderlay = true;
646     return;
647   }
648
649   if( mIsPlay )
650   {
651     mVideoPlayer.Pause();
652   }
653
654   Actor self( Self() );
655
656   if( mOverlayRenderer )
657   {
658     self.RemoveRenderer( mOverlayRenderer );
659
660     mOverlayRenderer.Reset();
661   }
662
663   self.RemovePropertyNotification( mPositionUpdateNotification );
664   self.RemovePropertyNotification( mSizeUpdateNotification );
665   self.RemovePropertyNotification( mScaleUpdateNotification );
666
667   int curPos = mVideoPlayer.GetPlayPosition();
668
669   Any source;
670   Dali::NativeImageSourcePtr nativeImageSourcePtr = Dali::NativeImageSource::New( source );
671   mNativeTexture = Dali::Texture::New( *nativeImageSourcePtr );
672
673   if( !mTextureRenderer )
674   {
675     Dali::Geometry geometry = VisualFactoryCache::CreateQuadGeometry();
676     Dali::Shader shader = CreateShader();
677     Dali::TextureSet textureSet = Dali::TextureSet::New();
678     textureSet.SetTexture( 0u, mNativeTexture );
679
680     mTextureRenderer = Renderer::New( geometry, shader );
681     mTextureRenderer.SetTextures( textureSet );
682   }
683   else
684   {
685     Dali::TextureSet textureSet = mTextureRenderer.GetTextures();
686     textureSet.SetTexture( 0u, mNativeTexture );
687   }
688   Self().AddRenderer( mTextureRenderer );
689
690   // Note VideoPlayer::SetRenderingTarget resets all the options. (e.g. url, mute, looping)
691   mVideoPlayer.SetRenderingTarget( nativeImageSourcePtr );
692
693   ApplyBackupProperties();
694
695   if( mIsPlay )
696   {
697     Play();
698   }
699
700   if( curPos > 0 )
701   {
702     mVideoPlayer.SetPlayPosition( curPos );
703   }
704 }
705
706 void VideoView::UpdateDisplayArea( Dali::PropertyNotification& source )
707 {
708   if( !mIsUnderlay )
709   {
710     return;
711   }
712
713   Actor self( Self() );
714
715   bool positionUsesAnchorPoint = self.GetProperty( DevelActor::Property::POSITION_USES_ANCHOR_POINT ).Get< bool >();
716   Vector3 actorSize = self.GetCurrentProperty< Vector3 >( Actor::Property::SIZE ) * self.GetCurrentProperty< Vector3 >( Actor::Property::SCALE );
717   Vector3 anchorPointOffSet = actorSize * ( positionUsesAnchorPoint ? self.GetCurrentProperty< Vector3 >( Actor::Property::ANCHOR_POINT ) : AnchorPoint::TOP_LEFT );
718
719   Vector2 screenPosition = self.GetProperty( DevelActor::Property::SCREEN_POSITION ).Get< Vector2 >();
720
721   mDisplayArea.x = screenPosition.x - anchorPointOffSet.x;
722   mDisplayArea.y = screenPosition.y - anchorPointOffSet.y;
723   mDisplayArea.width = actorSize.x;
724   mDisplayArea.height = actorSize.y;
725
726   mVideoPlayer.SetDisplayArea( mDisplayArea );
727 }
728
729 void VideoView::SetUnderlay( bool set )
730 {
731   if( set != mIsUnderlay )
732   {
733     mIsUnderlay = set;
734
735     if( mIsUnderlay )
736     {
737       SetWindowSurfaceTarget();
738     }
739     else
740     {
741       SetNativeImageTarget();
742     }
743
744     RelayoutRequest();
745   }
746 }
747
748 bool VideoView::IsUnderlay()
749 {
750   return mIsUnderlay;
751 }
752
753 void VideoView::SetSWCodec( bool on )
754 {
755   // If setting SW or HW type is failed , video-view shows video by default codec type.
756   // The default codec type is selected by platform.
757   if( on )
758   {
759     mVideoPlayer.SetCodecType( Dali::VideoPlayerPlugin::CodecType::SW );
760   }
761   else
762   {
763     mVideoPlayer.SetCodecType( Dali::VideoPlayerPlugin::CodecType::HW );
764   }
765 }
766
767 int VideoView::GetPlayPosition()
768 {
769   return mVideoPlayer.GetPlayPosition();
770 }
771
772 void VideoView::SetPlayPosition( int pos )
773 {
774   mVideoPlayer.SetPlayPosition( pos );
775 }
776
777 void VideoView::SetDisplayMode( int mode )
778 {
779   mVideoPlayer.SetDisplayMode( static_cast< Dali::VideoPlayerPlugin::DisplayMode::Type >( mode ) );
780 }
781
782 int VideoView::GetDisplayMode() const
783 {
784   return static_cast< int >( mVideoPlayer.GetDisplayMode() );
785 }
786
787 Any VideoView::GetMediaPlayer()
788 {
789   return mVideoPlayer.GetMediaPlayer();
790 }
791
792 Dali::Shader VideoView::CreateShader()
793 {
794   std::string fragmentShader = "#extension GL_OES_EGL_image_external:require\n";
795   std::string vertexShader;
796   std::string customFragmentShader;
797   bool checkShader = false;
798
799   if( !mEffectPropertyMap.Empty() )
800   {
801     Property::Value* vertexShaderValue = mEffectPropertyMap.Find( CUSTOM_VERTEX_SHADER );
802     if( vertexShaderValue )
803     {
804       checkShader = GetStringFromProperty( *vertexShaderValue, vertexShader );
805     }
806
807     if( !vertexShaderValue || !checkShader )
808     {
809       vertexShader = VERTEX_SHADER_TEXTURE;
810     }
811
812     Property::Value* fragmentShaderValue = mEffectPropertyMap.Find( CUSTOM_FRAGMENT_SHADER );
813     if( fragmentShaderValue )
814     {
815       checkShader = GetStringFromProperty( *fragmentShaderValue, customFragmentShader );
816
817       if( checkShader )
818       {
819         fragmentShader = customFragmentShader;
820       }
821     }
822
823     if( !fragmentShaderValue || !checkShader )
824     {
825       fragmentShader += FRAGMENT_SHADER_TEXTURE;
826     }
827   }
828   else
829   {
830     vertexShader = VERTEX_SHADER_TEXTURE;
831     fragmentShader += FRAGMENT_SHADER_TEXTURE;
832   }
833
834   return Dali::Shader::New( vertexShader, fragmentShader );
835 }
836
837 bool VideoView::GetStringFromProperty( const Dali::Property::Value& value, std::string& output )
838 {
839   bool extracted = false;
840   if( value.Get( output ) )
841   {
842     extracted = true;
843   }
844
845   return extracted;
846 }
847
848 void VideoView::ApplyBackupProperties()
849 {
850   Property::Map::SizeType pos = 0;
851   Property::Map::SizeType count = mPropertyBackup.Count();
852
853   for( ; pos < count; pos++ )
854   {
855     KeyValuePair property = mPropertyBackup.GetKeyValue( pos );
856
857     SetPropertyInternal( property.first.indexKey, property.second );
858   }
859 }
860
861 } // namespace Internal
862
863 } // namespace toolkit
864
865 } // namespace Dali