mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-09-25 21:40:34 +00:00
d3d11: Privatize d3d11memory implementation
Hide most of symbols of GstD3D11Memory object. GstD3D11Memory is one of primary resource for imcoming d3d11 library and it's expected to be a extensible feature. Hiding implementation detail would be helpful for later use case. Summary of this commit: * Now all native Direct3D11 resources are private of GstD3D11Memory. To access native resources, getter methods need to be used or generic map (e.g., gst_memory_map) API should be called apart from some exceptional case such as d3d11decoder case. * Various helper methods are added for GstBuffer related operations and in order to remove duplicated code. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/1892>
This commit is contained in:
parent
f1e3e5276a
commit
59a1897c39
17 changed files with 941 additions and 577 deletions
|
@ -1627,10 +1627,10 @@ gst_d3d11_convert_prefer_video_processor (GstD3D11Convert * self,
|
|||
/* If we can use shader, we prefer to use shader instead of video processor
|
||||
* because video processor implementation is vendor dependent
|
||||
* and not flexible */
|
||||
if (gst_d3d11_memory_ensure_shader_resource_view (dmem))
|
||||
if (gst_d3d11_memory_get_shader_resource_view_size (dmem))
|
||||
return FALSE;
|
||||
|
||||
if (!gst_d3d11_video_processor_ensure_input_view (self->processor, dmem))
|
||||
if (!gst_d3d11_video_processor_get_input_view (self->processor, dmem))
|
||||
return FALSE;
|
||||
|
||||
mem = gst_buffer_peek_memory (outbuf, 0);
|
||||
|
@ -1640,35 +1640,34 @@ gst_d3d11_convert_prefer_video_processor (GstD3D11Convert * self,
|
|||
if (dmem->device != filter->device)
|
||||
return FALSE;
|
||||
|
||||
if (!gst_d3d11_video_processor_ensure_output_view (self->processor, dmem))
|
||||
if (!gst_d3d11_video_processor_get_output_view (self->processor, dmem))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
static gboolean
|
||||
gst_d3d11_convert_transform_using_processor (GstD3D11Convert * self,
|
||||
GstBuffer * inbuf, GstBuffer * outbuf)
|
||||
{
|
||||
GstMemory *in_mem, *out_mem;
|
||||
GstD3D11Memory *in_dmem, *out_dmem;
|
||||
GstMapInfo in_map, out_map;
|
||||
GstD3D11Memory *in_mem, *out_mem;
|
||||
RECT in_rect, out_rect;
|
||||
gboolean ret;
|
||||
ID3D11VideoProcessorInputView *piv;
|
||||
ID3D11VideoProcessorOutputView *pov;
|
||||
|
||||
in_mem = gst_buffer_peek_memory (inbuf, 0);
|
||||
in_dmem = (GstD3D11Memory *) in_mem;
|
||||
if (!gst_memory_map (in_mem, &in_map, GST_MAP_D3D11 | GST_MAP_READ)) {
|
||||
GST_ERROR_OBJECT (self, "Failed to map input d3d11 memory");
|
||||
return GST_FLOW_ERROR;
|
||||
in_mem = (GstD3D11Memory *) gst_buffer_peek_memory (inbuf, 0);
|
||||
out_mem = (GstD3D11Memory *) gst_buffer_peek_memory (outbuf, 0);
|
||||
|
||||
piv = gst_d3d11_video_processor_get_input_view (self->processor, in_mem);
|
||||
if (!piv) {
|
||||
GST_ERROR_OBJECT (self, "ID3D11VideoProcessorInputView is unavailable");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
out_mem = gst_buffer_peek_memory (outbuf, 0);
|
||||
out_dmem = (GstD3D11Memory *) out_mem;
|
||||
if (!gst_memory_map (out_mem, &out_map, GST_MAP_D3D11 | GST_MAP_WRITE)) {
|
||||
GST_ERROR_OBJECT (self, "Failed to map output d3d11 memory");
|
||||
gst_memory_unmap (in_mem, &in_map);
|
||||
return GST_FLOW_ERROR;
|
||||
pov = gst_d3d11_video_processor_get_output_view (self->processor, out_mem);
|
||||
if (!pov) {
|
||||
GST_ERROR_OBJECT (self, "ID3D11VideoProcessorOutputView is unavailable");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
in_rect.left = 0;
|
||||
|
@ -1681,19 +1680,8 @@ gst_d3d11_convert_transform_using_processor (GstD3D11Convert * self,
|
|||
out_rect.right = self->out_src_box.right;
|
||||
out_rect.bottom = self->out_src_box.bottom;
|
||||
|
||||
ret = gst_d3d11_video_processor_render (self->processor,
|
||||
&in_rect, in_dmem->processor_input_view, &out_rect,
|
||||
out_dmem->processor_output_view);
|
||||
|
||||
gst_memory_unmap (in_mem, &in_map);
|
||||
gst_memory_unmap (out_mem, &out_map);
|
||||
|
||||
if (!ret) {
|
||||
GST_ERROR_OBJECT (self, "Couldn't convert using video processor");
|
||||
return GST_FLOW_ERROR;
|
||||
}
|
||||
|
||||
return GST_FLOW_OK;
|
||||
return gst_d3d11_video_processor_render (self->processor,
|
||||
&in_rect, piv, &out_rect, pov);
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
|
@ -1702,135 +1690,156 @@ gst_d3d11_convert_transform (GstBaseTransform * trans,
|
|||
{
|
||||
GstD3D11BaseFilter *filter = GST_D3D11_BASE_FILTER (trans);
|
||||
GstD3D11Convert *self = GST_D3D11_CONVERT (trans);
|
||||
GstD3D11Device *device = filter->device;
|
||||
ID3D11Device *device_handle;
|
||||
ID3D11DeviceContext *context_handle;
|
||||
ID3D11ShaderResourceView *resource_view[GST_VIDEO_MAX_PLANES] = { NULL, };
|
||||
ID3D11RenderTargetView *render_view[GST_VIDEO_MAX_PLANES] = { NULL, };
|
||||
gint i, j, view_index;
|
||||
gint i;
|
||||
gboolean copy_input = FALSE;
|
||||
gboolean copy_output = FALSE;
|
||||
GstD3D11Device *device = filter->device;
|
||||
|
||||
if (gst_d3d11_convert_prefer_video_processor (self, inbuf, outbuf))
|
||||
return gst_d3d11_convert_transform_using_processor (self, inbuf, outbuf);
|
||||
GstMapInfo in_map[GST_VIDEO_MAX_PLANES];
|
||||
GstMapInfo out_map[GST_VIDEO_MAX_PLANES];
|
||||
|
||||
device_handle = gst_d3d11_device_get_device_handle (device);
|
||||
context_handle = gst_d3d11_device_get_device_context_handle (device);
|
||||
|
||||
view_index = 0;
|
||||
for (i = 0; i < gst_buffer_n_memory (inbuf); i++) {
|
||||
GstMemory *mem = gst_buffer_peek_memory (inbuf, i);
|
||||
GstD3D11Memory *d3d11_mem;
|
||||
GstMapInfo info;
|
||||
|
||||
g_assert (gst_is_d3d11_memory (mem));
|
||||
|
||||
d3d11_mem = (GstD3D11Memory *) mem;
|
||||
/* map to transfer pending staging data if any */
|
||||
if (d3d11_mem->desc.Usage == D3D11_USAGE_DEFAULT) {
|
||||
gst_memory_map (mem, &info, GST_MAP_READ | GST_MAP_D3D11);
|
||||
gst_memory_unmap (mem, &info);
|
||||
}
|
||||
|
||||
if (gst_d3d11_memory_ensure_shader_resource_view (d3d11_mem)) {
|
||||
GST_TRACE_OBJECT (self, "Use input texture resource without copy");
|
||||
|
||||
for (j = 0; j < d3d11_mem->num_shader_resource_views; j++) {
|
||||
resource_view[view_index] = d3d11_mem->shader_resource_view[j];
|
||||
view_index++;
|
||||
}
|
||||
} else {
|
||||
GST_TRACE_OBJECT (self, "Render using fallback input texture");
|
||||
copy_input = TRUE;
|
||||
|
||||
if (!create_shader_input_resource (self, device,
|
||||
self->in_d3d11_format, &filter->in_info)) {
|
||||
GST_ERROR_OBJECT (self, "Failed to configure fallback input texture");
|
||||
return GST_FLOW_ERROR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!gst_d3d11_buffer_map (inbuf, device_handle, in_map, GST_MAP_READ)) {
|
||||
GST_ERROR_OBJECT (self, "Couldn't map input buffer");
|
||||
goto invalid_memory;
|
||||
}
|
||||
|
||||
/* if input memory has no resource view,
|
||||
* copy texture into our fallback texture */
|
||||
if (copy_input) {
|
||||
if (!gst_d3d11_buffer_map (outbuf, device_handle, out_map, GST_MAP_WRITE)) {
|
||||
GST_ERROR_OBJECT (self, "Couldn't map output buffer");
|
||||
gst_d3d11_buffer_unmap (inbuf, in_map);
|
||||
goto invalid_memory;
|
||||
}
|
||||
|
||||
if (gst_d3d11_convert_prefer_video_processor (self, inbuf, outbuf)) {
|
||||
gboolean ret =
|
||||
gst_d3d11_convert_transform_using_processor (self, inbuf, outbuf);
|
||||
|
||||
if (!ret) {
|
||||
GST_ERROR_OBJECT (self, "Couldn't convert using video processor");
|
||||
goto conversion_failed;
|
||||
}
|
||||
|
||||
gst_d3d11_buffer_unmap (inbuf, in_map);
|
||||
gst_d3d11_buffer_unmap (outbuf, out_map);
|
||||
|
||||
return GST_FLOW_OK;
|
||||
}
|
||||
|
||||
/* Ensure shader resource views */
|
||||
if (!gst_d3d11_buffer_get_shader_resource_view (inbuf, resource_view)) {
|
||||
if (!create_shader_input_resource (self, device,
|
||||
self->in_d3d11_format, &filter->in_info)) {
|
||||
GST_ERROR_OBJECT (self, "Failed to configure fallback input texture");
|
||||
goto fallback_failed;
|
||||
}
|
||||
|
||||
copy_input = TRUE;
|
||||
gst_d3d11_device_lock (device);
|
||||
for (i = 0; i < gst_buffer_n_memory (inbuf); i++) {
|
||||
GstMemory *mem = gst_buffer_peek_memory (inbuf, i);
|
||||
GstD3D11Memory *d3d11_mem;
|
||||
GstD3D11Memory *mem =
|
||||
(GstD3D11Memory *) gst_buffer_peek_memory (inbuf, i);
|
||||
guint subidx;
|
||||
D3D11_BOX src_box = { 0, };
|
||||
D3D11_TEXTURE2D_DESC src_desc;
|
||||
D3D11_TEXTURE2D_DESC dst_desc;
|
||||
|
||||
g_assert (gst_is_d3d11_memory (mem));
|
||||
subidx = gst_d3d11_memory_get_subresource_index (mem);
|
||||
gst_d3d11_memory_get_texture_desc (mem, &src_desc);
|
||||
|
||||
d3d11_mem = (GstD3D11Memory *) mem;
|
||||
ID3D11Texture2D_GetDesc (self->in_texture[i], &dst_desc);
|
||||
|
||||
src_box.left = 0;
|
||||
src_box.top = 0;
|
||||
src_box.front = 0;
|
||||
src_box.back = 1;
|
||||
src_box.right = MIN (src_desc.Width, dst_desc.Width);
|
||||
src_box.bottom = MIN (src_desc.Height, dst_desc.Height);
|
||||
|
||||
ID3D11DeviceContext_CopySubresourceRegion (context_handle,
|
||||
(ID3D11Resource *) self->in_texture[i], 0, 0, 0, 0,
|
||||
(ID3D11Resource *) d3d11_mem->texture, d3d11_mem->subresource_index,
|
||||
&self->in_src_box);
|
||||
(ID3D11Resource *) in_map[i].data, subidx, &src_box);
|
||||
}
|
||||
gst_d3d11_device_unlock (device);
|
||||
}
|
||||
|
||||
view_index = 0;
|
||||
for (i = 0; i < gst_buffer_n_memory (outbuf); i++) {
|
||||
GstMemory *mem = gst_buffer_peek_memory (outbuf, i);
|
||||
GstD3D11Memory *d3d11_mem;
|
||||
|
||||
g_assert (gst_is_d3d11_memory (mem));
|
||||
|
||||
d3d11_mem = (GstD3D11Memory *) mem;
|
||||
|
||||
if (gst_d3d11_memory_ensure_render_target_view (d3d11_mem)) {
|
||||
GST_TRACE_OBJECT (self, "Render to output texture directly");
|
||||
|
||||
for (j = 0; j < d3d11_mem->num_render_target_views; j++) {
|
||||
render_view[view_index] = d3d11_mem->render_target_view[j];
|
||||
view_index++;
|
||||
}
|
||||
} else {
|
||||
GST_TRACE_OBJECT (self, "Render to fallback output texture");
|
||||
copy_output = TRUE;
|
||||
|
||||
if (!create_shader_output_resource (self, device, self->out_d3d11_format,
|
||||
&filter->out_info)) {
|
||||
GST_ERROR_OBJECT (self, "Failed to configure fallback output texture");
|
||||
return GST_FLOW_ERROR;
|
||||
}
|
||||
break;
|
||||
/* Ensure render target views */
|
||||
if (!gst_d3d11_buffer_get_render_target_view (outbuf, render_view)) {
|
||||
if (!create_shader_output_resource (self, device,
|
||||
self->out_d3d11_format, &filter->out_info)) {
|
||||
GST_ERROR_OBJECT (self, "Failed to configure fallback output texture");
|
||||
goto fallback_failed;
|
||||
}
|
||||
|
||||
copy_output = TRUE;
|
||||
}
|
||||
|
||||
if (!gst_d3d11_color_converter_convert (self->converter,
|
||||
copy_input ? self->shader_resource_view : resource_view,
|
||||
copy_output ? self->render_target_view : render_view, NULL, NULL)) {
|
||||
GST_ERROR_OBJECT (self, "Failed to convert");
|
||||
|
||||
return GST_FLOW_ERROR;
|
||||
goto conversion_failed;
|
||||
}
|
||||
|
||||
if (copy_output) {
|
||||
gst_d3d11_device_lock (device);
|
||||
for (i = 0; i < gst_buffer_n_memory (outbuf); i++) {
|
||||
GstMemory *mem = gst_buffer_peek_memory (outbuf, i);
|
||||
GstD3D11Memory *d3d11_mem;
|
||||
GstD3D11Memory *mem =
|
||||
(GstD3D11Memory *) gst_buffer_peek_memory (outbuf, i);
|
||||
guint subidx;
|
||||
D3D11_BOX src_box = { 0, };
|
||||
D3D11_TEXTURE2D_DESC src_desc;
|
||||
D3D11_TEXTURE2D_DESC dst_desc;
|
||||
|
||||
g_assert (gst_is_d3d11_memory (mem));
|
||||
ID3D11Texture2D_GetDesc (self->out_texture[i], &src_desc);
|
||||
subidx = gst_d3d11_memory_get_subresource_index (mem);
|
||||
gst_d3d11_memory_get_texture_desc (mem, &dst_desc);
|
||||
|
||||
d3d11_mem = (GstD3D11Memory *) mem;
|
||||
src_box.left = 0;
|
||||
src_box.top = 0;
|
||||
src_box.front = 0;
|
||||
src_box.back = 1;
|
||||
src_box.right = MIN (src_desc.Width, dst_desc.Width);
|
||||
src_box.bottom = MIN (src_desc.Height, dst_desc.Height);
|
||||
|
||||
ID3D11DeviceContext_CopySubresourceRegion (context_handle,
|
||||
(ID3D11Resource *) d3d11_mem->texture, d3d11_mem->subresource_index,
|
||||
0, 0, 0, (ID3D11Resource *) self->out_texture[i], 0,
|
||||
&self->out_src_box);
|
||||
(ID3D11Resource *) out_map[i].data, subidx, 0, 0, 0,
|
||||
(ID3D11Resource *) self->out_texture[i], 0, &src_box);
|
||||
}
|
||||
gst_d3d11_device_unlock (device);
|
||||
} else {
|
||||
for (i = 0; i < gst_buffer_n_memory (outbuf); i++) {
|
||||
GstMemory *mem = gst_buffer_peek_memory (outbuf, i);
|
||||
GST_MINI_OBJECT_FLAG_SET (mem, GST_D3D11_MEMORY_TRANSFER_NEED_DOWNLOAD);
|
||||
}
|
||||
}
|
||||
|
||||
gst_d3d11_buffer_unmap (inbuf, in_map);
|
||||
gst_d3d11_buffer_unmap (outbuf, out_map);
|
||||
|
||||
return GST_FLOW_OK;
|
||||
|
||||
invalid_memory:
|
||||
{
|
||||
GST_ELEMENT_ERROR (self, CORE, FAILED, (NULL), ("Invalid memory"));
|
||||
return GST_FLOW_ERROR;
|
||||
}
|
||||
fallback_failed:
|
||||
{
|
||||
GST_ELEMENT_ERROR (self, CORE, FAILED, (NULL),
|
||||
("Couldn't prepare fallback memory"));
|
||||
gst_d3d11_buffer_unmap (inbuf, in_map);
|
||||
gst_d3d11_buffer_unmap (outbuf, out_map);
|
||||
|
||||
return GST_FLOW_ERROR;
|
||||
}
|
||||
conversion_failed:
|
||||
{
|
||||
GST_ELEMENT_ERROR (self, CORE, FAILED, (NULL),
|
||||
("Couldn't convert texture"));
|
||||
gst_d3d11_buffer_unmap (inbuf, in_map);
|
||||
gst_d3d11_buffer_unmap (outbuf, out_map);
|
||||
|
||||
return GST_FLOW_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
static GstCaps *gst_d3d11_color_convert_transform_caps (GstBaseTransform *
|
||||
|
|
|
@ -864,12 +864,12 @@ gst_d3d11_compsitor_prepare_fallback_buffer (GstD3D11Compositor * self,
|
|||
GstD3D11Memory *new_mem =
|
||||
(GstD3D11Memory *) gst_buffer_peek_memory (new_buf, i);
|
||||
|
||||
if (is_input && !gst_d3d11_memory_ensure_shader_resource_view (new_mem)) {
|
||||
if (is_input && !gst_d3d11_memory_get_shader_resource_view_size (new_mem)) {
|
||||
GST_ERROR_OBJECT (self, "Couldn't prepare shader resource view");
|
||||
gst_buffer_unref (new_buf);
|
||||
return FALSE;
|
||||
} else if (!is_input &&
|
||||
!gst_d3d11_memory_ensure_render_target_view (new_mem)) {
|
||||
!gst_d3d11_memory_get_render_target_view_size (new_mem)) {
|
||||
GST_ERROR_OBJECT (self, "Couldn't prepare render target view");
|
||||
gst_buffer_unref (new_buf);
|
||||
return FALSE;
|
||||
|
@ -889,7 +889,7 @@ gst_d3d11_compositor_copy_buffer (GstD3D11Compositor * self,
|
|||
gint i;
|
||||
|
||||
if (do_device_copy) {
|
||||
return gst_d3d11_buffer_copy_into (dest_buf, src_buf);
|
||||
return gst_d3d11_buffer_copy_into (dest_buf, src_buf, info);
|
||||
} else {
|
||||
GstVideoFrame src_frame, dest_frame;
|
||||
|
||||
|
@ -949,10 +949,10 @@ gst_d3d11_compositor_check_d3d11_memory (GstD3D11Compositor * self,
|
|||
}
|
||||
|
||||
if (is_input) {
|
||||
if (!gst_d3d11_memory_ensure_shader_resource_view (dmem))
|
||||
if (!gst_d3d11_memory_get_shader_resource_view_size (dmem))
|
||||
*view_available = FALSE;
|
||||
} else {
|
||||
if (!gst_d3d11_memory_ensure_render_target_view (dmem))
|
||||
if (!gst_d3d11_memory_get_render_target_view_size (dmem))
|
||||
*view_available = FALSE;
|
||||
}
|
||||
}
|
||||
|
@ -2097,6 +2097,7 @@ gst_d3d11_compositor_aggregate_frames (GstVideoAggregator * vagg,
|
|||
for (i = 0; i < gst_buffer_n_memory (target_buf); i++) {
|
||||
GstMemory *mem = gst_buffer_peek_memory (target_buf, i);
|
||||
GstD3D11Memory *dmem;
|
||||
guint rtv_size;
|
||||
|
||||
if (!gst_is_d3d11_memory (mem)) {
|
||||
GST_ERROR_OBJECT (self, "Invalid output memory");
|
||||
|
@ -2104,15 +2105,16 @@ gst_d3d11_compositor_aggregate_frames (GstVideoAggregator * vagg,
|
|||
}
|
||||
|
||||
dmem = (GstD3D11Memory *) mem;
|
||||
if (!gst_d3d11_memory_ensure_render_target_view (dmem)) {
|
||||
rtv_size = gst_d3d11_memory_get_render_target_view_size (dmem);
|
||||
if (!rtv_size) {
|
||||
GST_ERROR_OBJECT (self, "Render target view is unavailable");
|
||||
return GST_FLOW_ERROR;
|
||||
}
|
||||
|
||||
for (j = 0; j < dmem->num_render_target_views; j++) {
|
||||
for (j = 0; j < rtv_size; j++) {
|
||||
g_assert (view_idx < GST_VIDEO_MAX_PLANES);
|
||||
|
||||
rtv[view_idx] = dmem->render_target_view[j];
|
||||
rtv[view_idx] = gst_d3d11_memory_get_render_target_view (dmem, j);
|
||||
view_idx++;
|
||||
}
|
||||
|
||||
|
@ -2155,11 +2157,12 @@ gst_d3d11_compositor_aggregate_frames (GstVideoAggregator * vagg,
|
|||
for (i = 0; i < gst_buffer_n_memory (buffer); i++) {
|
||||
GstD3D11Memory *dmem =
|
||||
(GstD3D11Memory *) gst_buffer_peek_memory (buffer, i);
|
||||
guint srv_size = gst_d3d11_memory_get_shader_resource_view_size (dmem);
|
||||
|
||||
for (j = 0; j < dmem->num_shader_resource_views; j++) {
|
||||
for (j = 0; j < srv_size; j++) {
|
||||
g_assert (view_idx < GST_VIDEO_MAX_PLANES);
|
||||
|
||||
srv[view_idx] = dmem->shader_resource_view[j];
|
||||
srv[view_idx] = gst_d3d11_memory_get_shader_resource_view (dmem, j);
|
||||
view_idx++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -357,9 +357,8 @@ gst_d3d11_decoder_ensure_output_view (GstD3D11Decoder * self,
|
|||
GstD3D11Memory *mem;
|
||||
|
||||
mem = (GstD3D11Memory *) gst_buffer_peek_memory (buffer, 0);
|
||||
if (!gst_d3d11_memory_ensure_decoder_output_view (mem, priv->video_device,
|
||||
if (!gst_d3d11_memory_get_decoder_output_view (mem, priv->video_device,
|
||||
&priv->decoder_profile)) {
|
||||
|
||||
GST_ERROR_OBJECT (self, "Decoder output view is unavailable");
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -1065,12 +1064,16 @@ ID3D11VideoDecoderOutputView *
|
|||
gst_d3d11_decoder_get_output_view_from_buffer (GstD3D11Decoder * decoder,
|
||||
GstBuffer * buffer)
|
||||
{
|
||||
GstD3D11DecoderPrivate *priv;
|
||||
GstMemory *mem;
|
||||
GstD3D11Memory *dmem;
|
||||
ID3D11VideoDecoderOutputView *view;
|
||||
|
||||
g_return_val_if_fail (GST_IS_D3D11_DECODER (decoder), NULL);
|
||||
g_return_val_if_fail (GST_IS_BUFFER (buffer), NULL);
|
||||
|
||||
priv = decoder->priv;
|
||||
|
||||
mem = gst_buffer_peek_memory (buffer, 0);
|
||||
if (!gst_is_d3d11_memory (mem)) {
|
||||
GST_WARNING_OBJECT (decoder, "Not a d3d11 memory");
|
||||
|
@ -1078,13 +1081,15 @@ gst_d3d11_decoder_get_output_view_from_buffer (GstD3D11Decoder * decoder,
|
|||
}
|
||||
|
||||
dmem = (GstD3D11Memory *) mem;
|
||||
view = gst_d3d11_memory_get_decoder_output_view (dmem, priv->video_device,
|
||||
&priv->decoder_profile);
|
||||
|
||||
if (!dmem->decoder_output_view) {
|
||||
GST_WARNING_OBJECT (decoder, "memory does not have output view");
|
||||
if (!view) {
|
||||
GST_ERROR_OBJECT (decoder, "Decoder output view is unavailable");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return dmem->decoder_output_view;
|
||||
return view;
|
||||
}
|
||||
|
||||
guint8
|
||||
|
@ -1123,15 +1128,17 @@ copy_to_system (GstD3D11Decoder * self, GstVideoInfo * info, gint display_width,
|
|||
|
||||
in_mem = (GstD3D11Memory *) gst_buffer_peek_memory (decoder_buffer, 0);
|
||||
|
||||
in_texture = in_mem->texture;
|
||||
in_subresource_index = in_mem->subresource_index;
|
||||
in_texture = gst_d3d11_memory_get_texture_handle (in_mem);
|
||||
in_subresource_index = gst_d3d11_memory_get_subresource_index (in_mem);
|
||||
|
||||
gst_d3d11_device_lock (priv->device);
|
||||
|
||||
if (need_convert) {
|
||||
D3D11_BOX src_box;
|
||||
RECT rect;
|
||||
ID3D11ShaderResourceView **srv = NULL;
|
||||
ID3D11ShaderResourceView *srv[GST_VIDEO_MAX_PLANES] = { NULL, };
|
||||
guint srv_size;
|
||||
guint i;
|
||||
|
||||
GST_LOG_OBJECT (self, "convert resolution, %dx%d -> %dx%d",
|
||||
display_width, display_height,
|
||||
|
@ -1146,21 +1153,23 @@ copy_to_system (GstD3D11Decoder * self, GstVideoInfo * info, gint display_width,
|
|||
|
||||
/* array of texture can be used for shader resource view */
|
||||
if (priv->use_array_of_texture &&
|
||||
gst_d3d11_memory_ensure_shader_resource_view (in_mem)) {
|
||||
(srv_size =
|
||||
gst_d3d11_memory_get_shader_resource_view_size (in_mem)) != 0) {
|
||||
GST_TRACE_OBJECT (self, "Decoded texture supports shader resource view");
|
||||
srv = in_mem->shader_resource_view;
|
||||
for (i = 0; i < srv_size; i++)
|
||||
srv[i] = gst_d3d11_memory_get_shader_resource_view (in_mem, i);
|
||||
}
|
||||
|
||||
if (!srv) {
|
||||
if (!srv[0]) {
|
||||
/* copy decoded texture into shader resource texture */
|
||||
GST_TRACE_OBJECT (self,
|
||||
"Copy decoded texture to internal shader texture");
|
||||
ID3D11DeviceContext_CopySubresourceRegion (device_context,
|
||||
(ID3D11Resource *) priv->shader_resource_texture, 0, 0, 0, 0,
|
||||
(ID3D11Resource *) in_mem->texture, in_mem->subresource_index,
|
||||
&src_box);
|
||||
(ID3D11Resource *) in_texture, in_subresource_index, &src_box);
|
||||
|
||||
srv = priv->shader_resource_view;
|
||||
for (i = 0; i < priv->num_resource_views; i++)
|
||||
srv[i] = priv->shader_resource_view[i];
|
||||
}
|
||||
|
||||
rect.left = 0;
|
||||
|
@ -1241,19 +1250,26 @@ copy_to_d3d11 (GstD3D11Decoder * self, GstVideoInfo * info, gint display_width,
|
|||
GstD3D11DecoderPrivate *priv = self->priv;
|
||||
GstD3D11Memory *in_mem;
|
||||
GstD3D11Memory *out_mem;
|
||||
GstMapInfo out_map;
|
||||
D3D11_BOX src_box;
|
||||
ID3D11Texture2D *in_texture;
|
||||
guint in_subresource_index;
|
||||
guint in_subresource_index, out_subresource_index;
|
||||
ID3D11DeviceContext *device_context =
|
||||
gst_d3d11_device_get_device_context_handle (priv->device);
|
||||
|
||||
gst_d3d11_device_lock (priv->device);
|
||||
gboolean ret = FALSE;
|
||||
|
||||
in_mem = (GstD3D11Memory *) gst_buffer_peek_memory (decoder_buffer, 0);
|
||||
out_mem = (GstD3D11Memory *) gst_buffer_peek_memory (output, 0);
|
||||
|
||||
in_texture = in_mem->texture;
|
||||
in_subresource_index = in_mem->subresource_index;
|
||||
if (!gst_memory_map (GST_MEMORY_CAST (out_mem),
|
||||
&out_map, GST_MAP_WRITE | GST_MAP_D3D11)) {
|
||||
GST_ERROR_OBJECT (self, "Couldn't map output d3d11 memory");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gst_d3d11_device_lock (priv->device);
|
||||
in_texture = gst_d3d11_memory_get_texture_handle (in_mem);
|
||||
in_subresource_index = gst_d3d11_memory_get_subresource_index (in_mem);
|
||||
|
||||
src_box.left = 0;
|
||||
src_box.top = 0;
|
||||
|
@ -1262,21 +1278,28 @@ copy_to_d3d11 (GstD3D11Decoder * self, GstVideoInfo * info, gint display_width,
|
|||
|
||||
if (need_convert) {
|
||||
gboolean need_copy = FALSE;
|
||||
ID3D11RenderTargetView **rtv;
|
||||
ID3D11ShaderResourceView **srv = NULL;
|
||||
ID3D11RenderTargetView *rtv[GST_VIDEO_MAX_PLANES] = { NULL, };
|
||||
ID3D11ShaderResourceView *srv[GST_VIDEO_MAX_PLANES] = { NULL, };
|
||||
RECT rect;
|
||||
guint rtv_size;
|
||||
guint srv_size;
|
||||
guint i;
|
||||
|
||||
GST_LOG_OBJECT (self, "convert resolution, %dx%d -> %dx%d",
|
||||
display_width, display_height,
|
||||
priv->display_width, priv->display_height);
|
||||
|
||||
if (!gst_d3d11_memory_ensure_render_target_view (out_mem)) {
|
||||
rtv_size = gst_d3d11_memory_get_render_target_view_size (out_mem);
|
||||
|
||||
if (!rtv_size) {
|
||||
/* convert to fallback output view */
|
||||
GST_LOG_OBJECT (self, "output memory cannot support render target view");
|
||||
rtv = priv->fallback_render_target_view;
|
||||
for (i = 0; priv->num_resource_views; i++)
|
||||
rtv[i] = priv->fallback_render_target_view[i];
|
||||
need_copy = TRUE;
|
||||
} else {
|
||||
rtv = out_mem->render_target_view;
|
||||
for (i = 0; rtv_size; i++)
|
||||
rtv[i] = gst_d3d11_memory_get_render_target_view (out_mem, i);
|
||||
}
|
||||
|
||||
src_box.right = GST_ROUND_UP_2 (display_width);
|
||||
|
@ -1284,20 +1307,21 @@ copy_to_d3d11 (GstD3D11Decoder * self, GstVideoInfo * info, gint display_width,
|
|||
|
||||
/* array of texture can be used for shader resource view */
|
||||
if (priv->use_array_of_texture &&
|
||||
gst_d3d11_memory_ensure_shader_resource_view (in_mem)) {
|
||||
(srv_size =
|
||||
gst_d3d11_memory_get_shader_resource_view_size (in_mem)) != 0) {
|
||||
GST_TRACE_OBJECT (self, "Decoded texture supports shader resource view");
|
||||
srv = in_mem->shader_resource_view;
|
||||
}
|
||||
|
||||
if (!srv) {
|
||||
for (i = 0; i < srv_size; i++)
|
||||
srv[i] = gst_d3d11_memory_get_shader_resource_view (in_mem, i);
|
||||
} else {
|
||||
/* copy decoded texture into shader resource texture */
|
||||
GST_TRACE_OBJECT (self,
|
||||
"Copy decoded texture to internal shader texture");
|
||||
ID3D11DeviceContext_CopySubresourceRegion (device_context,
|
||||
(ID3D11Resource *) priv->shader_resource_texture, 0, 0, 0, 0,
|
||||
(ID3D11Resource *) in_texture, in_mem->subresource_index, &src_box);
|
||||
(ID3D11Resource *) in_texture, in_subresource_index, &src_box);
|
||||
|
||||
srv = priv->shader_resource_view;
|
||||
for (i = 0; i < priv->num_resource_views; i++)
|
||||
srv[i] = priv->shader_resource_view[i];
|
||||
}
|
||||
|
||||
rect.left = 0;
|
||||
|
@ -1310,12 +1334,13 @@ copy_to_d3d11 (GstD3D11Decoder * self, GstVideoInfo * info, gint display_width,
|
|||
if (!gst_d3d11_color_converter_convert_unlocked (priv->converter,
|
||||
srv, rtv, NULL, NULL)) {
|
||||
GST_ERROR_OBJECT (self, "Failed to convert");
|
||||
goto error;
|
||||
ret = FALSE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!need_copy) {
|
||||
gst_d3d11_device_unlock (priv->device);
|
||||
return TRUE;
|
||||
ret = TRUE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
in_texture = priv->fallback_shader_output_texture;
|
||||
|
@ -1325,19 +1350,19 @@ copy_to_d3d11 (GstD3D11Decoder * self, GstVideoInfo * info, gint display_width,
|
|||
src_box.right = GST_ROUND_UP_2 (priv->display_width);
|
||||
src_box.bottom = GST_ROUND_UP_2 (priv->display_height);
|
||||
|
||||
out_subresource_index = gst_d3d11_memory_get_subresource_index (out_mem);
|
||||
ID3D11DeviceContext_CopySubresourceRegion (device_context,
|
||||
(ID3D11Resource *) out_mem->texture,
|
||||
out_mem->subresource_index, 0, 0, 0,
|
||||
(ID3D11Resource *) out_map.data, out_subresource_index, 0, 0, 0,
|
||||
(ID3D11Resource *) in_texture, in_subresource_index, &src_box);
|
||||
|
||||
GST_MINI_OBJECT_FLAG_SET (out_mem, GST_D3D11_MEMORY_TRANSFER_NEED_DOWNLOAD);
|
||||
ret = TRUE;
|
||||
|
||||
out:
|
||||
gst_d3d11_device_unlock (priv->device);
|
||||
|
||||
return TRUE;
|
||||
gst_memory_unmap (GST_MEMORY_CAST (out_mem), &out_map);
|
||||
|
||||
error:
|
||||
gst_d3d11_device_unlock (priv->device);
|
||||
return FALSE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
|
|
|
@ -348,15 +348,11 @@ gst_d3d11_download_can_use_staging_buffer (GstD3D11Download * self,
|
|||
GstBuffer * inbuf)
|
||||
{
|
||||
GstD3D11BaseFilter *filter = GST_D3D11_BASE_FILTER (self);
|
||||
gint i;
|
||||
ID3D11Device *device_handle =
|
||||
gst_d3d11_device_get_device_handle (filter->device);
|
||||
|
||||
/* staging buffer doesn't need to be used for non-d3d11 memory */
|
||||
for (i = 0; i < gst_buffer_n_memory (inbuf); i++) {
|
||||
GstMemory *mem = gst_buffer_peek_memory (inbuf, i);
|
||||
|
||||
if (!gst_is_d3d11_memory (mem))
|
||||
return FALSE;
|
||||
}
|
||||
if (!gst_d3d11_buffer_can_access_device (inbuf, device_handle))
|
||||
return FALSE;
|
||||
|
||||
if (self->staging_buffer)
|
||||
return TRUE;
|
||||
|
@ -390,7 +386,8 @@ gst_d3d11_download_transform (GstBaseTransform * trans, GstBuffer * inbuf,
|
|||
GST_TRACE_OBJECT (self, "Copy input buffer to staging buffer");
|
||||
|
||||
/* Copy d3d11 texture to staging texture */
|
||||
if (!gst_d3d11_buffer_copy_into (self->staging_buffer, inbuf)) {
|
||||
if (!gst_d3d11_buffer_copy_into (self->staging_buffer,
|
||||
inbuf, &filter->in_info)) {
|
||||
GST_ERROR_OBJECT (self,
|
||||
"Failed to copy input buffer into staging texture");
|
||||
return GST_FLOW_ERROR;
|
||||
|
|
|
@ -766,7 +766,6 @@ gst_d3d11_h264_dec_new_picture (GstH264Decoder * decoder,
|
|||
{
|
||||
GstD3D11H264Dec *self = GST_D3D11_H264_DEC (decoder);
|
||||
GstBuffer *view_buffer;
|
||||
GstD3D11Memory *mem;
|
||||
|
||||
view_buffer = gst_d3d11_decoder_get_output_view_buffer (self->d3d11_decoder);
|
||||
if (!view_buffer) {
|
||||
|
@ -774,10 +773,7 @@ gst_d3d11_h264_dec_new_picture (GstH264Decoder * decoder,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
mem = (GstD3D11Memory *) gst_buffer_peek_memory (view_buffer, 0);
|
||||
|
||||
GST_LOG_OBJECT (self, "New output view buffer %" GST_PTR_FORMAT " (index %d)",
|
||||
view_buffer, mem->subresource_index);
|
||||
GST_LOG_OBJECT (self, "New output view buffer %" GST_PTR_FORMAT, view_buffer);
|
||||
|
||||
gst_h264_picture_set_user_data (picture,
|
||||
view_buffer, (GDestroyNotify) gst_buffer_unref);
|
||||
|
@ -793,7 +789,6 @@ gst_d3d11_h264_dec_new_field_picture (GstH264Decoder * decoder,
|
|||
{
|
||||
GstD3D11H264Dec *self = GST_D3D11_H264_DEC (decoder);
|
||||
GstBuffer *view_buffer;
|
||||
GstD3D11Memory *mem;
|
||||
|
||||
view_buffer = gst_h264_picture_get_user_data ((GstH264Picture *) first_field);
|
||||
|
||||
|
@ -802,10 +797,8 @@ gst_d3d11_h264_dec_new_field_picture (GstH264Decoder * decoder,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
mem = (GstD3D11Memory *) gst_buffer_peek_memory (view_buffer, 0);
|
||||
|
||||
GST_LOG_OBJECT (self, "New field picture with buffer %" GST_PTR_FORMAT
|
||||
" (index %d)", view_buffer, mem->subresource_index);
|
||||
GST_LOG_OBJECT (self, "New field picture with buffer %" GST_PTR_FORMAT,
|
||||
view_buffer);
|
||||
|
||||
gst_h264_picture_set_user_data (second_field,
|
||||
gst_buffer_ref (view_buffer), (GDestroyNotify) gst_buffer_unref);
|
||||
|
|
|
@ -750,7 +750,6 @@ gst_d3d11_h265_dec_new_picture (GstH265Decoder * decoder,
|
|||
{
|
||||
GstD3D11H265Dec *self = GST_D3D11_H265_DEC (decoder);
|
||||
GstBuffer *view_buffer;
|
||||
GstD3D11Memory *mem;
|
||||
|
||||
view_buffer = gst_d3d11_decoder_get_output_view_buffer (self->d3d11_decoder);
|
||||
if (!view_buffer) {
|
||||
|
@ -758,10 +757,7 @@ gst_d3d11_h265_dec_new_picture (GstH265Decoder * decoder,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
mem = (GstD3D11Memory *) gst_buffer_peek_memory (view_buffer, 0);
|
||||
|
||||
GST_LOG_OBJECT (self, "New output view buffer %" GST_PTR_FORMAT " (index %d)",
|
||||
view_buffer, mem->subresource_index);
|
||||
GST_LOG_OBJECT (self, "New output view buffer %" GST_PTR_FORMAT, view_buffer);
|
||||
|
||||
gst_h265_picture_set_user_data (picture,
|
||||
view_buffer, (GDestroyNotify) gst_buffer_unref);
|
||||
|
|
|
@ -34,7 +34,7 @@ GST_DEBUG_CATEGORY_STATIC (gst_d3d11_allocator_debug);
|
|||
#define GST_D3D11_ALLOCATOR_UNLOCK(a) g_mutex_unlock(GST_D3D11_ALLOCATOR_GET_LOCK(a))
|
||||
|
||||
#define GST_D3D11_MEMORY_CAST(m) ((GstD3D11Memory *) m)
|
||||
#define GST_D3D11_MEMORY_GET_LOCK(m) (&(GST_D3D11_MEMORY_CAST(m)->lock))
|
||||
#define GST_D3D11_MEMORY_GET_LOCK(m) (&(GST_D3D11_MEMORY_CAST(m)->priv->lock))
|
||||
#define GST_D3D11_MEMORY_LOCK(m) g_mutex_lock(GST_D3D11_MEMORY_GET_LOCK(m))
|
||||
#define GST_D3D11_MEMORY_UNLOCK(m) g_mutex_unlock(GST_D3D11_MEMORY_GET_LOCK(m))
|
||||
|
||||
|
@ -191,6 +191,41 @@ G_DEFINE_BOXED_TYPE_WITH_CODE (GstD3D11AllocationParams,
|
|||
(GBoxedFreeFunc) gst_d3d11_allocation_params_free,
|
||||
_init_alloc_params (g_define_type_id));
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GST_D3D11_MEMORY_TYPE_TEXTURE = 0,
|
||||
GST_D3D11_MEMORY_TYPE_ARRAY = 1,
|
||||
GST_D3D11_MEMORY_TYPE_STAGING = 2,
|
||||
} GstD3D11MemoryType;
|
||||
|
||||
struct _GstD3D11MemoryPrivate
|
||||
{
|
||||
GstD3D11MemoryType type;
|
||||
|
||||
ID3D11Texture2D *texture;
|
||||
D3D11_TEXTURE2D_DESC desc;
|
||||
|
||||
/* valid only for array typed memory */
|
||||
guint subresource_index;
|
||||
|
||||
ID3D11Texture2D *staging;
|
||||
|
||||
ID3D11ShaderResourceView *shader_resource_view[GST_VIDEO_MAX_PLANES];
|
||||
guint num_shader_resource_views;
|
||||
|
||||
ID3D11RenderTargetView *render_target_view[GST_VIDEO_MAX_PLANES];
|
||||
guint num_render_target_views;
|
||||
|
||||
ID3D11VideoDecoderOutputView *decoder_output_view;
|
||||
ID3D11VideoProcessorInputView *processor_input_view;
|
||||
ID3D11VideoProcessorOutputView *processor_output_view;
|
||||
|
||||
D3D11_MAPPED_SUBRESOURCE map;
|
||||
|
||||
GMutex lock;
|
||||
gint cpu_map_count;
|
||||
};
|
||||
|
||||
struct _GstD3D11AllocatorPrivate
|
||||
{
|
||||
/* parent texture when array typed memory is used */
|
||||
|
@ -254,21 +289,22 @@ create_staging_texture (GstD3D11Device * device,
|
|||
static gboolean
|
||||
map_cpu_access_data (GstD3D11Memory * dmem, D3D11_MAP map_type)
|
||||
{
|
||||
GstD3D11MemoryPrivate *priv = dmem->priv;
|
||||
HRESULT hr;
|
||||
gboolean ret = TRUE;
|
||||
ID3D11Resource *texture = (ID3D11Resource *) dmem->texture;
|
||||
ID3D11Resource *staging = (ID3D11Resource *) dmem->staging;
|
||||
ID3D11Resource *texture = (ID3D11Resource *) priv->texture;
|
||||
ID3D11Resource *staging = (ID3D11Resource *) priv->staging;
|
||||
ID3D11DeviceContext *device_context =
|
||||
gst_d3d11_device_get_device_context_handle (dmem->device);
|
||||
|
||||
gst_d3d11_device_lock (dmem->device);
|
||||
if (GST_MEMORY_FLAG_IS_SET (dmem, GST_D3D11_MEMORY_TRANSFER_NEED_DOWNLOAD)) {
|
||||
ID3D11DeviceContext_CopySubresourceRegion (device_context,
|
||||
staging, 0, 0, 0, 0, texture, dmem->subresource_index, NULL);
|
||||
staging, 0, 0, 0, 0, texture, priv->subresource_index, NULL);
|
||||
}
|
||||
|
||||
hr = ID3D11DeviceContext_Map (device_context,
|
||||
staging, 0, map_type, 0, &dmem->map);
|
||||
staging, 0, map_type, 0, &priv->map);
|
||||
|
||||
if (!gst_d3d11_result (hr, dmem->device)) {
|
||||
GST_ERROR_OBJECT (GST_MEMORY_CAST (dmem)->allocator,
|
||||
|
@ -285,9 +321,10 @@ static gpointer
|
|||
gst_d3d11_memory_map_staging (GstMemory * mem, GstMapFlags flags)
|
||||
{
|
||||
GstD3D11Memory *dmem = (GstD3D11Memory *) mem;
|
||||
GstD3D11MemoryPrivate *priv = dmem->priv;
|
||||
|
||||
GST_D3D11_MEMORY_LOCK (dmem);
|
||||
if (dmem->cpu_map_count == 0) {
|
||||
if (priv->cpu_map_count == 0) {
|
||||
ID3D11DeviceContext *device_context =
|
||||
gst_d3d11_device_get_device_context_handle (dmem->device);
|
||||
D3D11_MAP map_type;
|
||||
|
@ -298,7 +335,7 @@ gst_d3d11_memory_map_staging (GstMemory * mem, GstMapFlags flags)
|
|||
|
||||
gst_d3d11_device_lock (dmem->device);
|
||||
hr = ID3D11DeviceContext_Map (device_context,
|
||||
(ID3D11Resource *) dmem->texture, 0, map_type, 0, &dmem->map);
|
||||
(ID3D11Resource *) priv->texture, 0, map_type, 0, &priv->map);
|
||||
if (!gst_d3d11_result (hr, dmem->device)) {
|
||||
GST_ERROR_OBJECT (GST_MEMORY_CAST (dmem)->allocator,
|
||||
"Failed to map staging texture (0x%x)", (guint) hr);
|
||||
|
@ -312,35 +349,36 @@ gst_d3d11_memory_map_staging (GstMemory * mem, GstMapFlags flags)
|
|||
}
|
||||
}
|
||||
|
||||
dmem->cpu_map_count++;
|
||||
priv->cpu_map_count++;
|
||||
GST_D3D11_MEMORY_UNLOCK (dmem);
|
||||
|
||||
return dmem->map.pData;
|
||||
return dmem->priv->map.pData;
|
||||
}
|
||||
|
||||
static gpointer
|
||||
gst_d3d11_memory_map (GstMemory * mem, gsize maxsize, GstMapFlags flags)
|
||||
{
|
||||
GstD3D11Memory *dmem = (GstD3D11Memory *) mem;
|
||||
GstD3D11MemoryPrivate *priv = dmem->priv;
|
||||
|
||||
if (dmem->type == GST_D3D11_MEMORY_TYPE_STAGING) {
|
||||
if (priv->type == GST_D3D11_MEMORY_TYPE_STAGING) {
|
||||
if ((flags & GST_MAP_D3D11) == GST_MAP_D3D11)
|
||||
return dmem->texture;
|
||||
return priv->texture;
|
||||
|
||||
return gst_d3d11_memory_map_staging (mem, flags);
|
||||
}
|
||||
|
||||
GST_D3D11_MEMORY_LOCK (dmem);
|
||||
if ((flags & GST_MAP_D3D11) == GST_MAP_D3D11) {
|
||||
if (dmem->staging &&
|
||||
if (priv->staging &&
|
||||
GST_MEMORY_FLAG_IS_SET (dmem, GST_D3D11_MEMORY_TRANSFER_NEED_UPLOAD)) {
|
||||
ID3D11DeviceContext *device_context =
|
||||
gst_d3d11_device_get_device_context_handle (dmem->device);
|
||||
|
||||
gst_d3d11_device_lock (dmem->device);
|
||||
ID3D11DeviceContext_CopySubresourceRegion (device_context,
|
||||
(ID3D11Resource *) dmem->texture, dmem->subresource_index, 0, 0, 0,
|
||||
(ID3D11Resource *) dmem->staging, 0, NULL);
|
||||
(ID3D11Resource *) priv->texture, priv->subresource_index, 0, 0, 0,
|
||||
(ID3D11Resource *) priv->staging, 0, NULL);
|
||||
gst_d3d11_device_unlock (dmem->device);
|
||||
}
|
||||
|
||||
|
@ -349,21 +387,21 @@ gst_d3d11_memory_map (GstMemory * mem, gsize maxsize, GstMapFlags flags)
|
|||
if ((flags & GST_MAP_WRITE) == GST_MAP_WRITE)
|
||||
GST_MINI_OBJECT_FLAG_SET (dmem, GST_D3D11_MEMORY_TRANSFER_NEED_DOWNLOAD);
|
||||
|
||||
g_assert (dmem->texture != NULL);
|
||||
g_assert (priv->texture != NULL);
|
||||
GST_D3D11_MEMORY_UNLOCK (dmem);
|
||||
|
||||
return dmem->texture;
|
||||
return priv->texture;
|
||||
}
|
||||
|
||||
if (dmem->cpu_map_count == 0) {
|
||||
if (priv->cpu_map_count == 0) {
|
||||
D3D11_MAP map_type;
|
||||
|
||||
/* Allocate staging texture for CPU access */
|
||||
if (!dmem->staging) {
|
||||
dmem->staging = create_staging_texture (dmem->device, &dmem->desc);
|
||||
if (!dmem->staging) {
|
||||
if (!priv->staging) {
|
||||
priv->staging = create_staging_texture (dmem->device, &priv->desc);
|
||||
if (!priv->staging) {
|
||||
GST_ERROR_OBJECT (mem->allocator, "Couldn't create staging texture");
|
||||
g_mutex_unlock (&dmem->lock);
|
||||
GST_D3D11_MEMORY_UNLOCK (dmem);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -387,21 +425,22 @@ gst_d3d11_memory_map (GstMemory * mem, gsize maxsize, GstMapFlags flags)
|
|||
|
||||
GST_MEMORY_FLAG_UNSET (mem, GST_D3D11_MEMORY_TRANSFER_NEED_DOWNLOAD);
|
||||
|
||||
dmem->cpu_map_count++;
|
||||
priv->cpu_map_count++;
|
||||
GST_D3D11_MEMORY_UNLOCK (dmem);
|
||||
|
||||
return dmem->map.pData;
|
||||
return dmem->priv->map.pData;
|
||||
}
|
||||
|
||||
static void
|
||||
unmap_cpu_access_data (GstD3D11Memory * dmem)
|
||||
{
|
||||
ID3D11Resource *staging = (ID3D11Resource *) dmem->staging;
|
||||
GstD3D11MemoryPrivate *priv = dmem->priv;
|
||||
ID3D11Resource *staging = (ID3D11Resource *) priv->staging;
|
||||
ID3D11DeviceContext *device_context =
|
||||
gst_d3d11_device_get_device_context_handle (dmem->device);
|
||||
|
||||
if (dmem->type == GST_D3D11_MEMORY_TYPE_STAGING)
|
||||
staging = (ID3D11Resource *) dmem->texture;
|
||||
if (priv->type == GST_D3D11_MEMORY_TYPE_STAGING)
|
||||
staging = (ID3D11Resource *) priv->texture;
|
||||
|
||||
gst_d3d11_device_lock (dmem->device);
|
||||
ID3D11DeviceContext_Unmap (device_context, staging, 0);
|
||||
|
@ -412,10 +451,11 @@ static void
|
|||
gst_d3d11_memory_unmap_full (GstMemory * mem, GstMapInfo * info)
|
||||
{
|
||||
GstD3D11Memory *dmem = (GstD3D11Memory *) mem;
|
||||
GstD3D11MemoryPrivate *priv = dmem->priv;
|
||||
|
||||
GST_D3D11_MEMORY_LOCK (dmem);
|
||||
if ((info->flags & GST_MAP_D3D11) == GST_MAP_D3D11) {
|
||||
if (dmem->type != GST_D3D11_MEMORY_TYPE_STAGING &&
|
||||
if (priv->type != GST_D3D11_MEMORY_TYPE_STAGING &&
|
||||
(info->flags & GST_MAP_WRITE) == GST_MAP_WRITE)
|
||||
GST_MINI_OBJECT_FLAG_SET (mem, GST_D3D11_MEMORY_TRANSFER_NEED_DOWNLOAD);
|
||||
|
||||
|
@ -423,12 +463,12 @@ gst_d3d11_memory_unmap_full (GstMemory * mem, GstMapInfo * info)
|
|||
return;
|
||||
}
|
||||
|
||||
if (dmem->type != GST_D3D11_MEMORY_TYPE_STAGING &&
|
||||
if (priv->type != GST_D3D11_MEMORY_TYPE_STAGING &&
|
||||
(info->flags & GST_MAP_WRITE))
|
||||
GST_MINI_OBJECT_FLAG_SET (mem, GST_D3D11_MEMORY_TRANSFER_NEED_UPLOAD);
|
||||
|
||||
dmem->cpu_map_count--;
|
||||
if (dmem->cpu_map_count > 0) {
|
||||
priv->cpu_map_count--;
|
||||
if (priv->cpu_map_count > 0) {
|
||||
GST_D3D11_MEMORY_UNLOCK (dmem);
|
||||
return;
|
||||
}
|
||||
|
@ -458,43 +498,43 @@ gst_d3d11_allocator_free (GstAllocator * allocator, GstMemory * mem)
|
|||
GstD3D11Allocator *self = GST_D3D11_ALLOCATOR (allocator);
|
||||
GstD3D11AllocatorPrivate *priv = self->priv;
|
||||
GstD3D11Memory *dmem = (GstD3D11Memory *) mem;
|
||||
GstD3D11MemoryPrivate *dmem_priv = dmem->priv;
|
||||
gint i;
|
||||
|
||||
if (priv->array_in_use) {
|
||||
GST_D3D11_ALLOCATOR_LOCK (self);
|
||||
g_array_index (priv->array_in_use, guint8, dmem->subresource_index) = 0;
|
||||
g_array_index (priv->array_in_use,
|
||||
guint8, dmem_priv->subresource_index) = 0;
|
||||
g_cond_broadcast (&priv->cond);
|
||||
GST_D3D11_ALLOCATOR_UNLOCK (self);
|
||||
}
|
||||
|
||||
for (i = 0; i < GST_VIDEO_MAX_PLANES; i++) {
|
||||
if (dmem->render_target_view[i])
|
||||
ID3D11RenderTargetView_Release (dmem->render_target_view[i]);
|
||||
dmem->render_target_view[i] = NULL;
|
||||
if (dmem_priv->render_target_view[i])
|
||||
ID3D11RenderTargetView_Release (dmem_priv->render_target_view[i]);
|
||||
|
||||
if (dmem->shader_resource_view[i])
|
||||
ID3D11ShaderResourceView_Release (dmem->shader_resource_view[i]);
|
||||
dmem->shader_resource_view[i] = NULL;
|
||||
if (dmem_priv->shader_resource_view[i])
|
||||
ID3D11ShaderResourceView_Release (dmem_priv->shader_resource_view[i]);
|
||||
}
|
||||
|
||||
if (dmem->decoder_output_view)
|
||||
ID3D11VideoDecoderOutputView_Release (dmem->decoder_output_view);
|
||||
if (dmem_priv->decoder_output_view)
|
||||
ID3D11VideoDecoderOutputView_Release (dmem_priv->decoder_output_view);
|
||||
|
||||
if (dmem->processor_input_view)
|
||||
ID3D11VideoProcessorInputView_Release (dmem->processor_input_view);
|
||||
if (dmem_priv->processor_input_view)
|
||||
ID3D11VideoProcessorInputView_Release (dmem_priv->processor_input_view);
|
||||
|
||||
if (dmem->processor_output_view)
|
||||
ID3D11VideoProcessorOutputView_Release (dmem->processor_output_view);
|
||||
if (dmem_priv->processor_output_view)
|
||||
ID3D11VideoProcessorOutputView_Release (dmem_priv->processor_output_view);
|
||||
|
||||
if (dmem->texture)
|
||||
ID3D11Texture2D_Release (dmem->texture);
|
||||
if (dmem_priv->texture)
|
||||
ID3D11Texture2D_Release (dmem_priv->texture);
|
||||
|
||||
if (dmem->staging)
|
||||
ID3D11Texture2D_Release (dmem->staging);
|
||||
if (dmem_priv->staging)
|
||||
ID3D11Texture2D_Release (dmem_priv->staging);
|
||||
|
||||
gst_clear_object (&dmem->device);
|
||||
g_mutex_clear (&dmem->lock);
|
||||
|
||||
g_mutex_clear (&dmem_priv->lock);
|
||||
g_free (dmem->priv);
|
||||
g_free (dmem);
|
||||
}
|
||||
|
||||
|
@ -615,6 +655,7 @@ calculate_mem_size (GstD3D11Device * device, ID3D11Texture2D * texture,
|
|||
static gboolean
|
||||
create_shader_resource_views (GstD3D11Memory * mem)
|
||||
{
|
||||
GstD3D11MemoryPrivate *priv = mem->priv;
|
||||
gint i;
|
||||
HRESULT hr;
|
||||
guint num_views = 0;
|
||||
|
@ -624,7 +665,7 @@ create_shader_resource_views (GstD3D11Memory * mem)
|
|||
|
||||
device_handle = gst_d3d11_device_get_device_handle (mem->device);
|
||||
|
||||
switch (mem->desc.Format) {
|
||||
switch (priv->desc.Format) {
|
||||
case DXGI_FORMAT_B8G8R8A8_UNORM:
|
||||
case DXGI_FORMAT_R8G8B8A8_UNORM:
|
||||
case DXGI_FORMAT_R10G10B10A2_UNORM:
|
||||
|
@ -636,7 +677,7 @@ create_shader_resource_views (GstD3D11Memory * mem)
|
|||
case DXGI_FORMAT_R8G8_B8G8_UNORM:
|
||||
case DXGI_FORMAT_R16G16B16A16_UNORM:
|
||||
num_views = 1;
|
||||
formats[0] = mem->desc.Format;
|
||||
formats[0] = priv->desc.Format;
|
||||
break;
|
||||
case DXGI_FORMAT_AYUV:
|
||||
case DXGI_FORMAT_YUY2:
|
||||
|
@ -667,7 +708,7 @@ create_shader_resource_views (GstD3D11Memory * mem)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
if ((mem->desc.BindFlags & D3D11_BIND_SHADER_RESOURCE) ==
|
||||
if ((priv->desc.BindFlags & D3D11_BIND_SHADER_RESOURCE) ==
|
||||
D3D11_BIND_SHADER_RESOURCE) {
|
||||
resource_desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
|
||||
resource_desc.Texture2D.MipLevels = 1;
|
||||
|
@ -675,8 +716,8 @@ create_shader_resource_views (GstD3D11Memory * mem)
|
|||
for (i = 0; i < num_views; i++) {
|
||||
resource_desc.Format = formats[i];
|
||||
hr = ID3D11Device_CreateShaderResourceView (device_handle,
|
||||
(ID3D11Resource *) mem->texture, &resource_desc,
|
||||
&mem->shader_resource_view[i]);
|
||||
(ID3D11Resource *) priv->texture, &resource_desc,
|
||||
&priv->shader_resource_view[i]);
|
||||
|
||||
if (!gst_d3d11_result (hr, mem->device)) {
|
||||
GST_ERROR_OBJECT (GST_MEMORY_CAST (mem)->allocator,
|
||||
|
@ -685,7 +726,7 @@ create_shader_resource_views (GstD3D11Memory * mem)
|
|||
}
|
||||
}
|
||||
|
||||
mem->num_shader_resource_views = num_views;
|
||||
priv->num_shader_resource_views = num_views;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -694,12 +735,12 @@ create_shader_resource_views (GstD3D11Memory * mem)
|
|||
|
||||
error:
|
||||
for (i = 0; i < num_views; i++) {
|
||||
if (mem->shader_resource_view[i])
|
||||
ID3D11ShaderResourceView_Release (mem->shader_resource_view[i]);
|
||||
mem->shader_resource_view[i] = NULL;
|
||||
if (priv->shader_resource_view[i])
|
||||
ID3D11ShaderResourceView_Release (priv->shader_resource_view[i]);
|
||||
priv->shader_resource_view[i] = NULL;
|
||||
}
|
||||
|
||||
mem->num_shader_resource_views = 0;
|
||||
priv->num_shader_resource_views = 0;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -707,6 +748,7 @@ error:
|
|||
static gboolean
|
||||
create_render_target_views (GstD3D11Memory * mem)
|
||||
{
|
||||
GstD3D11MemoryPrivate *priv = mem->priv;
|
||||
gint i;
|
||||
HRESULT hr;
|
||||
guint num_views = 0;
|
||||
|
@ -716,7 +758,7 @@ create_render_target_views (GstD3D11Memory * mem)
|
|||
|
||||
device_handle = gst_d3d11_device_get_device_handle (mem->device);
|
||||
|
||||
switch (mem->desc.Format) {
|
||||
switch (priv->desc.Format) {
|
||||
case DXGI_FORMAT_B8G8R8A8_UNORM:
|
||||
case DXGI_FORMAT_R8G8B8A8_UNORM:
|
||||
case DXGI_FORMAT_R10G10B10A2_UNORM:
|
||||
|
@ -725,7 +767,7 @@ create_render_target_views (GstD3D11Memory * mem)
|
|||
case DXGI_FORMAT_R16_UNORM:
|
||||
case DXGI_FORMAT_R16G16_UNORM:
|
||||
num_views = 1;
|
||||
formats[0] = mem->desc.Format;
|
||||
formats[0] = priv->desc.Format;
|
||||
break;
|
||||
case DXGI_FORMAT_AYUV:
|
||||
num_views = 1;
|
||||
|
@ -747,7 +789,7 @@ create_render_target_views (GstD3D11Memory * mem)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
if ((mem->desc.BindFlags & D3D11_BIND_RENDER_TARGET) ==
|
||||
if ((priv->desc.BindFlags & D3D11_BIND_RENDER_TARGET) ==
|
||||
D3D11_BIND_RENDER_TARGET) {
|
||||
render_desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
|
||||
render_desc.Texture2D.MipSlice = 0;
|
||||
|
@ -756,8 +798,8 @@ create_render_target_views (GstD3D11Memory * mem)
|
|||
render_desc.Format = formats[i];
|
||||
|
||||
hr = ID3D11Device_CreateRenderTargetView (device_handle,
|
||||
(ID3D11Resource *) mem->texture, &render_desc,
|
||||
&mem->render_target_view[i]);
|
||||
(ID3D11Resource *) priv->texture, &render_desc,
|
||||
&priv->render_target_view[i]);
|
||||
if (!gst_d3d11_result (hr, mem->device)) {
|
||||
GST_ERROR_OBJECT (GST_MEMORY_CAST (mem)->allocator,
|
||||
"Failed to create %dth render target view (0x%x)", i, (guint) hr);
|
||||
|
@ -765,7 +807,7 @@ create_render_target_views (GstD3D11Memory * mem)
|
|||
}
|
||||
}
|
||||
|
||||
mem->num_render_target_views = num_views;
|
||||
priv->num_render_target_views = num_views;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -774,12 +816,12 @@ create_render_target_views (GstD3D11Memory * mem)
|
|||
|
||||
error:
|
||||
for (i = 0; i < num_views; i++) {
|
||||
if (mem->render_target_view[i])
|
||||
ID3D11RenderTargetView_Release (mem->render_target_view[i]);
|
||||
mem->render_target_view[i] = NULL;
|
||||
if (priv->render_target_view[i])
|
||||
ID3D11RenderTargetView_Release (priv->render_target_view[i]);
|
||||
priv->render_target_view[i] = NULL;
|
||||
}
|
||||
|
||||
mem->num_render_target_views = 0;
|
||||
priv->num_render_target_views = 0;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -915,16 +957,17 @@ gst_d3d11_allocator_alloc (GstD3D11Allocator * allocator,
|
|||
}
|
||||
|
||||
mem = g_new0 (GstD3D11Memory, 1);
|
||||
mem->priv = g_new0 (GstD3D11MemoryPrivate, 1);
|
||||
|
||||
gst_memory_init (GST_MEMORY_CAST (mem),
|
||||
0, GST_ALLOCATOR_CAST (allocator), NULL, size, 0, 0, size);
|
||||
|
||||
g_mutex_init (&mem->lock);
|
||||
mem->desc = *desc;
|
||||
mem->texture = texture;
|
||||
g_mutex_init (&mem->priv->lock);
|
||||
mem->priv->texture = texture;
|
||||
mem->priv->desc = *desc;
|
||||
mem->priv->type = type;
|
||||
mem->priv->subresource_index = index_to_use;
|
||||
mem->device = gst_object_ref (device);
|
||||
mem->type = type;
|
||||
mem->subresource_index = index_to_use;
|
||||
|
||||
return GST_MEMORY_CAST (mem);
|
||||
|
||||
|
@ -964,15 +1007,16 @@ gst_d3d11_allocator_alloc_staging (GstD3D11Allocator * allocator,
|
|||
}
|
||||
|
||||
mem = g_new0 (GstD3D11Memory, 1);
|
||||
mem->priv = g_new0 (GstD3D11MemoryPrivate, 1);
|
||||
|
||||
gst_memory_init (GST_MEMORY_CAST (mem),
|
||||
0, GST_ALLOCATOR_CAST (allocator), NULL, mem_size, 0, 0, mem_size);
|
||||
|
||||
g_mutex_init (&mem->lock);
|
||||
mem->desc = *desc;
|
||||
mem->texture = texture;
|
||||
g_mutex_init (&mem->priv->lock);
|
||||
mem->priv->texture = texture;
|
||||
mem->priv->desc = *desc;
|
||||
mem->priv->type = GST_D3D11_MEMORY_TYPE_STAGING;
|
||||
mem->device = gst_object_ref (device);
|
||||
mem->type = GST_D3D11_MEMORY_TYPE_STAGING;
|
||||
|
||||
/* every plan will have identical size */
|
||||
if (stride)
|
||||
|
@ -1010,21 +1054,48 @@ gst_is_d3d11_memory (GstMemory * mem)
|
|||
GST_IS_D3D11_ALLOCATOR (mem->allocator);
|
||||
}
|
||||
|
||||
ID3D11Texture2D *
|
||||
gst_d3d11_memory_get_texture_handle (GstD3D11Memory * mem)
|
||||
{
|
||||
g_return_val_if_fail (gst_is_d3d11_memory (GST_MEMORY_CAST (mem)), NULL);
|
||||
|
||||
return mem->priv->texture;
|
||||
}
|
||||
|
||||
guint
|
||||
gst_d3d11_memory_get_subresource_index (GstD3D11Memory * mem)
|
||||
{
|
||||
g_return_val_if_fail (gst_is_d3d11_memory (GST_MEMORY_CAST (mem)), 0);
|
||||
|
||||
return mem->priv->subresource_index;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_d3d11_memory_get_texture_desc (GstD3D11Memory * mem,
|
||||
D3D11_TEXTURE2D_DESC * desc)
|
||||
{
|
||||
g_return_val_if_fail (gst_is_d3d11_memory (GST_MEMORY_CAST (mem)), FALSE);
|
||||
g_return_val_if_fail (desc != NULL, FALSE);
|
||||
|
||||
*desc = mem->priv->desc;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_d3d11_memory_ensure_shader_resource_view (GstD3D11Memory * mem)
|
||||
{
|
||||
GstD3D11MemoryPrivate *priv = mem->priv;
|
||||
gboolean ret = FALSE;
|
||||
|
||||
g_return_val_if_fail (gst_is_d3d11_memory (GST_MEMORY_CAST (mem)), FALSE);
|
||||
|
||||
if (!(mem->desc.BindFlags & D3D11_BIND_SHADER_RESOURCE)) {
|
||||
if (!(priv->desc.BindFlags & D3D11_BIND_SHADER_RESOURCE)) {
|
||||
GST_LOG_OBJECT (GST_MEMORY_CAST (mem)->allocator,
|
||||
"Need BindFlags, current flag 0x%x", mem->desc.BindFlags);
|
||||
"Need BindFlags, current flag 0x%x", priv->desc.BindFlags);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GST_D3D11_MEMORY_LOCK (mem);
|
||||
if (mem->num_shader_resource_views) {
|
||||
if (priv->num_shader_resource_views) {
|
||||
ret = TRUE;
|
||||
goto done;
|
||||
}
|
||||
|
@ -1037,21 +1108,51 @@ done:
|
|||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
guint
|
||||
gst_d3d11_memory_get_shader_resource_view_size (GstD3D11Memory * mem)
|
||||
{
|
||||
g_return_val_if_fail (gst_is_d3d11_memory (GST_MEMORY_CAST (mem)), 0);
|
||||
|
||||
if (!gst_d3d11_memory_ensure_shader_resource_view (mem))
|
||||
return 0;
|
||||
|
||||
return mem->priv->num_shader_resource_views;
|
||||
}
|
||||
|
||||
ID3D11ShaderResourceView *
|
||||
gst_d3d11_memory_get_shader_resource_view (GstD3D11Memory * mem, guint index)
|
||||
{
|
||||
GstD3D11MemoryPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (gst_is_d3d11_memory (GST_MEMORY_CAST (mem)), NULL);
|
||||
|
||||
if (!gst_d3d11_memory_ensure_shader_resource_view (mem))
|
||||
return NULL;
|
||||
|
||||
priv = mem->priv;
|
||||
|
||||
if (index >= priv->num_shader_resource_views) {
|
||||
GST_ERROR ("Invalid SRV index %d", index);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return priv->shader_resource_view[index];
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_d3d11_memory_ensure_render_target_view (GstD3D11Memory * mem)
|
||||
{
|
||||
GstD3D11MemoryPrivate *priv = mem->priv;
|
||||
gboolean ret = FALSE;
|
||||
|
||||
g_return_val_if_fail (gst_is_d3d11_memory (GST_MEMORY_CAST (mem)), FALSE);
|
||||
|
||||
if (!(mem->desc.BindFlags & D3D11_BIND_RENDER_TARGET)) {
|
||||
if (!(priv->desc.BindFlags & D3D11_BIND_RENDER_TARGET)) {
|
||||
GST_WARNING_OBJECT (GST_MEMORY_CAST (mem)->allocator,
|
||||
"Need BindFlags, current flag 0x%x", mem->desc.BindFlags);
|
||||
"Need BindFlags, current flag 0x%x", priv->desc.BindFlags);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GST_D3D11_MEMORY_LOCK (mem);
|
||||
if (mem->num_render_target_views) {
|
||||
if (priv->num_render_target_views) {
|
||||
ret = TRUE;
|
||||
goto done;
|
||||
}
|
||||
|
@ -1064,10 +1165,42 @@ done:
|
|||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
guint
|
||||
gst_d3d11_memory_get_render_target_view_size (GstD3D11Memory * mem)
|
||||
{
|
||||
g_return_val_if_fail (gst_is_d3d11_memory (GST_MEMORY_CAST (mem)), 0);
|
||||
|
||||
if (!gst_d3d11_memory_ensure_render_target_view (mem))
|
||||
return 0;
|
||||
|
||||
return mem->priv->num_render_target_views;
|
||||
}
|
||||
|
||||
ID3D11RenderTargetView *
|
||||
gst_d3d11_memory_get_render_target_view (GstD3D11Memory * mem, guint index)
|
||||
{
|
||||
GstD3D11MemoryPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (gst_is_d3d11_memory (GST_MEMORY_CAST (mem)), NULL);
|
||||
|
||||
if (!gst_d3d11_memory_ensure_render_target_view (mem))
|
||||
return NULL;
|
||||
|
||||
priv = mem->priv;
|
||||
|
||||
if (index >= priv->num_render_target_views) {
|
||||
GST_ERROR ("Invalid RTV index %d", index);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return priv->render_target_view[index];
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_d3d11_memory_ensure_decoder_output_view (GstD3D11Memory * mem,
|
||||
ID3D11VideoDevice * video_device, GUID * decoder_profile)
|
||||
{
|
||||
GstD3D11MemoryPrivate *dmem_priv = mem->priv;
|
||||
GstD3D11Allocator *allocator;
|
||||
GstD3D11AllocatorPrivate *priv;
|
||||
D3D11_VIDEO_DECODER_OUTPUT_VIEW_DESC desc;
|
||||
|
@ -1075,37 +1208,34 @@ gst_d3d11_memory_ensure_decoder_output_view (GstD3D11Memory * mem,
|
|||
HRESULT hr;
|
||||
gboolean ret = FALSE;
|
||||
|
||||
g_return_val_if_fail (gst_is_d3d11_memory (GST_MEMORY_CAST (mem)), FALSE);
|
||||
g_return_val_if_fail (video_device != NULL, FALSE);
|
||||
g_return_val_if_fail (decoder_profile != NULL, FALSE);
|
||||
|
||||
allocator = GST_D3D11_ALLOCATOR (GST_MEMORY_CAST (mem)->allocator);
|
||||
priv = allocator->priv;
|
||||
|
||||
if (!(mem->desc.BindFlags & D3D11_BIND_DECODER)) {
|
||||
if (!(dmem_priv->desc.BindFlags & D3D11_BIND_DECODER)) {
|
||||
GST_LOG_OBJECT (allocator,
|
||||
"Need BindFlags, current flag 0x%x", mem->desc.BindFlags);
|
||||
"Need BindFlags, current flag 0x%x", dmem_priv->desc.BindFlags);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GST_D3D11_MEMORY_LOCK (mem);
|
||||
if (mem->decoder_output_view) {
|
||||
ID3D11VideoDecoderOutputView_GetDesc (mem->decoder_output_view, &desc);
|
||||
if (dmem_priv->decoder_output_view) {
|
||||
ID3D11VideoDecoderOutputView_GetDesc (dmem_priv->decoder_output_view,
|
||||
&desc);
|
||||
if (IsEqualGUID (&desc.DecodeProfile, decoder_profile)) {
|
||||
goto succeeded;
|
||||
} else {
|
||||
/* Shouldn't happen, but try again anyway */
|
||||
GST_WARNING_OBJECT (allocator,
|
||||
"Existing view has different decoder profile");
|
||||
ID3D11VideoDecoderOutputView_Release (mem->decoder_output_view);
|
||||
mem->decoder_output_view = NULL;
|
||||
ID3D11VideoDecoderOutputView_Release (dmem_priv->decoder_output_view);
|
||||
dmem_priv->decoder_output_view = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (priv->decoder_output_view_array) {
|
||||
GST_D3D11_ALLOCATOR_LOCK (allocator);
|
||||
view = g_array_index (priv->decoder_output_view_array,
|
||||
ID3D11VideoDecoderOutputView *, mem->subresource_index);
|
||||
ID3D11VideoDecoderOutputView *, dmem_priv->subresource_index);
|
||||
|
||||
if (view) {
|
||||
ID3D11VideoDecoderOutputView_GetDesc (view, &desc);
|
||||
|
@ -1117,25 +1247,27 @@ gst_d3d11_memory_ensure_decoder_output_view (GstD3D11Memory * mem,
|
|||
ID3D11VideoDecoderOutputView_Release (view);
|
||||
view = NULL;
|
||||
g_array_index (priv->decoder_output_view_array,
|
||||
ID3D11VideoDecoderOutputView *, mem->subresource_index) = NULL;
|
||||
ID3D11VideoDecoderOutputView *,
|
||||
dmem_priv->subresource_index) = NULL;
|
||||
} else {
|
||||
/* Increase refcount and reuse existing view */
|
||||
mem->decoder_output_view = view;
|
||||
dmem_priv->decoder_output_view = view;
|
||||
ID3D11VideoDecoderOutputView_AddRef (view);
|
||||
}
|
||||
}
|
||||
GST_D3D11_ALLOCATOR_UNLOCK (allocator);
|
||||
}
|
||||
|
||||
if (mem->decoder_output_view)
|
||||
if (dmem_priv->decoder_output_view)
|
||||
goto succeeded;
|
||||
|
||||
desc.DecodeProfile = *decoder_profile;
|
||||
desc.ViewDimension = D3D11_VDOV_DIMENSION_TEXTURE2D;
|
||||
desc.Texture2D.ArraySlice = mem->subresource_index;
|
||||
desc.Texture2D.ArraySlice = dmem_priv->subresource_index;
|
||||
|
||||
hr = ID3D11VideoDevice_CreateVideoDecoderOutputView (video_device,
|
||||
(ID3D11Resource *) mem->texture, &desc, &mem->decoder_output_view);
|
||||
(ID3D11Resource *) dmem_priv->texture, &desc,
|
||||
&dmem_priv->decoder_output_view);
|
||||
if (!gst_d3d11_result (hr, mem->device)) {
|
||||
GST_ERROR_OBJECT (allocator,
|
||||
"Could not create decoder output view, hr: 0x%x", (guint) hr);
|
||||
|
@ -1146,15 +1278,15 @@ gst_d3d11_memory_ensure_decoder_output_view (GstD3D11Memory * mem,
|
|||
if (priv->decoder_output_view_array) {
|
||||
GST_D3D11_ALLOCATOR_LOCK (allocator);
|
||||
view = g_array_index (priv->decoder_output_view_array,
|
||||
ID3D11VideoDecoderOutputView *, mem->subresource_index);
|
||||
ID3D11VideoDecoderOutputView *, dmem_priv->subresource_index);
|
||||
|
||||
if (view)
|
||||
ID3D11VideoDecoderOutputView_Release (view);
|
||||
|
||||
g_array_index (priv->decoder_output_view_array,
|
||||
ID3D11VideoDecoderOutputView *, mem->subresource_index) =
|
||||
mem->decoder_output_view;
|
||||
ID3D11VideoDecoderOutputView_AddRef (mem->decoder_output_view);
|
||||
ID3D11VideoDecoderOutputView *, dmem_priv->subresource_index) =
|
||||
dmem_priv->decoder_output_view;
|
||||
ID3D11VideoDecoderOutputView_AddRef (dmem_priv->decoder_output_view);
|
||||
GST_D3D11_ALLOCATOR_UNLOCK (allocator);
|
||||
}
|
||||
|
||||
|
@ -1167,11 +1299,27 @@ done:
|
|||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
ID3D11VideoDecoderOutputView *
|
||||
gst_d3d11_memory_get_decoder_output_view (GstD3D11Memory * mem,
|
||||
ID3D11VideoDevice * video_device, GUID * decoder_profile)
|
||||
{
|
||||
g_return_val_if_fail (gst_is_d3d11_memory (GST_MEMORY_CAST (mem)), NULL);
|
||||
g_return_val_if_fail (video_device != NULL, NULL);
|
||||
g_return_val_if_fail (decoder_profile != NULL, NULL);
|
||||
|
||||
if (!gst_d3d11_memory_ensure_decoder_output_view (mem,
|
||||
video_device, decoder_profile))
|
||||
return NULL;
|
||||
|
||||
return mem->priv->decoder_output_view;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_d3d11_memory_ensure_processor_input_view (GstD3D11Memory * mem,
|
||||
ID3D11VideoDevice * video_device,
|
||||
ID3D11VideoProcessorEnumerator * enumerator)
|
||||
{
|
||||
GstD3D11MemoryPrivate *dmem_priv = mem->priv;
|
||||
GstD3D11Allocator *allocator;
|
||||
GstD3D11AllocatorPrivate *priv;
|
||||
D3D11_VIDEO_PROCESSOR_INPUT_VIEW_DESC desc;
|
||||
|
@ -1179,47 +1327,43 @@ gst_d3d11_memory_ensure_processor_input_view (GstD3D11Memory * mem,
|
|||
HRESULT hr;
|
||||
gboolean ret = FALSE;
|
||||
|
||||
g_return_val_if_fail (gst_is_d3d11_memory (GST_MEMORY_CAST (mem)), FALSE);
|
||||
g_return_val_if_fail (video_device != NULL, FALSE);
|
||||
g_return_val_if_fail (enumerator != NULL, FALSE);
|
||||
|
||||
allocator = GST_D3D11_ALLOCATOR (GST_MEMORY_CAST (mem)->allocator);
|
||||
priv = allocator->priv;
|
||||
|
||||
if (!check_bind_flags_for_processor_input_view (mem->desc.BindFlags)) {
|
||||
if (!check_bind_flags_for_processor_input_view (dmem_priv->desc.BindFlags)) {
|
||||
GST_LOG_OBJECT (allocator,
|
||||
"Need BindFlags, current flag 0x%x", mem->desc.BindFlags);
|
||||
"Need BindFlags, current flag 0x%x", dmem_priv->desc.BindFlags);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GST_D3D11_MEMORY_LOCK (mem);
|
||||
if (mem->processor_input_view)
|
||||
if (dmem_priv->processor_input_view)
|
||||
goto succeeded;
|
||||
|
||||
if (priv->processor_input_view_array) {
|
||||
GST_D3D11_ALLOCATOR_LOCK (allocator);
|
||||
view = g_array_index (priv->processor_input_view_array,
|
||||
ID3D11VideoProcessorInputView *, mem->subresource_index);
|
||||
ID3D11VideoProcessorInputView *, dmem_priv->subresource_index);
|
||||
|
||||
/* Increase refcount and reuse existing view */
|
||||
if (view) {
|
||||
mem->processor_input_view = view;
|
||||
dmem_priv->processor_input_view = view;
|
||||
ID3D11VideoProcessorInputView_AddRef (view);
|
||||
}
|
||||
GST_D3D11_ALLOCATOR_UNLOCK (allocator);
|
||||
}
|
||||
|
||||
if (mem->processor_input_view)
|
||||
if (dmem_priv->processor_input_view)
|
||||
goto succeeded;
|
||||
|
||||
desc.FourCC = 0;
|
||||
desc.ViewDimension = D3D11_VPIV_DIMENSION_TEXTURE2D;
|
||||
desc.Texture2D.MipSlice = 0;
|
||||
desc.Texture2D.ArraySlice = mem->subresource_index;
|
||||
desc.Texture2D.ArraySlice = dmem_priv->subresource_index;
|
||||
|
||||
hr = ID3D11VideoDevice_CreateVideoProcessorInputView (video_device,
|
||||
(ID3D11Resource *) mem->texture, enumerator, &desc,
|
||||
&mem->processor_input_view);
|
||||
(ID3D11Resource *) dmem_priv->texture, enumerator, &desc,
|
||||
&dmem_priv->processor_input_view);
|
||||
if (!gst_d3d11_result (hr, mem->device)) {
|
||||
GST_ERROR_OBJECT (allocator,
|
||||
"Could not create processor input view, hr: 0x%x", (guint) hr);
|
||||
|
@ -1230,15 +1374,15 @@ gst_d3d11_memory_ensure_processor_input_view (GstD3D11Memory * mem,
|
|||
if (priv->processor_input_view_array) {
|
||||
GST_D3D11_ALLOCATOR_LOCK (allocator);
|
||||
view = g_array_index (priv->processor_input_view_array,
|
||||
ID3D11VideoProcessorInputView *, mem->subresource_index);
|
||||
ID3D11VideoProcessorInputView *, dmem_priv->subresource_index);
|
||||
|
||||
if (view)
|
||||
ID3D11VideoProcessorInputView_Release (view);
|
||||
|
||||
g_array_index (priv->processor_input_view_array,
|
||||
ID3D11VideoProcessorInputView *, mem->subresource_index) =
|
||||
mem->processor_input_view;
|
||||
ID3D11VideoProcessorInputView_AddRef (mem->processor_input_view);
|
||||
ID3D11VideoProcessorInputView *, dmem_priv->subresource_index) =
|
||||
dmem_priv->processor_input_view;
|
||||
ID3D11VideoProcessorInputView_AddRef (dmem_priv->processor_input_view);
|
||||
GST_D3D11_ALLOCATOR_UNLOCK (allocator);
|
||||
}
|
||||
|
||||
|
@ -1251,45 +1395,58 @@ done:
|
|||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
ID3D11VideoProcessorInputView *
|
||||
gst_d3d11_memory_get_processor_input_view (GstD3D11Memory * mem,
|
||||
ID3D11VideoDevice * video_device,
|
||||
ID3D11VideoProcessorEnumerator * enumerator)
|
||||
{
|
||||
g_return_val_if_fail (gst_is_d3d11_memory (GST_MEMORY_CAST (mem)), NULL);
|
||||
g_return_val_if_fail (video_device != NULL, NULL);
|
||||
g_return_val_if_fail (enumerator != NULL, NULL);
|
||||
|
||||
if (!gst_d3d11_memory_ensure_processor_input_view (mem, video_device,
|
||||
enumerator))
|
||||
return NULL;
|
||||
|
||||
return mem->priv->processor_input_view;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_d3d11_memory_ensure_processor_output_view (GstD3D11Memory * mem,
|
||||
ID3D11VideoDevice * video_device,
|
||||
ID3D11VideoProcessorEnumerator * enumerator)
|
||||
{
|
||||
GstD3D11MemoryPrivate *priv = mem->priv;
|
||||
GstD3D11Allocator *allocator;
|
||||
D3D11_VIDEO_PROCESSOR_OUTPUT_VIEW_DESC desc = { 0, };
|
||||
HRESULT hr;
|
||||
gboolean ret;
|
||||
|
||||
g_return_val_if_fail (gst_is_d3d11_memory (GST_MEMORY_CAST (mem)), FALSE);
|
||||
g_return_val_if_fail (video_device != NULL, FALSE);
|
||||
g_return_val_if_fail (enumerator != NULL, FALSE);
|
||||
|
||||
allocator = GST_D3D11_ALLOCATOR (GST_MEMORY_CAST (mem)->allocator);
|
||||
|
||||
if (!(mem->desc.BindFlags & D3D11_BIND_RENDER_TARGET)) {
|
||||
if (!(priv->desc.BindFlags & D3D11_BIND_RENDER_TARGET)) {
|
||||
GST_LOG_OBJECT (allocator,
|
||||
"Need BindFlags, current flag 0x%x", mem->desc.BindFlags);
|
||||
"Need BindFlags, current flag 0x%x", priv->desc.BindFlags);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* FIXME: texture array should be supported at some point */
|
||||
if (mem->subresource_index != 0) {
|
||||
if (priv->subresource_index != 0) {
|
||||
GST_FIXME_OBJECT (allocator,
|
||||
"Texture array is not suppoted for processor output view");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GST_D3D11_MEMORY_LOCK (mem);
|
||||
if (mem->processor_output_view)
|
||||
if (priv->processor_output_view)
|
||||
goto succeeded;
|
||||
|
||||
desc.ViewDimension = D3D11_VPOV_DIMENSION_TEXTURE2D;
|
||||
desc.Texture2D.MipSlice = 0;
|
||||
|
||||
hr = ID3D11VideoDevice_CreateVideoProcessorOutputView (video_device,
|
||||
(ID3D11Resource *) mem->texture, enumerator, &desc,
|
||||
&mem->processor_output_view);
|
||||
(ID3D11Resource *) priv->texture, enumerator, &desc,
|
||||
&priv->processor_output_view);
|
||||
if (!gst_d3d11_result (hr, mem->device)) {
|
||||
GST_ERROR_OBJECT (allocator,
|
||||
"Could not create processor input view, hr: 0x%x", (guint) hr);
|
||||
|
@ -1304,3 +1461,19 @@ done:
|
|||
|
||||
return ret;
|
||||
}
|
||||
|
||||
ID3D11VideoProcessorOutputView *
|
||||
gst_d3d11_memory_get_processor_output_view (GstD3D11Memory * mem,
|
||||
ID3D11VideoDevice * video_device,
|
||||
ID3D11VideoProcessorEnumerator * enumerator)
|
||||
{
|
||||
g_return_val_if_fail (gst_is_d3d11_memory (GST_MEMORY_CAST (mem)), NULL);
|
||||
g_return_val_if_fail (video_device != NULL, NULL);
|
||||
g_return_val_if_fail (enumerator != NULL, NULL);
|
||||
|
||||
if (!gst_d3d11_memory_ensure_processor_output_view (mem, video_device,
|
||||
enumerator))
|
||||
return NULL;
|
||||
|
||||
return mem->priv->processor_output_view;
|
||||
}
|
||||
|
|
|
@ -38,6 +38,8 @@ G_BEGIN_DECLS
|
|||
#define GST_D3D11_ALLOCATOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GST_TYPE_D3D11_ALLOCATOR, GstD3D11AllocatorClass))
|
||||
#define GST_D3D11_ALLOCATOR_CAST(obj) ((GstD3D11Allocator *)obj)
|
||||
|
||||
typedef struct _GstD3D11MemoryPrivate GstD3D11MemoryPrivate;
|
||||
|
||||
#define GST_D3D11_MEMORY_NAME "D3D11Memory"
|
||||
|
||||
/**
|
||||
|
@ -91,13 +93,6 @@ struct _GstD3D11AllocationParams
|
|||
gpointer _gst_reserved[GST_PADDING_LARGE];
|
||||
};
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GST_D3D11_MEMORY_TYPE_TEXTURE = 0,
|
||||
GST_D3D11_MEMORY_TYPE_ARRAY = 1,
|
||||
GST_D3D11_MEMORY_TYPE_STAGING = 2,
|
||||
} GstD3D11MemoryType;
|
||||
|
||||
struct _GstD3D11Memory
|
||||
{
|
||||
GstMemory mem;
|
||||
|
@ -105,30 +100,9 @@ struct _GstD3D11Memory
|
|||
/*< public > */
|
||||
GstD3D11Device *device;
|
||||
|
||||
ID3D11Texture2D *texture;
|
||||
ID3D11Texture2D *staging;
|
||||
|
||||
ID3D11ShaderResourceView *shader_resource_view[GST_VIDEO_MAX_PLANES];
|
||||
guint num_shader_resource_views;
|
||||
|
||||
ID3D11RenderTargetView *render_target_view[GST_VIDEO_MAX_PLANES];
|
||||
guint num_render_target_views;
|
||||
|
||||
ID3D11VideoDecoderOutputView *decoder_output_view;
|
||||
ID3D11VideoProcessorInputView *processor_input_view;
|
||||
ID3D11VideoProcessorOutputView *processor_output_view;
|
||||
|
||||
GstD3D11MemoryType type;
|
||||
|
||||
/* > 0 if this is Array typed memory */
|
||||
guint subresource_index;
|
||||
|
||||
D3D11_TEXTURE2D_DESC desc;
|
||||
D3D11_MAPPED_SUBRESOURCE map;
|
||||
|
||||
/*< private >*/
|
||||
GMutex lock;
|
||||
gint cpu_map_count;
|
||||
GstD3D11MemoryPrivate *priv;
|
||||
gpointer _gst_reserved[GST_PADDING];
|
||||
};
|
||||
|
||||
struct _GstD3D11Allocator
|
||||
|
@ -184,21 +158,34 @@ void gst_d3d11_allocator_set_flushing (GstD3D11Allocator * alloca
|
|||
|
||||
gboolean gst_is_d3d11_memory (GstMemory * mem);
|
||||
|
||||
gboolean gst_d3d11_memory_ensure_shader_resource_view (GstD3D11Memory * mem);
|
||||
ID3D11Texture2D * gst_d3d11_memory_get_texture_handle (GstD3D11Memory * mem);
|
||||
|
||||
gboolean gst_d3d11_memory_ensure_render_target_view (GstD3D11Memory * mem);
|
||||
gboolean gst_d3d11_memory_get_texture_desc (GstD3D11Memory * mem,
|
||||
D3D11_TEXTURE2D_DESC * desc);
|
||||
|
||||
gboolean gst_d3d11_memory_ensure_decoder_output_view (GstD3D11Memory * mem,
|
||||
ID3D11VideoDevice * video_device,
|
||||
GUID * decoder_profile);
|
||||
guint gst_d3d11_memory_get_subresource_index (GstD3D11Memory * mem);
|
||||
|
||||
gboolean gst_d3d11_memory_ensure_processor_input_view (GstD3D11Memory * mem,
|
||||
ID3D11VideoDevice * video_device,
|
||||
ID3D11VideoProcessorEnumerator * enumerator);
|
||||
guint gst_d3d11_memory_get_shader_resource_view_size (GstD3D11Memory * mem);
|
||||
|
||||
gboolean gst_d3d11_memory_ensure_processor_output_view (GstD3D11Memory * mem,
|
||||
ID3D11VideoDevice * video_device,
|
||||
ID3D11VideoProcessorEnumerator * enumerator);
|
||||
ID3D11ShaderResourceView * gst_d3d11_memory_get_shader_resource_view (GstD3D11Memory * mem,
|
||||
guint index);
|
||||
|
||||
guint gst_d3d11_memory_get_render_target_view_size (GstD3D11Memory * mem);
|
||||
|
||||
ID3D11RenderTargetView * gst_d3d11_memory_get_render_target_view (GstD3D11Memory * mem,
|
||||
guint index);
|
||||
|
||||
ID3D11VideoDecoderOutputView * gst_d3d11_memory_get_decoder_output_view (GstD3D11Memory * mem,
|
||||
ID3D11VideoDevice * video_device,
|
||||
GUID * decoder_profile);
|
||||
|
||||
ID3D11VideoProcessorInputView * gst_d3d11_memory_get_processor_input_view (GstD3D11Memory * mem,
|
||||
ID3D11VideoDevice * video_device,
|
||||
ID3D11VideoProcessorEnumerator * enumerator);
|
||||
|
||||
ID3D11VideoProcessorOutputView * gst_d3d11_memory_get_processor_output_view (GstD3D11Memory * mem,
|
||||
ID3D11VideoDevice * video_device,
|
||||
ID3D11VideoProcessorEnumerator * enumerator);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
|
|
@ -396,15 +396,11 @@ gst_d3d11_upload_can_use_staging_buffer (GstD3D11Upload * self,
|
|||
GstBuffer * outbuf)
|
||||
{
|
||||
GstD3D11BaseFilter *filter = GST_D3D11_BASE_FILTER (self);
|
||||
gint i;
|
||||
ID3D11Device *device_handle =
|
||||
gst_d3d11_device_get_device_handle (filter->device);
|
||||
|
||||
/* staging buffer doesn't need to be used for non-d3d11 memory */
|
||||
for (i = 0; i < gst_buffer_n_memory (outbuf); i++) {
|
||||
GstMemory *mem = gst_buffer_peek_memory (outbuf, i);
|
||||
|
||||
if (!gst_is_d3d11_memory (mem))
|
||||
return FALSE;
|
||||
}
|
||||
if (!gst_d3d11_buffer_can_access_device (outbuf, device_handle))
|
||||
return FALSE;
|
||||
|
||||
if (self->staging_buffer)
|
||||
return TRUE;
|
||||
|
@ -462,7 +458,8 @@ gst_d3d11_upload_transform (GstBaseTransform * trans, GstBuffer * inbuf,
|
|||
|
||||
/* Copy staging texture to d3d11 texture */
|
||||
if (use_staging_buf) {
|
||||
if (!gst_d3d11_buffer_copy_into (outbuf, self->staging_buffer)) {
|
||||
if (!gst_d3d11_buffer_copy_into (outbuf,
|
||||
self->staging_buffer, &filter->out_info)) {
|
||||
GST_ERROR_OBJECT (self, "Cannot copy staging texture into texture");
|
||||
return GST_FLOW_ERROR;
|
||||
}
|
||||
|
|
|
@ -579,22 +579,59 @@ _gst_d3d11_result (HRESULT hr, GstD3D11Device * device, GstDebugCategory * cat,
|
|||
#endif
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_d3d11_buffer_copy_into_fallback (GstBuffer * dst, GstBuffer * src,
|
||||
const GstVideoInfo * info)
|
||||
{
|
||||
GstVideoFrame in_frame, out_frame;
|
||||
gboolean ret;
|
||||
|
||||
if (!gst_video_frame_map (&in_frame, (GstVideoInfo *) info, src,
|
||||
GST_MAP_READ | GST_VIDEO_FRAME_MAP_FLAG_NO_REF))
|
||||
goto invalid_buffer;
|
||||
|
||||
if (!gst_video_frame_map (&out_frame, (GstVideoInfo *) info, dst,
|
||||
GST_MAP_WRITE | GST_VIDEO_FRAME_MAP_FLAG_NO_REF)) {
|
||||
gst_video_frame_unmap (&in_frame);
|
||||
goto invalid_buffer;
|
||||
}
|
||||
|
||||
ret = gst_video_frame_copy (&out_frame, &in_frame);
|
||||
|
||||
gst_video_frame_unmap (&in_frame);
|
||||
gst_video_frame_unmap (&out_frame);
|
||||
|
||||
return ret;
|
||||
|
||||
/* ERRORS */
|
||||
invalid_buffer:
|
||||
{
|
||||
GST_ERROR ("Invalid video buffer");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_d3d11_buffer_copy_into (GstBuffer * dst, GstBuffer * src)
|
||||
gst_d3d11_buffer_copy_into (GstBuffer * dst, GstBuffer * src,
|
||||
const GstVideoInfo * info)
|
||||
{
|
||||
guint i;
|
||||
guint num_mem;
|
||||
|
||||
g_return_val_if_fail (GST_IS_BUFFER (dst), FALSE);
|
||||
g_return_val_if_fail (GST_IS_BUFFER (src), FALSE);
|
||||
g_return_val_if_fail (info != NULL, FALSE);
|
||||
|
||||
num_mem = gst_buffer_n_memory (dst);
|
||||
if (num_mem != gst_buffer_n_memory (src)) {
|
||||
GST_WARNING ("different num memory");
|
||||
return FALSE;
|
||||
if (gst_buffer_n_memory (dst) != gst_buffer_n_memory (src)) {
|
||||
GST_LOG ("different memory layout, perform fallback copy");
|
||||
return gst_d3d11_buffer_copy_into_fallback (dst, src, info);
|
||||
}
|
||||
|
||||
for (i = 0; i < num_mem; i++) {
|
||||
if (!gst_is_d3d11_buffer (dst) || !gst_is_d3d11_buffer (src)) {
|
||||
GST_LOG ("non-d3d11 memory, perform fallback copy");
|
||||
return gst_d3d11_buffer_copy_into_fallback (dst, src, info);
|
||||
}
|
||||
|
||||
for (i = 0; i < gst_buffer_n_memory (dst); i++) {
|
||||
GstMemory *dst_mem, *src_mem;
|
||||
GstD3D11Memory *dst_dmem, *src_dmem;
|
||||
GstMapInfo dst_info;
|
||||
|
@ -603,30 +640,25 @@ gst_d3d11_buffer_copy_into (GstBuffer * dst, GstBuffer * src)
|
|||
ID3D11DeviceContext *device_context;
|
||||
GstD3D11Device *device;
|
||||
D3D11_BOX src_box = { 0, };
|
||||
D3D11_TEXTURE2D_DESC dst_desc, src_desc;
|
||||
guint dst_subidx, src_subidx;
|
||||
|
||||
dst_mem = gst_buffer_peek_memory (dst, i);
|
||||
src_mem = gst_buffer_peek_memory (src, i);
|
||||
|
||||
if (!gst_is_d3d11_memory (dst_mem)) {
|
||||
GST_WARNING ("dst memory is not d3d11");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!gst_is_d3d11_memory (src_mem)) {
|
||||
GST_WARNING ("src memory is not d3d11");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
dst_dmem = (GstD3D11Memory *) dst_mem;
|
||||
src_dmem = (GstD3D11Memory *) src_mem;
|
||||
|
||||
device = dst_dmem->device;
|
||||
if (device != src_dmem->device) {
|
||||
GST_WARNING ("different device");
|
||||
return FALSE;
|
||||
GST_LOG ("different device, perform fallback copy");
|
||||
return gst_d3d11_buffer_copy_into_fallback (dst, src, info);
|
||||
}
|
||||
|
||||
if (dst_dmem->desc.Format != src_dmem->desc.Format) {
|
||||
gst_d3d11_memory_get_texture_desc (dst_dmem, &dst_desc);
|
||||
gst_d3d11_memory_get_texture_desc (src_dmem, &src_desc);
|
||||
|
||||
if (dst_desc.Format != src_desc.Format) {
|
||||
GST_WARNING ("different dxgi format");
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -653,13 +685,15 @@ gst_d3d11_buffer_copy_into (GstBuffer * dst, GstBuffer * src)
|
|||
src_box.top = 0;
|
||||
src_box.front = 0;
|
||||
src_box.back = 1;
|
||||
src_box.right = MIN (src_dmem->desc.Width, dst_dmem->desc.Width);
|
||||
src_box.bottom = MIN (src_dmem->desc.Height, dst_dmem->desc.Height);
|
||||
src_box.right = MIN (src_desc.Width, dst_desc.Width);
|
||||
src_box.bottom = MIN (src_desc.Height, dst_desc.Height);
|
||||
|
||||
dst_subidx = gst_d3d11_memory_get_subresource_index (dst_dmem);
|
||||
src_subidx = gst_d3d11_memory_get_subresource_index (src_dmem);
|
||||
|
||||
gst_d3d11_device_lock (device);
|
||||
ID3D11DeviceContext_CopySubresourceRegion (device_context,
|
||||
dst_texture, dst_dmem->subresource_index, 0, 0, 0,
|
||||
src_texture, src_dmem->subresource_index, &src_box);
|
||||
dst_texture, dst_subidx, 0, 0, 0, src_texture, src_subidx, &src_box);
|
||||
gst_d3d11_device_unlock (device);
|
||||
|
||||
gst_memory_unmap (src_mem, &src_info);
|
||||
|
@ -669,6 +703,189 @@ gst_d3d11_buffer_copy_into (GstBuffer * dst, GstBuffer * src)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_is_d3d11_buffer (GstBuffer * buffer)
|
||||
{
|
||||
guint i;
|
||||
guint size;
|
||||
|
||||
g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
|
||||
|
||||
size = gst_buffer_n_memory (buffer);
|
||||
if (size == 0)
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
GstMemory *mem = gst_buffer_peek_memory (buffer, i);
|
||||
|
||||
if (!gst_is_d3d11_memory (mem))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_d3d11_buffer_can_access_device (GstBuffer * buffer, ID3D11Device * device)
|
||||
{
|
||||
guint i;
|
||||
|
||||
g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
|
||||
g_return_val_if_fail (device != NULL, FALSE);
|
||||
|
||||
if (!gst_is_d3d11_buffer (buffer)) {
|
||||
GST_LOG ("Not a d3d11 buffer");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
for (i = 0; i < gst_buffer_n_memory (buffer); i++) {
|
||||
GstD3D11Memory *mem = (GstD3D11Memory *) gst_buffer_peek_memory (buffer, i);
|
||||
ID3D11Device *handle;
|
||||
|
||||
handle = gst_d3d11_device_get_device_handle (mem->device);
|
||||
if (handle != device) {
|
||||
GST_LOG ("D3D11 device is incompatible");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_d3d11_buffer_map (GstBuffer * buffer, ID3D11Device * device,
|
||||
GstMapInfo info[GST_VIDEO_MAX_PLANES], GstMapFlags flags)
|
||||
{
|
||||
GstMapFlags map_flags;
|
||||
gint num_mapped = 0;
|
||||
|
||||
g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
|
||||
g_return_val_if_fail (info != NULL, FALSE);
|
||||
|
||||
if (!gst_d3d11_buffer_can_access_device (buffer, device))
|
||||
return FALSE;
|
||||
|
||||
map_flags = flags | GST_MAP_D3D11;
|
||||
|
||||
for (num_mapped = 0; num_mapped < gst_buffer_n_memory (buffer); num_mapped++) {
|
||||
GstMemory *mem = gst_buffer_peek_memory (buffer, num_mapped);
|
||||
|
||||
if (!gst_memory_map (mem, &info[num_mapped], map_flags)) {
|
||||
GST_ERROR ("Couldn't map memory");
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
||||
error:
|
||||
{
|
||||
gint i;
|
||||
for (i = 0; i < num_mapped; i++) {
|
||||
GstMemory *mem = gst_buffer_peek_memory (buffer, num_mapped);
|
||||
gst_memory_unmap (mem, &info[i]);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_d3d11_buffer_unmap (GstBuffer * buffer,
|
||||
GstMapInfo info[GST_VIDEO_MAX_PLANES])
|
||||
{
|
||||
gint i;
|
||||
|
||||
g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
|
||||
g_return_val_if_fail (info != NULL, FALSE);
|
||||
|
||||
for (i = 0; i < gst_buffer_n_memory (buffer); i++) {
|
||||
GstMemory *mem = gst_buffer_peek_memory (buffer, i);
|
||||
|
||||
gst_memory_unmap (mem, &info[i]);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
guint
|
||||
gst_d3d11_buffer_get_shader_resource_view (GstBuffer * buffer,
|
||||
ID3D11ShaderResourceView * view[GST_VIDEO_MAX_PLANES])
|
||||
{
|
||||
gint i;
|
||||
guint num_views = 0;
|
||||
|
||||
g_return_val_if_fail (GST_IS_BUFFER (buffer), 0);
|
||||
g_return_val_if_fail (view != NULL, 0);
|
||||
|
||||
if (!gst_is_d3d11_buffer (buffer)) {
|
||||
GST_ERROR ("Buffer contains non-d3d11 memory");
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < gst_buffer_n_memory (buffer); i++) {
|
||||
GstD3D11Memory *mem = (GstD3D11Memory *) gst_buffer_peek_memory (buffer, i);
|
||||
guint view_size;
|
||||
gint j;
|
||||
|
||||
view_size = gst_d3d11_memory_get_shader_resource_view_size (mem);
|
||||
if (!view_size) {
|
||||
GST_LOG ("SRV is unavailable for memory index %d", i);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (j = 0; j < view_size; j++) {
|
||||
if (num_views >= GST_VIDEO_MAX_PLANES) {
|
||||
GST_ERROR ("Too many SRVs");
|
||||
return 0;
|
||||
}
|
||||
|
||||
view[num_views++] = gst_d3d11_memory_get_shader_resource_view (mem, j);
|
||||
}
|
||||
}
|
||||
|
||||
return num_views;
|
||||
}
|
||||
|
||||
guint
|
||||
gst_d3d11_buffer_get_render_target_view (GstBuffer * buffer,
|
||||
ID3D11RenderTargetView * view[GST_VIDEO_MAX_PLANES])
|
||||
{
|
||||
gint i;
|
||||
guint num_views = 0;
|
||||
|
||||
g_return_val_if_fail (GST_IS_BUFFER (buffer), 0);
|
||||
g_return_val_if_fail (view != NULL, 0);
|
||||
|
||||
if (!gst_is_d3d11_buffer (buffer)) {
|
||||
GST_ERROR ("Buffer contains non-d3d11 memory");
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < gst_buffer_n_memory (buffer); i++) {
|
||||
GstD3D11Memory *mem = (GstD3D11Memory *) gst_buffer_peek_memory (buffer, i);
|
||||
guint view_size;
|
||||
gint j;
|
||||
|
||||
view_size = gst_d3d11_memory_get_render_target_view_size (mem);
|
||||
if (!view_size) {
|
||||
GST_LOG ("RTV is unavailable for memory index %d", i);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (j = 0; j < view_size; j++) {
|
||||
if (num_views >= GST_VIDEO_MAX_PLANES) {
|
||||
GST_ERROR ("Too many RTVs");
|
||||
return 0;
|
||||
}
|
||||
|
||||
view[num_views++] = gst_d3d11_memory_get_render_target_view (mem, j);
|
||||
}
|
||||
}
|
||||
|
||||
return num_views;
|
||||
}
|
||||
|
||||
GstBufferPool *
|
||||
gst_d3d11_buffer_pool_new_with_options (GstD3D11Device * device,
|
||||
GstCaps * caps, GstD3D11AllocationParams * alloc_params,
|
||||
|
|
|
@ -66,7 +66,27 @@ GstBuffer * gst_d3d11_allocate_staging_buffer_for (GstBuffer * buffer,
|
|||
gboolean add_videometa);
|
||||
|
||||
gboolean gst_d3d11_buffer_copy_into (GstBuffer * dst,
|
||||
GstBuffer * src);
|
||||
GstBuffer * src,
|
||||
const GstVideoInfo * info);
|
||||
|
||||
gboolean gst_is_d3d11_buffer (GstBuffer * buffer);
|
||||
|
||||
gboolean gst_d3d11_buffer_can_access_device (GstBuffer * buffer,
|
||||
ID3D11Device * device);
|
||||
|
||||
gboolean gst_d3d11_buffer_map (GstBuffer * buffer,
|
||||
ID3D11Device * device,
|
||||
GstMapInfo info[GST_VIDEO_MAX_PLANES],
|
||||
GstMapFlags flags);
|
||||
|
||||
gboolean gst_d3d11_buffer_unmap (GstBuffer * buffer,
|
||||
GstMapInfo info[GST_VIDEO_MAX_PLANES]);
|
||||
|
||||
guint gst_d3d11_buffer_get_shader_resource_view (GstBuffer * buffer,
|
||||
ID3D11ShaderResourceView * view[GST_VIDEO_MAX_PLANES]);
|
||||
|
||||
guint gst_d3d11_buffer_get_render_target_view (GstBuffer * buffer,
|
||||
ID3D11RenderTargetView * view[GST_VIDEO_MAX_PLANES]);
|
||||
|
||||
GstBufferPool * gst_d3d11_buffer_pool_new_with_options (GstD3D11Device * device,
|
||||
GstCaps * caps,
|
||||
|
@ -74,7 +94,6 @@ GstBufferPool * gst_d3d11_buffer_pool_new_with_options (GstD3D11Device * device
|
|||
guint min_buffers,
|
||||
guint max_buffers);
|
||||
|
||||
|
||||
gboolean _gst_d3d11_result (HRESULT hr,
|
||||
GstD3D11Device * device,
|
||||
GstDebugCategory * cat,
|
||||
|
|
|
@ -445,11 +445,11 @@ gst_d3d11_video_processor_create_input_view (GstD3D11VideoProcessor * processor,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_d3d11_video_processor_ensure_input_view (GstD3D11VideoProcessor * processor,
|
||||
ID3D11VideoProcessorInputView *
|
||||
gst_d3d11_video_processor_get_input_view (GstD3D11VideoProcessor * processor,
|
||||
GstD3D11Memory * mem)
|
||||
{
|
||||
return gst_d3d11_memory_ensure_processor_input_view (mem,
|
||||
return gst_d3d11_memory_get_processor_input_view (mem,
|
||||
processor->video_device, processor->enumerator);
|
||||
}
|
||||
|
||||
|
@ -473,11 +473,11 @@ gst_d3d11_video_processor_create_output_view (GstD3D11VideoProcessor *
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_d3d11_video_processor_ensure_output_view (GstD3D11VideoProcessor *
|
||||
ID3D11VideoProcessorOutputView *
|
||||
gst_d3d11_video_processor_get_output_view (GstD3D11VideoProcessor *
|
||||
processor, GstD3D11Memory * mem)
|
||||
{
|
||||
return gst_d3d11_memory_ensure_processor_output_view (mem,
|
||||
return gst_d3d11_memory_get_processor_output_view (mem,
|
||||
processor->video_device, processor->enumerator);
|
||||
}
|
||||
|
||||
|
|
|
@ -78,16 +78,16 @@ gboolean gst_d3d11_video_processor_create_input_view (GstD3D11VideoProcessor *
|
|||
ID3D11Resource *resource,
|
||||
ID3D11VideoProcessorInputView ** view);
|
||||
|
||||
gboolean gst_d3d11_video_processor_ensure_input_view (GstD3D11VideoProcessor * processor,
|
||||
GstD3D11Memory *mem);
|
||||
ID3D11VideoProcessorInputView * gst_d3d11_video_processor_get_input_view (GstD3D11VideoProcessor * processor,
|
||||
GstD3D11Memory *mem);
|
||||
|
||||
gboolean gst_d3d11_video_processor_create_output_view (GstD3D11VideoProcessor * processor,
|
||||
D3D11_VIDEO_PROCESSOR_OUTPUT_VIEW_DESC * desc,
|
||||
ID3D11Resource *resource,
|
||||
ID3D11VideoProcessorOutputView ** view);
|
||||
|
||||
gboolean gst_d3d11_video_processor_ensure_output_view (GstD3D11VideoProcessor * processor,
|
||||
GstD3D11Memory *mem);
|
||||
ID3D11VideoProcessorOutputView * gst_d3d11_video_processor_get_output_view (GstD3D11VideoProcessor * processor,
|
||||
GstD3D11Memory *mem);
|
||||
|
||||
void gst_d3d11_video_processor_input_view_release (ID3D11VideoProcessorInputView * view);
|
||||
|
||||
|
|
|
@ -785,7 +785,6 @@ gst_d3d11_video_sink_upload_frame (GstD3D11VideoSink * self, GstBuffer * inbuf,
|
|||
{
|
||||
GstVideoFrame in_frame, out_frame;
|
||||
gboolean ret;
|
||||
gint i;
|
||||
|
||||
GST_LOG_OBJECT (self, "Copy to fallback buffer");
|
||||
|
||||
|
@ -804,22 +803,6 @@ gst_d3d11_video_sink_upload_frame (GstD3D11VideoSink * self, GstBuffer * inbuf,
|
|||
gst_video_frame_unmap (&in_frame);
|
||||
gst_video_frame_unmap (&out_frame);
|
||||
|
||||
if (ret) {
|
||||
/* map to upload staging texture to render texture */
|
||||
for (i = 0; i < gst_buffer_n_memory (outbuf); i++) {
|
||||
GstMemory *mem;
|
||||
GstMapInfo map;
|
||||
|
||||
mem = gst_buffer_peek_memory (outbuf, i);
|
||||
if (!gst_memory_map (mem, &map, (GST_MAP_READ | GST_MAP_D3D11))) {
|
||||
GST_ERROR_OBJECT (self, "cannot upload staging texture");
|
||||
ret = FALSE;
|
||||
break;
|
||||
}
|
||||
gst_memory_unmap (mem, &map);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
/* ERRORS */
|
||||
|
@ -835,136 +818,105 @@ static gboolean
|
|||
gst_d3d11_video_sink_copy_d3d11_to_d3d11 (GstD3D11VideoSink * self,
|
||||
GstBuffer * inbuf, GstBuffer * outbuf)
|
||||
{
|
||||
gint i;
|
||||
ID3D11DeviceContext *context_handle =
|
||||
gst_d3d11_device_get_device_context_handle (self->device);
|
||||
|
||||
g_return_val_if_fail (gst_buffer_n_memory (inbuf) ==
|
||||
gst_buffer_n_memory (outbuf), FALSE);
|
||||
|
||||
GST_LOG_OBJECT (self, "Copy to fallback buffer using device memory copy");
|
||||
|
||||
gst_d3d11_device_lock (self->device);
|
||||
for (i = 0; i < gst_buffer_n_memory (inbuf); i++) {
|
||||
GstD3D11Memory *in_mem =
|
||||
(GstD3D11Memory *) gst_buffer_peek_memory (inbuf, i);
|
||||
GstD3D11Memory *out_mem =
|
||||
(GstD3D11Memory *) gst_buffer_peek_memory (outbuf, i);
|
||||
D3D11_BOX src_box;
|
||||
return gst_d3d11_buffer_copy_into (outbuf, inbuf, &self->info);
|
||||
}
|
||||
|
||||
/* input buffer might be larger than render size */
|
||||
src_box.left = 0;
|
||||
src_box.top = 0;
|
||||
src_box.front = 0;
|
||||
src_box.back = 1;
|
||||
src_box.right = out_mem->desc.Width;
|
||||
src_box.bottom = out_mem->desc.Height;
|
||||
static gboolean
|
||||
gst_d3d11_video_sink_get_fallback_buffer (GstD3D11VideoSink * self,
|
||||
GstBuffer * inbuf, GstBuffer ** fallback_buf, gboolean device_copy)
|
||||
{
|
||||
GstBuffer *outbuf = NULL;
|
||||
ID3D11ShaderResourceView *view[GST_VIDEO_MAX_PLANES];
|
||||
GstVideoOverlayCompositionMeta *compo_meta;
|
||||
|
||||
ID3D11DeviceContext_CopySubresourceRegion (context_handle,
|
||||
(ID3D11Resource *) out_mem->texture, 0, 0, 0, 0,
|
||||
(ID3D11Resource *) in_mem->texture, in_mem->subresource_index,
|
||||
&src_box);
|
||||
if (!self->fallback_pool ||
|
||||
!gst_buffer_pool_set_active (self->fallback_pool, TRUE) ||
|
||||
gst_buffer_pool_acquire_buffer (self->fallback_pool, &outbuf,
|
||||
NULL) != GST_FLOW_OK) {
|
||||
GST_ERROR_OBJECT (self, "fallback pool is unavailable");
|
||||
return FALSE;
|
||||
}
|
||||
gst_d3d11_device_unlock (self->device);
|
||||
|
||||
/* Ensure SRV */
|
||||
if (!gst_d3d11_buffer_get_shader_resource_view (outbuf, view)) {
|
||||
GST_ERROR_OBJECT (self, "fallback SRV is unavailable");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (device_copy) {
|
||||
if (!gst_d3d11_video_sink_copy_d3d11_to_d3d11 (self, inbuf, outbuf)) {
|
||||
GST_ERROR_OBJECT (self, "cannot copy frame");
|
||||
goto error;
|
||||
}
|
||||
} else if (!gst_d3d11_video_sink_upload_frame (self, inbuf, outbuf)) {
|
||||
GST_ERROR_OBJECT (self, "cannot upload frame");
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Copy overlaycomposition meta if any */
|
||||
compo_meta = gst_buffer_get_video_overlay_composition_meta (inbuf);
|
||||
if (compo_meta)
|
||||
gst_buffer_add_video_overlay_composition_meta (outbuf, compo_meta->overlay);
|
||||
|
||||
*fallback_buf = outbuf;
|
||||
|
||||
return TRUE;
|
||||
|
||||
error:
|
||||
gst_buffer_unref (outbuf);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
gst_d3d11_video_sink_show_frame (GstVideoSink * sink, GstBuffer * buf)
|
||||
{
|
||||
GstD3D11VideoSink *self = GST_D3D11_VIDEO_SINK (sink);
|
||||
GstMapInfo map;
|
||||
GstFlowReturn ret;
|
||||
GstVideoRectangle rect = { 0, };
|
||||
GstBuffer *render_buf;
|
||||
gboolean need_unref = FALSE;
|
||||
gboolean do_device_copy = TRUE;
|
||||
gint i;
|
||||
GstBuffer *fallback_buf = NULL;
|
||||
GstStructure *stats = NULL;
|
||||
ID3D11Device *device_handle =
|
||||
gst_d3d11_device_get_device_handle (self->device);
|
||||
ID3D11ShaderResourceView *view[GST_VIDEO_MAX_PLANES];
|
||||
|
||||
render_buf = buf;
|
||||
|
||||
for (i = 0; i < gst_buffer_n_memory (buf); i++) {
|
||||
GstMemory *mem;
|
||||
GstD3D11Memory *dmem;
|
||||
|
||||
mem = gst_buffer_peek_memory (buf, i);
|
||||
if (!gst_is_d3d11_memory (mem)) {
|
||||
GST_LOG_OBJECT (sink, "not a d3d11 memory, need fallback");
|
||||
render_buf = NULL;
|
||||
do_device_copy = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
dmem = (GstD3D11Memory *) mem;
|
||||
if (dmem->device != self->device) {
|
||||
GST_LOG_OBJECT (sink, "different d3d11 device, need fallback");
|
||||
render_buf = NULL;
|
||||
do_device_copy = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (dmem->desc.Usage == D3D11_USAGE_DEFAULT) {
|
||||
if (!gst_memory_map (mem, &map, (GST_MAP_READ | GST_MAP_D3D11))) {
|
||||
GST_ERROR_OBJECT (self, "cannot map d3d11 memory");
|
||||
return GST_FLOW_ERROR;
|
||||
}
|
||||
|
||||
gst_memory_unmap (mem, &map);
|
||||
}
|
||||
|
||||
if (gst_buffer_n_memory (buf) == 1 && self->have_video_processor &&
|
||||
gst_d3d11_video_processor_check_bind_flags_for_input_view
|
||||
(dmem->desc.BindFlags)) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!gst_d3d11_memory_ensure_shader_resource_view (dmem)) {
|
||||
GST_LOG_OBJECT (sink,
|
||||
"shader resource view is unavailable, need fallback");
|
||||
render_buf = NULL;
|
||||
/* keep run loop in order to upload staging memory to device memory */
|
||||
}
|
||||
}
|
||||
|
||||
if (!render_buf) {
|
||||
if (!self->fallback_pool ||
|
||||
!gst_buffer_pool_set_active (self->fallback_pool, TRUE) ||
|
||||
gst_buffer_pool_acquire_buffer (self->fallback_pool, &render_buf,
|
||||
NULL) != GST_FLOW_OK) {
|
||||
GST_ERROR_OBJECT (self, "fallback pool is unavailable");
|
||||
if (!gst_d3d11_buffer_can_access_device (buf, device_handle)) {
|
||||
GST_LOG_OBJECT (self, "Need fallback buffer");
|
||||
|
||||
if (!gst_d3d11_video_sink_get_fallback_buffer (self, buf, &fallback_buf,
|
||||
FALSE)) {
|
||||
return GST_FLOW_ERROR;
|
||||
}
|
||||
} else {
|
||||
gboolean direct_rendering = FALSE;
|
||||
|
||||
for (i = 0; i < gst_buffer_n_memory (render_buf); i++) {
|
||||
GstD3D11Memory *dmem;
|
||||
/* Check if we can use video processor for conversion */
|
||||
if (gst_buffer_n_memory (buf) == 1 && self->have_video_processor) {
|
||||
GstD3D11Memory *mem = (GstD3D11Memory *) gst_buffer_peek_memory (buf, 0);
|
||||
D3D11_TEXTURE2D_DESC desc;
|
||||
|
||||
dmem = (GstD3D11Memory *) gst_buffer_peek_memory (render_buf, i);
|
||||
if (!gst_d3d11_memory_ensure_shader_resource_view (dmem)) {
|
||||
GST_ERROR_OBJECT (self, "fallback shader resource view is unavailable");
|
||||
gst_buffer_unref (render_buf);
|
||||
|
||||
return GST_FLOW_ERROR;
|
||||
gst_d3d11_memory_get_texture_desc (mem, &desc);
|
||||
if ((desc.BindFlags & D3D11_BIND_DECODER) == D3D11_BIND_DECODER) {
|
||||
GST_TRACE_OBJECT (self,
|
||||
"Got VideoProcessor compatible texture, do direct rendering");
|
||||
direct_rendering = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (do_device_copy) {
|
||||
if (!gst_d3d11_video_sink_copy_d3d11_to_d3d11 (self, buf, render_buf)) {
|
||||
GST_ERROR_OBJECT (self, "cannot copy frame");
|
||||
gst_buffer_unref (render_buf);
|
||||
|
||||
return GST_FLOW_ERROR;
|
||||
/* Or, SRV should be available */
|
||||
if (!direct_rendering) {
|
||||
if (gst_d3d11_buffer_get_shader_resource_view (buf, view)) {
|
||||
GST_TRACE_OBJECT (self, "SRV is available, do direct rendering");
|
||||
direct_rendering = TRUE;
|
||||
}
|
||||
} else if (!gst_d3d11_video_sink_upload_frame (self, buf, render_buf)) {
|
||||
GST_ERROR_OBJECT (self, "cannot upload frame");
|
||||
gst_buffer_unref (render_buf);
|
||||
}
|
||||
|
||||
if (!direct_rendering &&
|
||||
!gst_d3d11_video_sink_get_fallback_buffer (self, buf, &fallback_buf,
|
||||
TRUE)) {
|
||||
return GST_FLOW_ERROR;
|
||||
}
|
||||
|
||||
need_unref = TRUE;
|
||||
}
|
||||
|
||||
gst_d3d11_window_show (self->window);
|
||||
|
@ -976,9 +928,9 @@ gst_d3d11_video_sink_show_frame (GstVideoSink * sink, GstBuffer * buf)
|
|||
if (self->render_stats)
|
||||
stats = gst_base_sink_get_stats (GST_BASE_SINK_CAST (self));
|
||||
|
||||
ret = gst_d3d11_window_render (self->window, render_buf, &rect, stats);
|
||||
if (need_unref)
|
||||
gst_buffer_unref (render_buf);
|
||||
ret = gst_d3d11_window_render (self->window,
|
||||
fallback_buf ? fallback_buf : buf, &rect, stats);
|
||||
gst_clear_buffer (&fallback_buf);
|
||||
|
||||
if (ret == GST_D3D11_WINDOW_FLOW_CLOSED) {
|
||||
GST_ELEMENT_ERROR (self, RESOURCE, NOT_FOUND,
|
||||
|
|
|
@ -341,7 +341,6 @@ gst_d3d11_vp8_dec_new_picture (GstVp8Decoder * decoder,
|
|||
{
|
||||
GstD3D11Vp8Dec *self = GST_D3D11_VP8_DEC (decoder);
|
||||
GstBuffer *view_buffer;
|
||||
GstD3D11Memory *mem;
|
||||
|
||||
view_buffer = gst_d3d11_decoder_get_output_view_buffer (self->d3d11_decoder);
|
||||
if (!view_buffer) {
|
||||
|
@ -349,10 +348,7 @@ gst_d3d11_vp8_dec_new_picture (GstVp8Decoder * decoder,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
mem = (GstD3D11Memory *) gst_buffer_peek_memory (view_buffer, 0);
|
||||
|
||||
GST_LOG_OBJECT (self, "New output view buffer %" GST_PTR_FORMAT " (index %d)",
|
||||
view_buffer, mem->subresource_index);
|
||||
GST_LOG_OBJECT (self, "New output view buffer %" GST_PTR_FORMAT, view_buffer);
|
||||
|
||||
gst_vp8_picture_set_user_data (picture,
|
||||
view_buffer, (GDestroyNotify) gst_buffer_unref);
|
||||
|
|
|
@ -413,7 +413,6 @@ gst_d3d11_vp9_dec_new_picture (GstVp9Decoder * decoder,
|
|||
{
|
||||
GstD3D11Vp9Dec *self = GST_D3D11_VP9_DEC (decoder);
|
||||
GstBuffer *view_buffer;
|
||||
GstD3D11Memory *mem;
|
||||
|
||||
view_buffer = gst_d3d11_decoder_get_output_view_buffer (self->d3d11_decoder);
|
||||
if (!view_buffer) {
|
||||
|
@ -421,10 +420,7 @@ gst_d3d11_vp9_dec_new_picture (GstVp9Decoder * decoder,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
mem = (GstD3D11Memory *) gst_buffer_peek_memory (view_buffer, 0);
|
||||
|
||||
GST_LOG_OBJECT (self, "New output view buffer %" GST_PTR_FORMAT " (index %d)",
|
||||
view_buffer, mem->subresource_index);
|
||||
GST_LOG_OBJECT (self, "New output view buffer %" GST_PTR_FORMAT, view_buffer);
|
||||
|
||||
gst_vp9_picture_set_user_data (picture,
|
||||
view_buffer, (GDestroyNotify) gst_buffer_unref);
|
||||
|
@ -440,7 +436,6 @@ gst_d3d11_vp9_dec_duplicate_picture (GstVp9Decoder * decoder,
|
|||
{
|
||||
GstD3D11Vp9Dec *self = GST_D3D11_VP9_DEC (decoder);
|
||||
GstBuffer *view_buffer;
|
||||
GstD3D11Memory *mem;
|
||||
GstVp9Picture *new_picture;
|
||||
|
||||
view_buffer = gst_vp9_picture_get_user_data (picture);
|
||||
|
@ -453,10 +448,8 @@ gst_d3d11_vp9_dec_duplicate_picture (GstVp9Decoder * decoder,
|
|||
new_picture = gst_vp9_picture_new ();
|
||||
new_picture->frame_hdr = picture->frame_hdr;
|
||||
|
||||
mem = (GstD3D11Memory *) gst_buffer_peek_memory (view_buffer, 0);
|
||||
|
||||
GST_LOG_OBJECT (self, "Duplicate output with buffer %" GST_PTR_FORMAT
|
||||
" (index %d)", view_buffer, mem->subresource_index);
|
||||
GST_LOG_OBJECT (self, "Duplicate output with buffer %" GST_PTR_FORMAT,
|
||||
view_buffer);
|
||||
|
||||
gst_vp9_picture_set_user_data (new_picture,
|
||||
gst_buffer_ref (view_buffer), (GDestroyNotify) gst_buffer_unref);
|
||||
|
|
|
@ -1008,6 +1008,7 @@ gst_d3d11_window_buffer_ensure_processor_input (GstD3D11Window * self,
|
|||
GstBuffer * buffer, ID3D11VideoProcessorInputView ** in_view)
|
||||
{
|
||||
GstD3D11Memory *mem;
|
||||
ID3D11VideoProcessorInputView *piv;
|
||||
|
||||
if (!self->processor)
|
||||
return FALSE;
|
||||
|
@ -1016,18 +1017,13 @@ gst_d3d11_window_buffer_ensure_processor_input (GstD3D11Window * self,
|
|||
return FALSE;
|
||||
|
||||
mem = (GstD3D11Memory *) gst_buffer_peek_memory (buffer, 0);
|
||||
|
||||
if (!gst_d3d11_video_processor_check_bind_flags_for_input_view
|
||||
(mem->desc.BindFlags)) {
|
||||
piv = gst_d3d11_video_processor_get_input_view (self->processor, mem);
|
||||
if (!piv) {
|
||||
GST_LOG_OBJECT (self, "Failed to get processor input view");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!gst_d3d11_video_processor_ensure_input_view (self->processor, mem)) {
|
||||
GST_LOG_OBJECT (self, "Failed to create processor input view");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*in_view = mem->processor_input_view;
|
||||
*in_view = piv;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -1096,19 +1092,25 @@ gst_d3d111_window_present (GstD3D11Window * self, GstBuffer * buffer,
|
|||
}
|
||||
|
||||
if (self->cached_buffer) {
|
||||
GstMapInfo infos[GST_VIDEO_MAX_PLANES];
|
||||
ID3D11ShaderResourceView *srv[GST_VIDEO_MAX_PLANES];
|
||||
ID3D11VideoProcessorInputView *piv = NULL;
|
||||
guint i, j, k;
|
||||
ID3D11Device *device_handle =
|
||||
gst_d3d11_device_get_device_handle (self->device);
|
||||
|
||||
if (!gst_d3d11_window_buffer_ensure_processor_input (self,
|
||||
self->cached_buffer, &piv)) {
|
||||
for (i = 0, j = 0; i < gst_buffer_n_memory (self->cached_buffer); i++) {
|
||||
GstD3D11Memory *mem =
|
||||
(GstD3D11Memory *) gst_buffer_peek_memory (self->cached_buffer, i);
|
||||
for (k = 0; k < mem->num_shader_resource_views; k++) {
|
||||
srv[j] = mem->shader_resource_view[k];
|
||||
j++;
|
||||
}
|
||||
/* Map memory in any case so that we can upload pending stage texture */
|
||||
if (!gst_d3d11_buffer_map (self->cached_buffer, device_handle,
|
||||
infos, GST_MAP_READ)) {
|
||||
GST_ERROR_OBJECT (self, "Couldn't map buffer");
|
||||
|
||||
return GST_FLOW_ERROR;
|
||||
}
|
||||
|
||||
if (!gst_d3d11_buffer_get_shader_resource_view (self->cached_buffer, srv)) {
|
||||
if (!gst_d3d11_window_buffer_ensure_processor_input (self,
|
||||
self->cached_buffer, &piv)) {
|
||||
GST_ERROR_OBJECT (self, "Input texture cannot be used for converter");
|
||||
return GST_FLOW_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1131,7 +1133,8 @@ gst_d3d111_window_present (GstD3D11Window * self, GstBuffer * buffer,
|
|||
if (!gst_d3d11_video_processor_render_unlocked (self->processor,
|
||||
&self->input_rect, piv, &self->render_rect, self->pov)) {
|
||||
GST_ERROR_OBJECT (self, "Couldn't render to backbuffer using processor");
|
||||
return GST_FLOW_ERROR;
|
||||
ret = GST_FLOW_ERROR;
|
||||
goto unmap_and_out;
|
||||
} else {
|
||||
GST_TRACE_OBJECT (self, "Rendered using processor");
|
||||
}
|
||||
|
@ -1139,7 +1142,8 @@ gst_d3d111_window_present (GstD3D11Window * self, GstBuffer * buffer,
|
|||
if (!gst_d3d11_color_converter_convert_unlocked (self->converter,
|
||||
srv, &self->rtv, NULL, NULL)) {
|
||||
GST_ERROR_OBJECT (self, "Couldn't render to backbuffer using converter");
|
||||
return GST_FLOW_ERROR;
|
||||
ret = GST_FLOW_ERROR;
|
||||
goto unmap_and_out;
|
||||
} else {
|
||||
GST_TRACE_OBJECT (self, "Rendered using converter");
|
||||
}
|
||||
|
@ -1161,6 +1165,9 @@ gst_d3d111_window_present (GstD3D11Window * self, GstBuffer * buffer,
|
|||
ret = klass->present (self, present_flags);
|
||||
|
||||
self->first_present = FALSE;
|
||||
|
||||
unmap_and_out:
|
||||
gst_d3d11_buffer_unmap (self->cached_buffer, infos);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
Loading…
Reference in a new issue