From: Hyunil Date: Tue, 23 Aug 2016 07:47:58 +0000 (+0900) Subject: waylandsink : 1. apply tizen view port. X-Git-Tag: accepted/tizen/unified/20220217.153506~2^2~10^2~9^2~12^2~2^2~181 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=f1ae2ed1dfe9bb40e53921c203160fbc1797e0d6;p=platform%2Fupstream%2Fgstreamer.git waylandsink : 1. apply tizen view port. 2. support using full window size for rendering without gst_video_overlay_set_render_rectangle(). 3. gst-launch can use full window size for convenient test. 4. Add new property (follow-parent-transform, corp(x, y, w, h) ratio(w, h), scale(w, h), align(w, h), offset(x, y, w, h)). Change-Id: I8236d1f4d3fb147a6d0fcda47e417d16e68cdb92 Signed-off-by: Hyunil --- diff --git a/ext/wayland/gstwaylandsink.c b/ext/wayland/gstwaylandsink.c index 2ca38e8..a526750 100755 --- a/ext/wayland/gstwaylandsink.c +++ b/ext/wayland/gstwaylandsink.c @@ -97,7 +97,8 @@ gst_waylandsink_display_geometry_method_get_type (void) {2, "Full-screen", "FULL_SCREEN"}, {3, "Cropped full-screen", "CROPPED_FULL_SCREEN"}, {4, "Origin size(if screen size is larger than video size(width/height)) or Letter box(if video size(width/height) is larger than screen size)", "ORIGIN_SIZE_OR_LETTER_BOX"}, - {5, NULL, NULL}, + {5, "Specially described destination ROI", "DISP_GEO_METHOD_CUSTOM_ROI"}, + {6, NULL, NULL}, }; if (!waylandsink_display_geometry_method_type) { @@ -148,9 +149,23 @@ enum PROP_USE_TBM, PROP_ROTATE_ANGLE, PROP_DISPLAY_GEOMETRY_METHOD, - PROP_ORIENTATION, PROP_FLIP, - PROP_VISIBLE + PROP_VISIBLE, + PROP_FOLLOW_PARENT_TRANSFORM, + PROP_CROP_X, + PROP_CROP_Y, + PROP_CROP_WIDTH, + PROP_CROP_HEIGHT, + PROP_RATIO_WIDTH, + PROP_RATIO_HEIGHT, + PROP_SCALE_WIDTH, + PROP_SCALE_HEIGHT, + PROP_OFFSET_X, + PROP_OFFSET_Y, + PROP_OFFSET_WIDTH, + PROP_OFFSET_HEIGHT, + PROP_ALIGN_WIDTH, + PROP_ALIGN_HEIGHT #endif }; int dump__cnt = 0; @@ -291,13 +306,6 @@ gst_wayland_sink_class_init (GstWaylandSinkClass * klass) DEF_DISPLAY_GEOMETRY_METHOD, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (gobject_class, PROP_ORIENTATION, - g_param_spec_enum ("orientation", - "Orientation information used for ROI/ZOOM", - "Orientation information for display", - GST_TYPE_WAYLANDSINK_ROTATE_ANGLE, DEGREE_0, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (gobject_class, PROP_FLIP, g_param_spec_enum ("flip", "Display flip", "Flip for display", @@ -308,6 +316,114 @@ gst_wayland_sink_class_init (GstWaylandSinkClass * klass) g_param_spec_boolean ("visible", "Visible", "Draws screen or blacks out, true means visible, false blacks out", TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, PROP_FOLLOW_PARENT_TRANSFORM, + g_param_spec_boolean ("follow-parent-transform", + "follow parent transform", + "Video is rotated automatically without setting rotate property by rotating Display" + "Function is not supported in DISP_GEO_METHOD_CUSTOM_ROI. ", TRUE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, PROP_CROP_X, + g_param_spec_uint ("crop-x", "crop x", + "x-coordinate for cropping video. " + "Please set crop-x, crop-y, crop-w and crop-h togethrer. " + "Function is not supported in DISP_GEO_METHOD_CUSTOM_ROI. ", 0, + G_MAXUINT, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, PROP_CROP_Y, + g_param_spec_uint ("crop-y", "crop y", + "y-coordinate for cropping video. " + "Please set crop-x, crop-y, crop-w and crop-h togethrer. " + "Function is not supported in DISP_GEO_METHOD_CUSTOM_ROI. ", 0, + G_MAXUINT, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, PROP_CROP_WIDTH, + g_param_spec_uint ("crop-w", "crop width", + "width for cropping video. " + "If value is not set or is set 0, Width is set to video width after set_caps. " + "Please set crop-x, crop-y, crop-w and crop-h togethrer. " + "Function is not supported in DISP_GEO_METHOD_CUSTOM_ROI. ", 0, + G_MAXUINT, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, PROP_CROP_HEIGHT, + g_param_spec_uint ("crop-h", "crop height", + "height for cropping video. " + "If value is not set or is set 0, Hight is set to video height after set_caps. " + "Please set crop-x, crop-y, crop-w and crop-h togethrer. " + "Function is not supported in DISP_GEO_METHOD_CUSTOM_ROI. ", 0, + G_MAXUINT, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, PROP_RATIO_WIDTH, + g_param_spec_double ("ratio-w", "ratio width", + "ratio width for rendering video," + "If value is set, Original video ratio is ignored. to restore original size, set to -1" + "Please set ratio-w and ratio-h togethrer. " + "Function is not supported in DISP_GEO_METHOD_CUSTOM_ROI. ", -1.0, + G_MAXDOUBLE, -1.0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, PROP_RATIO_HEIGHT, + g_param_spec_double ("ratio-h", "ratio height", + "ratio width for rendering video, " + "If value is set, Original video ratio is ignored. to restore original size, set to -1" + "Please set ratio-w and ratio-h togethrer. " + "Function is not support in DISP_GEO_METHOD_CUSTOM_ROI. ", -1.0, + G_MAXDOUBLE, -1.0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, PROP_SCALE_WIDTH, + g_param_spec_double ("scale-w", "ratio width", + "scale width for rendering video," + "Function is not supported in DISP_GEO_METHOD_CUSTOM_ROI. ", 0.0, + G_MAXDOUBLE, 1.0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, PROP_SCALE_HEIGHT, + g_param_spec_double ("scale-h", "scale height", + "scale width for rendering video, " + "Function is not support in DISP_GEO_METHOD_CUSTOM_ROI. ", 0.0, + G_MAXDOUBLE, 1.0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, PROP_OFFSET_X, + g_param_spec_uint ("offset-x", "offset x", + "x offset for moving x-coordinate of video pixel, " + "Please set x, y, w and h offset togethrer" + "Function is not supported in DISP_GEO_METHOD_CUSTOM_ROI. ", 0, + G_MAXUINT, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, PROP_OFFSET_Y, + g_param_spec_uint ("offset-y", "offset y", + "y offset for moving y-coordinate of video pixel, " + "Please set x, y, w and h offset togethrer" + "Function is not supported in DISP_GEO_METHOD_CUSTOM_ROI. ", 0, + G_MAXUINT, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, PROP_OFFSET_WIDTH, + g_param_spec_uint ("offset-w", "offset width", + "width offset for adjusting width of of video pixel, " + "Please set x, y, w and h offset togethrer" + "Function is not supported in DISP_GEO_METHOD_CUSTOM_ROI. ", 0, + G_MAXUINT, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, PROP_OFFSET_HEIGHT, + g_param_spec_uint ("offset-h", "offset height", + "height offset for adjusting height of of video pixel" + "Please set x, y, w and h offset togethrer" + "Function is not supported in DISP_GEO_METHOD_CUSTOM_ROI. ", 0, + G_MAXUINT, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, PROP_ALIGN_WIDTH, + g_param_spec_double ("align-w", "align width", + "Align with, Left: 0.0, Middle: 0.5, Right: 1.0 \n" + "Please set align-w and align-h togethrer" + "Function is not supported in DISP_GEO_METHOD_CUSTOM_ROI. ", 0.0, + 1.0, 0.5, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, PROP_ALIGN_HEIGHT, + g_param_spec_double ("align-h", "align height", + "Align height, Left: 0.0, Middle: 0.5, Right: 1.0 \n" + "Please set align-w and align-h togethrer" + "Function is not supported in DISP_GEO_METHOD_CUSTOM_ROI. ", 0.0, + 1.0, 0.5, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + #endif } @@ -338,8 +454,13 @@ gst_wayland_sink_init (GstWaylandSink * sink) sink->display_geometry_method = DEF_DISPLAY_GEOMETRY_METHOD; sink->flip = DEF_DISPLAY_FLIP; sink->rotate_angle = DEGREE_0; - sink->orientation = DEGREE_0; sink->visible = TRUE; + sink->follow_parent_transform = FALSE; + sink->crop_x = sink->crop_y = sink->crop_w = sink->crop_h = 0; + sink->ratio_w = sink->ratio_h = -1.0; //need to set -1.0 for original video ratio + sink->scale_w = sink->scale_h = 1.0; + sink->align_w = sink->align_h = 0.5; + sink->offset_x = sink->offset_y = sink->offset_w = sink->offset_h = 0; #endif g_mutex_init (&sink->display_lock); g_mutex_init (&sink->render_lock); @@ -385,12 +506,13 @@ static void gst_wayland_sink_update_last_buffer_geometry (GstWaylandSink * sink) { GstWlBuffer *wlbuffer; + gboolean no_render_buffer = FALSE; FUNCTION; g_return_if_fail (sink != NULL); g_return_if_fail (sink->last_buffer != NULL); wlbuffer = gst_buffer_get_wl_buffer (sink->last_buffer); + g_return_if_fail (wlbuffer != NULL); - gboolean no_render_buffer = FALSE; if (wlbuffer->used_by_compositor) { /* used last buffer by compositor don't receive buffer-release-event when attach */ @@ -470,7 +592,7 @@ gst_wayland_sink_make_flush_buffer (GstWlDisplay * display, strerror (errno)); return FALSE; } - GST_INFO ("flush buffer tbm_bo =(%p)", bo); + GST_LOG ("flush buffer tbm_bo =(%p)", bo); flush_buffer->bo[i] = bo; /* get virtual address */ src.ptr = dst.ptr = NULL; @@ -519,7 +641,7 @@ gst_wayland_sink_copy_mm_video_buf_info_to_flush (GstWlDisplay * display, display->stride_height[i] = mm_video_buf->stride_height[i]; display->native_video_size += display->plane_size[i]; } - memset (mm_video_buf, 0, sizeof(MMVideoBuffer)); + memset (mm_video_buf, 0, sizeof (MMVideoBuffer)); } return ret; } @@ -574,8 +696,8 @@ gst_wayland_sink_get_mm_video_buf_info (GstWaylandSink * sink, } /* assign mm_video_buf info */ if (mm_video_buf->type == MM_VIDEO_BUFFER_TYPE_TBM_BO) { - GST_DEBUG ("TBM bo %p %p %p", mm_video_buf->handle.bo[0], - mm_video_buf->handle.bo[1], mm_video_buf->handle.bo[2]); + GST_DEBUG ("TBM bo %p %p", mm_video_buf->handle.bo[0], + mm_video_buf->handle.bo[1]); display->native_video_size = 0; display->flush_request = mm_video_buf->flush_request; GST_DEBUG ("flush_request value is %d", display->flush_request); @@ -658,15 +780,57 @@ gst_wayland_sink_get_property (GObject * object, case PROP_DISPLAY_GEOMETRY_METHOD: g_value_set_enum (value, sink->display_geometry_method); break; - case PROP_ORIENTATION: - g_value_set_enum (value, sink->orientation); - break; case PROP_FLIP: g_value_set_enum (value, sink->flip); break; case PROP_VISIBLE: g_value_set_boolean (value, sink->visible); break; + case PROP_FOLLOW_PARENT_TRANSFORM: + g_value_set_boolean (value, sink->follow_parent_transform); + break; + case PROP_CROP_X: + g_value_set_uint (value, sink->crop_x); + break; + case PROP_CROP_Y: + g_value_set_uint (value, sink->crop_y); + break; + case PROP_CROP_WIDTH: + g_value_set_uint (value, sink->crop_w); + break; + case PROP_CROP_HEIGHT: + g_value_set_uint (value, sink->crop_h); + break; + case PROP_RATIO_WIDTH: + g_value_set_double (value, sink->ratio_w); + break; + case PROP_RATIO_HEIGHT: + g_value_set_double (value, sink->ratio_h); + break; + case PROP_SCALE_WIDTH: + g_value_set_double (value, sink->scale_w); + break; + case PROP_SCALE_HEIGHT: + g_value_set_double (value, sink->scale_h); + break; + case PROP_OFFSET_X: + g_value_set_uint (value, sink->offset_x); + break; + case PROP_OFFSET_Y: + g_value_set_uint (value, sink->offset_y); + break; + case PROP_OFFSET_WIDTH: + g_value_set_uint (value, sink->offset_w); + break; + case PROP_OFFSET_HEIGHT: + g_value_set_uint (value, sink->offset_h); + break; + case PROP_ALIGN_WIDTH: + g_value_set_double (value, sink->align_w); + break; + case PROP_ALIGN_HEIGHT: + g_value_set_double (value, sink->align_h); + break; #endif default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -715,20 +879,10 @@ gst_wayland_sink_set_property (GObject * object, sink->display_geometry_method); sink->video_info_changed = TRUE; if (sink->window) { - gst_wl_window_set_disp_geo_method (sink->window, + gst_wl_window_set_destination_mode (sink->window, sink->display_geometry_method); } break; - case PROP_ORIENTATION: - if (sink->orientation == g_value_get_enum (value)) - break; - sink->orientation = g_value_get_enum (value); - GST_WARNING_OBJECT (sink, "Orientation is set (%d)", sink->orientation); - sink->video_info_changed = TRUE; - if (sink->window) { - gst_wl_window_set_orientation (sink->window, sink->orientation); - } - break; case PROP_FLIP: if (sink->flip == g_value_get_enum (value)) break; @@ -754,6 +908,141 @@ gst_wayland_sink_set_property (GObject * object, } } break; + case PROP_FOLLOW_PARENT_TRANSFORM: + if (sink->follow_parent_transform == g_value_get_boolean (value) + || sink->display_geometry_method == DISP_GEO_METHOD_CUSTOM_ROI) + break; + sink->follow_parent_transform = g_value_get_boolean (value); + GST_WARNING_OBJECT (sink, "follow parent transform is set (%d)", + sink->follow_parent_transform); + sink->video_info_changed = TRUE; + if (sink->window) { + gst_wl_window_set_destination_mode_follow_parent_transform + (sink->window, sink->follow_parent_transform); + } + break; + case PROP_CROP_X: + if (sink->display_geometry_method == DISP_GEO_METHOD_CUSTOM_ROI) + break; + sink->crop_x = g_value_get_uint (value); + GST_WARNING_OBJECT (sink, "crop-x is set (%d)", sink->crop_x); + break; + case PROP_CROP_Y: + if (sink->display_geometry_method == DISP_GEO_METHOD_CUSTOM_ROI) + break; + sink->crop_y = g_value_get_uint (value); + GST_WARNING_OBJECT (sink, "crop-y is set (%d)", sink->crop_y); + break; + case PROP_CROP_WIDTH: + if (sink->display_geometry_method == DISP_GEO_METHOD_CUSTOM_ROI) + break; + sink->crop_w = g_value_get_uint (value); + GST_WARNING_OBJECT (sink, "crop_w is set (%d)", sink->crop_w); + /* crop-w is unset by 0, set to video width size */ + if (sink->crop_w == 0 && sink->video_info.width > 0) { + sink->crop_w = + gst_util_uint64_scale_int_round (sink->video_info.width, + sink->video_info.par_n, sink->video_info.par_d); + GST_LOG ("crop-w is unset by 0, set to video width size(%d)", + sink->crop_w); + } + break; + case PROP_CROP_HEIGHT: + if (sink->display_geometry_method == DISP_GEO_METHOD_CUSTOM_ROI) + break; + sink->crop_h = g_value_get_uint (value); + GST_WARNING_OBJECT (sink, "crop-h is set (%d)", sink->crop_h); + /* crop-h unset by 0, set to video height size */ + if (sink->crop_h == 0 && sink->video_info.height > 0) { + sink->crop_h = sink->video_info.height; + GST_LOG ("crop-h is unset by 0, set to video height size(%d)", + sink->crop_h); + } + sink->video_info_changed = TRUE; + if (sink->window && sink->crop_w > 0 && sink->crop_h > 0) { + gst_wl_window_set_destination_mode_crop_wl_buffer (sink->window, + sink->crop_x, sink->crop_y, sink->crop_w, sink->crop_h); + } + break; + case PROP_RATIO_WIDTH: + if (sink->display_geometry_method == DISP_GEO_METHOD_CUSTOM_ROI) + break; + sink->ratio_w = g_value_get_double (value); + GST_WARNING_OBJECT (sink, "ratio-w is set (%f)", sink->ratio_w); + break; + case PROP_RATIO_HEIGHT: + if (sink->scale_w == g_value_get_double (value) + || sink->display_geometry_method == DISP_GEO_METHOD_CUSTOM_ROI) + break; + sink->ratio_h = g_value_get_double (value); + GST_WARNING_OBJECT (sink, "ratio-h is set (%f)", sink->ratio_h); + sink->video_info_changed = TRUE; + if (sink->window) + gst_wl_window_set_destination_mode_ratio (sink->window, sink->ratio_w, + sink->ratio_h); + break; + case PROP_SCALE_WIDTH: + if (sink->scale_w == g_value_get_double (value) + || sink->display_geometry_method == DISP_GEO_METHOD_CUSTOM_ROI) + break; + sink->scale_w = g_value_get_double (value); + GST_WARNING_OBJECT (sink, "scale-h is set (%f)", sink->scale_w); + sink->video_info_changed = TRUE; + if (sink->window) + gst_wl_window_set_destination_mode_scale (sink->window, sink->ratio_w, + sink->ratio_h); + break; + case PROP_OFFSET_X: + if (sink->offset_x == g_value_get_uint (value) + || sink->display_geometry_method == DISP_GEO_METHOD_CUSTOM_ROI) + break; + sink->offset_x = g_value_get_uint (value); + GST_WARNING_OBJECT (sink, "offset-x is set (%d)", sink->offset_x); + break; + case PROP_OFFSET_Y: + if (sink->offset_y == g_value_get_uint (value) + || sink->display_geometry_method == DISP_GEO_METHOD_CUSTOM_ROI) + break; + sink->offset_y = g_value_get_uint (value); + GST_WARNING_OBJECT (sink, "offset-y is set (%d)", sink->offset_y); + break; + case PROP_OFFSET_WIDTH: + if (sink->offset_w == g_value_get_uint (value) + || sink->display_geometry_method == DISP_GEO_METHOD_CUSTOM_ROI) + break; + sink->offset_w = g_value_get_uint (value); + GST_WARNING_OBJECT (sink, "offset-w is set (%d)", sink->offset_w); + break; + case PROP_OFFSET_HEIGHT: + if (sink->offset_h == g_value_get_uint (value) + || sink->display_geometry_method == DISP_GEO_METHOD_CUSTOM_ROI) + break; + sink->offset_h = g_value_get_uint (value); + GST_WARNING_OBJECT (sink, "offset-h is set (%d)", sink->offset_h); + sink->video_info_changed = TRUE; + if (sink->window) + gst_wl_window_set_destination_mode_offset (sink->window, sink->offset_x, + sink->offset_y, sink->offset_w, sink->offset_h); + break; + case PROP_ALIGN_WIDTH: + if (sink->align_w == g_value_get_double (value) + || sink->display_geometry_method == DISP_GEO_METHOD_CUSTOM_ROI) + break; + sink->align_w = g_value_get_double (value); + GST_WARNING_OBJECT (sink, "align_w is set (%f)", sink->align_w); + break; + case PROP_ALIGN_HEIGHT: + if (sink->align_h == g_value_get_double (value) + || sink->display_geometry_method == DISP_GEO_METHOD_CUSTOM_ROI) + break; + sink->align_h = g_value_get_double (value); + GST_WARNING_OBJECT (sink, "align_h is set (%f)", sink->align_h); + sink->video_info_changed = TRUE; + if (sink->window) + gst_wl_window_set_destination_mode_align (sink->window, sink->align_w, + sink->align_h); + break; + #endif default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -1111,9 +1400,9 @@ gst_wayland_sink_set_caps (GstBaseSink * bsink, GstCaps * caps) GstBufferPool *newpool; GstVideoInfo info; #ifdef GST_WLSINK_ENHANCEMENT - uint32_t tbm_format; + uint32_t tbm_format = -1; #endif - enum wl_shm_format format; + enum wl_shm_format format = -1; GArray *formats; gint i; @@ -1150,14 +1439,14 @@ gst_wayland_sink_set_caps (GstBaseSink * bsink, GstCaps * caps) /* verify we support the requested format */ #ifdef GST_WLSINK_ENHANCEMENT if (sink->display->USE_TBM) { - GST_INFO ("USE TBM FORMAT"); + GST_LOG ("USE TBM FORMAT"); formats = sink->display->tbm_formats; for (i = 0; i < formats->len; i++) { if (g_array_index (formats, uint32_t, i) == tbm_format) break; } } else { /* USE SHM */ - GST_INFO ("USE SHM FORMAT"); + GST_LOG ("USE SHM FORMAT"); formats = sink->display->formats; for (i = 0; i < formats->len; i++) { if (g_array_index (formats, uint32_t, i) == format) @@ -1231,6 +1520,11 @@ gst_wayland_sink_set_caps (GstBaseSink * bsink, GstCaps * caps) gst_object_replace ((GstObject **) & sink->pool, (GstObject *) newpool); gst_object_unref (newpool); } +#ifdef GST_WLSINK_ENHANCEMENT + if (sink->window) + gst_wayland_sink_update_window_geometry (sink); +#endif + #else /*open source */ /* create a new pool for the new configuration */ newpool = gst_video_buffer_pool_new (); @@ -1341,6 +1635,7 @@ frame_redraw_callback (void *data, struct wl_callback *callback, uint32_t time) GST_LOG ("frame_redraw_cb"); g_atomic_int_set (&sink->redraw_pending, FALSE); + GST_INFO ("wl_callback_destroy (wl_callback@%p)", callback); wl_callback_destroy (callback); } @@ -1357,10 +1652,29 @@ gst_wayland_sink_update_window_geometry (GstWaylandSink * sink) g_return_if_fail (sink->window != NULL); gst_wl_window_set_rotate_angle (sink->window, sink->rotate_angle); - gst_wl_window_set_disp_geo_method (sink->window, + gst_wl_window_set_destination_mode (sink->window, sink->display_geometry_method); - gst_wl_window_set_orientation (sink->window, sink->orientation); gst_wl_window_set_flip (sink->window, sink->flip); + gst_wl_window_set_destination_mode_follow_parent_transform (sink->window, + sink->follow_parent_transform); + + if (sink->crop_w == 0 && sink->crop_h == 0) { + sink->crop_w = + gst_util_uint64_scale_int_round (sink->video_info.width, + sink->video_info.par_n, sink->video_info.par_d); + sink->crop_h = sink->video_info.height; + } + gst_wl_window_set_destination_mode_crop_wl_buffer (sink->window, sink->crop_x, + sink->crop_y, sink->crop_w, sink->crop_h); + gst_wl_window_set_destination_mode_ratio (sink->window, sink->ratio_w, + sink->ratio_h); + gst_wl_window_set_destination_mode_scale (sink->window, sink->scale_w, + sink->scale_h); + gst_wl_window_set_destination_mode_offset (sink->window, sink->offset_x, + sink->offset_y, sink->offset_w, sink->offset_h); + gst_wl_window_set_destination_mode_align (sink->window, sink->align_w, + sink->align_h); + } #endif /* must be called with the render lock */ @@ -1382,7 +1696,13 @@ render_last_buffer (GstWaylandSink * sink) g_atomic_int_set (&sink->redraw_pending, TRUE); callback = wl_surface_frame (surface); + GST_INFO ("wl_callback@%p = wl_surface_frame (video_surface@%p)", callback, + surface); + /* frame_callback_listener is called when wayland-client finish rendering the wl_buffer */ + GST_INFO + ("wl_callback_add_listener (wl_callback@%p, wl_callback_listener@%p, GstWaylandSink@%p)", + callback, &frame_callback_listener, sink); wl_callback_add_listener (callback, &frame_callback_listener, sink); if (G_UNLIKELY (sink->video_info_changed)) { @@ -1426,12 +1746,15 @@ gst_wayland_sink_render (GstBaseSink * bsink, GstBuffer * buffer) #endif } /* drop buffers until we get a frame callback */ - if (g_atomic_int_get (&sink->redraw_pending) == TRUE && !gst_wayland_sink_check_use_gapless (sink)) + if (g_atomic_int_get (&sink->redraw_pending) == TRUE + && !gst_wayland_sink_check_use_gapless (sink)) goto done; + +#ifndef GST_WLSINK_ENHANCEMENT /* for tizen view_port, we don't know window size */ /* make sure that the application has called set_render_rectangle() */ if (G_UNLIKELY (sink->window->render_rectangle.w == 0)) goto no_window_size; - +#endif #ifdef GST_WLSINK_ENHANCEMENT wlbuffer = gst_buffer_get_wl_buffer (buffer); @@ -1439,7 +1762,7 @@ gst_wayland_sink_render (GstBaseSink * bsink, GstBuffer * buffer) && !(gst_wayland_sink_check_use_gapless (sink)) && !sink->keep_camera_preview) { GST_LOG_OBJECT (sink, "buffer %p has a wl_buffer from our display, " "writing directly", buffer); //buffer is from our pool and have wl_buffer - GST_INFO ("wl_buffer (%p)", wlbuffer->wlbuffer); + GST_LOG ("wl_buffer (%p)", wlbuffer->wlbuffer); to_render = buffer; #ifdef DUMP_BUFFER GstMemory *mem; @@ -1458,7 +1781,7 @@ gst_wayland_sink_render (GstBaseSink * bsink, GstBuffer * buffer) if (ret) { GST_ERROR ("_write_rawdata() failed"); } - GST_INFO ("DUMP IMAGE %d, size (%d)", dump__cnt, size); + GST_LOG ("DUMP IMAGE %d, size (%d)", dump__cnt, size); gst_memory_unmap (mem, &mem_info); #endif } else { @@ -1517,7 +1840,7 @@ gst_wayland_sink_render (GstBaseSink * bsink, GstBuffer * buffer) //GstMemory *mem; //mem = gst_buffer_peek_memory (to_render, 0); //if (gst_is_wl_shm_memory (mem)) { - GST_INFO ("to_render buffer is our buffer"); + GST_LOG ("to_render buffer is our buffer"); //} /* the first time we acquire a buffer, * we need to attach a wl_buffer on it */ @@ -1617,7 +1940,7 @@ gst_wayland_sink_render (GstBaseSink * bsink, GstBuffer * buffer) GST_LOG_OBJECT (sink, "buffer %p has a wl_buffer from our display, " "writing directly", buffer); - GST_INFO ("wl_buffer (%p)", wlbuffer->wlbuffer); + GST_LOG ("wl_buffer (%p)", wlbuffer->wlbuffer); to_render = buffer; } else { @@ -1690,6 +2013,7 @@ gst_wayland_sink_render (GstBaseSink * bsink, GstBuffer * buffer) #endif /* GST_WLSINK_ENHANCEMENT */ +#ifndef GST_WLSINK_ENHANCEMENT no_window_size: { GST_ELEMENT_ERROR (sink, RESOURCE, WRITE, @@ -1698,6 +2022,7 @@ no_window_size: ret = GST_FLOW_ERROR; goto done; } +#endif no_buffer: { GST_WARNING_OBJECT (sink, "could not create buffer"); @@ -1734,7 +2059,8 @@ gst_wayland_sink_videooverlay_init (GstVideoOverlayInterface * iface) #endif } -#ifdef GST_WLSINK_ENHANCEMENT /* use unique_id */ +#ifdef GST_WLSINK_ENHANCEMENT +/* use unique_id */ static void gst_wayland_sink_set_wl_window_wl_surface_id (GstVideoOverlay * overlay, guintptr wl_surface_id) @@ -1750,7 +2076,7 @@ gst_wayland_sink_set_wl_window_wl_surface_id (GstVideoOverlay * overlay, g_mutex_lock (&sink->render_lock); g_clear_object (&sink->window); - GST_INFO ("wl_surface_id %d %x", (int) wl_surface_id, + GST_LOG ("wl_surface_id %d %x", (int) wl_surface_id, (guintptr) wl_surface_id); if (wl_surface_id) { @@ -1765,7 +2091,6 @@ gst_wayland_sink_set_wl_window_wl_surface_id (GstVideoOverlay * overlay, "ignoring window handle"); } } - gst_wayland_sink_update_window_geometry (sink); g_mutex_unlock (&sink->render_lock); } @@ -1811,11 +2136,7 @@ gst_wayland_sink_set_window_handle (GstVideoOverlay * overlay, guintptr handle) "ignoring window handle"); } } -#ifdef GST_WLSINK_ENHANCEMENT - gst_wayland_sink_update_window_geometry (sink); -#endif g_mutex_unlock (&sink->render_lock); - } static void diff --git a/ext/wayland/gstwaylandsink.h b/ext/wayland/gstwaylandsink.h index 6804639..8e43c53 100644 --- a/ext/wayland/gstwaylandsink.h +++ b/ext/wayland/gstwaylandsink.h @@ -51,6 +51,7 @@ enum DISP_GEO_METHOD_FULL_SCREEN, DISP_GEO_METHOD_CROPPED_FULL_SCREEN, DISP_GEO_METHOD_ORIGIN_SIZE_OR_LETTER_BOX, + DISP_GEO_METHOD_CUSTOM_ROI, DISP_GEO_METHOD_NUM, }; @@ -99,12 +100,17 @@ struct _GstWaylandSink #ifdef GST_WLSINK_ENHANCEMENT gboolean keep_camera_preview; gboolean got_costum_event; + gboolean visible; + gboolean follow_parent_transform; gboolean USE_TBM; guint rotate_angle; guint display_geometry_method; - guint orientation; guint flip; - gboolean visible; + guint crop_x, crop_y, crop_w, crop_h; + guint offset_x, offset_y, offset_w, offset_h; + gdouble ratio_w, ratio_h; + gdouble scale_w, scale_h; + gdouble align_w, align_h; #endif }; diff --git a/ext/wayland/wlbuffer.c b/ext/wayland/wlbuffer.c index 26c9114..8f5a4f7 100644 --- a/ext/wayland/wlbuffer.c +++ b/ext/wayland/wlbuffer.c @@ -91,7 +91,7 @@ gst_wl_buffer_dispose (GObject * gobject) { GstWlBuffer *self = GST_WL_BUFFER (gobject); FUNCTION; - GST_INFO ("GstWlBuffer:%p", self); + GST_LOG ("GstWlBuffer:%p", self); GST_TRACE_OBJECT (self, "dispose"); /* if the display is shutting down and we are trying to dipose @@ -115,12 +115,12 @@ gst_wl_buffer_finalize (GObject * gobject) GST_TRACE_OBJECT (self, "finalize"); #ifdef GST_WLSINK_ENHANCEMENT if (self->tsurface) { - GST_INFO ("self->tsurface:%p", self->tsurface); + GST_LOG ("tbm_surface_destroy (tbm_surface_h@%p)", self->tsurface); tbm_surface_destroy (self->tsurface); } #endif if (self->wlbuffer) { - GST_INFO ("self->wl_buffer:%p", self->wlbuffer); + GST_INFO ("wl_buffer_destroy (wl_buffer@%p)", self->wlbuffer); wl_buffer_destroy (self->wlbuffer); } #ifdef USE_WL_FLUSH_BUFFER @@ -130,6 +130,7 @@ gst_wl_buffer_finalize (GObject * gobject) self->display->flush_tbm_bufmgr = NULL; for (i = 0; i < NV_BUF_PLANE_NUM; i++) { if (self->display->flush_buffer->bo[i]) { + GST_LOG ("tbm_bo_unref (bo@%p)", self->display->flush_buffer->bo[i]); tbm_bo_unref (self->display->flush_buffer->bo[i]); self->display->flush_buffer->bo[i] = NULL; } @@ -164,8 +165,8 @@ buffer_release (void *data, struct wl_buffer *wl_buffer) FUNCTION; g_return_if_fail (self != NULL); - GST_LOG_OBJECT (self, - "get event : wl_buffer(%p)::release (GstBuffer: %p):: tsurface(%p)", + GST_INFO_OBJECT (self, + "get event : wl_buffer@%p ::release GstBuffer@%p:: tsurface@%p", wl_buffer, self->gstbuffer, self->tsurface); self->used_by_compositor = FALSE; @@ -233,7 +234,7 @@ gst_buffer_add_wl_buffer (GstBuffer * gstbuffer, struct wl_buffer *wlbuffer, self->tsurface = display->tsurface; else self->tsurface = NULL; - GST_INFO ("self->tsurface(%p)", self->tsurface); + GST_LOG ("self->tsurface(%p)", self->tsurface); #endif #ifdef USE_WL_FLUSH_BUFFER self->is_flush_request = FALSE; @@ -243,13 +244,16 @@ gst_buffer_add_wl_buffer (GstBuffer * gstbuffer, struct wl_buffer *wlbuffer, gst_wl_display_register_buffer (self->display, self); //register GstWlBuffer + GST_INFO + ("wl_buffer_add_listener (wl_buffer@%p, wl_buffer_listener@%p, GstWlBuffer@%p)", + self->wlbuffer, &buffer_listener, self); wl_buffer_add_listener (self->wlbuffer, &buffer_listener, self); #ifdef GST_WLSINK_ENHANCEMENT //need to contribute to upstream !! wl_proxy_set_queue ((struct wl_proxy *) self->wlbuffer, self->display->queue); #endif gst_mini_object_set_qdata ((GstMiniObject *) gstbuffer, gst_wl_buffer_qdata_quark (), self, (GDestroyNotify) gstbuffer_disposed); - GST_INFO ("GstWlBuffer (%p)", self); + GST_LOG ("GstWlBuffer (%p)", self); return self; } @@ -288,7 +292,7 @@ gst_wl_buffer_force_release_and_unref (GstWlBuffer * self) self->wlbuffer = NULL; self->display = NULL; #ifdef GST_WLSINK_ENHANCEMENT - GST_INFO ("self->tsurface(%p)", self->tsurface); + GST_LOG ("self->tsurface(%p)", self->tsurface); if (self->tsurface) tbm_surface_destroy (self->tsurface); #endif @@ -301,7 +305,8 @@ gst_wl_buffer_attach (GstWlBuffer * self, struct wl_surface *surface) { FUNCTION; g_return_if_fail (self->used_by_compositor == FALSE); - + GST_INFO ("wl_surface_attach (video_surface@%p, wl_buffer@%p, 0, 0)", surface, + self->wlbuffer); wl_surface_attach (surface, self->wlbuffer, 0, 0); /* Add a reference to the buffer. This represents the fact that diff --git a/ext/wayland/wldisplay.c b/ext/wayland/wldisplay.c index 98686ac..11caf6d 100644 --- a/ext/wayland/wldisplay.c +++ b/ext/wayland/wldisplay.c @@ -44,11 +44,11 @@ handle_tizen_video_format (void *data, struct tizen_video *tizen_video, g_return_if_fail (self != NULL); - GST_INFO ("format is %d", format); + GST_LOG ("format is %d", format); g_array_append_val (self->tbm_formats, format); } -static const struct tizen_video_listener tz_video_listener = { +static const struct tizen_video_listener tizen_video_listener = { handle_tizen_video_format }; #endif @@ -186,10 +186,22 @@ gst_wl_display_roundtrip (GstWlDisplay * self) /* We don't own the display, process only our queue */ callback = wl_display_sync (self->display); + GST_INFO ("wl_callback@%p = wl_display_sync (wl_display@%p)", callback, + self->display); wl_callback_add_listener (callback, &sync_listener, &done); + GST_INFO + ("wl_callback_add_listener (wl_callback@%p, wl_callback_listener@%p, done@%p)", + callback, &sync_listener, &done); wl_proxy_set_queue ((struct wl_proxy *) callback, self->queue); - while (ret != -1 && !done) + GST_INFO ("wl_proxy_set_queue (wl_callback@%p, wl_event_queue@%p)", callback, + self->queue); + while (ret != -1 && !done) { ret = wl_display_dispatch_queue (self->display, self->queue); + GST_INFO + ("ret(%d) = wl_display_dispatch_queue (wl_display@%p, wl_event_queue@%p)", + ret, self->display, self->queue); + } + GST_INFO ("wl_callback_destroy (wl_callback@%p)", callback); wl_callback_destroy (callback); return ret; @@ -216,28 +228,57 @@ registry_handle_global (void *data, struct wl_registry *registry, if (g_strcmp0 (interface, "wl_compositor") == 0) { self->compositor = wl_registry_bind (registry, id, &wl_compositor_interface, - MIN (version, 3)); + MIN (version, 4)); + GST_INFO + ("wl_compositor@%p = wl_registry_bind (wl_registry@%p, id@%d, wl_compositor_interface@%p, version@%d)", + self->compositor, registry, id, &wl_compositor_interface, MIN (version, + 4)); } else if (g_strcmp0 (interface, "wl_subcompositor") == 0) { self->subcompositor = wl_registry_bind (registry, id, &wl_subcompositor_interface, 1); + GST_INFO + ("wl_subcompositor@%p = wl_registry_bind (wl_registry@%p, id@%d, wl_subcompositor_interface@%p, version@%d)", + self->subcompositor, registry, id, &wl_subcompositor_interface, 1); } else if (g_strcmp0 (interface, "wl_shell") == 0) { self->shell = wl_registry_bind (registry, id, &wl_shell_interface, 1); + GST_INFO + ("wl_shell@%p = wl_registry_bind (wl_registry@%p, id@%d, wl_shell_interface@%p, version@%d)", + self->shell, registry, id, &wl_shell_interface, 1); } else if (g_strcmp0 (interface, "wl_shm") == 0) { self->shm = wl_registry_bind (registry, id, &wl_shm_interface, 1); + GST_INFO + ("wl_shm@%p = wl_registry_bind (wl_registry@%p, id@%d, wl_shm_interface@%p, version@%d)", + self->shm, registry, id, &wl_shm_interface, 1); + GST_INFO + ("wl_shm_add_listener (wl_shm@%p, wl_shm_listener@%p, GstWlDisplay@%p)", + self->shm, &shm_listener, self); wl_shm_add_listener (self->shm, &shm_listener, self); + + } else if (g_strcmp0 (interface, "wl_scaler") == 0) { self->scaler = wl_registry_bind (registry, id, &wl_scaler_interface, 2); + GST_INFO + ("wl_scaler@%p = wl_registry_bind (wl_registry@%p, id@%d, wl_scaler_interface@%p, version@%d)", + self->scaler, registry, id, &wl_scaler_interface, 2); #ifdef GST_WLSINK_ENHANCEMENT } else if (g_strcmp0 (interface, "tizen_policy") == 0) { self->tizen_policy = wl_registry_bind (registry, id, &tizen_policy_interface, 1); + GST_INFO + ("tizen_policy@%p = wl_registry_bind (wl_registry@%p, id@%d, tizen_policy_interface@%p, version@%d)", + self->tizen_policy, registry, id, &tizen_policy_interface, 1); } else if (g_strcmp0 (interface, "tizen_video") == 0) { self->tizen_video = wl_registry_bind (registry, id, &tizen_video_interface, version); g_return_if_fail (self->tizen_video != NULL); - GST_INFO ("id(%d)", id); - - tizen_video_add_listener (self->tizen_video, &tz_video_listener, self); + GST_INFO + ("tizen_video@%p = wl_registry_bind (wl_registry@%p, id@%d, tizen_video_interface@%p, version@%d)", + self->tizen_video, registry, id, &tizen_video_interface, version); + + GST_INFO + ("tizen_video_add_listener (tizen_video@%p, tizen_video_listener@%p, GstWlDisplay@%p)", + self->tizen_video, &tizen_video_listener, self); + tizen_video_add_listener (self->tizen_video, &tizen_video_listener, self); #endif } } @@ -259,19 +300,30 @@ gst_wl_display_thread_run (gpointer data) /* main loop */ while (1) { - while (wl_display_prepare_read_queue (self->display, self->queue) != 0) + GST_INFO + ("while (wl_display_prepare_read_queue (display@%p, queue@%p != 0)", + self->display, self->queue); + while (wl_display_prepare_read_queue (self->display, self->queue) != 0) { + GST_INFO ("wl_display_dispatch_queue_pending (display@%p, queue@%p)", + self->display, self->queue); wl_display_dispatch_queue_pending (self->display, self->queue); + } + GST_INFO ("wl_display_flush (display@%p)", self->display); wl_display_flush (self->display); if (gst_poll_wait (self->wl_fd_poll, GST_CLOCK_TIME_NONE) < 0) { gboolean normal = (errno == EBUSY); + GST_INFO ("wl_display_cancel_read (display@%p)", self->display); wl_display_cancel_read (self->display); if (normal) break; else goto error; } else { + GST_INFO ("wl_display_read_events (display@%p)", self->display); wl_display_read_events (self->display); + GST_INFO ("wl_display_dispatch_queue_pending (display@%p, queue@%p)", + self->display, self->queue); wl_display_dispatch_queue_pending (self->display, self->queue); } } @@ -290,7 +342,7 @@ gst_wl_display_new (const gchar * name, GError ** error) FUNCTION; display = wl_display_connect (name); - + GST_INFO ("wl_display@%p = wl_display_connect (name@%p)", display, name); if (!display) { *error = g_error_new (g_quark_from_static_string ("GstWlDisplay"), 0, "Failed to connect to the wayland display '%s'", @@ -317,9 +369,18 @@ gst_wl_display_new_existing (struct wl_display * display, self->own_display = take_ownership; self->queue = wl_display_create_queue (self->display); + GST_INFO ("wl_event_queue@%p = wl_display_create_queue (wl_display@%p)", + self->queue, self->display); self->registry = wl_display_get_registry (self->display); + GST_INFO ("wl_registry@%p = wl_display_get_registry (wl_display@%p)", + self->registry, self->display); wl_proxy_set_queue ((struct wl_proxy *) self->registry, self->queue); + GST_INFO ("wl_proxy_set_queue (wl_registry@%p, wl_event_queue@%p)", + self->registry, self->queue); wl_registry_add_listener (self->registry, ®istry_listener, self); + GST_INFO + ("wl_registry_add_listener (wl_registry@%p, wl_registry_listener@%p, GstWlDisplay@%p)", + self->registry, ®istry_listener, self); /* we need exactly 2 roundtrips to discover global objects and their state */ for (i = 0; i < 2; i++) { @@ -348,13 +409,16 @@ gst_wl_display_new_existing (struct wl_display * display, VERIFY_INTERFACE_EXISTS (tizen_video, "tizen_video"); self->tbm_client = wayland_tbm_client_init (self->display); + GST_INFO ("tbm_client@%p = wayland_tbm_client_init (wl_display@%p)", + self->tbm_client, self->display); + if (!self->tbm_client) { *error = g_error_new (g_quark_from_static_string ("GstWlDisplay"), 0, "Error initializing wayland-tbm"); g_object_unref (self); return NULL; } - GST_INFO ("tbm_client(%p)", self->tbm_client); + GST_LOG ("tbm_client(%p)", self->tbm_client); #endif VERIFY_INTERFACE_EXISTS (shm, "wl_shm"); VERIFY_INTERFACE_EXISTS (scaler, "wl_scaler"); diff --git a/ext/wayland/wldisplay.h b/ext/wayland/wldisplay.h index d9306a4..c1d6a4a 100644 --- a/ext/wayland/wldisplay.h +++ b/ext/wayland/wldisplay.h @@ -39,14 +39,15 @@ G_BEGIN_DECLS #define GST_WL_DISPLAY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_WL_DISPLAY, GstWlDisplayClass)) #define GST_IS_WL_DISPLAY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_WL_DISPLAY)) #define GST_WL_DISPLAY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_WL_DISPLAY, GstWlDisplayClass)) -#define FUNCTION GST_INFO ("") +#define FUNCTION GST_LOG ("") typedef struct _GstWlDisplay GstWlDisplay; typedef struct _GstWlDisplayClass GstWlDisplayClass; #ifdef USE_WL_FLUSH_BUFFER -typedef struct { +typedef struct +{ void *bo[NV_BUF_PLANE_NUM]; -}GstWlFlushBuffer; +} GstWlFlushBuffer; #endif #define TBM_BO_NUM 20 @@ -104,6 +105,7 @@ struct _GstWlDisplay int stride_height[NV_BUF_PLANE_NUM]; int native_video_size; unsigned int wl_surface_id; + int buffer_width, buffer_height; #endif #if 1 diff --git a/ext/wayland/wlshmallocator.c b/ext/wayland/wlshmallocator.c index 0d2c3f2..0950a34 100644 --- a/ext/wayland/wlshmallocator.c +++ b/ext/wayland/wlshmallocator.c @@ -74,7 +74,7 @@ gst_wl_shm_allocator_alloc (GstAllocator * allocator, gsize size, strerror (errno)); return FALSE; } - GST_INFO ("display->tbm_bo[%d]=(%p)", idx, self->display->tbm_bo[idx]); + GST_LOG ("display->tbm_bo[%d]=(%p)", idx, self->display->tbm_bo[idx]); virtual_addr.ptr = NULL; virtual_addr = tbm_bo_get_handle (self->display->tbm_bo[idx], TBM_DEVICE_CPU); @@ -91,7 +91,7 @@ gst_wl_shm_allocator_alloc (GstAllocator * allocator, gsize size, NULL, size, 0, 0, size); mem->data = virtual_addr.ptr; mem->tbm_bo_ptr = self->display->tbm_bo[idx]; - GST_INFO ("mem(%p) mem->data(%p) virtual_addr.ptr(%p) size(%d)", mem, + GST_LOG ("mem(%p) mem->data(%p) virtual_addr.ptr(%p) size(%d)", mem, mem->data, virtual_addr.ptr, size); return (GstMemory *) mem; @@ -102,7 +102,7 @@ gst_wl_shm_allocator_alloc (GstAllocator * allocator, gsize size, /* allocate shm pool */ snprintf (filename, 1024, "%s/%s-%d-%s", g_get_user_runtime_dir (), "wayland-shm", init++, "XXXXXX"); - GST_INFO ("opening temp file %s", filename); + GST_LOG ("opening temp file %s", filename); fd = g_mkstemp (filename); if (fd < 0) { @@ -265,7 +265,7 @@ gst_wl_shm_memory_construct_wl_buffer (GstMemory * mem, GstWlDisplay * display, height = GST_VIDEO_INFO_HEIGHT (info); size = display->native_video_size; format = gst_video_format_to_wl_tbm_format (GST_VIDEO_INFO_FORMAT (info)); - GST_INFO ("format %s, width(%d), height(%d), size(%d)", + GST_LOG ("format %s, width(%d), height(%d), size(%d)", gst_wl_tbm_format_to_string (format), width, height, size); #ifdef DUMP_BUFFER @@ -286,12 +286,13 @@ gst_wl_shm_memory_construct_wl_buffer (GstMemory * mem, GstWlDisplay * display, } } #endif - GST_DEBUG ("TBM bo %p %p %p", display->bo[0], display->bo[1], - display->bo[2]); - GST_INFO ("stride_width[0]: %d stride_height[0]:%d", + GST_LOG ("TBM bo %p %p", display->bo[0], display->bo[1]); + GST_LOG ("stride_width[0]: %d stride_height[0]:%d", display->stride_width[0], display->stride_height[1]); - ts_info.width = display->stride_width[0]; - ts_info.height = display->stride_height[0]; + width = display->stride_width[0]; + height = display->stride_height[0]; + ts_info.width = width; + ts_info.height = height; ts_info.format = format; ts_info.bpp = tbm_surface_internal_get_bpp (ts_info.format); ts_info.num_planes = tbm_surface_internal_get_num_planes (ts_info.format); @@ -304,13 +305,13 @@ gst_wl_shm_memory_construct_wl_buffer (GstMemory * mem, GstWlDisplay * display, ts_info.planes[0].offset = 0; ts_info.planes[1].offset = (display->bo[1]) ? 0 : display->plane_size[0]; num_bo = (display->bo[1]) ? 2 : 1; - GST_INFO ("num_bo(%d)", num_bo); + GST_LOG ("num_bo(%d)", num_bo); display->tsurface = tbm_surface_internal_create_with_bos (&ts_info, (tbm_bo *) display->bo, num_bo); - GST_INFO ("display->tsurface(%p)", display->tsurface); - GST_INFO ("tbm_client(%p),tsurface(%p)", display->tbm_client, + GST_LOG ("display->tsurface(%p)", display->tsurface); + GST_LOG ("tbm_client(%p),tsurface(%p)", display->tbm_client, display->tsurface); wbuffer = wayland_tbm_client_create_buffer (display->tbm_client, @@ -339,7 +340,7 @@ gst_wl_shm_memory_construct_wl_buffer (GstMemory * mem, GstWlDisplay * display, data = virtual_addr.ptr; int ret; char file_name[128]; - GST_INFO ("DUMP %d ", dump_cnt); + GST_LOG ("DUMP %d ", dump_cnt); sprintf (file_name, "/home/owner/WLSINK_OUT_DUMP_%2.2d.dump", dump_cnt++); ret = _write_rawdata (file_name, virtual_addr.ptr, size); if (ret) { @@ -358,7 +359,7 @@ gst_wl_shm_memory_construct_wl_buffer (GstMemory * mem, GstWlDisplay * display, ts_info.planes[1].offset = GST_VIDEO_INFO_PLANE_OFFSET (info, 1); ts_info.planes[2].offset = GST_VIDEO_INFO_PLANE_OFFSET (info, 2); - GST_INFO ("tbm_bo (%p)", shm_mem->tbm_bo_ptr); + GST_LOG ("tbm_bo (%p)", shm_mem->tbm_bo_ptr); display->tsurface = tbm_surface_internal_create_with_bos (&ts_info, @@ -367,9 +368,7 @@ gst_wl_shm_memory_construct_wl_buffer (GstMemory * mem, GstWlDisplay * display, wayland_tbm_client_create_buffer (display->tbm_client, display->tsurface); } - GST_INFO ("wayland_tbm_client_create_buffer create wl_buffer %p", wbuffer); - - return wbuffer; + GST_LOG ("wayland_tbm_client_create_buffer create wl_buffer %p", wbuffer); } else { /* USE SHM */ width = GST_VIDEO_INFO_WIDTH (info); @@ -392,9 +391,12 @@ gst_wl_shm_memory_construct_wl_buffer (GstMemory * mem, GstWlDisplay * display, close (shm_mem->fd); shm_mem->fd = -1; wl_shm_pool_destroy (wl_pool); - - return wbuffer; } + display->buffer_width = width; + display->buffer_height = height; + + return wbuffer; + #else /* open source */ width = GST_VIDEO_INFO_WIDTH (info); height = GST_VIDEO_INFO_HEIGHT (info); diff --git a/ext/wayland/wlvideoformat.c b/ext/wayland/wlvideoformat.c index f8a5624..59e9c95 100644 --- a/ext/wayland/wlvideoformat.c +++ b/ext/wayland/wlvideoformat.c @@ -28,7 +28,7 @@ GST_DEBUG_CATEGORY_EXTERN (gstwayland_debug); #define GST_CAT_DEFAULT gstwayland_debug -#define FUNCTION GST_INFO ("") +#define FUNCTION GST_LOG ("") typedef struct { enum wl_shm_format wl_format; diff --git a/ext/wayland/wlwindow.c b/ext/wayland/wlwindow.c index 7b3fae0..e925888 100644 --- a/ext/wayland/wlwindow.c +++ b/ext/wayland/wlwindow.c @@ -94,6 +94,9 @@ gst_wl_window_class_init (GstWlWindowClass * klass) static void gst_wl_window_init (GstWlWindow * self) { + g_return_if_fail (self != NULL); + self->buffer_width = self->buffer_height = self->buffer_x = self->buffer_y = + 0; } static void @@ -102,23 +105,31 @@ gst_wl_window_finalize (GObject * gobject) GstWlWindow *self = GST_WL_WINDOW (gobject); FUNCTION; -#ifdef GST_WLSINK_ENHANCEMENT - if (self->video_object) - tizen_video_object_destroy (self->video_object); -#endif - if (self->shell_surface) { wl_shell_surface_destroy (self->shell_surface); } - +#ifdef GST_WLSINK_ENHANCEMENT + if (self->video_object) + tizen_video_object_destroy (self->video_object); + if (self->tizen_area_viewport) + tizen_viewport_destroy (self->tizen_area_viewport); + if (self->tizen_video_viewport) + tizen_viewport_destroy (self->tizen_video_viewport); + if (self->tizen_video_dest_mode) + tizen_destination_mode_destroy (self->tizen_video_dest_mode); + if (self->tizen_area_dest_mode) + tizen_destination_mode_destroy (self->tizen_area_dest_mode); +#else wl_viewport_destroy (self->video_viewport); + wl_viewport_destroy (self->area_viewport); +#endif wl_subsurface_destroy (self->video_subsurface); wl_surface_destroy (self->video_surface); if (self->area_subsurface) { wl_subsurface_destroy (self->area_subsurface); } - wl_viewport_destroy (self->area_viewport); + wl_surface_destroy (self->area_surface); g_clear_object (&self->display); @@ -158,6 +169,18 @@ gst_wl_window_map_sub_surface (GstWlDisplay * display, GstWlWindow * window, gwlbuf = gst_buffer_add_wl_buffer (buf, wlbuf, display); gst_wl_buffer_attach (gwlbuf, window->area_surface); + /* for tizen view port + When change area_surface, we don't need to commit anymore if we do below code. + such as gst_wl_window_set_render_rectangle() and */ + GST_INFO + ("wl_surface_damage_buffer (area_surface(wl_surface)@%p, x@%d, y@%d, w@%d, h@%d)", + window->area_surface, 0, 0, info->width, info->height); + wl_surface_damage_buffer (window->area_surface, 0, 0, info->width, + info->height); + GST_INFO ("wl_surface_commit (area_surface(wl_surface)@%p)", + window->area_surface); + wl_surface_commit (window->area_surface); + /* at this point, the GstWlBuffer keeps the buffer * alive and will free it on wl_buffer::release */ gst_buffer_unref (buf); @@ -165,7 +188,8 @@ gst_wl_window_map_sub_surface (GstWlDisplay * display, GstWlWindow * window, #endif static GstWlWindow * -#ifdef GST_WLSINK_ENHANCEMENT +#if 1 +/* for enlightment, we need to get parent to create area_subsurface */ gst_wl_window_new_internal (GstWlDisplay * display, struct wl_surface *parent) #else gst_wl_window_new_internal (GstWlDisplay * display) @@ -186,9 +210,19 @@ gst_wl_window_new_internal (GstWlDisplay * display) window->display = g_object_ref (display); window->area_surface = wl_compositor_create_surface (display->compositor); + GST_INFO + ("area_surface(wl_surface)@%p = wl_compositor_create_surface(wl_compositor@%p)", + window->area_surface, display->compositor); window->video_surface = wl_compositor_create_surface (display->compositor); + GST_INFO + ("video_surface(wl_surface)@%p = wl_compositor_create_surface(wl_compositor@%p)", + window->video_surface, display->compositor); + GST_INFO ("wl_proxy_set_queue (area_surface@%p, wl_event_queue@%p)", + window->area_surface, display->queue); wl_proxy_set_queue ((struct wl_proxy *) window->area_surface, display->queue); + GST_INFO ("wl_proxy_set_queue (video_surface@%p, wl_event_queue@%p)", + window->video_surface, display->queue); wl_proxy_set_queue ((struct wl_proxy *) window->video_surface, display->queue); @@ -196,25 +230,41 @@ gst_wl_window_new_internal (GstWlDisplay * display) /* go toplevel */ if (display->need_shell_surface) { /* for internal window */ - window->shell_surface = wl_shell_get_shell_surface (display->shell, - window->area_surface); + GST_INFO + ("wl_shell_surface@%p = wl_shell_get_shell_surface (wl_shell@%p, area_subsurface(wl_surface)@%p)", + window->shell_surface, display->shell, window->area_surface); + window->shell_surface = + wl_shell_get_shell_surface (display->shell, window->area_surface); } else if (display->use_parent_wl_surface) { #ifdef GST_WLSINK_ENHANCEMENT - GST_INFO ("call tizen_policy_get_subsurface"); if (display->wl_surface_id && parent == NULL) { window->area_subsurface = tizen_policy_get_subsurface (display->tizen_policy, window->area_surface, display->wl_surface_id); + GST_INFO + ("area_subsurface(wl_subsurface)@%p = tizen_policy_get_subsurface(tizen_policy@%p, area_surface(wl_surface)@%p, wl_surface_id@%d)", + window->area_subsurface, display->tizen_policy, window->area_surface, + display->wl_surface_id); + GST_INFO ("wl_subsurface_set_desync (area_subsurface(wl_subsurface)@%p)", + window->area_subsurface); wl_subsurface_set_desync (window->area_subsurface); + GST_INFO ("wl_surface_commit (%p)", window->area_surface); wl_surface_commit (window->area_surface); } else { - GST_INFO (" wl_surface %p", parent); + GST_INFO (" wl_surface parent %p", parent); window->area_subsurface = wl_subcompositor_get_subsurface (display->subcompositor, window->area_surface, parent); + GST_INFO + ("area_subsurface(wl_subsurface)@%p = wl_subcompositor_get_subsurface(wl_subcompositor@%p, area_surface(wl_surface)@%p, parent@%p)", + window->area_subsurface, display->subcompositor, window->area_surface, + parent); + GST_INFO ("wl_subsurface_set_desync (area_subsurface(wl_subsurface)@%p)", + window->area_subsurface); wl_subsurface_set_desync (window->area_subsurface); } #else + /*for enlightment , below code is moved */ window->area_subsurface = wl_subcompositor_get_subsurface (display->subcompositor, window->area_surface, parent); @@ -227,14 +277,41 @@ gst_wl_window_new_internal (GstWlDisplay * display) window->video_subsurface = wl_subcompositor_get_subsurface (display->subcompositor, window->video_surface, window->area_surface); + GST_INFO + ("video_subsurface(wl_subsurface)@%p = wl_subcompositor_get_subsurface(wl_subcompositor@%p, video_surface(wl_surface)@%p, area_surface(wl_surface)@%p)", + window->video_subsurface, display->subcompositor, window->video_surface, + window->area_surface); + + GST_INFO ("wl_subsurface_set_desync (video_subsurface(wl_subsurface)@%p)", + window->video_subsurface); wl_subsurface_set_desync (window->video_subsurface); + GST_INFO ("wl_surface_commit (%p)", window->video_surface); wl_surface_commit (window->video_surface); +#ifdef GST_WLSINK_ENHANCEMENT + window->tizen_area_viewport = + tizen_video_get_viewport (display->tizen_video, window->area_surface); + GST_INFO + ("tizen_area_viewport(tizen_viewport)@%p = tizen_video_get_viewport(tizen_video@%p, area_surface(wl_surface)@%p)", + window->tizen_area_viewport, display->tizen_video, window->area_surface); + window->tizen_video_viewport = + tizen_video_get_viewport (display->tizen_video, window->video_surface); + GST_INFO + ("tizen_video_viewport(tizen_viewport)@%p = tizen_video_get_viewport(tizen_video@%p, video_surface(wl_surface%p)", + window->tizen_video_viewport, display->tizen_video, + window->video_surface); + window->tizen_video_dest_mode = + tizen_viewport_get_destination_mode (window->tizen_video_viewport); + GST_INFO + ("tizen_destination_mode@%p = tizen_viewport_get_destination_mode (tizen_video_viewport@%p)", + window->tizen_video_dest_mode, window->tizen_video_viewport); + +#else window->area_viewport = wl_scaler_get_viewport (display->scaler, window->area_surface); window->video_viewport = wl_scaler_get_viewport (display->scaler, window->video_surface); - +#endif /* draw the area_subsurface */ gst_video_info_set_format (&info, /* we want WL_SHM_FORMAT_XRGB8888 */ @@ -278,35 +355,98 @@ gst_wl_window_new_internal (GstWlDisplay * display) /* do not accept input */ region = wl_compositor_create_region (display->compositor); + GST_INFO ("wl_region@%p = wl_compositor_create_region (wl_compositor@%p)", + region, display->compositor); + GST_INFO ("wl_surface_set_input_region (area_surface@%p, wl_region@%p)", + window->area_surface, region); wl_surface_set_input_region (window->area_surface, region); + GST_INFO ("wl_region_destroy (wl_region@%p)", region); wl_region_destroy (region); region = wl_compositor_create_region (display->compositor); + GST_INFO ("wl_region@%p = wl_compositor_create_region (wl_compositor@%p)", + region, display->compositor); + GST_INFO ("wl_surface_set_input_region (video_surface@%p, wl_region@%p)", + window->video_surface, region); wl_surface_set_input_region (window->video_surface, region); + GST_INFO ("wl_region_destroy (wl_region@%p)", region); wl_region_destroy (region); +#ifdef GST_WLSINK_ENHANCEMENT + /* set area surface size by full mode(full size of parent window) , toplevel is set to fullmode too for convenient test */ + if (window->tizen_area_viewport) { + int tizen_disp_mode = TIZEN_DESTINATION_MODE_TYPE_FULL; + + window->tizen_area_dest_mode = + tizen_viewport_get_destination_mode (window->tizen_area_viewport); + GST_INFO + ("tizen_destination_mode@%p = tizen_viewport_get_destination_mode (tizen_video_viewport@%p)", + window->tizen_area_dest_mode, window->tizen_area_viewport); + if (window->tizen_area_dest_mode) { + GST_INFO ("tizen_destination_mode_set (tizen_destination_mode@%p, @%d)", + window->tizen_area_dest_mode, tizen_disp_mode); + tizen_destination_mode_set (window->tizen_area_dest_mode, + tizen_disp_mode); + } + GST_INFO ("wl_surface_commit (area_surface@%p)", window->area_surface); + wl_surface_commit (window->area_surface); + } +#endif return window; } GstWlWindow * gst_wl_window_new_toplevel (GstWlDisplay * display, const GstVideoInfo * info) { +#ifdef GST_WLSINK_ENHANCEMENT GstWlWindow *window; - gint width; FUNCTION; /* not create shell_surface here for enlightenment */ -#ifdef GST_WLSINK_ENHANCEMENT display->need_shell_surface = TRUE; - window = gst_wl_window_new_internal (display, NULL); -#if 0 //GST_WLSINK_ENHANCEMENT + /* for tizen enlightenment */ +#if 0 /* go toplevel */ window->shell_surface = wl_shell_get_shell_surface (display->shell, window->area_surface); #endif + if (window->shell_surface) { + GST_LOG + ("wl_shell_surface_add_listener (shell_surface@%p, wl_shell_surface_listener@%p, GstWlWindow@%p", + window->shell_surface, &shell_surface_listener, window); + wl_shell_surface_add_listener (window->shell_surface, + &shell_surface_listener, window); + GST_LOG ("wl_shell_surface_set_toplevel (shell_surface@%p", + window->shell_surface); + wl_shell_surface_set_toplevel (window->shell_surface); + } else { + GST_ERROR ("Unable to get wl_shell_surface"); + + g_object_unref (window); + return NULL; + } + + /* toplevel is set to fullmode for convenient test in tizen_viewport enviroment, don't use below code */ +#if 0 + /* set the initial size to be the same as the reported video size */ + width = + gst_util_uint64_scale_int_round (info->width, info->par_n, info->par_d); + gst_wl_window_set_render_rectangle (window, 0, 0, width, info->height); #endif + return window; + +#else /* open source */ + GstWlWindow *window; + gint width; + + window = gst_wl_window_new_internal (display); + + /* go toplevel */ + window->shell_surface = wl_shell_get_shell_surface (display->shell, + window->area_surface); + if (window->shell_surface) { wl_shell_surface_add_listener (window->shell_surface, &shell_surface_listener, window); @@ -324,47 +464,58 @@ gst_wl_window_new_toplevel (GstWlDisplay * display, const GstVideoInfo * info) gst_wl_window_set_render_rectangle (window, 0, 0, width, info->height); return window; +#endif } + GstWlWindow * gst_wl_window_new_in_surface (GstWlDisplay * display, struct wl_surface * parent) { +#ifdef GST_WLSINK_ENHANCEMENT + /* use App window */ GstWlWindow *window; FUNCTION; display->use_parent_wl_surface = TRUE; -#ifdef GST_WLSINK_ENHANCEMENT - if (parent) { /*use wl_surface */ + if (parent) { + /*use wl_surface */ window = gst_wl_window_new_internal (display, parent); - } else { /* use wl_surface id */ + } else { + /* use wl_surface id */ window = gst_wl_window_new_internal (display, NULL); } -#else - window = gst_wl_window_new_internal (display, parent); -#endif - -#if 0 /*for enlightment */ - /* embed in parent */ - window->area_subsurface = - wl_subcompositor_get_subsurface (display->subcompositor, - window->area_surface, parent); - wl_subsurface_set_desync (window->area_subsurface); -#endif -#ifdef GST_WLSINK_ENHANCEMENT /*Area surface from App need to be under parent surface */ if (display->tizen_policy) { - GST_INFO (" call tizen_policy_place_subsurface_below_parent "); + GST_INFO ("tizen_policy_place_subsurface_below_parent (%p, %p)", + display->tizen_policy, window->area_subsurface); tizen_policy_place_subsurface_below_parent (display->tizen_policy, window->area_subsurface); + GST_INFO ("tizen_policy_place_subsurface_below_parent (%p, %p)", + display->tizen_policy, window->video_subsurface); tizen_policy_place_subsurface_below_parent (display->tizen_policy, window->video_subsurface); } -#else - wl_surface_commit (parent); + return window; + +#else /* open source */ + + GstWlWindow *window; + window = gst_wl_window_new_internal (display, parent); //add parent for enlightment + + /*for enlightment , move to gst_wl_window_new_internal() */ +#if 0 + /* embed in parent */ + window->area_subsurface = + wl_subcompositor_get_subsurface (display->subcompositor, + window->area_surface, parent); + wl_subsurface_set_desync (window->area_subsurface); #endif + return window; + +#endif } GstWlDisplay * @@ -457,144 +608,224 @@ gst_wl_window_find_transform (guint rotate_angle, guint flip) } #endif +#if GST_WLSINK_ENHANCEMENT static void -gst_wl_window_resize_video_surface (GstWlWindow * window, gboolean commit) +gst_wl_window_resize_tizen_video_viewport (GstWlWindow * window, + gboolean commit) { - GstVideoRectangle src = { 0, }; - GstVideoRectangle res; -#ifdef GST_WLSINK_ENHANCEMENT // need to change ifndef to ifdef - GstVideoRectangle src_origin = { 0, 0, 0, 0 }; - GstVideoRectangle src_input = { 0, 0, 0, 0 }; - GstVideoRectangle dst = { 0, 0, 0, 0 }; - int temp = 0; gint transform = WL_OUTPUT_TRANSFORM_NORMAL; -#endif + FUNCTION; + g_return_if_fail (window->tizen_video_viewport != NULL); + g_return_if_fail (window->tizen_video_dest_mode != NULL); + + /* Set crop, wayland need to set tizen_viewport_set_source always when change video info */ + if (window->mode_crop.changed) { + /* we have known issue about mobile team kernel, when set orign green line can be shown with tbm */ + GST_INFO + ("tizen_viewport_set_source (tizen_video_viewport@%p, x@%d, y@%d, w@%d, h@%d)", + window->tizen_video_viewport, window->mode_crop.x, window->mode_crop.y, + window->mode_crop.w, window->mode_crop.h); + tizen_viewport_set_source (window->tizen_video_viewport, + window->mode_crop.x, window->mode_crop.y, window->mode_crop.w, + window->mode_crop.h); + window->mode_crop.changed = FALSE; + } - /* center the video_subsurface inside area_subsurface */ - src.w = window->video_width; - src.h = window->video_height; + /*set tizen destination mode */ + if (window->disp_geo_method.changed) { + int tizen_disp_mode = -1; + switch (window->disp_geo_method.value) { + + case DISP_GEO_METHOD_LETTER_BOX: + GST_LOG ("TIZEN_DESTINATION_MODE_TYPE_LETTER_BOX"); + tizen_disp_mode = TIZEN_DESTINATION_MODE_TYPE_LETTER_BOX; + break; + case DISP_GEO_METHOD_ORIGIN_SIZE: + GST_LOG ("TIZEN_DESTINATION_MODE_TYPE_ORIGIN"); + tizen_disp_mode = TIZEN_DESTINATION_MODE_TYPE_ORIGIN; + break; + case DISP_GEO_METHOD_FULL_SCREEN: + GST_LOG ("TIZEN_DESTINATION_MODE_TYPE_FULL"); + tizen_disp_mode = TIZEN_DESTINATION_MODE_TYPE_FULL; + break; + case DISP_GEO_METHOD_CROPPED_FULL_SCREEN: + GST_LOG ("TIZEN_DESTINATION_MODE_TYPE_CROPPED_FULL"); + tizen_disp_mode = TIZEN_DESTINATION_MODE_TYPE_CROPPED_FULL; + break; + case DISP_GEO_METHOD_ORIGIN_SIZE_OR_LETTER_BOX: + GST_LOG ("TIZEN_DESTINATION_MODE_TYPE_ORIGIN_OR_LETTER"); + tizen_disp_mode = TIZEN_DESTINATION_MODE_TYPE_ORIGIN_OR_LETTER; + break; + case DISP_GEO_METHOD_CUSTOM_ROI: + GST_LOG + ("DISP_GEO_METHOD_CUSTOM_ROI..don't need to set tizen disp mode"); + break; + default: + break; + } + if (tizen_disp_mode > -1) { + GST_INFO + ("tizen_destination_mode_set (tizen_destination_mode@%p, tizen_disp_mode@%d)", + window->tizen_video_dest_mode, tizen_disp_mode); + tizen_destination_mode_set (window->tizen_video_dest_mode, + tizen_disp_mode); + } + window->disp_geo_method.changed = FALSE; + } -#ifdef GST_WLSINK_ENHANCEMENT // need to change ifndef to ifdef - src.x = src.y = 0; - src_input.w = src_origin.w = window->video_width; - src_input.h = src_origin.h = window->video_height; - GST_INFO ("video (%d x %d)", window->video_width, window->video_height); - GST_INFO ("src_input(%d, %d, %d x %d)", src_input.x, src_input.y, src_input.w, - src_input.h); - GST_INFO ("src_origin(%d, %d, %d x %d)", src_origin.x, src_origin.y, - src_origin.w, src_origin.h); - - if (window->rotate_angle == DEGREE_0 || window->rotate_angle == DEGREE_180) { - src.w = window->video_width; //video_width - src.h = window->video_height; //video_height - } else { - src.w = window->video_height; - src.h = window->video_width; + if (window->disp_geo_method.value == DISP_GEO_METHOD_CUSTOM_ROI) + goto done; + + /* set or unset follow parent transform */ + if (window->follow_parent_transform.changed + && !gst_wl_window_is_toplevel (window)) { + if (window->follow_parent_transform.value) { + GST_INFO + ("tizen_destination_mode_follow_parent_transform (tizen_destination_mode@%p)", + window->tizen_area_dest_mode); + tizen_destination_mode_follow_parent_transform + (window->tizen_area_dest_mode); + GST_INFO + ("tizen_destination_mode_follow_parent_transform (tizen_destination_mode@%p)", + window->tizen_video_dest_mode); + tizen_destination_mode_follow_parent_transform + (window->tizen_video_dest_mode); + + } else { + GST_INFO + ("tizen_destination_mode_unfollow_parent_transform (tizen_destination_mode@%p)", + window->tizen_area_dest_mode); + tizen_destination_mode_unfollow_parent_transform + (window->tizen_area_dest_mode); + GST_INFO + ("tizen_destination_mode_unfollow_parent_transform (tizen_destination_mode@%p)", + window->tizen_video_dest_mode); + tizen_destination_mode_unfollow_parent_transform + (window->tizen_video_dest_mode); + } + window->follow_parent_transform.changed = FALSE; } - GST_INFO ("src(%d, %d, %d x %d)", src.x, src.y, src.w, src.h); - /*default res.w and res.h */ - dst.w = window->render_rectangle.w; - dst.h = window->render_rectangle.h; - dst.x = window->render_rectangle.x; - dst.y = window->render_rectangle.y; - - GST_INFO ("dst(%d,%d,%d x %d)", dst.x, dst.y, dst.w, dst.h); - GST_INFO ("window->render_rectangle(%d,%d,%d x %d)", - window->render_rectangle.x, window->render_rectangle.y, - window->render_rectangle.w, window->render_rectangle.h); - switch (window->disp_geo_method) { - case DISP_GEO_METHOD_LETTER_BOX: - GST_INFO ("DISP_GEO_METHOD_LETTER_BOX"); - gst_video_sink_center_rect (src, dst, &res, TRUE); - break; - case DISP_GEO_METHOD_ORIGIN_SIZE_OR_LETTER_BOX: - if (src.w > dst.w || src.h > dst.h) { - /*LETTER BOX */ - GST_INFO - ("DISP_GEO_METHOD_ORIGIN_SIZE_OR_LETTER_BOX -> set LETTER BOX"); - gst_video_sink_center_rect (src, dst, &res, TRUE); - } else { - /*ORIGIN SIZE */ - GST_INFO ("DISP_GEO_METHOD_ORIGIN_SIZE"); - gst_video_sink_center_rect (src, dst, &res, FALSE); - gst_video_sink_center_rect (dst, src, &src_input, FALSE); - } - break; - case DISP_GEO_METHOD_ORIGIN_SIZE: //is working - GST_INFO ("DISP_GEO_METHOD_ORIGIN_SIZE"); - gst_video_sink_center_rect (src, dst, &res, FALSE); - gst_video_sink_center_rect (dst, src, &src_input, FALSE); - break; - case DISP_GEO_METHOD_FULL_SCREEN: //is working - GST_INFO ("DISP_GEO_METHOD_FULL_SCREEN"); - res.x = res.y = 0; - res.w = window->render_rectangle.w; - res.h = window->render_rectangle.h; - break; - case DISP_GEO_METHOD_CROPPED_FULL_SCREEN: - GST_INFO ("DISP_GEO_METHOD_CROPPED_FULL_SCREEN"); - gst_video_sink_center_rect (src, dst, &res, FALSE); - gst_video_sink_center_rect (dst, src, &src_input, FALSE); - res.x = res.y = 0; - res.w = dst.w; - res.h = dst.h; - break; - default: - break; + /* set ratio */ + if (window->mode_ratio.changed) { + wl_fixed_t f_width, f_height; + f_width = wl_fixed_from_double (window->mode_ratio.w); + f_height = wl_fixed_from_double (window->mode_ratio.h); + + GST_INFO + ("tizen_destination_mode_set_ratio (tizen_destination_mode@%p, wl_fixed width@%f, wl_fixed height@%f)", + window->tizen_video_dest_mode, window->mode_ratio.w, + window->mode_ratio.h); + tizen_destination_mode_set_ratio (window->tizen_video_dest_mode, f_width, + f_height); + window->mode_ratio.changed = FALSE; } - transform = gst_wl_window_find_transform (window->rotate_angle, window->flip); + /* set scale */ + if (window->mode_scale.changed) { + wl_fixed_t f_width, f_height; + f_width = wl_fixed_from_double (window->mode_scale.w); + f_height = wl_fixed_from_double (window->mode_scale.h); + + GST_INFO + ("tizen_destination_mode_set_scale (tizen_destination_mode@%p, wl_fixed width@%f, wl_fixed height@%f)", + window->tizen_video_dest_mode, window->mode_scale.w, + window->mode_scale.h); + tizen_destination_mode_set_scale (window->tizen_video_dest_mode, f_width, + f_height); + window->mode_ratio.changed = FALSE; + } - GST_INFO - ("window[%d x %d] src[%d,%d,%d x %d],dst[%d,%d,%d x %d],input[%d,%d,%d x %d],result[%d,%d,%d x %d]", - window->render_rectangle.w, window->render_rectangle.h, - src.x, src.y, src.w, src.h, - dst.x, dst.y, dst.w, dst.h, - src_input.x, src_input.y, src_input.w, src_input.h, - res.x, res.y, res.w, res.h); - - GST_INFO ("video (%d x %d)", window->video_width, window->video_height); - GST_INFO ("src_input(%d, %d, %d x %d)", src_input.x, src_input.y, src_input.w, - src_input.h); - GST_INFO ("src_origin(%d, %d, %d x %d)", src_origin.x, src_origin.y, - src_origin.w, src_origin.h); - GST_INFO ("src(%d, %d, %d x %d)", src.x, src.y, src.w, src.h); - GST_INFO ("dst(%d,%d,%d x %d)", dst.x, dst.y, dst.w, dst.h); - GST_INFO ("window->render_rectangle(%d,%d,%d x %d)", - window->render_rectangle.x, window->render_rectangle.y, - window->render_rectangle.w, window->render_rectangle.h); - GST_INFO ("res(%d, %d, %d x %d)", res.x, res.y, res.w, res.h); - - if (window->video_subsurface) { - GST_INFO ("have window->subsurface"); - wl_subsurface_set_position (window->video_subsurface, res.x, res.y); - GST_INFO ("wl_subsurface_set_position(%d,%d)", res.x, res.y); + /* set offset */ + if (window->mode_offset.changed) { + GST_INFO + ("tizen_destination_mode_set_offset (tizen_destination_mode@%p, x@%d, y@%d, w@%d, h@%d)", + window->tizen_video_dest_mode, window->mode_offset.x, + window->mode_offset.y, window->mode_offset.w, window->mode_offset.h); + tizen_destination_mode_set_offset (window->tizen_video_dest_mode, + window->mode_offset.x, window->mode_offset.y, window->mode_offset.w, + window->mode_offset.h); + window->mode_offset.changed = FALSE; } - wl_viewport_set_destination (window->video_viewport, res.w, res.h); - GST_INFO ("wl_viewport_set_destination(%d,%d)", res.w, res.h); - - /*need to swap */ - if (transform % 2 == 1) { /*1, 3, 5, 7 */ - temp = src_input.w; - src_input.w = src_input.h; - src_input.h = temp; - } - wl_viewport_set_source (window->video_viewport, - wl_fixed_from_int (src_input.x), wl_fixed_from_int (src_input.y), - wl_fixed_from_int (src_input.w), wl_fixed_from_int (src_input.h)); - GST_INFO ("wl_viewport_set_source(%d,%d, %d x %d)", src_input.x, src_input.y, - src_input.w, src_input.h); - - wl_surface_set_buffer_transform (window->video_surface, transform); - GST_INFO ("wl_surface_set_buffer_transform (%d)", transform); + + /* set align */ + if (window->mode_align.changed) { + wl_fixed_t f_width, f_height; + f_width = wl_fixed_from_double (window->mode_align.w); + f_height = wl_fixed_from_double (window->mode_align.h); + GST_INFO + ("tizen_destination_mode_set_align (tizen_destination_mode@%p, wl_fixed_width@%f, wl_fixed_height@%f)", + window->tizen_video_dest_mode, window->mode_align.w, + window->mode_align.h); + tizen_destination_mode_set_align (window->tizen_video_dest_mode, f_width, + f_height); + window->mode_align.changed = FALSE; + } + +done: + + /* set transform */ + if (window->rotate_angle.changed || window->flip.changed) { + GST_LOG ("rotate_angle(%d), flip(%d)", window->rotate_angle.value, + window->flip.value); + transform = + gst_wl_window_find_transform (window->rotate_angle.value, + window->flip.value); + GST_INFO + ("tizen_viewport_set_transform(tizen_video_viewport@%p, transform@%d)", + window->tizen_video_viewport, transform); + tizen_viewport_set_transform (window->tizen_video_viewport, transform); + window->rotate_angle.changed = window->flip.changed = FALSE; + } + + if (commit) { + GST_INFO ("need to commit"); + GST_INFO + ("wl_surface_damage_buffer (video_surface@%p, buffer_@x%d, buffer_y@%d, buffer_w@%d, buffer_h@%d)", + window->video_surface, window->buffer_x, window->buffer_y, + window->buffer_width, window->buffer_height); + wl_surface_damage_buffer (window->video_surface, window->buffer_x, + window->buffer_y, window->buffer_width, window->buffer_height); + GST_INFO ("wl_surface_commit (video_surface@%p)", window->video_surface); + wl_surface_commit (window->video_surface); + } + + if (gst_wl_window_is_toplevel (window)) { + struct wl_region *region; + + region = wl_compositor_create_region (window->display->compositor); + GST_INFO ("wl_region@%p = wl_compositor_create_region (wl_compositor@%p)", + region, window->display->compositor); + GST_INFO ("wl_region_add (wl_region@%p, x@%d, y@%d, w@%d, h@%d)", region, 0, + 0, window->render_rectangle.w, window->render_rectangle.h); + wl_region_add (region, 0, 0, window->render_rectangle.w, + window->render_rectangle.h); + GST_INFO ("wl_surface_set_input_region (area_surface@%p, wl_region@%p)", + window->area_surface, region); + wl_surface_set_input_region (window->area_surface, region); + GST_INFO ("wl_region_destroy (wl_region@%p)", region); + wl_region_destroy (region); + } +} #else - gst_video_sink_center_rect (src, window->render_rectangle, &res, TRUE); +static void +gst_wl_window_resize_video_surface (GstWlWindow * window, gboolean commit) +{ + GstVideoRectangle src = { 0, }; + GstVideoRectangle dst = { 0, }; + GstVideoRectangle res; + + /* center the video_subsurface inside area_subsurface */ + src.w = window->video_width; + src.h = window->video_height; + dst.w = window->render_rectangle.w; + dst.h = window->render_rectangle.h; + gst_video_sink_center_rect (src, dst, &res, TRUE); wl_subsurface_set_position (window->video_subsurface, res.x, res.y); wl_viewport_set_destination (window->video_viewport, res.w, res.h); -#endif + if (commit) { wl_surface_damage (window->video_surface, 0, 0, res.w, res.h); wl_surface_commit (window->video_surface); @@ -614,52 +845,94 @@ gst_wl_window_resize_video_surface (GstWlWindow * window, gboolean commit) window->surface_width = res.w; window->surface_height = res.h; } - +#endif void gst_wl_window_render (GstWlWindow * window, GstWlBuffer * buffer, const GstVideoInfo * info) { +#if GST_WLSINK_ENHANCEMENT FUNCTION; + /* check if video buffer size is changed for setting video viewport destination */ + if (window->buffer_width != window->display->buffer_width + || window->buffer_height != window->display->buffer_height) { + window->buffer_width = window->display->buffer_width; + window->buffer_height = window->display->buffer_height; + GST_INFO + ("tizen_viewport_set_destination (tizen_video_viewport@%p, buffer_x@%d, buffer_y@%d, buffer_w@%d, buffer_h@%d)", + window->tizen_video_viewport, window->buffer_x, window->buffer_y, + window->buffer_width, window->buffer_height); + tizen_viewport_set_destination (window->tizen_video_viewport, + window->buffer_x, window->buffer_y, window->buffer_width, + window->buffer_height); + } if (G_UNLIKELY (info)) { window->video_width = gst_util_uint64_scale_int_round (info->width, info->par_n, info->par_d); window->video_height = info->height; wl_subsurface_set_sync (window->video_subsurface); -#ifdef GST_WLSINK_ENHANCEMENT + GST_INFO ("wl_subsurface_set_sync (video_subsurface@%p)", + window->video_subsurface); /* check video_info_changed to remove repetitive IPC */ if (window->video_info_changed) { - gst_wl_window_resize_video_surface (window, FALSE); + gst_wl_window_resize_tizen_video_viewport (window, FALSE); window->video_info_changed = FALSE; } -#else + } + + GST_LOG ("GstWlBuffer(%p)", buffer); + if (G_LIKELY (buffer)) + gst_wl_buffer_attach (buffer, window->video_surface); + else { + GST_INFO ("wl_surface_attach (video_surface@%p, NULL, 0, 0)", + window->video_surface); + wl_surface_attach (window->video_surface, NULL, 0, 0); + } + /* use tizen view port */ + GST_INFO + ("wl_surface_damage_buffer (video_surface@%p, buffer_x@%d, buffer_y@%d, buffer_w@%d, buffer_h@%d)", + window->video_surface, window->buffer_x, window->buffer_y, + window->buffer_width, window->buffer_height); + wl_surface_damage_buffer (window->video_surface, window->buffer_x, + window->buffer_y, window->buffer_width, window->buffer_height); + /* wl_surface_commit change surface state, if wl_buffer is not attached newly, then surface is not changed */ + GST_INFO ("wl_surface_commit (video_surface@%p)", window->video_surface); + wl_surface_commit (window->video_surface); + + if (G_UNLIKELY (info)) { + GST_INFO ("wl_surface_commit (area_surface@%p)", window->area_surface); + wl_surface_commit (window->area_surface); + GST_INFO ("wl_subsurface_set_desync (video_subsurface@%p)", + window->video_subsurface); + wl_subsurface_set_desync (window->video_subsurface); + } + + wl_display_flush (window->display->display); + +#else /* open source */ + + if (G_UNLIKELY (info)) { + window->video_width = + gst_util_uint64_scale_int_round (info->width, info->par_n, info->par_d); + window->video_height = info->height; + + wl_subsurface_set_sync (window->video_subsurface); gst_wl_window_resize_video_surface (window, FALSE); -#endif } - GST_INFO ("GstWlBuffer(%p)", buffer); + GST_LOG ("GstWlBuffer(%p)", buffer); if (G_LIKELY (buffer)) gst_wl_buffer_attach (buffer, window->video_surface); else wl_surface_attach (window->video_surface, NULL, 0, 0); - /*Wayland-compositor will try to render damage area which need to be updated */ wl_surface_damage (window->video_surface, 0, 0, window->surface_width, window->surface_height); -#ifdef GST_WLSINK_ENHANCEMENT - GST_LOG ("update area width %d, height %d", window->surface_width, - window->surface_height); -#endif - /* wl_surface_commit change surface state, if wl_buffer is not attached newly, then surface is not changed */ wl_surface_commit (window->video_surface); if (G_UNLIKELY (info)) { /* commit also the parent (area_surface) in order to change * the position of the video_subsurface */ -#ifdef GST_WLSINK_ENHANCEMENT - GST_DEBUG ("render_rectangle %d*%d", window->render_rectangle.w, - window->render_rectangle.h); -#endif wl_surface_damage (window->area_surface, 0, 0, window->render_rectangle.w, window->render_rectangle.h); wl_surface_commit (window->area_surface); @@ -667,21 +940,54 @@ gst_wl_window_render (GstWlWindow * window, GstWlBuffer * buffer, } wl_display_flush (window->display->display); +#endif } void gst_wl_window_set_render_rectangle (GstWlWindow * window, gint x, gint y, gint w, gint h) { +#if GST_WLSINK_ENHANCEMENT FUNCTION; g_return_if_fail (window != NULL); -#ifdef GST_WLSINK_ENHANCEMENT - if (window->render_rectangle.x == x && window->render_rectangle.y == y - && window->render_rectangle.w == w && window->render_rectangle.h == h) { - GST_DEBUG ("but the values are same. skip"); + if (gst_wl_window_is_toplevel (window)) { + /* let's set windwo size for convenient gst-launch test */ + x = 0, y = 0, w = 720, h = 1280; + window->render_rectangle.x = x; + window->render_rectangle.y = y; + window->render_rectangle.w = w; + window->render_rectangle.h = h; + } else { + /* we already set area surface size, ignore call by app, app need to remove call */ return; } -#endif + + /* position the area inside the parent - needs a parent commit to apply */ + /* use tizen view port */ + if (window->tizen_area_viewport) { + GST_INFO + ("tizen_viewport_set_destination (tizen_area_viewport(tizen_viewport)@%p, x@%d, y@%d, w@%d, h@%d)", + window->tizen_area_viewport, x, y, w, h); + tizen_viewport_set_destination (window->tizen_area_viewport, x, y, w, h); + } + + if (window->video_width != 0) { + GST_INFO ("wl_subsurface_set_sync (video_subsurface@%p)", + window->video_subsurface); + wl_subsurface_set_sync (window->video_subsurface); + /* use tizen view port */ + gst_wl_window_resize_tizen_video_viewport (window, TRUE); + GST_INFO ("wl_subsurface_set_desync (video_subsurface@%p)", + window->video_subsurface); + wl_subsurface_set_desync (window->video_subsurface); + } + GST_INFO ("wl_surface_commit (area_surface@%p)", window->area_surface); + wl_surface_commit (window->area_surface); + +#else /* open source */ + + g_return_if_fail (window != NULL); + window->render_rectangle.x = x; window->render_rectangle.y = y; window->render_rectangle.w = w; @@ -704,6 +1010,8 @@ gst_wl_window_set_render_rectangle (GstWlWindow * window, gint x, gint y, if (window->video_width != 0) wl_subsurface_set_desync (window->video_subsurface); + +#endif } #ifdef GST_WLSINK_ENHANCEMENT @@ -712,35 +1020,105 @@ gst_wl_window_set_rotate_angle (GstWlWindow * window, guint rotate_angle) { FUNCTION; g_return_if_fail (window != NULL); - window->rotate_angle = rotate_angle; - GST_INFO ("rotate_angle value is (%d)", window->rotate_angle); + window->rotate_angle.value = rotate_angle; + GST_LOG ("rotate_angle value is (%d)", window->rotate_angle.value); + window->rotate_angle.changed = TRUE; } void -gst_wl_window_set_disp_geo_method (GstWlWindow * window, guint disp_geo_method) +gst_wl_window_set_destination_mode (GstWlWindow * window, guint disp_geo_method) { FUNCTION; g_return_if_fail (window != NULL); - window->disp_geo_method = disp_geo_method; - GST_INFO ("disp_geo_method value is (%d)", window->disp_geo_method); + window->disp_geo_method.value = disp_geo_method; + GST_LOG ("disp_geo_method value is (%d)", window->disp_geo_method.value); + window->disp_geo_method.changed = TRUE; } void -gst_wl_window_set_orientation (GstWlWindow * window, guint orientation) +gst_wl_window_set_flip (GstWlWindow * window, guint flip) { FUNCTION; g_return_if_fail (window != NULL); - window->orientation = orientation; - GST_INFO ("orientation value is (%d)", window->orientation); + window->flip.value = flip; + GST_LOG ("flip value is (%d)", window->flip.value); + window->flip.changed = TRUE; } void -gst_wl_window_set_flip (GstWlWindow * window, guint flip) +gst_wl_window_set_destination_mode_follow_parent_transform (GstWlWindow * + window, gboolean follow_parent_transform) { FUNCTION; g_return_if_fail (window != NULL); - window->flip = flip; - GST_INFO ("flip value is (%d)", window->flip); + window->follow_parent_transform.value = follow_parent_transform; + GST_LOG ("follow_parent_transform value is (%d)", + window->follow_parent_transform.value); + window->follow_parent_transform.changed = TRUE; +} + +void +gst_wl_window_set_destination_mode_crop_wl_buffer (GstWlWindow * window, + guint x, guint y, guint w, guint h) +{ + FUNCTION; + g_return_if_fail (window != NULL); + GST_LOG ("set crop x@%d, y@%d, w@%d, h@%d", x, y, w, h); + window->mode_crop.x = x; + window->mode_crop.y = y; + window->mode_crop.w = w; + window->mode_crop.h = h; + window->mode_crop.changed = TRUE; +} + +void +gst_wl_window_set_destination_mode_offset (GstWlWindow * window, guint x, + guint y, guint w, guint h) +{ + FUNCTION; + g_return_if_fail (window != NULL); + GST_LOG ("set offset x@%d, y@%d", x, y); + window->mode_offset.x = x; + window->mode_offset.y = y; + window->mode_offset.w = w; + window->mode_offset.h = h; + window->mode_offset.changed = TRUE; +} + +void +gst_wl_window_set_destination_mode_ratio (GstWlWindow * window, gdouble w, + gdouble h) +{ + FUNCTION; + g_return_if_fail (window != NULL); + GST_LOG ("set ratio w@%f, h@%f", w, h); + window->mode_ratio.w = w; + window->mode_ratio.h = h; + window->mode_ratio.changed = TRUE; +} + +void +gst_wl_window_set_destination_mode_scale (GstWlWindow * window, gdouble w, + gdouble h) +{ + FUNCTION; + g_return_if_fail (window != NULL); + GST_LOG ("set scale w@%f, h@%f", w, h); + window->mode_scale.w = w; + window->mode_scale.h = h; + window->mode_scale.changed = TRUE; +} + +void +gst_wl_window_set_destination_mode_align (GstWlWindow * window, gdouble w, + gdouble h) +{ + FUNCTION; + g_return_if_fail (window != NULL); + GST_LOG ("set align w@%f, h@%f", w, h); + window->mode_align.w = w; + window->mode_align.h = h; + window->mode_align.changed = TRUE; } void @@ -749,7 +1127,6 @@ gst_wl_window_set_video_info_change (GstWlWindow * window, guint changed) FUNCTION; g_return_if_fail (window != NULL); window->video_info_changed = changed; - GST_INFO ("video_info_changed value is (%d)", window->video_info_changed); + GST_LOG ("video_info_changed value is (%d)", window->video_info_changed); } - #endif diff --git a/ext/wayland/wlwindow.h b/ext/wayland/wlwindow.h index 81e1009..0cc48a1 100644 --- a/ext/wayland/wlwindow.h +++ b/ext/wayland/wlwindow.h @@ -32,6 +32,29 @@ G_BEGIN_DECLS #define GST_WL_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_WL_WINDOW, GstWlWindowClass)) #define GST_IS_WL_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_WL_WINDOW)) #define GST_WL_WINDOW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_WL_WINDOW, GstWlWindowClass)) + +typedef struct +{ + guint value; + gboolean changed; +} WinGeometryValue; + +typedef struct +{ + guint x; + guint y; + guint w; + guint h; + gboolean changed; +} WinGeometryRect; + +typedef struct +{ + gdouble w; + gdouble h; + gboolean changed; +} WinGeometryRange; + typedef struct _GstWlWindow GstWlWindow; typedef struct _GstWlWindowClass GstWlWindowClass; @@ -42,19 +65,31 @@ struct _GstWlWindow GstWlDisplay *display; struct wl_surface *area_surface; struct wl_subsurface *area_subsurface; - struct wl_viewport *area_viewport; struct wl_surface *video_surface; struct wl_subsurface *video_subsurface; - struct wl_viewport *video_viewport; struct wl_shell_surface *shell_surface; -#ifdef GST_WLSINK_ENHANCEMENT +#ifndef GST_WLSINK_ENHANCEMENT /* no define */ + struct wl_viewport *video_viewport; + struct wl_viewport *area_viewport; +#else struct tizen_video_object *video_object; + struct tizen_viewport *tizen_area_viewport; + struct tizen_viewport *tizen_video_viewport; + struct tizen_destination_mode *tizen_video_dest_mode; + struct tizen_destination_mode *tizen_area_dest_mode; guint video_info_changed; /*Display geometry method */ - guint disp_geo_method; - guint rotate_angle; - guint orientation; - guint flip; + guint buffer_width, buffer_height; + guint buffer_x, buffer_y; + WinGeometryValue disp_geo_method; + WinGeometryValue rotate_angle; + WinGeometryValue flip; + WinGeometryValue follow_parent_transform; + WinGeometryRect mode_crop; + WinGeometryRect mode_offset; + WinGeometryRange mode_ratio; + WinGeometryRange mode_scale; + WinGeometryRange mode_align; #endif /* the size and position of the area_(sub)surface */ @@ -89,10 +124,14 @@ void gst_wl_window_set_render_rectangle (GstWlWindow * window, gint x, gint y, void gst_wl_window_set_video_info (GstWlWindow * window, const GstVideoInfo * info); void gst_wl_window_set_rotate_angle (GstWlWindow * window, guint rotate_angle); -void gst_wl_window_set_disp_geo_method (GstWlWindow * window, - guint disp_geo_method); -void gst_wl_window_set_orientation (GstWlWindow * window, guint orientation); void gst_wl_window_set_flip (GstWlWindow * window, guint flip); +void gst_wl_window_set_destination_mode (GstWlWindow * window, guint disp_geo_method); +void gst_wl_window_set_destination_mode_follow_parent_transform (GstWlWindow * window, gboolean follow_parent_transform); +void gst_wl_window_set_destination_mode_crop_wl_buffer (GstWlWindow * window, guint x, guint y, guint w, guint h); +void gst_wl_window_set_destination_mode_offset (GstWlWindow * window, guint x, guint y, guint w, guint h); +void gst_wl_window_set_destination_mode_ratio (GstWlWindow * window, gdouble w, gdouble h); +void gst_wl_window_set_destination_mode_scale (GstWlWindow * window, gdouble w, gdouble h); +void gst_wl_window_set_destination_mode_align (GstWlWindow * window, gdouble w, gdouble h); void gst_wl_window_set_video_info_change (GstWlWindow * window, guint changed); #endif