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 if (window->tizen_video_viewport) {
306 window->tizen_video_dest_mode =
307 tizen_viewport_get_destination_mode (window->tizen_video_viewport);
309 ("tizen_video_dest_mode(tizen_destination_mode)@%p = tizen_viewport_get_destination_mode (tizen_video_viewport@%p)",
310 window->tizen_video_dest_mode, window->tizen_video_viewport);
311 /* video surface always follow area surface by below code. */
313 ("tizen_viewport_follow_parent_transform(tizen_video_viewport@%p)",
314 window->tizen_video_viewport);
315 tizen_viewport_follow_parent_transform (window->tizen_video_viewport);
319 window->area_viewport = wl_scaler_get_viewport (display->scaler,
320 window->area_surface);
321 window->video_viewport = wl_scaler_get_viewport (display->scaler,
322 window->video_surface);
324 /* draw the area_subsurface */
325 gst_video_info_set_format (&info,
326 /* we want WL_SHM_FORMAT_XRGB8888 */
327 #if G_BYTE_ORDER == G_BIG_ENDIAN
328 GST_VIDEO_FORMAT_xRGB,
330 GST_VIDEO_FORMAT_BGRx,
334 #ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT
335 if (window->display->use_tbm) {
336 /* Inform enlightenment of surface which render video */
337 /* tizen_video(tbm) render on video_surface */
338 window->video_object =
339 tizen_video_get_object (display->tizen_video, window->video_surface);
342 gst_wl_window_mapping_sub_surface (display, window, &info);
343 #else /* open source */
345 gst_buffer_new_allocate (gst_tizen_wl_shm_allocator_get (), info.size,
347 gst_buffer_map (buf, &mapinfo, GST_MAP_WRITE);
348 *((guint32 *) mapinfo.data) = 0; /* paint it black */
349 gst_buffer_unmap (buf, &mapinfo);
351 gst_tizen_wl_shm_memory_construct_wl_buffer (gst_buffer_peek_memory (buf,
353 gwlbuf = gst_buffer_add_wl_buffer (buf, wlbuf, display);
354 gst_wl_buffer_attach (gwlbuf, window->area_surface);
356 /* at this point, the GstWlBuffer keeps the buffer
357 * alive and will free it on wl_buffer::release */
358 gst_buffer_unref (buf);
361 /* do not accept input */
362 region = wl_compositor_create_region (display->compositor);
363 GST_WARNING ("wl_region@%p = wl_compositor_create_region (wl_compositor@%p)",
364 region, display->compositor);
365 GST_WARNING ("wl_surface_set_input_region (area_surface@%p, wl_region@%p)",
366 window->area_surface, region);
367 wl_surface_set_input_region (window->area_surface, region);
368 GST_WARNING ("wl_region_destroy (wl_region@%p)", region);
369 wl_region_destroy (region);
371 region = wl_compositor_create_region (display->compositor);
372 GST_WARNING ("wl_region@%p = wl_compositor_create_region (wl_compositor@%p)",
373 region, display->compositor);
374 GST_WARNING ("wl_surface_set_input_region (video_surface@%p, wl_region@%p)",
375 window->video_surface, region);
376 wl_surface_set_input_region (window->video_surface, region);
377 GST_WARNING ("wl_region_destroy (wl_region@%p)", region);
378 wl_region_destroy (region);
380 #ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT
381 /* set area surface size by full mode(full size of parent window) , toplevel is set to fullmode too for convenient test */
382 if (window->tizen_area_viewport) {
383 int tizen_disp_mode = TIZEN_DESTINATION_MODE_TYPE_FULL;
385 window->tizen_area_dest_mode =
386 tizen_viewport_get_destination_mode (window->tizen_area_viewport);
388 ("tizen_area_dest_mode(tizen_destination_mode)@%p = tizen_viewport_get_destination_mode (tizen_area_viewport@%p)",
389 window->tizen_area_dest_mode, window->tizen_area_viewport);
390 if (window->tizen_area_dest_mode) {
392 ("tizen_destination_mode_set (tizen_destination_mode@%p, @%d, 3 is FULL)",
393 window->tizen_area_dest_mode, tizen_disp_mode);
394 tizen_destination_mode_set (window->tizen_area_dest_mode,
397 GST_WARNING ("wl_surface_commit (area_surface@%p)", window->area_surface);
398 wl_surface_commit (window->area_surface);
405 gst_wl_window_new_toplevel (GstWlDisplay * display, const GstVideoInfo * info,
406 GMutex * render_lock)
408 #ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT
412 /* not create shell_surface here for enlightenment */
413 display->need_shell_surface = TRUE;
414 window = gst_wl_window_new_internal (display, NULL, render_lock);
416 /* for tizen enlightenment */
419 window->shell_surface = wl_shell_get_shell_surface (display->shell,
420 window->area_surface);
422 if (window->shell_surface) {
424 ("wl_shell_surface_add_listener (shell_surface@%p, wl_shell_surface_listener@%p, GstWlWindow@%p",
425 window->shell_surface, &shell_surface_listener, window);
426 wl_shell_surface_add_listener (window->shell_surface,
427 &shell_surface_listener, window);
428 GST_INFO ("wl_shell_surface_set_toplevel (shell_surface@%p",
429 window->shell_surface);
430 wl_shell_surface_set_toplevel (window->shell_surface);
432 GST_ERROR ("Unable to get wl_shell_surface");
434 g_object_unref (window);
438 /* toplevel is set to fullmode for convenient test in tizen_viewport enviroment, don't use below code */
440 /* set the initial size to be the same as the reported video size */
442 gst_util_uint64_scale_int_round (info->width, info->par_n, info->par_d);
443 gst_wl_window_set_render_rectangle (window, 0, 0, width, info->height);
447 #else /* open source */
451 window = gst_wl_window_new_internal (display);
454 window->shell_surface = wl_shell_get_shell_surface (display->shell,
455 window->area_surface);
457 if (window->shell_surface) {
458 wl_shell_surface_add_listener (window->shell_surface,
459 &shell_surface_listener, window);
460 wl_shell_surface_set_toplevel (window->shell_surface);
462 GST_ERROR ("Unable to get wl_shell_surface");
464 g_object_unref (window);
468 /* set the initial size to be the same as the reported video size */
471 gst_util_uint64_scale_int_round (info->width, info->par_n, info->par_d);
472 gst_wl_window_set_render_rectangle (window, 0, 0, width, info->height);
478 #ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT
480 foreign_shell_cb_destroyed(void *data,
481 struct wtz_foreign_shell *foreign_shell)
483 GST_INFO("Destroyed the reference of foreign shell.");
487 foreign_shell_cb_destination_changed(void *data,
488 struct wtz_foreign_shell *foreign_shell,
489 int32_t width, int32_t height)
491 GST_INFO("Changed destination (%d x %d) of foreign shell.", width, height);
495 foreign_shell_cb_transform_changed(void *data,
496 struct wtz_foreign_shell *foreign_shell,
499 GST_INFO("Changed transform (%d) of foreign shell.", transform);
502 static const struct wtz_foreign_shell_listener foreign_shell_listener =
504 foreign_shell_cb_destroyed,
505 foreign_shell_cb_destination_changed,
506 foreign_shell_cb_transform_changed,
510 gst_wl_window_new_with_foreign_shell(GstWlDisplay * display)
513 struct wl_surface *video_surface;
514 struct wl_region *region;
516 g_return_val_if_fail (display, NULL);
518 video_surface = wl_compositor_create_surface (display->compositor);
519 if (!video_surface) {
520 GST_ERROR ("wl_compositor_create_surface(wl_compositor@%p) failed", display->compositor);
524 window = g_object_new (GST_TYPE_WL_WINDOW, NULL);
525 window->display = g_object_ref (display);
526 window->video_surface = video_surface;
529 ("video_surface(wl_surface)@%p = wl_compositor_create_surface(wl_compositor@%p)",
530 window->video_surface, display->compositor);
532 window->wtz_foreign_shell = wtz_importer_import_shell (display->wtz_importer,
533 window->video_surface, display->wtz_exported_shell_handle);
535 ("wtz_foreign_shell@%p = wtz_importer_import_shell(wtz_importer@%p, video_surface@%p, wtz_exported_shell_handle@%s",
536 window->wtz_foreign_shell, display->wtz_importer, window->video_surface, display->wtz_exported_shell_handle);
538 wtz_foreign_shell_add_listener (window->wtz_foreign_shell, &foreign_shell_listener, window);
540 ("wtz_foreign_shell_add_listener (wtz_foreign_shell@%p, &foreign_shell_listener@%p, window@%p)",
541 window->wtz_foreign_shell, &foreign_shell_listener, window);
543 GST_WARNING ("wl_proxy_set_queue (video_surface@%p, wl_event_queue@%p)",
544 window->video_surface, display->queue);
545 wl_proxy_set_queue ((struct wl_proxy *) window->video_surface,
548 if (window->display->use_tbm) {
549 /* Inform enlightenment of surface which render video */
550 /* tizen_video(tbm) render on video_surface */
551 window->video_object =
552 tizen_video_get_object (display->tizen_video, window->video_surface);
555 region = wl_compositor_create_region (display->compositor);
556 GST_WARNING ("wl_region@%p = wl_compositor_create_region (wl_compositor@%p)",
557 region, display->compositor);
558 GST_WARNING ("wl_surface_set_input_region (video_surface@%p, wl_region@%p)",
559 window->video_surface, region);
560 wl_surface_set_input_region (window->video_surface, region);
561 GST_WARNING ("wl_region_destroy (wl_region@%p)", region);
562 wl_region_destroy (region);
569 gst_wl_window_new_in_surface (GstWlDisplay * display,
570 struct wl_surface * parent, GMutex * render_lock)
572 #ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT
577 if (display->wtz_exported_shell_handle) {
578 window = gst_wl_window_new_with_foreign_shell (display);
582 display->use_parent_wl_surface = TRUE;
585 window = gst_wl_window_new_internal (display, parent, render_lock);
587 /* use wl_surface id */
588 window = gst_wl_window_new_internal (display, NULL, render_lock);
591 /*Area surface from App need to be under parent surface */
592 if (display->tizen_policy) {
594 ("tizen_policy_place_subsurface_below_parent (tizen_policy@%p, area_subsurface@%p)",
595 display->tizen_policy, window->area_subsurface);
596 tizen_policy_place_subsurface_below_parent (display->tizen_policy,
597 window->area_subsurface);
599 ("tizen_policy_place_subsurface_below_parent (tizen_policy@%p, video_subsurface@%p)",
600 display->tizen_policy, window->video_subsurface);
601 tizen_policy_place_subsurface_below_parent (display->tizen_policy,
602 window->video_subsurface);
609 gst_wl_window_get_display (GstWlWindow * window)
612 g_return_val_if_fail (window != NULL, NULL);
614 return g_object_ref (window->display);
618 gst_wl_window_get_wl_surface (GstWlWindow * window)
621 g_return_val_if_fail (window != NULL, NULL);
623 return window->video_surface;
627 gst_wl_window_is_toplevel (GstWlWindow * window)
630 g_return_val_if_fail (window != NULL, FALSE);
632 return (window->shell_surface != NULL);
635 #ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT
637 gst_wl_window_find_rotate_transform (guint rotate_angle)
639 gint transform = WL_OUTPUT_TRANSFORM_NORMAL;
642 GST_DEBUG ("rotate (%d)", rotate_angle);
643 switch (rotate_angle) {
645 transform = WL_OUTPUT_TRANSFORM_NORMAL;
648 transform = WL_OUTPUT_TRANSFORM_90;
651 transform = WL_OUTPUT_TRANSFORM_180;
654 transform = WL_OUTPUT_TRANSFORM_270;
661 gst_wl_window_find_flip_transform (guint flip)
663 gint transform = WL_OUTPUT_TRANSFORM_NORMAL;
666 GST_DEBUG ("flip (%d)", flip);
669 transform = WL_OUTPUT_TRANSFORM_NORMAL;
671 case FLIP_HORIZONTAL:
672 transform = WL_OUTPUT_TRANSFORM_FLIPPED;
675 transform = WL_OUTPUT_TRANSFORM_FLIPPED_180;
678 transform = WL_OUTPUT_TRANSFORM_180;
686 #ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT
688 gst_wl_window_resize_tizen_video_viewport (GstWlWindow * window,
691 gint transform = WL_OUTPUT_TRANSFORM_NORMAL;
694 g_return_if_fail (window->tizen_video_viewport != NULL);
695 g_return_if_fail (window->tizen_video_dest_mode != NULL);
697 /* Set source, wayland need to set "tizen_viewport_set_source" always when change video info,
698 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 */
699 if (window->set_source.changed) {
700 /* we have known issue about mobile team kernel, when set orign green line can be shown with tbm */
702 ("tizen_viewport_set_source (tizen_video_viewport@%p, x@%d, y@%d, w@%d, h@%d)",
703 window->tizen_video_viewport, window->set_source.x,
704 window->set_source.y, window->set_source.w, window->set_source.h);
705 tizen_viewport_set_source (window->tizen_video_viewport,
706 window->set_source.x, window->set_source.y, window->set_source.w,
707 window->set_source.h);
709 window->set_source.changed = FALSE;
712 /*set tizen destination mode */
713 if (window->disp_geo_method.changed
714 || (window->disp_geo_method.value == DISP_GEO_METHOD_CUSTOM_ROI
715 && window->roi_area_changed)) {
716 int tizen_disp_mode = -1;
717 switch (window->disp_geo_method.value) {
719 case DISP_GEO_METHOD_LETTER_BOX:
720 GST_LOG ("TIZEN_DESTINATION_MODE_TYPE_LETTER_BOX");
721 tizen_disp_mode = TIZEN_DESTINATION_MODE_TYPE_LETTER_BOX;
723 case DISP_GEO_METHOD_ORIGIN_SIZE:
724 GST_LOG ("TIZEN_DESTINATION_MODE_TYPE_ORIGIN");
725 tizen_disp_mode = TIZEN_DESTINATION_MODE_TYPE_ORIGIN;
727 case DISP_GEO_METHOD_FULL_SCREEN:
728 GST_LOG ("TIZEN_DESTINATION_MODE_TYPE_FULL");
729 tizen_disp_mode = TIZEN_DESTINATION_MODE_TYPE_FULL;
731 case DISP_GEO_METHOD_CROPPED_FULL_SCREEN:
732 GST_LOG ("TIZEN_DESTINATION_MODE_TYPE_CROPPED_FULL");
733 tizen_disp_mode = TIZEN_DESTINATION_MODE_TYPE_CROPPED_FULL;
735 case DISP_GEO_METHOD_ORIGIN_SIZE_OR_LETTER_BOX:
736 GST_LOG ("TIZEN_DESTINATION_MODE_TYPE_ORIGIN_OR_LETTER");
737 tizen_disp_mode = TIZEN_DESTINATION_MODE_TYPE_ORIGIN_OR_LETTER;
739 case DISP_GEO_METHOD_CUSTOM_ROI:
740 GST_LOG ("DISP_GEO_METHOD_CUSTOM_ROI..need to set destination ROI");
741 tizen_disp_mode = -1;
746 if (tizen_disp_mode > -1) {
748 ("tizen_destination_mode_set (tizen_destination_mode@%p, tizen_disp_mode@%d)",
749 window->tizen_video_dest_mode, tizen_disp_mode);
750 tizen_destination_mode_set (window->tizen_video_dest_mode,
753 if (window->disp_geo_method.value == DISP_GEO_METHOD_CUSTOM_ROI) {
754 /* set ROI destination */
756 ("tizen_viewport_set_destination (tizen_video_viewport(tizen_viewport)@%p, x@%d, y@%d, w@%d, h@%d)",
757 window->tizen_video_viewport, window->roi.x, window->roi.y,
758 window->roi.w, window->roi.h);
759 if (window->roi.x == 0 && window->roi.y == 0 && window->roi.w == 0
760 && window->roi.h == 0) {
761 GST_WARNING ("ROI Area isn't set");
765 tizen_viewport_set_destination (window->tizen_video_viewport,
766 window->roi.x, window->roi.y, window->roi.w, window->roi.h);
767 window->roi_area_changed = FALSE;
769 window->disp_geo_method.changed = FALSE;
775 /* 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. */
776 #ifdef ENABLE_FUNCTION
777 /* set or unset follow parent transform */
778 if (window->follow_parent_transform.changed
779 && !gst_wl_window_is_toplevel (window)) {
780 if (window->follow_parent_transform.value) {
782 ("tizen_destination_mode_follow_parent_transform (tizen_destination_mode@%p)",
783 window->tizen_area_dest_mode);
784 tizen_destination_mode_follow_parent_transform
785 (window->tizen_area_dest_mode);
787 ("tizen_destination_mode_follow_parent_transform (tizen_destination_mode@%p)",
788 window->tizen_video_dest_mode);
789 tizen_destination_mode_follow_parent_transform
790 (window->tizen_video_dest_mode);
794 ("tizen_destination_mode_unfollow_parent_transform (tizen_destination_mode@%p)",
795 window->tizen_area_dest_mode);
796 tizen_destination_mode_unfollow_parent_transform
797 (window->tizen_area_dest_mode);
799 ("tizen_destination_mode_unfollow_parent_transform (tizen_destination_mode@%p)",
800 window->tizen_video_dest_mode);
801 tizen_destination_mode_unfollow_parent_transform
802 (window->tizen_video_dest_mode);
804 window->follow_parent_transform.changed = FALSE;
808 if (window->mode_ratio.changed) {
809 wl_fixed_t f_width, f_height;
810 f_width = wl_fixed_from_double (window->mode_ratio.w);
811 f_height = wl_fixed_from_double (window->mode_ratio.h);
814 ("tizen_destination_mode_set_ratio (tizen_destination_mode@%p, wl_fixed width@%f, wl_fixed height@%f)",
815 window->tizen_video_dest_mode, window->mode_ratio.w,
816 window->mode_ratio.h);
817 tizen_destination_mode_set_ratio (window->tizen_video_dest_mode, f_width,
819 window->mode_ratio.changed = FALSE;
823 if (window->mode_offset.changed) {
825 ("tizen_destination_mode_set_offset (tizen_destination_mode@%p, x@%d, y@%d, w@%d, h@%d)",
826 window->tizen_video_dest_mode, window->mode_offset.x,
827 window->mode_offset.y, window->mode_offset.w, window->mode_offset.h);
828 tizen_destination_mode_set_offset (window->tizen_video_dest_mode,
829 window->mode_offset.x, window->mode_offset.y, window->mode_offset.w,
830 window->mode_offset.h);
831 window->mode_offset.changed = FALSE;
835 if (window->mode_scale.changed) {
836 wl_fixed_t f_width, f_height;
837 f_width = wl_fixed_from_double (window->mode_scale.w);
838 f_height = wl_fixed_from_double (window->mode_scale.h);
841 ("tizen_destination_mode_set_scale (tizen_destination_mode@%p, wl_fixed width@%f, wl_fixed height@%f)",
842 window->tizen_video_dest_mode, window->mode_scale.w,
843 window->mode_scale.h);
844 tizen_destination_mode_set_scale (window->tizen_video_dest_mode, f_width,
846 window->mode_scale.changed = FALSE;
850 if (window->mode_align.changed) {
851 wl_fixed_t f_width, f_height;
852 f_width = wl_fixed_from_double (window->mode_align.w);
853 f_height = wl_fixed_from_double (window->mode_align.h);
855 ("tizen_destination_mode_set_align (tizen_destination_mode@%p, wl_fixed_width@%f, wl_fixed_height@%f)",
856 window->tizen_video_dest_mode, window->mode_align.w,
857 window->mode_align.h);
858 tizen_destination_mode_set_align (window->tizen_video_dest_mode, f_width,
860 window->mode_align.changed = FALSE;
866 if (window->rotate_angle.changed) {
867 GST_LOG ("set rotate_angle(%d)", window->rotate_angle.value);
869 gst_wl_window_find_rotate_transform (window->rotate_angle.value);
871 ("tizen_viewport_set_transform(tizen_area_viewport@%p, transform@%d)",
872 window->tizen_area_viewport, transform);
873 tizen_viewport_set_transform (window->tizen_area_viewport, transform);
874 window->rotate_angle.changed = FALSE;
877 if (window->flip.changed) {
878 GST_LOG ("set flip(%d)", window->flip.value);
880 transform = gst_wl_window_find_flip_transform (window->flip.value);
882 ("tizen_viewport_set_transform(tizen_video_viewport@%p, transform@%d)",
883 window->tizen_video_viewport, transform);
884 tizen_viewport_set_transform (window->tizen_video_viewport, transform);
885 window->flip.changed = FALSE;
889 GST_LOG ("need to commit");
891 ("wl_surface_damage_buffer (video_surface@%p, buffer_@x%d, buffer_y@%d, buffer_w@%d, buffer_h@%d)",
892 window->video_surface, window->buffer_x, window->buffer_y,
893 window->buffer_width, window->buffer_height);
894 wl_surface_damage_buffer (window->video_surface, window->buffer_x,
895 window->buffer_y, window->buffer_width, window->buffer_height);
896 GST_INFO ("wl_surface_commit (video_surface@%p)", window->video_surface);
897 wl_surface_commit (window->video_surface);
902 gst_wl_window_resize_video_surface (GstWlWindow * window, gboolean commit)
904 GstVideoRectangle src = { 0, };
905 GstVideoRectangle dst = { 0, };
906 GstVideoRectangle res;
908 /* center the video_subsurface inside area_subsurface */
909 src.w = window->video_width;
910 src.h = window->video_height;
911 dst.w = window->render_rectangle.w;
912 dst.h = window->render_rectangle.h;
913 gst_video_sink_center_rect (src, dst, &res, TRUE);
915 wl_subsurface_set_position (window->video_subsurface, res.x, res.y);
916 wl_viewport_set_destination (window->video_viewport, res.w, res.h);
919 wl_surface_damage (window->video_surface, 0, 0, res.w, res.h);
920 wl_surface_commit (window->video_surface);
923 if (gst_wl_window_is_toplevel (window)) {
924 struct wl_region *region;
926 region = wl_compositor_create_region (window->display->compositor);
927 wl_region_add (region, 0, 0, window->render_rectangle.w,
928 window->render_rectangle.h);
929 wl_surface_set_input_region (window->area_surface, region);
930 wl_region_destroy (region);
933 /* this is saved for use in wl_surface_damage */
934 window->surface_width = res.w;
935 window->surface_height = res.h;
939 gst_wl_window_render (GstWlWindow * window, GstWlBuffer * buffer,
940 const GstVideoInfo * info)
942 #ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT
944 /* check video buffer size for wl_surface_damage_buffer */
945 if (window->buffer_width != window->display->buffer_width
946 || window->buffer_height != window->display->buffer_height) {
947 window->buffer_width = window->display->buffer_width;
948 window->buffer_height = window->display->buffer_height;
949 GST_LOG ("buffer_width(%d) buffer_height(%d)",
950 window->display->buffer_width, window->display->buffer_height);
952 GST_LOG ("buffer_width(%d) buffer_height(%d)", window->display->buffer_width,
953 window->display->buffer_height);
955 if (G_UNLIKELY (info)) {
956 window->video_width =
957 gst_util_uint64_scale_int_round (info->width, info->par_n, info->par_d);
958 window->video_height = info->height;
960 wl_subsurface_set_sync (window->video_subsurface);
961 GST_INFO ("wl_subsurface_set_sync (video_subsurface@%p)",
962 window->video_subsurface);
963 /* check video_info_changed to remove repetitive IPC */
964 if (window->video_info_changed) {
965 gst_wl_window_resize_tizen_video_viewport (window, FALSE);
966 window->video_info_changed = FALSE;
970 GST_LOG ("GstWlBuffer(%p)", buffer);
971 if (G_LIKELY (buffer))
972 gst_wl_buffer_attach (buffer, window->video_surface);
974 GST_INFO ("wl_surface_attach (video_surface@%p, NULL, 0, 0)",
975 window->video_surface);
976 wl_surface_attach (window->video_surface, NULL, 0, 0);
978 /* use tizen view port */
980 ("wl_surface_damage_buffer (video_surface@%p, buffer_x@%d, buffer_y@%d, buffer_w@%d, buffer_h@%d)",
981 window->video_surface, window->buffer_x, window->buffer_y,
982 window->buffer_width, window->buffer_height);
983 wl_surface_damage_buffer (window->video_surface, window->buffer_x,
984 window->buffer_y, window->buffer_width, window->buffer_height);
985 /* wl_surface_commit change surface state, if wl_buffer is not attached newly, then surface is not changed */
986 GST_INFO ("wl_surface_commit (video_surface@%p)", window->video_surface);
987 wl_surface_commit (window->video_surface);
989 if (G_UNLIKELY (info)) {
990 GST_INFO ("wl_surface_commit (area_surface@%p)", window->area_surface);
991 wl_surface_commit (window->area_surface);
992 GST_INFO ("wl_subsurface_set_desync (video_subsurface@%p)",
993 window->video_subsurface);
994 wl_subsurface_set_desync (window->video_subsurface);
997 wl_display_flush (window->display->display);
1001 #ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT
1003 gst_wl_window_set_roi_area (GstWlWindow * window, gint x, gint y,
1007 g_return_val_if_fail (window != NULL, FALSE);
1009 if (w < 0 || h < 0) {
1010 GST_ERROR ("Error : wrong roi size w(%d), h(%d)", w, h);
1018 GST_LOG ("set roi x(%d), y(%d), w(%d), h(%d)", x, y, w, h);
1019 window->roi_area_changed = TRUE;
1025 gst_wl_window_set_rotate_angle (GstWlWindow * window, guint rotate_angle)
1028 g_return_if_fail (window != NULL);
1029 window->rotate_angle.value = rotate_angle;
1030 GST_LOG ("rotate_angle value is (%d)", window->rotate_angle.value);
1031 window->rotate_angle.changed = TRUE;
1035 gst_wl_window_set_destination_mode (GstWlWindow * window, guint disp_geo_method)
1038 g_return_if_fail (window != NULL);
1039 window->disp_geo_method.value = disp_geo_method;
1040 GST_LOG ("disp_geo_method value is (%d)", window->disp_geo_method.value);
1041 window->disp_geo_method.changed = TRUE;
1045 gst_wl_window_set_flip (GstWlWindow * window, guint flip)
1048 g_return_if_fail (window != NULL);
1049 window->flip.value = flip;
1050 GST_LOG ("flip value is (%d)", window->flip.value);
1051 window->flip.changed = TRUE;
1055 gst_wl_window_set_source_wl_buffer (GstWlWindow * window,
1056 guint x, guint y, guint w, guint h)
1059 g_return_if_fail (window != NULL);
1060 g_return_if_fail (w > 0 && h > 0);
1061 GST_WARNING ("set video source x@%d, y@%d, w@%d, h@%d", x, y, w, h);
1062 window->set_source.x = x;
1063 window->set_source.y = y;
1064 window->set_source.w = w;
1065 window->set_source.h = h;
1066 window->set_source.changed = TRUE;
1069 #ifdef ENABLE_FUNCTION
1071 gst_wl_window_set_destination_mode_follow_parent_transform (GstWlWindow *
1072 window, gboolean follow_parent_transform)
1075 g_return_if_fail (window != NULL);
1076 window->follow_parent_transform.value = follow_parent_transform;
1077 GST_LOG ("follow_parent_transform value is (%d)",
1078 window->follow_parent_transform.value);
1079 window->follow_parent_transform.changed = TRUE;
1084 gst_wl_window_set_destination_mode_offset (GstWlWindow * window, guint x,
1085 guint y, guint w, guint h)
1088 g_return_if_fail (window != NULL);
1089 GST_LOG ("set offset x@%d, y@%d", x, y);
1090 window->mode_offset.x = x;
1091 window->mode_offset.y = y;
1092 window->mode_offset.w = w;
1093 window->mode_offset.h = h;
1094 window->mode_offset.changed = TRUE;
1098 gst_wl_window_set_destination_mode_ratio (GstWlWindow * window, gdouble w,
1102 g_return_if_fail (window != NULL);
1103 GST_LOG ("set ratio w@%f, h@%f", w, h);
1104 window->mode_ratio.w = w;
1105 window->mode_ratio.h = h;
1106 window->mode_ratio.changed = TRUE;
1110 gst_wl_window_set_destination_mode_scale (GstWlWindow * window, gdouble w,
1114 g_return_if_fail (window != NULL);
1115 GST_LOG ("set scale w@%f, h@%f", w, h);
1116 window->mode_scale.w = w;
1117 window->mode_scale.h = h;
1118 window->mode_scale.changed = TRUE;
1122 gst_wl_window_set_destination_mode_align (GstWlWindow * window, gdouble w,
1126 g_return_if_fail (window != NULL);
1127 GST_LOG ("set align w@%f, h@%f", w, h);
1128 window->mode_align.w = w;
1129 window->mode_align.h = h;
1130 window->mode_align.changed = TRUE;
1134 gst_wl_window_set_video_info_change (GstWlWindow * window, guint changed)
1137 g_return_if_fail (window != NULL);
1138 window->video_info_changed = changed;
1139 GST_LOG ("video_info_changed value is (%d)", window->video_info_changed);