[gnome-shell] shell-recorder: Use clutter-computed sizes and scaling for the capture



commit 6d6c2e5b995e0c5e56be0c9fe39ab84298bc75f7
Author: Marco Trevisan (Treviño) <mail 3v1n0 net>
Date:   Sat Dec 23 04:54:48 2017 +0100

    shell-recorder: Use clutter-computed sizes and scaling for the capture
    
    Get from clutter the capture sizes and scale and don't mind
    about doing any rounding here, as it might be different
    from the one done at clutter level (causing mismatch and
    not-working videos). Delegate this to clutter, and forget
    about the internal details.
    
    These values are then used to composte the image and set the video caps.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=7650111

 src/shell-recorder.c   | 34 +++++++++++++++++++++++++---------
 src/shell-screenshot.c | 35 +++++++++++++++++++----------------
 src/shell-util.c       | 21 +++++----------------
 src/shell-util.h       |  5 +++--
 4 files changed, 52 insertions(+), 43 deletions(-)
---
diff --git a/src/shell-recorder.c b/src/shell-recorder.c
index 9bf36e6db..c2e83412c 100644
--- a/src/shell-recorder.c
+++ b/src/shell-recorder.c
@@ -51,6 +51,10 @@ struct _ShellRecorder {
   int stage_width;
   int stage_height;
 
+  int capture_width;
+  int capture_height;
+  float scale;
+
   int pointer_x;
   int pointer_y;
 
@@ -430,10 +434,8 @@ recorder_record_frame (ShellRecorder *recorder,
     return;
   recorder->last_frame_time = now;
 
-  clutter_stage_capture (recorder->stage, paint, &recorder->area,
-                         &captures, &n_captures);
-
-  if (n_captures == 0)
+  if (!clutter_stage_capture (recorder->stage, paint, &recorder->area,
+                              &captures, &n_captures))
     return;
 
   if (n_captures == 1)
@@ -443,8 +445,9 @@ recorder_record_frame (ShellRecorder *recorder,
                                                  n_captures,
                                                  recorder->area.x,
                                                  recorder->area.y,
-                                                 recorder->area.width,
-                                                 recorder->area.height);
+                                                 recorder->capture_width,
+                                                 recorder->capture_height,
+                                                 recorder->scale);
 
   data = cairo_image_surface_get_data (image);
   size = (cairo_image_surface_get_height (image) *
@@ -500,6 +503,11 @@ recorder_update_size (ShellRecorder *recorder)
       recorder->area.y = 0;
       recorder->area.width = recorder->stage_width;
       recorder->area.height = recorder->stage_height;
+
+      clutter_stage_get_capture_final_size (recorder->stage, NULL,
+                                            &recorder->capture_width,
+                                            &recorder->capture_height,
+                                            &recorder->scale);
     }
 }
 
@@ -618,6 +626,8 @@ recorder_connect_stage_callbacks (ShellRecorder *recorder)
                     G_CALLBACK (recorder_on_stage_notify_size), recorder);
   g_signal_connect (recorder->stage, "notify::height",
                     G_CALLBACK (recorder_on_stage_notify_size), recorder);
+  g_signal_connect (recorder->stage, "notify::resource-scale",
+                    G_CALLBACK (recorder_on_stage_notify_size), recorder);
 }
 
 static void
@@ -875,6 +885,7 @@ shell_recorder_class_init (ShellRecorderClass *klass)
 static void
 recorder_pipeline_set_caps (RecorderPipeline *pipeline)
 {
+  ShellRecorder *recorder = pipeline->recorder;
   GstCaps *caps;
 
   /* The data is always native-endian xRGB; videoconvert
@@ -887,9 +898,9 @@ recorder_pipeline_set_caps (RecorderPipeline *pipeline)
 #else
                               "format", G_TYPE_STRING, "xRGB",
 #endif
-                              "framerate", GST_TYPE_FRACTION, pipeline->recorder->framerate, 1,
-                              "width", G_TYPE_INT, pipeline->recorder->area.width,
-                              "height", G_TYPE_INT, pipeline->recorder->area.height,
+                              "framerate", GST_TYPE_FRACTION, recorder->framerate, 1,
+                              "width", G_TYPE_INT, recorder->capture_width,
+                              "height", G_TYPE_INT, recorder->capture_height,
                               NULL);
   g_object_set (pipeline->src, "caps", caps, NULL);
   gst_caps_unref (caps);
@@ -1496,6 +1507,11 @@ shell_recorder_set_area (ShellRecorder *recorder,
   recorder->area.height = CLAMP (height,
                                  0, recorder->stage_height - recorder->area.y);
 
+  clutter_stage_get_capture_final_size (recorder->stage, &recorder->area,
+                                        &recorder->capture_width,
+                                        &recorder->capture_height,
+                                        &recorder->scale);
+
   /* This breaks the recording but tweaking the GStreamer pipeline a bit
    * might make it work, at least if the codec can handle a stream where
    * the frame size changes in the middle.
diff --git a/src/shell-screenshot.c b/src/shell-screenshot.c
index 4a119a153..125af823e 100644
--- a/src/shell-screenshot.c
+++ b/src/shell-screenshot.c
@@ -222,29 +222,32 @@ do_grab_screenshot (ShellScreenshot *screenshot,
                     int               height)
 {
   ShellScreenshotPrivate *priv = screenshot->priv;
+  cairo_rectangle_int_t screenshot_rect = { x, y, width, height };
   ClutterCapture *captures;
   int n_captures;
   int i;
 
-  clutter_stage_capture (stage, FALSE,
-                         &(cairo_rectangle_int_t) {
-                           .x = x,
-                           .y = y,
-                           .width = width,
-                           .height = height
-                         },
-                         &captures,
-                         &n_captures);
-
-  if (n_captures == 0)
+  if (!clutter_stage_capture (stage, FALSE,
+                              &screenshot_rect,
+                              &captures,
+                              &n_captures))
     return;
-  else if (n_captures == 1)
+
+  if (n_captures == 1)
     priv->image = cairo_surface_reference (captures[0].image);
   else
-    priv->image = shell_util_composite_capture_images (captures,
-                                                       n_captures,
-                                                       x, y,
-                                                       width, height);
+    {
+      float target_scale;
+
+      clutter_stage_get_capture_final_size (stage, &screenshot_rect,
+                                            &width, &height, &target_scale);
+      priv->image = shell_util_composite_capture_images (captures,
+                                                         n_captures,
+                                                         x, y,
+                                                         width, height,
+                                                         target_scale);
+    }
+
   priv->datetime = g_date_time_new_now_local ();
 
   for (i = 0; i < n_captures; i++)
diff --git a/src/shell-util.c b/src/shell-util.c
index 95d9f8e14..88a9ce11e 100644
--- a/src/shell-util.c
+++ b/src/shell-util.c
@@ -462,31 +462,20 @@ shell_util_composite_capture_images (ClutterCapture  *captures,
                                      int              n_captures,
                                      int              x,
                                      int              y,
-                                     int              width,
-                                     int              height)
+                                     int              target_width,
+                                     int              target_height,
+                                     float            target_scale)
 {
   int i;
-  double target_scale;
   cairo_format_t format;
   cairo_surface_t *image;
   cairo_t *cr;
 
   g_assert (n_captures > 0);
-
-  target_scale = 0.0;
-  for (i = 0; i < n_captures; i++)
-    {
-      ClutterCapture *capture = &captures[i];
-      double capture_scale = 1.0;
-
-      cairo_surface_get_device_scale (capture->image, &capture_scale, NULL);
-      target_scale = MAX (target_scale, capture_scale);
-    }
+  g_assert (target_scale > 0.0f);
 
   format = cairo_image_surface_get_format (captures[0].image);
-  image = cairo_image_surface_create (format,
-                                      width * target_scale,
-                                      height * target_scale);
+  image = cairo_image_surface_create (format, target_width, target_height);
   cairo_surface_set_device_scale (image, target_scale, target_scale);
 
   cr = cairo_create (image);
diff --git a/src/shell-util.h b/src/shell-util.h
index 914f438d2..6904f43bc 100644
--- a/src/shell-util.h
+++ b/src/shell-util.h
@@ -53,8 +53,9 @@ cairo_surface_t * shell_util_composite_capture_images (ClutterCapture  *captures
                                                        int              n_captures,
                                                        int              x,
                                                        int              y,
-                                                       int              width,
-                                                       int              height);
+                                                       int              target_width,
+                                                       int              target_height,
+                                                       float            target_scale);
 
 void shell_util_check_cloexec_fds (void);
 


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