1 /* GStreamer Wayland video sink
3 * Copyright (C) 2011 Intel Corporation
4 * Copyright (C) 2011 Sreerenj Balachandran <sreerenj.balachandran@intel.com>
5 * Copyright (C) 2014 Collabora Ltd.
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301 USA.
26 #ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT
27 #include "gsttizenwlsink.h"
31 #include "tizen-wlshmallocator.h"
34 GST_DEBUG_CATEGORY_EXTERN (gst_tizen_wl_debug);
35 #define GST_CAT_DEFAULT gst_tizen_wl_debug
37 G_DEFINE_TYPE (GstWlWindow, gst_wl_window, G_TYPE_OBJECT);
39 static void gst_wl_window_finalize (GObject * gobject);
42 handle_ping (void *data, struct wl_shell_surface *shell_surface,
45 wl_shell_surface_pong (shell_surface, serial);
49 handle_configure (void *data, struct wl_shell_surface *shell_surface,
50 uint32_t edges, int32_t width, int32_t height)
55 handle_popup_done (void *data, struct wl_shell_surface *shell_surface)
59 static const struct wl_shell_surface_listener shell_surface_listener = {
66 gst_wl_window_class_init (GstWlWindowClass * klass)
68 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
70 gobject_class->finalize = gst_wl_window_finalize;
74 gst_wl_window_init (GstWlWindow * self)
76 g_return_if_fail (self != NULL);
77 self->buffer_width = self->buffer_height = 0;
78 self->buffer_x = self->buffer_y = 0;
79 self->roi.x = self->roi.y = self->roi.w = self->roi.h = 0;
80 self->flip.changed = FALSE;
84 gst_wl_window_finalize (GObject * gobject)
86 GstWlWindow *self = GST_WL_WINDOW (gobject);
89 if (self->shell_surface)
90 wl_shell_surface_destroy (self->shell_surface);
92 #ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT
93 if (self->video_object)
94 tizen_video_object_destroy (self->video_object);
95 if (self->tizen_area_viewport)
96 tizen_viewport_destroy (self->tizen_area_viewport);
97 if (self->tizen_video_viewport)
98 tizen_viewport_destroy (self->tizen_video_viewport);
99 if (self->tizen_video_dest_mode)
100 tizen_destination_mode_destroy (self->tizen_video_dest_mode);
101 if (self->tizen_area_dest_mode)
102 tizen_destination_mode_destroy (self->tizen_area_dest_mode);
103 if (self->wtz_foreign_shell)
104 wtz_foreign_shell_destroy (self->wtz_foreign_shell);
106 wl_viewport_destroy (self->video_viewport);
107 wl_viewport_destroy (self->area_viewport);
109 if (self->video_subsurface)
110 wl_subsurface_destroy (self->video_subsurface);
111 if (self->video_surface)
112 wl_surface_destroy (self->video_surface);
114 if (self->area_subsurface)
115 wl_subsurface_destroy (self->area_subsurface);
116 if (self->area_surface)
117 wl_surface_destroy (self->area_surface);
119 g_clear_object (&self->display);
121 GST_WARNING ("wl_window finalize is done");
122 G_OBJECT_CLASS (gst_wl_window_parent_class)->finalize (gobject);
125 #ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT
127 gst_wl_window_mapping_sub_surface (GstWlDisplay * display, GstWlWindow * window,
130 /* A sub-surface becomes mapped, when a non-NULL wl_buffer is applied
131 * and the parent surface is mapped. To construct shm non-NULL wl_buffer,
132 * Set force_use_shm to TRUE regardless of use-tbm setting */
136 struct wl_buffer *wlbuf;
138 GstTizenWlShmAllocator *self = NULL;
141 g_return_if_fail (display != NULL);
142 g_return_if_fail (window != NULL);
143 g_return_if_fail (info != NULL);
145 display->force_use_shm = TRUE;
147 self = GST_TIZEN_WL_SHM_ALLOCATOR (gst_tizen_wl_shm_allocator_get ());
148 self->display = display;
151 gst_buffer_new_allocate (gst_tizen_wl_shm_allocator_get (), info->size,
153 gst_buffer_map (buf, &mapinfo, GST_MAP_WRITE);
154 *((guint32 *) mapinfo.data) = 0; /* paint it black */
155 gst_buffer_unmap (buf, &mapinfo);
158 gst_tizen_wl_shm_memory_construct_wl_buffer (gst_buffer_peek_memory (buf,
160 if (G_UNLIKELY (!wlbuf)) {
161 GST_ERROR ("could not create wl_buffer");
162 gst_buffer_unref (buf);
166 gwlbuf = gst_buffer_add_wl_buffer (buf, wlbuf, display);
167 gst_wl_buffer_attach (gwlbuf, window->area_surface);
169 /* for tizen view port
170 When change area_surface, we don't need to commit anymore if we do below code.
171 such as gst_wl_window_set_render_rectangle() and */
173 ("wl_surface_damage_buffer (area_surface(wl_surface)@%p, x@%d, y@%d, w@%d, h@%d)",
174 window->area_surface, 0, 0, info->width, info->height);
175 wl_surface_damage_buffer (window->area_surface, 0, 0, info->width,
177 GST_INFO ("wl_surface_commit (area_surface(wl_surface)@%p)",
178 window->area_surface);
179 wl_surface_commit (window->area_surface);
181 /* at this point, the GstWlBuffer keeps the buffer
182 * alive and will free it on wl_buffer::release */
183 gst_buffer_unref (buf);
184 display->force_use_shm = FALSE;
190 /* for enlightment, we need to get parent to create area_subsurface */
191 gst_wl_window_new_internal (GstWlDisplay * display, struct wl_surface *parent,
192 GMutex * render_lock)
194 gst_wl_window_new_internal (GstWlDisplay * display)
199 #ifndef TIZEN_FEATURE_WLSINK_ENHANCEMENT
202 struct wl_buffer *wlbuf;
205 struct wl_region *region;
208 window = g_object_new (GST_TYPE_WL_WINDOW, NULL);
209 window->display = g_object_ref (display);
210 window->render_lock = render_lock;
212 window->area_surface = wl_compositor_create_surface (display->compositor);
214 ("area_surface(wl_surface)@%p = wl_compositor_create_surface(wl_compositor@%p)",
215 window->area_surface, display->compositor);
216 window->video_surface = wl_compositor_create_surface (display->compositor);
218 ("video_surface(wl_surface)@%p = wl_compositor_create_surface(wl_compositor@%p)",
219 window->video_surface, display->compositor);
221 GST_WARNING ("wl_proxy_set_queue (area_surface@%p, wl_event_queue@%p)",
222 window->area_surface, display->queue);
223 wl_proxy_set_queue ((struct wl_proxy *) window->area_surface, display->queue);
224 GST_WARNING ("wl_proxy_set_queue (video_surface@%p, wl_event_queue@%p)",
225 window->video_surface, display->queue);
226 wl_proxy_set_queue ((struct wl_proxy *) window->video_surface,
229 #if 1 /* create shell_surface here for enlightenment */
231 if (display->need_shell_surface) {
232 /* for internal window */
234 ("wl_shell_surface@%p = wl_shell_get_shell_surface (wl_shell@%p, area_subsurface(wl_surface)@%p)",
235 window->shell_surface, display->shell, window->area_surface);
236 window->shell_surface =
237 wl_shell_get_shell_surface (display->shell, window->area_surface);
238 } else if (display->use_parent_wl_surface) {
239 #ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT
240 if (display->wl_surface_id && parent == NULL) {
241 window->area_subsurface =
242 tizen_policy_get_subsurface (display->tizen_policy,
243 window->area_surface, display->wl_surface_id);
245 ("area_subsurface(wl_subsurface)@%p = tizen_policy_get_subsurface(tizen_policy@%p, area_surface(wl_surface)@%p, wl_surface_id@%d)",
246 window->area_subsurface, display->tizen_policy, window->area_surface,
247 display->wl_surface_id);
249 ("wl_subsurface_set_desync (area_subsurface(wl_subsurface)@%p)",
250 window->area_subsurface);
251 wl_subsurface_set_desync (window->area_subsurface);
252 GST_WARNING ("wl_surface_commit (%p)", window->area_surface);
253 wl_surface_commit (window->area_surface);
255 GST_WARNING (" wl_surface parent %p", parent);
256 window->area_subsurface =
257 wl_subcompositor_get_subsurface (display->subcompositor,
258 window->area_surface, parent);
260 ("area_subsurface(wl_subsurface)@%p = wl_subcompositor_get_subsurface(wl_subcompositor@%p, area_surface(wl_surface)@%p, parent@%p)",
261 window->area_subsurface, display->subcompositor, window->area_surface,
264 ("wl_subsurface_set_desync (area_subsurface(wl_subsurface)@%p)",
265 window->area_subsurface);
266 wl_subsurface_set_desync (window->area_subsurface);
269 /*for enlightment , below code is moved */
270 window->area_subsurface =
271 wl_subcompositor_get_subsurface (display->subcompositor,
272 window->area_surface, parent);
273 wl_subsurface_set_desync (window->area_subsurface);
278 /* embed video_surface in area_surface */
279 window->video_subsurface =
280 wl_subcompositor_get_subsurface (display->subcompositor,
281 window->video_surface, window->area_surface);
283 ("video_subsurface(wl_subsurface)@%p = wl_subcompositor_get_subsurface(wl_subcompositor@%p, video_surface(wl_surface)@%p, area_surface(wl_surface)@%p)",
284 window->video_subsurface, display->subcompositor, window->video_surface,
285 window->area_surface);
287 GST_WARNING ("wl_subsurface_set_desync (video_subsurface(wl_subsurface)@%p)",
288 window->video_subsurface);
289 wl_subsurface_set_desync (window->video_subsurface);
290 GST_WARNING ("wl_surface_commit (%p)", window->video_surface);
291 wl_surface_commit (window->video_surface);
293 #ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT
294 window->tizen_area_viewport =
295 tizen_video_get_viewport (display->tizen_video, window->area_surface);
297 ("tizen_area_viewport(tizen_viewport)@%p = tizen_video_get_viewport(tizen_video@%p, area_surface(wl_surface)@%p)",
298 window->tizen_area_viewport, display->tizen_video, window->area_surface);
299 window->tizen_video_viewport =
300 tizen_video_get_viewport (display->tizen_video, window->video_surface);
302 ("tizen_video_viewport(tizen_viewport)@%p = tizen_video_get_viewport(tizen_video@%p, video_surface(wl_surface)@%p)",
303 window->tizen_video_viewport, display->tizen_video,
304 window->video_surface);
305 window->tizen_video_dest_mode =
306 tizen_viewport_get_destination_mode (window->tizen_video_viewport);
308 ("tizen_video_dest_mode(tizen_destination_mode)@%p = tizen_viewport_get_destination_mode (tizen_video_viewport@%p)",
309 window->tizen_video_dest_mode, window->tizen_video_viewport);
310 /* video surface always follow area surface by below code. */
312 ("tizen_viewport_follow_parent_transform(tizen_video_viewport@%p)",
313 window->tizen_video_viewport);
314 tizen_viewport_follow_parent_transform (window->tizen_video_viewport);
317 window->area_viewport = wl_scaler_get_viewport (display->scaler,
318 window->area_surface);
319 window->video_viewport = wl_scaler_get_viewport (display->scaler,
320 window->video_surface);
322 /* draw the area_subsurface */
323 gst_video_info_set_format (&info,
324 /* we want WL_SHM_FORMAT_XRGB8888 */
325 #if G_BYTE_ORDER == G_BIG_ENDIAN
326 GST_VIDEO_FORMAT_xRGB,
328 GST_VIDEO_FORMAT_BGRx,
332 #ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT
333 if (window->display->use_tbm) {
334 /* Inform enlightenment of surface which render video */
335 /* tizen_video(tbm) render on video_surface */
336 window->video_object =
337 tizen_video_get_object (display->tizen_video, window->video_surface);
340 gst_wl_window_mapping_sub_surface (display, window, &info);
341 #else /* open source */
343 gst_buffer_new_allocate (gst_tizen_wl_shm_allocator_get (), info.size,
345 gst_buffer_map (buf, &mapinfo, GST_MAP_WRITE);
346 *((guint32 *) mapinfo.data) = 0; /* paint it black */
347 gst_buffer_unmap (buf, &mapinfo);
349 gst_tizen_wl_shm_memory_construct_wl_buffer (gst_buffer_peek_memory (buf,
351 gwlbuf = gst_buffer_add_wl_buffer (buf, wlbuf, display);
352 gst_wl_buffer_attach (gwlbuf, window->area_surface);
354 /* at this point, the GstWlBuffer keeps the buffer
355 * alive and will free it on wl_buffer::release */
356 gst_buffer_unref (buf);
359 /* do not accept input */
360 region = wl_compositor_create_region (display->compositor);
361 GST_WARNING ("wl_region@%p = wl_compositor_create_region (wl_compositor@%p)",
362 region, display->compositor);
363 GST_WARNING ("wl_surface_set_input_region (area_surface@%p, wl_region@%p)",
364 window->area_surface, region);
365 wl_surface_set_input_region (window->area_surface, region);
366 GST_WARNING ("wl_region_destroy (wl_region@%p)", region);
367 wl_region_destroy (region);
369 region = wl_compositor_create_region (display->compositor);
370 GST_WARNING ("wl_region@%p = wl_compositor_create_region (wl_compositor@%p)",
371 region, display->compositor);
372 GST_WARNING ("wl_surface_set_input_region (video_surface@%p, wl_region@%p)",
373 window->video_surface, region);
374 wl_surface_set_input_region (window->video_surface, region);
375 GST_WARNING ("wl_region_destroy (wl_region@%p)", region);
376 wl_region_destroy (region);
378 #ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT
379 /* set area surface size by full mode(full size of parent window) , toplevel is set to fullmode too for convenient test */
380 if (window->tizen_area_viewport) {
381 int tizen_disp_mode = TIZEN_DESTINATION_MODE_TYPE_FULL;
383 window->tizen_area_dest_mode =
384 tizen_viewport_get_destination_mode (window->tizen_area_viewport);
386 ("tizen_area_dest_mode(tizen_destination_mode)@%p = tizen_viewport_get_destination_mode (tizen_area_viewport@%p)",
387 window->tizen_area_dest_mode, window->tizen_area_viewport);
388 if (window->tizen_area_dest_mode) {
390 ("tizen_destination_mode_set (tizen_destination_mode@%p, @%d, 3 is FULL)",
391 window->tizen_area_dest_mode, tizen_disp_mode);
392 tizen_destination_mode_set (window->tizen_area_dest_mode,
395 GST_WARNING ("wl_surface_commit (area_surface@%p)", window->area_surface);
396 wl_surface_commit (window->area_surface);
403 gst_wl_window_new_toplevel (GstWlDisplay * display, const GstVideoInfo * info,
404 GMutex * render_lock)
406 #ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT
410 /* not create shell_surface here for enlightenment */
411 display->need_shell_surface = TRUE;
412 window = gst_wl_window_new_internal (display, NULL, render_lock);
414 /* for tizen enlightenment */
417 window->shell_surface = wl_shell_get_shell_surface (display->shell,
418 window->area_surface);
420 if (window->shell_surface) {
422 ("wl_shell_surface_add_listener (shell_surface@%p, wl_shell_surface_listener@%p, GstWlWindow@%p",
423 window->shell_surface, &shell_surface_listener, window);
424 wl_shell_surface_add_listener (window->shell_surface,
425 &shell_surface_listener, window);
426 GST_INFO ("wl_shell_surface_set_toplevel (shell_surface@%p",
427 window->shell_surface);
428 wl_shell_surface_set_toplevel (window->shell_surface);
430 GST_ERROR ("Unable to get wl_shell_surface");
432 g_object_unref (window);
436 /* toplevel is set to fullmode for convenient test in tizen_viewport enviroment, don't use below code */
438 /* set the initial size to be the same as the reported video size */
440 gst_util_uint64_scale_int_round (info->width, info->par_n, info->par_d);
441 gst_wl_window_set_render_rectangle (window, 0, 0, width, info->height);
445 #else /* open source */
449 window = gst_wl_window_new_internal (display);
452 window->shell_surface = wl_shell_get_shell_surface (display->shell,
453 window->area_surface);
455 if (window->shell_surface) {
456 wl_shell_surface_add_listener (window->shell_surface,
457 &shell_surface_listener, window);
458 wl_shell_surface_set_toplevel (window->shell_surface);
460 GST_ERROR ("Unable to get wl_shell_surface");
462 g_object_unref (window);
466 /* set the initial size to be the same as the reported video size */
469 gst_util_uint64_scale_int_round (info->width, info->par_n, info->par_d);
470 gst_wl_window_set_render_rectangle (window, 0, 0, width, info->height);
476 #ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT
478 foreign_shell_cb_destroyed(void *data,
479 struct wtz_foreign_shell *foreign_shell)
481 GST_INFO("Destroyed the reference of foreign shell.");
485 foreign_shell_cb_destination_changed(void *data,
486 struct wtz_foreign_shell *foreign_shell,
487 int32_t width, int32_t height)
489 GST_INFO("Changed destination (%d x %d) of foreign shell.", width, height);
493 foreign_shell_cb_transform_changed(void *data,
494 struct wtz_foreign_shell *foreign_shell,
497 GST_INFO("Changed transform (%d) of foreign shell.", transform);
500 static const struct wtz_foreign_shell_listener foreign_shell_listener =
502 foreign_shell_cb_destroyed,
503 foreign_shell_cb_destination_changed,
504 foreign_shell_cb_transform_changed,
508 gst_wl_window_new_with_foreign_shell(GstWlDisplay * display)
511 struct wl_surface *video_surface;
512 struct wl_region *region;
514 g_return_val_if_fail (display, NULL);
516 video_surface = wl_compositor_create_surface (display->compositor);
517 if (!video_surface) {
518 GST_ERROR ("wl_compositor_create_surface(wl_compositor@%p) failed", display->compositor);
522 window = g_object_new (GST_TYPE_WL_WINDOW, NULL);
523 window->display = g_object_ref (display);
524 window->video_surface = video_surface;
527 ("video_surface(wl_surface)@%p = wl_compositor_create_surface(wl_compositor@%p)",
528 window->video_surface, display->compositor);
530 window->wtz_foreign_shell = wtz_importer_import_shell (display->wtz_importer,
531 window->video_surface, display->wtz_exported_shell_handle);
533 ("wtz_foreign_shell@%p = wtz_importer_import_shell(wtz_importer@%p, video_surface@%p, wtz_exported_shell_handle@%s",
534 window->wtz_foreign_shell, display->wtz_importer, window->video_surface, display->wtz_exported_shell_handle);
536 wtz_foreign_shell_add_listener (window->wtz_foreign_shell, &foreign_shell_listener, window);
538 ("wtz_foreign_shell_add_listener (wtz_foreign_shell@%p, &foreign_shell_listener@%p, window@%p)",
539 window->wtz_foreign_shell, &foreign_shell_listener, window);
541 GST_WARNING ("wl_proxy_set_queue (video_surface@%p, wl_event_queue@%p)",
542 window->video_surface, display->queue);
543 wl_proxy_set_queue ((struct wl_proxy *) window->video_surface,
546 if (window->display->use_tbm) {
547 /* Inform enlightenment of surface which render video */
548 /* tizen_video(tbm) render on video_surface */
549 window->video_object =
550 tizen_video_get_object (display->tizen_video, window->video_surface);
553 region = wl_compositor_create_region (display->compositor);
554 GST_WARNING ("wl_region@%p = wl_compositor_create_region (wl_compositor@%p)",
555 region, display->compositor);
556 GST_WARNING ("wl_surface_set_input_region (video_surface@%p, wl_region@%p)",
557 window->video_surface, region);
558 wl_surface_set_input_region (window->video_surface, region);
559 GST_WARNING ("wl_region_destroy (wl_region@%p)", region);
560 wl_region_destroy (region);
567 gst_wl_window_new_in_surface (GstWlDisplay * display,
568 struct wl_surface * parent, GMutex * render_lock)
570 #ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT
575 if (display->wtz_exported_shell_handle) {
576 window = gst_wl_window_new_with_foreign_shell (display);
580 display->use_parent_wl_surface = TRUE;
583 window = gst_wl_window_new_internal (display, parent, render_lock);
585 /* use wl_surface id */
586 window = gst_wl_window_new_internal (display, NULL, render_lock);
589 /*Area surface from App need to be under parent surface */
590 if (display->tizen_policy) {
592 ("tizen_policy_place_subsurface_below_parent (tizen_policy@%p, area_subsurface@%p)",
593 display->tizen_policy, window->area_subsurface);
594 tizen_policy_place_subsurface_below_parent (display->tizen_policy,
595 window->area_subsurface);
597 ("tizen_policy_place_subsurface_below_parent (tizen_policy@%p, video_subsurface@%p)",
598 display->tizen_policy, window->video_subsurface);
599 tizen_policy_place_subsurface_below_parent (display->tizen_policy,
600 window->video_subsurface);
607 gst_wl_window_get_display (GstWlWindow * window)
610 g_return_val_if_fail (window != NULL, NULL);
612 return g_object_ref (window->display);
616 gst_wl_window_get_wl_surface (GstWlWindow * window)
619 g_return_val_if_fail (window != NULL, NULL);
621 return window->video_surface;
625 gst_wl_window_is_toplevel (GstWlWindow * window)
628 g_return_val_if_fail (window != NULL, FALSE);
630 return (window->shell_surface != NULL);
633 #ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT
635 gst_wl_window_find_rotate_transform (guint rotate_angle)
637 gint transform = WL_OUTPUT_TRANSFORM_NORMAL;
640 GST_DEBUG ("rotate (%d)", rotate_angle);
641 switch (rotate_angle) {
643 transform = WL_OUTPUT_TRANSFORM_NORMAL;
646 transform = WL_OUTPUT_TRANSFORM_90;
649 transform = WL_OUTPUT_TRANSFORM_180;
652 transform = WL_OUTPUT_TRANSFORM_270;
659 gst_wl_window_find_flip_transform (guint flip)
661 gint transform = WL_OUTPUT_TRANSFORM_NORMAL;
664 GST_DEBUG ("flip (%d)", flip);
667 transform = WL_OUTPUT_TRANSFORM_NORMAL;
669 case FLIP_HORIZONTAL:
670 transform = WL_OUTPUT_TRANSFORM_FLIPPED;
673 transform = WL_OUTPUT_TRANSFORM_FLIPPED_180;
676 transform = WL_OUTPUT_TRANSFORM_180;
684 #ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT
686 gst_wl_window_resize_tizen_video_viewport (GstWlWindow * window,
689 gint transform = WL_OUTPUT_TRANSFORM_NORMAL;
692 g_return_if_fail (window->tizen_video_viewport != NULL);
693 g_return_if_fail (window->tizen_video_dest_mode != NULL);
695 /* Set source, wayland need to set "tizen_viewport_set_source" always when change video info,
696 aligned video issue=> ex) 854 x 480 video : aligned buffer size 864 x 480, so we need to set original video size by set source */
697 if (window->set_source.changed) {
698 /* we have known issue about mobile team kernel, when set orign green line can be shown with tbm */
700 ("tizen_viewport_set_source (tizen_video_viewport@%p, x@%d, y@%d, w@%d, h@%d)",
701 window->tizen_video_viewport, window->set_source.x,
702 window->set_source.y, window->set_source.w, window->set_source.h);
703 tizen_viewport_set_source (window->tizen_video_viewport,
704 window->set_source.x, window->set_source.y, window->set_source.w,
705 window->set_source.h);
707 window->set_source.changed = FALSE;
710 /*set tizen destination mode */
711 if (window->disp_geo_method.changed
712 || (window->disp_geo_method.value == DISP_GEO_METHOD_CUSTOM_ROI
713 && window->roi_area_changed)) {
714 int tizen_disp_mode = -1;
715 switch (window->disp_geo_method.value) {
717 case DISP_GEO_METHOD_LETTER_BOX:
718 GST_LOG ("TIZEN_DESTINATION_MODE_TYPE_LETTER_BOX");
719 tizen_disp_mode = TIZEN_DESTINATION_MODE_TYPE_LETTER_BOX;
721 case DISP_GEO_METHOD_ORIGIN_SIZE:
722 GST_LOG ("TIZEN_DESTINATION_MODE_TYPE_ORIGIN");
723 tizen_disp_mode = TIZEN_DESTINATION_MODE_TYPE_ORIGIN;
725 case DISP_GEO_METHOD_FULL_SCREEN:
726 GST_LOG ("TIZEN_DESTINATION_MODE_TYPE_FULL");
727 tizen_disp_mode = TIZEN_DESTINATION_MODE_TYPE_FULL;
729 case DISP_GEO_METHOD_CROPPED_FULL_SCREEN:
730 GST_LOG ("TIZEN_DESTINATION_MODE_TYPE_CROPPED_FULL");
731 tizen_disp_mode = TIZEN_DESTINATION_MODE_TYPE_CROPPED_FULL;
733 case DISP_GEO_METHOD_ORIGIN_SIZE_OR_LETTER_BOX:
734 GST_LOG ("TIZEN_DESTINATION_MODE_TYPE_ORIGIN_OR_LETTER");
735 tizen_disp_mode = TIZEN_DESTINATION_MODE_TYPE_ORIGIN_OR_LETTER;
737 case DISP_GEO_METHOD_CUSTOM_ROI:
738 GST_LOG ("DISP_GEO_METHOD_CUSTOM_ROI..need to set destination ROI");
739 tizen_disp_mode = -1;
744 if (tizen_disp_mode > -1) {
746 ("tizen_destination_mode_set (tizen_destination_mode@%p, tizen_disp_mode@%d)",
747 window->tizen_video_dest_mode, tizen_disp_mode);
748 tizen_destination_mode_set (window->tizen_video_dest_mode,
751 if (window->disp_geo_method.value == DISP_GEO_METHOD_CUSTOM_ROI) {
752 /* set ROI destination */
754 ("tizen_viewport_set_destination (tizen_video_viewport(tizen_viewport)@%p, x@%d, y@%d, w@%d, h@%d)",
755 window->tizen_video_viewport, window->roi.x, window->roi.y,
756 window->roi.w, window->roi.h);
757 if (window->roi.x == 0 && window->roi.y == 0 && window->roi.w == 0
758 && window->roi.h == 0) {
759 GST_WARNING ("ROI Area isn't set");
763 tizen_viewport_set_destination (window->tizen_video_viewport,
764 window->roi.x, window->roi.y, window->roi.w, window->roi.h);
765 window->roi_area_changed = FALSE;
767 window->disp_geo_method.changed = FALSE;
773 /* Even though area_viewport is set to ROI mode, we can set below functions too if video_viewport is set to tizen_destination_mode_set. */
774 #ifdef ENABLE_FUNCTION
775 /* set or unset follow parent transform */
776 if (window->follow_parent_transform.changed
777 && !gst_wl_window_is_toplevel (window)) {
778 if (window->follow_parent_transform.value) {
780 ("tizen_destination_mode_follow_parent_transform (tizen_destination_mode@%p)",
781 window->tizen_area_dest_mode);
782 tizen_destination_mode_follow_parent_transform
783 (window->tizen_area_dest_mode);
785 ("tizen_destination_mode_follow_parent_transform (tizen_destination_mode@%p)",
786 window->tizen_video_dest_mode);
787 tizen_destination_mode_follow_parent_transform
788 (window->tizen_video_dest_mode);
792 ("tizen_destination_mode_unfollow_parent_transform (tizen_destination_mode@%p)",
793 window->tizen_area_dest_mode);
794 tizen_destination_mode_unfollow_parent_transform
795 (window->tizen_area_dest_mode);
797 ("tizen_destination_mode_unfollow_parent_transform (tizen_destination_mode@%p)",
798 window->tizen_video_dest_mode);
799 tizen_destination_mode_unfollow_parent_transform
800 (window->tizen_video_dest_mode);
802 window->follow_parent_transform.changed = FALSE;
806 if (window->mode_ratio.changed) {
807 wl_fixed_t f_width, f_height;
808 f_width = wl_fixed_from_double (window->mode_ratio.w);
809 f_height = wl_fixed_from_double (window->mode_ratio.h);
812 ("tizen_destination_mode_set_ratio (tizen_destination_mode@%p, wl_fixed width@%f, wl_fixed height@%f)",
813 window->tizen_video_dest_mode, window->mode_ratio.w,
814 window->mode_ratio.h);
815 tizen_destination_mode_set_ratio (window->tizen_video_dest_mode, f_width,
817 window->mode_ratio.changed = FALSE;
821 if (window->mode_offset.changed) {
823 ("tizen_destination_mode_set_offset (tizen_destination_mode@%p, x@%d, y@%d, w@%d, h@%d)",
824 window->tizen_video_dest_mode, window->mode_offset.x,
825 window->mode_offset.y, window->mode_offset.w, window->mode_offset.h);
826 tizen_destination_mode_set_offset (window->tizen_video_dest_mode,
827 window->mode_offset.x, window->mode_offset.y, window->mode_offset.w,
828 window->mode_offset.h);
829 window->mode_offset.changed = FALSE;
833 if (window->mode_scale.changed) {
834 wl_fixed_t f_width, f_height;
835 f_width = wl_fixed_from_double (window->mode_scale.w);
836 f_height = wl_fixed_from_double (window->mode_scale.h);
839 ("tizen_destination_mode_set_scale (tizen_destination_mode@%p, wl_fixed width@%f, wl_fixed height@%f)",
840 window->tizen_video_dest_mode, window->mode_scale.w,
841 window->mode_scale.h);
842 tizen_destination_mode_set_scale (window->tizen_video_dest_mode, f_width,
844 window->mode_scale.changed = FALSE;
848 if (window->mode_align.changed) {
849 wl_fixed_t f_width, f_height;
850 f_width = wl_fixed_from_double (window->mode_align.w);
851 f_height = wl_fixed_from_double (window->mode_align.h);
853 ("tizen_destination_mode_set_align (tizen_destination_mode@%p, wl_fixed_width@%f, wl_fixed_height@%f)",
854 window->tizen_video_dest_mode, window->mode_align.w,
855 window->mode_align.h);
856 tizen_destination_mode_set_align (window->tizen_video_dest_mode, f_width,
858 window->mode_align.changed = FALSE;
864 if (window->rotate_angle.changed) {
865 GST_LOG ("set rotate_angle(%d)", window->rotate_angle.value);
867 gst_wl_window_find_rotate_transform (window->rotate_angle.value);
869 ("tizen_viewport_set_transform(tizen_area_viewport@%p, transform@%d)",
870 window->tizen_area_viewport, transform);
871 tizen_viewport_set_transform (window->tizen_area_viewport, transform);
872 window->rotate_angle.changed = FALSE;
875 if (window->flip.changed) {
876 GST_LOG ("set flip(%d)", window->flip.value);
878 transform = gst_wl_window_find_flip_transform (window->flip.value);
880 ("tizen_viewport_set_transform(tizen_video_viewport@%p, transform@%d)",
881 window->tizen_video_viewport, transform);
882 tizen_viewport_set_transform (window->tizen_video_viewport, transform);
883 window->flip.changed = FALSE;
887 GST_LOG ("need to commit");
889 ("wl_surface_damage_buffer (video_surface@%p, buffer_@x%d, buffer_y@%d, buffer_w@%d, buffer_h@%d)",
890 window->video_surface, window->buffer_x, window->buffer_y,
891 window->buffer_width, window->buffer_height);
892 wl_surface_damage_buffer (window->video_surface, window->buffer_x,
893 window->buffer_y, window->buffer_width, window->buffer_height);
894 GST_INFO ("wl_surface_commit (video_surface@%p)", window->video_surface);
895 wl_surface_commit (window->video_surface);
900 gst_wl_window_resize_video_surface (GstWlWindow * window, gboolean commit)
902 GstVideoRectangle src = { 0, };
903 GstVideoRectangle dst = { 0, };
904 GstVideoRectangle res;
906 /* center the video_subsurface inside area_subsurface */
907 src.w = window->video_width;
908 src.h = window->video_height;
909 dst.w = window->render_rectangle.w;
910 dst.h = window->render_rectangle.h;
911 gst_video_sink_center_rect (src, dst, &res, TRUE);
913 wl_subsurface_set_position (window->video_subsurface, res.x, res.y);
914 wl_viewport_set_destination (window->video_viewport, res.w, res.h);
917 wl_surface_damage (window->video_surface, 0, 0, res.w, res.h);
918 wl_surface_commit (window->video_surface);
921 if (gst_wl_window_is_toplevel (window)) {
922 struct wl_region *region;
924 region = wl_compositor_create_region (window->display->compositor);
925 wl_region_add (region, 0, 0, window->render_rectangle.w,
926 window->render_rectangle.h);
927 wl_surface_set_input_region (window->area_surface, region);
928 wl_region_destroy (region);
931 /* this is saved for use in wl_surface_damage */
932 window->surface_width = res.w;
933 window->surface_height = res.h;
937 gst_wl_window_render (GstWlWindow * window, GstWlBuffer * buffer,
938 const GstVideoInfo * info)
940 #ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT
942 /* check video buffer size for wl_surface_damage_buffer */
943 if (window->buffer_width != window->display->buffer_width
944 || window->buffer_height != window->display->buffer_height) {
945 window->buffer_width = window->display->buffer_width;
946 window->buffer_height = window->display->buffer_height;
947 GST_LOG ("buffer_width(%d) buffer_height(%d)",
948 window->display->buffer_width, window->display->buffer_height);
950 GST_LOG ("buffer_width(%d) buffer_height(%d)", window->display->buffer_width,
951 window->display->buffer_height);
953 if (G_UNLIKELY (info)) {
954 window->video_width =
955 gst_util_uint64_scale_int_round (info->width, info->par_n, info->par_d);
956 window->video_height = info->height;
958 wl_subsurface_set_sync (window->video_subsurface);
959 GST_INFO ("wl_subsurface_set_sync (video_subsurface@%p)",
960 window->video_subsurface);
961 /* check video_info_changed to remove repetitive IPC */
962 if (window->video_info_changed) {
963 gst_wl_window_resize_tizen_video_viewport (window, FALSE);
964 window->video_info_changed = FALSE;
968 GST_LOG ("GstWlBuffer(%p)", buffer);
969 if (G_LIKELY (buffer))
970 gst_wl_buffer_attach (buffer, window->video_surface);
972 GST_INFO ("wl_surface_attach (video_surface@%p, NULL, 0, 0)",
973 window->video_surface);
974 wl_surface_attach (window->video_surface, NULL, 0, 0);
976 /* use tizen view port */
978 ("wl_surface_damage_buffer (video_surface@%p, buffer_x@%d, buffer_y@%d, buffer_w@%d, buffer_h@%d)",
979 window->video_surface, window->buffer_x, window->buffer_y,
980 window->buffer_width, window->buffer_height);
981 wl_surface_damage_buffer (window->video_surface, window->buffer_x,
982 window->buffer_y, window->buffer_width, window->buffer_height);
983 /* wl_surface_commit change surface state, if wl_buffer is not attached newly, then surface is not changed */
984 GST_INFO ("wl_surface_commit (video_surface@%p)", window->video_surface);
985 wl_surface_commit (window->video_surface);
987 if (G_UNLIKELY (info)) {
988 GST_INFO ("wl_surface_commit (area_surface@%p)", window->area_surface);
989 wl_surface_commit (window->area_surface);
990 GST_INFO ("wl_subsurface_set_desync (video_subsurface@%p)",
991 window->video_subsurface);
992 wl_subsurface_set_desync (window->video_subsurface);
995 wl_display_flush (window->display->display);
999 #ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT
1001 gst_wl_window_set_roi_area (GstWlWindow * window, gint x, gint y,
1005 g_return_val_if_fail (window != NULL, FALSE);
1007 if (w < 0 || h < 0) {
1008 GST_ERROR ("Error : wrong roi size w(%d), h(%d)", w, h);
1016 GST_LOG ("set roi x(%d), y(%d), w(%d), h(%d)", x, y, w, h);
1017 window->roi_area_changed = TRUE;
1023 gst_wl_window_set_rotate_angle (GstWlWindow * window, guint rotate_angle)
1026 g_return_if_fail (window != NULL);
1027 window->rotate_angle.value = rotate_angle;
1028 GST_LOG ("rotate_angle value is (%d)", window->rotate_angle.value);
1029 window->rotate_angle.changed = TRUE;
1033 gst_wl_window_set_destination_mode (GstWlWindow * window, guint disp_geo_method)
1036 g_return_if_fail (window != NULL);
1037 window->disp_geo_method.value = disp_geo_method;
1038 GST_LOG ("disp_geo_method value is (%d)", window->disp_geo_method.value);
1039 window->disp_geo_method.changed = TRUE;
1043 gst_wl_window_set_flip (GstWlWindow * window, guint flip)
1046 g_return_if_fail (window != NULL);
1047 window->flip.value = flip;
1048 GST_LOG ("flip value is (%d)", window->flip.value);
1049 window->flip.changed = TRUE;
1053 gst_wl_window_set_source_wl_buffer (GstWlWindow * window,
1054 guint x, guint y, guint w, guint h)
1057 g_return_if_fail (window != NULL);
1058 g_return_if_fail (w > 0 && h > 0);
1059 GST_WARNING ("set video source x@%d, y@%d, w@%d, h@%d", x, y, w, h);
1060 window->set_source.x = x;
1061 window->set_source.y = y;
1062 window->set_source.w = w;
1063 window->set_source.h = h;
1064 window->set_source.changed = TRUE;
1067 #ifdef ENABLE_FUNCTION
1069 gst_wl_window_set_destination_mode_follow_parent_transform (GstWlWindow *
1070 window, gboolean follow_parent_transform)
1073 g_return_if_fail (window != NULL);
1074 window->follow_parent_transform.value = follow_parent_transform;
1075 GST_LOG ("follow_parent_transform value is (%d)",
1076 window->follow_parent_transform.value);
1077 window->follow_parent_transform.changed = TRUE;
1082 gst_wl_window_set_destination_mode_offset (GstWlWindow * window, guint x,
1083 guint y, guint w, guint h)
1086 g_return_if_fail (window != NULL);
1087 GST_LOG ("set offset x@%d, y@%d", x, y);
1088 window->mode_offset.x = x;
1089 window->mode_offset.y = y;
1090 window->mode_offset.w = w;
1091 window->mode_offset.h = h;
1092 window->mode_offset.changed = TRUE;
1096 gst_wl_window_set_destination_mode_ratio (GstWlWindow * window, gdouble w,
1100 g_return_if_fail (window != NULL);
1101 GST_LOG ("set ratio w@%f, h@%f", w, h);
1102 window->mode_ratio.w = w;
1103 window->mode_ratio.h = h;
1104 window->mode_ratio.changed = TRUE;
1108 gst_wl_window_set_destination_mode_scale (GstWlWindow * window, gdouble w,
1112 g_return_if_fail (window != NULL);
1113 GST_LOG ("set scale w@%f, h@%f", w, h);
1114 window->mode_scale.w = w;
1115 window->mode_scale.h = h;
1116 window->mode_scale.changed = TRUE;
1120 gst_wl_window_set_destination_mode_align (GstWlWindow * window, gdouble w,
1124 g_return_if_fail (window != NULL);
1125 GST_LOG ("set align w@%f, h@%f", w, h);
1126 window->mode_align.w = w;
1127 window->mode_align.h = h;
1128 window->mode_align.changed = TRUE;
1132 gst_wl_window_set_video_info_change (GstWlWindow * window, guint changed)
1135 g_return_if_fail (window != NULL);
1136 window->video_info_changed = changed;
1137 GST_LOG ("video_info_changed value is (%d)", window->video_info_changed);