mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-17 03:35:21 +00:00
d3d11videosink: Add support for crop meta
... when upstream element is d3d11. Note that, if upstream element is not d3d11, crop meta is almost pointless since d3d11videosink will upload video frame to GPU memory in any case. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/933>
This commit is contained in:
parent
0fa5a06ed9
commit
052983014e
2 changed files with 55 additions and 6 deletions
|
@ -905,6 +905,12 @@ gst_d3d11_video_sink_propose_allocation (GstBaseSink * sink, GstQuery * query)
|
||||||
gst_buffer_pool_config_get_params (config, nullptr, &size, nullptr,
|
gst_buffer_pool_config_get_params (config, nullptr, &size, nullptr,
|
||||||
nullptr);
|
nullptr);
|
||||||
gst_structure_free (config);
|
gst_structure_free (config);
|
||||||
|
|
||||||
|
/* In case of system memory, we will upload video frame to GPU memory,
|
||||||
|
* (which is copy in any case), so crop meta support for system memory
|
||||||
|
* is almost pointless */
|
||||||
|
gst_query_add_allocation_meta (query,
|
||||||
|
GST_VIDEO_CROP_META_API_TYPE, nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1068,6 +1074,7 @@ gst_d3d11_video_sink_get_fallback_buffer (GstD3D11VideoSink * self,
|
||||||
GstBuffer *outbuf = NULL;
|
GstBuffer *outbuf = NULL;
|
||||||
ID3D11ShaderResourceView *view[GST_VIDEO_MAX_PLANES];
|
ID3D11ShaderResourceView *view[GST_VIDEO_MAX_PLANES];
|
||||||
GstVideoOverlayCompositionMeta *compo_meta;
|
GstVideoOverlayCompositionMeta *compo_meta;
|
||||||
|
GstVideoCropMeta *crop_meta;
|
||||||
|
|
||||||
if (!self->fallback_pool ||
|
if (!self->fallback_pool ||
|
||||||
!gst_buffer_pool_set_active (self->fallback_pool, TRUE) ||
|
!gst_buffer_pool_set_active (self->fallback_pool, TRUE) ||
|
||||||
|
@ -1098,6 +1105,17 @@ gst_d3d11_video_sink_get_fallback_buffer (GstD3D11VideoSink * self,
|
||||||
if (compo_meta)
|
if (compo_meta)
|
||||||
gst_buffer_add_video_overlay_composition_meta (outbuf, compo_meta->overlay);
|
gst_buffer_add_video_overlay_composition_meta (outbuf, compo_meta->overlay);
|
||||||
|
|
||||||
|
/* And copy crop meta as well */
|
||||||
|
crop_meta = gst_buffer_get_video_crop_meta (inbuf);
|
||||||
|
if (crop_meta) {
|
||||||
|
GstVideoCropMeta *new_crop_meta = gst_buffer_add_video_crop_meta (outbuf);
|
||||||
|
|
||||||
|
new_crop_meta->x = crop_meta->x;
|
||||||
|
new_crop_meta->y = crop_meta->y;
|
||||||
|
new_crop_meta->width = crop_meta->width;
|
||||||
|
new_crop_meta->height = crop_meta->height;
|
||||||
|
}
|
||||||
|
|
||||||
*fallback_buf = outbuf;
|
*fallback_buf = outbuf;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
|
@ -828,12 +828,13 @@ gst_d3d11_window_buffer_ensure_processor_input (GstD3D11Window * self,
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_d3d11_window_do_processor (GstD3D11Window * self,
|
gst_d3d11_window_do_processor (GstD3D11Window * self,
|
||||||
ID3D11VideoProcessorInputView * piv, ID3D11VideoProcessorOutputView * pov)
|
ID3D11VideoProcessorInputView * piv, ID3D11VideoProcessorOutputView * pov,
|
||||||
|
RECT * input_rect)
|
||||||
{
|
{
|
||||||
gboolean ret;
|
gboolean ret;
|
||||||
|
|
||||||
ret = gst_d3d11_video_processor_render_unlocked (self->processor,
|
ret = gst_d3d11_video_processor_render_unlocked (self->processor,
|
||||||
&self->input_rect, piv, &self->render_rect, pov);
|
input_rect, piv, &self->render_rect, pov);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
GST_ERROR_OBJECT (self, "Couldn't render to backbuffer using processor");
|
GST_ERROR_OBJECT (self, "Couldn't render to backbuffer using processor");
|
||||||
} else {
|
} else {
|
||||||
|
@ -847,8 +848,13 @@ gst_d3d11_window_do_processor (GstD3D11Window * self,
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_d3d11_window_do_convert (GstD3D11Window * self,
|
gst_d3d11_window_do_convert (GstD3D11Window * self,
|
||||||
ID3D11ShaderResourceView * srv[GST_VIDEO_MAX_PLANES],
|
ID3D11ShaderResourceView * srv[GST_VIDEO_MAX_PLANES],
|
||||||
ID3D11RenderTargetView * rtv)
|
ID3D11RenderTargetView * rtv, RECT * input_rect)
|
||||||
{
|
{
|
||||||
|
if (!gst_d3d11_converter_update_src_rect (self->converter, input_rect)) {
|
||||||
|
GST_ERROR_OBJECT (self, "Failed to update src rect");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
if (!gst_d3d11_converter_convert_unlocked (self->converter,
|
if (!gst_d3d11_converter_convert_unlocked (self->converter,
|
||||||
srv, &rtv, NULL, NULL)) {
|
srv, &rtv, NULL, NULL)) {
|
||||||
GST_ERROR_OBJECT (self, "Couldn't render to backbuffer using converter");
|
GST_ERROR_OBJECT (self, "Couldn't render to backbuffer using converter");
|
||||||
|
@ -880,6 +886,8 @@ gst_d3d111_window_present (GstD3D11Window * self, GstBuffer * buffer,
|
||||||
gboolean can_convert = FALSE;
|
gboolean can_convert = FALSE;
|
||||||
gboolean can_process = FALSE;
|
gboolean can_process = FALSE;
|
||||||
gboolean convert_ret = FALSE;
|
gboolean convert_ret = FALSE;
|
||||||
|
RECT input_rect = self->input_rect;
|
||||||
|
GstVideoCropMeta *crop_meta;
|
||||||
|
|
||||||
/* Map memory in any case so that we can upload pending stage texture */
|
/* Map memory in any case so that we can upload pending stage texture */
|
||||||
if (!gst_d3d11_buffer_map (buffer, device_handle, infos, GST_MAP_READ)) {
|
if (!gst_d3d11_buffer_map (buffer, device_handle, infos, GST_MAP_READ)) {
|
||||||
|
@ -898,6 +906,29 @@ gst_d3d111_window_present (GstD3D11Window * self, GstBuffer * buffer,
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
crop_meta = gst_buffer_get_video_crop_meta (buffer);
|
||||||
|
/* Do minimal validate */
|
||||||
|
if (crop_meta) {
|
||||||
|
ID3D11Texture2D *texture = (ID3D11Texture2D *) infos[0].data;
|
||||||
|
D3D11_TEXTURE2D_DESC desc = { 0, };
|
||||||
|
|
||||||
|
texture->GetDesc (&desc);
|
||||||
|
|
||||||
|
if (desc.Width < crop_meta->x + crop_meta->width ||
|
||||||
|
desc.Height < crop_meta->y + crop_meta->height) {
|
||||||
|
GST_WARNING_OBJECT (self, "Invalid crop meta, ignore");
|
||||||
|
|
||||||
|
crop_meta = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (crop_meta) {
|
||||||
|
input_rect.left = crop_meta->x;
|
||||||
|
input_rect.right = crop_meta->x + crop_meta->width;
|
||||||
|
input_rect.top = crop_meta->y;
|
||||||
|
input_rect.bottom = crop_meta->y + crop_meta->height;
|
||||||
|
}
|
||||||
|
|
||||||
if (self->first_present) {
|
if (self->first_present) {
|
||||||
D3D11_VIEWPORT viewport;
|
D3D11_VIEWPORT viewport;
|
||||||
|
|
||||||
|
@ -919,11 +950,11 @@ gst_d3d111_window_present (GstD3D11Window * self, GstBuffer * buffer,
|
||||||
* 3) otherwise, use processor
|
* 3) otherwise, use processor
|
||||||
*/
|
*/
|
||||||
if (can_process && self->processor_in_use) {
|
if (can_process && self->processor_in_use) {
|
||||||
convert_ret = gst_d3d11_window_do_processor (self, piv, pov);
|
convert_ret = gst_d3d11_window_do_processor (self, piv, pov, &input_rect);
|
||||||
} else if (can_convert) {
|
} else if (can_convert) {
|
||||||
convert_ret = gst_d3d11_window_do_convert (self, srv, rtv);
|
convert_ret = gst_d3d11_window_do_convert (self, srv, rtv, &input_rect);
|
||||||
} else if (can_process) {
|
} else if (can_process) {
|
||||||
convert_ret = gst_d3d11_window_do_processor (self, piv, pov);
|
convert_ret = gst_d3d11_window_do_processor (self, piv, pov, &input_rect);
|
||||||
} else {
|
} else {
|
||||||
g_assert_not_reached ();
|
g_assert_not_reached ();
|
||||||
ret = GST_FLOW_ERROR;
|
ret = GST_FLOW_ERROR;
|
||||||
|
|
Loading…
Reference in a new issue