[mutter] screen-cast/src: Allow for source with adaptive stream size



commit 2fbde287207d56215431e9ff78d211ee6c529e16
Author: Jonas Ã…dahl <jadahl gmail com>
Date:   Mon Feb 1 10:41:57 2021 +0100

    screen-cast/src: Allow for source with adaptive stream size
    
    The area source, window source, and monitor source, currently set up the
    stream size up front, given the area, maximum allowed window size or
    monitor resolution, but for to be introduced sources, the size will be
    negotiated using PipeWire, instead of specified via the D-Bus API. This
    commit changes the internal source API to allow for this. There are
    currently no users of this new behaviour.
    
    Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1698>

 src/backends/meta-screen-cast-area-stream-src.c    |  4 +-
 src/backends/meta-screen-cast-monitor-stream-src.c |  4 +-
 src/backends/meta-screen-cast-stream-src.c         | 81 ++++++++++++++++------
 src/backends/meta-screen-cast-stream-src.h         | 11 +--
 src/backends/meta-screen-cast-window-stream-src.c  |  4 +-
 5 files changed, 74 insertions(+), 30 deletions(-)
---
diff --git a/src/backends/meta-screen-cast-area-stream-src.c b/src/backends/meta-screen-cast-area-stream-src.c
index b7de04d7b6..91251cc63b 100644
--- a/src/backends/meta-screen-cast-area-stream-src.c
+++ b/src/backends/meta-screen-cast-area-stream-src.c
@@ -83,7 +83,7 @@ get_backend (MetaScreenCastAreaStreamSrc *area_src)
   return meta_screen_cast_get_backend (screen_cast);
 }
 
-static void
+static gboolean
 meta_screen_cast_area_stream_src_get_specs (MetaScreenCastStreamSrc *src,
                                             int                     *width,
                                             int                     *height,
@@ -100,6 +100,8 @@ meta_screen_cast_area_stream_src_get_specs (MetaScreenCastStreamSrc *src,
   *width = (int) roundf (area->width * scale);
   *height = (int) roundf (area->height * scale);
   *frame_rate = 60.0;
+
+  return TRUE;
 }
 
 static gboolean
diff --git a/src/backends/meta-screen-cast-monitor-stream-src.c 
b/src/backends/meta-screen-cast-monitor-stream-src.c
index 6753f176a7..008cd6de70 100644
--- a/src/backends/meta-screen-cast-monitor-stream-src.c
+++ b/src/backends/meta-screen-cast-monitor-stream-src.c
@@ -87,7 +87,7 @@ get_monitor (MetaScreenCastMonitorStreamSrc *monitor_src)
   return meta_screen_cast_monitor_stream_get_monitor (monitor_stream);
 }
 
-static void
+static gboolean
 meta_screen_cast_monitor_stream_src_get_specs (MetaScreenCastStreamSrc *src,
                                                int                     *width,
                                                int                     *height,
@@ -112,6 +112,8 @@ meta_screen_cast_monitor_stream_src_get_specs (MetaScreenCastStreamSrc *src,
   *width = (int) roundf (logical_monitor->rect.width * scale);
   *height = (int) roundf (logical_monitor->rect.height * scale);
   *frame_rate = meta_monitor_mode_get_refresh_rate (mode);
+
+  return TRUE;
 }
 
 static void
diff --git a/src/backends/meta-screen-cast-stream-src.c b/src/backends/meta-screen-cast-stream-src.c
index 610679dcc7..c3ede8aea8 100644
--- a/src/backends/meta-screen-cast-stream-src.c
+++ b/src/backends/meta-screen-cast-stream-src.c
@@ -47,6 +47,14 @@
   (sizeof (struct spa_meta_cursor) + \
    sizeof (struct spa_meta_bitmap) + width * height * 4)
 
+#define DEFAULT_SIZE SPA_RECTANGLE (1280, 720)
+#define MIN_SIZE SPA_RECTANGLE (1, 1)
+#define MAX_SIZE SPA_RECTANGLE (16384, 16386)
+
+#define DEFAULT_FRAME_RATE SPA_FRACTION (60, 1)
+#define MIN_FRAME_RATE SPA_FRACTION (1, 1)
+#define MAX_FRAME_RATE SPA_FRACTION (1000, 1)
+
 enum
 {
   PROP_0,
@@ -107,7 +115,7 @@ G_DEFINE_TYPE_WITH_CODE (MetaScreenCastStreamSrc,
                                                 meta_screen_cast_stream_src_init_initable_iface)
                          G_ADD_PRIVATE (MetaScreenCastStreamSrc))
 
-static void
+static gboolean
 meta_screen_cast_stream_src_get_specs (MetaScreenCastStreamSrc *src,
                                        int                     *width,
                                        int                     *height,
@@ -116,7 +124,7 @@ meta_screen_cast_stream_src_get_specs (MetaScreenCastStreamSrc *src,
   MetaScreenCastStreamSrcClass *klass =
     META_SCREEN_CAST_STREAM_SRC_GET_CLASS (src);
 
-  klass->get_specs (src, width, height, frame_rate);
+  return klass->get_specs (src, width, height, frame_rate);
 }
 
 static gboolean
@@ -694,6 +702,8 @@ on_stream_param_changed (void                 *data,
   MetaScreenCastStreamSrc *src = data;
   MetaScreenCastStreamSrcPrivate *priv =
     meta_screen_cast_stream_src_get_instance_private (src);
+  MetaScreenCastStreamSrcClass *klass =
+    META_SCREEN_CAST_STREAM_SRC_GET_CLASS (src);
   uint8_t params_buffer[1024];
   int32_t width, height, stride, size;
   struct spa_pod_builder pod_builder;
@@ -737,6 +747,9 @@ on_stream_param_changed (void                 *data,
     SPA_PARAM_META_size, SPA_POD_Int (CURSOR_META_SIZE (384, 384)));
 
   pw_stream_update_params (priv->pipewire_stream, params, G_N_ELEMENTS (params));
+
+  if (klass->notify_params_updated)
+    klass->notify_params_updated (src, &priv->video_format);
 }
 
 static void
@@ -884,9 +897,6 @@ create_pipewire_stream (MetaScreenCastStreamSrc  *src,
   int width;
   int height;
   float frame_rate;
-  MetaFraction frame_rate_fraction;
-  struct spa_fraction max_framerate;
-  struct spa_fraction min_framerate;
   const struct spa_pod *params[1];
   int result;
 
@@ -903,24 +913,49 @@ create_pipewire_stream (MetaScreenCastStreamSrc  *src,
       return NULL;
     }
 
-  meta_screen_cast_stream_src_get_specs (src, &width, &height, &frame_rate);
-  frame_rate_fraction = meta_fraction_from_double (frame_rate);
-
-  min_framerate = SPA_FRACTION (1, 1);
-  max_framerate = SPA_FRACTION (frame_rate_fraction.num,
-                                frame_rate_fraction.denom);
-
-  params[0] = spa_pod_builder_add_object (
-    &pod_builder,
-    SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat,
-    SPA_FORMAT_mediaType, SPA_POD_Id (SPA_MEDIA_TYPE_video),
-    SPA_FORMAT_mediaSubtype, SPA_POD_Id (SPA_MEDIA_SUBTYPE_raw),
-    SPA_FORMAT_VIDEO_format, SPA_POD_Id (SPA_VIDEO_FORMAT_BGRx),
-    SPA_FORMAT_VIDEO_size, SPA_POD_Rectangle (&SPA_RECTANGLE (width, height)),
-    SPA_FORMAT_VIDEO_framerate, SPA_POD_Fraction (&SPA_FRACTION (0, 1)),
-    SPA_FORMAT_VIDEO_maxFramerate, SPA_POD_CHOICE_RANGE_Fraction (&max_framerate,
-                                                                  &min_framerate,
-                                                                  &max_framerate));
+  if (meta_screen_cast_stream_src_get_specs (src, &width, &height, &frame_rate))
+    {
+      MetaFraction frame_rate_fraction;
+      struct spa_fraction max_framerate;
+      struct spa_fraction min_framerate;
+
+      frame_rate_fraction = meta_fraction_from_double (frame_rate);
+
+      min_framerate = SPA_FRACTION (1, 1);
+      max_framerate = SPA_FRACTION (frame_rate_fraction.num,
+                                    frame_rate_fraction.denom);
+
+      params[0] = spa_pod_builder_add_object (
+        &pod_builder,
+        SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat,
+        SPA_FORMAT_mediaType, SPA_POD_Id (SPA_MEDIA_TYPE_video),
+        SPA_FORMAT_mediaSubtype, SPA_POD_Id (SPA_MEDIA_SUBTYPE_raw),
+        SPA_FORMAT_VIDEO_format, SPA_POD_Id (SPA_VIDEO_FORMAT_BGRx),
+        SPA_FORMAT_VIDEO_size, SPA_POD_Rectangle (&SPA_RECTANGLE (width,
+                                                                  height)),
+        SPA_FORMAT_VIDEO_framerate, SPA_POD_Fraction (&SPA_FRACTION (0, 1)),
+        SPA_FORMAT_VIDEO_maxFramerate,
+          SPA_POD_CHOICE_RANGE_Fraction (&max_framerate,
+                                         &min_framerate,
+                                         &max_framerate));
+    }
+  else
+    {
+      params[0] = spa_pod_builder_add_object (
+        &pod_builder,
+        SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat,
+        SPA_FORMAT_mediaType, SPA_POD_Id (SPA_MEDIA_TYPE_video),
+        SPA_FORMAT_mediaSubtype, SPA_POD_Id (SPA_MEDIA_SUBTYPE_raw),
+        SPA_FORMAT_VIDEO_format, SPA_POD_Id (SPA_VIDEO_FORMAT_BGRx),
+        SPA_FORMAT_VIDEO_size, SPA_POD_CHOICE_RANGE_Rectangle (&DEFAULT_SIZE,
+                                                               &MIN_SIZE,
+                                                               &MAX_SIZE),
+        SPA_FORMAT_VIDEO_framerate, SPA_POD_Fraction (&SPA_FRACTION (0, 1)),
+        SPA_FORMAT_VIDEO_maxFramerate,
+          SPA_POD_CHOICE_RANGE_Fraction (&DEFAULT_FRAME_RATE,
+                                         &MIN_FRAME_RATE,
+                                         &MAX_FRAME_RATE));
+    }
 
   pw_stream_add_listener (pipewire_stream,
                           &priv->pipewire_stream_listener,
diff --git a/src/backends/meta-screen-cast-stream-src.h b/src/backends/meta-screen-cast-stream-src.h
index 08c1815341..456b5bd978 100644
--- a/src/backends/meta-screen-cast-stream-src.h
+++ b/src/backends/meta-screen-cast-stream-src.h
@@ -53,10 +53,10 @@ struct _MetaScreenCastStreamSrcClass
 {
   GObjectClass parent_class;
 
-  void (* get_specs) (MetaScreenCastStreamSrc *src,
-                      int                     *width,
-                      int                     *height,
-                      float                   *frame_rate);
+  gboolean (* get_specs) (MetaScreenCastStreamSrc *src,
+                          int                     *width,
+                          int                     *height,
+                          float                   *frame_rate);
   void (* enable) (MetaScreenCastStreamSrc *src);
   void (* disable) (MetaScreenCastStreamSrc *src);
   gboolean (* record_to_buffer) (MetaScreenCastStreamSrc  *src,
@@ -74,6 +74,9 @@ struct _MetaScreenCastStreamSrcClass
                               MetaRectangle           *crop_rect);
   void (* set_cursor_metadata) (MetaScreenCastStreamSrc *src,
                                 struct spa_meta_cursor  *spa_meta_cursor);
+
+  void (* notify_params_updated) (MetaScreenCastStreamSrc   *src,
+                                  struct spa_video_info_raw *video_format);
 };
 
 void meta_screen_cast_stream_src_close (MetaScreenCastStreamSrc *src);
diff --git a/src/backends/meta-screen-cast-window-stream-src.c 
b/src/backends/meta-screen-cast-window-stream-src.c
index 014a97c324..3fa932b4b1 100644
--- a/src/backends/meta-screen-cast-window-stream-src.c
+++ b/src/backends/meta-screen-cast-window-stream-src.c
@@ -275,7 +275,7 @@ capture_into (MetaScreenCastWindowStreamSrc *window_src,
   return TRUE;
 }
 
-static void
+static gboolean
 meta_screen_cast_window_stream_src_get_specs (MetaScreenCastStreamSrc *src,
                                               int                     *width,
                                               int                     *height,
@@ -287,6 +287,8 @@ meta_screen_cast_window_stream_src_get_specs (MetaScreenCastStreamSrc *src,
   *width = get_stream_width (window_src);
   *height = get_stream_height (window_src);
   *frame_rate = 60.0f;
+
+  return TRUE;
 }
 
 static gboolean


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]