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