mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-23 10:11:08 +00:00
d3d11decoder: Add helper methods for negotiation and decide_allocation
The implementation for all codecs is almost the same. No need to duplicate code. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/1079>
This commit is contained in:
parent
9524e6adec
commit
5965b6ef85
5 changed files with 183 additions and 343 deletions
|
@ -1429,6 +1429,157 @@ do_process:
|
|||
need_convert, decoder_buffer, output);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_d3d11_decoder_negotiate (GstVideoDecoder * decoder,
|
||||
GstVideoCodecState * input_state, GstVideoFormat format,
|
||||
guint width, guint height, GstVideoCodecState ** output_state,
|
||||
gboolean * downstream_supports_d3d11)
|
||||
{
|
||||
GstCaps *peer_caps;
|
||||
GstVideoCodecState *state;
|
||||
|
||||
g_return_val_if_fail (GST_IS_VIDEO_DECODER (decoder), FALSE);
|
||||
g_return_val_if_fail (input_state != NULL, FALSE);
|
||||
g_return_val_if_fail (format != GST_VIDEO_FORMAT_UNKNOWN, FALSE);
|
||||
g_return_val_if_fail (width > 0, FALSE);
|
||||
g_return_val_if_fail (height > 0, FALSE);
|
||||
g_return_val_if_fail (output_state != NULL, FALSE);
|
||||
g_return_val_if_fail (downstream_supports_d3d11 != NULL, FALSE);
|
||||
|
||||
state = gst_video_decoder_set_output_state (decoder,
|
||||
format, width, height, input_state);
|
||||
state->caps = gst_video_info_to_caps (&state->info);
|
||||
|
||||
if (*output_state)
|
||||
gst_video_codec_state_unref (*output_state);
|
||||
*output_state = state;
|
||||
|
||||
peer_caps = gst_pad_get_allowed_caps (GST_VIDEO_DECODER_SRC_PAD (decoder));
|
||||
GST_DEBUG_OBJECT (decoder, "Allowed caps %" GST_PTR_FORMAT, peer_caps);
|
||||
|
||||
*downstream_supports_d3d11 = FALSE;
|
||||
|
||||
if (!peer_caps || gst_caps_is_any (peer_caps)) {
|
||||
GST_DEBUG_OBJECT (decoder,
|
||||
"cannot determine output format, use system memory");
|
||||
} else {
|
||||
GstCapsFeatures *features;
|
||||
guint size = gst_caps_get_size (peer_caps);
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
features = gst_caps_get_features (peer_caps, i);
|
||||
if (features && gst_caps_features_contains (features,
|
||||
GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY)) {
|
||||
GST_DEBUG_OBJECT (decoder, "found D3D11 memory feature");
|
||||
gst_caps_set_features (state->caps, 0,
|
||||
gst_caps_features_new (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY, NULL));
|
||||
|
||||
*downstream_supports_d3d11 = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
gst_clear_caps (&peer_caps);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_d3d11_decoder_decide_allocation (GstVideoDecoder * decoder,
|
||||
GstQuery * query, GstD3D11Device * device, GstD3D11Codec codec,
|
||||
gboolean use_d3d11_pool)
|
||||
{
|
||||
GstCaps *outcaps;
|
||||
GstBufferPool *pool = NULL;
|
||||
guint n, size, min, max;
|
||||
GstVideoInfo vinfo = { 0, };
|
||||
GstStructure *config;
|
||||
GstD3D11AllocationParams *d3d11_params;
|
||||
|
||||
g_return_val_if_fail (GST_IS_VIDEO_DECODER (decoder), FALSE);
|
||||
g_return_val_if_fail (query != NULL, FALSE);
|
||||
g_return_val_if_fail (GST_IS_D3D11_DEVICE (device), FALSE);
|
||||
g_return_val_if_fail (codec > GST_D3D11_CODEC_NONE &&
|
||||
codec < GST_D3D11_CODEC_LAST, FALSE);
|
||||
|
||||
gst_query_parse_allocation (query, &outcaps, NULL);
|
||||
|
||||
if (!outcaps) {
|
||||
GST_DEBUG_OBJECT (decoder, "No output caps");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gst_video_info_from_caps (&vinfo, outcaps);
|
||||
n = gst_query_get_n_allocation_pools (query);
|
||||
if (n > 0)
|
||||
gst_query_parse_nth_allocation_pool (query, 0, &pool, &size, &min, &max);
|
||||
|
||||
/* create our own pool */
|
||||
if (pool && (use_d3d11_pool && !GST_D3D11_BUFFER_POOL (pool))) {
|
||||
gst_object_unref (pool);
|
||||
pool = NULL;
|
||||
}
|
||||
|
||||
if (!pool) {
|
||||
if (use_d3d11_pool)
|
||||
pool = gst_d3d11_buffer_pool_new (device);
|
||||
else
|
||||
pool = gst_video_buffer_pool_new ();
|
||||
|
||||
min = max = 0;
|
||||
size = (guint) vinfo.size;
|
||||
}
|
||||
|
||||
config = gst_buffer_pool_get_config (pool);
|
||||
gst_buffer_pool_config_set_params (config, outcaps, size, min, max);
|
||||
gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META);
|
||||
|
||||
if (use_d3d11_pool) {
|
||||
GstVideoAlignment align;
|
||||
gint width, height;
|
||||
|
||||
gst_video_alignment_reset (&align);
|
||||
|
||||
d3d11_params = gst_buffer_pool_config_get_d3d11_allocation_params (config);
|
||||
if (!d3d11_params)
|
||||
d3d11_params = gst_d3d11_allocation_params_new (device, &vinfo, 0, 0);
|
||||
|
||||
width = GST_VIDEO_INFO_WIDTH (&vinfo);
|
||||
height = GST_VIDEO_INFO_HEIGHT (&vinfo);
|
||||
|
||||
/* need alignment to copy decoder output texture to downstream texture */
|
||||
align.padding_right = GST_ROUND_UP_16 (width) - width;
|
||||
align.padding_bottom = GST_ROUND_UP_16 (height) - height;
|
||||
if (!gst_d3d11_allocation_params_alignment (d3d11_params, &align)) {
|
||||
GST_ERROR_OBJECT (decoder, "Cannot set alignment");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (codec == GST_D3D11_CODEC_VP9) {
|
||||
/* Needs render target bind flag so that it can be used for
|
||||
* output of shader pipeline if internal resizing is required */
|
||||
d3d11_params->desc[0].BindFlags |= D3D11_BIND_RENDER_TARGET;
|
||||
}
|
||||
|
||||
gst_buffer_pool_config_set_d3d11_allocation_params (config, d3d11_params);
|
||||
gst_d3d11_allocation_params_free (d3d11_params);
|
||||
}
|
||||
|
||||
gst_buffer_pool_set_config (pool, config);
|
||||
if (use_d3d11_pool)
|
||||
size = GST_D3D11_BUFFER_POOL (pool)->buffer_size;
|
||||
|
||||
if (n > 0)
|
||||
gst_query_set_nth_allocation_pool (query, 0, pool, size, min, max);
|
||||
else
|
||||
gst_query_add_allocation_pool (query, pool, size, min, max);
|
||||
gst_object_unref (pool);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/* Keep sync with chromium and keep in sorted order.
|
||||
* See supported_profile_helpers.cc in chromium */
|
||||
static const guint legacy_amd_list[] = {
|
||||
|
|
|
@ -137,6 +137,20 @@ gboolean gst_d3d11_decoder_process_output (GstD3D11Decoder * decod
|
|||
GstBuffer * decoder_buffer,
|
||||
GstBuffer * output);
|
||||
|
||||
gboolean gst_d3d11_decoder_negotiate (GstVideoDecoder * decoder,
|
||||
GstVideoCodecState * input_state,
|
||||
GstVideoFormat format,
|
||||
guint width,
|
||||
guint height,
|
||||
GstVideoCodecState ** output_state,
|
||||
gboolean * downstream_supports_d3d11);
|
||||
|
||||
gboolean gst_d3d11_decoder_decide_allocation (GstVideoDecoder * decoder,
|
||||
GstQuery * query,
|
||||
GstD3D11Device * device,
|
||||
GstD3D11Codec codec,
|
||||
gboolean use_d3d11_pool);
|
||||
|
||||
/* Utils for class registration */
|
||||
gboolean gst_d3d11_decoder_util_is_legacy_device (GstD3D11Device * device);
|
||||
|
||||
|
|
|
@ -330,46 +330,11 @@ gst_d3d11_h264_dec_negotiate (GstVideoDecoder * decoder)
|
|||
{
|
||||
GstD3D11H264Dec *self = GST_D3D11_H264_DEC (decoder);
|
||||
GstH264Decoder *h264dec = GST_H264_DECODER (decoder);
|
||||
GstCaps *peer_caps;
|
||||
|
||||
GST_DEBUG_OBJECT (self, "negotiate");
|
||||
|
||||
if (self->output_state)
|
||||
gst_video_codec_state_unref (self->output_state);
|
||||
|
||||
self->output_state =
|
||||
gst_video_decoder_set_output_state (GST_VIDEO_DECODER (self),
|
||||
self->out_format, self->width, self->height, h264dec->input_state);
|
||||
|
||||
self->output_state->caps = gst_video_info_to_caps (&self->output_state->info);
|
||||
|
||||
peer_caps = gst_pad_get_allowed_caps (GST_VIDEO_DECODER_SRC_PAD (self));
|
||||
GST_DEBUG_OBJECT (self, "Allowed caps %" GST_PTR_FORMAT, peer_caps);
|
||||
|
||||
self->use_d3d11_output = FALSE;
|
||||
|
||||
if (!peer_caps || gst_caps_is_any (peer_caps)) {
|
||||
GST_DEBUG_OBJECT (self,
|
||||
"cannot determine output format, use system memory");
|
||||
} else {
|
||||
GstCapsFeatures *features;
|
||||
guint size = gst_caps_get_size (peer_caps);
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
features = gst_caps_get_features (peer_caps, i);
|
||||
if (features && gst_caps_features_contains (features,
|
||||
GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY)) {
|
||||
GST_DEBUG_OBJECT (self, "found D3D11 memory feature");
|
||||
gst_caps_set_features (self->output_state->caps, 0,
|
||||
gst_caps_features_new (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY, NULL));
|
||||
|
||||
self->use_d3d11_output = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
gst_clear_caps (&peer_caps);
|
||||
if (!gst_d3d11_decoder_negotiate (decoder, h264dec->input_state,
|
||||
self->out_format, self->width, self->height, &self->output_state,
|
||||
&self->use_d3d11_output))
|
||||
return FALSE;
|
||||
|
||||
return GST_VIDEO_DECODER_CLASS (parent_class)->negotiate (decoder);
|
||||
}
|
||||
|
@ -379,82 +344,10 @@ gst_d3d11_h264_dec_decide_allocation (GstVideoDecoder * decoder,
|
|||
GstQuery * query)
|
||||
{
|
||||
GstD3D11H264Dec *self = GST_D3D11_H264_DEC (decoder);
|
||||
GstCaps *outcaps;
|
||||
GstBufferPool *pool = NULL;
|
||||
guint n, size, min, max;
|
||||
GstVideoInfo vinfo = { 0, };
|
||||
GstStructure *config;
|
||||
GstD3D11AllocationParams *d3d11_params;
|
||||
|
||||
GST_DEBUG_OBJECT (self, "decide allocation");
|
||||
|
||||
gst_query_parse_allocation (query, &outcaps, NULL);
|
||||
|
||||
if (!outcaps) {
|
||||
GST_DEBUG_OBJECT (self, "No output caps");
|
||||
if (!gst_d3d11_decoder_decide_allocation (decoder, query, self->device,
|
||||
GST_D3D11_CODEC_H264, self->use_d3d11_output))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gst_video_info_from_caps (&vinfo, outcaps);
|
||||
n = gst_query_get_n_allocation_pools (query);
|
||||
if (n > 0)
|
||||
gst_query_parse_nth_allocation_pool (query, 0, &pool, &size, &min, &max);
|
||||
|
||||
/* create our own pool */
|
||||
if (pool && (self->use_d3d11_output && !GST_D3D11_BUFFER_POOL (pool))) {
|
||||
gst_object_unref (pool);
|
||||
pool = NULL;
|
||||
}
|
||||
|
||||
if (!pool) {
|
||||
if (self->use_d3d11_output)
|
||||
pool = gst_d3d11_buffer_pool_new (self->device);
|
||||
else
|
||||
pool = gst_video_buffer_pool_new ();
|
||||
|
||||
min = max = 0;
|
||||
size = (guint) vinfo.size;
|
||||
}
|
||||
|
||||
config = gst_buffer_pool_get_config (pool);
|
||||
gst_buffer_pool_config_set_params (config, outcaps, size, min, max);
|
||||
gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META);
|
||||
|
||||
if (self->use_d3d11_output) {
|
||||
GstVideoAlignment align;
|
||||
gint width, height;
|
||||
|
||||
gst_video_alignment_reset (&align);
|
||||
|
||||
d3d11_params = gst_buffer_pool_config_get_d3d11_allocation_params (config);
|
||||
if (!d3d11_params)
|
||||
d3d11_params = gst_d3d11_allocation_params_new (self->device,
|
||||
&vinfo, 0, 0);
|
||||
|
||||
width = GST_VIDEO_INFO_WIDTH (&vinfo);
|
||||
height = GST_VIDEO_INFO_HEIGHT (&vinfo);
|
||||
|
||||
/* need alignment to copy decoder output texture to downstream texture */
|
||||
align.padding_right = GST_ROUND_UP_16 (width) - width;
|
||||
align.padding_bottom = GST_ROUND_UP_16 (height) - height;
|
||||
if (!gst_d3d11_allocation_params_alignment (d3d11_params, &align)) {
|
||||
GST_ERROR_OBJECT (self, "Cannot set alignment");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gst_buffer_pool_config_set_d3d11_allocation_params (config, d3d11_params);
|
||||
gst_d3d11_allocation_params_free (d3d11_params);
|
||||
}
|
||||
|
||||
gst_buffer_pool_set_config (pool, config);
|
||||
if (self->use_d3d11_output)
|
||||
size = GST_D3D11_BUFFER_POOL (pool)->buffer_size;
|
||||
|
||||
if (n > 0)
|
||||
gst_query_set_nth_allocation_pool (query, 0, pool, size, min, max);
|
||||
else
|
||||
gst_query_add_allocation_pool (query, pool, size, min, max);
|
||||
gst_object_unref (pool);
|
||||
|
||||
return GST_VIDEO_DECODER_CLASS (parent_class)->decide_allocation
|
||||
(decoder, query);
|
||||
|
|
|
@ -299,46 +299,11 @@ gst_d3d11_h265_dec_negotiate (GstVideoDecoder * decoder)
|
|||
{
|
||||
GstD3D11H265Dec *self = GST_D3D11_H265_DEC (decoder);
|
||||
GstH265Decoder *h265dec = GST_H265_DECODER (decoder);
|
||||
GstCaps *peer_caps;
|
||||
|
||||
GST_DEBUG_OBJECT (self, "negotiate");
|
||||
|
||||
if (self->output_state)
|
||||
gst_video_codec_state_unref (self->output_state);
|
||||
|
||||
self->output_state =
|
||||
gst_video_decoder_set_output_state (GST_VIDEO_DECODER (self),
|
||||
self->out_format, self->width, self->height, h265dec->input_state);
|
||||
|
||||
self->output_state->caps = gst_video_info_to_caps (&self->output_state->info);
|
||||
|
||||
peer_caps = gst_pad_get_allowed_caps (GST_VIDEO_DECODER_SRC_PAD (self));
|
||||
GST_DEBUG_OBJECT (self, "Allowed caps %" GST_PTR_FORMAT, peer_caps);
|
||||
|
||||
self->use_d3d11_output = FALSE;
|
||||
|
||||
if (!peer_caps || gst_caps_is_any (peer_caps)) {
|
||||
GST_DEBUG_OBJECT (self,
|
||||
"cannot determine output format, use system memory");
|
||||
} else {
|
||||
GstCapsFeatures *features;
|
||||
guint size = gst_caps_get_size (peer_caps);
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
features = gst_caps_get_features (peer_caps, i);
|
||||
if (features && gst_caps_features_contains (features,
|
||||
GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY)) {
|
||||
GST_DEBUG_OBJECT (self, "found D3D11 memory feature");
|
||||
gst_caps_set_features (self->output_state->caps, 0,
|
||||
gst_caps_features_new (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY, NULL));
|
||||
|
||||
self->use_d3d11_output = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
gst_clear_caps (&peer_caps);
|
||||
if (!gst_d3d11_decoder_negotiate (decoder, h265dec->input_state,
|
||||
self->out_format, self->width, self->height, &self->output_state,
|
||||
&self->use_d3d11_output))
|
||||
return FALSE;
|
||||
|
||||
return GST_VIDEO_DECODER_CLASS (parent_class)->negotiate (decoder);
|
||||
}
|
||||
|
@ -348,82 +313,10 @@ gst_d3d11_h265_dec_decide_allocation (GstVideoDecoder * decoder,
|
|||
GstQuery * query)
|
||||
{
|
||||
GstD3D11H265Dec *self = GST_D3D11_H265_DEC (decoder);
|
||||
GstCaps *outcaps;
|
||||
GstBufferPool *pool = NULL;
|
||||
guint n, size, min, max;
|
||||
GstVideoInfo vinfo = { 0, };
|
||||
GstStructure *config;
|
||||
GstD3D11AllocationParams *d3d11_params;
|
||||
|
||||
GST_DEBUG_OBJECT (self, "decide allocation");
|
||||
|
||||
gst_query_parse_allocation (query, &outcaps, NULL);
|
||||
|
||||
if (!outcaps) {
|
||||
GST_DEBUG_OBJECT (self, "No output caps");
|
||||
if (!gst_d3d11_decoder_decide_allocation (decoder, query, self->device,
|
||||
GST_D3D11_CODEC_H265, self->use_d3d11_output))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gst_video_info_from_caps (&vinfo, outcaps);
|
||||
n = gst_query_get_n_allocation_pools (query);
|
||||
if (n > 0)
|
||||
gst_query_parse_nth_allocation_pool (query, 0, &pool, &size, &min, &max);
|
||||
|
||||
/* create our own pool */
|
||||
if (pool && (self->use_d3d11_output && !GST_D3D11_BUFFER_POOL (pool))) {
|
||||
gst_object_unref (pool);
|
||||
pool = NULL;
|
||||
}
|
||||
|
||||
if (!pool) {
|
||||
if (self->use_d3d11_output)
|
||||
pool = gst_d3d11_buffer_pool_new (self->device);
|
||||
else
|
||||
pool = gst_video_buffer_pool_new ();
|
||||
|
||||
min = max = 0;
|
||||
size = (guint) vinfo.size;
|
||||
}
|
||||
|
||||
config = gst_buffer_pool_get_config (pool);
|
||||
gst_buffer_pool_config_set_params (config, outcaps, size, min, max);
|
||||
gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META);
|
||||
|
||||
if (self->use_d3d11_output) {
|
||||
GstVideoAlignment align;
|
||||
gint width, height;
|
||||
|
||||
gst_video_alignment_reset (&align);
|
||||
|
||||
d3d11_params = gst_buffer_pool_config_get_d3d11_allocation_params (config);
|
||||
if (!d3d11_params)
|
||||
d3d11_params = gst_d3d11_allocation_params_new (self->device,
|
||||
&vinfo, 0, 0);
|
||||
|
||||
width = GST_VIDEO_INFO_WIDTH (&vinfo);
|
||||
height = GST_VIDEO_INFO_HEIGHT (&vinfo);
|
||||
|
||||
/* need alignment to copy decoder output texture to downstream texture */
|
||||
align.padding_right = GST_ROUND_UP_16 (width) - width;
|
||||
align.padding_bottom = GST_ROUND_UP_16 (height) - height;
|
||||
if (!gst_d3d11_allocation_params_alignment (d3d11_params, &align)) {
|
||||
GST_ERROR_OBJECT (self, "Cannot set alignment");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gst_buffer_pool_config_set_d3d11_allocation_params (config, d3d11_params);
|
||||
gst_d3d11_allocation_params_free (d3d11_params);
|
||||
}
|
||||
|
||||
gst_buffer_pool_set_config (pool, config);
|
||||
if (self->use_d3d11_output)
|
||||
size = GST_D3D11_BUFFER_POOL (pool)->buffer_size;
|
||||
|
||||
if (n > 0)
|
||||
gst_query_set_nth_allocation_pool (query, 0, pool, size, min, max);
|
||||
else
|
||||
gst_query_add_allocation_pool (query, pool, size, min, max);
|
||||
gst_object_unref (pool);
|
||||
|
||||
return GST_VIDEO_DECODER_CLASS (parent_class)->decide_allocation
|
||||
(decoder, query);
|
||||
|
|
|
@ -298,46 +298,11 @@ gst_d3d11_vp9_dec_negotiate (GstVideoDecoder * decoder)
|
|||
{
|
||||
GstD3D11Vp9Dec *self = GST_D3D11_VP9_DEC (decoder);
|
||||
GstVp9Decoder *vp9dec = GST_VP9_DECODER (decoder);
|
||||
GstCaps *peer_caps;
|
||||
|
||||
GST_DEBUG_OBJECT (self, "negotiate");
|
||||
|
||||
if (self->output_state)
|
||||
gst_video_codec_state_unref (self->output_state);
|
||||
|
||||
self->output_state =
|
||||
gst_video_decoder_set_output_state (GST_VIDEO_DECODER (self),
|
||||
self->out_format, self->width, self->height, vp9dec->input_state);
|
||||
|
||||
self->output_state->caps = gst_video_info_to_caps (&self->output_state->info);
|
||||
|
||||
peer_caps = gst_pad_get_allowed_caps (GST_VIDEO_DECODER_SRC_PAD (self));
|
||||
GST_DEBUG_OBJECT (self, "Allowed caps %" GST_PTR_FORMAT, peer_caps);
|
||||
|
||||
self->use_d3d11_output = FALSE;
|
||||
|
||||
if (!peer_caps || gst_caps_is_any (peer_caps)) {
|
||||
GST_DEBUG_OBJECT (self,
|
||||
"cannot determine output format, use system memory");
|
||||
} else {
|
||||
GstCapsFeatures *features;
|
||||
guint size = gst_caps_get_size (peer_caps);
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
features = gst_caps_get_features (peer_caps, i);
|
||||
if (features && gst_caps_features_contains (features,
|
||||
GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY)) {
|
||||
GST_DEBUG_OBJECT (self, "found D3D11 memory feature");
|
||||
gst_caps_set_features (self->output_state->caps, 0,
|
||||
gst_caps_features_new (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY, NULL));
|
||||
|
||||
self->use_d3d11_output = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
gst_clear_caps (&peer_caps);
|
||||
if (!gst_d3d11_decoder_negotiate (decoder, vp9dec->input_state,
|
||||
self->out_format, self->width, self->height, &self->output_state,
|
||||
&self->use_d3d11_output))
|
||||
return FALSE;
|
||||
|
||||
return GST_VIDEO_DECODER_CLASS (parent_class)->negotiate (decoder);
|
||||
}
|
||||
|
@ -347,86 +312,10 @@ gst_d3d11_vp9_dec_decide_allocation (GstVideoDecoder * decoder,
|
|||
GstQuery * query)
|
||||
{
|
||||
GstD3D11Vp9Dec *self = GST_D3D11_VP9_DEC (decoder);
|
||||
GstCaps *outcaps;
|
||||
GstBufferPool *pool = NULL;
|
||||
guint n, size, min, max;
|
||||
GstVideoInfo vinfo = { 0, };
|
||||
GstStructure *config;
|
||||
GstD3D11AllocationParams *d3d11_params;
|
||||
|
||||
GST_DEBUG_OBJECT (self, "decide allocation");
|
||||
|
||||
gst_query_parse_allocation (query, &outcaps, NULL);
|
||||
|
||||
if (!outcaps) {
|
||||
GST_DEBUG_OBJECT (self, "No output caps");
|
||||
if (!gst_d3d11_decoder_decide_allocation (decoder, query, self->device,
|
||||
GST_D3D11_CODEC_VP9, self->use_d3d11_output))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gst_video_info_from_caps (&vinfo, outcaps);
|
||||
n = gst_query_get_n_allocation_pools (query);
|
||||
if (n > 0)
|
||||
gst_query_parse_nth_allocation_pool (query, 0, &pool, &size, &min, &max);
|
||||
|
||||
/* create our own pool */
|
||||
if (pool && (self->use_d3d11_output && !GST_D3D11_BUFFER_POOL (pool))) {
|
||||
gst_object_unref (pool);
|
||||
pool = NULL;
|
||||
}
|
||||
|
||||
if (!pool) {
|
||||
if (self->use_d3d11_output)
|
||||
pool = gst_d3d11_buffer_pool_new (self->device);
|
||||
else
|
||||
pool = gst_video_buffer_pool_new ();
|
||||
|
||||
min = max = 0;
|
||||
size = (guint) vinfo.size;
|
||||
}
|
||||
|
||||
config = gst_buffer_pool_get_config (pool);
|
||||
gst_buffer_pool_config_set_params (config, outcaps, size, min, max);
|
||||
gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META);
|
||||
|
||||
if (self->use_d3d11_output) {
|
||||
GstVideoAlignment align;
|
||||
gint width, height;
|
||||
|
||||
gst_video_alignment_reset (&align);
|
||||
|
||||
d3d11_params = gst_buffer_pool_config_get_d3d11_allocation_params (config);
|
||||
if (!d3d11_params)
|
||||
d3d11_params = gst_d3d11_allocation_params_new (self->device,
|
||||
&vinfo, 0, 0);
|
||||
|
||||
width = GST_VIDEO_INFO_WIDTH (&vinfo);
|
||||
height = GST_VIDEO_INFO_HEIGHT (&vinfo);
|
||||
|
||||
/* need alignment to copy decoder output texture to downstream texture */
|
||||
align.padding_right = GST_ROUND_UP_16 (width) - width;
|
||||
align.padding_bottom = GST_ROUND_UP_16 (height) - height;
|
||||
if (!gst_d3d11_allocation_params_alignment (d3d11_params, &align)) {
|
||||
GST_ERROR_OBJECT (self, "Cannot set alignment");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Needs render target bind flag so that it can be used for
|
||||
* output of shader pipeline if internal resizing is required */
|
||||
d3d11_params->desc[0].BindFlags |= D3D11_BIND_RENDER_TARGET;
|
||||
|
||||
gst_buffer_pool_config_set_d3d11_allocation_params (config, d3d11_params);
|
||||
gst_d3d11_allocation_params_free (d3d11_params);
|
||||
}
|
||||
|
||||
gst_buffer_pool_set_config (pool, config);
|
||||
if (self->use_d3d11_output)
|
||||
size = GST_D3D11_BUFFER_POOL (pool)->buffer_size;
|
||||
|
||||
if (n > 0)
|
||||
gst_query_set_nth_allocation_pool (query, 0, pool, size, min, max);
|
||||
else
|
||||
gst_query_add_allocation_pool (query, pool, size, min, max);
|
||||
gst_object_unref (pool);
|
||||
|
||||
return GST_VIDEO_DECODER_CLASS (parent_class)->decide_allocation
|
||||
(decoder, query);
|
||||
|
|
Loading…
Reference in a new issue