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()
213 mPlayerState( PLAYER_STATE_NONE ),
216 mTargetType( NativeImage ),
217 mAlphaBitChanged( false )
221 TizenVideoPlayer::~TizenVideoPlayer()
225 void TizenVideoPlayer::GetPlayerState( player_state_e* state )
227 if( mPlayer != NULL && player_get_state( mPlayer, state ) != PLAYER_ERROR_NONE )
229 DALI_LOG_ERROR( "player_get_state error: Invalid parameter\n" );
230 *state = PLAYER_STATE_NONE;
234 void TizenVideoPlayer::SetUrl( const std::string& url )
240 GetPlayerState( &mPlayerState );
242 if( mPlayerState != PLAYER_STATE_NONE && mPlayerState != PLAYER_STATE_IDLE )
245 int error = player_unprepare( mPlayer );
246 LogPlayerError( error );
249 if( mPlayerState == PLAYER_STATE_IDLE )
251 int error = player_set_uri( mPlayer, mUrl.c_str() );
252 LogPlayerError( error );
254 error = player_prepare( mPlayer );
255 LogPlayerError( error );
260 std::string TizenVideoPlayer::GetUrl()
265 void TizenVideoPlayer::SetRenderingTarget( Any target )
268 if( mPlayerState != PLAYER_STATE_NONE )
270 GetPlayerState( &mPlayerState );
272 if( mPlayerState != PLAYER_STATE_IDLE )
275 error = player_unprepare( mPlayer );
276 LogPlayerError( error );
279 error = player_destroy( mPlayer );
280 LogPlayerError( error );
281 mPlayerState = PLAYER_STATE_NONE;
286 mNativeImageSourcePtr = NULL;
287 mEcoreWlWindow = NULL;
289 if( target.GetType() == typeid( Dali::NativeImageSourcePtr ) )
291 mTargetType = TizenVideoPlayer::NativeImage;
293 Dali::NativeImageSourcePtr nativeImageSourcePtr = AnyCast< Dali::NativeImageSourcePtr >( target );
295 InitializeTextureStreamMode( nativeImageSourcePtr );
297 else if( target.GetType() == typeid( Ecore_Wl_Window* ) )
299 mTargetType = TizenVideoPlayer::WindowSurface;
301 Ecore_Wl_Window* nativeWindow = Dali::AnyCast< Ecore_Wl_Window* >( target );
302 InitializeUnderlayMode( nativeWindow );
306 DALI_LOG_ERROR( "Video rendering target is unknown\n" );
310 void TizenVideoPlayer::SetLooping( bool looping )
312 GetPlayerState( &mPlayerState );
314 if( mPlayerState != PLAYER_STATE_NONE )
316 int error = player_set_looping( mPlayer, looping );
317 LogPlayerError( error );
321 bool TizenVideoPlayer::IsLooping()
323 GetPlayerState( &mPlayerState );
325 bool looping = false;
326 if( mPlayerState != PLAYER_STATE_NONE )
328 int error = player_is_looping( mPlayer, &looping );
329 LogPlayerError( error );
335 void TizenVideoPlayer::Play()
337 GetPlayerState( &mPlayerState );
339 if( mPlayerState == PLAYER_STATE_READY || mPlayerState == PLAYER_STATE_PAUSED )
341 if( mNativeImageSourcePtr != NULL && mTimer )
346 int error = player_start( mPlayer );
347 LogPlayerError( error );
351 void TizenVideoPlayer::Pause()
353 GetPlayerState( &mPlayerState );
355 if( mPlayerState == PLAYER_STATE_PLAYING )
357 int error = player_pause( mPlayer );
358 LogPlayerError( error );
360 if( mNativeImageSourcePtr != NULL && mTimer )
368 void TizenVideoPlayer::Stop()
370 GetPlayerState( &mPlayerState );
372 if( mPlayerState == PLAYER_STATE_PLAYING || mPlayerState == PLAYER_STATE_PAUSED )
374 int error = player_stop( mPlayer );
375 LogPlayerError( error );
378 if( mNativeImageSourcePtr != NULL && mTimer )
385 void TizenVideoPlayer::SetMute( bool muted )
387 GetPlayerState( &mPlayerState );
389 if( mPlayerState == PLAYER_STATE_IDLE ||
390 mPlayerState == PLAYER_STATE_READY ||
391 mPlayerState == PLAYER_STATE_PLAYING ||
392 mPlayerState == PLAYER_STATE_PAUSED
395 int error = player_set_mute( mPlayer, muted );
396 LogPlayerError( error );
400 bool TizenVideoPlayer::IsMuted()
402 GetPlayerState( &mPlayerState );
405 if( mPlayerState == PLAYER_STATE_IDLE ||
406 mPlayerState == PLAYER_STATE_READY ||
407 mPlayerState == PLAYER_STATE_PLAYING ||
408 mPlayerState == PLAYER_STATE_PAUSED
411 int error = player_is_muted( mPlayer, &muted );
412 LogPlayerError( error );
418 void TizenVideoPlayer::SetVolume( float left, float right )
420 GetPlayerState( &mPlayerState );
422 int error = player_set_volume( mPlayer, left, right );
423 LogPlayerError( error );
426 void TizenVideoPlayer::GetVolume( float& left, float& right )
428 GetPlayerState( &mPlayerState );
430 int error = player_get_volume( mPlayer, &left, &right );
431 LogPlayerError( error );
434 void TizenVideoPlayer::SetPlayPosition( int millisecond )
438 GetPlayerState( &mPlayerState );
440 if( mPlayerState == PLAYER_STATE_READY ||
441 mPlayerState == PLAYER_STATE_PLAYING ||
442 mPlayerState == PLAYER_STATE_PAUSED
445 error = player_set_play_position( mPlayer, millisecond, false, PlayerSeekCompletedCb, NULL );
446 LogPlayerError( error );
450 int TizenVideoPlayer::GetPlayPosition()
455 GetPlayerState( &mPlayerState );
457 if( mPlayerState == PLAYER_STATE_IDLE ||
458 mPlayerState == PLAYER_STATE_READY ||
459 mPlayerState == PLAYER_STATE_PLAYING ||
460 mPlayerState == PLAYER_STATE_PAUSED
463 error = player_get_play_position( mPlayer, &millisecond );
464 LogPlayerError( error );
470 void TizenVideoPlayer::SetDisplayRotation( Dali::VideoPlayerPlugin::DisplayRotation rotation )
472 if( mNativeImageSourcePtr != NULL )
474 DALI_LOG_ERROR( "SetDisplayRotation is only for window rendering target.\n" );
479 if( mPlayerState != PLAYER_STATE_NONE )
481 error = player_set_display_rotation( mPlayer, static_cast< player_display_rotation_e >( rotation ) );
482 LogPlayerError( error );
486 Dali::VideoPlayerPlugin::DisplayRotation TizenVideoPlayer::GetDisplayRotation()
488 if( mNativeImageSourcePtr != NULL )
490 DALI_LOG_ERROR( "GetDisplayRotation is only for window rendering target.\n" );
491 return Dali::VideoPlayerPlugin::ROTATION_NONE;
495 player_display_rotation_e rotation = PLAYER_DISPLAY_ROTATION_NONE;
496 if( mPlayerState != PLAYER_STATE_NONE )
498 error = player_get_display_rotation( mPlayer, &rotation );
499 LogPlayerError( error );
501 return static_cast< Dali::VideoPlayerPlugin::DisplayRotation >( rotation );
504 Dali::VideoPlayerPlugin::VideoPlayerSignalType& TizenVideoPlayer::FinishedSignal()
506 return mFinishedSignal;
509 void TizenVideoPlayer::InitializeTextureStreamMode( Dali::NativeImageSourcePtr nativeImageSourcePtr )
513 mNativeImageSourcePtr = nativeImageSourcePtr;
515 if( mAlphaBitChanged )
517 ecore_wl_window_alpha_set( mEcoreWlWindow, false );
518 mAlphaBitChanged = false;
521 if( mPlayerState == PLAYER_STATE_NONE )
523 error = player_create( &mPlayer );
524 LogPlayerError( error );
527 GetPlayerState( &mPlayerState );
529 if( mPlayerState == PLAYER_STATE_IDLE )
531 error = player_set_completed_cb( mPlayer, EmitPlaybackFinishedSignal, this );
532 LogPlayerError( error );
534 error = player_set_media_packet_video_frame_decoded_cb( mPlayer, MediaPacketVideoDecodedCb, this );
535 LogPlayerError( error );
537 error = player_set_sound_type( mPlayer, SOUND_TYPE_MEDIA );
538 LogPlayerError( error );
540 error = player_set_display_mode( mPlayer, PLAYER_DISPLAY_MODE_FULL_SCREEN );
541 LogPlayerError( error );
543 error = player_set_display( mPlayer, PLAYER_DISPLAY_TYPE_NONE, NULL );
544 LogPlayerError( error );
546 error = player_set_display_visible( mPlayer, true );
547 LogPlayerError( error );
549 mTimer = Dali::Timer::New( TIMER_INTERVAL );
550 mTimer.TickSignal().Connect( this, &TizenVideoPlayer::Update );
554 void TizenVideoPlayer::InitializeUnderlayMode( Ecore_Wl_Window* ecoreWlWindow )
557 if( mPlayerState == PLAYER_STATE_NONE )
559 error = player_create( &mPlayer );
560 LogPlayerError( error );
563 GetPlayerState( &mPlayerState );
564 mEcoreWlWindow = ecoreWlWindow;
566 if( mPlayerState == PLAYER_STATE_IDLE )
568 error = player_set_completed_cb( mPlayer, EmitPlaybackFinishedSignal, this );
569 LogPlayerError( error );
571 error = player_set_sound_type( mPlayer, SOUND_TYPE_MEDIA );
572 LogPlayerError( error );
574 error = player_set_display_mode( mPlayer, PLAYER_DISPLAY_MODE_DST_ROI );
575 LogPlayerError( error );
577 error = player_set_display_roi_area( mPlayer, 0, 0, 1, 1 );
580 mAlphaBitChanged = ( ecore_wl_window_alpha_get( mEcoreWlWindow ) )? false: true;
581 ecore_wl_screen_size_get( &width, &height );
583 if( mAlphaBitChanged )
585 ecore_wl_window_alpha_set( mEcoreWlWindow, true );
587 error = player_set_ecore_wl_display( mPlayer, PLAYER_DISPLAY_TYPE_OVERLAY, mEcoreWlWindow, 0, 0, width, height );
588 LogPlayerError( error );
590 error = player_set_display_visible( mPlayer, true );
591 LogPlayerError( error );
595 bool TizenVideoPlayer::Update()
597 Dali::Mutex::ScopedLock lock( mPacketMutex );
601 if( mPacket != NULL )
603 error = media_packet_destroy( mPacket );
604 if( error != MEDIA_PACKET_ERROR_NONE )
606 DALI_LOG_ERROR( "Media packet destroy error: %d\n", error );
611 if( !mPacketVector.Empty() )
613 mPacket = static_cast< media_packet_h >( mPacketVector[0] );
614 mPacketVector.Remove( mPacketVector.Begin() );
617 if( mPacket == NULL )
622 error = media_packet_get_tbm_surface( mPacket, &mTbmSurface );
623 if( error != MEDIA_PACKET_ERROR_NONE )
625 media_packet_destroy( mPacket );
627 DALI_LOG_ERROR( " error: %d\n", error );
631 Any source( mTbmSurface );
632 mNativeImageSourcePtr->SetSource( source );
633 Dali::Stage::GetCurrent().KeepRendering( 0.0f );
638 void TizenVideoPlayer::DestroyPackets()
641 if( mPacket != NULL )
643 error = media_packet_destroy( mPacket );
644 DALI_LOG_ERROR( "Media packet destroy error: %d\n", error );
648 for(unsigned int i = 0; i < mPacketVector.Size(); ++i)
650 mPacket = static_cast< media_packet_h >( mPacketVector[i] );
651 error = media_packet_destroy( mPacket );
652 DALI_LOG_ERROR( "Media packet destroy error: %d\n", error );
655 mPacketVector.Clear();
658 void TizenVideoPlayer::PushPacket( media_packet_h packet )
660 Dali::Mutex::ScopedLock lock( mPacketMutex );
661 mPacketVector.PushBack( packet );
664 void TizenVideoPlayer::SetDisplayArea( DisplayArea area )
666 GetPlayerState( &mPlayerState );
668 if( mNativeImageSourcePtr != NULL )
670 DALI_LOG_ERROR( "SetDisplayArea is only for window surface target.\n" );
674 if( mPlayerState == PLAYER_STATE_IDLE ||
675 mPlayerState == PLAYER_STATE_READY ||
676 mPlayerState == PLAYER_STATE_PLAYING ||
677 mPlayerState == PLAYER_STATE_PAUSED
681 int error = player_set_display_roi_area( mPlayer, area.x, area.y, area.width, area.height );
682 LogPlayerError( error );
686 void TizenVideoPlayer::Forward( int millisecond )
690 GetPlayerState( &mPlayerState );
692 if( mPlayerState == PLAYER_STATE_READY ||
693 mPlayerState == PLAYER_STATE_PLAYING ||
694 mPlayerState == PLAYER_STATE_PAUSED
697 int currentPosition = 0;
698 int nextPosition = 0;
700 error = player_get_play_position( mPlayer, ¤tPosition );
701 LogPlayerError( error );
703 nextPosition = currentPosition + millisecond;
705 error = player_set_play_position( mPlayer, nextPosition, false, PlayerSeekCompletedCb, NULL );
706 LogPlayerError( error );
710 void TizenVideoPlayer::Backward( int millisecond )
714 GetPlayerState( &mPlayerState );
716 if( mPlayerState == PLAYER_STATE_READY ||
717 mPlayerState == PLAYER_STATE_PLAYING ||
718 mPlayerState == PLAYER_STATE_PAUSED
721 int currentPosition = 0;
722 int nextPosition = 0;
724 error = player_get_play_position( mPlayer, ¤tPosition );
725 LogPlayerError( error );
727 nextPosition = currentPosition - millisecond;
728 nextPosition = ( nextPosition < 0 )? 0 : nextPosition;
730 error = player_set_play_position( mPlayer, nextPosition, false, PlayerSeekCompletedCb, NULL );
731 LogPlayerError( error );
735 } // namespace Plugin