Blame SOURCES/0004-screen-cast-src-Add-VideoCrop-support.patch

776610
From 20dbf18596feafc17341c330d573807b4940a636 Mon Sep 17 00:00:00 2001
776610
From: Olivier Fourdan <ofourdan@redhat.com>
776610
Date: Thu, 22 Nov 2018 11:59:10 +0100
776610
Subject: [PATCH 04/12] screen-cast-src: Add VideoCrop support
776610
776610
To be able to cast windows, which by definition can change in size
776610
dynamically, we need a way to specify the video crop meta to adjust to
776610
the window size whenever it changes.
776610
776610
Add VideoCrop support with a new optional hook `get_videocrop()` in the
776610
`ScreenCastStreamSrcClass` which, if defined, can let the child specify
776610
a rectangle for the video cropping area.
776610
776610
https://gitlab.gnome.org/GNOME/mutter/merge_requests/306
776610
(cherry picked from commit f64eba57ce3fb67a65a5c5755469d4b97067030f)
776610
---
776610
 src/backends/meta-screen-cast-stream-src.c | 56 ++++++++++++++++++++--
776610
 src/backends/meta-screen-cast-stream-src.h |  3 ++
776610
 2 files changed, 55 insertions(+), 4 deletions(-)
776610
776610
diff --git a/src/backends/meta-screen-cast-stream-src.c b/src/backends/meta-screen-cast-stream-src.c
776610
index 0c4f33b..673a464 100644
776610
--- a/src/backends/meta-screen-cast-stream-src.c
776610
+++ b/src/backends/meta-screen-cast-stream-src.c
776610
@@ -91,6 +91,9 @@ typedef struct _MetaScreenCastStreamSrcPrivate
776610
   struct spa_video_info_raw video_format;
776610
 
776610
   uint64_t last_frame_timestamp_us;
776610
+
776610
+  int stream_width;
776610
+  int stream_height;
776610
 } MetaScreenCastStreamSrcPrivate;
776610
 
776610
 static void
776610
@@ -117,6 +120,19 @@ meta_screen_cast_stream_src_get_specs (MetaScreenCastStreamSrc *src,
776610
   klass->get_specs (src, width, height, frame_rate);
776610
 }
776610
 
776610
+static gboolean
776610
+meta_screen_cast_stream_src_get_videocrop (MetaScreenCastStreamSrc *src,
776610
+                                           MetaRectangle           *crop_rect)
776610
+{
776610
+  MetaScreenCastStreamSrcClass *klass =
776610
+    META_SCREEN_CAST_STREAM_SRC_GET_CLASS (src);
776610
+
776610
+  if (klass->get_videocrop)
776610
+    return klass->get_videocrop (src, crop_rect);
776610
+
776610
+  return FALSE;
776610
+}
776610
+
776610
 static void
776610
 meta_screen_cast_stream_src_record_frame (MetaScreenCastStreamSrc *src,
776610
                                           uint8_t                 *data)
776610
@@ -132,8 +148,10 @@ meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc *src)
776610
 {
776610
   MetaScreenCastStreamSrcPrivate *priv =
776610
     meta_screen_cast_stream_src_get_instance_private (src);
776610
+  MetaRectangle crop_rect;
776610
   struct pw_buffer *buffer;
776610
   struct spa_buffer *spa_buffer;
776610
+  struct spa_meta_video_crop *spa_meta_video_crop;
776610
   uint8_t *map = NULL;
776610
   uint8_t *data;
776610
   uint64_t now_us;
776610
@@ -182,6 +200,27 @@ meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc *src)
776610
     }
776610
 
776610
   meta_screen_cast_stream_src_record_frame (src, data);
776610
+
776610
+  /* Update VideoCrop if needed */
776610
+  spa_meta_video_crop = spa_buffer_find_meta (spa_buffer, priv->pipewire_type->meta.VideoCrop);
776610
+  if (spa_meta_video_crop)
776610
+    {
776610
+      if (meta_screen_cast_stream_src_get_videocrop (src, &crop_rect))
776610
+        {
776610
+          spa_meta_video_crop->x = crop_rect.x;
776610
+          spa_meta_video_crop->y = crop_rect.y;
776610
+          spa_meta_video_crop->width = crop_rect.width;
776610
+          spa_meta_video_crop->height = crop_rect.height;
776610
+        }
776610
+      else
776610
+        {
776610
+          spa_meta_video_crop->x = 0;
776610
+          spa_meta_video_crop->y = 0;
776610
+          spa_meta_video_crop->width = priv->stream_width;
776610
+          spa_meta_video_crop->height = priv->stream_height;
776610
+        }
776610
+    }
776610
+
776610
   priv->last_frame_timestamp_us = now_us;
776610
 
776610
   if (map)
776610
@@ -275,7 +314,7 @@ on_stream_format_changed (void                 *data,
776610
   uint8_t params_buffer[1024];
776610
   int32_t width, height, stride, size;
776610
   struct spa_pod_builder pod_builder;
776610
-  const struct spa_pod *params[1];
776610
+  const struct spa_pod *params[2];
776610
   const int bpp = 4;
776610
 
776610
   if (!format)
776610
@@ -303,6 +342,12 @@ on_stream_format_changed (void                 *data,
776610
     ":", pipewire_type->param_buffers.buffers, "iru", 16, PROP_RANGE (2, 16),
776610
     ":", pipewire_type->param_buffers.align, "i", 16);
776610
 
776610
+  params[1] = spa_pod_builder_object (
776610
+    &pod_builder,
776610
+    pipewire_type->param.idMeta, pipewire_type->param_meta.Meta,
776610
+    ":", pipewire_type->param_meta.type, "I", pipewire_type->meta.VideoCrop,
776610
+    ":", pipewire_type->param_meta.size, "i", sizeof (struct spa_meta_video_crop));
776610
+
776610
   pw_stream_finish_format (priv->pipewire_stream, 0,
776610
                            params, G_N_ELEMENTS (params));
776610
 }
776610
@@ -325,7 +370,6 @@ create_pipewire_stream (MetaScreenCastStreamSrc  *src,
776610
     SPA_POD_BUILDER_INIT (buffer, sizeof (buffer));
776610
   MetaSpaType *spa_type = &priv->spa_type;
776610
   struct pw_type *pipewire_type = priv->pipewire_type;
776610
-  int width, height;
776610
   float frame_rate;
776610
   MetaFraction frame_rate_fraction;
776610
   struct spa_fraction max_framerate;
776610
@@ -344,7 +388,10 @@ create_pipewire_stream (MetaScreenCastStreamSrc  *src,
776610
       return NULL;
776610
     }
776610
 
776610
-  meta_screen_cast_stream_src_get_specs (src, &width, &height, &frame_rate);
776610
+  meta_screen_cast_stream_src_get_specs (src,
776610
+                                         &priv->stream_width,
776610
+                                         &priv->stream_height,
776610
+                                         &frame_rate);
776610
   frame_rate_fraction = meta_fraction_from_double (frame_rate);
776610
 
776610
   min_framerate = SPA_FRACTION (1, 1);
776610
@@ -357,7 +404,8 @@ create_pipewire_stream (MetaScreenCastStreamSrc  *src,
776610
     "I", spa_type->media_type.video,
776610
     "I", spa_type->media_subtype.raw,
776610
     ":", spa_type->format_video.format, "I", spa_type->video_format.BGRx,
776610
-    ":", spa_type->format_video.size, "R", &SPA_RECTANGLE (width, height),
776610
+    ":", spa_type->format_video.size, "R", &SPA_RECTANGLE (priv->stream_width,
776610
+                                                           priv->stream_height),
776610
     ":", spa_type->format_video.framerate, "F", &SPA_FRACTION (0, 1),
776610
     ":", spa_type->format_video.max_framerate, "Fru", &max_framerate,
776610
                                                       PROP_RANGE (&min_framerate,
776610
diff --git a/src/backends/meta-screen-cast-stream-src.h b/src/backends/meta-screen-cast-stream-src.h
776610
index c7ac57b..f3b3fd7 100644
776610
--- a/src/backends/meta-screen-cast-stream-src.h
776610
+++ b/src/backends/meta-screen-cast-stream-src.h
776610
@@ -26,6 +26,7 @@
776610
 #include <glib-object.h>
776610
 
776610
 #include "clutter/clutter.h"
776610
+#include "meta/boxes.h"
776610
 
776610
 typedef struct _MetaScreenCastStream MetaScreenCastStream;
776610
 
776610
@@ -47,6 +48,8 @@ struct _MetaScreenCastStreamSrcClass
776610
   void (* disable) (MetaScreenCastStreamSrc *src);
776610
   void (* record_frame) (MetaScreenCastStreamSrc *src,
776610
                          uint8_t                 *data);
776610
+  gboolean (* get_videocrop) (MetaScreenCastStreamSrc *src,
776610
+                              MetaRectangle           *crop_rect);
776610
 };
776610
 
776610
 void meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc *src);
776610
-- 
776610
2.19.2
776610