2 * Copyright (c) 2016 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <tizen-video-player.h>
22 #include <dali/public-api/common/stage.h>
23 #include <dali/devel-api/threading/mutex.h>
24 #include <dali/integration-api/debug.h>
28 // The plugin factories
29 extern "C" DALI_EXPORT_API Dali::VideoPlayerPlugin* CreateVideoPlayerPlugin( void )
31 return new Dali::Plugin::TizenVideoPlayer;
34 extern "C" DALI_EXPORT_API void DestroyVideoPlayerPlugin( Dali::VideoPlayerPlugin* plugin )
51 const int TIMER_INTERVAL( 20 );
53 static void MediaPacketVideoDecodedCb( media_packet_h packet, void* user_data )
55 TizenVideoPlayer* player = static_cast< TizenVideoPlayer* >( user_data );
59 DALI_LOG_ERROR( "Decoded callback got Null pointer as user_data.\n" );
63 player->PushPacket( packet );
66 static void EmitPlaybackFinishedSignal( void* user_data )
68 TizenVideoPlayer* player = static_cast< TizenVideoPlayer* >( user_data );
69 DALI_LOG_ERROR( "EmitPlaybackFinishedSignal.\n" );
73 DALI_LOG_ERROR( "Decoded callback got Null pointer as user_data.\n" );
77 DALI_LOG_ERROR( "EmitPlaybackFinishedSignal.\n" );
79 if( !player->mFinishedSignal.Empty() )
81 DALI_LOG_ERROR( "EmitPlaybackFinishedSignal.3\n" );
82 player->mFinishedSignal.Emit();
88 // ToDo: VD player_set_play_position() doesn't work when callback pointer is NULL.
89 // We should check whether this callback is needed in platform.
90 static void PlayerSeekCompletedCb( void* data )
94 void LogPlayerError( int error )
96 if( error != PLAYER_ERROR_NONE )
100 case PLAYER_ERROR_OUT_OF_MEMORY:
102 DALI_LOG_ERROR( "Player error: Out of memory\n" );
105 case PLAYER_ERROR_INVALID_PARAMETER:
107 DALI_LOG_ERROR( "Player error: Invalid parameter\n" );
110 case PLAYER_ERROR_NO_SUCH_FILE:
112 DALI_LOG_ERROR( "Player error: No such file\n" );
115 case PLAYER_ERROR_INVALID_OPERATION:
117 DALI_LOG_ERROR( "Player error: Invalid operation\n" );
120 case PLAYER_ERROR_FILE_NO_SPACE_ON_DEVICE:
122 DALI_LOG_ERROR( "Player error: No space on device\n" );
125 case PLAYER_ERROR_FEATURE_NOT_SUPPORTED_ON_DEVICE:
127 DALI_LOG_ERROR( "Player error: Not supported feature on device\n" );
130 case PLAYER_ERROR_SEEK_FAILED:
132 DALI_LOG_ERROR( "Player error: Seek failed\n" );
135 case PLAYER_ERROR_INVALID_STATE:
137 DALI_LOG_ERROR( "Player error: Invalid state\n" );
140 case PLAYER_ERROR_NOT_SUPPORTED_FILE:
142 DALI_LOG_ERROR( "Player error: Not supported file\n" );
145 case PLAYER_ERROR_INVALID_URI:
147 DALI_LOG_ERROR( "Player error: Invalid uri\n" );
150 case PLAYER_ERROR_SOUND_POLICY:
152 DALI_LOG_ERROR( "Player error: Sound policy\n" );
155 case PLAYER_ERROR_CONNECTION_FAILED:
157 DALI_LOG_ERROR( "Player error: Connection failed\n" );
160 case PLAYER_ERROR_VIDEO_CAPTURE_FAILED:
162 DALI_LOG_ERROR( "Player error: Video capture failed\n" );
165 case PLAYER_ERROR_DRM_EXPIRED:
167 DALI_LOG_ERROR( "Player error: DRM expired\n" );
170 case PLAYER_ERROR_DRM_NO_LICENSE:
172 DALI_LOG_ERROR( "Player error: No license\n" );
175 case PLAYER_ERROR_DRM_FUTURE_USE:
177 DALI_LOG_ERROR( "Player error: License for future use\n" );
180 case PLAYER_ERROR_DRM_NOT_PERMITTED:
182 DALI_LOG_ERROR( "Player error: Format not permitted\n" );
185 case PLAYER_ERROR_RESOURCE_LIMIT:
187 DALI_LOG_ERROR( "Player error: Resource limit\n" );
190 case PLAYER_ERROR_PERMISSION_DENIED:
192 DALI_LOG_ERROR( "Player error: Permission denied\n" );
195 case PLAYER_ERROR_SERVICE_DISCONNECTED:
197 DALI_LOG_ERROR( "Player error: Service disconnected\n" );
200 case PLAYER_ERROR_BUFFER_SPACE:
202 DALI_LOG_ERROR( "Player error: Buffer space\n" );
209 } // unnamed namespace
211 TizenVideoPlayer::TizenVideoPlayer()
214 mPlayerState( PLAYER_STATE_NONE ),
217 mNativeImageSourcePtr( NULL ),
219 mBackgroundColor( Vector4( 1.0f, 1.0f, 1.0f, 0.0f ) ),
220 mTargetType( NativeImage ),
223 mEcoreWlWindow( NULL ),
224 mAlphaBitChanged( false )
228 TizenVideoPlayer::~TizenVideoPlayer()
232 void TizenVideoPlayer::GetPlayerState( player_state_e* state )
234 if( mPlayer != NULL && player_get_state( mPlayer, state ) != PLAYER_ERROR_NONE )
236 DALI_LOG_ERROR( "player_get_state error: Invalid parameter\n" );
237 *state = PLAYER_STATE_NONE;
241 void TizenVideoPlayer::SetUrl( const std::string& url )
247 GetPlayerState( &mPlayerState );
249 if( mPlayerState != PLAYER_STATE_NONE && mPlayerState != PLAYER_STATE_IDLE )
252 int error = player_unprepare( mPlayer );
253 LogPlayerError( error );
256 if( mPlayerState == PLAYER_STATE_IDLE )
258 int error = player_set_uri( mPlayer, mUrl.c_str() );
259 LogPlayerError( error );
261 error = player_prepare( mPlayer );
262 LogPlayerError( error );
267 std::string TizenVideoPlayer::GetUrl()
272 void TizenVideoPlayer::SetRenderingTarget( Any target )
275 if( mPlayerState != PLAYER_STATE_NONE )
277 GetPlayerState( &mPlayerState );
279 if( mPlayerState != PLAYER_STATE_IDLE )
282 error = player_unprepare( mPlayer );
283 LogPlayerError( error );
286 error = player_destroy( mPlayer );
287 LogPlayerError( error );
288 mPlayerState = PLAYER_STATE_NONE;
293 mNativeImageSourcePtr = NULL;
294 mEcoreWlWindow = NULL;
296 if( target.GetType() == typeid( Dali::NativeImageSourcePtr ) )
298 mTargetType = TizenVideoPlayer::NativeImage;
300 Dali::NativeImageSourcePtr nativeImageSourcePtr = AnyCast< Dali::NativeImageSourcePtr >( target );
302 InitializeTextureStreamMode( nativeImageSourcePtr );
304 else if( target.GetType() == typeid( Ecore_Wl_Window* ) )
306 mTargetType = TizenVideoPlayer::WindowSurface;
308 Ecore_Wl_Window* nativeWindow = Dali::AnyCast< Ecore_Wl_Window* >( target );
309 InitializeUnderlayMode( nativeWindow );
313 DALI_LOG_ERROR( "Video rendering target is unknown\n" );
317 void TizenVideoPlayer::SetLooping( bool looping )
319 GetPlayerState( &mPlayerState );
321 if( mPlayerState != PLAYER_STATE_NONE )
323 int error = player_set_looping( mPlayer, looping );
324 LogPlayerError( error );
328 bool TizenVideoPlayer::IsLooping()
330 GetPlayerState( &mPlayerState );
332 bool looping = false;
333 if( mPlayerState != PLAYER_STATE_NONE )
335 int error = player_is_looping( mPlayer, &looping );
336 LogPlayerError( error );
342 void TizenVideoPlayer::Play()
344 GetPlayerState( &mPlayerState );
346 if( mPlayerState == PLAYER_STATE_READY || mPlayerState == PLAYER_STATE_PAUSED )
348 if( mNativeImageSourcePtr != NULL && mTimer )
353 int error = player_start( mPlayer );
354 LogPlayerError( error );
358 void TizenVideoPlayer::Pause()
360 GetPlayerState( &mPlayerState );
362 if( mPlayerState == PLAYER_STATE_PLAYING )
364 int error = player_pause( mPlayer );
365 LogPlayerError( error );
367 if( mNativeImageSourcePtr != NULL && mTimer )
375 void TizenVideoPlayer::Stop()
377 GetPlayerState( &mPlayerState );
379 if( mPlayerState == PLAYER_STATE_PLAYING || mPlayerState == PLAYER_STATE_PAUSED )
381 int error = player_stop( mPlayer );
382 LogPlayerError( error );
385 if( mNativeImageSourcePtr != NULL && mTimer )
392 void TizenVideoPlayer::SetMute( bool muted )
394 GetPlayerState( &mPlayerState );
396 if( mPlayerState == PLAYER_STATE_IDLE ||
397 mPlayerState == PLAYER_STATE_READY ||
398 mPlayerState == PLAYER_STATE_PLAYING ||
399 mPlayerState == PLAYER_STATE_PAUSED
402 int error = player_set_mute( mPlayer, muted );
403 LogPlayerError( error );
407 bool TizenVideoPlayer::IsMuted()
409 GetPlayerState( &mPlayerState );
412 if( mPlayerState == PLAYER_STATE_IDLE ||
413 mPlayerState == PLAYER_STATE_READY ||
414 mPlayerState == PLAYER_STATE_PLAYING ||
415 mPlayerState == PLAYER_STATE_PAUSED
418 int error = player_is_muted( mPlayer, &muted );
419 LogPlayerError( error );
425 void TizenVideoPlayer::SetVolume( float left, float right )
427 GetPlayerState( &mPlayerState );
429 int error = player_set_volume( mPlayer, left, right );
430 LogPlayerError( error );
433 void TizenVideoPlayer::GetVolume( float& left, float& right )
435 GetPlayerState( &mPlayerState );
437 int error = player_get_volume( mPlayer, &left, &right );
438 LogPlayerError( error );
441 void TizenVideoPlayer::SetPlayPosition( int millisecond )
445 GetPlayerState( &mPlayerState );
447 if( mPlayerState == PLAYER_STATE_READY ||
448 mPlayerState == PLAYER_STATE_PLAYING ||
449 mPlayerState == PLAYER_STATE_PAUSED
452 error = player_set_play_position( mPlayer, millisecond, false, PlayerSeekCompletedCb, NULL );
453 LogPlayerError( error );
457 int TizenVideoPlayer::GetPlayPosition()
462 GetPlayerState( &mPlayerState );
464 if( mPlayerState == PLAYER_STATE_IDLE ||
465 mPlayerState == PLAYER_STATE_READY ||
466 mPlayerState == PLAYER_STATE_PLAYING ||
467 mPlayerState == PLAYER_STATE_PAUSED
470 error = player_get_play_position( mPlayer, &millisecond );
471 LogPlayerError( error );
477 void TizenVideoPlayer::SetDisplayRotation( Dali::VideoPlayerPlugin::DisplayRotation rotation )
479 if( mNativeImageSourcePtr != NULL )
481 DALI_LOG_ERROR( "SetDisplayRotation is only for window rendering target.\n" );
486 if( mPlayerState != PLAYER_STATE_NONE )
488 error = player_set_display_rotation( mPlayer, static_cast< player_display_rotation_e >( rotation ) );
489 LogPlayerError( error );
493 Dali::VideoPlayerPlugin::DisplayRotation TizenVideoPlayer::GetDisplayRotation()
495 if( mNativeImageSourcePtr != NULL )
497 DALI_LOG_ERROR( "GetDisplayRotation is only for window rendering target.\n" );
498 return Dali::VideoPlayerPlugin::ROTATION_NONE;
502 player_display_rotation_e rotation = PLAYER_DISPLAY_ROTATION_NONE;
503 if( mPlayerState != PLAYER_STATE_NONE )
505 error = player_get_display_rotation( mPlayer, &rotation );
506 LogPlayerError( error );
508 return static_cast< Dali::VideoPlayerPlugin::DisplayRotation >( rotation );
511 Dali::VideoPlayerPlugin::VideoPlayerSignalType& TizenVideoPlayer::FinishedSignal()
513 return mFinishedSignal;
516 void TizenVideoPlayer::InitializeTextureStreamMode( Dali::NativeImageSourcePtr nativeImageSourcePtr )
520 mNativeImageSourcePtr = nativeImageSourcePtr;
522 if( mAlphaBitChanged )
524 ecore_wl_window_alpha_set( mEcoreWlWindow, false );
525 mAlphaBitChanged = false;
528 if( mPlayerState == PLAYER_STATE_NONE )
530 error = player_create( &mPlayer );
531 LogPlayerError( error );
534 GetPlayerState( &mPlayerState );
536 if( mPlayerState == PLAYER_STATE_IDLE )
538 error = player_set_completed_cb( mPlayer, EmitPlaybackFinishedSignal, this );
539 LogPlayerError( error );
541 error = player_set_media_packet_video_frame_decoded_cb( mPlayer, MediaPacketVideoDecodedCb, this );
542 LogPlayerError( error );
544 error = player_set_sound_type( mPlayer, SOUND_TYPE_MEDIA );
545 LogPlayerError( error );
547 error = player_set_display_mode( mPlayer, PLAYER_DISPLAY_MODE_FULL_SCREEN );
548 LogPlayerError( error );
550 error = player_set_display( mPlayer, PLAYER_DISPLAY_TYPE_NONE, NULL );
551 LogPlayerError( error );
553 error = player_set_display_visible( mPlayer, true );
554 LogPlayerError( error );
556 mTimer = Dali::Timer::New( TIMER_INTERVAL );
557 mTimer.TickSignal().Connect( this, &TizenVideoPlayer::Update );
561 void TizenVideoPlayer::InitializeUnderlayMode( Ecore_Wl_Window* ecoreWlWindow )
564 if( mPlayerState == PLAYER_STATE_NONE )
566 error = player_create( &mPlayer );
567 LogPlayerError( error );
570 GetPlayerState( &mPlayerState );
571 mEcoreWlWindow = ecoreWlWindow;
573 if( mPlayerState == PLAYER_STATE_IDLE )
575 error = player_set_completed_cb( mPlayer, EmitPlaybackFinishedSignal, this );
576 LogPlayerError( error );
578 error = player_set_sound_type( mPlayer, SOUND_TYPE_MEDIA );
579 LogPlayerError( error );
581 error = player_set_display_mode( mPlayer, PLAYER_DISPLAY_MODE_DST_ROI );
582 LogPlayerError( error );
584 error = player_set_display_roi_area( mPlayer, 0, 0, 1, 1 );
587 mAlphaBitChanged = ( ecore_wl_window_alpha_get( mEcoreWlWindow ) )? false: true;
588 ecore_wl_screen_size_get( &width, &height );
590 if( mAlphaBitChanged )
592 ecore_wl_window_alpha_set( mEcoreWlWindow, true );
594 error = player_set_ecore_wl_display( mPlayer, PLAYER_DISPLAY_TYPE_OVERLAY, mEcoreWlWindow, 0, 0, width, height );
595 LogPlayerError( error );
597 error = player_set_display_visible( mPlayer, true );
598 LogPlayerError( error );
602 bool TizenVideoPlayer::Update()
604 Dali::Mutex::ScopedLock lock( mPacketMutex );
608 if( mPacket != NULL )
610 error = media_packet_destroy( mPacket );
611 if( error != MEDIA_PACKET_ERROR_NONE )
613 DALI_LOG_ERROR( "Media packet destroy error: %d\n", error );
618 if( !mPacketVector.Empty() )
620 mPacket = static_cast< media_packet_h >( mPacketVector[0] );
621 mPacketVector.Remove( mPacketVector.Begin() );
624 if( mPacket == NULL )
629 error = media_packet_get_tbm_surface( mPacket, &mTbmSurface );
630 if( error != MEDIA_PACKET_ERROR_NONE )
632 media_packet_destroy( mPacket );
634 DALI_LOG_ERROR( " error: %d\n", error );
638 Any source( mTbmSurface );
639 mNativeImageSourcePtr->SetSource( source );
640 Dali::Stage::GetCurrent().KeepRendering( 0.0f );
645 void TizenVideoPlayer::DestroyPackets()
648 if( mPacket != NULL )
650 error = media_packet_destroy( mPacket );
651 DALI_LOG_ERROR( "Media packet destroy error: %d\n", error );
655 for(unsigned int i = 0; i < mPacketVector.Size(); ++i)
657 mPacket = static_cast< media_packet_h >( mPacketVector[i] );
658 error = media_packet_destroy( mPacket );
659 DALI_LOG_ERROR( "Media packet destroy error: %d\n", error );
662 mPacketVector.Clear();
665 void TizenVideoPlayer::PushPacket( media_packet_h packet )
667 Dali::Mutex::ScopedLock lock( mPacketMutex );
668 mPacketVector.PushBack( packet );
671 void TizenVideoPlayer::SetDisplayArea( DisplayArea area )
673 GetPlayerState( &mPlayerState );
675 if( mNativeImageSourcePtr != NULL )
677 DALI_LOG_ERROR( "SetDisplayArea is only for window surface target.\n" );
681 if( mPlayerState == PLAYER_STATE_IDLE ||
682 mPlayerState == PLAYER_STATE_READY ||
683 mPlayerState == PLAYER_STATE_PLAYING ||
684 mPlayerState == PLAYER_STATE_PAUSED
688 int error = player_set_display_roi_area( mPlayer, area.x, area.y, area.width, area.height );
689 LogPlayerError( error );
693 void TizenVideoPlayer::Forward( int millisecond )
697 GetPlayerState( &mPlayerState );
699 if( mPlayerState == PLAYER_STATE_READY ||
700 mPlayerState == PLAYER_STATE_PLAYING ||
701 mPlayerState == PLAYER_STATE_PAUSED
704 int currentPosition = 0;
705 int nextPosition = 0;
707 error = player_get_play_position( mPlayer, ¤tPosition );
708 LogPlayerError( error );
710 nextPosition = currentPosition + millisecond;
712 error = player_set_play_position( mPlayer, nextPosition, false, PlayerSeekCompletedCb, NULL );
713 LogPlayerError( error );
717 void TizenVideoPlayer::Backward( int millisecond )
721 GetPlayerState( &mPlayerState );
723 if( mPlayerState == PLAYER_STATE_READY ||
724 mPlayerState == PLAYER_STATE_PLAYING ||
725 mPlayerState == PLAYER_STATE_PAUSED
728 int currentPosition = 0;
729 int nextPosition = 0;
731 error = player_get_play_position( mPlayer, ¤tPosition );
732 LogPlayerError( error );
734 nextPosition = currentPosition - millisecond;
735 nextPosition = ( nextPosition < 0 )? 0 : nextPosition;
737 error = player_set_play_position( mPlayer, nextPosition, false, PlayerSeekCompletedCb, NULL );
738 LogPlayerError( error );
742 } // namespace Plugin