[Spice-devel] [RFC v2 3/5] display-channel: Share the drawable's copy of fd with the encoder
Vivek Kasireddy
vivek.kasireddy at intel.com
Mon Jan 23 08:41:21 UTC 2023
Once the drawable gets a copy of the fd, the goal is to share it with
the encoder. This patch accomplishes this task and also registers
a callback to unblock the pipeline once the encoder is done using
the fd.
Additionally, this patch also does the following:
- Adds helpers to manage the async count for different situations
- Creates an object of type VideoEncoderDmabufData and populates
it with relevant data such as fd, callback, etc.
Cc: Gerd Hoffmann <kraxel at redhat.com>
Cc: Marc-André Lureau <marcandre.lureau at redhat.com>
Cc: Dongwon Kim <dongwon.kim at intel.com>
Signed-off-by: Vivek Kasireddy <vivek.kasireddy at intel.com>
---
server/dcc-send.cpp | 30 ++++++++++++++++++++++++++++++
server/display-channel.cpp | 14 ++++++++++++++
server/display-channel.h | 3 +++
server/video-stream.cpp | 6 ++++++
4 files changed, 53 insertions(+)
diff --git a/server/dcc-send.cpp b/server/dcc-send.cpp
index 2c40a231..13406865 100644
--- a/server/dcc-send.cpp
+++ b/server/dcc-send.cpp
@@ -1637,6 +1637,13 @@ static void red_release_video_encoder_buffer(uint8_t *data, void *opaque)
buffer->free(buffer);
}
+static void red_mem_free_cb(void *opaque)
+{
+ auto display = static_cast<DisplayChannel *>(opaque);
+
+ display_channel_gl_draw_done(display);
+}
+
static bool red_marshall_stream_data(DisplayChannelClient *dcc,
SpiceMarshaller *base_marshaller,
Drawable *drawable)
@@ -1667,10 +1674,22 @@ static bool red_marshall_stream_data(DisplayChannelClient *dcc,
int stream_id = display_channel_get_video_stream_id(display, stream);
VideoStreamAgent *agent = &dcc->priv->stream_agents[stream_id];
VideoBuffer *outbuf;
+ VideoEncoderDmabufData *dmabuf_data = NULL;
/* workaround for vga streams */
frame_mm_time = drawable->red_drawable->mm_time ?
drawable->red_drawable->mm_time :
reds_get_mm_time();
+
+ if (drawable->dmabuf_fd > 0) {
+ dmabuf_data = g_new0(VideoEncoderDmabufData, 1);
+ dmabuf_data->dmabuf_fd = drawable->dmabuf_fd;
+ dmabuf_data->opaque = display;
+ dmabuf_data->notify_mem_free = red_mem_free_cb;
+
+ display_channel_add_encode_async(display);
+ }
+ agent->video_encoder->dmabuf_data = dmabuf_data;
+
ret = !agent->video_encoder ? VIDEO_ENCODER_FRAME_UNSUPPORTED :
agent->video_encoder->encode_frame(agent->video_encoder,
frame_mm_time,
@@ -1678,6 +1697,13 @@ static bool red_marshall_stream_data(DisplayChannelClient *dcc,
©->src_area, stream->top_down,
drawable->red_drawable.get(),
&outbuf);
+ if (agent->video_encoder->dmabuf_data &&
+ ret != VIDEO_ENCODER_FRAME_ENCODE_DONE) {
+ display_channel_gl_draw_done(display);
+ g_free(agent->video_encoder->dmabuf_data);
+ agent->video_encoder->dmabuf_data = NULL;
+ }
+
switch (ret) {
case VIDEO_ENCODER_FRAME_DROP:
#ifdef STREAM_STATS
@@ -2095,6 +2121,10 @@ static void marshall_qxl_drawable(DisplayChannelClient *dcc,
marshall_lossy_qxl_drawable(dcc, m, dpi);
else
marshall_lossless_qxl_drawable(dcc, m, dpi);
+
+ if (item->dmabuf_fd > 0) {
+ display_channel_gl_draw_done(display);
+ }
}
static void marshall_stream_start(DisplayChannelClient *dcc,
diff --git a/server/display-channel.cpp b/server/display-channel.cpp
index 9534bbf2..349c1405 100644
--- a/server/display-channel.cpp
+++ b/server/display-channel.cpp
@@ -2343,6 +2343,20 @@ void display_channel_gl_draw_done(DisplayChannel *display)
set_gl_draw_async_count(display, display->priv->gl_draw_async_count - 1);
}
+void display_channel_set_encode_async(DisplayChannel *display, int num)
+{
+ set_gl_draw_async_count(display, num);
+}
+
+void display_channel_add_encode_async(DisplayChannel *display)
+{
+ int num = display->priv->gl_draw_async_count;
+
+ if (num == 0) {
+ display_channel_set_encode_async(display, num + 1);
+ }
+}
+
int display_channel_get_video_stream_id(DisplayChannel *display, VideoStream *stream)
{
return static_cast<int>(stream - display->priv->streams_buf.data());
diff --git a/server/display-channel.h b/server/display-channel.h
index 276d015a..de1243d2 100644
--- a/server/display-channel.h
+++ b/server/display-channel.h
@@ -128,6 +128,9 @@ void display_channel_gl_scanout (DisplayCha
void display_channel_gl_draw (DisplayChannel *display,
SpiceMsgDisplayGlDraw *draw);
void display_channel_gl_draw_done (DisplayChannel *display);
+void display_channel_set_encode_async (DisplayChannel *display,
+ int num_clients);
+void display_channel_add_encode_async (DisplayChannel *display);
void display_channel_process_draw(DisplayChannel *display,
red::shared_ptr<RedDrawable> &&red_drawable,
diff --git a/server/video-stream.cpp b/server/video-stream.cpp
index 056d0c31..28b42d91 100644
--- a/server/video-stream.cpp
+++ b/server/video-stream.cpp
@@ -371,6 +371,7 @@ static void display_channel_create_stream(DisplayChannel *display, Drawable *dra
DisplayChannelClient *dcc;
VideoStream *stream;
SpiceRect* src_rect;
+ int num_clients = 0;
spice_assert(!drawable->stream);
@@ -407,7 +408,12 @@ static void display_channel_create_stream(DisplayChannel *display, Drawable *dra
display->priv->stream_count++;
FOREACH_DCC(display, dcc) {
dcc_create_stream(dcc, stream);
+ num_clients++;
}
+ if (drawable->dmabuf_fd > 0) {
+ display_channel_set_encode_async(display, num_clients);
+ }
+
spice_debug("stream %d %dx%d (%d, %d) (%d, %d) %u fps",
display_channel_get_video_stream_id(display, stream), stream->width,
stream->height, stream->dest_area.left, stream->dest_area.top,
--
2.37.2
More information about the Spice-devel
mailing list