return result;
}
+int
+__mmwfd_apply_attribute(MMHandleType handle, const char *attribute_name)
+{
+ MMHandleType attrs = 0;
+ mm_wfd_sink_t *wfd_sink = MMWFDSINK_CAST(handle);
+
+ wfd_sink_debug_fenter();
+
+ return_val_if_fail(wfd_sink, MM_ERROR_COMMON_INVALID_ARGUMENT);
+ return_val_if_fail(attribute_name, MM_ERROR_COMMON_INVALID_ARGUMENT);
+
+ attrs = MMWFDSINK_GET_ATTRS(handle);
+
+ return_val_if_fail(attrs, MM_ERROR_COMMON_INVALID_ARGUMENT);
+
+ if (!wfd_sink->pipeline ||
+ !wfd_sink->pipeline->v_sinkbin ||
+ !wfd_sink->pipeline->v_sinkbin[WFD_SINK_V_S_SINK].gst) {
+ /*
+ * The attribute should be committed even though video sink bin is not created yet.
+ * So, true should be returned here.
+ * Otherwise, video can be displayed abnormal.
+ */
+ return MM_ERROR_NONE;
+ }
+
+ if (g_strrstr(attribute_name, "display")) {
+ g_autofree char *param_name = g_strdup(attribute_name);
+ wfd_sink_debug("param_name: %s", param_name);
+ if (MM_ERROR_NONE != _mm_wfd_sink_update_video_param(wfd_sink, param_name)) {
+ wfd_sink_error("failed to update video param");
+ return MM_ERROR_WFD_INTERNAL;
+ }
+ }
+
+ wfd_sink_debug_fleave();
+
+ return MM_ERROR_NONE;
+}
+
int
_mmwfd_set_attribute(MMHandleType handle, char **err_attr_name, const char *attribute_name, va_list args_list)
{
return_val_if_fail(attribute_name, MM_ERROR_COMMON_INVALID_ARGUMENT);
return_val_if_fail(handle, MM_ERROR_COMMON_INVALID_ARGUMENT);
- attrs = handle;
+ attrs = MMWFDSINK_GET_ATTRS(handle);
return_val_if_fail(attrs, MM_ERROR_COMMON_INVALID_ARGUMENT);
return result;
}
- /*__mmwfd_apply_attribute(handle, attribute_name); */
+ /* Note: 'attr_commit' function is called before committing the new value to attr struct.
+ so if there is a value to apply after committing, it should be added below function. */
+ result = __mmwfd_apply_attribute(handle, attribute_name);
+ if (result != MM_ERROR_NONE) {
+ wfd_sink_error("failed to apply attributes\n");
+ return result;
+ }
wfd_sink_debug_fleave();
/* take it */
wfd_sink->pipeline->v_sinkbin = v_sinkbin;
+ /* configuring display */
+ if (_mm_wfd_sink_update_video_param(wfd_sink, "update_all_param") != MM_ERROR_NONE)
+ return MM_ERROR_WFD_INTERNAL;
+
wfd_sink_debug_fleave();
return MM_ERROR_NONE;
return MM_ERROR_NONE;
}
+static bool
+__mm_wfd_sink_video_param_check_video_sink_bin(mm_wfd_sink_t *wfd_sink)
+{
+ /* check video sinkbin is created */
+ wfd_sink_return_val_if_fail(wfd_sink &&
+ wfd_sink->pipeline &&
+ wfd_sink->pipeline->v_sinkbin &&
+ wfd_sink->pipeline->v_sinkbin[WFD_SINK_V_S_BIN].gst &&
+ wfd_sink->pipeline->v_sinkbin[WFD_SINK_V_S_SINK].gst,
+ false);
+
+ return true;
+}
+
+static void
+__mm_wfd_sink_video_param_set_display_rotation(mm_wfd_sink_t *wfd_sink)
+{
+ MMHandleType attrs = 0;
+ int rotation_value = 0;
+ wfd_sink_debug_fenter();
+
+ /* check video sinkbin is created */
+ if (!__mm_wfd_sink_video_param_check_video_sink_bin(wfd_sink))
+ return;
+
+ attrs = MMWFDSINK_GET_ATTRS(wfd_sink);
+ wfd_sink_return_if_fail(attrs);
+
+ mm_attrs_get_int_by_name(attrs, "display_rotate", &rotation_value);
+ rotation_value = (4 - rotation_value) % 4;
+ g_object_set(wfd_sink->pipeline->v_sinkbin[WFD_SINK_V_S_SINK].gst, "rotate", rotation_value, NULL);
+ wfd_sink_debug("set video param : rotate %d", rotation_value);
+}
+
+static void
+__mm_wfd_sink_video_param_set_display_visible(mm_wfd_sink_t *wfd_sink)
+{
+ MMHandleType attrs = 0;
+ int visible = 0;
+ wfd_sink_debug_fenter();
+
+ /* check video sinkbin is created */
+ if (!__mm_wfd_sink_video_param_check_video_sink_bin(wfd_sink))
+ return;
+
+ attrs = MMWFDSINK_GET_ATTRS(wfd_sink);
+ wfd_sink_return_if_fail(attrs);
+
+ mm_attrs_get_int_by_name(attrs, "display_visible", &visible);
+ g_object_set(wfd_sink->pipeline->v_sinkbin[WFD_SINK_V_S_SINK].gst, "visible", visible, NULL);
+ wfd_sink_debug("set video param : visible %d", visible);
+}
+
+static void
+__mm_wfd_sink_video_param_set_display_method(mm_wfd_sink_t *wfd_sink)
+{
+ MMHandleType attrs = 0;
+ int display_method = 0;
+ wfd_sink_debug_fenter();
+
+ /* check video sinkbin is created */
+ if (!__mm_wfd_sink_video_param_check_video_sink_bin(wfd_sink))
+ return;
+
+ attrs = MMWFDSINK_GET_ATTRS(wfd_sink);
+ wfd_sink_return_if_fail(attrs);
+
+ mm_attrs_get_int_by_name(attrs, "display_method", &display_method);
+ g_object_set(wfd_sink->pipeline->v_sinkbin[WFD_SINK_V_S_SINK].gst, "display-geometry-method", display_method, NULL);
+ wfd_sink_debug("set video param : method %d", display_method);
+}
+
+static void
+__mm_wfd_sink_video_param_set_render_rectangle(mm_wfd_sink_t *wfd_sink)
+{
+ MMHandleType attrs = 0;
+ int display_method = 0;
+ void *handle = NULL;
+ /*set wl_display*/
+ int wl_window_x = 0;
+ int wl_window_y = 0;
+ int wl_window_width = 0;
+ int wl_window_height = 0;
+ wfd_sink_debug_fenter();
+
+ /* check video sinkbin is created */
+ if (!__mm_wfd_sink_video_param_check_video_sink_bin(wfd_sink))
+ return;
+
+ attrs = MMWFDSINK_GET_ATTRS(wfd_sink);
+ wfd_sink_return_if_fail(attrs);
+
+ /* check roi mode is set */
+ mm_attrs_get_int_by_name(attrs, "display_method", &display_method);
+ if (display_method != MM_DISPLAY_METHOD_CUSTOM_ROI) {
+ wfd_sink_error("must be set display-geometry-method to MM_DISPLAY_METHOD_CUSTOM_ROI before setting render rectangle");
+ return;
+ }
+ mm_attrs_get_data_by_name(attrs, "display_overlay", &handle);
+ wfd_sink_return_if_fail(handle);
+
+ /*It should be set after setting window*/
+ mm_attrs_get_int_by_name(attrs, "display_roi_x", &wl_window_x);
+ mm_attrs_get_int_by_name(attrs, "display_roi_y", &wl_window_y);
+ mm_attrs_get_int_by_name(attrs, "display_roi_width", &wl_window_width);
+ mm_attrs_get_int_by_name(attrs, "display_roi_height", &wl_window_height);
+
+ /* After setting window handle, set render rectangle */
+ gst_video_overlay_set_display_roi_area(
+ GST_VIDEO_OVERLAY(wfd_sink->pipeline->v_sinkbin[WFD_SINK_V_S_SINK].gst),
+ wl_window_x, wl_window_y, wl_window_width, wl_window_height);
+ wfd_sink_debug("set video param : render rectangle : x(%d) y(%d) width(%d) height(%d)",
+ wl_window_x, wl_window_y, wl_window_width, wl_window_height);
+}
+
+static int
+__mm_wfd_sink_update_videosink_video_param(mm_wfd_sink_t* wfd_sink, const char *param_name)
+{
+ gboolean update_all_param = FALSE;
+ wfd_sink_debug_fenter();
+
+ /* check video sinkbin is created */
+ if (!__mm_wfd_sink_video_param_check_video_sink_bin(wfd_sink))
+ return MM_ERROR_WFD_NOT_INITIALIZED;
+
+ if(strcmp(wfd_sink->ini.name_of_video_sink, "tizenwlsink")) {
+ wfd_sink_error("invalid videosink [%s]", wfd_sink->ini.name_of_video_sink);
+ return MM_ERROR_WFD_INTERNAL;
+ }
+
+ wfd_sink_debug("param_name : %s", param_name);
+ update_all_param = (g_strcmp0(param_name, "update_all_param") == 0);
+
+ if (update_all_param || !g_strcmp0(param_name, "display_method"))
+ __mm_wfd_sink_video_param_set_display_method(wfd_sink);
+ if (update_all_param || !g_strcmp0(param_name, "display_visible"))
+ __mm_wfd_sink_video_param_set_display_visible(wfd_sink);
+ if (update_all_param || !g_strcmp0(param_name, "display_rotate"))
+ __mm_wfd_sink_video_param_set_display_rotation(wfd_sink);
+ if (update_all_param || !g_strcmp0(param_name, "display_roi_x"))
+ __mm_wfd_sink_video_param_set_render_rectangle(wfd_sink);
+
+ return MM_ERROR_NONE;
+}
+
+int
+_mm_wfd_sink_update_video_param(mm_wfd_sink_t* wfd_sink, const char *param_name)
+{
+ int surface_type = 0;
+ int ret = MM_ERROR_NONE;
+
+ wfd_sink_debug_fenter();
+
+ wfd_sink_return_val_if_fail(wfd_sink->pipeline->v_sinkbin[WFD_SINK_V_S_SINK].gst, MM_ERROR_WFD_INVALID_ARGUMENT);
+ wfd_sink_return_val_if_fail(wfd_sink && wfd_sink->attrs, MM_ERROR_WFD_NOT_INITIALIZED);
+
+ /* update display surface */
+ mm_attrs_get_int_by_name(wfd_sink->attrs, "display_surface_type", &surface_type);
+ wfd_sink_info("check display surface type attribute: %d", surface_type);
+
+ /* configuring display */
+ switch (surface_type) {
+ case MM_DISPLAY_SURFACE_EVAS:
+ {
+ void *object = NULL;
+ gint scaling = 0;
+ /* common case if using evas surface */
+ mm_attrs_get_data_by_name(wfd_sink->attrs, "display_overlay", &object);
+ mm_attrs_get_int_by_name(wfd_sink->attrs, "display_evas_do_scaling", &scaling);
+ if (!object) {
+ wfd_sink_error("no evas object");
+ return MM_ERROR_WFD_INTERNAL;
+ }
+ wfd_sink_debug("set video param : evas-object %p", object);
+ g_object_set(G_OBJECT(wfd_sink->pipeline->v_sinkbin[WFD_SINK_V_S_SINK].gst), "evas-object", object, NULL);
+ }
+ break;
+
+ case MM_DISPLAY_SURFACE_OVERLAY:
+ {
+ ret = __mm_wfd_sink_update_videosink_video_param(wfd_sink, param_name);
+ if (ret != MM_ERROR_NONE)
+ return ret;
+ }
+ break;
+
+ case MM_DISPLAY_SURFACE_NULL:
+ {
+ /* do nothing */
+ wfd_sink_error("Not Supported Surface.");
+ return MM_ERROR_WFD_INTERNAL;
+ }
+ break;
+ default:
+ {
+ wfd_sink_error("Not Supported Surface.(default case)");
+ return MM_ERROR_WFD_INTERNAL;
+ }
+ break;
+ }
+
+ wfd_sink_debug_fleave();
+
+ return MM_ERROR_NONE;
+}
+
int _mm_wfd_sink_set_src_device_type(mm_wfd_sink_t *wfd_sink, MMWFDSinkDeviceType device_type)
{
MMWFDSinkStateType cur_state = MM_WFD_SINK_STATE_NONE;