d3d12swapchainsink: Update uv-remap signal to support background color

Allow per viewport background color setting

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/9393>
This commit is contained in:
Seungha Yang 2025-07-14 22:58:25 +09:00 committed by GStreamer Marge Bot
parent d255ed96f0
commit 0d1cd40097
4 changed files with 61 additions and 11 deletions

View File

@ -64,6 +64,7 @@ gboolean gst_d3d12_converter_convert_buffer_for_uv_remap (GstD3D12Converter * c
gboolean execute_gpu_wait,
guint num_remap,
ID3D12Resource ** lut,
GstVideoRectangle * viewport);
GstVideoRectangle * viewport,
guint64 * border_color);
G_END_DECLS

View File

@ -1767,6 +1767,7 @@ gst_d3d12_converter_calculate_border_color (GstD3D12Converter * self)
comm->const_data_dyn.bgColor[i] = CLAMP (comm->const_data_dyn.bgColor[i],
in_m->min[i], in_m->max[i]);
}
comm->const_data_dyn.bgColor[3] = a;
GST_DEBUG_OBJECT (self, "Calculated background color ARGB: %f, %f, %f, %f",
a, converted[0], converted[1], converted[2]);
@ -1955,6 +1956,36 @@ gst_d3d12_converter_calculate_border_color (GstD3D12Converter * self)
}
}
static void
gst_d3d12_converter_calculate_remap_border_color (GstD3D12Converter * self,
guint64 color)
{
auto priv = self->priv;
GstD3D12ColorMatrix *in_m = &priv->in_clear_color_matrix;
gdouble a;
gdouble rgb[3];
auto comm = priv->main_ctx->comm;
a = ((color & 0xffff000000000000) >> 48) / (gdouble) G_MAXUINT16;
rgb[0] = ((color & 0x0000ffff00000000) >> 32) / (gdouble) G_MAXUINT16;
rgb[1] = ((color & 0x00000000ffff0000) >> 16) / (gdouble) G_MAXUINT16;
rgb[2] = (color & 0x000000000000ffff) / (gdouble) G_MAXUINT16;
for (guint i = 0; i < 3; i++) {
comm->const_data_dyn.bgColor[i] = 0;
for (guint j = 0; j < 3; j++)
comm->const_data_dyn.bgColor[i] += in_m->matrix[i][j] * rgb[j];
comm->const_data_dyn.bgColor[i] += in_m->offset[i];
comm->const_data_dyn.bgColor[i] = CLAMP (comm->const_data_dyn.bgColor[i],
in_m->min[i], in_m->max[i]);
}
comm->const_data_dyn.bgColor[3] = a;
}
static gboolean
gst_d3d12_converter_setup_colorspace (GstD3D12Converter * self,
const GstVideoInfo * in_info, const GstVideoInfo * out_info,
@ -2685,7 +2716,8 @@ static gboolean
gst_d3d12_converter_convert_buffer_internal (GstD3D12Converter * converter,
GstBuffer * in_buf, GstBuffer * out_buf, GstD3D12FenceData * fence_data,
ID3D12GraphicsCommandList * command_list, gboolean execute_gpu_wait,
guint num_remap, ID3D12Resource ** lut, GstVideoRectangle * viewport)
guint num_remap, ID3D12Resource ** lut, GstVideoRectangle * viewport,
guint64 * border_color)
{
GstD3D12Frame in_frame;
GstD3D12Frame out_frame;
@ -2932,11 +2964,16 @@ gst_d3d12_converter_convert_buffer_internal (GstD3D12Converter * converter,
auto prev_y = priv->dest_y;
auto prev_w = priv->dest_width;
auto prev_h = priv->dest_height;
FLOAT prev_color[4];
for (guint i = 0; i < 4; i++)
prev_color[i] = priv->main_ctx->comm->const_data_dyn.bgColor[i];
for (guint i = 0; i < num_remap; i++) {
gst_d3d12_converter_set_remap_unlocked (converter, lut[i]);
gst_d3d12_converter_update_viewport_unlocked (converter,
viewport[i].x, viewport[i].y, viewport[i].w, viewport[i].h);
gst_d3d12_converter_calculate_remap_border_color (converter,
border_color[i]);
if (priv->post_mipgen_ctx) {
ret = gst_d3d12_converter_execute (converter,
@ -2956,6 +2993,8 @@ gst_d3d12_converter_convert_buffer_internal (GstD3D12Converter * converter,
gst_d3d12_converter_set_remap_unlocked (converter, prev_remap.Get ());
gst_d3d12_converter_update_viewport_unlocked (converter,
prev_x, prev_y, prev_w, prev_h);
for (guint i = 0; i < 4; i++)
priv->main_ctx->comm->const_data_dyn.bgColor[i] = prev_color[i];
}
gst_d3d12_frame_unmap (&mipgen_frame);
@ -3046,14 +3085,15 @@ gst_d3d12_converter_convert_buffer (GstD3D12Converter * converter,
return gst_d3d12_converter_convert_buffer_internal (converter,
in_buf, out_buf, fence_data, command_list, execute_gpu_wait,
0, nullptr, nullptr);
0, nullptr, nullptr, nullptr);
}
gboolean
gst_d3d12_converter_convert_buffer_for_uv_remap (GstD3D12Converter * converter,
GstBuffer * in_buf, GstBuffer * out_buf, GstD3D12FenceData * fence_data,
ID3D12GraphicsCommandList * command_list, gboolean execute_gpu_wait,
guint num_remap, ID3D12Resource ** lut, GstVideoRectangle * viewport)
guint num_remap, ID3D12Resource ** lut, GstVideoRectangle * viewport,
guint64 * border_color)
{
g_return_val_if_fail (GST_IS_D3D12_CONVERTER (converter), FALSE);
g_return_val_if_fail (GST_IS_BUFFER (in_buf), FALSE);
@ -3066,7 +3106,7 @@ gst_d3d12_converter_convert_buffer_for_uv_remap (GstD3D12Converter * converter,
return gst_d3d12_converter_convert_buffer_internal (converter,
in_buf, out_buf, fence_data, command_list, execute_gpu_wait,
num_remap, lut, viewport);
num_remap, lut, viewport, border_color);
}
/**

View File

@ -233,6 +233,7 @@ struct GstD3D12SwapChainSinkPrivate
std::vector<ComPtr<ID3D12Resource>> uv_remap;
std::vector<D3D12_VIEWPORT> uv_remap_viewport_origin;
std::vector<GstVideoRectangle> uv_remap_viewport;
std::vector<guint64> uv_remap_bg_color;
gint adapter = DEFAULT_ADAPTER;
gint force_aspect_ratio = DEFAULT_FORCE_ASPECT_RATIO;
@ -281,7 +282,8 @@ static GstFlowReturn gst_d3d12_swapchain_sink_show_frame (GstVideoSink * sink,
static void gst_d3d12_swapchain_sink_resize (GstD3D12SwapChainSink * self,
guint width, guint height);
static void gst_d3d12_swapchain_sink_uv_remap (GstD3D12SwapChainSink * self,
guint num_lut, ID3D12Resource ** lut, D3D12_VIEWPORT * viewport);
guint num_lut, ID3D12Resource ** lut, D3D12_VIEWPORT * viewport,
guint64 * bg_color);
static void gst_d3d12_swapchain_sink_redraw (GstD3D12SwapChainSink * self);
static void
gst_d3d12_swapchain_sink_resize_internal (GstD3D12SwapChainSink * self,
@ -405,6 +407,7 @@ gst_d3d12_swapchain_sink_class_init (GstD3D12SwapChainSinkClass * klass)
* @num_lut: LUT resource array length
* @lut: Array of ID3D12Resource used for UV remap operation
* @viewport: Array of D3D12_VIEWPORT
* @bg_color: Array of background color represented via ARGB64 value
*
* Sets list of ID3D12Resource for UV coordinates remapping.
* Valid formats are R8G8B8A8_UNORM and R16G16B16A16_UNORM.
@ -421,7 +424,8 @@ gst_d3d12_swapchain_sink_class_init (GstD3D12SwapChainSinkClass * klass)
g_signal_new_class_handler ("uv-remap", G_TYPE_FROM_CLASS (klass),
(GSignalFlags) (G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
G_CALLBACK (gst_d3d12_swapchain_sink_uv_remap), nullptr, nullptr, nullptr,
G_TYPE_NONE, 3, G_TYPE_UINT, G_TYPE_POINTER, G_TYPE_POINTER);
G_TYPE_NONE, 4, G_TYPE_UINT, G_TYPE_POINTER, G_TYPE_POINTER,
G_TYPE_POINTER);
/**
* GstD3D12SwapChainSink::redraw
@ -1092,7 +1096,7 @@ gst_d3d12_swapchain_sink_render (GstD3D12SwapChainSink * self)
if (!gst_d3d12_converter_convert_buffer_for_uv_remap (priv->conv,
priv->cached_buf, conv_outbuf, fence_data, cl.Get (), TRUE,
(guint) priv->uv_remap.size (), uv_remap.data (),
priv->uv_remap_viewport.data ())) {
priv->uv_remap_viewport.data (), priv->uv_remap_bg_color.data ())) {
GST_ERROR_OBJECT (self, "Couldn't build convert command");
gst_d3d12_fence_data_unref (fence_data);
return FALSE;
@ -1392,7 +1396,7 @@ gst_d3d12_swapchain_sink_resize (GstD3D12SwapChainSink * self, guint width,
static void
gst_d3d12_swapchain_sink_uv_remap (GstD3D12SwapChainSink * self, guint num_lut,
ID3D12Resource ** lut, D3D12_VIEWPORT * viewport)
ID3D12Resource ** lut, D3D12_VIEWPORT * viewport, guint64 * bg_color)
{
auto priv = self->priv;
@ -1400,11 +1404,13 @@ gst_d3d12_swapchain_sink_uv_remap (GstD3D12SwapChainSink * self, guint num_lut,
priv->uv_remap.clear ();
priv->uv_remap_viewport.clear ();
priv->uv_remap_viewport_origin.clear ();
priv->uv_remap_bg_color.clear ();
for (guint i = 0; i < num_lut; i++) {
ComPtr < ID3D12Resource > remap = lut[i];
priv->uv_remap.push_back (remap);
priv->uv_remap_viewport_origin.push_back (viewport[i]);
priv->uv_remap_bg_color.push_back (bg_color[i]);
GstVideoRectangle rect = { };
calculate_remap_viewport (self, &viewport[i], &rect);

View File

@ -259,6 +259,8 @@ keyboard_cb (gchar input, gboolean is_ascii, AppData * app_data)
if (set_remap) {
ID3D12Resource *remap[2];
D3D12_VIEWPORT viewport[2];
guint64 bg_colors[2] = { G_GUINT64_CONSTANT(0xffff000000000000),
G_GUINT64_CONSTANT(0xffff000000000000) };
/* top-left, draw original image */
remap[0] = nullptr;
@ -274,11 +276,12 @@ keyboard_cb (gchar input, gboolean is_ascii, AppData * app_data)
viewport[1].Width = 0.5;
viewport[1].Height = 0.5;
g_signal_emit_by_name (app_data->sink, "uv-remap", 2, remap, viewport);
g_signal_emit_by_name (app_data->sink, "uv-remap", 2, remap, viewport,
bg_colors);
} else {
/* Clear remap */
g_signal_emit_by_name (app_data->sink,
"uv-remap", 0, nullptr, nullptr);
"uv-remap", 0, nullptr, nullptr, nullptr);
}
/* Redraw to update view */