summaryrefslogtreecommitdiff
path: root/sys/d3d11/gstd3d11decoder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sys/d3d11/gstd3d11decoder.cpp')
-rw-r--r--sys/d3d11/gstd3d11decoder.cpp348
1 files changed, 247 insertions, 101 deletions
diff --git a/sys/d3d11/gstd3d11decoder.cpp b/sys/d3d11/gstd3d11decoder.cpp
index a9f59e4ad..ce65b537f 100644
--- a/sys/d3d11/gstd3d11decoder.cpp
+++ b/sys/d3d11/gstd3d11decoder.cpp
@@ -61,8 +61,8 @@
#include <timeapi.h>
#endif
-GST_DEBUG_CATEGORY (d3d11_decoder_debug);
-#define GST_CAT_DEFAULT d3d11_decoder_debug
+GST_DEBUG_CATEGORY_EXTERN (gst_d3d11_decoder_debug);
+#define GST_CAT_DEFAULT gst_d3d11_decoder_debug
/* GUID might not be defined in MinGW header */
DEFINE_GUID (GST_GUID_D3D11_DECODER_PROFILE_H264_IDCT_FGT, 0x1b81be67, 0xa0c7,
@@ -146,7 +146,7 @@ struct _GstD3D11Decoder
GstVideoInfo info;
GstVideoInfo output_info;
- GstD3D11Codec codec;
+ GstDXVACodec codec;
gint coded_width;
gint coded_height;
DXGI_FORMAT decoder_format;
@@ -214,9 +214,6 @@ gst_d3d11_decoder_class_init (GstD3D11DecoderClass * klass)
"D3D11 Devicd to use", GST_TYPE_D3D11_DEVICE,
(GParamFlags) (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS)));
-
- GST_DEBUG_CATEGORY_INIT (d3d11_decoder_debug,
- "d3d11decoder", 0, "Direct3D11 Base Video Decoder object");
}
static void
@@ -359,11 +356,13 @@ gst_d3d11_decoder_finalize (GObject * obj)
}
GstD3D11Decoder *
-gst_d3d11_decoder_new (GstD3D11Device * device)
+gst_d3d11_decoder_new (GstD3D11Device * device, GstDXVACodec codec)
{
GstD3D11Decoder *self;
- g_return_val_if_fail (GST_IS_D3D11_DEVICE (device), NULL);
+ g_return_val_if_fail (GST_IS_D3D11_DEVICE (device), nullptr);
+ g_return_val_if_fail (codec > GST_DXVA_CODEC_NONE, nullptr);
+ g_return_val_if_fail (codec < GST_DXVA_CODEC_LAST, nullptr);
self = (GstD3D11Decoder *)
g_object_new (GST_TYPE_D3D11_DECODER, "device", device, NULL);
@@ -373,6 +372,8 @@ gst_d3d11_decoder_new (GstD3D11Device * device)
return NULL;
}
+ self->codec = codec;
+
gst_object_ref_sink (self);
return self;
@@ -537,22 +538,22 @@ error:
}
static const gchar *
-gst_d3d11_codec_to_string (GstD3D11Codec codec)
+gst_dxva_codec_to_string (GstDXVACodec codec)
{
switch (codec) {
- case GST_D3D11_CODEC_NONE:
+ case GST_DXVA_CODEC_NONE:
return "none";
- case GST_D3D11_CODEC_H264:
+ case GST_DXVA_CODEC_H264:
return "H.264";
- case GST_D3D11_CODEC_VP9:
+ case GST_DXVA_CODEC_VP9:
return "VP9";
- case GST_D3D11_CODEC_H265:
+ case GST_DXVA_CODEC_H265:
return "H.265";
- case GST_D3D11_CODEC_VP8:
+ case GST_DXVA_CODEC_VP8:
return "VP8";
- case GST_D3D11_CODEC_MPEG2:
+ case GST_DXVA_CODEC_MPEG2:
return "MPEG2";
- case GST_D3D11_CODEC_AV1:
+ case GST_DXVA_CODEC_AV1:
return "AV1";
default:
g_assert_not_reached ();
@@ -563,29 +564,33 @@ gst_d3d11_codec_to_string (GstD3D11Codec codec)
}
gboolean
-gst_d3d11_decoder_get_supported_decoder_profile (GstD3D11Decoder * decoder,
- GstD3D11Codec codec, GstVideoFormat format, const GUID ** selected_profile)
+gst_d3d11_decoder_get_supported_decoder_profile (GstD3D11Device * device,
+ GstDXVACodec codec, GstVideoFormat format, const GUID ** selected_profile)
{
- GUID *guid_list = NULL;
- const GUID *profile = NULL;
+ GUID *guid_list = nullptr;
+ const GUID *profile = nullptr;
guint available_profile_count;
guint i, j;
HRESULT hr;
ID3D11VideoDevice *video_device;
- const GUID **profile_list = NULL;
+ const GUID **profile_list = nullptr;
guint profile_size = 0;
- g_return_val_if_fail (GST_IS_D3D11_DECODER (decoder), FALSE);
- g_return_val_if_fail (selected_profile != NULL, FALSE);
+ g_return_val_if_fail (GST_IS_D3D11_DEVICE (device), FALSE);
+ g_return_val_if_fail (selected_profile != nullptr, FALSE);
+
+ video_device = gst_d3d11_device_get_video_device_handle (device);
+ if (!video_device)
+ return FALSE;
switch (codec) {
- case GST_D3D11_CODEC_H264:
+ case GST_DXVA_CODEC_H264:
if (format == GST_VIDEO_FORMAT_NV12) {
profile_list = profile_h264_list;
profile_size = G_N_ELEMENTS (profile_h264_list);
}
break;
- case GST_D3D11_CODEC_H265:
+ case GST_DXVA_CODEC_H265:
if (format == GST_VIDEO_FORMAT_NV12) {
profile_list = profile_hevc_list;
profile_size = G_N_ELEMENTS (profile_hevc_list);
@@ -594,13 +599,13 @@ gst_d3d11_decoder_get_supported_decoder_profile (GstD3D11Decoder * decoder,
profile_size = G_N_ELEMENTS (profile_hevc_10_list);
}
break;
- case GST_D3D11_CODEC_VP8:
+ case GST_DXVA_CODEC_VP8:
if (format == GST_VIDEO_FORMAT_NV12) {
profile_list = profile_vp8_list;
profile_size = G_N_ELEMENTS (profile_vp8_list);
}
break;
- case GST_D3D11_CODEC_VP9:
+ case GST_DXVA_CODEC_VP9:
if (format == GST_VIDEO_FORMAT_NV12) {
profile_list = profile_vp9_list;
profile_size = G_N_ELEMENTS (profile_vp9_list);
@@ -609,13 +614,13 @@ gst_d3d11_decoder_get_supported_decoder_profile (GstD3D11Decoder * decoder,
profile_size = G_N_ELEMENTS (profile_vp9_10_list);
}
break;
- case GST_D3D11_CODEC_MPEG2:
+ case GST_DXVA_CODEC_MPEG2:
if (format == GST_VIDEO_FORMAT_NV12) {
profile_list = profile_mpeg2_list;
profile_size = G_N_ELEMENTS (profile_mpeg2_list);
}
break;
- case GST_D3D11_CODEC_AV1:
+ case GST_DXVA_CODEC_AV1:
profile_list = profile_av1_list;
profile_size = G_N_ELEMENTS (profile_av1_list);
break;
@@ -624,50 +629,48 @@ gst_d3d11_decoder_get_supported_decoder_profile (GstD3D11Decoder * decoder,
}
if (!profile_list) {
- GST_ERROR_OBJECT (decoder,
+ GST_ERROR_OBJECT (device,
"Not supported codec (%d) and format (%s) configuration", codec,
gst_video_format_to_string (format));
return FALSE;
}
- video_device = decoder->video_device;
-
available_profile_count = video_device->GetVideoDecoderProfileCount ();
if (available_profile_count == 0) {
- GST_WARNING_OBJECT (decoder, "No available decoder profile");
+ GST_INFO_OBJECT (device, "No available decoder profile");
return FALSE;
}
- GST_DEBUG_OBJECT (decoder,
+ GST_DEBUG_OBJECT (device,
"Have %u available decoder profiles", available_profile_count);
guid_list = (GUID *) g_alloca (sizeof (GUID) * available_profile_count);
for (i = 0; i < available_profile_count; i++) {
hr = video_device->GetVideoDecoderProfile (i, &guid_list[i]);
- if (!gst_d3d11_result (hr, decoder->device)) {
- GST_WARNING_OBJECT (decoder, "Failed to get %d th decoder profile", i);
+ if (!gst_d3d11_result (hr, device)) {
+ GST_WARNING_OBJECT (device, "Failed to get %d th decoder profile", i);
return FALSE;
}
}
#ifndef GST_DISABLE_GST_DEBUG
- GST_LOG_OBJECT (decoder, "Supported decoder GUID");
+ GST_LOG_OBJECT (device, "Supported decoder GUID");
for (i = 0; i < available_profile_count; i++) {
const GUID *guid = &guid_list[i];
- GST_LOG_OBJECT (decoder,
+ GST_LOG_OBJECT (device,
"\t { %8.8x-%4.4x-%4.4x-%2.2x%2.2x-%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x }",
(guint) guid->Data1, (guint) guid->Data2, (guint) guid->Data3,
guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
}
- GST_LOG_OBJECT (decoder, "Requested decoder GUID");
+ GST_LOG_OBJECT (device, "Requested decoder GUID");
for (i = 0; i < profile_size; i++) {
const GUID *guid = profile_list[i];
- GST_LOG_OBJECT (decoder,
+ GST_LOG_OBJECT (device,
"\t { %8.8x-%4.4x-%4.4x-%2.2x%2.2x-%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x }",
(guint) guid->Data1, (guint) guid->Data2, (guint) guid->Data3,
guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
@@ -685,14 +688,14 @@ gst_d3d11_decoder_get_supported_decoder_profile (GstD3D11Decoder * decoder,
}
if (!profile) {
- GST_INFO_OBJECT (decoder, "No supported decoder profile for %s codec",
- gst_d3d11_codec_to_string (codec));
+ GST_INFO_OBJECT (device, "No supported decoder profile for %s codec",
+ gst_dxva_codec_to_string (codec));
return FALSE;
}
*selected_profile = profile;
- GST_DEBUG_OBJECT (decoder,
+ GST_DEBUG_OBJECT (device,
"Selected guid "
"{ %8.8x-%4.4x-%4.4x-%2.2x%2.2x-%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x }",
(guint) profile->Data1, (guint) profile->Data2, (guint) profile->Data3,
@@ -705,15 +708,13 @@ gst_d3d11_decoder_get_supported_decoder_profile (GstD3D11Decoder * decoder,
gboolean
-gst_d3d11_decoder_configure (GstD3D11Decoder * decoder, GstD3D11Codec codec,
+gst_d3d11_decoder_configure (GstD3D11Decoder * decoder,
GstVideoCodecState * input_state, GstVideoInfo * info, gint coded_width,
gint coded_height, guint dpb_size)
{
const GstD3D11Format *d3d11_format;
g_return_val_if_fail (GST_IS_D3D11_DECODER (decoder), FALSE);
- g_return_val_if_fail (codec > GST_D3D11_CODEC_NONE, FALSE);
- g_return_val_if_fail (codec < GST_D3D11_CODEC_LAST, FALSE);
g_return_val_if_fail (info != NULL, FALSE);
g_return_val_if_fail (input_state != NULL, FALSE);
g_return_val_if_fail (coded_width >= GST_VIDEO_INFO_WIDTH (info), FALSE);
@@ -730,7 +731,6 @@ gst_d3d11_decoder_configure (GstD3D11Decoder * decoder, GstD3D11Codec codec,
return FALSE;
}
- decoder->codec = codec;
decoder->input_state = gst_video_codec_state_ref (input_state);
decoder->info = decoder->output_info = *info;
decoder->coded_width = coded_width;
@@ -832,7 +832,7 @@ gst_d3d11_decoder_open (GstD3D11Decoder * self)
video_device = self->video_device;
gst_d3d11_device_lock (self->device);
- if (!gst_d3d11_decoder_get_supported_decoder_profile (self,
+ if (!gst_d3d11_decoder_get_supported_decoder_profile (self->device,
self->codec, GST_VIDEO_INFO_FORMAT (info), &selected_profile)) {
goto error;
}
@@ -867,15 +867,15 @@ gst_d3d11_decoder_open (GstD3D11Decoder * self)
* directx_va_Setup() in directx_va.c of vlc.
* But... where it is? */
switch (self->codec) {
- case GST_D3D11_CODEC_H265:
- case GST_D3D11_CODEC_AV1:
+ case GST_DXVA_CODEC_H265:
+ case GST_DXVA_CODEC_AV1:
/* See directx_va_Setup() impl. in vlc */
if (vendor != GST_D3D11_DEVICE_VENDOR_XBOX)
alignment = 128;
else
alignment = 16;
break;
- case GST_D3D11_CODEC_MPEG2:
+ case GST_DXVA_CODEC_MPEG2:
/* XXX: ffmpeg does this */
alignment = 32;
break;
@@ -926,15 +926,15 @@ gst_d3d11_decoder_open (GstD3D11Decoder * self)
/* FIXME: need support DXVA_Slice_H264_Long ?? */
/* this config uses DXVA_Slice_H264_Short */
switch (self->codec) {
- case GST_D3D11_CODEC_H264:
+ case GST_DXVA_CODEC_H264:
if (config_list[i].ConfigBitstreamRaw == 2)
best_config = &config_list[i];
break;
- case GST_D3D11_CODEC_H265:
- case GST_D3D11_CODEC_VP9:
- case GST_D3D11_CODEC_VP8:
- case GST_D3D11_CODEC_MPEG2:
- case GST_D3D11_CODEC_AV1:
+ case GST_DXVA_CODEC_H265:
+ case GST_DXVA_CODEC_VP9:
+ case GST_DXVA_CODEC_VP8:
+ case GST_DXVA_CODEC_MPEG2:
+ case GST_DXVA_CODEC_AV1:
if (config_list[i].ConfigBitstreamRaw == 1)
best_config = &config_list[i];
break;
@@ -1001,7 +1001,7 @@ error:
return FALSE;
}
-gboolean
+static gboolean
gst_d3d11_decoder_begin_frame (GstD3D11Decoder * decoder,
ID3D11VideoDecoderOutputView * output_view, guint content_key_size,
gconstpointer content_key)
@@ -1015,12 +1015,8 @@ gst_d3d11_decoder_begin_frame (GstD3D11Decoder * decoder,
if (decoder->timer_resolution)
retry_threshold = 500;
- g_return_val_if_fail (GST_IS_D3D11_DECODER (decoder), FALSE);
- g_return_val_if_fail (output_view != NULL, FALSE);
-
video_context = decoder->video_context;
- gst_d3d11_device_lock (decoder->device);
do {
GST_LOG_OBJECT (decoder, "Try begin frame, retry count %d", retry_count);
hr = video_context->DecoderBeginFrame (decoder->decoder_handle,
@@ -1041,7 +1037,6 @@ gst_d3d11_decoder_begin_frame (GstD3D11Decoder * decoder,
retry_count++;
} while (TRUE);
- gst_d3d11_device_unlock (decoder->device);
if (!gst_d3d11_result (hr, decoder->device)) {
GST_ERROR_OBJECT (decoder, "Failed to begin frame, hr: 0x%x", (guint) hr);
@@ -1051,19 +1046,14 @@ gst_d3d11_decoder_begin_frame (GstD3D11Decoder * decoder,
return TRUE;
}
-gboolean
+static gboolean
gst_d3d11_decoder_end_frame (GstD3D11Decoder * decoder)
{
HRESULT hr;
ID3D11VideoContext *video_context;
- g_return_val_if_fail (GST_IS_D3D11_DECODER (decoder), FALSE);
-
video_context = decoder->video_context;
-
- gst_d3d11_device_lock (decoder->device);
hr = video_context->DecoderEndFrame (decoder->decoder_handle);
- gst_d3d11_device_unlock (decoder->device);
if (!gst_d3d11_result (hr, decoder->device)) {
GST_WARNING_OBJECT (decoder, "EndFrame failed, hr: 0x%x", (guint) hr);
@@ -1073,7 +1063,7 @@ gst_d3d11_decoder_end_frame (GstD3D11Decoder * decoder)
return TRUE;
}
-gboolean
+static gboolean
gst_d3d11_decoder_get_decoder_buffer (GstD3D11Decoder * decoder,
D3D11_VIDEO_DECODER_BUFFER_TYPE type, guint * buffer_size,
gpointer * buffer)
@@ -1083,14 +1073,9 @@ gst_d3d11_decoder_get_decoder_buffer (GstD3D11Decoder * decoder,
HRESULT hr;
ID3D11VideoContext *video_context;
- g_return_val_if_fail (GST_IS_D3D11_DECODER (decoder), FALSE);
-
video_context = decoder->video_context;
-
- gst_d3d11_device_lock (decoder->device);
hr = video_context->GetDecoderBuffer (decoder->decoder_handle,
type, &size, &decoder_buffer);
- gst_d3d11_device_unlock (decoder->device);
if (!gst_d3d11_result (hr, decoder->device)) {
GST_WARNING_OBJECT (decoder, "Getting buffer type %d error, hr: 0x%x",
@@ -1104,20 +1089,15 @@ gst_d3d11_decoder_get_decoder_buffer (GstD3D11Decoder * decoder,
return TRUE;
}
-gboolean
+static gboolean
gst_d3d11_decoder_release_decoder_buffer (GstD3D11Decoder * decoder,
D3D11_VIDEO_DECODER_BUFFER_TYPE type)
{
HRESULT hr;
ID3D11VideoContext *video_context;
- g_return_val_if_fail (GST_IS_D3D11_DECODER (decoder), FALSE);
-
video_context = decoder->video_context;
-
- gst_d3d11_device_lock (decoder->device);
hr = video_context->ReleaseDecoderBuffer (decoder->decoder_handle, type);
- gst_d3d11_device_unlock (decoder->device);
if (!gst_d3d11_result (hr, decoder->device)) {
GST_WARNING_OBJECT (decoder, "ReleaseDecoderBuffer failed, hr: 0x%x",
@@ -1128,22 +1108,16 @@ gst_d3d11_decoder_release_decoder_buffer (GstD3D11Decoder * decoder,
return TRUE;
}
-gboolean
+static gboolean
gst_d3d11_decoder_submit_decoder_buffers (GstD3D11Decoder * decoder,
guint buffer_count, const D3D11_VIDEO_DECODER_BUFFER_DESC * buffers)
{
HRESULT hr;
ID3D11VideoContext *video_context;
- g_return_val_if_fail (GST_IS_D3D11_DECODER (decoder), FALSE);
-
video_context = decoder->video_context;
-
- gst_d3d11_device_lock (decoder->device);
hr = video_context->SubmitDecoderBuffers (decoder->decoder_handle,
buffer_count, buffers);
- gst_d3d11_device_unlock (decoder->device);
-
if (!gst_d3d11_result (hr, decoder->device)) {
GST_WARNING_OBJECT (decoder, "SubmitDecoderBuffers failed, hr: 0x%x",
(guint) hr);
@@ -1153,6 +1127,174 @@ gst_d3d11_decoder_submit_decoder_buffers (GstD3D11Decoder * decoder,
return TRUE;
}
+gboolean
+gst_d3d11_decoder_decode_frame (GstD3D11Decoder * decoder,
+ ID3D11VideoDecoderOutputView * output_view,
+ GstD3D11DecodeInputStreamArgs * input_args)
+{
+ guint d3d11_buffer_size;
+ gpointer d3d11_buffer;
+ D3D11_VIDEO_DECODER_BUFFER_DESC buffer_desc[4];
+ guint buffer_desc_size;
+
+ g_return_val_if_fail (GST_IS_D3D11_DECODER (decoder), FALSE);
+ g_return_val_if_fail (output_view != nullptr, FALSE);
+ g_return_val_if_fail (input_args != nullptr, FALSE);
+
+ memset (buffer_desc, 0, sizeof (buffer_desc));
+
+ buffer_desc[0].BufferType = D3D11_VIDEO_DECODER_BUFFER_PICTURE_PARAMETERS;
+ buffer_desc[0].DataSize = input_args->picture_params_size;
+
+ buffer_desc[1].BufferType = D3D11_VIDEO_DECODER_BUFFER_SLICE_CONTROL;
+ buffer_desc[1].DataSize = input_args->slice_control_size;
+
+ buffer_desc[2].BufferType = D3D11_VIDEO_DECODER_BUFFER_BITSTREAM;
+ buffer_desc[2].DataOffset = 0;
+ buffer_desc[2].DataSize = input_args->bitstream_size;
+
+ buffer_desc_size = 3;
+ if (input_args->inverse_quantization_matrix &&
+ input_args->inverse_quantization_matrix_size > 0) {
+ buffer_desc[3].BufferType =
+ D3D11_VIDEO_DECODER_BUFFER_INVERSE_QUANTIZATION_MATRIX;
+ buffer_desc[3].DataSize = input_args->inverse_quantization_matrix_size;
+ buffer_desc_size++;
+ }
+
+ gst_d3d11_device_lock (decoder->device);
+ if (!gst_d3d11_decoder_begin_frame (decoder, output_view, 0, nullptr)) {
+ gst_d3d11_device_unlock (decoder->device);
+
+ return FALSE;
+ }
+
+ if (!gst_d3d11_decoder_get_decoder_buffer (decoder,
+ D3D11_VIDEO_DECODER_BUFFER_PICTURE_PARAMETERS, &d3d11_buffer_size,
+ &d3d11_buffer)) {
+ GST_ERROR_OBJECT (decoder,
+ "Failed to get decoder buffer for picture parameters");
+ goto error;
+ }
+
+ if (d3d11_buffer_size < input_args->picture_params_size) {
+ GST_ERROR_OBJECT (decoder,
+ "Too small picture param buffer size %d", d3d11_buffer_size);
+
+ gst_d3d11_decoder_release_decoder_buffer (decoder,
+ D3D11_VIDEO_DECODER_BUFFER_PICTURE_PARAMETERS);
+ goto error;
+ }
+
+ memcpy (d3d11_buffer, input_args->picture_params,
+ input_args->picture_params_size);
+
+ if (!gst_d3d11_decoder_release_decoder_buffer (decoder,
+ D3D11_VIDEO_DECODER_BUFFER_PICTURE_PARAMETERS)) {
+ GST_ERROR_OBJECT (decoder, "Failed to release picture param buffer");
+ goto error;
+ }
+
+ if (!gst_d3d11_decoder_get_decoder_buffer (decoder,
+ D3D11_VIDEO_DECODER_BUFFER_SLICE_CONTROL, &d3d11_buffer_size,
+ &d3d11_buffer)) {
+ GST_ERROR_OBJECT (decoder, "Failed to get slice control buffer");
+ goto error;
+ }
+
+ if (d3d11_buffer_size < input_args->slice_control_size) {
+ GST_ERROR_OBJECT (decoder,
+ "Too small slice control buffer size %d", d3d11_buffer_size);
+
+ gst_d3d11_decoder_release_decoder_buffer (decoder,
+ D3D11_VIDEO_DECODER_BUFFER_SLICE_CONTROL);
+ goto error;
+ }
+
+ memcpy (d3d11_buffer,
+ input_args->slice_control, input_args->slice_control_size);
+
+ if (!gst_d3d11_decoder_release_decoder_buffer (decoder,
+ D3D11_VIDEO_DECODER_BUFFER_SLICE_CONTROL)) {
+ GST_ERROR_OBJECT (decoder, "Failed to release slice control buffer");
+ goto error;
+ }
+
+ if (!gst_d3d11_decoder_get_decoder_buffer (decoder,
+ D3D11_VIDEO_DECODER_BUFFER_BITSTREAM, &d3d11_buffer_size,
+ &d3d11_buffer)) {
+ GST_ERROR_OBJECT (decoder, "Failed to get bitstream buffer");
+ goto error;
+ }
+
+ if (d3d11_buffer_size < input_args->bitstream_size) {
+ GST_ERROR_OBJECT (decoder, "Too small bitstream buffer size %d",
+ d3d11_buffer_size);
+
+ gst_d3d11_decoder_release_decoder_buffer (decoder,
+ D3D11_VIDEO_DECODER_BUFFER_BITSTREAM);
+ goto error;
+ }
+
+ memcpy (d3d11_buffer, input_args->bitstream, input_args->bitstream_size);
+
+ if (!gst_d3d11_decoder_release_decoder_buffer (decoder,
+ D3D11_VIDEO_DECODER_BUFFER_BITSTREAM)) {
+ GST_ERROR_OBJECT (decoder, "Failed to release bitstream buffer");
+ goto error;
+ }
+
+ if (input_args->inverse_quantization_matrix_size > 0) {
+ if (!gst_d3d11_decoder_get_decoder_buffer (decoder,
+ D3D11_VIDEO_DECODER_BUFFER_INVERSE_QUANTIZATION_MATRIX,
+ &d3d11_buffer_size, &d3d11_buffer)) {
+ GST_ERROR_OBJECT (decoder,
+ "Failed to get inverse quantization matrix buffer");
+ goto error;
+ }
+
+ if (d3d11_buffer_size < input_args->inverse_quantization_matrix_size) {
+ GST_ERROR_OBJECT (decoder,
+ "Too small inverse quantization matrix buffer buffer %d",
+ d3d11_buffer_size);
+
+ gst_d3d11_decoder_release_decoder_buffer (decoder,
+ D3D11_VIDEO_DECODER_BUFFER_INVERSE_QUANTIZATION_MATRIX);
+ goto error;
+ }
+
+ memcpy (d3d11_buffer, input_args->inverse_quantization_matrix,
+ input_args->inverse_quantization_matrix_size);
+
+ if (!gst_d3d11_decoder_release_decoder_buffer (decoder,
+ D3D11_VIDEO_DECODER_BUFFER_INVERSE_QUANTIZATION_MATRIX)) {
+ GST_ERROR_OBJECT (decoder,
+ "Failed to release inverse quantization matrix buffer");
+ goto error;
+ }
+ }
+
+ if (!gst_d3d11_decoder_submit_decoder_buffers (decoder,
+ buffer_desc_size, buffer_desc)) {
+ GST_ERROR_OBJECT (decoder, "Failed to submit decoder buffers");
+ goto error;
+ }
+
+ if (!gst_d3d11_decoder_end_frame (decoder)) {
+ gst_d3d11_device_unlock (decoder->device);
+ return FALSE;
+ }
+
+ gst_d3d11_device_unlock (decoder->device);
+
+ return TRUE;
+
+error:
+ gst_d3d11_decoder_end_frame (decoder);
+ gst_d3d11_device_unlock (decoder->device);
+ return FALSE;
+}
+
GstBuffer *
gst_d3d11_decoder_get_output_view_buffer (GstD3D11Decoder * decoder,
GstVideoDecoder * videodec)
@@ -1885,23 +2027,25 @@ gst_d3d11_decoder_util_is_legacy_device (GstD3D11Device * device)
}
gboolean
-gst_d3d11_decoder_supports_format (GstD3D11Decoder * decoder,
+gst_d3d11_decoder_supports_format (GstD3D11Device * device,
const GUID * decoder_profile, DXGI_FORMAT format)
{
HRESULT hr;
BOOL can_support = FALSE;
ID3D11VideoDevice *video_device;
- g_return_val_if_fail (GST_IS_D3D11_DECODER (decoder), FALSE);
+ g_return_val_if_fail (GST_IS_D3D11_DEVICE (device), FALSE);
g_return_val_if_fail (decoder_profile != NULL, FALSE);
g_return_val_if_fail (format != DXGI_FORMAT_UNKNOWN, FALSE);
- video_device = decoder->video_device;
+ video_device = gst_d3d11_device_get_video_device_handle (device);
+ if (!video_device)
+ return FALSE;
hr = video_device->CheckVideoDecoderFormat (decoder_profile, format,
&can_support);
- if (!gst_d3d11_result (hr, decoder->device) || !can_support) {
- GST_DEBUG_OBJECT (decoder,
+ if (!gst_d3d11_result (hr, device) || !can_support) {
+ GST_DEBUG_OBJECT (device,
"VideoDevice could not support dxgi format %d, hr: 0x%x",
format, (guint) hr);
@@ -1913,7 +2057,7 @@ gst_d3d11_decoder_supports_format (GstD3D11Decoder * decoder,
/* Don't call this method with legacy device */
gboolean
-gst_d3d11_decoder_supports_resolution (GstD3D11Decoder * decoder,
+gst_d3d11_decoder_supports_resolution (GstD3D11Device * device,
const GUID * decoder_profile, DXGI_FORMAT format, guint width, guint height)
{
D3D11_VIDEO_DECODER_DESC desc;
@@ -1921,11 +2065,13 @@ gst_d3d11_decoder_supports_resolution (GstD3D11Decoder * decoder,
UINT config_count;
ID3D11VideoDevice *video_device;
- g_return_val_if_fail (GST_IS_D3D11_DECODER (decoder), FALSE);
+ g_return_val_if_fail (GST_IS_D3D11_DEVICE (device), FALSE);
g_return_val_if_fail (decoder_profile != NULL, FALSE);
g_return_val_if_fail (format != DXGI_FORMAT_UNKNOWN, FALSE);
- video_device = decoder->video_device;
+ video_device = gst_d3d11_device_get_video_device_handle (device);
+ if (!video_device)
+ return FALSE;
desc.SampleWidth = width;
desc.SampleHeight = height;
@@ -1933,8 +2079,8 @@ gst_d3d11_decoder_supports_resolution (GstD3D11Decoder * decoder,
desc.Guid = *decoder_profile;
hr = video_device->GetVideoDecoderConfigCount (&desc, &config_count);
- if (!gst_d3d11_result (hr, decoder->device) || config_count == 0) {
- GST_DEBUG_OBJECT (decoder, "Could not get decoder config count, hr: 0x%x",
+ if (!gst_d3d11_result (hr, device) || config_count == 0) {
+ GST_DEBUG_OBJECT (device, "Could not get decoder config count, hr: 0x%x",
(guint) hr);
return FALSE;
}
@@ -1955,7 +2101,7 @@ struct _GstD3D11DecoderClassData
GstCaps *sink_caps;
GstCaps *src_caps;
gchar *description;
- GstD3D11Codec codec;
+ GstDXVACodec codec;
};
/**
@@ -1969,7 +2115,7 @@ struct _GstD3D11DecoderClassData
* Returns: (transfer full): the new #GstD3D11DecoderClassData
*/
GstD3D11DecoderClassData *
-gst_d3d11_decoder_class_data_new (GstD3D11Device * device, GstD3D11Codec codec,
+gst_d3d11_decoder_class_data_new (GstD3D11Device * device, GstDXVACodec codec,
GstCaps * sink_caps, GstCaps * src_caps)
{
GstD3D11DecoderClassData *ret;
@@ -2044,7 +2190,7 @@ gst_d3d11_decoder_proxy_class_init (GstElementClass * klass,
"DXGI Vendor ID", 0, G_MAXUINT32, 0,
(GParamFlags) (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)));
- codec_name = gst_d3d11_codec_to_string (data->codec);
+ codec_name = gst_dxva_codec_to_string (data->codec);
long_name = "Direct3D11/DXVA " + std::string (codec_name) + " " +
std::string (data->description) + " Decoder";
description = "Direct3D11/DXVA based " + std::string (codec_name) +