From 052d9ca5192c22128b2710f8be6a4493b89daa40 Mon Sep 17 00:00:00 2001 From: Andriy Martynets Date: Wed, 27 Sep 2017 11:42:40 +0300 Subject: [PATCH] Test application and API doxygen updates for video360 functions Change-Id: I54b683e842f095fddfd708ae024c9f58fde0d4d3 Signed-off-by: Andriy Martynets --- include/player_internal.h | 127 ++++--- packaging/capi-media-player.spec | 2 + test/CMakeLists.txt | 6 +- test/event-handler/CMakeLists.txt | 26 ++ test/event-handler/include/mm_navevent_handler.h | 248 +++++++++++++ .../include/mm_navevent_handler_priv.h | 61 ++++ .../include/mm_navevent_handler_util.h | 75 ++++ test/event-handler/src/mm_navevent_handler.c | 112 ++++++ .../src/mm_navevent_handler_internal.c | 382 +++++++++++++++++++++ test/player_test.c | 271 ++++++++++++++- 10 files changed, 1253 insertions(+), 57 deletions(-) create mode 100644 test/event-handler/CMakeLists.txt create mode 100644 test/event-handler/include/mm_navevent_handler.h create mode 100644 test/event-handler/include/mm_navevent_handler_priv.h create mode 100644 test/event-handler/include/mm_navevent_handler_util.h create mode 100644 test/event-handler/src/mm_navevent_handler.c create mode 100644 test/event-handler/src/mm_navevent_handler_internal.c diff --git a/include/player_internal.h b/include/player_internal.h index 02b4ed2..3f60d65 100644 --- a/include/player_internal.h +++ b/include/player_internal.h @@ -533,19 +533,21 @@ int player_get_media_packet_video_frame_pool_size(player_h player, int *size); int player_enable_media_packet_video_frame_decoded_cb(player_h player, bool enable); /** - * @brief Enables 360 video mode + * @brief Enables/disables 360 video mode. * @since_tizen 4.0 * @details If it is @c true, the content will be displayed with 360 video mode. * If it is @c false, the content will be displayed with full panorama mode. The default value is @c true. * @param[in] player The handle to the media player - * @param[in] enable The 360 video display status : (@c true = display with 360 video mode, @c false = display with full panorama mode) + * @param[in] enable The 360 video display status: @c true = display with 360 video mode, + @c false = display with full panorama mode * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter - * @pre The player state must be one of #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING, or #PLAYER_STATE_PAUSED. + * @retval #PLAYER_ERROR_INVALID_OPERATION Not a spherical media + * @retval #PLAYER_ERROR_INVALID_STATE Player isn't prepared + * @pre The player state must be one of #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING or #PLAYER_STATE_PAUSED. * @see player_360_is_enabled() - * @see player_360_set_direction_of_view() */ int player_360_set_enable(player_h player, bool enable); @@ -553,14 +555,16 @@ int player_360_set_enable(player_h player, bool enable); * @brief Gets the 360 video display status. * @since_tizen 4.0 * @param[in] player The handle to the media player - * @param[out] enabled The 360 video display status : (@c true = display with 360 video mode, @c false = display with full panorama mode) + * @param[out] enabled Pointer to store current 360 video display status: + * (@c true = display with 360 video mode, + @c false = display with full panorama mode) * @return @c 0 on success, * otherwise a negative error value * @retval #PLAYER_ERROR_NONE Successful * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation - * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state - * @pre The player state must be one of #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING, or #PLAYER_STATE_PAUSED. + * @retval #PLAYER_ERROR_INVALID_OPERATION Not a spherical media + * @retval #PLAYER_ERROR_INVALID_STATE Player isn't prepared + * @pre The player state must be one of #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING or #PLAYER_STATE_PAUSED. * @see player_360_set_enable() */ int player_360_is_enabled(player_h player, bool *enabled); @@ -568,36 +572,45 @@ int player_360_is_enabled(player_h player, bool *enabled); /** * @brief Sets the 360 video direction of view. * @since_tizen 4.0 - * @details This function is to set the vertical and lateral axis value. + * @details This function is to set horizontal (yaw) and vertical (pitch) angles + * of current direction of view in radians. Default direction of view + * is taken from meta-data stored in the media. If meta-data omits + * these values zeros are assumed that is equal to the centre of the + * panorama image. * @param[in] player The handle to the media player - * @param[in] yaw The vertical axis value - * @param[in] pitch The lateral axis value + * @param[in] yaw The angle value around vertical axis. Valid values are in + * range +/- PI. + * @param[in] pitch The angle value around lateral axis. Valid values are in + * range +/- PI/2. * @return @c 0 on success, * otherwise a negative error value - * @retval #PLAYER_ERROR_NONE Successful - * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation - * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state - * @pre The player state must be one of: #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING, or #PLAYER_STATE_PAUSED. - * @see player_is_audio_only() + * @retval #PLAYER_ERROR_NONE Successful + * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #PLAYER_ERROR_INVALID_OPERATION Not a spherical media + * @retval #PLAYER_ERROR_INVALID_STATE Player isn't prepared + * @pre The player state must be one of #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING or #PLAYER_STATE_PAUSED. + * @see player_360_get_direction_of_view() */ int player_360_set_direction_of_view(player_h player, float yaw, float pitch); /** * @brief Gets the 360 video direction of view. * @since_tizen 4.0 - * @details This function is to get the vertical and lateral axis value. + * @details This function is to get horizontal (yaw) and vertical (pitch) angles + * of current direction of view in radians. * @param[in] player The handle to the media player - * @param[out] yaw The vertical axis value - * @param[out] pitch The lateral axis value + * @param[out] yaw Pointer to store current value of direction of view + * angle around vertical axis + * @param[out] pitch Pointer to store current value of direction of view + * angle around lateral axis * @return @c 0 on success, * otherwise a negative error value - * @retval #PLAYER_ERROR_NONE Successful - * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation - * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state - * @pre The player state must be one of #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING, or #PLAYER_STATE_PAUSED. - * @see player_is_audio_only() + * @retval #PLAYER_ERROR_NONE Successful + * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #PLAYER_ERROR_INVALID_OPERATION Not a spherical media + * @retval #PLAYER_ERROR_INVALID_STATE Player isn't prepared + * @pre The player state must be one of #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING or #PLAYER_STATE_PAUSED. + * @see player_360_set_direction_of_view() */ int player_360_get_direction_of_view(player_h player, float *yaw, float *pitch); @@ -605,16 +618,17 @@ int player_360_get_direction_of_view(player_h player, float *yaw, float *pitch); * @brief Sets the zoom level of 360 video. * @since_tizen 4.0 * @details The zoom means scaling of the flat image cutted from the panorama. - * The valid range is from [TBD]. Default value is 1.0. + * The valid range is from 1.0 to 10.0. Where 1.0 is actual image and + * values above are zoom-in factor. Default value is 1.0 - no zoom. * @param[in] player The handle to the media player * @param[in] level The zoom level * @return @c 0 on success, * otherwise a negative error value - * @retval #PLAYER_ERROR_NONE Successful - * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation - * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state - * @pre The player state must be one of #PLAYER_STATE_PLAYING, or #PLAYER_STATE_PAUSED. + * @retval #PLAYER_ERROR_NONE Successful + * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #PLAYER_ERROR_INVALID_OPERATION Not a spherical media + * @retval #PLAYER_ERROR_INVALID_STATE Player isn't prepared + * @pre The player state must be one of #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING or #PLAYER_STATE_PAUSED. * @see player_360_get_zoom() */ int player_360_set_zoom(player_h player, float level); @@ -623,16 +637,17 @@ int player_360_set_zoom(player_h player, float level); * @brief Gets the current zoom level of 360 video. * @since_tizen 4.0 * @details The zoom means scaling of the flat image cutted from the panorama. - * The valid range is from [TBD]. Default value is 1.0. + * The valid range is from 1.0 to 10.0. Where 1.0 is actual image and + * values above are zoom-in factor. Default value is 1.0 - no zoom. * @param[in] player The handle to the media player - * @param[out] level The zoom level + * @param[out] level Pointer to store current value of zoom level * @return @c 0 on success, * otherwise a negative error value - * @retval #PLAYER_ERROR_NONE Successful - * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation - * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state - * @pre The player state must be one of #PLAYER_STATE_PLAYING, or #PLAYER_STATE_PAUSED. + * @retval #PLAYER_ERROR_NONE Successful + * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #PLAYER_ERROR_INVALID_OPERATION Not a spherical media + * @retval #PLAYER_ERROR_INVALID_STATE Player isn't prepared + * @pre The player state must be one of #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING or #PLAYER_STATE_PAUSED. * @see player_360_set_zoom() */ int player_360_get_zoom(player_h player, float *level); @@ -641,16 +656,20 @@ int player_360_get_zoom(player_h player, float *level); * @brief Sets the field of view information of 360 video. * @since_tizen 4.0 * @details This function is to set the field of view to decide the output frame size. + * Note: values above the default ones extends field of view to significantly + * distorted areas and thus don't make real sense. * @param[in] player The handle to the media player - * @param[in] horizontal_degrees The horizontal degrees to display (The default value is [TBD]) - * @param[in] vertical_degrees The vertical degrees to display (The default value is [TBD]) + * @param[in] horizontal_degrees The horizontal field of view to display in degrees. + * Valid range is 1-360 degrees. Default value is 120 degrees. + * @param[in] vertical_degrees The vertical field of view to display in degrees. + * Valid range is 1-180 degrees. Default value is 67 degrees. * @return @c 0 on success, * otherwise a negative error value - * @retval #PLAYER_ERROR_NONE Successful - * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation - * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state - * @pre The player state must be one of #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING, or #PLAYER_STATE_PAUSED. + * @retval #PLAYER_ERROR_NONE Successful + * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #PLAYER_ERROR_INVALID_OPERATION Not a spherical media + * @retval #PLAYER_ERROR_INVALID_STATE Player isn't prepared + * @pre The player state must be one of #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING or #PLAYER_STATE_PAUSED. * @see player_360_get_field_of_view() */ int player_360_set_field_of_view(player_h player, int horizontal_degrees, int vertical_degrees); @@ -660,15 +679,17 @@ int player_360_set_field_of_view(player_h player, int horizontal_degrees, int ve * @since_tizen 4.0 * @details This function is to get the field of view information. * @param[in] player The handle to the media player - * @param[out] horizontal_degrees The horizontal degrees to display (The default value is [TBD]) - * @param[out] vertical_degrees The vertical degrees to display (The default value is [TBD]) + * @param[out] horizontal_degrees Pointer to store current value of horizontal + * field of view to display in degrees. + * @param[out] vertical_degrees Pointer to store current value of vertical + * field of view to display in degrees. * @return @c 0 on success, * otherwise a negative error value - * @retval #PLAYER_ERROR_NONE Successful - * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation - * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state - * @pre The player state must be one of #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING, or #PLAYER_STATE_PAUSED. + * @retval #PLAYER_ERROR_NONE Successful + * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #PLAYER_ERROR_INVALID_OPERATION Not a spherical media + * @retval #PLAYER_ERROR_INVALID_STATE Player isn't prepared + * @pre The player state must be one of #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING or #PLAYER_STATE_PAUSED. * @see player_360_set_field_of_view() */ int player_360_get_field_of_view(player_h player, int *horizontal_degrees, int *vertical_degrees); diff --git a/packaging/capi-media-player.spec b/packaging/capi-media-player.spec index 9423d7d..ca70726 100644 --- a/packaging/capi-media-player.spec +++ b/packaging/capi-media-player.spec @@ -25,6 +25,7 @@ BuildRequires: pkgconfig(libtbm) BuildRequires: pkgconfig(eom) BuildRequires: pkgconfig(storage) BuildRequires: pkgconfig(capi-system-info) +BuildRequires: pkgconfig(libinput) %if "%{TIZEN_PRODUCT_TV}" != "1" BuildRequires: pkgconfig(mm-evas-renderer) %endif @@ -120,3 +121,4 @@ cp test/player_audio_test %{buildroot}/usr/bin %{_bindir}/player_media_packet_test %{_bindir}/player_es_push_test %{_bindir}/player_audio_test +%{_libdir}/libmm-navevent-handler.so* diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index dba7898..674431a 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -7,12 +7,13 @@ ELSE (TIZEN_WEARABLE) INCLUDE_DIRECTORIES(../include/common) ENDIF (TIZEN_WEARABLE) +INCLUDE_DIRECTORIES(event-handler/include) link_directories(${CMAKE_SOURCE_DIR}/../) SET(WIN_PKG "${WIN_PKG} ecore-wayland") INCLUDE(FindPkgConfig) -pkg_check_modules(${fw_test} REQUIRED appcore-efl elementary ecore evas capi-media-sound-manager ${WIN_PKG}) +pkg_check_modules(${fw_test} REQUIRED libudev libinput capi-system-info appcore-efl elementary ecore evas capi-media-sound-manager ${WIN_PKG}) FOREACH(flag ${${fw_test}_CFLAGS}) SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") ENDFOREACH(flag) @@ -24,7 +25,8 @@ FOREACH(src ${sources}) GET_FILENAME_COMPONENT(src_name ${src} NAME_WE) MESSAGE("${src_name}") ADD_EXECUTABLE(${src_name} ${src}) - TARGET_LINK_LIBRARIES(${src_name} capi-media-player ${${fw_test}_LDFLAGS}) + TARGET_LINK_LIBRARIES(${src_name} capi-media-player mm-navevent-handler ${${fw_test}_LDFLAGS}) INSTALL(TARGETS ${src_name} DESTINATION bin) ENDFOREACH() +ADD_SUBDIRECTORY(event-handler) diff --git a/test/event-handler/CMakeLists.txt b/test/event-handler/CMakeLists.txt new file mode 100644 index 0000000..e6e4c78 --- /dev/null +++ b/test/event-handler/CMakeLists.txt @@ -0,0 +1,26 @@ + +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +SET(fw_handler "mm-navevent-handler") + +PROJECT(${fw_handler}) + +SET(dependents "dlog libudev libinput capi-system-info") +SET(pc_dependents "libudev libinput capi-system-info") + +INCLUDE(FindPkgConfig) +pkg_check_modules(${fw_handler} REQUIRED ${dependents}) +FOREACH(flag ${${fw_handler}_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +AUX_SOURCE_DIRECTORY (./src HANDLER_SRC) +ADD_LIBRARY(${fw_handler} SHARED ${HANDLER_SRC}) + +SET_TARGET_PROPERTIES(${fw_handler} + PROPERTIES + VERSION ${FULLVER} + SOVERSION ${MAJORVER} + CLEAN_DIRECT_OUTPUT 1 +) + +INSTALL(TARGETS ${fw_handler} DESTINATION ${LIB_INSTALL_DIR}) diff --git a/test/event-handler/include/mm_navevent_handler.h b/test/event-handler/include/mm_navevent_handler.h new file mode 100644 index 0000000..99d9510 --- /dev/null +++ b/test/event-handler/include/mm_navevent_handler.h @@ -0,0 +1,248 @@ +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved + * + * @author: Volodymyr Brynza + * Andriy Martynets + * + * 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. + */ + +#ifndef __MM_NAVEVENT_HANDLER__ +#define __MM_NAVEVENT_HANDLER__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * @file mm_navevent_handler.h + * @brief Navigation event handler handle type. + * + * @since_tizen 3.0 + */ +typedef void *mm_navevent_handler_h; + +/** + * @brief Convenience type for screen/window sizes representation. + * + * @since_tizen 3.0 + */ +typedef struct { + int width; + int height; +} mm_navevent_handler_size_s; + +/** + * @brief Enumeration of window orientation relatively to screen + * counter-clockwise for event handling. Valid values of this enum + * complies with corresponding enumeration of walandsink's rotate + * property. + * + * @since_tizen 3.0 + */ +typedef enum { + MM_NAVEVENT_HANDLER_ORIENTATION_INVALID = -1, + MM_NAVEVENT_HANDLER_ORIENTATION_DEGREE_0 = 0, + MM_NAVEVENT_HANDLER_ORIENTATION_DEGREE_90 = 1, + MM_NAVEVENT_HANDLER_ORIENTATION_DEGREE_180 = 2, + MM_NAVEVENT_HANDLER_ORIENTATION_DEGREE_270 = 3, + MM_NAVEVENT_HANDLER_ORIENTATION_MAX, +} mm_navevent_handler_orientation_e; + +/** + * @brief Constants for default values of Field-Of-View angles in degrees. + * @details Human eye horizontal stereoscopic FOV is 120 degrees. + * With image aspect ratio of 16:9 vertical FOV is roughly 68 degrees. + * @since_tizen 3.0 + */ +#define MM_NAVEVENT_HANDLER_DEFAULT_HORIZONTAL_FOV_DEGREE 120 +#define MM_NAVEVENT_HANDLER_DEFAULT_VERTICAL_FOV_DEGREE 68 + +/** + * @brief Enumeration of device for event handling. + * @remarks Note that available device types can differ depending + * on platform. #MM_NAVEVENT_HANDLER_DEVICE_TYPE_INVALID and + * #MM_NAVEVENT_HANDLER_DEVICE_TYPE_MAX are invalid device types. + * @since_tizen 3.0 + */ +typedef enum { + MM_NAVEVENT_HANDLER_DEVICE_TYPE_INVALID = -1, + MM_NAVEVENT_HANDLER_DEVICE_TYPE_TOUCH, + MM_NAVEVENT_HANDLER_DEVICE_TYPE_MAX, +} mm_navevent_handler_device_type_e; + +/** + * @brief Enumeration for navigation event handler error. + * + * @since_tizen 3.0 + */ +typedef enum { + MM_NAVEVENT_HANDLER_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful */ + MM_NAVEVENT_HANDLER_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */ + MM_NAVEVENT_HANDLER_ERROR_INVALID_OPERATION = TIZEN_ERROR_INVALID_OPERATION, /**< Invalid operation */ + MM_NAVEVENT_HANDLER_ERROR_FILE_NO_SPACE_ON_DEVICE = TIZEN_ERROR_FILE_NO_SPACE_ON_DEVICE, /**< No space left on the device */ + MM_NAVEVENT_HANDLER_ERROR_NOT_SUPPORTED = TIZEN_ERROR_NOT_SUPPORTED, /**< The feature is not supported */ + MM_NAVEVENT_HANDLER_ERROR_INVALID_STATE, /**< Invalid state */ +} mm_navenvent_handler_error_e; + +/** + * @brief Called after processing each input event. + * @since_tizen 3.0 + * @param [in] ev_t Type of the libinput event + * @param [in] x Value of pointer horizontal position in screen + * coordinates + * @param [in] y Value of pointer vertical position in screen coordinates + * @param [in] data The user data passed from the code where + * mm_navevent_handler_set_cb() was invoked + * This data will be accessible from mm_navevent_handler_cb + * @param [in] e Euler angles (XYZ configuration) + * @remarks @a Pointer coordinates are passed as screen coordinates regardless + * given application window size and orientation + * @pre @a handle must be created by calling mm_navevent_handler_create() + * @see mm_navevent_handler_set_cb() + * @see mm_navevent_handler_unset_cb() + */ +typedef void (*mm_navevent_handler_cb) (enum libinput_event_type ev_t, int x, int y, void* data, float e[3]); + +/** + * @brief Creates an instance of navigation event handler and + * passes the handle to the caller. + * @since_tizen 3.0 + * @remarks @a handle must be released by calling mm_navevent_handler_destroy() + * @param [out] handle Event handler handle + * @param [in] device Device type + * @return @c 0 on success, + * otherwise a negative error value + * @retval #MM_NAVEVENT_HANDLER_ERROR_NONE Successful + * @retval #MM_NAVEVENT_HANDLER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #MM_NAVEVENT_HANDLER_ERROR_INVALID_OPERATION Invalid operation + * @retval #MM_NAVEVENT_HANDLER_ERROR_INVALID_STATE Invalid state + * @see mm_navevent_handler_destroy() + * @see mm_navevent_handler_device_type_e + */ +int mm_navevent_handler_create(mm_navevent_handler_h *handle, mm_navevent_handler_device_type_e device); + +/** + * @brief Destroys event handler. + * @since_tizen 3.0 + * @param [in] handle Event handler handle + * @return @c 0 on success, + * otherwise a negative error value + * @retval #MM_NAVEVENT_HANDLER_ERROR_NONE Successful + * @retval #MM_NAVEVENT_HANDLER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #MM_NAVEVENT_HANDLER_ERROR_INVALID_OPERATION Invalid operation + * @pre @a handle must be created by calling mm_navevent_handler_create() + * @see mm_navevent_handler_create() + */ +int mm_navevent_handler_destroy(mm_navevent_handler_h handle); + +/** + * @brief Sets navigation event callback. + * @since_tizen 3.0 + * @param [in] handle Event handler handle + * @param [in] cb Navigation event callback + * @param [in] data Data that will be passed to callback + * @return @c 0 on success, + * otherwise a negative error value + * @retval #MM_NAVEVENT_HANDLER_ERROR_NONE Successful + * @retval #MM_NAVEVENT_HANDLER_ERROR_INVALID_PARAMETER Invalid parameter + * @pre @a handle must be created by calling mm_navevent_handler_create() + * @see mm_navevent_handler_create() + */ +int mm_navevent_handler_set_cb(mm_navevent_handler_h handle, mm_navevent_handler_cb cb, void *data); + +/** + * @brief Unsets navigation event callback. + * @since_tizen 3.0 + * @param [in] handle Event handler handle + * @return @c 0 on success, + * otherwise a negative error value + * @retval #MM_NAVEVENT_HANDLER_ERROR_NONE Successful + * @retval #MM_NAVEVENT_HANDLER_ERROR_INVALID_PARAMETER Invalid parameter + * @pre @a handle must be created by calling mm_navevent_handler_create() + * @see mm_navevent_handler_create() + */ +int mm_navevent_handler_unset_cb(mm_navevent_handler_h handle); + +/** + * @brief Sets application window orientation and size. + * @details Window size defines the step of FOV degrees. Window orientation + * defines x and y coordinates exchange and coordinates + * increment/decrement direction. + * @since_tizen 3.0 + * @param [in] handle Event handler handle + * @param [in] wo Window orientation + * @param [in] ws Window size + * @return @c 0 on success, + * otherwise a negative error value + * @retval #MM_NAVEVENT_HANDLER_ERROR_NONE Successful + * @retval #MM_NAVEVENT_HANDLER_ERROR_INVALID_PARAMETER Invalid parameter + * @pre @a handle must be created by calling mm_navevent_handler_create() + * @see mm_navevent_handler_create() + */ +int mm_navevent_handler_set_window_parameters(mm_navevent_handler_h handle, mm_navevent_handler_orientation_e wo, mm_navevent_handler_size_s ws); + +/** + * @brief Sets Field-Of-View size in degrees. + * @details Field-Of-View size defines scale factor from pixels to angles. + * @since_tizen 3.0 + * @param [in] handle Event handler handle + * @param [in] fovs Field-Of-View size in degrees + * @return @c 0 on success, + * otherwise a negative error value + * @retval #MM_NAVEVENT_HANDLER_ERROR_NONE Successful + * @retval #MM_NAVEVENT_HANDLER_ERROR_INVALID_PARAMETER Invalid parameter + * @pre @a handle must be created by calling mm_navevent_handler_create() + * @see mm_navevent_handler_create() + */ +int mm_navevent_handler_set_fov_size(mm_navevent_handler_h handle, mm_navevent_handler_size_s fovs); + +/** + * @brief Returns screen size in pixels. + * @details Provides application with screen size information. + * @since_tizen 3.0 + * @param [in] handle Event handler handle + * @param [in] size Pointer to where the size to store + * @return @c 0 on success, + * otherwise a negative error value + * @retval #MM_NAVEVENT_HANDLER_ERROR_NONE Successful + * @retval #MM_NAVEVENT_HANDLER_ERROR_INVALID_PARAMETER Invalid parameter + * @pre @a handle must be created by calling mm_navevent_handler_create() + * @see mm_navevent_handler_create() + */ +int mm_navevent_handler_get_screen_size(mm_navevent_handler_h handle, mm_navevent_handler_size_s *size); + +/** + * @brief Sets direction of view angles (yaw, pitch and roll) in radians. + * @details Subsequent navigation events modify these values. + * @since_tizen 3.0 + * @param [in] handle Event handler handle + * @param [in] angles array of 3 angles in radians (yaw, pitch and roll) + * @return @c 0 on success, + * otherwise a negative error value + * @retval #MM_NAVEVENT_HANDLER_ERROR_NONE Successful + * @retval #MM_NAVEVENT_HANDLER_ERROR_INVALID_PARAMETER Invalid parameter + * @pre @a handle must be created by calling mm_navevent_handler_create() + * @see mm_navevent_handler_create() + */ +int mm_navevent_handler_set_angles(mm_navevent_handler_h handle, float angles[3]); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __MM_NAVEVENT_HANDLER__ */ diff --git a/test/event-handler/include/mm_navevent_handler_priv.h b/test/event-handler/include/mm_navevent_handler_priv.h new file mode 100644 index 0000000..8f637f9 --- /dev/null +++ b/test/event-handler/include/mm_navevent_handler_priv.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved + * + * @author: Volodymyr Brynza + * Andriy Martynets + * + * 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. + */ + +#ifndef __MM_NAVEVENT_HANDLER_PRIV__ +#define __MM_NAVEVENT_HANDLER_PRIV__ + +#include +#include +#include + +#include "mm_navevent_handler.h" + +typedef struct _mm_navevent_handler_s mm_navevent_handler_s; + +struct _mm_navevent_handler_s { + struct libinput *lih; + mm_navevent_handler_device_type_e dev; + mm_navevent_handler_orientation_e window_orientation; + mm_navevent_handler_size_s window_size; /*<< Application window size in pixels */ + mm_navevent_handler_size_s fov; /*<< Field-Of-View size in degrees */ + mm_navevent_handler_size_s screen_size; /*<< Screen size in pixels */ + + unsigned int current[2]; + unsigned int last[2]; + + float angles[3]; /*<< yaw, pitch and roll angles */ + + mm_navevent_handler_cb cb; + void *user_data; + + pthread_t event_thread; + pthread_mutex_t event_lock; + int event_loop_run; +}; + +mm_navevent_handler_s *_mm_navevent_handler_create(mm_navevent_handler_device_type_e device); +int _mm_navevent_handler_destroy(mm_navevent_handler_s *handler); +int _mm_navevent_handler_set_cb(mm_navevent_handler_s *handler, mm_navevent_handler_cb cb, void *data); +int _mm_navevent_handler_unset_cb(mm_navevent_handler_s *handler); +int _mm_navevent_handler_set_window_parameters(mm_navevent_handler_s *handler, mm_navevent_handler_orientation_e wo, mm_navevent_handler_size_s ws); +int _mm_navevent_handler_set_fov_size(mm_navevent_handler_s *handler, mm_navevent_handler_size_s fovs); +int _mm_navevent_handler_get_screen_size(mm_navevent_handler_s *handler, mm_navevent_handler_size_s *size); +int _mm_navevent_handler_set_angles(mm_navevent_handler_s *handler, float angles[3]); + +#endif /* __MM_NAVEVENT_HANDLER_PRIV__ */ diff --git a/test/event-handler/include/mm_navevent_handler_util.h b/test/event-handler/include/mm_navevent_handler_util.h new file mode 100644 index 0000000..5a30179 --- /dev/null +++ b/test/event-handler/include/mm_navevent_handler_util.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved + * + * @author: Volodymyr Brynza + * Andriy Martynets + * + * 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. + */ + +#ifndef __MM_NAVEVENT_HANDLER_UTIL__ +#define __MM_NAVEVENT_HANDLER_UTIL__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef LOG_TAG +#undef LOG_TAG +#endif + +#define LOG_TAG "MM_NAVEVENT_HANDLER" + +#define FONT_COLOR_RESET "\033[0m" +#define FONT_COLOR_RED "\033[31m" +#define FONT_COLOR_GREEN "\033[32m" + +#define MM_EH_DEBUG(fmt, arg...) \ + do { \ + LOGD(FONT_COLOR_RESET""fmt""FONT_COLOR_RESET, ##arg); \ + } while (0) + +#define MM_EH_INFO(fmt, arg...) \ + do { \ + LOGI(FONT_COLOR_GREEN""fmt""FONT_COLOR_RESET, ##arg); \ + } while (0) + +#define MM_EH_ERROR(fmt, arg...) \ + do { \ + LOGE(FONT_COLOR_RED""fmt""FONT_COLOR_RESET, ##arg); \ + } while (0) + +#define MM_EH_RETM_IF(expr, fmt, arg...) \ + do { \ + if (expr) { \ + LOGE(FONT_COLOR_RED""fmt""FONT_COLOR_RESET, ##arg); \ + return; \ + } \ + } while (0) + +#define MM_EH_RETVM_IF(expr, val, fmt, arg...) \ + do { \ + if (expr) { \ + LOGE(FONT_COLOR_RED""fmt""FONT_COLOR_RESET, ##arg); \ + return(val); \ + } \ + } while (0) + + +#ifdef __cplusplus +} +#endif + +#endif /* __MM_NAVEVENT_HANDLER_UTIL__ */ diff --git a/test/event-handler/src/mm_navevent_handler.c b/test/event-handler/src/mm_navevent_handler.c new file mode 100644 index 0000000..c6e4fff --- /dev/null +++ b/test/event-handler/src/mm_navevent_handler.c @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved + * + * @author: Volodymyr Brynza + * Andriy Martynets + * + * 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. + */ + +#include "mm_navevent_handler_util.h" +#include "mm_navevent_handler_priv.h" + +int mm_navevent_handler_create(mm_navevent_handler_h *handle, mm_navevent_handler_device_type_e device) +{ + MM_EH_RETVM_IF(device <= MM_NAVEVENT_HANDLER_DEVICE_TYPE_INVALID || + device >= MM_NAVEVENT_HANDLER_DEVICE_TYPE_MAX, MM_NAVEVENT_HANDLER_ERROR_INVALID_PARAMETER, + "Wrong device type"); + + *handle = _mm_navevent_handler_create(device); + if (NULL == *handle) + return MM_NAVEVENT_HANDLER_ERROR_INVALID_OPERATION; + + return MM_NAVEVENT_HANDLER_ERROR_NONE; +} + +int mm_navevent_handler_destroy(mm_navevent_handler_h handle) +{ + MM_EH_RETVM_IF(NULL == handle, MM_NAVEVENT_HANDLER_ERROR_INVALID_PARAMETER, + "Handle is NULL"); + + mm_navevent_handler_s *handler = (mm_navevent_handler_s *)handle; + + return _mm_navevent_handler_destroy(handler); +} + +int mm_navevent_handler_set_cb(mm_navevent_handler_h handle, mm_navevent_handler_cb cb, void *data) +{ + MM_EH_RETVM_IF(NULL == handle, MM_NAVEVENT_HANDLER_ERROR_INVALID_PARAMETER, + "Handle is NULL"); + MM_EH_RETVM_IF(NULL == cb, MM_NAVEVENT_HANDLER_ERROR_INVALID_PARAMETER, + "cb is NULL"); + + mm_navevent_handler_s *handler = (mm_navevent_handler_s *)handle; + + return _mm_navevent_handler_set_cb(handler, cb, data); +} + +int mm_navevent_handler_unset_cb(mm_navevent_handler_h handle) +{ + MM_EH_RETVM_IF(NULL == handle, MM_NAVEVENT_HANDLER_ERROR_INVALID_PARAMETER, + "Handle is NULL"); + + mm_navevent_handler_s *handler = (mm_navevent_handler_s *)handle; + + return _mm_navevent_handler_unset_cb(handler); +} + +int mm_navevent_handler_set_window_parameters(mm_navevent_handler_h handle, mm_navevent_handler_orientation_e wo, mm_navevent_handler_size_s ws) +{ + MM_EH_RETVM_IF(NULL == handle, MM_NAVEVENT_HANDLER_ERROR_INVALID_PARAMETER, + "Handle is NULL"); + + mm_navevent_handler_s *handler = (mm_navevent_handler_s *)handle; + + return _mm_navevent_handler_set_window_parameters(handler, wo, ws); +} + +int mm_navevent_handler_set_fov_size(mm_navevent_handler_h handle, mm_navevent_handler_size_s fovs) +{ + MM_EH_RETVM_IF(NULL == handle, MM_NAVEVENT_HANDLER_ERROR_INVALID_PARAMETER, + "Handle is NULL"); + + mm_navevent_handler_s *handler = (mm_navevent_handler_s *)handle; + + return _mm_navevent_handler_set_fov_size(handler, fovs); +} + +int mm_navevent_handler_get_screen_size(mm_navevent_handler_h handle, mm_navevent_handler_size_s *size) +{ + MM_EH_RETVM_IF(NULL == handle, MM_NAVEVENT_HANDLER_ERROR_INVALID_PARAMETER, + "Handle is NULL"); + + MM_EH_RETVM_IF(NULL == size, MM_NAVEVENT_HANDLER_ERROR_INVALID_PARAMETER, + "Structure address is NULL"); + + mm_navevent_handler_s *handler = (mm_navevent_handler_s *)handle; + + return _mm_navevent_handler_get_screen_size(handler, size); +} + +int mm_navevent_handler_set_angles(mm_navevent_handler_h handle, float angles[3]) +{ + MM_EH_RETVM_IF(NULL == handle, MM_NAVEVENT_HANDLER_ERROR_INVALID_PARAMETER, + "Handle is NULL"); + + MM_EH_RETVM_IF(NULL == angles, MM_NAVEVENT_HANDLER_ERROR_INVALID_PARAMETER, + "Array address is NULL"); + + mm_navevent_handler_s *handler = (mm_navevent_handler_s *)handle; + + return _mm_navevent_handler_set_angles(handler, angles); +} diff --git a/test/event-handler/src/mm_navevent_handler_internal.c b/test/event-handler/src/mm_navevent_handler_internal.c new file mode 100644 index 0000000..36f5ee4 --- /dev/null +++ b/test/event-handler/src/mm_navevent_handler_internal.c @@ -0,0 +1,382 @@ +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved + * + * @author: Volodymyr Brynza + * Andriy Martynets + * + * 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. + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mm_navevent_handler_priv.h" +#include "mm_navevent_handler_util.h" + +const char *UDEV_SEAT = "seat0"; + +static int __mm_navevent_handler_input_open(const char *path, int flags, void *user_data) +{ + int fd = open(path, flags); + return fd < 0 ? -errno : fd; +} + +static void __mm_navevent_handler_input_close(int fd, void *user_data) +{ + close(fd); +} + +static const struct libinput_interface iface = { + .open_restricted = __mm_navevent_handler_input_open, + .close_restricted = __mm_navevent_handler_input_close, +}; + +static int __mm_navevent_handler_init_input(mm_navevent_handler_s *handler) +{ + struct udev *udev = udev_new(); + if (NULL == udev) { + MM_EH_ERROR("Failed to initialize udev"); + return MM_NAVEVENT_HANDLER_ERROR_INVALID_OPERATION; + } + + handler->lih = libinput_udev_create_context(&iface, NULL, udev); + if (NULL == handler->lih) { + MM_EH_ERROR("Failed to initialize libinput context from udev"); + udev_unref(udev); + return MM_NAVEVENT_HANDLER_ERROR_INVALID_OPERATION; + } + + if (libinput_udev_assign_seat(handler->lih, UDEV_SEAT)) { + MM_EH_ERROR("Failed to set seat for context"); + libinput_unref(handler->lih); + handler->lih = NULL; + udev_unref(udev); + return MM_NAVEVENT_HANDLER_ERROR_INVALID_OPERATION; + } + + return MM_NAVEVENT_HANDLER_ERROR_NONE; +} + +static void set_initial_coordinates(mm_navevent_handler_s *handler, struct libinput_event *ev) +{ + struct libinput_event_touch *t = libinput_event_get_touch_event(ev); + MM_EH_DEBUG("Got touch down event. Time - %f sec", libinput_event_touch_get_time(t)/1000.0); + + pthread_mutex_lock(&handler->event_lock); + + handler->last[0] = libinput_event_touch_get_x(t); + handler->last[1] = libinput_event_touch_get_y(t); + + if (handler->cb) { + /* Below call simulates mouse depressed move */ + handler->cb(LIBINPUT_EVENT_TOUCH_MOTION, handler->last[0], handler->last[1], handler->user_data, handler->angles); + handler->cb(libinput_event_get_type(ev), handler->last[0], handler->last[1], handler->user_data, handler->angles); + } + + pthread_mutex_unlock(&handler->event_lock); +} + +static void set_final_coordinates(mm_navevent_handler_s *handler, struct libinput_event *ev) +{ + struct libinput_event_touch *t = libinput_event_get_touch_event(ev); + MM_EH_DEBUG("Got touch up event. Time - %f sec", libinput_event_touch_get_time(t)/1000.0); + + pthread_mutex_lock(&handler->event_lock); + + if (handler->cb) + handler->cb(libinput_event_get_type(ev), handler->current[0], handler->current[1], handler->user_data, handler->angles); + + pthread_mutex_unlock(&handler->event_lock); +} + +/* NOTE: pointer slides the image, thus the direction of view moves in opposit + * direction. + * Orientation (degrees): + * 0 yaw: last_x - x; pitch: y - last_y; + * 0,0 ------> X + * | + * | + * | + * v Y + * + * 90 yaw: y - last_y; pitch: x - last_x; + * Y <------ 0,0 + * | + * | + * | + * X v + * + * 180 yaw: x - last_x; pitch: last_y - y; + * Y ^ + * | + * | + * | + * X <------ 0,0 + * + * 270 yaw: last_y - y; pitch: last_x - x; + * ^ X + * | + * | + * | + * 0,0 ------> Y + */ +static void update_angles(mm_navevent_handler_s *handler) +{ + float x, last_x, y, last_y; + + switch (handler->window_orientation) { + case MM_NAVEVENT_HANDLER_ORIENTATION_DEGREE_0: + x = handler->last[0]; + last_x = handler->current[0]; + y = handler->current[1]; + last_y = handler->last[1]; + break; + case MM_NAVEVENT_HANDLER_ORIENTATION_DEGREE_90: + x = handler->current[1]; + last_x = handler->last[1]; + y = handler->current[0]; + last_y = handler->last[0]; + break; + case MM_NAVEVENT_HANDLER_ORIENTATION_DEGREE_180: + x = handler->current[0]; + last_x = handler->last[0]; + y = handler->last[1]; + last_y = handler->current[1]; + break; + case MM_NAVEVENT_HANDLER_ORIENTATION_DEGREE_270: + x = handler->last[1]; + last_x = handler->current[1]; + y = handler->last[0]; + last_y = handler->current[0]; + break; + default: + return; + } + + handler->angles[0] += ((float)handler->fov.width * (x - last_x) / (float)handler->window_size.width) * M_PI / 180.0; + handler->angles[1] += ((float)handler->fov.height * (y - last_y) / (float)handler->window_size.height) * M_PI / 180.0; + + /* Fix yaw angle */ + if (handler->angles[0] <= -(M_PI)) handler->angles[0] += 2 * M_PI; + else if (handler->angles[0] > M_PI) handler->angles[0] -= 2 * M_PI; + + /* Fix pitch angle */ + if (handler->angles[1] < -(M_PI_2)) handler->angles[1] = -(M_PI_2); + else if (handler->angles[1] > M_PI_2) handler->angles[1] = M_PI_2; +} + +static void process_move(mm_navevent_handler_s *handler, struct libinput_event *ev) +{ + struct libinput_event_touch *t = libinput_event_get_touch_event(ev); + MM_EH_DEBUG("Got touch event. Time - %f sec", libinput_event_touch_get_time(t)/1000.0); + + pthread_mutex_lock(&handler->event_lock); + + handler->current[0] = libinput_event_touch_get_x(t); + handler->current[1] = libinput_event_touch_get_y(t); + + update_angles(handler); + + handler->last[0] = handler->current[0]; + handler->last[1] = handler->current[1]; + + if (handler->cb) { + MM_EH_INFO("Sending position to user code"); + handler->cb(libinput_event_get_type(ev), handler->current[0], handler->current[1], handler->user_data, handler->angles); + } + + pthread_mutex_unlock(&handler->event_lock); +} + +static void handle_events(mm_navevent_handler_s *handler) +{ + struct libinput_event *ev = NULL; + + MM_EH_INFO("Process events"); + + libinput_dispatch(handler->lih); + + while ((ev = libinput_get_event(handler->lih))) { + switch (libinput_event_get_type(ev)) { + case LIBINPUT_EVENT_TOUCH_MOTION: + MM_EH_DEBUG("Got touch event with coords"); + /* Process coordinates and send event */ + if (handler->dev == MM_NAVEVENT_HANDLER_DEVICE_TYPE_TOUCH) + process_move(handler, ev); + break; + case LIBINPUT_EVENT_TOUCH_DOWN: + if (handler->dev == MM_NAVEVENT_HANDLER_DEVICE_TYPE_TOUCH) + set_initial_coordinates(handler, ev); + break; + case LIBINPUT_EVENT_TOUCH_UP: + if (handler->dev == MM_NAVEVENT_HANDLER_DEVICE_TYPE_TOUCH) + set_final_coordinates(handler, ev); + /* Do nothing as we don't get any coordinates here */ + MM_EH_DEBUG("Got touch event"); + break; + default: + break; + } + + libinput_event_destroy(ev); + libinput_dispatch(handler->lih); + } +} + +static void *__mm_navevent_handler_handle_event(void *data) +{ + struct pollfd fds; + mm_navevent_handler_s *handler = (mm_navevent_handler_s *)data; + + fds.fd = libinput_get_fd(handler->lih); + fds.events = POLLIN; + fds.revents = 0; + + MM_EH_INFO("Start processing navigation event"); + while (poll(&fds, 1, -1)) + handle_events(handler); + MM_EH_INFO("End processing navigation event"); + + return NULL; +} + +mm_navevent_handler_s *_mm_navevent_handler_create(mm_navevent_handler_device_type_e device) +{ + int res = 0; + mm_navevent_handler_s *handle = (mm_navevent_handler_s *)calloc(sizeof(mm_navevent_handler_s), 1); + if (NULL == handle) { + MM_EH_ERROR("Cannot allocate memory for event handler"); + return NULL; + } + + handle->dev = device; + + res = system_info_get_platform_int("http://tizen.org/feature/screen.width", &handle->screen_size.width); + if (SYSTEM_INFO_ERROR_NONE != res) { + MM_EH_ERROR("Failed to get Device screen width from System Info with error - [%d]", res); + free(handle); + return NULL; + } + + res = system_info_get_platform_int("http://tizen.org/feature/screen.height", &handle->screen_size.height); + if (SYSTEM_INFO_ERROR_NONE != res) { + MM_EH_ERROR("Failed to get Device screen height from System Info with error - [%d]", res); + free(handle); + return NULL; + } + + res = __mm_navevent_handler_init_input(handle); + if (MM_NAVEVENT_HANDLER_ERROR_NONE != res) { + MM_EH_ERROR("Failed to initialize input for event handling with error - [%d]", res); + free(handle); + return NULL; + } + + pthread_mutex_init(&handle->event_lock, NULL); + + handle->window_orientation = MM_NAVEVENT_HANDLER_ORIENTATION_DEGREE_0; + handle->window_size.width = handle->screen_size.width; + handle->window_size.height = handle->screen_size.height; + handle->fov.width = MM_NAVEVENT_HANDLER_DEFAULT_HORIZONTAL_FOV_DEGREE; + handle->fov.height = MM_NAVEVENT_HANDLER_DEFAULT_VERTICAL_FOV_DEGREE; + handle->angles[0] = handle->angles[1] = handle->angles[2] = .0f; + + pthread_create(&handle->event_thread, NULL, __mm_navevent_handler_handle_event, handle); + + return handle; +} + +int _mm_navevent_handler_destroy(mm_navevent_handler_s *handler) +{ + if (NULL == handler) { + MM_EH_ERROR("Invalid pointer to event handler"); + return MM_NAVEVENT_HANDLER_ERROR_INVALID_PARAMETER; + } + + pthread_mutex_lock(&handler->event_lock); + pthread_cancel(handler->event_thread); + pthread_mutex_unlock(&handler->event_lock); + + void *thread_res = NULL; + pthread_join(handler->event_thread, &thread_res); + + pthread_mutex_destroy(&handler->event_lock); + + libinput_unref(handler->lih); + + free(handler); + + return MM_NAVEVENT_HANDLER_ERROR_NONE; +} + +int _mm_navevent_handler_set_cb(mm_navevent_handler_s *handler, mm_navevent_handler_cb cb, void *data) +{ + if (NULL == handler) { + MM_EH_ERROR("Invalid pointer to event handler"); + return MM_NAVEVENT_HANDLER_ERROR_INVALID_PARAMETER; + } + + handler->cb = cb; + handler->user_data = data; + + return MM_NAVEVENT_HANDLER_ERROR_NONE; +} + +int _mm_navevent_handler_unset_cb(mm_navevent_handler_s *handler) +{ + if (NULL == handler) { + MM_EH_ERROR("Invalid pointer to event handler"); + return MM_NAVEVENT_HANDLER_ERROR_INVALID_PARAMETER; + } + + handler->cb = NULL; + handler->user_data = NULL; + + return MM_NAVEVENT_HANDLER_ERROR_NONE; +} + +int _mm_navevent_handler_set_window_parameters(mm_navevent_handler_s *handler, mm_navevent_handler_orientation_e wo, mm_navevent_handler_size_s ws) +{ + handler->window_size = ws; + handler->window_orientation = wo; + + return MM_NAVEVENT_HANDLER_ERROR_NONE; +} + +int _mm_navevent_handler_set_fov_size(mm_navevent_handler_s *handler, mm_navevent_handler_size_s fovs) +{ + handler->fov = fovs; + + return MM_NAVEVENT_HANDLER_ERROR_NONE; +} + +int _mm_navevent_handler_get_screen_size(mm_navevent_handler_s *handler, mm_navevent_handler_size_s *size) +{ + memcpy(size, &handler->screen_size, sizeof(*size)); + + return MM_NAVEVENT_HANDLER_ERROR_NONE; +} + +int _mm_navevent_handler_set_angles(mm_navevent_handler_s *handler, float angles[3]) +{ + memcpy(handler->angles, angles, sizeof(*angles) * 3); + + return MM_NAVEVENT_HANDLER_ERROR_NONE; +} diff --git a/test/player_test.c b/test/player_test.c index a7e9e06..d8dd82e 100644 --- a/test/player_test.c +++ b/test/player_test.c @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#define USE_EVENT_HANDLER + #include #include #include @@ -29,6 +31,10 @@ #include #endif +#ifdef USE_EVENT_HANDLER +#include +#endif + #ifdef PACKAGE #undef PACKAGE #endif @@ -65,6 +71,14 @@ typedef struct { int rebuffer_ms; } buffer_size_t; +#ifdef USE_EVENT_HANDLER +static void event_handler_cb(enum libinput_event_type ev_t, int x, int y, void * data, float e[3]); +static void event_handler_set_dov_fov(); +static void event_handler_set_window_parameters(); +mm_navevent_handler_h event_handler; +mm_navevent_handler_size_s image_size; +#endif + static tizen_profile_t _get_tizen_profile() { char *profileName; @@ -152,6 +166,12 @@ enum { CURRENT_STATUS_SET_AUDIO_ONLY, CURRENT_STATUS_SET_PRE_BUFFERING_SIZE, CURRENT_STATUS_SET_RE_BUFFERING_SIZE, + CURRENT_STATUS_VIDEO360_SET_ENABLE, + CURRENT_STATUS_VIDEO360_SET_DOV, + CURRENT_STATUS_VIDEO360_SET_DOV1, + CURRENT_STATUS_VIDEO360_SET_FOV, + CURRENT_STATUS_VIDEO360_SET_FOV1, + CURRENT_STATUS_VIDEO360_SET_ZOOM, }; typedef struct { @@ -456,6 +476,7 @@ static int app_create(void *data) #ifdef _ACTIVATE_EOM_ eom_output_mode_e output_mode = EOM_OUTPUT_MODE_NONE; #endif + /* use gl backend */ elm_config_accel_preference_set("opengl"); @@ -510,6 +531,21 @@ static int app_create(void *data) eom_set_mode_changed_cb(eom_notify_cb_mode_changed, ad); eom_set_attribute_changed_cb(eom_notify_cb_attribute_changed, ad); #endif + +#ifdef USE_EVENT_HANDLER + if (mm_navevent_handler_create(&event_handler, + MM_NAVEVENT_HANDLER_DEVICE_TYPE_TOUCH) != MM_NAVEVENT_HANDLER_ERROR_NONE) { + g_print ("Error during handler creation\n"); + return -1; + } + + if (mm_navevent_handler_set_cb(event_handler, event_handler_cb, NULL) != + MM_NAVEVENT_HANDLER_ERROR_NONE) { + g_print ("Error during callback set\n"); + return -1; + } +#endif + return 0; } @@ -518,6 +554,10 @@ static int app_terminate(void *data) appdata *ad = data; int i = 0; +#ifdef USE_EVENT_HANDLER + mm_navevent_handler_destroy(event_handler); +#endif + for (i = 0; i < MAX_HANDLE; i++) { if (g_eo[i]) { evas_object_del(g_eo[i]); @@ -607,6 +647,12 @@ static void interrupted_cb(player_interrupted_code_e code, void *user_data) static void video_changed_cb(int width, int height, int fps, int bit_rate, void *user_data) { g_print("[Player_Test] video_changed_cb!!!! %d x %d, %d, %d \n", width, height, fps, bit_rate); + +#ifdef USE_EVENT_HANDLER + image_size.width = width; + image_size.height = height; + event_handler_set_window_parameters(); +#endif } #if 0 @@ -1051,6 +1097,9 @@ static void _player_prepare(bool async) if (is_es_push_mode) pthread_create(&g_feed_video_thread_id, NULL, (void *)feed_video_data_thread_func, NULL); +#ifdef USE_EVENT_HANDLER + event_handler_set_dov_fov(); +#endif } static void _player_unprepare() @@ -1701,6 +1750,9 @@ static void set_display_rotation(int rotation) { if (player_set_display_rotation(g_player[0], rotation) != PLAYER_ERROR_NONE) g_print("failed to set_display_rotation\n"); +#ifdef USE_EVENT_HANDLER + event_handler_set_window_parameters(); +#endif } static void get_display_rotation() @@ -1860,6 +1912,139 @@ static void get_audio_eq() g_print(" ==> [Player_Test] eq bands frequency range: [%d] \n", value); } +static void video360_set_enable(bool enable) +{ +#ifdef USE_EVENT_HANDLER + event_handler_set_dov_fov(); +#endif + + if (player_360_set_enable(g_player[0], enable) != PLAYER_ERROR_NONE) + g_print("failed to %s video 360 mode\n", enable ? "enable" : "disable"); +} + +static void video360_get_enable() +{ + bool enable; + + if (player_360_is_enabled(g_player[0], &enable) != PLAYER_ERROR_NONE) + g_print("failed to get video 360 mode status\n"); + else + g_print(" ==> [Player_Test] Video 360 mode = %s\n", enable ? "enabled" : "disabled"); +} + +static void video360_set_fov(int hfov, int vfov) +{ +#ifdef USE_EVENT_HANDLER + mm_navevent_handler_size_s fov; + + fov.width = hfov; + fov.height = vfov; + mm_navevent_handler_set_fov_size(event_handler, fov); +#endif + if (player_360_set_field_of_view(g_player[0], hfov, vfov) != PLAYER_ERROR_NONE) + g_print("failed to set video 360 field of view\n"); +} + +static void video360_get_fov() +{ + int hfov, vfov; + + if (player_360_get_field_of_view(g_player[0], &hfov, &vfov) != PLAYER_ERROR_NONE) + g_print("failed to get video 360 field of view\n"); + else + g_print(" ==> [Player_Test] Video 360 FOV = %dx%d deg.\n", hfov, vfov); +} + +static void video360_set_dov(int yaw_deg, int pitch_deg) +{ + float angles[3]; + + angles[0] = M_PI * yaw_deg / 180.0f; + angles[1] = M_PI * pitch_deg / 180.0f; + angles[2] = 0; + +#ifdef USE_EVENT_HANDLER + mm_navevent_handler_set_angles(event_handler, angles); +#endif + if (player_360_set_direction_of_view(g_player[0], angles[0], angles[1]) != PLAYER_ERROR_NONE) + g_print("failed to set video 360 direction of view\n"); +} + +static void video360_get_dov() +{ + float yaw, pitch; + + if (player_360_get_direction_of_view(g_player[0], &yaw, &pitch) != PLAYER_ERROR_NONE) + g_print("failed to get video 360 direction of view\n"); + else + g_print(" ==> [Player_Test] Video 360 DOV yaw = %d, pitch = %d deg.\n", (int)(yaw * 180.0f / M_PI), (int)(pitch * 180.0f / M_PI)); +} + +static void video360_set_zoom(float zoom) +{ + if (player_360_set_zoom(g_player[0], zoom) != PLAYER_ERROR_NONE) + g_print("failed to set video 360 zoom\n"); +} + +static void video360_get_zoom() +{ + float zoom; + + if (player_360_get_zoom(g_player[0], &zoom) != PLAYER_ERROR_NONE) + g_print("failed to get video 360 zoom\n"); + else + g_print(" ==> [Player_Test] Video 360 zoom = %f\n", zoom); +} + +#ifdef USE_EVENT_HANDLER +static void event_handler_cb(enum libinput_event_type ev_t, int x, int y, void * data, float e[3]) +{ + if (ev_t == LIBINPUT_EVENT_TOUCH_MOTION) + if (player_360_set_direction_of_view(g_player[0], e[0], e[1]) != PLAYER_ERROR_NONE) + g_print("Event handler callback: failed to set direction of view\n"); +} + +static void event_handler_set_dov_fov() +{ + float angles[3]; + mm_navevent_handler_size_s fov; + + if (player_360_get_direction_of_view(g_player[0], &angles[0], &angles[1]) != PLAYER_ERROR_NONE) { + g_print("Failed to get video360 direction of view\n"); + return; + } + if (player_360_get_field_of_view(g_player[0], &fov.width, &fov.height) != PLAYER_ERROR_NONE) { + g_print("Failed to get video360 field of view\n"); + return; + } + mm_navevent_handler_set_angles(event_handler, angles); + mm_navevent_handler_set_fov_size(event_handler, fov); +} + +static void event_handler_set_window_parameters() +{ + player_display_rotation_e window_orientation; + mm_navevent_handler_size_s window_size; + float image_ratio; + + player_get_display_rotation(g_player[0], &window_orientation); + elm_win_screen_size_get(selected_win_id, NULL, NULL, &window_size.width, &window_size.height); + + image_ratio = (float) image_size.width / (float) image_size.height; + + if (window_orientation == PLAYER_DISPLAY_ROTATION_NONE || + window_orientation == PLAYER_DISPLAY_ROTATION_180) { + window_size.height = (int)((float) window_size.width / image_ratio); + } else { + window_size.height = window_size.width; + window_size.width = (int)((float) window_size.width * image_ratio); + } + + mm_navevent_handler_set_window_parameters(event_handler, + (mm_navevent_handler_orientation_e) window_orientation, window_size); +} +#endif + void quit_program() { @@ -2023,12 +2208,32 @@ void _interpret_main_menu(char *cmd) } else { g_print("unknown menu \n"); } - } else { + } else if (len == 3) { if (strncmp(cmd, "trs", 3) == 0) g_menu_state = CURRENT_STATUS_STREAMING_PLAYBACK_RATE; else g_print("unknown menu \n"); - } + } else if (len == 4) { + if (!strncmp(cmd, "v3se", 4)) + g_menu_state = CURRENT_STATUS_VIDEO360_SET_ENABLE; + else if (!strncmp(cmd, "v3ge", 4)) + video360_get_enable(); + else if (!strncmp(cmd, "v3sd", 4)) + g_menu_state = CURRENT_STATUS_VIDEO360_SET_DOV; + else if (!strncmp(cmd, "v3gd", 4)) + video360_get_dov(); + else if (!strncmp(cmd, "v3sf", 4)) + g_menu_state = CURRENT_STATUS_VIDEO360_SET_FOV; + else if (!strncmp(cmd, "v3gf", 4)) + video360_get_fov(); + else if (!strncmp(cmd, "v3sz", 4)) + g_menu_state = CURRENT_STATUS_VIDEO360_SET_ZOOM; + else if (!strncmp(cmd, "v3gz", 4)) + video360_get_zoom(); + else + g_print("unknown menu \n"); + } else + g_print("unknown menu \n"); } void display_sub_basic() @@ -2084,6 +2289,14 @@ void display_sub_basic() g_print("X4. set audio_cb with async \n"); g_print("[video_frame_decoded_cb] ep. enable tbm surface pool\n"); g_print("[buffering] bf. set new buffering size\n"); + g_print("[Video 360] v3se. Set Enable\t\t"); + g_print("v3ge. Get Enable\n"); + g_print("[Video 360] v3sd. Set Direction Of View\t"); + g_print("v3gd. Get Direction Of View\n"); + g_print("[Video 360] v3sf. Set Field Of View\t"); + g_print("v3gf. Get Field Of View\n"); + g_print("[Video 360] v3sz. Set Zoom\t\t"); + g_print("v3gz. Get Zoom\n"); g_print("[etc] sp. Set Progressive Download\t"); g_print("gp. Get Progressive Download status\t"); g_print("mp. memory playback\n"); @@ -2159,6 +2372,18 @@ static void displaymenu() g_print("*** set audio only mode (0:disable, 1:enable) \n"); } else if (g_menu_state == CURRENT_STATUS_SET_PRE_BUFFERING_SIZE) { g_print("*** set pre buffering size (ms) \n"); + } else if (g_menu_state == CURRENT_STATUS_VIDEO360_SET_ENABLE) { + g_print("*** input video 360 status (0: disabled (full panorama), 1: enabled)\n"); + } else if (g_menu_state == CURRENT_STATUS_VIDEO360_SET_DOV) { + g_print("*** input direction of view yaw angle (+/- 180 deg.)\n"); + } else if (g_menu_state == CURRENT_STATUS_VIDEO360_SET_DOV1) { + g_print("*** input direction of view pitch angle (+/- 90 deg.)\n"); + } else if (g_menu_state == CURRENT_STATUS_VIDEO360_SET_FOV) { + g_print("*** input horizontal field of view angle (1~360 deg.)\n"); + } else if (g_menu_state == CURRENT_STATUS_VIDEO360_SET_FOV1) { + g_print("*** input vertical field of view angle (1~180 deg.)\n"); + } else if (g_menu_state == CURRENT_STATUS_VIDEO360_SET_ZOOM) { + g_print("*** input zoom factor.(1.0~10.0, where 1.0 - no zoom, actual image) \n"); } else { g_print("*** unknown status.\n"); quit_program(); @@ -2185,6 +2410,8 @@ void reset_menu_state(void) static void interpret(char *cmd) { + static int value1, value2; + switch (g_menu_state) { case CURRENT_STATUS_MAINMENU: { @@ -2417,6 +2644,46 @@ static void interpret(char *cmd) reset_menu_state(); } break; + case CURRENT_STATUS_VIDEO360_SET_ENABLE: + { + int enable = atoi(cmd); + video360_set_enable(enable); + reset_menu_state(); + } + break; + case CURRENT_STATUS_VIDEO360_SET_DOV: + { + value1 = atoi(cmd); + g_menu_state = CURRENT_STATUS_VIDEO360_SET_DOV1; + } + break; + case CURRENT_STATUS_VIDEO360_SET_DOV1: + { + value2 = atoi(cmd); + video360_set_dov(value1, value2); + reset_menu_state(); + } + break; + case CURRENT_STATUS_VIDEO360_SET_FOV: + { + value1 = atoi(cmd); + g_menu_state = CURRENT_STATUS_VIDEO360_SET_FOV1; + } + break; + case CURRENT_STATUS_VIDEO360_SET_FOV1: + { + value2 = atoi(cmd); + video360_set_fov(value1, value2); + reset_menu_state(); + } + break; + case CURRENT_STATUS_VIDEO360_SET_ZOOM: + { + float zoom = atof(cmd); + video360_set_zoom(zoom); + reset_menu_state(); + } + break; } -- 2.7.4