mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-02 12:32:29 +00:00
d3d11decoder: Use aligned resolution for staging texture
Not only any textures for decoder output view, any destination texture which would be copied from decoder output texture need to be aligned too. Otherwise driver sometimes crashed/hung (not sure why).
This commit is contained in:
parent
5074cecc82
commit
5c51601cdf
1 changed files with 30 additions and 33 deletions
|
@ -79,8 +79,8 @@ struct _GstD3D11DecoderPrivate
|
|||
|
||||
/* for staging */
|
||||
ID3D11Texture2D *staging;
|
||||
D3D11_TEXTURE2D_DESC staging_desc;
|
||||
D3D11_BOX staging_box;
|
||||
gsize staging_texture_offset[GST_VIDEO_MAX_PLANES];
|
||||
gint stating_texture_stride[GST_VIDEO_MAX_PLANES];
|
||||
|
||||
GUID decoder_profile;
|
||||
};
|
||||
|
@ -559,6 +559,7 @@ gst_d3d11_decoder_open (GstD3D11Decoder * decoder, GstD3D11Codec codec,
|
|||
D3D11_VIDEO_DECODER_CONFIG *config_list;
|
||||
D3D11_VIDEO_DECODER_CONFIG *best_config = NULL;
|
||||
D3D11_VIDEO_DECODER_DESC decoder_desc = { 0, };
|
||||
D3D11_TEXTURE2D_DESC staging_desc = { 0, };
|
||||
GUID selected_profile;
|
||||
gint i;
|
||||
guint aligned_width, aligned_height;
|
||||
|
@ -686,34 +687,26 @@ gst_d3d11_decoder_open (GstD3D11Decoder * decoder, GstD3D11Codec codec,
|
|||
GST_DEBUG_OBJECT (decoder, "Decoder object %p created", priv->decoder);
|
||||
|
||||
/* create stage texture to copy out */
|
||||
memset (&priv->staging_desc, 0, sizeof (D3D11_TEXTURE2D_DESC));
|
||||
priv->staging_desc.Width = GST_VIDEO_INFO_WIDTH (info);
|
||||
priv->staging_desc.Height = GST_VIDEO_INFO_HEIGHT (info);
|
||||
priv->staging_desc.MipLevels = 1;
|
||||
priv->staging_desc.Format = d3d11_format->dxgi_format;
|
||||
priv->staging_desc.SampleDesc.Count = 1;
|
||||
priv->staging_desc.ArraySize = 1;
|
||||
priv->staging_desc.Usage = D3D11_USAGE_STAGING;
|
||||
priv->staging_desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
|
||||
staging_desc.Width = aligned_width;
|
||||
staging_desc.Height = aligned_height;
|
||||
staging_desc.MipLevels = 1;
|
||||
staging_desc.Format = d3d11_format->dxgi_format;
|
||||
staging_desc.SampleDesc.Count = 1;
|
||||
staging_desc.ArraySize = 1;
|
||||
staging_desc.Usage = D3D11_USAGE_STAGING;
|
||||
staging_desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
|
||||
|
||||
priv->staging = gst_d3d11_device_create_texture (priv->device,
|
||||
&priv->staging_desc, NULL);
|
||||
&staging_desc, NULL);
|
||||
if (!priv->staging) {
|
||||
GST_ERROR_OBJECT (decoder, "Couldn't create staging texture");
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* This D3D11_BOX structure is used to copy decoder view to staging texture,
|
||||
* in case of system memory downstream.
|
||||
* Since resolution of decoder view might be larger than this staging texture,
|
||||
* this D3D11_BOX structure will guide the target area which need to be copied.
|
||||
*/
|
||||
priv->staging_box.left = 0;
|
||||
priv->staging_box.top = 0;
|
||||
priv->staging_box.front = 0;
|
||||
priv->staging_box.back = 1;
|
||||
priv->staging_box.right = GST_VIDEO_INFO_WIDTH (info);
|
||||
priv->staging_box.bottom = GST_VIDEO_INFO_HEIGHT (info);
|
||||
memset (priv->staging_texture_offset,
|
||||
0, sizeof (priv->staging_texture_offset));
|
||||
memset (priv->stating_texture_stride,
|
||||
0, sizeof (priv->stating_texture_stride));
|
||||
|
||||
priv->decoder_profile = selected_profile;
|
||||
decoder->opened = TRUE;
|
||||
|
@ -949,14 +942,10 @@ copy_to_system (GstD3D11Decoder * self, GstVideoInfo * info,
|
|||
GstBuffer * decoder_buffer, GstBuffer * output)
|
||||
{
|
||||
GstD3D11DecoderPrivate *priv = self->priv;
|
||||
D3D11_TEXTURE2D_DESC *desc = &priv->staging_desc;
|
||||
GstVideoFrame out_frame;
|
||||
gint i;
|
||||
GstD3D11Memory *in_mem;
|
||||
D3D11_MAPPED_SUBRESOURCE map;
|
||||
gsize offset[GST_VIDEO_MAX_PLANES];
|
||||
gint stride[GST_VIDEO_MAX_PLANES];
|
||||
gsize dummy;
|
||||
HRESULT hr;
|
||||
ID3D11DeviceContext *device_context =
|
||||
gst_d3d11_device_get_device_context_handle (priv->device);
|
||||
|
@ -971,8 +960,7 @@ copy_to_system (GstD3D11Decoder * self, GstVideoInfo * info,
|
|||
gst_d3d11_device_lock (priv->device);
|
||||
ID3D11DeviceContext_CopySubresourceRegion (device_context,
|
||||
(ID3D11Resource *) priv->staging, 0, 0, 0, 0,
|
||||
(ID3D11Resource *) in_mem->texture, in_mem->subresource_index,
|
||||
&priv->staging_box);
|
||||
(ID3D11Resource *) in_mem->texture, in_mem->subresource_index, NULL);
|
||||
|
||||
hr = ID3D11DeviceContext_Map (device_context,
|
||||
(ID3D11Resource *) priv->staging, 0, D3D11_MAP_READ, 0, &map);
|
||||
|
@ -983,15 +971,24 @@ copy_to_system (GstD3D11Decoder * self, GstVideoInfo * info,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
gst_d3d11_dxgi_format_get_size (desc->Format, desc->Width, desc->Height,
|
||||
map.RowPitch, offset, stride, &dummy);
|
||||
/* calculate stride and offset only once */
|
||||
if (priv->stating_texture_stride[0] == 0) {
|
||||
D3D11_TEXTURE2D_DESC desc;
|
||||
gsize dummy;
|
||||
|
||||
ID3D11Texture2D_GetDesc (priv->staging, &desc);
|
||||
|
||||
gst_d3d11_dxgi_format_get_size (desc.Format, desc.Width, desc.Height,
|
||||
map.RowPitch, priv->staging_texture_offset,
|
||||
priv->stating_texture_stride, &dummy);
|
||||
}
|
||||
|
||||
for (i = 0; i < GST_VIDEO_FRAME_N_PLANES (&out_frame); i++) {
|
||||
guint8 *src, *dst;
|
||||
gint j;
|
||||
gint width;
|
||||
|
||||
src = (guint8 *) map.pData + offset[i];
|
||||
src = (guint8 *) map.pData + priv->staging_texture_offset[i];
|
||||
dst = GST_VIDEO_FRAME_PLANE_DATA (&out_frame, i);
|
||||
width = GST_VIDEO_FRAME_COMP_WIDTH (&out_frame, i) *
|
||||
GST_VIDEO_FRAME_COMP_PSTRIDE (&out_frame, i);
|
||||
|
@ -999,7 +996,7 @@ copy_to_system (GstD3D11Decoder * self, GstVideoInfo * info,
|
|||
for (j = 0; j < GST_VIDEO_FRAME_COMP_HEIGHT (&out_frame, i); j++) {
|
||||
memcpy (dst, src, width);
|
||||
dst += GST_VIDEO_FRAME_PLANE_STRIDE (&out_frame, i);
|
||||
src += map.RowPitch;
|
||||
src += priv->stating_texture_stride[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue