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 );
67 static void EmitPlaybackFinishedSignal( void* user_data )
69 TizenVideoPlayer* player = static_cast< TizenVideoPlayer* >( user_data );
70 DALI_LOG_ERROR( "EmitPlaybackFinishedSignal.\n" );
74 DALI_LOG_ERROR( "Decoded callback got Null pointer as user_data.\n" );
78 DALI_LOG_ERROR( "EmitPlaybackFinishedSignal.\n" );
80 if( !player->mFinishedSignal.Empty() )
82 DALI_LOG_ERROR( "EmitPlaybackFinishedSignal.3\n" );
83 player->mFinishedSignal.Emit();
89 void LogPlayerError( int error )
91 if( error != PLAYER_ERROR_NONE )
95 case PLAYER_ERROR_OUT_OF_MEMORY:
97 DALI_LOG_ERROR( "Player error: Out of memory\n" );
100 case PLAYER_ERROR_INVALID_PARAMETER:
102 DALI_LOG_ERROR( "Player error: Invalid parameter\n" );
105 case PLAYER_ERROR_NO_SUCH_FILE:
107 DALI_LOG_ERROR( "Player error: No such file\n" );
110 case PLAYER_ERROR_INVALID_OPERATION:
112 DALI_LOG_ERROR( "Player error: Invalid operation\n" );
115 case PLAYER_ERROR_FILE_NO_SPACE_ON_DEVICE:
117 DALI_LOG_ERROR( "Player error: No space on device\n" );
120 case PLAYER_ERROR_FEATURE_NOT_SUPPORTED_ON_DEVICE:
122 DALI_LOG_ERROR( "Player error: Not supported feature on device\n" );
125 case PLAYER_ERROR_SEEK_FAILED:
127 DALI_LOG_ERROR( "Player error: Seek failed\n" );
130 case PLAYER_ERROR_INVALID_STATE:
132 DALI_LOG_ERROR( "Player error: Invalid state\n" );
135 case PLAYER_ERROR_NOT_SUPPORTED_FILE:
137 DALI_LOG_ERROR( "Player error: Not supported file\n" );
140 case PLAYER_ERROR_INVALID_URI:
142 DALI_LOG_ERROR( "Player error: Invalid uri\n" );
145 case PLAYER_ERROR_SOUND_POLICY:
147 DALI_LOG_ERROR( "Player error: Sound policy\n" );
150 case PLAYER_ERROR_CONNECTION_FAILED:
152 DALI_LOG_ERROR( "Player error: Connection failed\n" );
155 case PLAYER_ERROR_VIDEO_CAPTURE_FAILED:
157 DALI_LOG_ERROR( "Player error: Video capture failed\n" );
160 case PLAYER_ERROR_DRM_EXPIRED:
162 DALI_LOG_ERROR( "Player error: DRM expired\n" );
165 case PLAYER_ERROR_DRM_NO_LICENSE:
167 DALI_LOG_ERROR( "Player error: No license\n" );
170 case PLAYER_ERROR_DRM_FUTURE_USE:
172 DALI_LOG_ERROR( "Player error: License for future use\n" );
175 case PLAYER_ERROR_DRM_NOT_PERMITTED:
177 DALI_LOG_ERROR( "Player error: Format not permitted\n" );
180 case PLAYER_ERROR_RESOURCE_LIMIT:
182 DALI_LOG_ERROR( "Player error: Resource limit\n" );
185 case PLAYER_ERROR_PERMISSION_DENIED:
187 DALI_LOG_ERROR( "Player error: Permission denied\n" );
190 case PLAYER_ERROR_SERVICE_DISCONNECTED:
192 DALI_LOG_ERROR( "Player error: Service disconnected\n" );
195 case PLAYER_ERROR_BUFFER_SPACE:
197 DALI_LOG_ERROR( "Player error: Buffer space\n" );
204 } // unnamed namespace
206 TizenVideoPlayer::TizenVideoPlayer()
208 mPlayerState( PLAYER_STATE_NONE ),
211 mTargetType( NativeImage ),
212 mAlphaBitChanged( false )
216 TizenVideoPlayer::~TizenVideoPlayer()
220 void TizenVideoPlayer::GetPlayerState( player_state_e* state )
222 if( mPlayer != NULL && player_get_state( mPlayer, state ) != PLAYER_ERROR_NONE )
224 DALI_LOG_ERROR( "player_get_state error: Invalid parameter\n" );
225 *state = PLAYER_STATE_NONE;
229 void TizenVideoPlayer::SetUrl( const std::string& url )
235 GetPlayerState( &mPlayerState );
237 if( mPlayerState != PLAYER_STATE_NONE && mPlayerState != PLAYER_STATE_IDLE )
240 int error = player_unprepare( mPlayer );
241 LogPlayerError( error );
244 if( mPlayerState == PLAYER_STATE_IDLE )
246 int error = player_set_uri( mPlayer, mUrl.c_str() );
247 LogPlayerError( error );
249 error = player_prepare( mPlayer );
250 LogPlayerError( error );
255 std::string TizenVideoPlayer::GetUrl()
260 void TizenVideoPlayer::SetRenderingTarget( Any target )
263 if( mPlayerState != PLAYER_STATE_NONE )
265 GetPlayerState( &mPlayerState );
267 if( mPlayerState != PLAYER_STATE_IDLE )
270 error = player_unprepare( mPlayer );
271 LogPlayerError( error );
274 error = player_destroy( mPlayer );
275 LogPlayerError( error );
276 mPlayerState = PLAYER_STATE_NONE;
281 mNativeImageSourcePtr = NULL;
282 mEcoreWlWindow = NULL;
284 if( target.GetType() == typeid( Dali::NativeImageSourcePtr ) )
286 mTargetType = TizenVideoPlayer::NativeImage;
288 Dali::NativeImageSourcePtr nativeImageSourcePtr = AnyCast< Dali::NativeImageSourcePtr >( target );
290 InitializeTextureStreamMode( nativeImageSourcePtr );
292 else if( target.GetType() == typeid( Ecore_Wl_Window* ) )
294 mTargetType = TizenVideoPlayer::WindowSurface;
296 Ecore_Wl_Window* nativeWindow = Dali::AnyCast< Ecore_Wl_Window* >( target );
297 InitializeUnderlayMode( nativeWindow );
301 DALI_LOG_ERROR( "Video rendering target is unknown\n" );
305 void TizenVideoPlayer::SetLooping( bool looping )
307 GetPlayerState( &mPlayerState );
309 if( mPlayerState != PLAYER_STATE_NONE )
311 int error = player_set_looping( mPlayer, looping );
312 LogPlayerError( error );
316 bool TizenVideoPlayer::IsLooping()
318 GetPlayerState( &mPlayerState );
320 bool looping = false;
321 if( mPlayerState != PLAYER_STATE_NONE )
323 int error = player_is_looping( mPlayer, &looping );
324 LogPlayerError( error );
330 void TizenVideoPlayer::Play()
332 GetPlayerState( &mPlayerState );
334 if( mPlayerState == PLAYER_STATE_READY || mPlayerState == PLAYER_STATE_PAUSED )
336 if( mNativeImageSourcePtr != NULL && mTimer )
341 int error = player_start( mPlayer );
342 LogPlayerError( error );
346 void TizenVideoPlayer::Pause()
348 GetPlayerState( &mPlayerState );
350 if( mPlayerState == PLAYER_STATE_PLAYING )
352 int error = player_pause( mPlayer );
353 LogPlayerError( error );
355 if( mNativeImageSourcePtr != NULL && mTimer )
363 void TizenVideoPlayer::Stop()
365 GetPlayerState( &mPlayerState );
367 if( mPlayerState == PLAYER_STATE_PLAYING || mPlayerState == PLAYER_STATE_PAUSED )
369 int error = player_stop( mPlayer );
370 LogPlayerError( error );
373 if( mNativeImageSourcePtr != NULL && mTimer )
380 void TizenVideoPlayer::SetMute( bool muted )
382 GetPlayerState( &mPlayerState );
384 if( mPlayerState == PLAYER_STATE_IDLE ||
385 mPlayerState == PLAYER_STATE_READY ||
386 mPlayerState == PLAYER_STATE_PLAYING ||
387 mPlayerState == PLAYER_STATE_PAUSED
390 int error = player_set_mute( mPlayer, muted );
391 LogPlayerError( error );
395 bool TizenVideoPlayer::IsMuted()
397 GetPlayerState( &mPlayerState );
400 if( mPlayerState == PLAYER_STATE_IDLE ||
401 mPlayerState == PLAYER_STATE_READY ||
402 mPlayerState == PLAYER_STATE_PLAYING ||
403 mPlayerState == PLAYER_STATE_PAUSED
406 int error = player_is_muted( mPlayer, &muted );
407 LogPlayerError( error );
413 void TizenVideoPlayer::SetVolume( float left, float right )
415 GetPlayerState( &mPlayerState );
417 int error = player_set_volume( mPlayer, left, right );
418 LogPlayerError( error );
421 void TizenVideoPlayer::GetVolume( float& left, float& right )
423 GetPlayerState( &mPlayerState );
425 int error = player_get_volume( mPlayer, &left, &right );
426 LogPlayerError( error );
429 void TizenVideoPlayer::SetPlayPosition( int millisecond )
433 GetPlayerState( &mPlayerState );
435 if( mPlayerState == PLAYER_STATE_READY ||
436 mPlayerState == PLAYER_STATE_PLAYING ||
437 mPlayerState == PLAYER_STATE_PAUSED
440 error = player_set_play_position( mPlayer, millisecond, true, NULL, NULL );
441 LogPlayerError( error );
445 int TizenVideoPlayer::GetPlayPosition()
450 GetPlayerState( &mPlayerState );
452 if( mPlayerState == PLAYER_STATE_IDLE ||
453 mPlayerState == PLAYER_STATE_READY ||
454 mPlayerState == PLAYER_STATE_PLAYING ||
455 mPlayerState == PLAYER_STATE_PAUSED
458 error = player_get_play_position( mPlayer, &millisecond );
459 LogPlayerError( error );
465 void TizenVideoPlayer::SetDisplayRotation( Dali::VideoPlayerPlugin::DisplayRotation rotation )
467 if( mNativeImageSourcePtr != NULL )
469 DALI_LOG_ERROR( "SetDisplayRotation is only for window rendering target.\n" );
474 if( mPlayerState != PLAYER_STATE_NONE )
476 error = player_set_display_rotation( mPlayer, static_cast< player_display_rotation_e >( rotation ) );
477 LogPlayerError( error );
481 Dali::VideoPlayerPlugin::DisplayRotation TizenVideoPlayer::GetDisplayRotation()
483 if( mNativeImageSourcePtr != NULL )
485 DALI_LOG_ERROR( "GetDisplayRotation is only for window rendering target.\n" );
486 return Dali::VideoPlayerPlugin::ROTATION_NONE;
490 player_display_rotation_e rotation = PLAYER_DISPLAY_ROTATION_NONE;
491 if( mPlayerState != PLAYER_STATE_NONE )
493 error = player_get_display_rotation( mPlayer, &rotation );
494 LogPlayerError( error );
496 return static_cast< Dali::VideoPlayerPlugin::DisplayRotation >( rotation );
499 Dali::VideoPlayerPlugin::VideoPlayerSignalType& TizenVideoPlayer::FinishedSignal()
501 return mFinishedSignal;
504 void TizenVideoPlayer::InitializeTextureStreamMode( Dali::NativeImageSourcePtr nativeImageSourcePtr )
508 mNativeImageSourcePtr = nativeImageSourcePtr;
510 if( mAlphaBitChanged )
512 ecore_wl_window_alpha_set( mEcoreWlWindow, false );
513 mAlphaBitChanged = false;
516 if( mPlayerState == PLAYER_STATE_NONE )
518 error = player_create( &mPlayer );
519 LogPlayerError( error );
522 GetPlayerState( &mPlayerState );
524 if( mPlayerState == PLAYER_STATE_IDLE )
526 error = player_set_completed_cb( mPlayer, EmitPlaybackFinishedSignal, this );
527 LogPlayerError( error );
529 error = player_set_media_packet_video_frame_decoded_cb( mPlayer, MediaPacketVideoDecodedCb, this );
530 LogPlayerError( error );
532 error = player_set_sound_type( mPlayer, SOUND_TYPE_MEDIA );
533 LogPlayerError( error );
535 error = player_set_display_mode( mPlayer, PLAYER_DISPLAY_MODE_FULL_SCREEN );
536 LogPlayerError( error );
538 error = player_set_display( mPlayer, PLAYER_DISPLAY_TYPE_NONE, NULL );
539 LogPlayerError( error );
541 error = player_set_display_visible( mPlayer, true );
542 LogPlayerError( error );
544 mTimer = Dali::Timer::New( TIMER_INTERVAL );
545 mTimer.TickSignal().Connect( this, &TizenVideoPlayer::Update );
549 void TizenVideoPlayer::InitializeUnderlayMode( Ecore_Wl_Window* ecoreWlWindow )
552 if( mPlayerState == PLAYER_STATE_NONE )
554 error = player_create( &mPlayer );
555 LogPlayerError( error );
558 GetPlayerState( &mPlayerState );
559 mEcoreWlWindow = ecoreWlWindow;
561 if( mPlayerState == PLAYER_STATE_IDLE )
563 error = player_set_completed_cb( mPlayer, EmitPlaybackFinishedSignal, this );
564 LogPlayerError( error );
566 error = player_set_sound_type( mPlayer, SOUND_TYPE_MEDIA );
567 LogPlayerError( error );
569 error = player_set_display_mode( mPlayer, PLAYER_DISPLAY_MODE_DST_ROI );
570 LogPlayerError( error );
572 error = player_set_display_roi_area( mPlayer, 0, 0, 1, 1 );
575 mAlphaBitChanged = ( ecore_wl_window_alpha_get( mEcoreWlWindow ) )? false: true;
576 ecore_wl_screen_size_get( &width, &height );
578 if( mAlphaBitChanged )
580 ecore_wl_window_alpha_set( mEcoreWlWindow, true );
582 error = player_set_ecore_wl_display( mPlayer, PLAYER_DISPLAY_TYPE_OVERLAY, mEcoreWlWindow, 0, 0, width, height );
583 LogPlayerError( error );
585 error = player_set_display_visible( mPlayer, true );
586 LogPlayerError( error );
590 bool TizenVideoPlayer::Update()
592 Dali::Mutex::ScopedLock lock( mPacketMutex );
596 if( mPacket != NULL )
598 error = media_packet_destroy( mPacket );
599 if( error != MEDIA_PACKET_ERROR_NONE )
601 DALI_LOG_ERROR( "Media packet destroy error: %d\n", error );
606 if( !mPacketVector.Empty() )
608 mPacket = static_cast< media_packet_h >( mPacketVector[0] );
609 mPacketVector.Remove( mPacketVector.Begin() );
612 if( mPacket == NULL )
617 error = media_packet_get_tbm_surface( mPacket, &mTbmSurface );
618 if( error != MEDIA_PACKET_ERROR_NONE )
620 media_packet_destroy( mPacket );
622 DALI_LOG_ERROR( " error: %d\n", error );
626 Any source( mTbmSurface );
627 mNativeImageSourcePtr->SetSource( source );
628 Dali::Stage::GetCurrent().KeepRendering( 0.0f );
633 void TizenVideoPlayer::DestroyPackets()
636 if( mPacket != NULL )
638 error = media_packet_destroy( mPacket );
639 DALI_LOG_ERROR( "Media packet destroy error: %d\n", error );
643 for(unsigned int i = 0; i < mPacketVector.Size(); ++i)
645 mPacket = static_cast< media_packet_h >( mPacketVector[i] );
646 error = media_packet_destroy( mPacket );
647 DALI_LOG_ERROR( "Media packet destroy error: %d\n", error );
650 mPacketVector.Clear();
653 void TizenVideoPlayer::PushPacket( media_packet_h packet )
655 Dali::Mutex::ScopedLock lock( mPacketMutex );
656 mPacketVector.PushBack( packet );
659 void TizenVideoPlayer::SetDisplayArea( DisplayArea area )
661 GetPlayerState( &mPlayerState );
663 if( mNativeImageSourcePtr != NULL )
665 DALI_LOG_ERROR( "SetDisplayArea is only for window surface target.\n" );
669 if( mPlayerState == PLAYER_STATE_IDLE ||
670 mPlayerState == PLAYER_STATE_READY ||
671 mPlayerState == PLAYER_STATE_PLAYING ||
672 mPlayerState == PLAYER_STATE_PAUSED
676 int error = player_set_display_roi_area( mPlayer, area.x, area.y, area.width, area.height );
677 LogPlayerError( error );
681 void TizenVideoPlayer::Forward( int millisecond )
685 GetPlayerState( &mPlayerState );
687 if( mPlayerState == PLAYER_STATE_READY ||
688 mPlayerState == PLAYER_STATE_PLAYING ||
689 mPlayerState == PLAYER_STATE_PAUSED
692 int currentPosition = 0;
693 int nextPosition = 0;
695 error = player_get_play_position( mPlayer, ¤tPosition );
696 LogPlayerError( error );
698 nextPosition = currentPosition + millisecond;
700 error = player_set_play_position( mPlayer, nextPosition, true, NULL, NULL );
701 LogPlayerError( error );
705 void TizenVideoPlayer::Backward( int millisecond )
709 GetPlayerState( &mPlayerState );
711 if( mPlayerState == PLAYER_STATE_READY ||
712 mPlayerState == PLAYER_STATE_PLAYING ||
713 mPlayerState == PLAYER_STATE_PAUSED
716 int currentPosition = 0;
717 int nextPosition = 0;
719 error = player_get_play_position( mPlayer, ¤tPosition );
720 LogPlayerError( error );
722 nextPosition = currentPosition - millisecond;
723 nextPosition = ( nextPosition < 0 )? 0 : nextPosition;
725 error = player_set_play_position( mPlayer, nextPosition, true, NULL, NULL );
726 LogPlayerError( error );
730 } // namespace Plugin