summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorges Basile Stavracas Neto <georges.stavracas@gmail.com>2023-01-24 12:03:05 -0300
committerRobert Mader <robert.mader@collabora.com>2023-04-07 12:49:48 +0200
commit16aa2943e20b4164bc069007b4ebe7fafd46fdf9 (patch)
treeba1eb09d3d9bad95b3e4fc26dfad096d643bca27
parentb47d96b86248daa1451f25028e98609c0eca633c (diff)
downloadmutter-16aa2943e20b4164bc069007b4ebe7fafd46fdf9.tar.gz
screen-cast/src: Add frame recording variant with timestamp
Add meta_screen_cast_stream_src_maybe_record_frame_with_timestamp() which operates on arbitrary timestamps; and make the current function meta_screen_cast_stream_src_maybe_record_frame() just call into the new variant, passing g_get_monotonic_time() as the timestamp. This will be useful later we start using the target timestamp of the frame for screencasting. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2804>
-rw-r--r--src/backends/meta-screen-cast-stream-src.c48
-rw-r--r--src/backends/meta-screen-cast-stream-src.h18
2 files changed, 48 insertions, 18 deletions
diff --git a/src/backends/meta-screen-cast-stream-src.c b/src/backends/meta-screen-cast-stream-src.c
index c757bbd28..21427c3bd 100644
--- a/src/backends/meta-screen-cast-stream-src.c
+++ b/src/backends/meta-screen-cast-stream-src.c
@@ -484,7 +484,7 @@ add_cursor_metadata (MetaScreenCastStreamSrc *src,
meta_screen_cast_stream_src_set_cursor_metadata (src, spa_meta_cursor);
}
-static void
+static MetaScreenCastRecordResult
maybe_record_cursor (MetaScreenCastStreamSrc *src,
struct spa_buffer *spa_buffer)
{
@@ -493,11 +493,12 @@ maybe_record_cursor (MetaScreenCastStreamSrc *src,
switch (meta_screen_cast_stream_get_cursor_mode (stream))
{
case META_SCREEN_CAST_CURSOR_MODE_HIDDEN:
+ return META_SCREEN_CAST_RECORD_RESULT_RECORDED_NOTHING;
case META_SCREEN_CAST_CURSOR_MODE_EMBEDDED:
- return;
+ return META_SCREEN_CAST_RECORD_RESULT_RECORDED_CURSOR;
case META_SCREEN_CAST_CURSOR_MODE_METADATA:
add_cursor_metadata (src, spa_buffer);
- return;
+ return META_SCREEN_CAST_RECORD_RESULT_RECORDED_CURSOR;
}
g_assert_not_reached ();
@@ -675,20 +676,34 @@ maybe_add_damaged_regions_metadata (MetaScreenCastStreamSrc *src,
g_clear_pointer (&priv->redraw_clip, cairo_region_destroy);
}
-
-void
+MetaScreenCastRecordResult
meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc *src,
MetaScreenCastRecordFlag flags,
const cairo_region_t *redraw_clip)
{
+ int64_t now_us = g_get_monotonic_time ();
+
+ return meta_screen_cast_stream_src_maybe_record_frame_with_timestamp (src,
+ flags,
+ redraw_clip,
+ now_us);
+}
+
+MetaScreenCastRecordResult
+meta_screen_cast_stream_src_maybe_record_frame_with_timestamp (MetaScreenCastStreamSrc *src,
+ MetaScreenCastRecordFlag flags,
+ const cairo_region_t *redraw_clip,
+ int64_t frame_timestamp_us)
+{
MetaScreenCastStreamSrcPrivate *priv =
meta_screen_cast_stream_src_get_instance_private (src);
+ MetaScreenCastRecordResult record_result =
+ META_SCREEN_CAST_RECORD_RESULT_RECORDED_NOTHING;
MetaRectangle crop_rect;
struct pw_buffer *buffer;
struct spa_buffer *spa_buffer;
struct spa_meta_header *header;
uint8_t *data = NULL;
- uint64_t now_us;
g_autoptr (GError) error = NULL;
/* Accumulate the damaged region since we might not schedule a frame capture
@@ -702,7 +717,6 @@ meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc *src,
priv->redraw_clip = cairo_region_copy (redraw_clip);
}
- now_us = g_get_monotonic_time ();
if (priv->video_format.max_framerate.num > 0 &&
priv->last_frame_timestamp_us != 0)
{
@@ -713,7 +727,7 @@ meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc *src,
((G_USEC_PER_SEC * ((int64_t) priv->video_format.max_framerate.denom)) /
((int64_t) priv->video_format.max_framerate.num));
- time_since_last_frame_us = now_us - priv->last_frame_timestamp_us;
+ time_since_last_frame_us = frame_timestamp_us - priv->last_frame_timestamp_us;
if (time_since_last_frame_us < min_interval_us)
{
int64_t timeout_us;
@@ -723,12 +737,12 @@ meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc *src,
meta_topic (META_DEBUG_SCREEN_CAST,
"Skipped recording frame on stream %u, too early",
priv->node_id);
- return;
+ return record_result;
}
}
if (!priv->pipewire_stream)
- return;
+ return META_SCREEN_CAST_RECORD_RESULT_RECORDED_NOTHING;
meta_topic (META_DEBUG_SCREEN_CAST, "Recording %s frame on stream %u",
flags & META_SCREEN_CAST_RECORD_FLAG_CURSOR_ONLY ?
@@ -742,7 +756,7 @@ meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc *src,
"Couldn't dequeue a buffer from pipewire stream (node id %u), "
"maybe your encoding is too slow?",
pw_stream_get_node_id (priv->pipewire_stream));
- return;
+ return record_result;
}
spa_buffer = buffer->buffer;
@@ -759,7 +773,7 @@ meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc *src,
header->flags = SPA_META_HEADER_FLAG_CORRUPTED;
pw_stream_queue_buffer (priv->pipewire_stream, buffer);
- return;
+ return record_result;
}
if (!(flags & META_SCREEN_CAST_RECORD_FLAG_CURSOR_ONLY))
@@ -799,6 +813,8 @@ meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc *src,
priv->video_format.size.height;
}
}
+
+ record_result |= META_SCREEN_CAST_RECORD_RESULT_RECORDED_FRAME;
}
else
{
@@ -813,17 +829,19 @@ meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc *src,
spa_buffer->datas[0].chunk->flags = SPA_CHUNK_FLAG_CORRUPTED;
}
- maybe_record_cursor (src, spa_buffer);
+ record_result |= maybe_record_cursor (src, spa_buffer);
- priv->last_frame_timestamp_us = now_us;
+ priv->last_frame_timestamp_us = frame_timestamp_us;
if (header)
{
- header->pts = now_us * SPA_NSEC_PER_USEC;
+ header->pts = frame_timestamp_us * SPA_NSEC_PER_USEC;
header->flags = 0;
}
pw_stream_queue_buffer (priv->pipewire_stream, buffer);
+
+ return record_result;
}
gboolean
diff --git a/src/backends/meta-screen-cast-stream-src.h b/src/backends/meta-screen-cast-stream-src.h
index 65952cc49..63058f2c3 100644
--- a/src/backends/meta-screen-cast-stream-src.h
+++ b/src/backends/meta-screen-cast-stream-src.h
@@ -44,6 +44,13 @@ typedef enum _MetaScreenCastRecordFlag
META_SCREEN_CAST_RECORD_FLAG_DMABUF_ONLY = 1 << 1,
} MetaScreenCastRecordFlag;
+typedef enum _MetaScreenCastRecordResult
+{
+ META_SCREEN_CAST_RECORD_RESULT_RECORDED_NOTHING = 0,
+ META_SCREEN_CAST_RECORD_RESULT_RECORDED_FRAME = 1 << 0,
+ META_SCREEN_CAST_RECORD_RESULT_RECORDED_CURSOR = 1 << 1,
+} MetaScreenCastRecordResult;
+
#define META_TYPE_SCREEN_CAST_STREAM_SRC (meta_screen_cast_stream_src_get_type ())
G_DECLARE_DERIVABLE_TYPE (MetaScreenCastStreamSrc,
meta_screen_cast_stream_src,
@@ -84,9 +91,14 @@ void meta_screen_cast_stream_src_close (MetaScreenCastStreamSrc *src);
gboolean meta_screen_cast_stream_src_is_enabled (MetaScreenCastStreamSrc *src);
-void meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc *src,
- MetaScreenCastRecordFlag flags,
- const cairo_region_t *redraw_clip);
+MetaScreenCastRecordResult meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc *src,
+ MetaScreenCastRecordFlag flags,
+ const cairo_region_t *redraw_clip);
+
+MetaScreenCastRecordResult meta_screen_cast_stream_src_maybe_record_frame_with_timestamp (MetaScreenCastStreamSrc *src,
+ MetaScreenCastRecordFlag flags,
+ const cairo_region_t *redraw_clip,
+ int64_t frame_timestamp_us);
gboolean meta_screen_cast_stream_src_pending_follow_up_frame (MetaScreenCastStreamSrc *src);