[vlc-commits] wayland/shm: use wl_scaler for A/R, crop and zoom (where available)

Rémi Denis-Courmont git at videolan.org
Sun Oct 5 10:10:58 CEST 2014


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Sun Oct  5 10:59:03 2014 +0300| [a2c3a8889bd0d8ed1ce495346694283fcb460602] | committer: Rémi Denis-Courmont

wayland/shm: use wl_scaler for A/R, crop and zoom (where available)

Note: The wl_scaler object is retained after Open() even though it is
not currently used afterwards. It will probably be needed for scaling
subpictures going forward.

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=a2c3a8889bd0d8ed1ce495346694283fcb460602
---

 modules/video_output/Makefile.am |    1 +
 modules/video_output/wl/shm.c    |   95 +++++++++++++++++++++++++++-----------
 2 files changed, 70 insertions(+), 26 deletions(-)

diff --git a/modules/video_output/Makefile.am b/modules/video_output/Makefile.am
index 737023d..5d7b483 100644
--- a/modules/video_output/Makefile.am
+++ b/modules/video_output/Makefile.am
@@ -127,6 +127,7 @@ endif
 ### Wayland ###
 libwl_shm_plugin_la_SOURCES = video_output/wl/shm.c
 nodist_libwl_shm_plugin_la_SOURCES = video_output/wl/scaler-protocol.c
+libwl_shm_plugin_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(builddir)/video_output/wl
 libwl_shm_plugin_la_CFLAGS = $(WAYLAND_CLIENT_CFLAGS)
 libwl_shm_plugin_la_LIBADD = $(WAYLAND_CLIENT_LIBS)
 EXTRA_DIST += video_output/wayland/scaler.xml
diff --git a/modules/video_output/wl/shm.c b/modules/video_output/wl/shm.c
index 3a7cb0a..ec29e98 100644
--- a/modules/video_output/wl/shm.c
+++ b/modules/video_output/wl/shm.c
@@ -24,6 +24,7 @@
 # include <config.h>
 #endif
 
+#include <assert.h>
 #include <errno.h>
 #include <stdlib.h>
 #include <string.h>
@@ -34,6 +35,7 @@
 #include <unistd.h>
 
 #include <wayland-client.h>
+#include "scaler-client-protocol.h"
 
 #include <vlc_common.h>
 #include <vlc_plugin.h>
@@ -47,6 +49,8 @@ struct vout_display_sys_t
     vout_window_t *embed; /* VLC window */
     struct wl_event_queue *eventq;
     struct wl_shm *shm;
+    struct wl_scaler *scaler;
+    struct wl_viewport *viewport;
 
     picture_pool_t *pool; /* picture pool */
 
@@ -98,7 +102,7 @@ static picture_pool_t *Pool(vout_display_t *vd, unsigned req)
 
     /* We need one extra line to cover for horizontal crop offset */
     unsigned stride = 4 * ((vd->fmt.i_width + 31) & ~31);
-    unsigned lines = (vd->fmt.i_height + 31 + 1) & ~31;
+    unsigned lines = (vd->fmt.i_height + 31 + (sys->viewport == NULL)) & ~31;
     const long pagemask = sysconf(_SC_PAGE_SIZE) - 1;
     size_t picsize = ((stride * lines) + pagemask) & ~pagemask;
     size_t length = picsize * req;
@@ -139,11 +143,14 @@ static picture_pool_t *Pool(vout_display_t *vd, unsigned req)
             },
         },
     };
-    size_t offset = 4 * vd->fmt.i_x_offset + stride * vd->fmt.i_y_offset;
+    size_t offset = 0;
     unsigned width = vd->fmt.i_visible_width;
     unsigned height = vd->fmt.i_visible_height;
     unsigned count = 0;
 
+    if (sys->viewport == NULL) /* Poor man's crop */
+        offset += 4 * vd->fmt.i_x_offset + stride * vd->fmt.i_y_offset;
+
     while (count < req)
     {
         struct wl_buffer *buf;
@@ -197,7 +204,7 @@ static void Prepare(vout_display_t *vd, picture_t *pic, subpicture_t *subpic)
 
     wl_surface_attach(surface, buf, sys->x, sys->y);
     wl_surface_damage(surface, 0, 0,
-                      vd->fmt.i_visible_width, vd->fmt.i_visible_height);
+                      vd->cfg->display.width, vd->cfg->display.height);
     wl_display_flush(display);
 
     sys->x = 0;
@@ -244,8 +251,7 @@ static int Control(vout_display_t *vd, int query, va_list ap)
             vout_display_place_t place;
             video_format_t src;
 
-            sys->x += vd->fmt.i_visible_width / 2;
-            sys->y += vd->fmt.i_visible_height / 2;
+            assert(sys->viewport == NULL);
 
             vout_display_PlacePicture(&place, &vd->source, vd->cfg, false);
             video_format_ApplyRotation(&src, &vd->source);
@@ -260,10 +266,6 @@ static int Control(vout_display_t *vd, int query, va_list ap)
                                                 / src.i_visible_width;
             vd->fmt.i_y_offset = src.i_y_offset * place.height
                                                 / src.i_visible_height;
-
-            sys->x -= vd->fmt.i_visible_width / 2;
-            sys->y -= vd->fmt.i_visible_height / 2;
-
             ResetPictures(vd);
             break;
         }
@@ -282,12 +284,27 @@ static int Control(vout_display_t *vd, int query, va_list ap)
         }
 
         case VOUT_DISPLAY_CHANGE_DISPLAY_SIZE:
+        case VOUT_DISPLAY_CHANGE_DISPLAY_FILLED:
+        case VOUT_DISPLAY_CHANGE_ZOOM:
+        case VOUT_DISPLAY_CHANGE_SOURCE_ASPECT:
+        case VOUT_DISPLAY_CHANGE_SOURCE_CROP:
         {
-            const vout_display_cfg_t *cfg =
-                va_arg(ap, const vout_display_cfg_t *);
-            const bool forced = va_arg(ap, int);
+            const vout_display_cfg_t *cfg;
+            const video_format_t *src;
+
+            if (query == VOUT_DISPLAY_CHANGE_SOURCE_ASPECT
+             || query == VOUT_DISPLAY_CHANGE_SOURCE_CROP)
+            {
+                src = va_arg(ap, const video_format_t *);
+                cfg = vd->cfg;
+            }
+            else
+            {
+                src = &vd->source;
+                cfg = va_arg(ap, const vout_display_cfg_t *);
+            }
 
-            if (forced)
+            if (query == VOUT_DISPLAY_CHANGE_DISPLAY_SIZE && va_arg(ap, int))
             {
                 vout_display_SendEventDisplaySize(vd, cfg->display.width,
                                                   cfg->display.height,
@@ -296,20 +313,31 @@ static int Control(vout_display_t *vd, int query, va_list ap)
             }
 
             vout_display_place_t place;
-            vout_display_PlacePicture(&place, &vd->source, cfg, false);
 
-            if (place.width == vd->fmt.i_visible_width
-             && place.height == vd->fmt.i_visible_height)
-                break;
-            /* fall through */
-        }
-        case VOUT_DISPLAY_CHANGE_DISPLAY_FILLED:
-        case VOUT_DISPLAY_CHANGE_ZOOM:
-        case VOUT_DISPLAY_CHANGE_SOURCE_ASPECT:
-        case VOUT_DISPLAY_CHANGE_SOURCE_CROP:
-             vout_display_SendEventPicturesInvalid(vd);
-             break;
+            vout_display_PlacePicture(&place, &vd->source, vd->cfg, false);
+            sys->x += place.width / 2;
+            sys->y += place.height / 2;
+
+            vout_display_PlacePicture(&place, src, cfg, false);
+            sys->x -= place.width / 2;
+            sys->y -= place.height / 2;
 
+            if (sys->viewport != NULL)
+            {
+                video_format_t fmt;
+
+                video_format_ApplyRotation(&fmt, src);
+                wl_viewport_set(sys->viewport,
+                                wl_fixed_from_int(fmt.i_x_offset),
+                                wl_fixed_from_int(fmt.i_y_offset),
+                                wl_fixed_from_int(fmt.i_visible_width),
+                                wl_fixed_from_int(fmt.i_visible_height),
+                                place.width, place.height);
+            }
+            else
+                vout_display_SendEventPicturesInvalid(vd);
+            break;
+        }
         default:
              msg_Err(vd, "unknown request %d", query);
              return VLC_EGENERIC;
@@ -346,6 +374,10 @@ static void registry_global_cb(void *data, struct wl_registry *registry,
 
     if (!strcmp(iface, "wl_shm"))
         sys->shm = wl_registry_bind(registry, name, &wl_shm_interface, 1);
+    else
+    if (!strcmp(iface, "wl_scaler"))
+        sys->scaler = wl_registry_bind(registry, name, &wl_scaler_interface,
+                                       1);
 }
 
 static void registry_global_remove_cb(void *data, struct wl_registry *registry,
@@ -374,6 +406,7 @@ static int Open(vlc_object_t *obj)
     sys->embed = NULL;
     sys->eventq = NULL;
     sys->shm = NULL;
+    sys->scaler = NULL;
     sys->pool = NULL;
     sys->x = 0;
     sys->y = 0;
@@ -409,13 +442,19 @@ static int Open(vlc_object_t *obj)
     wl_shm_add_listener(sys->shm, &shm_cbs, vd);
     wl_display_roundtrip_queue(display, sys->eventq);
 
+    if (sys->scaler != NULL)
+        sys->viewport = wl_scaler_get_viewport(sys->scaler,
+                                               sys->embed->handle.wl);
+    else
+        sys->viewport = NULL;
+
     /* Determine our pixel format */
     video_format_t fmt_pic;
 
     video_format_ApplyRotation(&fmt_pic, &vd->fmt);
     fmt_pic.i_chroma = VLC_CODEC_RGB32;
 
-    vd->info.has_pictures_invalid = true;
+    vd->info.has_pictures_invalid = sys->viewport == NULL;
     vd->info.has_event_thread = true;
 
     vd->fmt = fmt_pic;
@@ -449,6 +488,10 @@ static void Close(vlc_object_t *obj)
 
     ResetPictures(vd);
 
+    if (sys->viewport != NULL)
+        wl_viewport_destroy(sys->viewport);
+    if (sys->scaler != NULL)
+        wl_scaler_destroy(sys->scaler);
     wl_shm_destroy(sys->shm);
     wl_display_flush(sys->embed->display.wl);
     wl_event_queue_destroy(sys->eventq);



More information about the vlc-commits mailing list