3db94faf9ca33bb070ff462ed1d9116b63d0c96e
[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
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 mediump 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   uniform lowp vec4 uColor;\n
103   uniform lowp vec3 mixColor;\n
104   \n
105   void main()\n
106   {\n
107     gl_FragColor = vec4(mixColor, 1.0)*uColor;\n
108   }\n
109 );
110
111 const char* VERTEX_SHADER_TEXTURE = DALI_COMPOSE_SHADER(
112   attribute mediump vec2 aPosition;\n
113   varying mediump vec2 vTexCoord;\n
114   uniform mediump mat4 uMvpMatrix;\n
115   uniform mediump vec3 uSize;\n
116   varying mediump vec2 sTexCoordRect;\n
117   void main()\n
118   {\n
119     gl_Position = uMvpMatrix * vec4(aPosition * uSize.xy, 0.0, 1.0);\n
120     vTexCoord = aPosition + vec2(0.5);\n
121   }\n
122 );
123
124 const char* FRAGMENT_SHADER_TEXTURE = DALI_COMPOSE_SHADER(
125   uniform lowp vec4 uColor;\n
126   varying mediump vec2 vTexCoord;\n
127   uniform samplerExternalOES sTexture;\n
128   void main()\n
129   {\n
130     gl_FragColor = texture2D( sTexture, vTexCoord ) * uColor;\n
131   }\n
132 );
133
134 } // anonymous namepsace
135
136 VideoView::VideoView()
137 : Control( ControlBehaviour( ACTOR_BEHAVIOUR_DEFAULT | DISABLE_STYLE_CHANGE_SIGNALS ) ),
138   mCurrentVideoPlayPosition( 0 ),
139   mIsPlay( false ),
140   mIsUnderlay( true )
141 {
142   mVideoPlayer = Dali::VideoPlayer::New();
143 }
144
145 VideoView::~VideoView()
146 {
147 }
148
149 Toolkit::VideoView VideoView::New()
150 {
151   VideoView* impl = new VideoView();
152   Toolkit::VideoView handle = Toolkit::VideoView( *impl );
153
154   impl->Initialize();
155
156   return handle;
157 }
158
159 void VideoView::OnInitialize()
160 {
161   mVideoPlayer.FinishedSignal().Connect( this, &VideoView::EmitSignalFinish );
162   SetWindowSurfaceTarget();
163 }
164
165 void VideoView::SetUrl( const std::string& url )
166 {
167     mUrl = url;
168     mPropertyMap.Clear();
169
170   mVideoPlayer.SetUrl( mUrl );
171 }
172
173 void VideoView::SetPropertyMap( Property::Map map )
174 {
175   mPropertyMap = map;
176
177   Property::Value* target = map.Find( RENDERING_TARGET );
178   std::string targetType;
179
180   if( target && target->Get( targetType ) && targetType == WINDOW_SURFACE_TARGET )
181   {
182     mIsUnderlay = true;
183     SetWindowSurfaceTarget();
184   }
185   else if( target && target->Get( targetType ) && targetType == NATIVE_IMAGE_TARGET )
186   {
187     mIsUnderlay = false;
188     SetNativeImageTarget();
189   }
190
191   // Custom shader
192   Property::Value* shaderValue;
193   if( !map.Empty() )
194   {
195     shaderValue = map.Find( CUSTOM_SHADER );
196
197     if( shaderValue )
198     {
199       mEffectPropertyMap = *( shaderValue->GetMap() );
200     }
201   }
202
203   if( mTextureRenderer && !mEffectPropertyMap.Empty() )
204   {
205     Dali::Shader shader = CreateShader();
206     mTextureRenderer.SetShader( shader );
207   }
208
209   RelayoutRequest();
210 }
211
212 std::string VideoView::GetUrl()
213 {
214   return mUrl;
215 }
216
217 void VideoView::SetLooping( bool looping )
218 {
219   mVideoPlayer.SetLooping( looping );
220 }
221
222 bool VideoView::IsLooping()
223 {
224   return mVideoPlayer.IsLooping();
225 }
226
227 void VideoView::Play()
228 {
229   if( mIsUnderlay )
230   {
231     Self().AddRenderer( mOverlayRenderer );
232   }
233
234   mVideoPlayer.Play();
235   mIsPlay = true;
236 }
237
238 void VideoView::Pause()
239 {
240   mVideoPlayer.Pause();
241   mIsPlay = false;
242 }
243
244 void VideoView::Stop()
245 {
246   mVideoPlayer.Stop();
247   mIsPlay = false;
248 }
249
250 void VideoView::Forward( int millisecond )
251 {
252   int curPos = mVideoPlayer.GetPlayPosition();
253
254   int nextPos = curPos + millisecond;
255
256   mVideoPlayer.SetPlayPosition( nextPos );
257 }
258
259 void VideoView::Backward( int millisecond )
260 {
261   int curPos = mVideoPlayer.GetPlayPosition();
262
263   int nextPos = curPos - millisecond;
264   nextPos = ( nextPos < 0 )? 0: nextPos;
265
266   mVideoPlayer.SetPlayPosition( nextPos );
267 }
268
269 void VideoView::SetMute( bool mute )
270 {
271   mVideoPlayer.SetMute( mute );
272 }
273
274 bool VideoView::IsMuted()
275 {
276   return mVideoPlayer.IsMuted();
277 }
278
279 void VideoView::SetVolume( float left, float right )
280 {
281   mVideoPlayer.SetVolume( left, right );
282 }
283
284 void VideoView::GetVolume( float& left, float& right )
285 {
286   mVideoPlayer.GetVolume( left, right );
287 }
288
289 Dali::Toolkit::VideoView::VideoViewSignalType& VideoView::FinishedSignal()
290 {
291   return mFinishedSignal;
292 }
293
294 void VideoView::EmitSignalFinish()
295 {
296   if( mIsUnderlay )
297   {
298     Self().RemoveRenderer( mOverlayRenderer );
299   }
300
301   if ( !mFinishedSignal.Empty() )
302   {
303     Dali::Toolkit::VideoView handle( GetOwner() );
304     mFinishedSignal.Emit( handle );
305   }
306 }
307
308 bool VideoView::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& attributes )
309 {
310   bool ret = false;
311
312   Dali::BaseHandle handle( object );
313   Toolkit::VideoView videoView = Toolkit::VideoView::DownCast( handle );
314
315   if( !videoView )
316   {
317     return ret;
318   }
319
320   VideoView& impl = GetImpl( videoView );
321
322   if( strcmp( actionName.c_str(), ACTION_VIDEOVIEW_PLAY ) == 0 )
323   {
324     impl.Play();
325     ret = true;
326   }
327   else if( strcmp( actionName.c_str(), ACTION_VIDEOVIEW_PAUSE ) == 0 )
328   {
329     impl.Pause();
330     ret = true;
331   }
332   else if( strcmp( actionName.c_str(), ACTION_VIDEOVIEW_STOP ) == 0 )
333   {
334     impl.Stop();
335     ret = true;
336   }
337   else if( strcmp( actionName.c_str(), ACTION_VIDEOVIEW_FORWARD ) == 0 )
338   {
339     int millisecond = 0;
340     if( attributes["videoForward"].Get( millisecond ) )
341     {
342       impl.Forward( millisecond );
343       ret = true;
344     }
345   }
346   else if( strcmp( actionName.c_str(), ACTION_VIDEOVIEW_BACKWARD ) == 0 )
347   {
348     int millisecond = 0;
349     if( attributes["videoBackward"].Get( millisecond ) )
350     {
351       impl.Backward( millisecond );
352       ret = true;
353     }
354   }
355
356   return ret;
357 }
358
359 bool VideoView::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
360 {
361   Dali::BaseHandle handle( object );
362
363   bool connected( true );
364   Toolkit::VideoView videoView = Toolkit::VideoView::DownCast( handle );
365
366   if( 0 == strcmp( signalName.c_str(), FINISHED_SIGNAL ) )
367   {
368     videoView.FinishedSignal().Connect( tracker, functor );
369   }
370   else
371   {
372     // signalName does not match any signal
373     connected = false;
374   }
375
376   return connected;
377 }
378
379 void VideoView::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
380 {
381   Toolkit::VideoView videoView = Toolkit::VideoView::DownCast( Dali::BaseHandle( object ) );
382
383   if( videoView )
384   {
385     VideoView& impl = GetImpl( videoView );
386
387     switch( index )
388     {
389       case Toolkit::VideoView::Property::VIDEO:
390       {
391         std::string videoUrl;
392         Property::Map map;
393
394         if( value.Get( videoUrl ) )
395         {
396           impl.SetUrl( videoUrl );
397         }
398         else if( value.Get( map ) )
399         {
400             impl.SetPropertyMap( map );
401           }
402         break;
403       }
404       case Toolkit::VideoView::Property::LOOPING:
405       {
406         bool looping;
407         if( value.Get( looping ) )
408         {
409           impl.SetLooping( looping );
410         }
411         break;
412       }
413       case Toolkit::VideoView::Property::MUTED:
414       {
415         bool mute;
416         if( value.Get( mute ) )
417         {
418           impl.SetMute( mute );
419         }
420         break;
421       }
422       case Toolkit::VideoView::Property::VOLUME:
423       {
424         Property::Map map;
425         float left, right;
426         if( value.Get( map ) )
427         {
428           Property::Value* volumeLeft = map.Find( VOLUME_LEFT );
429           Property::Value* volumeRight = map.Find( VOLUME_RIGHT );
430           if( volumeLeft && volumeLeft->Get( left ) && volumeRight && volumeRight->Get( right ) )
431           {
432             impl.SetVolume( left, right );
433           }
434         }
435         break;
436       }
437       case Toolkit::VideoView::Property::UNDERLAY:
438       {
439         bool underlay;
440         if( value.Get( underlay ) )
441         {
442           impl.SetUnderlay( underlay );
443         }
444         break;
445       }
446       case Toolkit::VideoView::Property::PLAY_POSITION:
447       {
448         int pos;
449         if( value.Get( pos ) )
450         {
451           impl.SetPlayPosition( pos );
452         }
453         break;
454       }
455       case Toolkit::VideoView::Property::DISPLAY_MODE:
456       {
457         int mode;
458         if( value.Get( mode ) )
459         {
460           impl.SetDisplayMode( mode );
461         }
462         break;
463       }
464     }
465   }
466 }
467
468 Property::Value VideoView::GetProperty( BaseObject* object, Property::Index propertyIndex )
469 {
470   Property::Value value;
471   Toolkit::VideoView videoView = Toolkit::VideoView::DownCast( Dali::BaseHandle( object ) );
472
473   if( videoView )
474   {
475     VideoView& impl = GetImpl( videoView );
476
477     switch( propertyIndex )
478     {
479       case Toolkit::VideoView::Property::VIDEO:
480       {
481         if( !impl.mUrl.empty() )
482         {
483           value = impl.mUrl;
484         }
485         else if( !impl.mPropertyMap.Empty() )
486         {
487           value = impl.mPropertyMap;
488         }
489         break;
490       }
491       case Toolkit::VideoView::Property::LOOPING:
492       {
493         value = impl.IsLooping();
494         break;
495       }
496       case Toolkit::VideoView::Property::MUTED:
497       {
498         value = impl.IsMuted();
499         break;
500       }
501       case Toolkit::VideoView::Property::VOLUME:
502       {
503         Property::Map map;
504         float left, right;
505
506         impl.GetVolume( left, right );
507         map.Insert( VOLUME_LEFT, left );
508         map.Insert( VOLUME_RIGHT, right );
509         value = map;
510         break;
511       }
512       case Toolkit::VideoView::Property::UNDERLAY:
513       {
514         value = impl.IsUnderlay();
515         break;
516       }
517       case Toolkit::VideoView::Property::PLAY_POSITION:
518       {
519         value = impl.GetPlayPosition();
520         break;
521       }
522       case Toolkit::VideoView::Property::DISPLAY_MODE:
523       {
524         value = impl.GetDisplayMode();
525         break;
526       }
527     }
528   }
529
530   return value;
531 }
532
533 void VideoView::SetDepthIndex( int depthIndex )
534 {
535   if( mTextureRenderer )
536   {
537     mTextureRenderer.SetProperty( Renderer::Property::DEPTH_INDEX, depthIndex );
538   }
539 }
540
541 void VideoView::OnStageConnection( int depth )
542 {
543   Control::OnStageConnection( depth );
544 }
545
546 void VideoView::OnStageDisconnection()
547 {
548   Control::OnStageDisconnection();
549 }
550
551 Vector3 VideoView::GetNaturalSize()
552 {
553   Vector3 size;
554   size.x = mVideoSize.GetWidth();
555   size.y = mVideoSize.GetHeight();
556
557   if( size.x > 0 && size.y > 0 )
558   {
559     size.z = std::min( size.x, size.y );
560     return size;
561   }
562   else
563   {
564     return Control::GetNaturalSize();
565   }
566 }
567
568 float VideoView::GetHeightForWidth( float width )
569 {
570   if( mVideoSize.GetWidth() > 0 && mVideoSize.GetHeight() > 0 )
571   {
572     return GetHeightForWidthBase( width );
573   }
574   else
575   {
576     return Control::GetHeightForWidthBase( width );
577   }
578 }
579
580 float VideoView::GetWidthForHeight( float height )
581 {
582   if( mVideoSize.GetWidth() > 0 && mVideoSize.GetHeight() > 0 )
583   {
584     return GetWidthForHeightBase( height );
585   }
586   else
587   {
588     return Control::GetWidthForHeightBase( height );
589   }
590 }
591
592 void VideoView::SetWindowSurfaceTarget()
593 {
594   Actor self = Self();
595   int curPos = mVideoPlayer.GetPlayPosition();
596
597   if( mIsPlay )
598   {
599     mVideoPlayer.Pause();
600   }
601
602   mPositionUpdateNotification = self.AddPropertyNotification( Actor::Property::WORLD_POSITION, StepCondition( 1.0f, 1.0f ) );
603   mSizeUpdateNotification = self.AddPropertyNotification( Actor::Property::SIZE, StepCondition( 1.0f, 1.0f ) );
604   mScaleUpdateNotification = self.AddPropertyNotification( Actor::Property::WORLD_SCALE, StepCondition( 0.1f, 1.0f ) );
605   mPositionUpdateNotification.NotifySignal().Connect( this, &VideoView::UpdateDisplayArea );
606   mSizeUpdateNotification.NotifySignal().Connect( this, &VideoView::UpdateDisplayArea );
607   mScaleUpdateNotification.NotifySignal().Connect( this, &VideoView::UpdateDisplayArea );
608
609   if( mTextureRenderer )
610   {
611     self.RemoveRenderer( mTextureRenderer );
612   }
613
614   mVideoPlayer.SetRenderingTarget( Dali::Adaptor::Get().GetNativeWindowHandle() );
615   mVideoPlayer.SetUrl( mUrl );
616
617   if( !mOverlayRenderer )
618   {
619     // For underlay rendering mode, video display area have to be transparent.
620     Geometry geometry = VisualFactoryCache::CreateQuadGeometry();
621     Shader shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER );
622     mOverlayRenderer = Renderer::New( geometry, shader );
623
624     mOverlayRenderer.SetProperty( Renderer::Property::BLEND_MODE, BlendMode::ON );
625     mOverlayRenderer.SetProperty( Renderer::Property::BLEND_FACTOR_SRC_RGB, BlendFactor::ONE );
626     mOverlayRenderer.SetProperty( Renderer::Property::BLEND_FACTOR_DEST_RGB, BlendFactor::ZERO );
627     mOverlayRenderer.SetProperty( Renderer::Property::BLEND_FACTOR_SRC_ALPHA, BlendFactor::ONE );
628     mOverlayRenderer.SetProperty( Renderer::Property::BLEND_FACTOR_DEST_ALPHA, BlendFactor::ZERO );
629   }
630
631   if( mIsPlay )
632   {
633     Play();
634   }
635
636   if( curPos > 0 )
637   {
638     mVideoPlayer.SetPlayPosition( curPos );
639   }
640 }
641
642 void VideoView::SetNativeImageTarget()
643 {
644   if( mVideoPlayer.IsVideoTextureSupported() == false )
645   {
646     DALI_LOG_ERROR( "Platform doesn't support decoded video frame images\n" );
647     mIsUnderlay = true;
648     return;
649   }
650
651   if( mIsPlay )
652   {
653     mVideoPlayer.Pause();
654   }
655
656   Actor self( Self() );
657
658   if( mOverlayRenderer )
659   {
660     self.RemoveRenderer( mOverlayRenderer );
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   mVideoPlayer.SetRenderingTarget( nativeImageSourcePtr );
691   mVideoPlayer.SetUrl( mUrl );
692
693   if( mIsPlay )
694   {
695     Play();
696   }
697
698   if( curPos > 0 )
699   {
700     mVideoPlayer.SetPlayPosition( curPos );
701   }
702 }
703
704 void VideoView::UpdateDisplayArea( Dali::PropertyNotification& source )
705 {
706   if( !mIsUnderlay )
707   {
708     return;
709   }
710
711   Actor self( Self() );
712
713   bool positionUsesAnchorPoint = self.GetProperty( DevelActor::Property::POSITION_USES_ANCHOR_POINT ).Get< bool >();
714   Vector3 actorSize = self.GetCurrentSize() * self.GetCurrentScale();
715   Vector3 anchorPointOffSet = actorSize * ( positionUsesAnchorPoint ? self.GetCurrentAnchorPoint() : AnchorPoint::TOP_LEFT );
716
717   Vector2 screenPosition = self.GetProperty( DevelActor::Property::SCREEN_POSITION ).Get< Vector2 >();
718
719   mDisplayArea.x = screenPosition.x - anchorPointOffSet.x;
720   mDisplayArea.y = screenPosition.y - anchorPointOffSet.y;
721   mDisplayArea.width = actorSize.x;
722   mDisplayArea.height = actorSize.y;
723
724   mVideoPlayer.SetDisplayArea( mDisplayArea );
725 }
726
727 void VideoView::SetUnderlay( bool set )
728 {
729   if( set != mIsUnderlay )
730   {
731     mIsUnderlay = set;
732
733     if( mIsUnderlay )
734     {
735       SetWindowSurfaceTarget();
736     }
737     else
738     {
739       SetNativeImageTarget();
740     }
741
742     RelayoutRequest();
743   }
744 }
745
746 bool VideoView::IsUnderlay()
747 {
748   return mIsUnderlay;
749 }
750
751 void VideoView::SetSWCodec( bool on )
752 {
753   // If setting SW or HW type is failed , video-view shows video by default codec type.
754   // The default codec type is selected by platform.
755   if( on )
756   {
757     mVideoPlayer.SetCodecType( Dali::VideoPlayerPlugin::CodecType::SW );
758   }
759   else
760   {
761     mVideoPlayer.SetCodecType( Dali::VideoPlayerPlugin::CodecType::HW );
762   }
763 }
764
765 int VideoView::GetPlayPosition()
766 {
767   return mVideoPlayer.GetPlayPosition();
768 }
769
770 void VideoView::SetPlayPosition( int pos )
771 {
772   mVideoPlayer.SetPlayPosition( pos );
773 }
774
775 void VideoView::SetDisplayMode( int mode )
776 {
777   mVideoPlayer.SetDisplayMode( static_cast< Dali::VideoPlayerPlugin::DisplayMode::Type >( mode ) );
778 }
779
780 int VideoView::GetDisplayMode() const
781 {
782   return static_cast< int >( mVideoPlayer.GetDisplayMode() );
783 }
784
785 Dali::Shader VideoView::CreateShader()
786 {
787   std::string fragmentShader = "#extension GL_OES_EGL_image_external:require\n";
788   std::string vertexShader;
789   std::string customFragmentShader;
790   bool checkShader = false;
791
792   if( !mEffectPropertyMap.Empty() )
793   {
794     Property::Value* vertexShaderValue = mEffectPropertyMap.Find( CUSTOM_VERTEX_SHADER );
795     if( vertexShaderValue )
796     {
797       checkShader = GetStringFromProperty( *vertexShaderValue, vertexShader );
798     }
799
800     if( !vertexShaderValue || !checkShader )
801     {
802       vertexShader = VERTEX_SHADER_TEXTURE;
803     }
804
805     Property::Value* fragmentShaderValue = mEffectPropertyMap.Find( CUSTOM_FRAGMENT_SHADER );
806     if( fragmentShaderValue )
807     {
808       checkShader = GetStringFromProperty( *fragmentShaderValue, customFragmentShader );
809
810       if( checkShader )
811       {
812         fragmentShader = customFragmentShader;
813       }
814     }
815
816     if( !fragmentShaderValue || !checkShader )
817     {
818       fragmentShader += FRAGMENT_SHADER_TEXTURE;
819     }
820   }
821   else
822   {
823     vertexShader = VERTEX_SHADER_TEXTURE;
824     fragmentShader += FRAGMENT_SHADER_TEXTURE;
825   }
826
827   return Dali::Shader::New( vertexShader, fragmentShader );
828 }
829
830 bool VideoView::GetStringFromProperty( const Dali::Property::Value& value, std::string& output )
831 {
832   bool extracted = false;
833   if( value.Get( output ) )
834   {
835     extracted = true;
836   }
837
838   return extracted;
839 }
840
841 } // namespace Internal
842
843 } // namespace toolkit
844
845 } // namespace Dali