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>
25 #include <system_info.h>
29 // The plugin factories
30 extern "C" DALI_EXPORT_API Dali::VideoPlayerPlugin* CreateVideoPlayerPlugin( void )
32 return new Dali::Plugin::TizenVideoPlayer;
35 extern "C" DALI_EXPORT_API void DestroyVideoPlayerPlugin( Dali::VideoPlayerPlugin* plugin )
52 const int TIMER_INTERVAL( 20 );
54 static void MediaPacketVideoDecodedCb( media_packet_h packet, void* user_data )
56 TizenVideoPlayer* player = static_cast< TizenVideoPlayer* >( user_data );
60 DALI_LOG_ERROR( "Decoded callback got Null pointer as user_data.\n" );
64 player->PushPacket( packet );
67 static void EmitPlaybackFinishedSignal( void* user_data )
69 TizenVideoPlayer* player = static_cast< TizenVideoPlayer* >( user_data );
73 DALI_LOG_ERROR( "Decoded callback got Null pointer as user_data.\n" );
77 if( !player->mFinishedSignal.Empty() )
79 DALI_LOG_ERROR( "EmitPlaybackFinishedSignal.3\n" );
80 player->mFinishedSignal.Emit();
86 // ToDo: VD player_set_play_position() doesn't work when callback pointer is NULL.
87 // We should check whether this callback is needed in platform.
88 static void PlayerSeekCompletedCb( void* data )
92 void LogPlayerError( int error )
94 if( error != PLAYER_ERROR_NONE )
98 case PLAYER_ERROR_OUT_OF_MEMORY:
100 DALI_LOG_ERROR( "Player error: Out of memory\n" );
103 case PLAYER_ERROR_INVALID_PARAMETER:
105 DALI_LOG_ERROR( "Player error: Invalid parameter\n" );
108 case PLAYER_ERROR_NO_SUCH_FILE:
110 DALI_LOG_ERROR( "Player error: No such file\n" );
113 case PLAYER_ERROR_INVALID_OPERATION:
115 DALI_LOG_ERROR( "Player error: Invalid operation\n" );
118 case PLAYER_ERROR_FILE_NO_SPACE_ON_DEVICE:
120 DALI_LOG_ERROR( "Player error: No space on device\n" );
123 case PLAYER_ERROR_FEATURE_NOT_SUPPORTED_ON_DEVICE:
125 DALI_LOG_ERROR( "Player error: Not supported feature on device\n" );
128 case PLAYER_ERROR_SEEK_FAILED:
130 DALI_LOG_ERROR( "Player error: Seek failed\n" );
133 case PLAYER_ERROR_INVALID_STATE:
135 DALI_LOG_ERROR( "Player error: Invalid state\n" );
138 case PLAYER_ERROR_NOT_SUPPORTED_FILE:
140 DALI_LOG_ERROR( "Player error: Not supported file\n" );
143 case PLAYER_ERROR_INVALID_URI:
145 DALI_LOG_ERROR( "Player error: Invalid uri\n" );
148 case PLAYER_ERROR_SOUND_POLICY:
150 DALI_LOG_ERROR( "Player error: Sound policy\n" );
153 case PLAYER_ERROR_CONNECTION_FAILED:
155 DALI_LOG_ERROR( "Player error: Connection failed\n" );
158 case PLAYER_ERROR_VIDEO_CAPTURE_FAILED:
160 DALI_LOG_ERROR( "Player error: Video capture failed\n" );
163 case PLAYER_ERROR_DRM_EXPIRED:
165 DALI_LOG_ERROR( "Player error: DRM expired\n" );
168 case PLAYER_ERROR_DRM_NO_LICENSE:
170 DALI_LOG_ERROR( "Player error: No license\n" );
173 case PLAYER_ERROR_DRM_FUTURE_USE:
175 DALI_LOG_ERROR( "Player error: License for future use\n" );
178 case PLAYER_ERROR_DRM_NOT_PERMITTED:
180 DALI_LOG_ERROR( "Player error: Format not permitted\n" );
183 case PLAYER_ERROR_RESOURCE_LIMIT:
185 DALI_LOG_ERROR( "Player error: Resource limit\n" );
188 case PLAYER_ERROR_PERMISSION_DENIED:
190 DALI_LOG_ERROR( "Player error: Permission denied\n" );
193 case PLAYER_ERROR_SERVICE_DISCONNECTED:
195 DALI_LOG_ERROR( "Player error: Service disconnected\n" );
198 case PLAYER_ERROR_BUFFER_SPACE:
200 DALI_LOG_ERROR( "Player error: Buffer space\n" );
207 } // unnamed namespace
209 TizenVideoPlayer::TizenVideoPlayer()
212 mPlayerState( PLAYER_STATE_NONE ),
215 mNativeImageSourcePtr( NULL ),
217 mBackgroundColor( Dali::Vector4( 1.0f, 1.0f, 1.0f, 0.0f ) ),
218 mTargetType( NativeImage ),
221 mEcoreWlWindow( NULL ),
222 mAlphaBitChanged( false ),
223 mCodecType( PLAYER_CODEC_TYPE_DEFAULT ),
225 mStreamType( SOUND_STREAM_TYPE_MEDIA )
229 TizenVideoPlayer::~TizenVideoPlayer()
234 void TizenVideoPlayer::GetPlayerState( player_state_e* state ) const
236 if( mPlayer != NULL && player_get_state( mPlayer, state ) != PLAYER_ERROR_NONE )
238 DALI_LOG_ERROR( "player_get_state error: Invalid parameter\n" );
239 *state = PLAYER_STATE_NONE;
243 void TizenVideoPlayer::SetUrl( const std::string& url )
247 int error = PLAYER_ERROR_NONE;
251 GetPlayerState( &mPlayerState );
253 if( mPlayerState != PLAYER_STATE_NONE && mPlayerState != PLAYER_STATE_IDLE )
256 if( mNativeImageSourcePtr )
258 error = player_unset_media_packet_video_frame_decoded_cb( mPlayer );
259 LogPlayerError( error );
264 error = player_unprepare( mPlayer );
265 LogPlayerError( error );
267 if( mNativeImageSourcePtr )
269 error = player_set_media_packet_video_frame_decoded_cb( mPlayer, MediaPacketVideoDecodedCb, this );
270 LogPlayerError( error );
275 ecore_wl_screen_size_get( &width, &height );
276 error = player_set_ecore_wl_display( mPlayer, PLAYER_DISPLAY_TYPE_OVERLAY, mEcoreWlWindow, 0, 0, width, height );
277 LogPlayerError( error );
280 GetPlayerState( &mPlayerState );
281 LogPlayerError( error );
284 if( mPlayerState == PLAYER_STATE_IDLE )
286 error = player_set_uri( mPlayer, mUrl.c_str() );
287 LogPlayerError( error );
289 error = player_prepare( mPlayer );
290 LogPlayerError( error );
295 std::string TizenVideoPlayer::GetUrl()
300 void TizenVideoPlayer::SetRenderingTarget( Any target )
304 mNativeImageSourcePtr = NULL;
305 mEcoreWlWindow = NULL;
307 if( target.GetType() == typeid( Dali::NativeImageSourcePtr ) )
309 mTargetType = TizenVideoPlayer::NativeImage;
311 Dali::NativeImageSourcePtr nativeImageSourcePtr = AnyCast< Dali::NativeImageSourcePtr >( target );
313 InitializeTextureStreamMode( nativeImageSourcePtr );
315 else if( target.GetType() == typeid( Ecore_Wl_Window* ) )
317 mTargetType = TizenVideoPlayer::WindowSurface;
319 Ecore_Wl_Window* nativeWindow = Dali::AnyCast< Ecore_Wl_Window* >( target );
320 InitializeUnderlayMode( nativeWindow );
324 DALI_LOG_ERROR( "Video rendering target is unknown\n" );
328 void TizenVideoPlayer::SetLooping( bool looping )
330 GetPlayerState( &mPlayerState );
332 if( mPlayerState != PLAYER_STATE_NONE )
334 int error = player_set_looping( mPlayer, looping );
335 LogPlayerError( error );
339 bool TizenVideoPlayer::IsLooping()
341 GetPlayerState( &mPlayerState );
343 bool looping = false;
344 if( mPlayerState != PLAYER_STATE_NONE )
346 int error = player_is_looping( mPlayer, &looping );
347 LogPlayerError( error );
353 void TizenVideoPlayer::Play()
355 GetPlayerState( &mPlayerState );
357 if( mPlayerState == PLAYER_STATE_READY || mPlayerState == PLAYER_STATE_PAUSED )
359 if( mNativeImageSourcePtr != NULL && mTimer )
364 int error = player_start( mPlayer );
365 LogPlayerError( error );
369 void TizenVideoPlayer::Pause()
371 GetPlayerState( &mPlayerState );
373 if( mPlayerState == PLAYER_STATE_PLAYING )
375 int error = player_pause( mPlayer );
376 LogPlayerError( error );
378 if( mNativeImageSourcePtr != NULL && mTimer )
386 void TizenVideoPlayer::Stop()
388 GetPlayerState( &mPlayerState );
390 if( mPlayerState == PLAYER_STATE_PLAYING || mPlayerState == PLAYER_STATE_PAUSED )
392 int error = player_stop( mPlayer );
393 LogPlayerError( error );
396 if( mNativeImageSourcePtr != NULL && mTimer )
403 void TizenVideoPlayer::SetMute( bool muted )
405 GetPlayerState( &mPlayerState );
407 if( mPlayerState == PLAYER_STATE_IDLE ||
408 mPlayerState == PLAYER_STATE_READY ||
409 mPlayerState == PLAYER_STATE_PLAYING ||
410 mPlayerState == PLAYER_STATE_PAUSED
413 int error = player_set_mute( mPlayer, muted );
414 LogPlayerError( error );
418 bool TizenVideoPlayer::IsMuted()
420 GetPlayerState( &mPlayerState );
423 if( mPlayerState == PLAYER_STATE_IDLE ||
424 mPlayerState == PLAYER_STATE_READY ||
425 mPlayerState == PLAYER_STATE_PLAYING ||
426 mPlayerState == PLAYER_STATE_PAUSED
429 int error = player_is_muted( mPlayer, &muted );
430 LogPlayerError( error );
436 void TizenVideoPlayer::SetVolume( float left, float right )
438 GetPlayerState( &mPlayerState );
440 int error = player_set_volume( mPlayer, left, right );
441 LogPlayerError( error );
444 void TizenVideoPlayer::GetVolume( float& left, float& right )
446 GetPlayerState( &mPlayerState );
448 int error = player_get_volume( mPlayer, &left, &right );
449 LogPlayerError( error );
452 void TizenVideoPlayer::SetPlayPosition( int millisecond )
456 GetPlayerState( &mPlayerState );
458 if( mPlayerState == PLAYER_STATE_READY ||
459 mPlayerState == PLAYER_STATE_PLAYING ||
460 mPlayerState == PLAYER_STATE_PAUSED
463 error = player_set_play_position( mPlayer, millisecond, false, PlayerSeekCompletedCb, NULL );
464 LogPlayerError( error );
468 int TizenVideoPlayer::GetPlayPosition()
473 GetPlayerState( &mPlayerState );
475 if( mPlayerState == PLAYER_STATE_IDLE ||
476 mPlayerState == PLAYER_STATE_READY ||
477 mPlayerState == PLAYER_STATE_PLAYING ||
478 mPlayerState == PLAYER_STATE_PAUSED
481 error = player_get_play_position( mPlayer, &millisecond );
482 LogPlayerError( error );
488 void TizenVideoPlayer::SetDisplayRotation( Dali::VideoPlayerPlugin::DisplayRotation rotation )
490 if( mNativeImageSourcePtr != NULL )
492 DALI_LOG_ERROR( "SetDisplayRotation is only for window rendering target.\n" );
497 if( mPlayerState != PLAYER_STATE_NONE )
499 error = player_set_display_rotation( mPlayer, static_cast< player_display_rotation_e >( rotation ) );
500 LogPlayerError( error );
504 Dali::VideoPlayerPlugin::DisplayRotation TizenVideoPlayer::GetDisplayRotation()
506 if( mNativeImageSourcePtr != NULL )
508 DALI_LOG_ERROR( "GetDisplayRotation is only for window rendering target.\n" );
509 return Dali::VideoPlayerPlugin::ROTATION_NONE;
513 player_display_rotation_e rotation = PLAYER_DISPLAY_ROTATION_NONE;
514 if( mPlayerState != PLAYER_STATE_NONE )
516 error = player_get_display_rotation( mPlayer, &rotation );
517 LogPlayerError( error );
519 return static_cast< Dali::VideoPlayerPlugin::DisplayRotation >( rotation );
522 Dali::VideoPlayerPlugin::VideoPlayerSignalType& TizenVideoPlayer::FinishedSignal()
524 return mFinishedSignal;
527 void TizenVideoPlayer::InitializeTextureStreamMode( Dali::NativeImageSourcePtr nativeImageSourcePtr )
531 mNativeImageSourcePtr = nativeImageSourcePtr;
533 if( mAlphaBitChanged )
535 ecore_wl_window_alpha_set( mEcoreWlWindow, false );
536 mAlphaBitChanged = false;
539 if( mPlayerState == PLAYER_STATE_NONE )
541 error = player_create( &mPlayer );
542 LogPlayerError( error );
545 GetPlayerState( &mPlayerState );
547 if( mPlayerState == PLAYER_STATE_IDLE )
549 error = player_set_completed_cb( mPlayer, EmitPlaybackFinishedSignal, this );
550 LogPlayerError( error );
552 error = player_set_media_packet_video_frame_decoded_cb( mPlayer, MediaPacketVideoDecodedCb, this );
553 LogPlayerError( error );
555 error = sound_manager_create_stream_information( mStreamType, NULL, NULL, &mStreamInfo );
556 LogPlayerError( error );
558 error = player_set_sound_stream_info( mPlayer, mStreamInfo );
559 LogPlayerError( error );
561 error = player_set_display_mode( mPlayer, PLAYER_DISPLAY_MODE_FULL_SCREEN );
562 LogPlayerError( error );
564 error = player_set_display( mPlayer, PLAYER_DISPLAY_TYPE_NONE, NULL );
565 LogPlayerError( error );
567 error = player_set_display_visible( mPlayer, true );
568 LogPlayerError( error );
570 mTimer = Dali::Timer::New( TIMER_INTERVAL );
571 mTimer.TickSignal().Connect( this, &TizenVideoPlayer::Update );
575 void TizenVideoPlayer::InitializeUnderlayMode( Ecore_Wl_Window* ecoreWlWindow )
578 if( mPlayerState == PLAYER_STATE_NONE )
580 error = player_create( &mPlayer );
581 LogPlayerError( error );
584 GetPlayerState( &mPlayerState );
585 mEcoreWlWindow = ecoreWlWindow;
587 if( mPlayerState == PLAYER_STATE_IDLE )
589 error = player_set_completed_cb( mPlayer, EmitPlaybackFinishedSignal, this );
590 LogPlayerError( error );
592 error = sound_manager_create_stream_information( mStreamType, NULL, NULL, &mStreamInfo );
593 LogPlayerError( error );
595 error = player_set_sound_stream_info( mPlayer, mStreamInfo );
596 LogPlayerError( error );
598 error = player_set_display_mode( mPlayer, PLAYER_DISPLAY_MODE_DST_ROI );
599 LogPlayerError( error );
601 error = player_set_display_roi_area( mPlayer, 0, 0, 1, 1 );
604 ecore_wl_screen_size_get( &width, &height );
605 ecore_wl_window_alpha_set( mEcoreWlWindow, false );
607 error = player_set_ecore_wl_display( mPlayer, PLAYER_DISPLAY_TYPE_OVERLAY, mEcoreWlWindow, 0, 0, width, height );
608 LogPlayerError( error );
610 error = player_set_display_visible( mPlayer, true );
611 LogPlayerError( error );
615 bool TizenVideoPlayer::Update()
617 Dali::Mutex::ScopedLock lock( mPacketMutex );
621 if( mPacket != NULL )
623 error = media_packet_destroy( mPacket );
624 if( error != MEDIA_PACKET_ERROR_NONE )
626 DALI_LOG_ERROR( "Media packet destroy error: %d\n", error );
631 if( !mPacketVector.Empty() )
633 mPacket = static_cast< media_packet_h >( mPacketVector[0] );
634 mPacketVector.Remove( mPacketVector.Begin() );
637 if( mPacket == NULL )
642 error = media_packet_get_tbm_surface( mPacket, &mTbmSurface );
643 if( error != MEDIA_PACKET_ERROR_NONE )
645 media_packet_destroy( mPacket );
647 DALI_LOG_ERROR( " error: %d\n", error );
651 Any source( mTbmSurface );
652 mNativeImageSourcePtr->SetSource( source );
653 Dali::Stage::GetCurrent().KeepRendering( 0.0f );
658 void TizenVideoPlayer::DestroyPackets()
661 if( mPacket != NULL )
663 error = media_packet_destroy( mPacket );
664 DALI_LOG_ERROR( "Media packet destroy error: %d\n", error );
668 for(unsigned int i = 0; i < mPacketVector.Size(); ++i)
670 mPacket = static_cast< media_packet_h >( mPacketVector[i] );
671 error = media_packet_destroy( mPacket );
672 DALI_LOG_ERROR( "Media packet destroy error: %d\n", error );
675 mPacketVector.Clear();
678 void TizenVideoPlayer::PushPacket( media_packet_h packet )
680 Dali::Mutex::ScopedLock lock( mPacketMutex );
681 mPacketVector.PushBack( packet );
684 void TizenVideoPlayer::SetDisplayArea( DisplayArea area )
686 GetPlayerState( &mPlayerState );
688 if( mNativeImageSourcePtr != NULL )
690 DALI_LOG_ERROR( "SetDisplayArea is only for window surface target.\n" );
694 if( mPlayerState == PLAYER_STATE_IDLE ||
695 mPlayerState == PLAYER_STATE_READY ||
696 mPlayerState == PLAYER_STATE_PLAYING ||
697 mPlayerState == PLAYER_STATE_PAUSED
701 area.x = ( area.x < 0 ) ? 0: area.x;
702 area.y = ( area.y < 0 ) ? 0: area.y;
703 int error = player_set_display_roi_area( mPlayer, area.x, area.y, area.width, area.height );
704 LogPlayerError( error );
708 void TizenVideoPlayer::Forward( int millisecond )
712 GetPlayerState( &mPlayerState );
714 if( mPlayerState == PLAYER_STATE_READY ||
715 mPlayerState == PLAYER_STATE_PLAYING ||
716 mPlayerState == PLAYER_STATE_PAUSED
719 int currentPosition = 0;
720 int nextPosition = 0;
722 error = player_get_play_position( mPlayer, ¤tPosition );
723 LogPlayerError( error );
725 nextPosition = currentPosition + millisecond;
727 error = player_set_play_position( mPlayer, nextPosition, false, PlayerSeekCompletedCb, NULL );
728 LogPlayerError( error );
732 void TizenVideoPlayer::Backward( int millisecond )
736 GetPlayerState( &mPlayerState );
738 if( mPlayerState == PLAYER_STATE_READY ||
739 mPlayerState == PLAYER_STATE_PLAYING ||
740 mPlayerState == PLAYER_STATE_PAUSED
743 int currentPosition = 0;
744 int nextPosition = 0;
746 error = player_get_play_position( mPlayer, ¤tPosition );
747 LogPlayerError( error );
749 nextPosition = currentPosition - millisecond;
750 nextPosition = ( nextPosition < 0 )? 0 : nextPosition;
752 error = player_set_play_position( mPlayer, nextPosition, false, PlayerSeekCompletedCb, NULL );
753 LogPlayerError( error );
757 bool TizenVideoPlayer::IsVideoTextureSupported()
759 bool featureFlag = true;
760 int error = SYSTEM_INFO_ERROR_NONE;
762 error = system_info_get_platform_bool( "tizen.org/feature/multimedia.raw_video", &featureFlag );
764 if( error != SYSTEM_INFO_ERROR_NONE )
766 DALI_LOG_ERROR( "Plugin can't check platform feature\n" );
773 void TizenVideoPlayer::DestroyPlayer()
776 if( mPlayerState != PLAYER_STATE_NONE )
778 GetPlayerState( &mPlayerState );
780 if( mPlayerState != PLAYER_STATE_IDLE )
783 error = player_unprepare( mPlayer );
784 LogPlayerError( error );
787 error = player_destroy( mPlayer );
788 LogPlayerError( error );
790 error = sound_manager_destroy_stream_information(mStreamInfo);
791 LogPlayerError( error );
793 mPlayerState = PLAYER_STATE_NONE;
799 void TizenVideoPlayer::SetCodecType( Dali::VideoPlayerPlugin::CodecType type )
802 if( mPlayerState != PLAYER_STATE_NONE )
804 GetPlayerState( &mPlayerState );
806 if( mPlayerState == PLAYER_STATE_IDLE )
808 error = player_set_codec_type( mPlayer, PLAYER_STREAM_TYPE_VIDEO, static_cast< player_codec_type_e >( type ) );
809 LogPlayerError( error );
811 if( error == PLAYER_ERROR_INVALID_OPERATION )
813 DALI_LOG_ERROR( "The target should not support the codec type\n" );
815 error = player_get_codec_type( mPlayer, PLAYER_STREAM_TYPE_VIDEO, &mCodecType );
816 LogPlayerError( error );
821 Dali::VideoPlayerPlugin::CodecType TizenVideoPlayer::GetCodecType() const
823 return static_cast< Dali::VideoPlayerPlugin::CodecType >( mCodecType );
826 void TizenVideoPlayer::SetDisplayMode( Dali::VideoPlayerPlugin::DisplayMode::Type mode )
829 error = player_set_display_mode( mPlayer, static_cast< player_display_mode_e >( mode ) );
830 LogPlayerError( error );
833 Dali::VideoPlayerPlugin::DisplayMode::Type TizenVideoPlayer::GetDisplayMode() const
835 player_display_mode_e mode;
836 player_get_display_mode( mPlayer, &mode );
837 return static_cast< Dali::VideoPlayerPlugin::DisplayMode::Type >( mode );
841 } // namespace Plugin