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 "gstwaylandsink.h"
31 #include "wlshmallocator.h"
37 ROTATE_0_FLIP_HORIZONTAL,
38 ROTATE_0_FLIP_VERTICAL,
40 ROTATE_90_FLIP_NONE = 10,
41 ROTATE_90_FLIP_HORIZONTAL,
42 ROTATE_90_FLIP_VERTICAL,
44 ROTATE_180_FLIP_NONE = 20,
45 ROTATE_180_FLIP_HORIZONTAL,
46 ROTATE_180_FLIP_VERTICAL,
48 ROTATE_270_FLIP_NONE = 30,
49 ROTATE_270_FLIP_HORIZONTAL,
50 ROTATE_270_FLIP_VERTICAL,
55 GST_DEBUG_CATEGORY_EXTERN (gstwayland_debug);
56 #define GST_CAT_DEFAULT gstwayland_debug
58 G_DEFINE_TYPE (GstWlWindow, gst_wl_window, G_TYPE_OBJECT);
60 static void gst_wl_window_finalize (GObject * gobject);
63 handle_ping (void *data, struct wl_shell_surface *shell_surface,
66 wl_shell_surface_pong (shell_surface, serial);
70 handle_configure (void *data, struct wl_shell_surface *shell_surface,
71 uint32_t edges, int32_t width, int32_t height)
76 handle_popup_done (void *data, struct wl_shell_surface *shell_surface)
80 static const struct wl_shell_surface_listener shell_surface_listener = {
87 gst_wl_window_class_init (GstWlWindowClass * klass)
89 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
91 gobject_class->finalize = gst_wl_window_finalize;
95 gst_wl_window_init (GstWlWindow * self)
97 g_return_if_fail (self != NULL);
98 self->buffer_width = self->buffer_height = self->buffer_x = self->buffer_y =
103 gst_wl_window_finalize (GObject * gobject)
105 GstWlWindow *self = GST_WL_WINDOW (gobject);
108 if (self->shell_surface) {
109 wl_shell_surface_destroy (self->shell_surface);
111 #ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT
112 if (self->video_object)
113 tizen_video_object_destroy (self->video_object);
114 if (self->tizen_area_viewport)
115 tizen_viewport_destroy (self->tizen_area_viewport);
116 if (self->tizen_video_viewport)
117 tizen_viewport_destroy (self->tizen_video_viewport);
118 if (self->tizen_video_dest_mode)
119 tizen_destination_mode_destroy (self->tizen_video_dest_mode);
120 if (self->tizen_area_dest_mode)
121 tizen_destination_mode_destroy (self->tizen_area_dest_mode);
123 wl_viewport_destroy (self->video_viewport);
124 wl_viewport_destroy (self->area_viewport);
126 wl_subsurface_destroy (self->video_subsurface);
127 wl_surface_destroy (self->video_surface);
129 if (self->area_subsurface) {
130 wl_subsurface_destroy (self->area_subsurface);
133 wl_surface_destroy (self->area_surface);
135 g_clear_object (&self->display);
137 G_OBJECT_CLASS (gst_wl_window_parent_class)->finalize (gobject);
140 #ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT
142 gst_wl_window_map_sub_surface (GstWlDisplay * display, GstWlWindow * window,
145 /* A sub-surface becomes mapped, when a non-NULL wl_buffer is applied
146 * and the parent surface is mapped */
149 struct wl_buffer *wlbuf;
151 GstWlShmAllocator *self = NULL;
154 g_return_if_fail (display != NULL);
155 g_return_if_fail (window != NULL);
156 g_return_if_fail (info != NULL);
158 self = GST_WL_SHM_ALLOCATOR (gst_wl_shm_allocator_get ());
159 self->display = display;
161 buf = gst_buffer_new_allocate (gst_wl_shm_allocator_get (), info->size, NULL);
162 gst_buffer_map (buf, &mapinfo, GST_MAP_WRITE);
163 *((guint32 *) mapinfo.data) = 0; /* paint it black */
164 gst_buffer_unmap (buf, &mapinfo);
166 gst_wl_shm_memory_construct_wl_buffer (gst_buffer_peek_memory (buf, 0),
169 gwlbuf = gst_buffer_add_wl_buffer (buf, wlbuf, display);
170 gst_wl_buffer_attach (gwlbuf, window->area_surface);
172 /* for tizen view port
173 When change area_surface, we don't need to commit anymore if we do below code.
174 such as gst_wl_window_set_render_rectangle() and */
176 ("wl_surface_damage_buffer (area_surface(wl_surface)@%p, x@%d, y@%d, w@%d, h@%d)",
177 window->area_surface, 0, 0, info->width, info->height);
178 wl_surface_damage_buffer (window->area_surface, 0, 0, info->width,
180 GST_INFO ("wl_surface_commit (area_surface(wl_surface)@%p)",
181 window->area_surface);
182 wl_surface_commit (window->area_surface);
184 /* at this point, the GstWlBuffer keeps the buffer
185 * alive and will free it on wl_buffer::release */
186 gst_buffer_unref (buf);
192 /* for enlightment, we need to get parent to create area_subsurface */
193 gst_wl_window_new_internal (GstWlDisplay * display, struct wl_surface *parent)
195 gst_wl_window_new_internal (GstWlDisplay * display)
200 #ifndef TIZEN_FEATURE_WLSINK_ENHANCEMENT
203 struct wl_buffer *wlbuf;
206 struct wl_region *region;
209 window = g_object_new (GST_TYPE_WL_WINDOW, NULL);
210 window->display = g_object_ref (display);
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_INFO ("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_INFO ("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);
248 GST_INFO ("wl_subsurface_set_desync (area_subsurface(wl_subsurface)@%p)",
249 window->area_subsurface);
250 wl_subsurface_set_desync (window->area_subsurface);
251 GST_INFO ("wl_surface_commit (%p)", window->area_surface);
252 wl_surface_commit (window->area_surface);
254 GST_INFO (" wl_surface parent %p", parent);
255 window->area_subsurface =
256 wl_subcompositor_get_subsurface (display->subcompositor,
257 window->area_surface, parent);
259 ("area_subsurface(wl_subsurface)@%p = wl_subcompositor_get_subsurface(wl_subcompositor@%p, area_surface(wl_surface)@%p, parent@%p)",
260 window->area_subsurface, display->subcompositor, window->area_surface,
262 GST_INFO ("wl_subsurface_set_desync (area_subsurface(wl_subsurface)@%p)",
263 window->area_subsurface);
264 wl_subsurface_set_desync (window->area_subsurface);
267 /*for enlightment , below code is moved */
268 window->area_subsurface =
269 wl_subcompositor_get_subsurface (display->subcompositor,
270 window->area_surface, parent);
271 wl_subsurface_set_desync (window->area_subsurface);
276 /* embed video_surface in area_surface */
277 window->video_subsurface =
278 wl_subcompositor_get_subsurface (display->subcompositor,
279 window->video_surface, window->area_surface);
281 ("video_subsurface(wl_subsurface)@%p = wl_subcompositor_get_subsurface(wl_subcompositor@%p, video_surface(wl_surface)@%p, area_surface(wl_surface)@%p)",
282 window->video_subsurface, display->subcompositor, window->video_surface,
283 window->area_surface);
285 GST_INFO ("wl_subsurface_set_desync (video_subsurface(wl_subsurface)@%p)",
286 window->video_subsurface);
287 wl_subsurface_set_desync (window->video_subsurface);
288 GST_INFO ("wl_surface_commit (%p)", window->video_surface);
289 wl_surface_commit (window->video_surface);
291 #ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT
292 window->tizen_area_viewport =
293 tizen_video_get_viewport (display->tizen_video, window->area_surface);
295 ("tizen_area_viewport(tizen_viewport)@%p = tizen_video_get_viewport(tizen_video@%p, area_surface(wl_surface)@%p)",
296 window->tizen_area_viewport, display->tizen_video, window->area_surface);
297 window->tizen_video_viewport =
298 tizen_video_get_viewport (display->tizen_video, window->video_surface);
300 ("tizen_video_viewport(tizen_viewport)@%p = tizen_video_get_viewport(tizen_video@%p, video_surface(wl_surface)@%p)",
301 window->tizen_video_viewport, display->tizen_video,
302 window->video_surface);
303 window->tizen_video_dest_mode =
304 tizen_viewport_get_destination_mode (window->tizen_video_viewport);
306 ("tizen_destination_mode@%p = tizen_viewport_get_destination_mode (tizen_video_viewport@%p)",
307 window->tizen_video_dest_mode, window->tizen_video_viewport);
310 window->area_viewport = wl_scaler_get_viewport (display->scaler,
311 window->area_surface);
312 window->video_viewport = wl_scaler_get_viewport (display->scaler,
313 window->video_surface);
315 /* draw the area_subsurface */
316 gst_video_info_set_format (&info,
317 /* we want WL_SHM_FORMAT_XRGB8888 */
318 #if G_BYTE_ORDER == G_BIG_ENDIAN
319 GST_VIDEO_FORMAT_xRGB,
321 GST_VIDEO_FORMAT_BGRx,
325 #ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT
326 if (window->display->USE_TBM) {
327 /* Inform enlightenment of surface which render video */
328 /* tizen_video(tbm) render on video_surface */
329 window->video_object =
330 tizen_video_get_object (display->tizen_video, window->video_surface);
332 /* to use shm memory for mapping sub-surface, set FALSE to USE_TBM */
333 window->display->USE_TBM = FALSE;
334 gst_wl_window_map_sub_surface (display, window, &info);
336 window->display->USE_TBM = TRUE;
338 gst_wl_window_map_sub_surface (display, window, &info);
340 #else /* open source */
341 buf = gst_buffer_new_allocate (gst_wl_shm_allocator_get (), info.size, NULL);
342 gst_buffer_map (buf, &mapinfo, GST_MAP_WRITE);
343 *((guint32 *) mapinfo.data) = 0; /* paint it black */
344 gst_buffer_unmap (buf, &mapinfo);
346 gst_wl_shm_memory_construct_wl_buffer (gst_buffer_peek_memory (buf, 0),
348 gwlbuf = gst_buffer_add_wl_buffer (buf, wlbuf, display);
349 gst_wl_buffer_attach (gwlbuf, window->area_surface);
351 /* at this point, the GstWlBuffer keeps the buffer
352 * alive and will free it on wl_buffer::release */
353 gst_buffer_unref (buf);
356 /* do not accept input */
357 region = wl_compositor_create_region (display->compositor);
358 GST_INFO ("wl_region@%p = wl_compositor_create_region (wl_compositor@%p)",
359 region, display->compositor);
360 GST_INFO ("wl_surface_set_input_region (area_surface@%p, wl_region@%p)",
361 window->area_surface, region);
362 wl_surface_set_input_region (window->area_surface, region);
363 GST_INFO ("wl_region_destroy (wl_region@%p)", region);
364 wl_region_destroy (region);
366 region = wl_compositor_create_region (display->compositor);
367 GST_INFO ("wl_region@%p = wl_compositor_create_region (wl_compositor@%p)",
368 region, display->compositor);
369 GST_INFO ("wl_surface_set_input_region (video_surface@%p, wl_region@%p)",
370 window->video_surface, region);
371 wl_surface_set_input_region (window->video_surface, region);
372 GST_INFO ("wl_region_destroy (wl_region@%p)", region);
373 wl_region_destroy (region);
375 #ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT
376 /* set area surface size by full mode(full size of parent window) , toplevel is set to fullmode too for convenient test */
377 if (window->tizen_area_viewport) {
378 int tizen_disp_mode = TIZEN_DESTINATION_MODE_TYPE_FULL;
380 window->tizen_area_dest_mode =
381 tizen_viewport_get_destination_mode (window->tizen_area_viewport);
383 ("tizen_destination_mode@%p = tizen_viewport_get_destination_mode (tizen_video_viewport@%p)",
384 window->tizen_area_dest_mode, window->tizen_area_viewport);
385 if (window->tizen_area_dest_mode) {
386 GST_INFO ("tizen_destination_mode_set (tizen_destination_mode@%p, @%d)",
387 window->tizen_area_dest_mode, tizen_disp_mode);
388 tizen_destination_mode_set (window->tizen_area_dest_mode,
391 GST_INFO ("wl_surface_commit (area_surface@%p)", window->area_surface);
392 wl_surface_commit (window->area_surface);
399 gst_wl_window_new_toplevel (GstWlDisplay * display, const GstVideoInfo * info)
401 #ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT
405 /* not create shell_surface here for enlightenment */
406 display->need_shell_surface = TRUE;
407 window = gst_wl_window_new_internal (display, NULL);
409 /* for tizen enlightenment */
412 window->shell_surface = wl_shell_get_shell_surface (display->shell,
413 window->area_surface);
415 if (window->shell_surface) {
417 ("wl_shell_surface_add_listener (shell_surface@%p, wl_shell_surface_listener@%p, GstWlWindow@%p",
418 window->shell_surface, &shell_surface_listener, window);
419 wl_shell_surface_add_listener (window->shell_surface,
420 &shell_surface_listener, window);
421 GST_LOG ("wl_shell_surface_set_toplevel (shell_surface@%p",
422 window->shell_surface);
423 wl_shell_surface_set_toplevel (window->shell_surface);
425 GST_ERROR ("Unable to get wl_shell_surface");
427 g_object_unref (window);
431 /* toplevel is set to fullmode for convenient test in tizen_viewport enviroment, don't use below code */
433 /* set the initial size to be the same as the reported video size */
435 gst_util_uint64_scale_int_round (info->width, info->par_n, info->par_d);
436 gst_wl_window_set_render_rectangle (window, 0, 0, width, info->height);
440 #else /* open source */
444 window = gst_wl_window_new_internal (display);
447 window->shell_surface = wl_shell_get_shell_surface (display->shell,
448 window->area_surface);
450 if (window->shell_surface) {
451 wl_shell_surface_add_listener (window->shell_surface,
452 &shell_surface_listener, window);
453 wl_shell_surface_set_toplevel (window->shell_surface);
455 GST_ERROR ("Unable to get wl_shell_surface");
457 g_object_unref (window);
461 /* set the initial size to be the same as the reported video size */
463 gst_util_uint64_scale_int_round (info->width, info->par_n, info->par_d);
464 gst_wl_window_set_render_rectangle (window, 0, 0, width, info->height);
472 gst_wl_window_new_in_surface (GstWlDisplay * display,
473 struct wl_surface * parent)
475 #ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT
480 display->use_parent_wl_surface = TRUE;
483 window = gst_wl_window_new_internal (display, parent);
485 /* use wl_surface id */
486 window = gst_wl_window_new_internal (display, NULL);
489 /*Area surface from App need to be under parent surface */
490 if (display->tizen_policy) {
491 GST_INFO ("tizen_policy_place_subsurface_below_parent (%p, %p)",
492 display->tizen_policy, window->area_subsurface);
493 tizen_policy_place_subsurface_below_parent (display->tizen_policy,
494 window->area_subsurface);
495 GST_INFO ("tizen_policy_place_subsurface_below_parent (%p, %p)",
496 display->tizen_policy, window->video_subsurface);
497 tizen_policy_place_subsurface_below_parent (display->tizen_policy,
498 window->video_subsurface);
502 #else /* open source */
505 window = gst_wl_window_new_internal (display, parent); //add parent for enlightment
507 /*for enlightment , move to gst_wl_window_new_internal() */
509 /* embed in parent */
510 window->area_subsurface =
511 wl_subcompositor_get_subsurface (display->subcompositor,
512 window->area_surface, parent);
513 wl_subsurface_set_desync (window->area_subsurface);
522 gst_wl_window_get_display (GstWlWindow * window)
525 g_return_val_if_fail (window != NULL, NULL);
527 return g_object_ref (window->display);
531 gst_wl_window_get_wl_surface (GstWlWindow * window)
534 g_return_val_if_fail (window != NULL, NULL);
536 return window->video_surface;
540 gst_wl_window_is_toplevel (GstWlWindow * window)
543 g_return_val_if_fail (window != NULL, FALSE);
545 return (window->shell_surface != NULL);
548 #ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT
550 gst_wl_window_find_transform (guint rotate_angle, guint flip)
552 gint transform = WL_OUTPUT_TRANSFORM_NORMAL;
553 guint combine = rotate_angle * 10 + flip;
555 GST_DEBUG ("rotate %d, flip %d, combine %d", rotate_angle, flip, combine);
557 case ROTATE_0_FLIP_NONE:
558 transform = WL_OUTPUT_TRANSFORM_NORMAL;
560 case ROTATE_0_FLIP_HORIZONTAL:
561 transform = WL_OUTPUT_TRANSFORM_FLIPPED;
563 case ROTATE_0_FLIP_VERTICAL:
564 transform = WL_OUTPUT_TRANSFORM_FLIPPED_180;
566 case ROTATE_0_FLIP_BOTH:
567 transform = WL_OUTPUT_TRANSFORM_180;
569 case ROTATE_90_FLIP_NONE:
570 transform = WL_OUTPUT_TRANSFORM_90;
572 case ROTATE_90_FLIP_HORIZONTAL:
573 transform = WL_OUTPUT_TRANSFORM_FLIPPED_90;
575 case ROTATE_90_FLIP_VERTICAL:
576 transform = WL_OUTPUT_TRANSFORM_FLIPPED_270;
578 case ROTATE_90_FLIP_BOTH:
579 transform = WL_OUTPUT_TRANSFORM_270;
581 case ROTATE_180_FLIP_NONE:
582 transform = WL_OUTPUT_TRANSFORM_180;
584 case ROTATE_180_FLIP_HORIZONTAL:
585 transform = WL_OUTPUT_TRANSFORM_FLIPPED_180;
587 case ROTATE_180_FLIP_VERTICAL:
588 transform = WL_OUTPUT_TRANSFORM_FLIPPED;
590 case ROTATE_180_FLIP_BOTH:
591 transform = WL_OUTPUT_TRANSFORM_NORMAL;
593 case ROTATE_270_FLIP_NONE:
594 transform = WL_OUTPUT_TRANSFORM_270;
596 case ROTATE_270_FLIP_HORIZONTAL:
597 transform = WL_OUTPUT_TRANSFORM_FLIPPED_270;
599 case ROTATE_270_FLIP_VERTICAL:
600 transform = WL_OUTPUT_TRANSFORM_FLIPPED_90;
602 case ROTATE_270_FLIP_BOTH:
603 transform = WL_OUTPUT_TRANSFORM_90;
611 #if TIZEN_FEATURE_WLSINK_ENHANCEMENT
613 gst_wl_window_resize_tizen_video_viewport (GstWlWindow * window,
616 gint transform = WL_OUTPUT_TRANSFORM_NORMAL;
619 g_return_if_fail (window->tizen_video_viewport != NULL);
620 g_return_if_fail (window->tizen_video_dest_mode != NULL);
622 /* Set source, wayland need to set "tizen_viewport_set_source" always when change video info,
623 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 */
624 if (window->mode_crop.changed) {
625 /* we have known issue about mobile team kernel, when set orign green line can be shown with tbm */
627 ("tizen_viewport_set_source (tizen_video_viewport@%p, x@%d, y@%d, w@%d, h@%d)",
628 window->tizen_video_viewport, window->mode_crop.x, window->mode_crop.y,
629 window->mode_crop.w, window->mode_crop.h);
630 tizen_viewport_set_source (window->tizen_video_viewport,
631 window->mode_crop.x, window->mode_crop.y, window->mode_crop.w,
632 window->mode_crop.h);
633 window->mode_crop.changed = FALSE;
636 /*set tizen destination mode */
637 if (window->disp_geo_method.changed) {
638 int tizen_disp_mode = -1;
639 switch (window->disp_geo_method.value) {
641 case DISP_GEO_METHOD_LETTER_BOX:
642 GST_LOG ("TIZEN_DESTINATION_MODE_TYPE_LETTER_BOX");
643 tizen_disp_mode = TIZEN_DESTINATION_MODE_TYPE_LETTER_BOX;
645 case DISP_GEO_METHOD_ORIGIN_SIZE:
646 GST_LOG ("TIZEN_DESTINATION_MODE_TYPE_ORIGIN");
647 tizen_disp_mode = TIZEN_DESTINATION_MODE_TYPE_ORIGIN;
649 case DISP_GEO_METHOD_FULL_SCREEN:
650 GST_LOG ("TIZEN_DESTINATION_MODE_TYPE_FULL");
651 tizen_disp_mode = TIZEN_DESTINATION_MODE_TYPE_FULL;
653 case DISP_GEO_METHOD_CROPPED_FULL_SCREEN:
654 GST_LOG ("TIZEN_DESTINATION_MODE_TYPE_CROPPED_FULL");
655 tizen_disp_mode = TIZEN_DESTINATION_MODE_TYPE_CROPPED_FULL;
657 case DISP_GEO_METHOD_ORIGIN_SIZE_OR_LETTER_BOX:
658 GST_LOG ("TIZEN_DESTINATION_MODE_TYPE_ORIGIN_OR_LETTER");
659 tizen_disp_mode = TIZEN_DESTINATION_MODE_TYPE_ORIGIN_OR_LETTER;
661 case DISP_GEO_METHOD_CUSTOM_ROI:
662 GST_LOG ("DISP_GEO_METHOD_CUSTOM_ROI..need to set tizen disp mode");
663 GST_LOG ("Video need to set TIZEN_DESTINATION_MODE_TYPE_FULL");
664 tizen_disp_mode = TIZEN_DESTINATION_MODE_TYPE_FULL;
669 if (tizen_disp_mode > -1) {
671 ("tizen_destination_mode_set (tizen_destination_mode@%p, tizen_disp_mode@%d)",
672 window->tizen_video_dest_mode, tizen_disp_mode);
673 tizen_destination_mode_set (window->tizen_video_dest_mode,
676 window->disp_geo_method.changed = FALSE;
679 if (window->disp_geo_method.value == DISP_GEO_METHOD_CUSTOM_ROI)
682 /* 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. */
683 #ifdef ENABLE_FUNCTION
684 /* set or unset follow parent transform */
685 if (window->follow_parent_transform.changed
686 && !gst_wl_window_is_toplevel (window)) {
687 if (window->follow_parent_transform.value) {
689 ("tizen_destination_mode_follow_parent_transform (tizen_destination_mode@%p)",
690 window->tizen_area_dest_mode);
691 tizen_destination_mode_follow_parent_transform
692 (window->tizen_area_dest_mode);
694 ("tizen_destination_mode_follow_parent_transform (tizen_destination_mode@%p)",
695 window->tizen_video_dest_mode);
696 tizen_destination_mode_follow_parent_transform
697 (window->tizen_video_dest_mode);
701 ("tizen_destination_mode_unfollow_parent_transform (tizen_destination_mode@%p)",
702 window->tizen_area_dest_mode);
703 tizen_destination_mode_unfollow_parent_transform
704 (window->tizen_area_dest_mode);
706 ("tizen_destination_mode_unfollow_parent_transform (tizen_destination_mode@%p)",
707 window->tizen_video_dest_mode);
708 tizen_destination_mode_unfollow_parent_transform
709 (window->tizen_video_dest_mode);
711 window->follow_parent_transform.changed = FALSE;
715 if (window->mode_ratio.changed) {
716 wl_fixed_t f_width, f_height;
717 f_width = wl_fixed_from_double (window->mode_ratio.w);
718 f_height = wl_fixed_from_double (window->mode_ratio.h);
721 ("tizen_destination_mode_set_ratio (tizen_destination_mode@%p, wl_fixed width@%f, wl_fixed height@%f)",
722 window->tizen_video_dest_mode, window->mode_ratio.w,
723 window->mode_ratio.h);
724 tizen_destination_mode_set_ratio (window->tizen_video_dest_mode, f_width,
726 window->mode_ratio.changed = FALSE;
730 if (window->mode_offset.changed) {
732 ("tizen_destination_mode_set_offset (tizen_destination_mode@%p, x@%d, y@%d, w@%d, h@%d)",
733 window->tizen_video_dest_mode, window->mode_offset.x,
734 window->mode_offset.y, window->mode_offset.w, window->mode_offset.h);
735 tizen_destination_mode_set_offset (window->tizen_video_dest_mode,
736 window->mode_offset.x, window->mode_offset.y, window->mode_offset.w,
737 window->mode_offset.h);
738 window->mode_offset.changed = FALSE;
742 if (window->mode_scale.changed) {
743 wl_fixed_t f_width, f_height;
744 f_width = wl_fixed_from_double (window->mode_scale.w);
745 f_height = wl_fixed_from_double (window->mode_scale.h);
748 ("tizen_destination_mode_set_scale (tizen_destination_mode@%p, wl_fixed width@%f, wl_fixed height@%f)",
749 window->tizen_video_dest_mode, window->mode_scale.w,
750 window->mode_scale.h);
751 tizen_destination_mode_set_scale (window->tizen_video_dest_mode, f_width,
753 window->mode_scale.changed = FALSE;
757 if (window->mode_align.changed) {
758 wl_fixed_t f_width, f_height;
759 f_width = wl_fixed_from_double (window->mode_align.w);
760 f_height = wl_fixed_from_double (window->mode_align.h);
762 ("tizen_destination_mode_set_align (tizen_destination_mode@%p, wl_fixed_width@%f, wl_fixed_height@%f)",
763 window->tizen_video_dest_mode, window->mode_align.w,
764 window->mode_align.h);
765 tizen_destination_mode_set_align (window->tizen_video_dest_mode, f_width,
767 window->mode_align.changed = FALSE;
774 if (window->rotate_angle.changed || window->flip.changed) {
775 GST_LOG ("rotate_angle(%d), flip(%d)", window->rotate_angle.value,
778 gst_wl_window_find_transform (window->rotate_angle.value,
781 ("tizen_viewport_set_transform(tizen_video_viewport@%p, transform@%d)",
782 window->tizen_video_viewport, transform);
783 tizen_viewport_set_transform (window->tizen_video_viewport, transform);
784 window->rotate_angle.changed = window->flip.changed = FALSE;
788 GST_INFO ("need to commit");
790 ("wl_surface_damage_buffer (video_surface@%p, buffer_@x%d, buffer_y@%d, buffer_w@%d, buffer_h@%d)",
791 window->video_surface, window->buffer_x, window->buffer_y,
792 window->buffer_width, window->buffer_height);
793 wl_surface_damage_buffer (window->video_surface, window->buffer_x,
794 window->buffer_y, window->buffer_width, window->buffer_height);
795 GST_INFO ("wl_surface_commit (video_surface@%p)", window->video_surface);
796 wl_surface_commit (window->video_surface);
801 gst_wl_window_resize_video_surface (GstWlWindow * window, gboolean commit)
803 GstVideoRectangle src = { 0, };
804 GstVideoRectangle dst = { 0, };
805 GstVideoRectangle res;
807 /* center the video_subsurface inside area_subsurface */
808 src.w = window->video_width;
809 src.h = window->video_height;
810 dst.w = window->render_rectangle.w;
811 dst.h = window->render_rectangle.h;
812 gst_video_sink_center_rect (src, dst, &res, TRUE);
814 wl_subsurface_set_position (window->video_subsurface, res.x, res.y);
815 wl_viewport_set_destination (window->video_viewport, res.w, res.h);
818 wl_surface_damage (window->video_surface, 0, 0, res.w, res.h);
819 wl_surface_commit (window->video_surface);
822 if (gst_wl_window_is_toplevel (window)) {
823 struct wl_region *region;
825 region = wl_compositor_create_region (window->display->compositor);
826 wl_region_add (region, 0, 0, window->render_rectangle.w,
827 window->render_rectangle.h);
828 wl_surface_set_input_region (window->area_surface, region);
829 wl_region_destroy (region);
832 /* this is saved for use in wl_surface_damage */
833 window->surface_width = res.w;
834 window->surface_height = res.h;
838 gst_wl_window_render (GstWlWindow * window, GstWlBuffer * buffer,
839 const GstVideoInfo * info)
841 #if TIZEN_FEATURE_WLSINK_ENHANCEMENT
843 /* check video buffer size for wl_surface_damage_buffer */
844 if (window->buffer_width != window->display->buffer_width
845 || window->buffer_height != window->display->buffer_height) {
846 window->buffer_width = window->display->buffer_width;
847 window->buffer_height = window->display->buffer_height;
850 if (G_UNLIKELY (info)) {
851 window->video_width =
852 gst_util_uint64_scale_int_round (info->width, info->par_n, info->par_d);
853 window->video_height = info->height;
855 wl_subsurface_set_sync (window->video_subsurface);
856 GST_INFO ("wl_subsurface_set_sync (video_subsurface@%p)",
857 window->video_subsurface);
858 /* check video_info_changed to remove repetitive IPC */
859 if (window->video_info_changed) {
860 gst_wl_window_resize_tizen_video_viewport (window, FALSE);
861 window->video_info_changed = FALSE;
865 GST_LOG ("GstWlBuffer(%p)", buffer);
866 if (G_LIKELY (buffer))
867 gst_wl_buffer_attach (buffer, window->video_surface);
869 GST_INFO ("wl_surface_attach (video_surface@%p, NULL, 0, 0)",
870 window->video_surface);
871 wl_surface_attach (window->video_surface, NULL, 0, 0);
873 /* use tizen view port */
875 ("wl_surface_damage_buffer (video_surface@%p, buffer_x@%d, buffer_y@%d, buffer_w@%d, buffer_h@%d)",
876 window->video_surface, window->buffer_x, window->buffer_y,
877 window->buffer_width, window->buffer_height);
878 wl_surface_damage_buffer (window->video_surface, window->buffer_x,
879 window->buffer_y, window->buffer_width, window->buffer_height);
880 /* wl_surface_commit change surface state, if wl_buffer is not attached newly, then surface is not changed */
881 GST_INFO ("wl_surface_commit (video_surface@%p)", window->video_surface);
882 wl_surface_commit (window->video_surface);
884 if (G_UNLIKELY (info)) {
885 GST_INFO ("wl_surface_commit (area_surface@%p)", window->area_surface);
886 wl_surface_commit (window->area_surface);
887 GST_INFO ("wl_subsurface_set_desync (video_subsurface@%p)",
888 window->video_subsurface);
889 wl_subsurface_set_desync (window->video_subsurface);
892 wl_display_flush (window->display->display);
894 #else /* open source */
896 if (G_UNLIKELY (info)) {
897 window->video_width =
898 gst_util_uint64_scale_int_round (info->width, info->par_n, info->par_d);
899 window->video_height = info->height;
901 wl_subsurface_set_sync (window->video_subsurface);
902 gst_wl_window_resize_video_surface (window, FALSE);
905 GST_LOG ("GstWlBuffer(%p)", buffer);
906 if (G_LIKELY (buffer))
907 gst_wl_buffer_attach (buffer, window->video_surface);
909 wl_surface_attach (window->video_surface, NULL, 0, 0);
911 wl_surface_damage (window->video_surface, 0, 0, window->surface_width,
912 window->surface_height);
913 wl_surface_commit (window->video_surface);
915 if (G_UNLIKELY (info)) {
916 /* commit also the parent (area_surface) in order to change
917 * the position of the video_subsurface */
918 wl_surface_damage (window->area_surface, 0, 0, window->render_rectangle.w,
919 window->render_rectangle.h);
920 wl_surface_commit (window->area_surface);
921 wl_subsurface_set_desync (window->video_subsurface);
924 wl_display_flush (window->display->display);
929 gst_wl_window_set_render_rectangle (GstWlWindow * window, gint x, gint y,
932 #if TIZEN_FEATURE_WLSINK_ENHANCEMENT
934 g_return_if_fail (window != NULL);
936 if (window->disp_geo_method.value != DISP_GEO_METHOD_CUSTOM_ROI) {
938 ("must be set display-geometry-method to DISP_GEO_METHOD_CUSTOM_ROI before setting render rectangle()");
942 /* position the area inside the parent - needs a parent commit to apply */
943 /* use tizen view port */
944 if (window->tizen_area_viewport) {
946 ("tizen_viewport_set_destination (tizen_area_viewport(tizen_viewport)@%p, x@%d, y@%d, w@%d, h@%d)",
947 window->tizen_area_viewport, x, y, w, h);
948 tizen_viewport_set_destination (window->tizen_area_viewport, x, y, w, h);
951 if (window->video_width != 0) {
952 GST_INFO ("wl_subsurface_set_sync (video_subsurface@%p)",
953 window->video_subsurface);
954 wl_subsurface_set_sync (window->video_subsurface);
955 /* use tizen view port */
956 gst_wl_window_resize_tizen_video_viewport (window, TRUE);
957 GST_INFO ("wl_subsurface_set_desync (video_subsurface@%p)",
958 window->video_subsurface);
959 wl_subsurface_set_desync (window->video_subsurface);
961 GST_INFO ("wl_surface_commit (area_surface@%p)", window->area_surface);
962 wl_surface_commit (window->area_surface);
964 #else /* open source */
966 g_return_if_fail (window != NULL);
968 window->render_rectangle.x = x;
969 window->render_rectangle.y = y;
970 window->render_rectangle.w = w;
971 window->render_rectangle.h = h;
973 /* position the area inside the parent - needs a parent commit to apply */
974 if (window->area_subsurface)
975 wl_subsurface_set_position (window->area_subsurface, x, y);
977 /* change the size of the area */
978 wl_viewport_set_destination (window->area_viewport, w, h);
980 if (window->video_width != 0) {
981 wl_subsurface_set_sync (window->video_subsurface);
982 gst_wl_window_resize_video_surface (window, TRUE);
985 wl_surface_damage (window->area_surface, 0, 0, w, h);
986 wl_surface_commit (window->area_surface);
988 if (window->video_width != 0)
989 wl_subsurface_set_desync (window->video_subsurface);
994 #ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT
996 gst_wl_window_set_rotate_angle (GstWlWindow * window, guint rotate_angle)
999 g_return_if_fail (window != NULL);
1000 window->rotate_angle.value = rotate_angle;
1001 GST_LOG ("rotate_angle value is (%d)", window->rotate_angle.value);
1002 window->rotate_angle.changed = TRUE;
1006 gst_wl_window_set_destination_mode (GstWlWindow * window, guint disp_geo_method)
1009 g_return_if_fail (window != NULL);
1010 window->disp_geo_method.value = disp_geo_method;
1011 GST_LOG ("disp_geo_method value is (%d)", window->disp_geo_method.value);
1012 window->disp_geo_method.changed = TRUE;
1016 gst_wl_window_set_flip (GstWlWindow * window, guint flip)
1019 g_return_if_fail (window != NULL);
1020 window->flip.value = flip;
1021 GST_LOG ("flip value is (%d)", window->flip.value);
1022 window->flip.changed = TRUE;
1026 gst_wl_window_set_destination_mode_crop_wl_buffer (GstWlWindow * window,
1027 guint x, guint y, guint w, guint h)
1030 g_return_if_fail (window != NULL);
1031 GST_LOG ("set crop x@%d, y@%d, w@%d, h@%d", x, y, w, h);
1032 window->mode_crop.x = x;
1033 window->mode_crop.y = y;
1034 window->mode_crop.w = w;
1035 window->mode_crop.h = h;
1036 window->mode_crop.changed = TRUE;
1039 #ifdef ENABLE_FUNCTION
1041 gst_wl_window_set_destination_mode_follow_parent_transform (GstWlWindow *
1042 window, gboolean follow_parent_transform)
1045 g_return_if_fail (window != NULL);
1046 window->follow_parent_transform.value = follow_parent_transform;
1047 GST_LOG ("follow_parent_transform value is (%d)",
1048 window->follow_parent_transform.value);
1049 window->follow_parent_transform.changed = TRUE;
1054 gst_wl_window_set_destination_mode_offset (GstWlWindow * window, guint x,
1055 guint y, guint w, guint h)
1058 g_return_if_fail (window != NULL);
1059 GST_LOG ("set offset x@%d, y@%d", x, y);
1060 window->mode_offset.x = x;
1061 window->mode_offset.y = y;
1062 window->mode_offset.w = w;
1063 window->mode_offset.h = h;
1064 window->mode_offset.changed = TRUE;
1068 gst_wl_window_set_destination_mode_ratio (GstWlWindow * window, gdouble w,
1072 g_return_if_fail (window != NULL);
1073 GST_LOG ("set ratio w@%f, h@%f", w, h);
1074 window->mode_ratio.w = w;
1075 window->mode_ratio.h = h;
1076 window->mode_ratio.changed = TRUE;
1080 gst_wl_window_set_destination_mode_scale (GstWlWindow * window, gdouble w,
1084 g_return_if_fail (window != NULL);
1085 GST_LOG ("set scale w@%f, h@%f", w, h);
1086 window->mode_scale.w = w;
1087 window->mode_scale.h = h;
1088 window->mode_scale.changed = TRUE;
1092 gst_wl_window_set_destination_mode_align (GstWlWindow * window, gdouble w,
1096 g_return_if_fail (window != NULL);
1097 GST_LOG ("set align w@%f, h@%f", w, h);
1098 window->mode_align.w = w;
1099 window->mode_align.h = h;
1100 window->mode_align.changed = TRUE;
1104 gst_wl_window_set_video_info_change (GstWlWindow * window, guint changed)
1107 g_return_if_fail (window != NULL);
1108 window->video_info_changed = changed;
1109 GST_LOG ("video_info_changed value is (%d)", window->video_info_changed);