2 * Copyright (c) 2021 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/devel-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(Dali::Actor actor, Dali::VideoSyncMode syncMode)
32 return new Dali::Plugin::TizenVideoPlayer(actor, syncMode);
35 extern "C" DALI_EXPORT_API void DestroyVideoPlayerPlugin(Dali::VideoPlayerPlugin* plugin)
49 const int TIMER_INTERVAL(20);
51 static void MediaPacketVideoDecodedCb(media_packet_h packet, void* user_data)
53 TizenVideoPlayer* player = static_cast<TizenVideoPlayer*>(user_data);
57 DALI_LOG_ERROR("Decoded callback got Null pointer as user_data.\n");
61 player->PushPacket(packet);
64 static GMainContext* GetTizenGlibContext()
66 static GMainContext* context = nullptr;
70 const char* env = getenv("TIZEN_GLIB_CONTEXT");
73 context = (GMainContext*)strtoul(env, nullptr, 10);
80 static void EmitPlaybackFinishedSignal(void* user_data)
82 TizenVideoPlayer* player = static_cast<TizenVideoPlayer*>(user_data);
86 DALI_LOG_ERROR("Decoded callback got Null pointer as user_data.\n");
90 if(!player->mFinishedSignal.Empty())
92 DALI_LOG_ERROR("EmitPlaybackFinishedSignal.\n");
94 // This function is invoked on the main thread from MMFW.
95 // So the FinishedSignal has to be posted to UIThread when UIThread is enabled.
96 // If not, it causes an assertion in the timer.
97 // The timer has to run on the same thread as the adaptor's
98 GMainContext* context = GetTizenGlibContext();
101 GSource* source = g_idle_source_new();
102 g_source_set_callback(
104 [](gpointer userData) -> gboolean
106 auto* player = static_cast<TizenVideoPlayer*>(userData);
107 player->mFinishedSignal.Emit();
109 return G_SOURCE_REMOVE;
113 g_source_attach(source, context);
114 g_source_unref(source);
118 player->mFinishedSignal.Emit();
124 // ToDo: VD player_set_play_position() doesn't work when callback pointer is NULL.
125 // We should check whether this callback is needed in platform.
126 static void PlayerSeekCompletedCb(void* data)
130 int LogPlayerError(int error)
133 if(error != PLAYER_ERROR_NONE)
138 case PLAYER_ERROR_OUT_OF_MEMORY:
140 DALI_LOG_ERROR("Player error: Out of memory\n");
143 case PLAYER_ERROR_INVALID_PARAMETER:
145 DALI_LOG_ERROR("Player error: Invalid parameter\n");
148 case PLAYER_ERROR_NO_SUCH_FILE:
150 DALI_LOG_ERROR("Player error: No such file\n");
153 case PLAYER_ERROR_INVALID_OPERATION:
155 DALI_LOG_ERROR("Player error: Invalid operation\n");
158 case PLAYER_ERROR_FILE_NO_SPACE_ON_DEVICE:
160 DALI_LOG_ERROR("Player error: No space on device\n");
163 case PLAYER_ERROR_FEATURE_NOT_SUPPORTED_ON_DEVICE:
165 DALI_LOG_ERROR("Player error: Not supported feature on device\n");
168 case PLAYER_ERROR_SEEK_FAILED:
170 DALI_LOG_ERROR("Player error: Seek failed\n");
173 case PLAYER_ERROR_INVALID_STATE:
175 DALI_LOG_ERROR("Player error: Invalid state\n");
178 case PLAYER_ERROR_NOT_SUPPORTED_FILE:
180 DALI_LOG_ERROR("Player error: Not supported file\n");
183 case PLAYER_ERROR_INVALID_URI:
185 DALI_LOG_ERROR("Player error: Invalid uri\n");
188 case PLAYER_ERROR_SOUND_POLICY:
190 DALI_LOG_ERROR("Player error: Sound policy\n");
193 case PLAYER_ERROR_CONNECTION_FAILED:
195 DALI_LOG_ERROR("Player error: Connection failed\n");
198 case PLAYER_ERROR_VIDEO_CAPTURE_FAILED:
200 DALI_LOG_ERROR("Player error: Video capture failed\n");
203 case PLAYER_ERROR_DRM_EXPIRED:
205 DALI_LOG_ERROR("Player error: DRM expired\n");
208 case PLAYER_ERROR_DRM_NO_LICENSE:
210 DALI_LOG_ERROR("Player error: No license\n");
213 case PLAYER_ERROR_DRM_FUTURE_USE:
215 DALI_LOG_ERROR("Player error: License for future use\n");
218 case PLAYER_ERROR_DRM_NOT_PERMITTED:
220 DALI_LOG_ERROR("Player error: Format not permitted\n");
223 case PLAYER_ERROR_RESOURCE_LIMIT:
225 DALI_LOG_ERROR("Player error: Resource limit\n");
228 case PLAYER_ERROR_PERMISSION_DENIED:
230 DALI_LOG_ERROR("Player error: Permission denied\n");
233 case PLAYER_ERROR_SERVICE_DISCONNECTED:
235 DALI_LOG_ERROR("Player error: Service disconnected\n");
238 case PLAYER_ERROR_BUFFER_SPACE:
240 DALI_LOG_ERROR("Player error: Buffer space\n");
243 case PLAYER_ERROR_NOT_SUPPORTED_VIDEO_CODEC:
245 DALI_LOG_ERROR("Player error: The target should not support the codec type\n");
250 DALI_LOG_ERROR("Player error: Unknown error code ( %d ) \n", error);
258 const char* const VIDEO_PLAYER_SIZE_NAME("videoPlayerSize");
260 struct VideoPlayerSyncConstraint
263 VideoPlayerSyncConstraint(Ecore_Wl2_Subsurface* ecoreSubVideoWindow, int screenWidth, int screenHeight)
265 mEcoreSubVideoWindow = ecoreSubVideoWindow;
266 mHalfScreenWidth = static_cast<float>(screenWidth) / 2;
267 mHalfScreenHeight = static_cast<float>(screenHeight) / 2;
270 void operator()(Vector3& current, const PropertyInputContainer& inputs)
272 const Vector3& size = inputs[0]->GetVector3();
273 const Vector3& worldScale = inputs[1]->GetVector3();
274 const Vector3& worldPosition = inputs[2]->GetVector3();
276 Vector3 actorSize = size * worldScale;
277 Vector2 screenPosition(mHalfScreenWidth + worldPosition.x, mHalfScreenHeight + worldPosition.y);
280 area.x = screenPosition.x - actorSize.x / 2;
281 area.y = screenPosition.y - actorSize.y / 2;
282 area.width = actorSize.x;
283 area.height = actorSize.y;
285 if(mEcoreSubVideoWindow)
287 ecore_wl2_subsurface_video_surface_destination_set(mEcoreSubVideoWindow, area.x, area.y, area.width, area.height);
292 Ecore_Wl2_Subsurface* mEcoreSubVideoWindow;
293 float mHalfScreenWidth;
294 float mHalfScreenHeight;
298 * @brief Whether set play positoin accurately or not.
299 * If true, we set play position to the nearest frame position. but this might be considerably slow, accurately.
300 * If false, we set play position to the nearest key frame position. this might be faster but less accurate.
301 * see player_set_play_position()
303 constexpr bool ACCURATE_PLAY_POSITION_SET = true;
305 } // unnamed namespace
307 TizenVideoPlayer::TizenVideoPlayer(Dali::Actor actor, Dali::VideoSyncMode syncMode)
310 mPlayerState(PLAYER_STATE_NONE),
313 mNativeImageSourcePtr(NULL),
315 mBackgroundColor(Dali::Vector4(1.0f, 1.0f, 1.0f, 0.0f)),
316 mTargetType(NATIVE_IMAGE),
320 mStreamType(SOUND_STREAM_TYPE_MEDIA),
321 mCodecType(PLAYER_CODEC_TYPE_HW),
322 mEcoreWlWindow(nullptr),
323 mEcoreSubVideoWindow(nullptr),
325 mVideoSizePropertyIndex(Property::INVALID_INDEX),
327 mIsInitForSyncMode(false),
328 mIsMovedHandle(false)
332 TizenVideoPlayer::~TizenVideoPlayer()
335 if(mEcoreSubVideoWindow)
337 ecore_wl2_subsurface_del(mEcoreSubVideoWindow);
338 mEcoreSubVideoWindow = nullptr;
344 void TizenVideoPlayer::GetPlayerState(player_state_e* state) const
346 if(mPlayer != NULL && player_get_state(mPlayer, state) != PLAYER_ERROR_NONE)
348 DALI_LOG_ERROR("player_get_state error: Invalid parameter\n");
349 *state = PLAYER_STATE_NONE;
353 void TizenVideoPlayer::SetUrl(const std::string& url)
358 int error = PLAYER_ERROR_NONE;
362 GetPlayerState(&mPlayerState);
364 if(mPlayerState != PLAYER_STATE_NONE && mPlayerState != PLAYER_STATE_IDLE)
366 if(mNativeImageSourcePtr)
368 error = player_unset_media_packet_video_frame_decoded_cb(mPlayer);
369 ret = LogPlayerError(error);
372 DALI_LOG_ERROR("SetUrl, player_unset_media_packet_video_frame_decoded_cb() is failed\n");
377 error = player_unprepare(mPlayer);
378 ret = LogPlayerError(error);
381 DALI_LOG_ERROR("SetUrl, player_unprepare() is failed\n");
384 if(mNativeImageSourcePtr)
386 error = player_set_media_packet_video_frame_decoded_cb(mPlayer, MediaPacketVideoDecodedCb, this);
387 ret = LogPlayerError(error);
390 DALI_LOG_ERROR("SetUrl, player_set_media_packet_video_frame_decoded_cb() is failed\n");
396 Ecore_Wl2_Display* wl2_display = ecore_wl2_connected_display_get(NULL);
397 ecore_wl2_display_screen_size_get(wl2_display, &width, &height);
399 if(mSyncMode == Dali::VideoSyncMode::ENABLED)
401 if(mIsInitForSyncMode)
403 InitializeEnableSyncMode(mEcoreWlWindow);
407 if(!ecore_wl2_subsurface_video_surface_destination_set(mEcoreSubVideoWindow, 0, 0, width, height))
409 DALI_LOG_ERROR("SetUrl, ecore_wl2_subsurface_video_surface_destination_set() is failed\n");
415 error = player_set_ecore_wl_display(mPlayer, PLAYER_DISPLAY_TYPE_OVERLAY, mEcoreWlWindow, 0, 0, width, height);
416 ret = LogPlayerError(error);
419 DALI_LOG_ERROR("SetUrl, player_set_ecore_wl_display() is failed\n");
423 GetPlayerState(&mPlayerState);
424 ret = LogPlayerError(error);
427 DALI_LOG_ERROR("SetUrl, GetPlayerState() is failed\n");
431 if(mPlayerState == PLAYER_STATE_IDLE)
433 error = player_set_uri(mPlayer, mUrl.c_str());
434 ret = LogPlayerError(error);
437 DALI_LOG_ERROR("SetUrl, player_set_uri() is failed\n");
440 error = player_prepare(mPlayer);
441 ret = LogPlayerError(error);
444 DALI_LOG_ERROR("SetUrl, player_prepare() is failed\n");
450 std::string TizenVideoPlayer::GetUrl()
455 void TizenVideoPlayer::SetRenderingTarget(Any target)
459 mNativeImageSourcePtr = NULL;
461 if(target.GetType() == typeid(Dali::NativeImageSourcePtr))
463 if(mSyncMode == Dali::VideoSyncMode::ENABLED)
467 mTargetType = TizenVideoPlayer::NATIVE_IMAGE;
469 Dali::NativeImageSourcePtr nativeImageSourcePtr = AnyCast<Dali::NativeImageSourcePtr>(target);
471 InitializeTextureStreamMode(nativeImageSourcePtr);
473 else if(target.GetType() == typeid(Ecore_Wl2_Window*))
475 mTargetType = TizenVideoPlayer::WINDOW_SURFACE;
477 InitializeUnderlayMode(Dali::AnyCast<Ecore_Wl2_Window*>(target));
479 if(mSyncMode == Dali::VideoSyncMode::ENABLED)
486 DALI_LOG_ERROR("SetRenderingTarget, Video rendering target is unknown\n");
490 void TizenVideoPlayer::SetLooping(bool looping)
492 GetPlayerState(&mPlayerState);
494 if(mPlayerState != PLAYER_STATE_NONE)
496 int error = player_set_looping(mPlayer, looping);
497 int ret = LogPlayerError(error);
500 DALI_LOG_ERROR("SetLooping, player_set_looping() is failed\n");
505 bool TizenVideoPlayer::IsLooping()
507 GetPlayerState(&mPlayerState);
509 bool looping = false;
510 if(mPlayerState != PLAYER_STATE_NONE)
512 int error = player_is_looping(mPlayer, &looping);
513 int ret = LogPlayerError(error);
516 DALI_LOG_ERROR("IsLooping, player_is_looping() is failed\n");
523 void TizenVideoPlayer::Play()
525 GetPlayerState(&mPlayerState);
527 if(mPlayerState == PLAYER_STATE_READY || mPlayerState == PLAYER_STATE_PAUSED)
529 if(mNativeImageSourcePtr && mTimer)
534 int error = player_start(mPlayer);
535 int ret = LogPlayerError(error);
538 DALI_LOG_ERROR("Play, player_start() is failed\n");
543 void TizenVideoPlayer::Pause()
545 GetPlayerState(&mPlayerState);
547 if(mPlayerState == PLAYER_STATE_PLAYING)
549 int error = player_pause(mPlayer);
550 ret = LogPlayerError(error);
553 DALI_LOG_ERROR("Pause, player_pause() is failed\n");
556 if(mNativeImageSourcePtr && mTimer)
564 void TizenVideoPlayer::Stop()
566 GetPlayerState(&mPlayerState);
568 if(mPlayerState == PLAYER_STATE_PLAYING || mPlayerState == PLAYER_STATE_PAUSED)
570 int error = player_stop(mPlayer);
571 int ret = LogPlayerError(error);
574 DALI_LOG_ERROR("Stop, player_stop() is failed\n");
577 if(mNativeImageSourcePtr && mTimer)
585 void TizenVideoPlayer::SetMute(bool muted)
587 GetPlayerState(&mPlayerState);
589 if(mPlayerState == PLAYER_STATE_IDLE ||
590 mPlayerState == PLAYER_STATE_READY ||
591 mPlayerState == PLAYER_STATE_PLAYING ||
592 mPlayerState == PLAYER_STATE_PAUSED)
594 int error = player_set_mute(mPlayer, muted);
595 int ret = LogPlayerError(error);
598 DALI_LOG_ERROR("SetMute, player_set_mute() is failed\n");
603 bool TizenVideoPlayer::IsMuted()
605 GetPlayerState(&mPlayerState);
608 if(mPlayerState == PLAYER_STATE_IDLE ||
609 mPlayerState == PLAYER_STATE_READY ||
610 mPlayerState == PLAYER_STATE_PLAYING ||
611 mPlayerState == PLAYER_STATE_PAUSED)
613 int error = player_is_muted(mPlayer, &muted);
614 int ret = LogPlayerError(error);
617 DALI_LOG_ERROR("IsMuted, player_is_muted() is failed\n");
624 void TizenVideoPlayer::SetVolume(float left, float right)
626 GetPlayerState(&mPlayerState);
628 int error = player_set_volume(mPlayer, left, right);
629 int ret = LogPlayerError(error);
632 DALI_LOG_ERROR("SetVolume, player_set_volume() is failed\n");
636 void TizenVideoPlayer::GetVolume(float& left, float& right)
638 GetPlayerState(&mPlayerState);
640 int error = player_get_volume(mPlayer, &left, &right);
641 int ret = LogPlayerError(error);
644 DALI_LOG_ERROR("GetVolume, player_get_volume() is failed\n");
648 void TizenVideoPlayer::SetPlayPosition(int millisecond)
653 GetPlayerState(&mPlayerState);
655 if(mPlayerState == PLAYER_STATE_IDLE)
657 error = player_prepare(mPlayer);
658 ret = LogPlayerError(error);
661 DALI_LOG_ERROR("SetPlayPosition, player_prepare() is failed\n");
664 GetPlayerState(&mPlayerState); // Check the status again.
667 if(mPlayerState == PLAYER_STATE_READY ||
668 mPlayerState == PLAYER_STATE_PLAYING ||
669 mPlayerState == PLAYER_STATE_PAUSED)
671 error = player_set_play_position(mPlayer, millisecond, ACCURATE_PLAY_POSITION_SET, PlayerSeekCompletedCb, NULL);
672 ret = LogPlayerError(error);
675 DALI_LOG_ERROR("SetPlayPosition, player_set_play_position() is failed\n");
680 int TizenVideoPlayer::GetPlayPosition()
685 GetPlayerState(&mPlayerState);
687 if(mPlayerState == PLAYER_STATE_IDLE ||
688 mPlayerState == PLAYER_STATE_READY ||
689 mPlayerState == PLAYER_STATE_PLAYING ||
690 mPlayerState == PLAYER_STATE_PAUSED)
692 error = player_get_play_position(mPlayer, &millisecond);
693 int ret = LogPlayerError(error);
696 DALI_LOG_ERROR("GetPlayPosition, player_get_play_position() is failed\n");
703 void TizenVideoPlayer::SetDisplayRotation(Dali::VideoPlayerPlugin::DisplayRotation rotation)
705 if(mNativeImageSourcePtr)
707 DALI_LOG_ERROR("SetDisplayRotation is only for window rendering target.\n");
712 if(mPlayerState != PLAYER_STATE_NONE)
714 error = player_set_display_rotation(mPlayer, static_cast<player_display_rotation_e>(rotation));
715 int ret = LogPlayerError(error);
718 DALI_LOG_ERROR("SetDisplayRotation, player_set_display_rotation() is failed\n");
723 Dali::VideoPlayerPlugin::DisplayRotation TizenVideoPlayer::GetDisplayRotation()
725 if(mNativeImageSourcePtr)
727 DALI_LOG_ERROR("GetDisplayRotation is only for window rendering target.\n");
728 return Dali::VideoPlayerPlugin::ROTATION_NONE;
732 player_display_rotation_e rotation = PLAYER_DISPLAY_ROTATION_NONE;
733 if(mPlayerState != PLAYER_STATE_NONE)
735 error = player_get_display_rotation(mPlayer, &rotation);
736 int ret = LogPlayerError(error);
739 DALI_LOG_ERROR("GetDisplayRotation, player_get_display_rotation() is failed\n");
742 return static_cast<Dali::VideoPlayerPlugin::DisplayRotation>(rotation);
745 Dali::VideoPlayerPlugin::VideoPlayerSignalType& TizenVideoPlayer::FinishedSignal()
747 return mFinishedSignal;
750 void TizenVideoPlayer::InitializeTextureStreamMode(Dali::NativeImageSourcePtr nativeImageSourcePtr)
755 mNativeImageSourcePtr = nativeImageSourcePtr;
757 if(mPlayerState == PLAYER_STATE_NONE)
759 error = player_create(&mPlayer);
760 ret = LogPlayerError(error);
763 DALI_LOG_ERROR("InitializeTextureStreamMode, player_create() is failed\n");
767 GetPlayerState(&mPlayerState);
769 if(mPlayerState == PLAYER_STATE_IDLE)
771 error = player_set_completed_cb(mPlayer, EmitPlaybackFinishedSignal, this);
772 ret = LogPlayerError(error);
775 DALI_LOG_ERROR("InitializeTextureStreamMode, player_set_completed_cb() is failed\n");
778 error = player_set_media_packet_video_frame_decoded_cb(mPlayer, MediaPacketVideoDecodedCb, this);
779 ret = LogPlayerError(error);
782 DALI_LOG_ERROR("InitializeTextureStreamMode, player_set_media_packet_video_frame_decoded_cb() is failed\n");
785 error = sound_manager_create_stream_information(mStreamType, NULL, NULL, &mStreamInfo);
786 ret = LogPlayerError(error);
789 DALI_LOG_ERROR("InitializeTextureStreamMode, sound_manager_create_stream_information() is failed\n");
792 error = player_set_sound_stream_info(mPlayer, mStreamInfo);
793 ret = LogPlayerError(error);
796 DALI_LOG_ERROR("InitializeTextureStreamMode, player_set_sound_stream_info() is failed\n");
799 error = player_set_display_mode(mPlayer, PLAYER_DISPLAY_MODE_FULL_SCREEN);
800 ret = LogPlayerError(error);
803 DALI_LOG_ERROR("InitializeTextureStreamMode, player_set_display_mode() is failed\n");
806 error = player_set_display(mPlayer, PLAYER_DISPLAY_TYPE_NONE, NULL);
807 ret = LogPlayerError(error);
810 DALI_LOG_ERROR("InitializeTextureStreamMode, player_set_display() is failed\n");
813 error = player_set_video_codec_type(mPlayer, mCodecType);
814 ret = LogPlayerError(error);
817 DALI_LOG_ERROR("InitializeTextureStreamMode, player_set_video_codec_type() is failed\n");
819 error = player_set_display_visible(mPlayer, true);
820 ret = LogPlayerError(error);
823 DALI_LOG_ERROR("InitializeTextureStreamMode, player_set_display_visible() is failed\n");
826 mTimer = Dali::Timer::New(TIMER_INTERVAL);
827 mTimer.TickSignal().Connect(this, &TizenVideoPlayer::Update);
831 void TizenVideoPlayer::InitializeEnableSyncMode(Ecore_Wl2_Window* ecoreWlWindow)
836 if(mEcoreWlWindow != ecoreWlWindow)
838 mEcoreWlWindow = ecoreWlWindow;
839 // check previous video subsurface and destroy
840 if(mEcoreSubVideoWindow)
842 ecore_wl2_subsurface_del(mEcoreSubVideoWindow);
845 // Crate ecore_wl2 sursurface
846 mEcoreSubVideoWindow = ecore_wl2_subsurface_new(mEcoreWlWindow);
847 if(!mEcoreSubVideoWindow)
849 DALI_LOG_ERROR("InitializeEnableSyncMode, ecore_wl2_subsurface_new() is failed\n");
853 // ecore_wl2_subsurface_video_surface_prepare
854 if(!ecore_wl2_subsurface_video_surface_prepare(mEcoreSubVideoWindow))
856 ecore_wl2_subsurface_del(mEcoreSubVideoWindow);
857 DALI_LOG_ERROR("InitializeEnableSyncMode, : ecore_wl2_subsurface_video_surface_prepare() is failed\n");
861 DALI_LOG_RELEASE_INFO("InitializeEnableSyncMode, desync VideoPlayer\n");
862 ecore_wl2_subsurface_sync_set(mEcoreSubVideoWindow, EINA_FALSE);
865 if(mPlayerState == PLAYER_STATE_NONE)
867 error = player_create(&mPlayer);
868 ret = LogPlayerError(error);
871 DALI_LOG_ERROR("InitializeEnableSyncMode, player_create() is failed\n");
875 GetPlayerState(&mPlayerState);
876 if(mPlayerState == PLAYER_STATE_IDLE)
878 error = player_set_completed_cb(mPlayer, EmitPlaybackFinishedSignal, this);
879 ret = LogPlayerError(error);
882 DALI_LOG_ERROR("InitializeEnableSyncMode, player_set_completed_cb() is failed\n");
885 error = sound_manager_create_stream_information(mStreamType, NULL, NULL, &mStreamInfo);
886 ret = LogPlayerError(error);
889 DALI_LOG_ERROR("InitializeEnableSyncMode, sound_manager_create_stream_information() is failed\n");
892 error = player_set_sound_stream_info(mPlayer, mStreamInfo);
893 ret = LogPlayerError(error);
896 DALI_LOG_ERROR("InitializeEnableSyncMode, player_set_sound_stream_info() is failed\n");
899 error = player_set_video_codec_type(mPlayer, mCodecType);
900 ret = LogPlayerError(error);
903 DALI_LOG_ERROR("InitializeEnableSyncMode, player_set_video_codec_type() is failed\n");
907 Ecore_Wl2_Display* wl2_display = ecore_wl2_connected_display_get(NULL);
908 ecore_wl2_display_screen_size_get(wl2_display, &width, &height);
909 ecore_wl2_window_alpha_set(mEcoreWlWindow, false);
911 if(!ecore_wl2_subsurface_video_surface_destination_set(mEcoreSubVideoWindow, 0, 0, width, height))
913 DALI_LOG_ERROR("InitializeEnableSyncMode, ecore_wl2_subsurface_video_surface_destination_set() is failed\n");
915 error = player_set_display(mPlayer, PLAYER_DISPLAY_TYPE_OVERLAY, mEcoreWlWindow);
916 ret = LogPlayerError(error);
919 DALI_LOG_ERROR("InitializeEnableSyncMode, player_set_display() is failed\n");
922 mIsInitForSyncMode = true;
926 void TizenVideoPlayer::InitializeUnderlayMode(Ecore_Wl2_Window* ecoreWlWindow)
931 if(mSyncMode == Dali::VideoSyncMode::ENABLED)
933 DALI_LOG_RELEASE_INFO("InitializeUnderlayMode, \n");
934 InitializeEnableSyncMode(ecoreWlWindow);
938 mEcoreWlWindow = ecoreWlWindow;
940 if(mPlayerState == PLAYER_STATE_NONE)
942 error = player_create(&mPlayer);
943 ret = LogPlayerError(error);
946 DALI_LOG_ERROR("InitializeUnderlayMode, player_create() is failed\n");
950 GetPlayerState(&mPlayerState);
951 if(mPlayerState == PLAYER_STATE_IDLE)
953 error = player_set_completed_cb(mPlayer, EmitPlaybackFinishedSignal, this);
954 ret = LogPlayerError(error);
957 DALI_LOG_ERROR("InitializeUnderlayMode, player_set_completed_cb() is failed\n");
960 error = sound_manager_create_stream_information(mStreamType, NULL, NULL, &mStreamInfo);
961 ret = LogPlayerError(error);
964 DALI_LOG_ERROR("InitializeUnderlayMode, sound_manager_create_stream_information() is failed\n");
967 error = player_set_sound_stream_info(mPlayer, mStreamInfo);
968 ret = LogPlayerError(error);
971 DALI_LOG_ERROR("InitializeUnderlayMode, player_set_sound_stream_info() is failed\n");
974 error = player_set_video_codec_type(mPlayer, mCodecType);
975 ret = LogPlayerError(error);
978 DALI_LOG_ERROR("InitializeUnderlayMode, player_set_video_codec_type() is failed\n");
982 Ecore_Wl2_Display* wl2_display = ecore_wl2_connected_display_get(NULL);
983 ecore_wl2_display_screen_size_get(wl2_display, &width, &height);
984 ecore_wl2_window_alpha_set(mEcoreWlWindow, false);
986 error = player_set_display_mode(mPlayer, PLAYER_DISPLAY_MODE_DST_ROI);
987 ret = LogPlayerError(error);
990 DALI_LOG_ERROR("InitializeUnderlayMode, player_set_display_mode() is failed\n");
993 error = player_set_display_roi_area(mPlayer, 0, 0, 1, 1);
994 ret = LogPlayerError(error);
997 DALI_LOG_ERROR("InitializeUnderlayMode, player_set_display_roi_area() is failed\n");
1000 error = player_set_ecore_wl_display(mPlayer, PLAYER_DISPLAY_TYPE_OVERLAY, mEcoreWlWindow, 0, 0, width, height);
1001 ret = LogPlayerError(error);
1004 DALI_LOG_ERROR("InitializeUnderlayMode, player_set_ecore_wl_display() is failed\n");
1007 error = player_set_display_visible(mPlayer, true);
1008 ret = LogPlayerError(error);
1011 DALI_LOG_ERROR("InitializeUnderlayMode, player_set_display_visible() is failed\n");
1016 bool TizenVideoPlayer::Update()
1018 Dali::Mutex::ScopedLock lock(mPacketMutex);
1024 error = media_packet_destroy(mPacket);
1025 if(error != MEDIA_PACKET_ERROR_NONE)
1027 DALI_LOG_ERROR("Update, media_packet_destroy() is failed\n");
1032 if(!mPacketList.empty())
1034 mPacket = static_cast< media_packet_h >( mPacketList.front() );
1035 mPacketList.pop_front();
1043 error = media_packet_get_tbm_surface(mPacket, &mTbmSurface);
1044 if(error != MEDIA_PACKET_ERROR_NONE)
1046 media_packet_destroy(mPacket);
1048 DALI_LOG_ERROR(" error: %d\n", error);
1052 Any source(mTbmSurface);
1053 mNativeImageSourcePtr->SetSource(source);
1054 Dali::Stage::GetCurrent().KeepRendering(0.0f);
1059 void TizenVideoPlayer::DestroyPackets()
1064 error = media_packet_destroy(mPacket);
1065 DALI_LOG_ERROR("Media packet destroy error: %d\n", error);
1069 std::list<media_packet_h>::iterator iter = mPacketList.begin();
1070 for (; iter != mPacketList.end(); ++iter)
1073 error = media_packet_destroy( mPacket );
1074 DALI_LOG_ERROR( "Media packet destroy error: %d\n", error );
1077 mPacketList.clear();
1080 void TizenVideoPlayer::PushPacket(media_packet_h packet)
1082 Dali::Mutex::ScopedLock lock(mPacketMutex);
1083 mPacketList.push_back(packet);
1086 void TizenVideoPlayer::SetDisplayArea(DisplayArea area)
1089 GetPlayerState(&mPlayerState);
1091 if(mNativeImageSourcePtr)
1093 DALI_LOG_ERROR("SetDisplayArea is only for window surface target.\n");
1097 if(mPlayerState == PLAYER_STATE_IDLE ||
1098 mPlayerState == PLAYER_STATE_READY ||
1099 mPlayerState == PLAYER_STATE_PLAYING ||
1100 mPlayerState == PLAYER_STATE_PAUSED)
1102 area.x = (area.x < 0) ? 0 : area.x;
1103 area.y = (area.y < 0) ? 0 : area.y;
1104 if(mSyncMode == Dali::VideoSyncMode::ENABLED)
1106 if(!ecore_wl2_subsurface_video_surface_destination_set(mEcoreSubVideoWindow, area.x, area.y, area.width, area.height))
1108 DALI_LOG_ERROR("SetDisplayArea, ecore_wl2_subsurface_video_surface_destination_set() is failed\n");
1113 int error = player_set_display_roi_area(mPlayer, area.x, area.y, area.width, area.height);
1114 ret = LogPlayerError(error);
1117 DALI_LOG_ERROR("SetDisplayArea, player_set_display_roi_area() is failed\n");
1123 void TizenVideoPlayer::Forward(int millisecond)
1128 GetPlayerState(&mPlayerState);
1130 if(mPlayerState == PLAYER_STATE_READY ||
1131 mPlayerState == PLAYER_STATE_PLAYING ||
1132 mPlayerState == PLAYER_STATE_PAUSED)
1134 int currentPosition = 0;
1135 int nextPosition = 0;
1137 error = player_get_play_position(mPlayer, ¤tPosition);
1138 ret = LogPlayerError(error);
1141 DALI_LOG_ERROR("Forward, player_get_play_position() is failed\n");
1144 nextPosition = currentPosition + millisecond;
1146 error = player_set_play_position(mPlayer, nextPosition, ACCURATE_PLAY_POSITION_SET, PlayerSeekCompletedCb, NULL);
1147 ret = LogPlayerError(error);
1150 DALI_LOG_ERROR("Forward, player_set_play_position() is failed\n");
1155 void TizenVideoPlayer::Backward(int millisecond)
1160 GetPlayerState(&mPlayerState);
1162 if(mPlayerState == PLAYER_STATE_READY ||
1163 mPlayerState == PLAYER_STATE_PLAYING ||
1164 mPlayerState == PLAYER_STATE_PAUSED)
1166 int currentPosition = 0;
1167 int nextPosition = 0;
1169 error = player_get_play_position(mPlayer, ¤tPosition);
1170 ret = LogPlayerError(error);
1173 DALI_LOG_ERROR("Backward, player_get_play_position() is failed\n");
1176 nextPosition = currentPosition - millisecond;
1177 nextPosition = (nextPosition < 0) ? 0 : nextPosition;
1179 error = player_set_play_position(mPlayer, nextPosition, ACCURATE_PLAY_POSITION_SET, PlayerSeekCompletedCb, NULL);
1180 ret = LogPlayerError(error);
1183 DALI_LOG_ERROR("Backward, player_set_play_position() is failed\n");
1188 bool TizenVideoPlayer::IsVideoTextureSupported()
1190 bool featureFlag = true;
1191 int error = SYSTEM_INFO_ERROR_NONE;
1193 error = system_info_get_platform_bool("tizen.org/feature/multimedia.raw_video", &featureFlag);
1195 if(error != SYSTEM_INFO_ERROR_NONE)
1197 DALI_LOG_ERROR("Plugin can't check platform feature\n");
1204 void TizenVideoPlayer::DestroyPlayer()
1210 // If user take the handle, user must be responsible for its destruction.
1211 if(mPlayerState != PLAYER_STATE_NONE && !mIsMovedHandle)
1213 GetPlayerState(&mPlayerState);
1215 if(mPlayerState != PLAYER_STATE_IDLE)
1218 error = player_unprepare(mPlayer);
1219 ret = LogPlayerError(error);
1222 DALI_LOG_ERROR("DestroyPlayer, player_unprepare() is failed\n");
1226 error = player_destroy(mPlayer);
1227 ret = LogPlayerError(error);
1230 DALI_LOG_ERROR("DestroyPlayer, player_destroy() is failed\n");
1234 error = sound_manager_destroy_stream_information(mStreamInfo);
1235 ret = LogPlayerError(error);
1238 DALI_LOG_ERROR("DestroyPlayer, sound_manager_destroy_stream_information() is failed\n");
1241 mPlayerState = PLAYER_STATE_NONE;
1245 void TizenVideoPlayer::SetCodecType(Dali::VideoPlayerPlugin::CodecType type)
1251 case Dali::VideoPlayerPlugin::CodecType::HW:
1253 mCodecType = PLAYER_CODEC_TYPE_HW;
1256 case Dali::VideoPlayerPlugin::CodecType::SW:
1258 mCodecType = PLAYER_CODEC_TYPE_SW;
1263 mCodecType = PLAYER_CODEC_TYPE_HW;
1268 if(mPlayerState != PLAYER_STATE_NONE)
1270 GetPlayerState(&mPlayerState);
1272 if(mPlayerState == PLAYER_STATE_IDLE)
1274 error = player_set_video_codec_type(mPlayer, mCodecType);
1275 ret = LogPlayerError(error);
1278 DALI_LOG_ERROR("SetCodecType, player_set_video_codec_type() is failed\n");
1284 Dali::VideoPlayerPlugin::CodecType TizenVideoPlayer::GetCodecType() const
1286 Dali::VideoPlayerPlugin::CodecType type = Dali::VideoPlayerPlugin::CodecType::HW;
1288 if(mPlayerState != PLAYER_STATE_NONE)
1290 player_codec_type_e codecType = PLAYER_CODEC_TYPE_HW;
1291 int error = player_get_video_codec_type(mPlayer, &codecType);
1292 if(error != PLAYER_ERROR_NONE)
1294 ret = LogPlayerError(error);
1297 DALI_LOG_ERROR("GetCodecType, player_get_video_codec_type() is failed\n");
1304 case PLAYER_CODEC_TYPE_HW:
1306 type = Dali::VideoPlayerPlugin::CodecType::HW;
1309 case PLAYER_CODEC_TYPE_SW:
1311 type = Dali::VideoPlayerPlugin::CodecType::SW;
1316 type = Dali::VideoPlayerPlugin::CodecType::HW;
1324 void TizenVideoPlayer::SetDisplayMode(Dali::VideoPlayerPlugin::DisplayMode::Type mode)
1327 error = player_set_display_mode(mPlayer, static_cast<player_display_mode_e>(mode));
1328 int ret = LogPlayerError(error);
1331 DALI_LOG_ERROR("SetDisplayMode, player_set_display_mode() is failed\n");
1335 Dali::VideoPlayerPlugin::DisplayMode::Type TizenVideoPlayer::GetDisplayMode() const
1337 player_display_mode_e mode;
1338 player_get_display_mode(mPlayer, &mode);
1339 return static_cast<Dali::VideoPlayerPlugin::DisplayMode::Type>(mode);
1342 Any TizenVideoPlayer::GetMediaPlayer()
1344 mIsMovedHandle = true;
1345 return Any((void*)mPlayer);
1348 void TizenVideoPlayer::StartSynchronization()
1350 DALI_LOG_RELEASE_INFO("sync VideoPlayer\n");
1351 ecore_wl2_subsurface_sync_set(mEcoreSubVideoWindow, EINA_TRUE);
1354 void TizenVideoPlayer::FinishSynchronization()
1357 DALI_LOG_RELEASE_INFO("desync VideoPlayer\n");
1358 ecore_wl2_subsurface_sync_set(mEcoreSubVideoWindow, EINA_FALSE);
1361 void TizenVideoPlayer::CreateConstraint()
1363 if(mVideoSizePropertyIndex == Property::INVALID_INDEX)
1365 if(mVideoSizePropertyConstraint)
1367 mVideoSizePropertyConstraint.Remove();
1370 Actor syncActor = mSyncActor.GetHandle();
1373 mVideoSizePropertyIndex = syncActor.RegisterProperty(VIDEO_PLAYER_SIZE_NAME, Vector3::ZERO);
1376 Ecore_Wl2_Display* wl2_display = ecore_wl2_connected_display_get(NULL);
1377 ecore_wl2_display_screen_size_get(wl2_display, &width, &height);
1379 mVideoSizePropertyConstraint = Constraint::New<Vector3>(syncActor,
1380 mVideoSizePropertyIndex,
1381 VideoPlayerSyncConstraint(mEcoreSubVideoWindow, width, height));
1383 mVideoSizePropertyConstraint.AddSource(LocalSource(Actor::Property::SIZE));
1384 mVideoSizePropertyConstraint.AddSource(LocalSource(Actor::Property::WORLD_SCALE));
1385 mVideoSizePropertyConstraint.AddSource(LocalSource(Actor::Property::WORLD_POSITION));
1387 mVideoSizePropertyConstraint.Apply();
1392 void TizenVideoPlayer::DestroyConstraint()
1394 if(mVideoSizePropertyIndex != Property::INVALID_INDEX)
1396 mVideoSizePropertyConstraint.Remove();
1397 mVideoSizePropertyIndex = Property::INVALID_INDEX;
1401 void TizenVideoPlayer::RaiseAbove(Any videoSurface)
1403 Ecore_Wl2_Subsurface* surface = AnyCast<Ecore_Wl2_Subsurface*>(videoSurface);
1404 ecore_wl2_subsurface_place_surface_above(mEcoreSubVideoWindow, surface);
1407 void TizenVideoPlayer::LowerBelow(Any videoSurface)
1409 Ecore_Wl2_Subsurface* surface = AnyCast<Ecore_Wl2_Subsurface*>(videoSurface);
1410 ecore_wl2_subsurface_place_surface_below(mEcoreSubVideoWindow, surface);
1413 void TizenVideoPlayer::RaiseToTop()
1415 ecore_wl2_subsurface_place_surface_above(mEcoreSubVideoWindow, NULL);
1418 void TizenVideoPlayer::LowerToBottom()
1420 ecore_wl2_subsurface_place_surface_below(mEcoreSubVideoWindow, NULL);
1423 Any TizenVideoPlayer::GetVideoPlayerSurface()
1425 return mEcoreSubVideoWindow;
1428 } // namespace Plugin