mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 12:11:13 +00:00
d3d11colorconverter: Add support cropping
Vertex buffer will be updated if input texture resolution is different from GstVideoInfo or when an user requests specific crop area.
This commit is contained in:
parent
c6c83ca493
commit
5074cecc82
2 changed files with 141 additions and 0 deletions
|
@ -291,6 +291,12 @@ struct _GstD3D11ColorConverter
|
||||||
|
|
||||||
D3D11_VIEWPORT viewport[GST_VIDEO_MAX_PLANES];
|
D3D11_VIEWPORT viewport[GST_VIDEO_MAX_PLANES];
|
||||||
|
|
||||||
|
RECT crop_rect;
|
||||||
|
gint input_texture_width;
|
||||||
|
gint input_texture_height;
|
||||||
|
ID3D11Buffer *vertex_buffer;
|
||||||
|
gboolean update_vertex;
|
||||||
|
|
||||||
ConvertInfo convert_info;
|
ConvertInfo convert_info;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1048,6 +1054,18 @@ gst_d3d11_color_convert_setup_shader (GstD3D11ColorConverter * self,
|
||||||
self->num_input_view = GST_VIDEO_INFO_N_PLANES (in_info);
|
self->num_input_view = GST_VIDEO_INFO_N_PLANES (in_info);
|
||||||
self->num_output_view = GST_VIDEO_INFO_N_PLANES (out_info);
|
self->num_output_view = GST_VIDEO_INFO_N_PLANES (out_info);
|
||||||
|
|
||||||
|
/* holds vertex buffer for crop rect update */
|
||||||
|
self->vertex_buffer = vertex_buffer;
|
||||||
|
ID3D11Buffer_AddRef (vertex_buffer);
|
||||||
|
|
||||||
|
self->crop_rect.left = 0;
|
||||||
|
self->crop_rect.top = 0;
|
||||||
|
self->crop_rect.right = GST_VIDEO_INFO_WIDTH (in_info);
|
||||||
|
self->crop_rect.bottom = GST_VIDEO_INFO_HEIGHT (in_info);
|
||||||
|
|
||||||
|
self->input_texture_width = GST_VIDEO_INFO_WIDTH (in_info);
|
||||||
|
self->input_texture_height = GST_VIDEO_INFO_HEIGHT (in_info);
|
||||||
|
|
||||||
clear:
|
clear:
|
||||||
for (i = 0; i < CONVERTER_MAX_QUADS; i++) {
|
for (i = 0; i < CONVERTER_MAX_QUADS; i++) {
|
||||||
if (ps[i])
|
if (ps[i])
|
||||||
|
@ -1203,10 +1221,88 @@ gst_d3d11_color_converter_free (GstD3D11ColorConverter * converter)
|
||||||
g_free (converter->convert_info.ps_body[i]);
|
g_free (converter->convert_info.ps_body[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (converter->vertex_buffer)
|
||||||
|
ID3D11Buffer_Release (converter->vertex_buffer);
|
||||||
|
|
||||||
gst_clear_object (&converter->device);
|
gst_clear_object (&converter->device);
|
||||||
g_free (converter);
|
g_free (converter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* must be called with gst_d3d11_device_lock since ID3D11DeviceContext is not
|
||||||
|
* thread-safe */
|
||||||
|
static gboolean
|
||||||
|
gst_d3d11_color_converter_update_vertex_buffer (GstD3D11ColorConverter * self)
|
||||||
|
{
|
||||||
|
D3D11_MAPPED_SUBRESOURCE map;
|
||||||
|
VertexData *vertex_data;
|
||||||
|
ID3D11DeviceContext *context_handle;
|
||||||
|
HRESULT hr;
|
||||||
|
FLOAT u, v;
|
||||||
|
const RECT *crop_rect = &self->crop_rect;
|
||||||
|
gint texture_width = self->input_texture_width;
|
||||||
|
gint texture_height = self->input_texture_height;
|
||||||
|
|
||||||
|
context_handle = gst_d3d11_device_get_device_context_handle (self->device);
|
||||||
|
|
||||||
|
hr = ID3D11DeviceContext_Map (context_handle,
|
||||||
|
(ID3D11Resource *) self->vertex_buffer, 0, D3D11_MAP_WRITE_DISCARD,
|
||||||
|
0, &map);
|
||||||
|
|
||||||
|
if (!gst_d3d11_result (hr, self->device)) {
|
||||||
|
GST_ERROR ("Couldn't map vertex buffer, hr: 0x%x", (guint) hr);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
vertex_data = (VertexData *) map.pData;
|
||||||
|
|
||||||
|
/* bottom left */
|
||||||
|
u = (crop_rect->left / (gfloat) texture_width) - 0.5f / texture_width;
|
||||||
|
v = (crop_rect->bottom / (gfloat) texture_height) - 0.5f / texture_height;
|
||||||
|
|
||||||
|
vertex_data[0].position.x = -1.0f;
|
||||||
|
vertex_data[0].position.y = -1.0f;
|
||||||
|
vertex_data[0].position.z = 0.0f;
|
||||||
|
vertex_data[0].texture.x = u;
|
||||||
|
vertex_data[0].texture.y = v;
|
||||||
|
|
||||||
|
/* top left */
|
||||||
|
u = (crop_rect->left / (gfloat) texture_width) - 0.5f / texture_width;
|
||||||
|
v = (crop_rect->top / (gfloat) texture_height) - 0.5f / texture_height;
|
||||||
|
|
||||||
|
vertex_data[1].position.x = -1.0f;
|
||||||
|
vertex_data[1].position.y = 1.0f;
|
||||||
|
vertex_data[1].position.z = 0.0f;
|
||||||
|
vertex_data[1].texture.x = u;
|
||||||
|
vertex_data[1].texture.y = v;
|
||||||
|
|
||||||
|
/* top right */
|
||||||
|
u = (crop_rect->right / (gfloat) texture_width) - 0.5f / texture_width;
|
||||||
|
v = (crop_rect->top / (gfloat) texture_height) - 0.5f / texture_height;
|
||||||
|
|
||||||
|
vertex_data[2].position.x = 1.0f;
|
||||||
|
vertex_data[2].position.y = 1.0f;
|
||||||
|
vertex_data[2].position.z = 0.0f;
|
||||||
|
vertex_data[2].texture.x = u;
|
||||||
|
vertex_data[2].texture.y = v;
|
||||||
|
|
||||||
|
/* bottom right */
|
||||||
|
u = (crop_rect->right / (gfloat) texture_width) - 0.5f / texture_width;
|
||||||
|
v = (crop_rect->bottom / (gfloat) texture_height) - 0.5f / texture_height;
|
||||||
|
|
||||||
|
vertex_data[3].position.x = 1.0f;
|
||||||
|
vertex_data[3].position.y = -1.0f;
|
||||||
|
vertex_data[3].position.z = 0.0f;
|
||||||
|
vertex_data[3].texture.x = u;
|
||||||
|
vertex_data[3].texture.y = v;
|
||||||
|
|
||||||
|
ID3D11DeviceContext_Unmap (context_handle,
|
||||||
|
(ID3D11Resource *) self->vertex_buffer, 0);
|
||||||
|
|
||||||
|
self->update_vertex = FALSE;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
gst_d3d11_color_converter_convert (GstD3D11ColorConverter * converter,
|
gst_d3d11_color_converter_convert (GstD3D11ColorConverter * converter,
|
||||||
ID3D11ShaderResourceView * srv[GST_VIDEO_MAX_PLANES],
|
ID3D11ShaderResourceView * srv[GST_VIDEO_MAX_PLANES],
|
||||||
|
@ -1231,11 +1327,33 @@ gst_d3d11_color_converter_convert_unlocked (GstD3D11ColorConverter * converter,
|
||||||
ID3D11RenderTargetView * rtv[GST_VIDEO_MAX_PLANES])
|
ID3D11RenderTargetView * rtv[GST_VIDEO_MAX_PLANES])
|
||||||
{
|
{
|
||||||
gboolean ret;
|
gboolean ret;
|
||||||
|
ID3D11Resource *resource;
|
||||||
|
D3D11_TEXTURE2D_DESC desc;
|
||||||
|
|
||||||
g_return_val_if_fail (converter != NULL, FALSE);
|
g_return_val_if_fail (converter != NULL, FALSE);
|
||||||
g_return_val_if_fail (srv != NULL, FALSE);
|
g_return_val_if_fail (srv != NULL, FALSE);
|
||||||
g_return_val_if_fail (rtv != NULL, FALSE);
|
g_return_val_if_fail (rtv != NULL, FALSE);
|
||||||
|
|
||||||
|
/* check texture resolution and update crop area */
|
||||||
|
ID3D11ShaderResourceView_GetResource (srv[0], &resource);
|
||||||
|
ID3D11Texture2D_GetDesc ((ID3D11Texture2D *) resource, &desc);
|
||||||
|
ID3D11Resource_Release (resource);
|
||||||
|
|
||||||
|
if (converter->update_vertex ||
|
||||||
|
desc.Width != converter->input_texture_width ||
|
||||||
|
desc.Height != converter->input_texture_height) {
|
||||||
|
GST_DEBUG ("Update vertext buffer, texture resolution: %dx%d",
|
||||||
|
desc.Width, desc.Height);
|
||||||
|
|
||||||
|
converter->input_texture_width = desc.Width;
|
||||||
|
converter->input_texture_height = desc.Height;
|
||||||
|
|
||||||
|
if (!gst_d3d11_color_converter_update_vertex_buffer (converter)) {
|
||||||
|
GST_ERROR ("Cannot update vertex buffer");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ret = gst_d3d11_draw_quad_unlocked (converter->quad[0], converter->viewport,
|
ret = gst_d3d11_draw_quad_unlocked (converter->quad[0], converter->viewport,
|
||||||
1, srv, converter->num_input_view, rtv, 1, NULL);
|
1, srv, converter->num_input_view, rtv, 1, NULL);
|
||||||
|
|
||||||
|
@ -1292,3 +1410,23 @@ gst_d3d11_color_converter_update_rect (GstD3D11ColorConverter * converter,
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gst_d3d11_color_converter_update_crop_rect (GstD3D11ColorConverter * converter,
|
||||||
|
RECT * crop_rect)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (converter != NULL, FALSE);
|
||||||
|
g_return_val_if_fail (crop_rect != NULL, FALSE);
|
||||||
|
|
||||||
|
if (converter->crop_rect.left != crop_rect->left ||
|
||||||
|
converter->crop_rect.top != crop_rect->top ||
|
||||||
|
converter->crop_rect.right != crop_rect->right ||
|
||||||
|
converter->crop_rect.bottom != crop_rect->bottom) {
|
||||||
|
converter->crop_rect = *crop_rect;
|
||||||
|
|
||||||
|
/* vertex buffer will be updated on next convert() call */
|
||||||
|
converter->update_vertex = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
|
@ -45,6 +45,9 @@ gboolean gst_d3d11_color_converter_convert_unlocked (GstD3D11Col
|
||||||
gboolean gst_d3d11_color_converter_update_rect (GstD3D11ColorConverter * converter,
|
gboolean gst_d3d11_color_converter_update_rect (GstD3D11ColorConverter * converter,
|
||||||
RECT *rect);
|
RECT *rect);
|
||||||
|
|
||||||
|
gboolean gst_d3d11_color_converter_update_crop_rect (GstD3D11ColorConverter * converter,
|
||||||
|
RECT *crop_rect);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __GST_D3D11_COLOR_CONVERTER_H__ */
|
#endif /* __GST_D3D11_COLOR_CONVERTER_H__ */
|
||||||
|
|
Loading…
Reference in a new issue