- player_set_display could get wayland tizen exported shell handle with new type
- Display related function set as PLAYER_DISPLAY_OVERLAY cannot be used except for visible
and PLAYER_ERROR_NOT_AVAILABLE is returned if they are used
- Add sample function to player_test with move, resize and transform
- Video is always rendered at full scale inside tizen exported shell
Change-Id: I61c20cb7e124d16a86b0a11dbd941f6ae693b7d8
Signed-off-by: Hyunil <hyunil46.park@samsung.com>
/**
* @brief Enumeration for display type.
* @since_tizen @if WEARABLE 2.3.1 @else 2.3 @endif
+ * @details In case of using #PLAYER_DISPLAY_TYPE_OVERLAY_SYNC_UI, the video is rendering in full scale in the rendering area.\n
+ * To change the video rendering position, use UI API functions like ecore_wl2_subsurface_exported_surface_move(),
+ * ecore_wl2_subsurface_exported_surface_resize(), ecore_wl2_subsurface_exported_surface_transform_set(),
+ * ecore_wl2_subsurface_exported_surface_show() and ecore_wl2_subsurface_exported_surface_commit().\n
+ * player_set_display_mode(), player_set_display_rotation() and player_set_display_roi_area() cannot be used and
+ * #PLAYER_ERROR_NOT_AVAILABLE is returned if they are used.\n
+ * Exported shell handle must be obtained by ecore_wl2_subsurface_exported_surface_handle_get() from Ecore_Wl2_Subsurface.\n
+ * Then the exported shell handle should be set with player_set_display().\n
+ * To render the first video buffer, commit by ecore_wl2_window_commit() after player_prepare() of Ecore_Wl2_Subsurface.\n
+ * Always commit with ecore_wl2_window_commit() with parent surface when the UI changes and the video needs to be synchronized.
*/
typedef enum {
PLAYER_DISPLAY_TYPE_OVERLAY = 0, /**< Overlay surface display */
PLAYER_DISPLAY_TYPE_EVAS = 3, /**< Evas image object surface display (Since 4.0) */
PLAYER_DISPLAY_TYPE_NONE = 4, /**< This disposes of buffers (Since 4.0) */
+ PLAYER_DISPLAY_TYPE_OVERLAY_SYNC_UI = 5 /**< Overlay surface display for synchronization between UI and video (Since 6.5) */
} player_display_type_e;
/**
* @retval #PLAYER_ERROR_NONE Successful
* @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter
* @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation
+ * @retval #PLAYER_ERROR_NOT_AVAILABLE Not available (Since 6.5)
* @see #player_display_mode_e
* @see player_set_display()
* @see player_get_display_mode()
* @retval #PLAYER_ERROR_NONE Successful
* @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter
* @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation
+ * @retval #PLAYER_ERROR_NOT_AVAILABLE Not available (Since 6.5)
* @see #player_display_mode_e
* @see player_set_display_mode()
*/
* @retval #PLAYER_ERROR_NONE Successful
* @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter
* @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation
+ * @retval #PLAYER_ERROR_NOT_AVAILABLE Not available (Since 6.5)
* @see player_set_display()
* @see player_set_display_mode()
*/
* @retval #PLAYER_ERROR_NONE Successful
* @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter
* @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation
+ * @retval #PLAYER_ERROR_NOT_AVAILABLE Not available (Since 6.5)
* @see #player_display_rotation_e
* @see player_set_display()
* @see player_get_display_rotation()
* @retval #PLAYER_ERROR_NONE Successful
* @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter
* @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation
+ * @retval #PLAYER_ERROR_NOT_AVAILABLE Not available (Since 6.5)
* @see #player_display_rotation_e
* @see player_set_display_rotation()
*/
Name: capi-media-player
Summary: A Media Player API
-Version: 0.3.143
+Version: 0.3.144
Release: 0
Group: Multimedia/API
License: Apache-2.0
BuildRequires: pkgconfig(appcore-efl)
BuildRequires: pkgconfig(elementary)
BuildRequires: pkgconfig(ecore)
+BuildRequires: pkgconfig(ecore-wl2)
BuildRequires: pkgconfig(evas)
BuildRequires: pkgconfig(capi-media-tool)
BuildRequires: pkgconfig(mmsvc-player)
char *param_name = NULL;
void *value = NULL;
- LOGE("ENTER");
-
void *jobj = muse_core_msg_object_new(buf, NULL, &err);
if (!jobj) {
case PLAYER_DISPLAY_TYPE_OVERLAY:
*out_type = MM_DISPLAY_TYPE_OVERLAY;
break;
+ case PLAYER_DISPLAY_TYPE_OVERLAY_SYNC_UI:
+ *out_type = MM_DISPLAY_TYPE_OVERLAY_SYNC_UI;
+ break;
case PLAYER_DISPLAY_TYPE_EVAS:
*out_type = MM_DISPLAY_TYPE_EVAS;
break;
return PLAYER_ERROR_INVALID_OPERATION;
}
- if (conv_type == MM_DISPLAY_TYPE_EVAS) {
+ if (conv_type == MM_DISPLAY_TYPE_OVERLAY_SYNC_UI) {
+ g_strlcpy(wl_win.exported_shell_handle, (char *)display, MAX_EXPORTED_SHELL_HANDLE_LEN);
+ } else if (conv_type == MM_DISPLAY_TYPE_EVAS) {
/* before evas handle is created, user could set display information */
player_display_mode_e mode = PLAYER_DISPLAY_MODE_LETTER_BOX;
player_display_rotation_e rotation = PLAYER_DISPLAY_ROTATION_NONE;
PLAYER_GET_DISPLAY_TYPE(pc, display_type);
+ if (display_type == MM_DISPLAY_TYPE_OVERLAY_SYNC_UI) {
+ LOGE("Function is not available in MM_DISPLAY_TYPE_OVERLAY_SYNC_UI type");
+ return PLAYER_ERROR_NOT_AVAILABLE;
+ }
+
if (display_type == MM_DISPLAY_TYPE_EVAS) {
mm_ret = mm_display_interface_evas_set_mode(DP_INTERFACE(pc), mode);
if (mm_ret != MM_ERROR_NONE) {
player_cli_s *pc = (player_cli_s *)player;
char *ret_buf = NULL;
int mode = -1;
+ mm_display_type_e display_type = MM_DISPLAY_TYPE_NONE;
PLAYER_INSTANCE_CHECK(player);
PLAYER_NULL_ARG_CHECK(pmode);
LOGD("ENTER");
+ PLAYER_GET_DISPLAY_TYPE(pc, display_type);
+
+ if (display_type == MM_DISPLAY_TYPE_OVERLAY_SYNC_UI) {
+ LOGE("Function is not available in MM_DISPLAY_TYPE_OVERLAY_SYNC_UI type");
+ return PLAYER_ERROR_NOT_AVAILABLE;
+ }
+
PLAYER_SEND_MSG(api, pc, ret_buf, ret);
if (ret == PLAYER_ERROR_NONE) {
PLAYER_GET_DISPLAY_TYPE(pc, display_type);
+ if (display_type == MM_DISPLAY_TYPE_OVERLAY_SYNC_UI) {
+ LOGE("Function is not available in MM_DISPLAY_TYPE_OVERLAY_SYNC_UI type");
+ return PLAYER_ERROR_NOT_AVAILABLE;
+ }
+
if (display_type == MM_DISPLAY_TYPE_EVAS) {
LOGE("Display type is EVAS, video display interface is not supported");
return PLAYER_ERROR_INVALID_OPERATION;
player_cli_s *pc = (player_cli_s *)player;
char *ret_buf = NULL;
double scale_x = 0, scale_y = 0, scale_w = 0, scale_h = 0;
+ mm_display_type_e display_type = MM_DISPLAY_TYPE_NONE;
PLAYER_INSTANCE_CHECK(player);
+ PLAYER_GET_DISPLAY_TYPE(pc, display_type);
+
+ if (display_type == MM_DISPLAY_TYPE_OVERLAY_SYNC_UI) {
+ LOGE("Function is not available in MM_DISPLAY_TYPE_OVERLAY_SYNC_UI type");
+ return PLAYER_ERROR_NOT_AVAILABLE;
+ }
+
PLAYER_NULL_ARG_CHECK(x_scale && y_scale && w_scale && h_scale);
PLAYER_SEND_MSG(api, pc, ret_buf, ret);
PLAYER_GET_DISPLAY_TYPE(pc, display_type);
+ if (display_type == MM_DISPLAY_TYPE_OVERLAY_SYNC_UI) {
+ LOGE("Function is not available in MM_DISPLAY_TYPE_OVERLAY_SYNC_UI type");
+ return PLAYER_ERROR_NOT_AVAILABLE;
+ }
+
if (display_type == MM_DISPLAY_TYPE_EVAS) {
mm_ret = mm_display_interface_evas_set_rotation(DP_INTERFACE(pc), rotation);
if (mm_ret != MM_ERROR_NONE) {
muse_player_api_e api = MUSE_PLAYER_API_GET_DISPLAY_ROTATION;
char *ret_buf = NULL;
int rotation = -1;
+ mm_display_type_e display_type = MM_DISPLAY_TYPE_NONE;
PLAYER_INSTANCE_CHECK(player);
+ PLAYER_GET_DISPLAY_TYPE(pc, display_type);
+
+ if (display_type == MM_DISPLAY_TYPE_OVERLAY_SYNC_UI) {
+ LOGE("Function is not available in MM_DISPLAY_TYPE_OVERLAY_SYNC_UI type");
+ return PLAYER_ERROR_NOT_AVAILABLE;
+ }
+
PLAYER_NULL_ARG_CHECK(protation);
LOGD("ENTER");
link_directories(${CMAKE_SOURCE_DIR}/../)
INCLUDE(FindPkgConfig)
-pkg_check_modules(${fw_test} REQUIRED libudev libinput capi-system-info appcore-efl elementary ecore evas capi-media-sound-manager)
+pkg_check_modules(${fw_test} REQUIRED libudev libinput capi-system-info appcore-efl elementary ecore ecore-wl2 evas capi-media-sound-manager)
FOREACH(flag ${${fw_test}_CFLAGS})
SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
ENDFOREACH(flag)
#include <appcore-efl.h>
#include <Elementary.h>
#include <Ecore.h>
+#include <Ecore_Wl2.h>
#include <stdio.h>
#include <string.h>
#ifdef _ACTIVATE_EOM_
static Evas_Object *selected_win_id;
static Evas_Object *g_eo[MAX_HANDLE] = { 0, };
+static Ecore_Wl2_Subsurface *g_ecore_wl2_subsurface = NULL;
+static Ecore_Wl2_Window *g_ecore_wl2_window = NULL;
static int g_current_surface_type = -1;
typedef struct {
return 0;
}
+static void __ecore_wl2_subsurface_del(Ecore_Wl2_Subsurface *ecore_wl2_subsurface)
+{
+ if (!ecore_wl2_subsurface) {
+ g_print("ecore_wl2_subsurface is NULL\n");
+ return;
+ }
+ ecore_wl2_subsurface_del(ecore_wl2_subsurface);
+ ecore_wl2_subsurface = NULL;
+}
+
static int app_terminate(void *data)
{
appdata *ad = data;
g_eo[i] = NULL;
}
}
+
+ __ecore_wl2_subsurface_del(g_ecore_wl2_subsurface);
+
if (g_win_id) {
evas_object_del(g_win_id);
g_win_id = NULL;
if (is_es_push_mode)
pthread_create(&g_feed_video_thread_id, NULL, (void *)feed_video_data_thread_func, NULL);
+ if (g_current_surface_type == PLAYER_DISPLAY_TYPE_OVERLAY_SYNC_UI &&
+ g_ecore_wl2_subsurface && g_ecore_wl2_window) {
+ ecore_wl2_window_commit(g_ecore_wl2_window, EINA_TRUE);
+ }
+
#ifdef USE_EVENT_HANDLER
event_handler_set_dov_fov();
#endif
{
int bRet = FALSE;
int i = 0;
+
if (g_current_surface_type == PLAYER_DISPLAY_TYPE_OVERLAY) {
#ifdef _ACTIVATE_EOM_
/* for checking external display.... */
{
player_display_type_e surface_type = 0;
int ret = PLAYER_ERROR_NONE;
+ Eina_Bool res = EINA_FALSE;
+ const char *exported_shell_handle = NULL;
#ifdef _ACTIVATE_EOM_
int hdmi_output_id;
eom_output_mode_e output_mode;
case 0:
/* X surface */
surface_type = PLAYER_DISPLAY_TYPE_OVERLAY;
- g_print("change surface type to X\n");
+ g_print("change surface type to OVERLAY\n");
break;
case 1:
/* EVAS surface */
surface_type = g_current_surface_type = PLAYER_DISPLAY_TYPE_NONE;
player_set_display(g_player[0], PLAYER_DISPLAY_TYPE_NONE, NULL);
break;
+ case 3:
+ g_print("change surface type to OVERLAY_SYNC_UI\n");
+ surface_type = g_current_surface_type = PLAYER_DISPLAY_TYPE_OVERLAY_SYNC_UI;
+ Ecore_Wl2_Window *ecore_wl2_win = (Ecore_Wl2_Window *)elm_win_wl_window_get(g_win_id);
+ Ecore_Wl2_Subsurface *ecore_wl2_subsurface = ecore_wl2_subsurface_new(ecore_wl2_win);
+ g_ecore_wl2_window = ecore_wl2_win;
+
+ res = ecore_wl2_subsurface_export(ecore_wl2_subsurface);
+ if (res != EINA_TRUE) {
+ g_print("failed to export foreign shell");
+ return;
+ }
+ exported_shell_handle = ecore_wl2_subsurface_exported_surface_handle_get(ecore_wl2_subsurface);
+ if (!exported_shell_handle) {
+ g_print("failed to get exported foreign shell handle");
+ return;
+ }
+ // Enables or disables exported surface synchronization for a given subsurface (default: EINA_TRUE)
+ ecore_wl2_subsurface_exported_surface_sync_set(ecore_wl2_subsurface, EINA_TRUE);
+ // If NULL is used, exported subsurface is placed under exported surface
+ ecore_wl2_subsurface_exported_surface_place_below(ecore_wl2_subsurface, NULL);
+ ecore_wl2_subsurface_exported_surface_move(ecore_wl2_subsurface, 200, 200);
+ ecore_wl2_subsurface_exported_surface_resize(ecore_wl2_subsurface, 500, 500);
+ ecore_wl2_subsurface_exported_surface_show(ecore_wl2_subsurface);
+ ecore_wl2_subsurface_exported_surface_commit(ecore_wl2_subsurface);
+ g_ecore_wl2_subsurface = ecore_wl2_subsurface;
+ player_set_display(g_player[0], PLAYER_DISPLAY_TYPE_OVERLAY_SYNC_UI, GET_DISPLAY(exported_shell_handle));
+
+ return;
default:
g_print("invalid surface type\n");
return;
}
+ if (surface_type != PLAYER_DISPLAY_TYPE_OVERLAY_SYNC_UI && g_ecore_wl2_subsurface)
+ __ecore_wl2_subsurface_del(g_ecore_wl2_subsurface);
+
player_state_e player_state = PLAYER_STATE_NONE;
ret = player_get_state(g_player[0], &player_state);
if (ret)
static void set_display_rotation(int rotation)
{
+ if (g_ecore_wl2_subsurface) {
+ g_print("set_display_rotation (%d)\n", rotation);
+ ecore_wl2_subsurface_exported_surface_transform_set(g_ecore_wl2_subsurface, rotation);
+ ecore_wl2_subsurface_exported_surface_show(g_ecore_wl2_subsurface);
+ ecore_wl2_subsurface_exported_surface_commit(g_ecore_wl2_subsurface);
+ ecore_wl2_window_commit(g_ecore_wl2_window, EINA_TRUE);
+ return;
+ }
+
if (player_set_display_rotation(g_player[0], rotation) != PLAYER_ERROR_NONE)
g_print("failed to set_display_rotation\n");
#ifdef USE_EVENT_HANDLER
static void get_display_rotation()
{
player_display_rotation_e rotation = 0;
+ if (g_ecore_wl2_subsurface)
+ return;
+
player_get_display_rotation(g_player[0], &rotation);
#ifdef USE_EVENT_HANDLER
g_rotation = (player_display_rotation_e) rotation;
} else if (g_menu_state == CURRENT_STATUS_LOOPING) {
g_print("*** input looping value.(0: Not Looping, 1: Looping) \n");
} else if (g_menu_state == CURRENT_STATUS_DISPLAY_SURFACE_CHANGE) {
- g_print("*** input display surface type.(0: Wayland surface, 1: EVAS surface, 2: No use surface (e.g: audio playback)) \n");
+ g_print("*** input display surface type.(0: Wayland surface, 1: EVAS surface, 2: No use surface (e.g: audio playback)) 3: Wayland surface(foreign shell)\n");
} else if (g_menu_state == CURRENT_STATUS_EXPORT_VIDEO_FRAME) {
g_print("*** set video_decoded_cb (0: none, 1: set cb) \n");
} else if (g_menu_state == CURRENT_STATUS_DISPLAY_MODE) {