mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 12:11:13 +00:00
d3d11decoder: Create decoder output view whenever it's required
Whatever the reason, buffer in pool might be freed then we need to configure decoder output views again.
This commit is contained in:
parent
567575e33d
commit
69f7f958a0
1 changed files with 42 additions and 75 deletions
|
@ -50,6 +50,8 @@ struct _GstD3D11DecoderPrivate
|
||||||
/* for staging */
|
/* for staging */
|
||||||
ID3D11Texture2D *staging;
|
ID3D11Texture2D *staging;
|
||||||
D3D11_TEXTURE2D_DESC staging_desc;
|
D3D11_TEXTURE2D_DESC staging_desc;
|
||||||
|
|
||||||
|
GUID decoder_profile;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define OUTPUT_VIEW_QUARK _decoder_output_view_get()
|
#define OUTPUT_VIEW_QUARK _decoder_output_view_get()
|
||||||
|
@ -298,86 +300,48 @@ gst_d3d11_decoder_output_view_free (GstD3D11DecoderOutputView * view)
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_d3d11_decoder_prepare_output_view (GstD3D11Decoder * self,
|
gst_d3d11_decoder_ensure_output_view (GstD3D11Decoder * self,
|
||||||
GstBufferPool * pool, guint pool_size, const GUID * decoder_profile)
|
GstBuffer * buffer)
|
||||||
{
|
{
|
||||||
GstD3D11DecoderPrivate *priv = self->priv;
|
GstD3D11DecoderPrivate *priv = self->priv;
|
||||||
GstBuffer **list = NULL;
|
|
||||||
D3D11_VIDEO_DECODER_OUTPUT_VIEW_DESC view_desc = { 0, };
|
D3D11_VIDEO_DECODER_OUTPUT_VIEW_DESC view_desc = { 0, };
|
||||||
guint i;
|
GstD3D11Memory *mem;
|
||||||
|
GstD3D11DecoderOutputView *view;
|
||||||
|
ID3D11VideoDecoderOutputView *view_handle;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
view_desc.DecodeProfile = *decoder_profile;
|
mem = (GstD3D11Memory *) gst_buffer_peek_memory (buffer, 0);
|
||||||
|
|
||||||
|
view = (GstD3D11DecoderOutputView *)
|
||||||
|
gst_mini_object_get_qdata (GST_MINI_OBJECT_CAST (mem), OUTPUT_VIEW_QUARK);
|
||||||
|
|
||||||
|
if (view)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
view_desc.DecodeProfile = priv->decoder_profile;
|
||||||
view_desc.ViewDimension = D3D11_VDOV_DIMENSION_TEXTURE2D;
|
view_desc.ViewDimension = D3D11_VDOV_DIMENSION_TEXTURE2D;
|
||||||
|
view_desc.Texture2D.ArraySlice = mem->subresource_index;
|
||||||
|
|
||||||
list = g_newa (GstBuffer *, pool_size);
|
GST_LOG_OBJECT (self,
|
||||||
memset (list, 0, sizeof (GstBuffer *) * pool_size);
|
"Create decoder output view with index %d", mem->subresource_index);
|
||||||
|
|
||||||
/* create output view here */
|
hr = ID3D11VideoDevice_CreateVideoDecoderOutputView (priv->video_device,
|
||||||
for (i = 0; i < pool_size; i++) {
|
(ID3D11Resource *) mem->texture, &view_desc, &view_handle);
|
||||||
GstFlowReturn ret;
|
if (!gst_d3d11_result (hr, priv->device)) {
|
||||||
GstBuffer *buf = NULL;
|
GST_ERROR_OBJECT (self,
|
||||||
GstD3D11Memory *mem;
|
"Could not create decoder output view, hr: 0x%x", (guint) hr);
|
||||||
GstD3D11DecoderOutputView *view;
|
return FALSE;
|
||||||
ID3D11VideoDecoderOutputView *view_handle;
|
|
||||||
HRESULT hr;
|
|
||||||
ID3D11Texture2D *texture;
|
|
||||||
GstD3D11Allocator *allocator;
|
|
||||||
|
|
||||||
ret = gst_buffer_pool_acquire_buffer (pool, &buf, NULL);
|
|
||||||
|
|
||||||
if (ret != GST_FLOW_OK || !buf) {
|
|
||||||
GST_ERROR_OBJECT (self, "Could acquire buffer from pool");
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
list[i] = buf;
|
|
||||||
mem = (GstD3D11Memory *) gst_buffer_peek_memory (buf, 0);
|
|
||||||
|
|
||||||
allocator = GST_D3D11_ALLOCATOR (GST_MEMORY_CAST (mem)->allocator);
|
|
||||||
texture = allocator->texture;
|
|
||||||
|
|
||||||
if (!texture) {
|
|
||||||
GST_ERROR_OBJECT (self, "D3D11 allocator does not have texture");
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
view_desc.Texture2D.ArraySlice = mem->subresource_index;
|
|
||||||
GST_LOG_OBJECT (self,
|
|
||||||
"Create decoder output view with index %d", mem->subresource_index);
|
|
||||||
|
|
||||||
hr = ID3D11VideoDevice_CreateVideoDecoderOutputView (priv->video_device,
|
|
||||||
(ID3D11Resource *) texture, &view_desc, &view_handle);
|
|
||||||
if (!gst_d3d11_result (hr, priv->device)) {
|
|
||||||
GST_ERROR_OBJECT (self,
|
|
||||||
"Could not create decoder output view, hr: 0x%x", (guint) hr);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
view = g_new0 (GstD3D11DecoderOutputView, 1);
|
|
||||||
view->device = gst_object_ref (priv->device);
|
|
||||||
view->handle = view_handle;
|
|
||||||
view->view_id = mem->subresource_index;
|
|
||||||
|
|
||||||
gst_mini_object_set_qdata (GST_MINI_OBJECT_CAST (mem), OUTPUT_VIEW_QUARK,
|
|
||||||
view, (GDestroyNotify) gst_d3d11_decoder_output_view_free);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* return buffers to pool */
|
view = g_new0 (GstD3D11DecoderOutputView, 1);
|
||||||
for (i = 0; i < pool_size; i++) {
|
view->device = gst_object_ref (priv->device);
|
||||||
gst_buffer_unref (list[i]);
|
view->handle = view_handle;
|
||||||
}
|
view->view_id = mem->subresource_index;
|
||||||
|
|
||||||
|
gst_mini_object_set_qdata (GST_MINI_OBJECT_CAST (mem), OUTPUT_VIEW_QUARK,
|
||||||
|
view, (GDestroyNotify) gst_d3d11_decoder_output_view_free);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
error:
|
|
||||||
if (list) {
|
|
||||||
for (i = 0; i < pool_size; i++) {
|
|
||||||
if (list[i])
|
|
||||||
gst_buffer_unref (list[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Must be called from D3D11Device thread */
|
/* Must be called from D3D11Device thread */
|
||||||
|
@ -434,11 +398,6 @@ gst_d3d11_decoder_prepare_output_view_pool (GstD3D11Decoder * self,
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gst_d3d11_decoder_prepare_output_view (self,
|
|
||||||
pool, pool_size, decoder_profile)) {
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
priv->internal_pool = pool;
|
priv->internal_pool = pool;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -651,6 +610,7 @@ gst_d3d11_decoder_open (GstD3D11Decoder * decoder, GstD3D11Codec codec,
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
priv->decoder_profile = *selected_profile;
|
||||||
decoder->opened = TRUE;
|
decoder->opened = TRUE;
|
||||||
gst_d3d11_device_unlock (priv->device);
|
gst_d3d11_device_unlock (priv->device);
|
||||||
|
|
||||||
|
@ -827,7 +787,14 @@ gst_d3d11_decoder_get_output_view_buffer (GstD3D11Decoder * decoder)
|
||||||
if (ret != GST_FLOW_OK || !buf) {
|
if (ret != GST_FLOW_OK || !buf) {
|
||||||
GST_ERROR_OBJECT (decoder, "Couldn't get buffer from pool, ret %s",
|
GST_ERROR_OBJECT (decoder, "Couldn't get buffer from pool, ret %s",
|
||||||
gst_flow_get_name (ret));
|
gst_flow_get_name (ret));
|
||||||
return FALSE;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!gst_d3d11_decoder_ensure_output_view (decoder, buf)) {
|
||||||
|
GST_ERROR_OBJECT (decoder, "Output view unavailable");
|
||||||
|
gst_buffer_unref (buf);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return buf;
|
return buf;
|
||||||
|
|
Loading…
Reference in a new issue