}
+void TizenVideoPlayer::SetAutoRotationEnabled(bool enable)
+{
+ DALI_LOG_ERROR("SetAutoRotation is not supported.\n");
+}
+
+bool TizenVideoPlayer::IsAutoRotationEnabled() const
+{
+ DALI_LOG_ERROR("IsAutoRotationEnabled is not supported.\n");
+ return false;
+}
+
+void TizenVideoPlayer::SetLetterBoxEnabled(bool enable)
+{
+ DALI_LOG_ERROR("SetLetterBox is not supported.\n");
+}
+
+bool TizenVideoPlayer::IsLetterBoxEnabled() const
+{
+ DALI_LOG_ERROR("IsLetterBoxEnabled is not supported.\n");
+ return false;
+}
+
+
} // namespace Plugin
} // namespace Dali;
--- /dev/null
+/*
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include "tizen-video-constraint-helper.h"
+
+namespace Dali
+{
+namespace Plugin
+{
+
+VideoConstraintHelperPtr VideoConstraintHelper::New(Dali::NativeImageSourcePtr nativeImageSourcePtr)
+{
+ VideoConstraintHelperPtr ptr = new VideoConstraintHelper(nativeImageSourcePtr);
+ return ptr;
+}
+
+VideoConstraintHelper::VideoConstraintHelper(Dali::NativeImageSourcePtr nativeImageSourcePtr)
+: mNativeImageSourcePtr(nativeImageSourcePtr),
+ mSurface(NULL),
+ mOrientation(0.0f),
+ mWidth(0),
+ mHeight(0),
+ mIsSetInfo(false),
+ mIsAutoRotationEnabled(false),
+ mIsLetterBoxEnabled(false)
+{
+
+}
+
+VideoConstraintHelper::~VideoConstraintHelper()
+{
+}
+
+void VideoConstraintHelper::SetInfo(tbm_surface_h surface, int orientation, int width, int height)
+{
+ Dali::Mutex::ScopedLock lock(mConstraintMutex);
+ mIsSetInfo = true;
+ mSurface = surface;
+ // Orientation should be set to zero when auto rotation is disabled.
+ mOrientation = mIsAutoRotationEnabled ? orientation : 0;
+ if (mIsLetterBoxEnabled)
+ {
+ mWidth = width;
+ mHeight = height;
+ }
+}
+
+void VideoConstraintHelper::UpdateVideo()
+{
+ {
+ Dali::Mutex::ScopedLock lock(mConstraintMutex);
+ if(mIsSetInfo && mNativeImageSourcePtr)
+ {
+ mNativeImageSourcePtr->SetSource(mSurface);
+ mIsSetInfo = false;
+ }
+ }
+}
+
+Dali::Vector4 VideoConstraintHelper::GetOrientationMatrix()
+{
+ Dali::Mutex::ScopedLock lock(mConstraintMutex);
+ switch (mOrientation)
+ {
+ case 0:
+ return Dali::Vector4(1.0f, 0.0f, 0.0f, 1.0f);
+ case 90:
+ return Dali::Vector4(0.0f, -1.0f, 1.0f, 0.0f);
+ case 180:
+ return Dali::Vector4(-1.0f, 0.0f, 0.0f, -1.0f);
+ case 270:
+ return Dali::Vector4(0.0f, 1.0f, -1.0f, 0.0f);
+ default:
+ return Dali::Vector4(1.0f, 0.0f, 0.0f, 1.0f);
+ }
+}
+
+Dali::Vector2 VideoConstraintHelper::RetriveSize()
+{
+ Dali::Mutex::ScopedLock lock(mConstraintMutex);
+ if(mOrientation == 0 || mOrientation == 180)
+ {
+ return Dali::Vector2(mWidth, mHeight);
+ }
+ else
+ {
+ return Dali::Vector2(mHeight, mWidth);
+ }
+}
+
+void VideoConstraintHelper::SetAutoRotationEnabled(bool enable)
+{
+ Dali::Mutex::ScopedLock lock(mConstraintMutex);
+ mIsAutoRotationEnabled = enable;
+ if (!mIsAutoRotationEnabled)
+ {
+ mOrientation = 0;
+ }
+}
+
+bool VideoConstraintHelper::IsAutoRotationEnabled() const
+{
+ return mIsAutoRotationEnabled;
+}
+
+void VideoConstraintHelper::SetLetterBoxEnabled(bool enable)
+{
+ Dali::Mutex::ScopedLock lock(mConstraintMutex);
+ mIsLetterBoxEnabled = enable;
+ if (!mIsLetterBoxEnabled)
+ {
+ mWidth = 0;
+ mHeight = 0;
+ }
+}
+
+bool VideoConstraintHelper::IsLetterBoxEnabled() const
+{
+ return mIsLetterBoxEnabled;
+}
+
+}
+}
--- /dev/null
+#ifndef __DALI_TIZEN_VIDEO_CONSTRAINT_HELPER_H__
+#define __DALI_TIZEN_VIDEO_CONSTRAINT_HELPER_H__
+
+
+/*
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/object/ref-object.h>
+#include <dali/devel-api/threading/mutex.h>
+#include <tbm_surface.h>
+#include <dali/public-api/common/intrusive-ptr.h>
+#include <dali/public-api/adaptor-framework/native-image-source.h>
+#include <dali/public-api/math/vector2.h>
+#include <dali/public-api/math/vector4.h>
+
+
+namespace Dali
+{
+namespace Plugin
+{
+
+class VideoConstraintHelper;
+typedef Dali::IntrusivePtr<VideoConstraintHelper> VideoConstraintHelperPtr;
+
+class VideoConstraintHelper: public Dali::RefObject
+{
+public:
+
+ /**
+ * @brief Creates a new instance of VideoConstraintHelper
+ * @param[in] nativeImageSourcePtr Native image source pointer
+ * @return A pointer to a newly allocated video constraint helper
+ */
+ static VideoConstraintHelperPtr New(Dali::NativeImageSourcePtr nativeImageSourcePtr);
+
+ /**
+ * @brief Sets the video info
+ * @param[in] surface TBM surface
+ * @param[in] orientation Orientation of the video
+ * @param[in] width Width of the video
+ * @param[in] height Height of the video
+ */
+ void SetInfo(tbm_surface_h surface, int orientation, int width, int height);
+
+ /**
+ * @brief Enables or disables auto rotation
+ * @param[in] enable True to enable auto rotation, false otherwise. Default value is false.
+ */
+ void SetAutoRotationEnabled(bool enable);
+
+ /**
+ * @brief Checks if auto rotation is enabled
+ * @return True if auto rotation is enabled, false otherwise. Default value is false.
+ */
+ bool IsAutoRotationEnabled() const;
+
+ /**
+ * @brief Enables or disables letter box
+ * @param[in] enable True to enable letter box, false otherwise. Default value is false.
+ */
+ void SetLetterBoxEnabled(bool enable);
+
+ /**
+ * @brief Checks if letter box is enabled
+ * @return True if letter box is enabled, false otherwise. Default value is false.
+ */
+ bool IsLetterBoxEnabled() const;
+
+ /**
+ * @brief Gets the video orientation matrix
+ * @return OrientationMatrix of the video
+ */
+ Dali::Vector4 GetOrientationMatrix();
+
+ /**
+ * @brief Gets the video width and height
+ * @return Size of the video in Vector2 format (width, height)
+ */
+ Dali::Vector2 RetriveSize();
+
+ /**
+ * @brief Updates the video
+ */
+ void UpdateVideo();
+
+private:
+ VideoConstraintHelper(Dali::NativeImageSourcePtr nativeImageSourcePtr);
+
+ virtual ~VideoConstraintHelper();
+
+private:
+ Dali::NativeImageSourcePtr mNativeImageSourcePtr;
+ Dali::Mutex mConstraintMutex;
+ tbm_surface_h mSurface;
+ int mOrientation;
+ int mWidth;
+ int mHeight;
+ bool mIsSetInfo : 1;
+ bool mIsAutoRotationEnabled : 1;
+ bool mIsLetterBoxEnabled : 1;
+};
+
+} // namespace Plugin
+} // namespace Dali
+
+#endif // __DALI_TIZEN_VIDEO_CONSTRAINT_HELPER_H__
{
const char* TIZEN_GLIB_CONTEXT_ENV = "TIZEN_GLIB_CONTEXT";
-const int TIMER_INTERVAL(20);
-
static void MediaPacketVideoDecodedCb(media_packet_h packet, void* user_data)
{
TizenVideoPlayer* player = static_cast<TizenVideoPlayer*>(user_data);
};
#endif
+struct VideoPlayerRotationConstraint
+{
+ public:
+ VideoPlayerRotationConstraint(Dali::IntrusivePtr<VideoConstraintHelper> handler)
+ : mVideoHandler(handler)
+ {
+ }
+
+ void operator()(Dali::Vector4& current, const Dali::PropertyInputContainer& inputs)
+ {
+ if(inputs.Size() > 0) { // to avoid build warning
+ }
+ if (mVideoHandler)
+ {
+ current = mVideoHandler->GetOrientationMatrix();
+ mVideoHandler->UpdateVideo();
+ }
+ }
+
+private:
+ Dali::IntrusivePtr<VideoConstraintHelper> mVideoHandler;
+};
+
+struct VideoPlayerRatioConstraint
+{
+ public:
+ VideoPlayerRatioConstraint(Dali::IntrusivePtr<VideoConstraintHelper> handler)
+ : mVideoHandler(handler)
+ {
+ }
+
+ void operator()(Dali::Vector2& current, const Dali::PropertyInputContainer& inputs)
+ {
+ if(inputs.Size() > 0) { // to avoid build warning
+ }
+ if (mVideoHandler)
+ {
+ current = mVideoHandler->RetriveSize();
+ }
+ }
+
+private:
+ Dali::IntrusivePtr<VideoConstraintHelper> mVideoHandler;
+};
+
/**
* @brief Whether set play positoin accurately or not.
* If true, we set play position to the nearest frame position. but this might be considerably slow, accurately.
mTbmSurface(NULL),
mPacket(NULL),
mNativeImageSourcePtr(NULL),
- mTimer(),
mBackgroundColor(Dali::Vector4(1.0f, 1.0f, 1.0f, 0.0f)),
mTargetType(NATIVE_IMAGE),
mPacketMutex(),
mEcoreSubVideoWindow(nullptr),
mSyncActor(actor),
mVideoSizePropertyIndex(Property::INVALID_INDEX),
+ mVideoRotationPropertyIndex(Property::INVALID_INDEX),
+ mVideoRatioPropertyIndex(Property::INVALID_INDEX),
mSyncMode(syncMode),
mIsMovedHandle(false),
mIsSceneConnected(false),
DestroyVideoShellConstraint();
}
+ DestroyVideoConstraint();
if(mEcoreSubVideoWindow)
{
ecore_wl2_subsurface_del(mEcoreSubVideoWindow);
{
DestroyVideoShellConstraint();
}
+
mTargetType = TizenVideoPlayer::NATIVE_IMAGE;
Dali::NativeImageSourcePtr nativeImageSourcePtr = AnyCast<Dali::NativeImageSourcePtr>(target);
InitializeTextureStreamMode(nativeImageSourcePtr);
+
+ CreateVideoConstraint(nativeImageSourcePtr);
}
else if(target.GetType() == typeid(Ecore_Wl2_Window*))
{
DALI_LOG_RELEASE_INFO("target is underlay mode\n");
InitializeUnderlayMode(Dali::AnyCast<Ecore_Wl2_Window*>(target));
+
+ DestroyVideoConstraint();
}
else
{
if(mPlayerState == PLAYER_STATE_READY || mPlayerState == PLAYER_STATE_PAUSED)
{
- if(mNativeImageSourcePtr && mTimer)
- {
- mTimer.Start();
- }
-
int error = player_start(mPlayer);
int ret = LogPlayerError(error);
if(ret)
DALI_LOG_ERROR("Pause, player_pause() is failed\n");
}
- if(mNativeImageSourcePtr && mTimer)
- {
- mTimer.Stop();
- DestroyPackets();
- }
+ DestroyPackets();
}
}
DALI_LOG_ERROR("Stop, player_stop() is failed\n");
}
- if(mNativeImageSourcePtr && mTimer)
- {
- mTimer.Stop();
- DestroyPackets();
- }
+ DestroyPackets();
}
}
DALI_LOG_ERROR("InitializeTextureStreamMode, player_set_display_visible() is failed\n");
}
- mTimer = Dali::Timer::New(TIMER_INTERVAL);
- mTimer.TickSignal().Connect(this, &TizenVideoPlayer::Update);
}
}
}
}
-bool TizenVideoPlayer::Update()
+void TizenVideoPlayer::Update()
{
- Dali::Mutex::ScopedLock lock(mPacketMutex);
-
int error;
if(mPacket != NULL)
if(mPacket == NULL)
{
- return true;
+ return;
}
error = media_packet_get_tbm_surface(mPacket, &mTbmSurface);
media_packet_destroy(mPacket);
mPacket = NULL;
DALI_LOG_ERROR(" error: %d\n", error);
- return true;
+ return;
+ }
+
+ media_packet_rotate_method_e org_orient;
+ media_packet_get_rotate_method(mPacket, &org_orient);
+ int orientation = 0;
+
+ switch (org_orient) {
+ case MEDIA_PACKET_ROTATE_IDENTITY: //0
+ orientation = 0;
+ break;
+ case MEDIA_PACKET_ROTATE_90: //1
+ orientation = 270;
+ break;
+ case MEDIA_PACKET_ROTATE_180: //2
+ orientation = 180;
+ break;
+ case MEDIA_PACKET_ROTATE_270: //3
+ orientation = 90;
+ break;
+ default:
+ DALI_LOG_ERROR("wrong angle type : %d", org_orient);
+ break;
+ }
+
+ media_format_h format;
+ int width, height;
+ if (media_packet_get_format(mPacket, &format) != MEDIA_PACKET_ERROR_NONE)
+ {
+ DALI_LOG_ERROR("failed to media_packet_get_format\n");
+ return;
+ }
+
+ if (media_format_get_video_info(format, NULL, &width, &height, NULL, NULL) != MEDIA_FORMAT_ERROR_NONE)
+ {
+ DALI_LOG_ERROR("failed to media_format_get_video_info\n");
+ media_format_unref(format);
+ return;
}
- Any source(mTbmSurface);
- mNativeImageSourcePtr->SetSource(source);
- Dali::Stage::GetCurrent().KeepRendering(0.0f);
+ media_format_unref(format);
- return true;
+ mVideoConstraintHelper->SetInfo(mTbmSurface, orientation, width, height);
}
void TizenVideoPlayer::DestroyPackets()
{
Dali::Mutex::ScopedLock lock(mPacketMutex);
mPacketList.push_back(packet);
+
+ Update();
}
void TizenVideoPlayer::SetDisplayArea(DisplayArea area)
mIsSceneConnected = false;
}
+void TizenVideoPlayer::CreateVideoConstraint(Dali::NativeImageSourcePtr nativeImageSourcePtr)
+{
+ Actor syncActor = mSyncActor.GetHandle();
+ if(syncActor)
+ {
+ mVideoRotationPropertyIndex = syncActor.RegisterProperty("uRotationMatrix", Property::Value(Vector4(1.0f, 0.0f, 0.0f, 1.0f)));
+ mVideoRatioPropertyIndex = syncActor.RegisterProperty("uSizeRatio", Property::Value(Vector2(0.0f, 0.0f)));
+
+ mVideoConstraintHelper = VideoConstraintHelper::New(nativeImageSourcePtr);
+ mVideoRotationConstraint = Constraint::New<Vector4>(syncActor, mVideoRotationPropertyIndex, VideoPlayerRotationConstraint(mVideoConstraintHelper));
+ mVideoRotationConstraint.Apply();
+
+ mVideoLetterBoxConstraint = Constraint::New<Vector2>(syncActor, mVideoRatioPropertyIndex, VideoPlayerRatioConstraint(mVideoConstraintHelper));
+ mVideoLetterBoxConstraint.Apply();
+ }
+}
+
+void TizenVideoPlayer::DestroyVideoConstraint()
+{
+ if(mVideoRotationPropertyIndex != Property::INVALID_INDEX)
+ {
+ mVideoRotationConstraint.Remove();
+ mVideoRotationPropertyIndex = Property::INVALID_INDEX;
+ }
+
+ if(mVideoRatioPropertyIndex != Property::INVALID_INDEX)
+ {
+ mVideoLetterBoxConstraint.Remove();
+ mVideoRatioPropertyIndex = Property::INVALID_INDEX;
+ }
+}
+
+void TizenVideoPlayer::SetAutoRotationEnabled(bool enable)
+{
+ if(!mNativeImageSourcePtr)
+ {
+ DALI_LOG_ERROR("SetAutoRotationEnabled is only for native image rendering target.\n");
+ return;
+ }
+
+ if(mVideoConstraintHelper)
+ {
+ mVideoConstraintHelper->SetAutoRotationEnabled(enable);
+ }
+}
+
+bool TizenVideoPlayer::IsAutoRotationEnabled() const
+{
+ if(!mNativeImageSourcePtr)
+ {
+ DALI_LOG_ERROR("IsAutoRotationEnabled is only for native image rendering target.\n");
+ return false;
+ }
+
+ if(mVideoConstraintHelper)
+ {
+ return mVideoConstraintHelper->IsAutoRotationEnabled();
+ }
+ return false;
+}
+
+void TizenVideoPlayer::SetLetterBoxEnabled(bool enable)
+{
+ if(!mNativeImageSourcePtr)
+ {
+ DALI_LOG_ERROR("SetLetterBoxEnabled is only for native image rendering target.\n");
+ return;
+ }
+
+ if(mVideoConstraintHelper)
+ {
+ mVideoConstraintHelper->SetLetterBoxEnabled(enable);
+ }
+}
+
+bool TizenVideoPlayer::IsLetterBoxEnabled() const
+{
+ if(!mNativeImageSourcePtr)
+ {
+ DALI_LOG_ERROR("IsLetterBoxEnabled is only for native image rendering target.\n");
+ return false;
+ }
+
+ if(mVideoConstraintHelper)
+ {
+ return mVideoConstraintHelper->IsLetterBoxEnabled();
+ }
+ return false;
+}
+
} // namespace Plugin
} // namespace Dali
*
*/
+// INTERNAL INCLUDES
+#include "tizen-video-constraint-helper.h"
+
// EXTERNAL INCLUDES
#include <dali/devel-api/adaptor-framework/video-player-plugin.h>
#include <dali/devel-api/adaptor-framework/video-sync-mode.h>
*/
virtual Dali::VideoPlayerPlugin::VideoPlayerSignalType& FinishedSignal();
+ /**
+ * @copydoc Dali::VideoPlayerPlugin::SetAutoRotationEnabled()
+ */
+ virtual void SetAutoRotationEnabled(bool enable);
+
+ /**
+ * @copydoc Dali::VideoPlayerPlugin::IsAutoRotationEnabled() const
+ */
+ virtual bool IsAutoRotationEnabled() const;
+
+ /**
+ * @copydoc Dali::VideoPlayerPlugin::SetLetterBoxEnabled()
+ */
+ virtual void SetLetterBoxEnabled(bool enable);
+
+ /**
+ * @copydoc Dali::VideoPlayerPlugin::IsLetterBoxEnabled() const
+ */
+ virtual bool IsLetterBoxEnabled() const;
+
/**
* @brief Push media packet with video frame image
*/
void SceneDisconnection();
private:
+
/**
- * @brief Updates video frame image by timer if rendering targe is native image source
+ * @brief Update video frame image to native image source
*/
- bool Update();
+ void Update();
/**
* @brief Gets current player state
*/
void DestroyVideoShellConstraint();
+ /**
+ * @brief Create Constraint for oriention and ratio of video
+ */
+ void CreateVideoConstraint(Dali::NativeImageSourcePtr nativeImageSourcePtr);
+
+ /**
+ * @brief Destroy Constraint for oriention and ratio of video
+ */
+ void DestroyVideoConstraint();
+
private:
std::string mUrl; ///< The video file path
player_h mPlayer; ///< Tizen player handle
tbm_surface_h mTbmSurface; ///< tbm surface handle
media_packet_h mPacket; ///< Media packet handle with tbm surface of current video frame image
Dali::NativeImageSourcePtr mNativeImageSourcePtr; ///< native image source for video rendering
- Dali::Timer mTimer; ///< Timer for texture streaming rendering
Dali::Vector4 mBackgroundColor; ///< Current background color, which texturestream mode needs.
RenderingTargetType mTargetType; ///< Current rendering target type
Ecore_Wl2_Subsurface* mEcoreSubVideoWindow; ///< ecore native subsurface for synchronization with video player
Dali::WeakHandle<Dali::Actor> mSyncActor;
Constraint mVideoSizePropertyConstraint;
+ Constraint mVideoRotationConstraint;
+ Constraint mVideoLetterBoxConstraint;
Property::Index mVideoSizePropertyIndex;
+ Property::Index mVideoRotationPropertyIndex;
+ Property::Index mVideoRatioPropertyIndex;
Dali::VideoSyncMode mSyncMode;
bool mIsMovedHandle; ///< the flag for moved the handle
#endif
Constraint mVideoShellSizePropertyConstraint;
Property::Index mVideoShellSizePropertyIndex;
+ Dali::IntrusivePtr<VideoConstraintHelper> mVideoConstraintHelper;
public:
Dali::VideoPlayerPlugin::VideoPlayerSignalType mFinishedSignal;
video_player_ecore_wl2_plugin_src_files = \
- $(extension_src_dir)/video-player/ecore-wl2/tizen-video-player-ecore-wl2.cpp
+ $(extension_src_dir)/video-player/ecore-wl2/tizen-video-player-ecore-wl2.cpp \
+ $(extension_src_dir)/video-player/ecore-wl2/tizen-video-constraint-helper.cpp
video_player_ecore_wl_plugin_src_files = \
$(extension_src_dir)/video-player/ecore-wl/tizen-video-player-ecore-wl.cpp