692048d61111cf1a05ae26ce63cca982156f7dcc
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / video-view / video-view-impl.cpp
1 /*
2  * Copyright (c) 2016 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
30 // INTERNAL INCLUDES
31 #include <dali-toolkit/public-api/controls/video-view/video-view.h>
32
33 namespace Dali
34 {
35
36 namespace Toolkit
37 {
38
39 namespace Internal
40 {
41
42 namespace
43 {
44
45 BaseHandle Create()
46 {
47   return Toolkit::VideoView::New();
48 }
49
50 DALI_TYPE_REGISTRATION_BEGIN( Toolkit::VideoView, Toolkit::Control, Create );
51
52 DALI_PROPERTY_REGISTRATION( Toolkit, VideoView, "video", MAP, VIDEO )
53 DALI_PROPERTY_REGISTRATION( Toolkit, VideoView, "looping", BOOLEAN, LOOPING )
54 DALI_PROPERTY_REGISTRATION( Toolkit, VideoView, "muted", BOOLEAN, MUTED )
55 DALI_PROPERTY_REGISTRATION( Toolkit, VideoView, "volume", MAP, VOLUME )
56
57 DALI_SIGNAL_REGISTRATION( Toolkit, VideoView, "finished", FINISHED_SIGNAL )
58
59 DALI_ACTION_REGISTRATION( Toolkit, VideoView, "play", ACTION_VIDEOVIEW_PLAY )
60 DALI_ACTION_REGISTRATION( Toolkit, VideoView, "pause", ACTION_VIDEOVIEW_PAUSE )
61 DALI_ACTION_REGISTRATION( Toolkit, VideoView, "stop", ACTION_VIDEOVIEW_STOP )
62 DALI_ACTION_REGISTRATION( Toolkit, VideoView, "forward", ACTION_VIDEOVIEW_FORWARD )
63 DALI_ACTION_REGISTRATION( Toolkit, VideoView, "backward", ACTION_VIDEOVIEW_BACKWARD )
64
65 DALI_TYPE_REGISTRATION_END()
66
67 const char* const VOLUME_LEFT( "volumeLeft" );
68 const char* const VOLUME_RIGHT( "volumeRight" );
69 const char* const RENDERING_TARGET( "RENDERING_TARGET" );
70 const char* const WINDOW_SURFACE_TARGET( "windowSurfaceTarget" );
71 const char* const NATIVE_IMAGE_TARGET( "nativeImageTarget" );
72
73 } // anonymous namepsace
74
75 VideoView::VideoView()
76 : Control( ControlBehaviour( ACTOR_BEHAVIOUR_NONE ) ),
77   mCurrentVideoPlayPosition( 0 ),
78   mSetRenderingTarget( false ),
79   mIsPlay( false ),
80   mIsPause( false )
81 {
82   mVideoPlayer = Dali::VideoPlayer::New();
83 }
84
85 VideoView::~VideoView()
86 {
87 }
88
89 Toolkit::VideoView VideoView::New()
90 {
91   VideoView* impl = new VideoView();
92   Toolkit::VideoView handle = Toolkit::VideoView( *impl );
93
94   impl->Initialize();
95
96   return handle;
97 }
98
99 void VideoView::SetUrl( const std::string& url )
100 {
101   if( mUrl != url || !mPropertyMap.Empty() )
102   {
103     mPropertyMap.Clear();
104
105     mUrl = url;
106   }
107
108   if( mSetRenderingTarget )
109   {
110     mVideoPlayer.SetUrl( mUrl );
111   }
112   else
113   {
114     SetNativeImageTarget();
115   }
116 }
117
118 void VideoView::SetPropertyMap( Property::Map map )
119 {
120   mPropertyMap = map;
121
122   Actor self( Self() );
123   InitializeVisual( self, mVisual, mPropertyMap );
124
125   Property::Value* widthValue = mPropertyMap.Find( "width" );
126   if( widthValue )
127   {
128     int width;
129     if( widthValue->Get( width ) )
130     {
131       mVideoSize = ImageDimensions( width, mVideoSize.GetHeight() );
132     }
133   }
134
135   Property::Value* heightValue = mPropertyMap.Find( "height" );
136   if( heightValue )
137   {
138     int height;
139     if( heightValue->Get( height ) )
140     {
141       mVideoSize = ImageDimensions( mVideoSize.GetWidth(), height );
142     }
143   }
144
145   RelayoutRequest();
146 }
147
148 std::string VideoView::GetUrl()
149 {
150   return mUrl;
151 }
152
153 void VideoView::SetLooping(bool looping)
154 {
155   mVideoPlayer.SetLooping( looping );
156 }
157
158 bool VideoView::IsLooping()
159 {
160   return mVideoPlayer.IsLooping();
161 }
162
163 void VideoView::Play()
164 {
165   mVideoPlayer.Play();
166   mIsPlay = true;
167   mIsPause = false;
168 }
169
170 void VideoView::Pause()
171 {
172   mVideoPlayer.Pause();
173   mIsPlay = false;
174   mIsPause = true;
175 }
176
177 void VideoView::Stop()
178 {
179   mVideoPlayer.Stop();
180   mIsPlay = false;
181   mIsPause = false;
182 }
183
184 void VideoView::Forward( int millisecond )
185 {
186   int curPos = mVideoPlayer.GetPlayPosition();
187
188   int nextPos = curPos + millisecond;
189
190   mVideoPlayer.SetPlayPosition( nextPos );
191 }
192
193 void VideoView::Backward( int millisecond )
194 {
195   int curPos = mVideoPlayer.GetPlayPosition();
196
197   int nextPos = curPos - millisecond;
198   nextPos = ( nextPos < 0 )? 0: nextPos;
199
200   mVideoPlayer.SetPlayPosition( nextPos );
201 }
202
203 void VideoView::SetMute( bool mute )
204 {
205   mVideoPlayer.SetMute( mute );
206 }
207
208 bool VideoView::IsMuted()
209 {
210   return mVideoPlayer.IsMuted();
211 }
212
213 void VideoView::SetVolume( float left, float right )
214 {
215   mVideoPlayer.SetVolume( left, right );
216 }
217
218 void VideoView::GetVolume( float& left, float& right )
219 {
220   mVideoPlayer.GetVolume( left, right );
221 }
222
223 Dali::Toolkit::VideoView::VideoViewSignalType& VideoView::FinishedSignal()
224 {
225   return mFinishedSignal;
226 }
227
228 void VideoView::EmitSignalFinish()
229 {
230   if ( !mFinishedSignal.Empty() )
231   {
232     Dali::Toolkit::VideoView handle( GetOwner() );
233     mFinishedSignal.Emit( handle );
234   }
235 }
236
237 bool VideoView::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& attributes )
238 {
239   bool ret = false;
240
241   Dali::BaseHandle handle( object );
242   Toolkit::VideoView videoView = Toolkit::VideoView::DownCast( handle );
243
244   if( !videoView )
245   {
246     return ret;
247   }
248
249   VideoView& impl = GetImpl( videoView );
250
251   if( strcmp( actionName.c_str(), ACTION_VIDEOVIEW_PLAY ) == 0 )
252   {
253     impl.Play();
254     ret = true;
255   }
256   else if( strcmp( actionName.c_str(), ACTION_VIDEOVIEW_PAUSE ) == 0 )
257   {
258     impl.Pause();
259     ret = true;
260   }
261   else if( strcmp( actionName.c_str(), ACTION_VIDEOVIEW_STOP ) == 0 )
262   {
263     impl.Stop();
264     ret = true;
265   }
266   else if( strcmp( actionName.c_str(), ACTION_VIDEOVIEW_FORWARD ) == 0 )
267   {
268     int millisecond = 0;
269     if( attributes["videoForward"].Get( millisecond ) )
270     {
271       impl.Forward( millisecond );
272       ret = true;
273     }
274   }
275   else if( strcmp( actionName.c_str(), ACTION_VIDEOVIEW_BACKWARD ) == 0 )
276   {
277     int millisecond = 0;
278     if( attributes["videoBackward"].Get( millisecond ) )
279     {
280       impl.Backward( millisecond );
281       ret = true;
282     }
283   }
284
285   return ret;
286 }
287
288 bool VideoView::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
289 {
290   Dali::BaseHandle handle( object );
291
292   bool connected( true );
293   Toolkit::VideoView videoView = Toolkit::VideoView::DownCast( handle );
294
295   if( 0 == strcmp( signalName.c_str(), FINISHED_SIGNAL ) )
296   {
297     videoView.FinishedSignal().Connect( tracker, functor );
298   }
299   else
300   {
301     // signalName does not match any signal
302     connected = false;
303   }
304
305   return connected;
306 }
307
308 void VideoView::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
309 {
310   Toolkit::VideoView videoView = Toolkit::VideoView::DownCast( Dali::BaseHandle( object ) );
311
312   if( videoView )
313   {
314     VideoView& impl = GetImpl( videoView );
315
316     switch( index )
317     {
318       case Toolkit::VideoView::Property::VIDEO:
319       {
320         std::string videoUrl;
321         if( value.Get( videoUrl ) )
322         {
323           impl.SetUrl( videoUrl );
324         }
325
326         Property::Map map;
327         if( value.Get( map ) )
328         {
329           impl.SetPropertyMap( map );
330
331           Property::Value* target = map.Find( RENDERING_TARGET );
332           std::string targetType;
333           if( target && target->Get( targetType ) && targetType == WINDOW_SURFACE_TARGET )
334           {
335             impl.SetWindowSurfaceTarget();
336           }
337           else if( target && target->Get( targetType ) && targetType == NATIVE_IMAGE_TARGET )
338           {
339             impl.SetNativeImageTarget();
340           }
341         }
342         break;
343       }
344       case Toolkit::VideoView::Property::LOOPING:
345       {
346         bool looping;
347         if( value.Get( looping ) )
348         {
349           impl.SetLooping( looping );
350         }
351         break;
352       }
353       case Toolkit::VideoView::Property::MUTED:
354       {
355         bool mute;
356         if( value.Get( mute ) )
357         {
358           impl.SetMute( mute );
359         }
360         break;
361       }
362       case Toolkit::VideoView::Property::VOLUME:
363       {
364         Property::Map map;
365         float left, right;
366         if( value.Get( map ) )
367         {
368           Property::Value* volumeLeft = map.Find( VOLUME_LEFT );
369           Property::Value* volumeRight = map.Find( VOLUME_RIGHT );
370           if( volumeLeft && volumeLeft->Get( left ) && volumeRight && volumeRight->Get( right ) )
371           {
372             impl.SetVolume( left, right );
373           }
374         }
375         break;
376       }
377     }
378   }
379 }
380
381 Property::Value VideoView::GetProperty( BaseObject* object, Property::Index propertyIndex )
382 {
383   Property::Value value;
384   Toolkit::VideoView videoView = Toolkit::VideoView::DownCast( Dali::BaseHandle( object ) );
385
386   if( videoView )
387   {
388     VideoView& impl = GetImpl( videoView );
389
390     switch( propertyIndex )
391     {
392       case Toolkit::VideoView::Property::VIDEO:
393       {
394         if( !impl.mUrl.empty() )
395         {
396           value = impl.mUrl;
397         }
398         else if( !impl.mPropertyMap.Empty() )
399         {
400           value = impl.mPropertyMap;
401         }
402         break;
403       }
404       case Toolkit::VideoView::Property::LOOPING:
405       {
406         value = impl.IsLooping();
407         break;
408       }
409       case Toolkit::VideoView::Property::MUTED:
410       {
411         value = impl.IsMuted();
412         break;
413       }
414       case Toolkit::VideoView::Property::VOLUME:
415       {
416         Property::Map map;
417         float left, right;
418
419         impl.GetVolume( left, right );
420         map.Insert( VOLUME_LEFT, left );
421         map.Insert( VOLUME_RIGHT, right );
422         value = map;
423         break;
424       }
425     }
426   }
427
428   return value;
429 }
430
431 void VideoView::SetDepthIndex( int depthIndex )
432 {
433   if( mVisual )
434   {
435     mVisual.SetDepthIndex( depthIndex );
436   }
437 }
438
439 void VideoView::OnStageConnection( int depth )
440 {
441   Control::OnStageConnection( depth );
442
443   if( mVisual )
444   {
445     CustomActor self = Self();
446     mVisual.SetOnStage( self );
447   }
448 }
449
450 void VideoView::OnStageDisconnection()
451 {
452   if( mVisual )
453   {
454     CustomActor self = Self();
455     mVisual.SetOffStage( self );
456   }
457
458   Control::OnStageDisconnection();
459 }
460
461 Vector3 VideoView::GetNaturalSize()
462 {
463   Vector3 size;
464   size.x = mVideoSize.GetWidth();
465   size.y = mVideoSize.GetHeight();
466
467   if( size.x > 0 && size.y > 0 )
468   {
469     size.z = std::min( size.x, size.y );
470     return size;
471   }
472   else
473   {
474     return Control::GetNaturalSize();
475   }
476 }
477
478 float VideoView::GetHeightForWidth( float width )
479 {
480   if( mVideoSize.GetWidth() > 0 && mVideoSize.GetHeight() > 0 )
481   {
482     return GetHeightForWidthBase( width );
483   }
484   else
485   {
486     return Control::GetHeightForWidthBase( width );
487   }
488 }
489
490 float VideoView::GetWidthForHeight( float height )
491 {
492   if( mVideoSize.GetWidth() > 0 && mVideoSize.GetHeight() > 0 )
493   {
494     return GetWidthForHeightBase( height );
495   }
496   else
497   {
498     return Control::GetWidthForHeightBase( height );
499   }
500 }
501
502 void VideoView::SetWindowSurfaceTarget()
503 {
504   Actor self = Self();
505   int curPos = mVideoPlayer.GetPlayPosition();
506
507   mSetRenderingTarget = true;
508   mVisual.RemoveAndReset( self );
509
510   mVideoPlayer.SetRenderingTarget( Dali::Adaptor::Get().GetNativeWindowHandle() );
511   mVideoPlayer.SetUrl( mUrl );
512   mVideoPlayer.FinishedSignal().Connect( this, &VideoView::EmitSignalFinish );
513
514   if( mIsPlay )
515   {
516     mVideoPlayer.Play();
517   }
518   if( mIsPause )
519   {
520     mVideoPlayer.Play();
521     mVideoPlayer.Pause();
522   }
523   mVideoPlayer.SetPlayPosition( curPos );
524 }
525
526 void VideoView::SetNativeImageTarget()
527 {
528   Actor self( Self() );
529   int curPos = mVideoPlayer.GetPlayPosition();
530
531   mSetRenderingTarget = true;
532
533   Any source;
534   Dali::NativeImageSourcePtr nativeImageSourcePtr = Dali::NativeImageSource::New( source );
535   mNativeImage = Dali::NativeImage::New( *nativeImageSourcePtr );
536
537   mVideoPlayer.SetRenderingTarget( nativeImageSourcePtr );
538   mVideoPlayer.SetUrl( mUrl );
539   mVideoPlayer.FinishedSignal().Connect( this, &VideoView::EmitSignalFinish );
540
541   InitializeVisual( self, mVisual, mNativeImage );
542
543   if( mIsPlay )
544   {
545     mVideoPlayer.Play();
546   }
547
548   if( mIsPause )
549   {
550     mVideoPlayer.Play();
551     mVideoPlayer.Pause();
552   }
553   mVideoPlayer.SetPlayPosition( curPos );
554 }
555
556 } // namespace Internal
557
558 } // namespace Toolkit
559
560 } // namespace Dali