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>
This commit is contained in:
parent
b47d96b862
commit
16aa2943e2
2 changed files with 48 additions and 18 deletions
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in a new issue