mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 04:01:08 +00:00
d3d11decoder: Check decoder status report
... and if h/w decoder reports error, increase error count.
This commit is contained in:
parent
26ac42f7c0
commit
418e6991c1
5 changed files with 170 additions and 3 deletions
|
@ -1098,6 +1098,90 @@ gst_d3d11_decoder_copy_decoder_buffer (GstD3D11Decoder * decoder,
|
|||
return copy_to_system (decoder, info, decoder_buffer, output);
|
||||
}
|
||||
|
||||
static const gchar *
|
||||
gst_d3d11_decoder_status_code_to_verbose_string (guint status_code)
|
||||
{
|
||||
const gchar *status = NULL;
|
||||
|
||||
switch (status_code) {
|
||||
case 0:
|
||||
status = "The operation succeeded";
|
||||
break;
|
||||
case 1:
|
||||
status = "Minor problem in the data format. "
|
||||
"The host decoder should continue processing";
|
||||
break;
|
||||
case 2:
|
||||
status = "Significant problem in the data format. The host decoder may "
|
||||
"continue executing or skip the display of the output picture";
|
||||
break;
|
||||
case 3:
|
||||
status = "Severe problem in the data format. The host decoder should "
|
||||
"restart the entire decoding process, starting at a sequence or "
|
||||
"random-access entry point";
|
||||
break;
|
||||
case 4:
|
||||
status =
|
||||
"Other severe problem. The host decoder should restart the entire "
|
||||
"decoding process, starting at a sequence or random-access entry point";
|
||||
break;
|
||||
default:
|
||||
status = "Unknown status";
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_d3d11_decoder_get_status_report (GstD3D11Decoder * decoder,
|
||||
GstDXVAStatus * status, GError ** err)
|
||||
{
|
||||
GstD3D11DecoderPrivate *priv;
|
||||
HRESULT hr;
|
||||
D3D11_VIDEO_DECODER_EXTENSION extension = { 0, };
|
||||
gboolean ret;
|
||||
|
||||
g_return_val_if_fail (GST_IS_D3D11_DECODER (decoder), FALSE);
|
||||
g_return_val_if_fail (status != NULL, FALSE);
|
||||
|
||||
priv = decoder->priv;
|
||||
|
||||
/* For status report */
|
||||
extension.Function = 7;
|
||||
extension.pPrivateOutputData = (PVOID) status;
|
||||
extension.PrivateOutputDataSize = sizeof (GstDXVAStatus);
|
||||
|
||||
gst_d3d11_device_lock (priv->device);
|
||||
hr = ID3D11VideoContext_DecoderExtension (priv->video_context, priv->decoder,
|
||||
&extension);
|
||||
gst_d3d11_device_unlock (priv->device);
|
||||
|
||||
ret = gst_d3d11_result (hr, priv->device);
|
||||
|
||||
if (ret && status->bStatus != 0) {
|
||||
/* TODO: if status code is 3 or 4, we might need to restart decoding
|
||||
* from new keyframe */
|
||||
GST_WARNING_OBJECT (decoder,
|
||||
"Status code: %d, StatusReportFeedbackNumber: %d, "
|
||||
"CurrPic.Index7Bits: %d, CurrPic.AssociatedFlag: %d, bBufType: %d, "
|
||||
"wNumMbsAffected: %d", status->bStatus,
|
||||
status->StatusReportFeedbackNumber,
|
||||
status->CurrPic.Index7Bits, status->CurrPic.AssociatedFlag,
|
||||
status->bBufType, status->wNumMbsAffected);
|
||||
|
||||
if (status->bStatus > 1) {
|
||||
const gchar *status_str =
|
||||
gst_d3d11_decoder_status_code_to_verbose_string (status->bStatus);
|
||||
|
||||
g_set_error_literal (err, GST_STREAM_ERROR,
|
||||
GST_STREAM_ERROR_DECODE, status_str);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Keep sync with chromium and keep in sorted order.
|
||||
* See supported_profile_helpers.cc in chromium */
|
||||
static const guint legacy_amd_list[] = {
|
||||
|
|
|
@ -41,6 +41,16 @@ G_BEGIN_DECLS
|
|||
#define GST_IS_D3D11_DECODER_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_D3D11_DECODER))
|
||||
|
||||
#define GST_D3D11_VIDEO_DECODER_ERROR_FROM_ERROR(el, err) G_STMT_START { \
|
||||
gchar *__dbg = g_strdup (err->message); \
|
||||
GstVideoDecoder *__dec = GST_VIDEO_DECODER (el); \
|
||||
GST_WARNING_OBJECT (el, "error: %s", __dbg); \
|
||||
_gst_video_decoder_error (__dec, 1, \
|
||||
err->domain, err->code, \
|
||||
NULL, __dbg, __FILE__, GST_FUNCTION, __LINE__); \
|
||||
g_clear_error (&err); \
|
||||
} G_STMT_END
|
||||
|
||||
typedef struct _GstD3D11DecoderOutputView GstD3D11DecoderOutputView;
|
||||
|
||||
struct _GstD3D11DecoderOutputView
|
||||
|
@ -71,6 +81,35 @@ typedef struct
|
|||
gchar *description;
|
||||
} GstD3D11DecoderClassData;
|
||||
|
||||
/* use our struct for DXVA_Status_* (including DXVA_PicEntry_*) to query
|
||||
* decoding status. Microsoft defines the struct per codec but their ABI are
|
||||
* compatible each other and mingw header does not define some structs */
|
||||
|
||||
/* DXVA_PicEntry_*, from dxva.h */
|
||||
typedef struct
|
||||
{
|
||||
union {
|
||||
struct {
|
||||
UCHAR Index7Bits : 7;
|
||||
UCHAR AssociatedFlag : 1;
|
||||
};
|
||||
UCHAR bPicEntry;
|
||||
};
|
||||
} GstDXVAPicEntry;
|
||||
|
||||
/* DXVA_Status_*, from dxva.h */
|
||||
typedef struct
|
||||
{
|
||||
UINT StatusReportFeedbackNumber;
|
||||
GstDXVAPicEntry CurrPic; /* flag is bot field flag */
|
||||
UCHAR field_pic_flag;
|
||||
UCHAR bDXVA_Func;
|
||||
UCHAR bBufType;
|
||||
UCHAR bStatus;
|
||||
UCHAR bReserved8Bits;
|
||||
USHORT wNumMbsAffected;
|
||||
} GstDXVAStatus;
|
||||
|
||||
struct _GstD3D11Decoder
|
||||
{
|
||||
GstObject parent;
|
||||
|
@ -135,6 +174,10 @@ gboolean gst_d3d11_decoder_copy_decoder_buffer (GstD3D11Decoder * decod
|
|||
GstBuffer * decoder_buffer,
|
||||
GstBuffer * output);
|
||||
|
||||
gboolean gst_d3d11_decoder_get_status_report (GstD3D11Decoder * decoder,
|
||||
GstDXVAStatus * status,
|
||||
GError ** error);
|
||||
|
||||
/* Utils for class registration */
|
||||
gboolean gst_d3d11_decoder_util_is_legacy_device (GstD3D11Device * device);
|
||||
|
||||
|
|
|
@ -120,6 +120,8 @@ typedef struct _GstD3D11H264Dec
|
|||
USHORT frame_num_list[16];
|
||||
UINT used_for_reference_flags;
|
||||
USHORT non_existing_frame_flags;
|
||||
|
||||
guint status_report_feedback_number;
|
||||
} GstD3D11H264Dec;
|
||||
|
||||
typedef struct _GstD3D11H264DecClass
|
||||
|
@ -557,6 +559,8 @@ gst_d3d11_h264_dec_new_sequence (GstH264Decoder * decoder,
|
|||
GST_ERROR_OBJECT (self, "Failed to negotiate with downstream");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
self->status_report_feedback_number = 0;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
@ -915,6 +919,8 @@ gst_d3d11_h264_dec_end_picture (GstH264Decoder * decoder,
|
|||
GstH264Picture * picture)
|
||||
{
|
||||
GstD3D11H264Dec *self = GST_D3D11_H264_DEC (decoder);
|
||||
GError *err = NULL;
|
||||
GstDXVAStatus status = { 0, };
|
||||
|
||||
GST_LOG_OBJECT (self, "end picture %p, (poc %d)",
|
||||
picture, picture->pic_order_cnt);
|
||||
|
@ -929,6 +935,11 @@ gst_d3d11_h264_dec_end_picture (GstH264Decoder * decoder,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
if (gst_d3d11_decoder_get_status_report (self->d3d11_decoder,
|
||||
&status, &err) && err) {
|
||||
GST_D3D11_VIDEO_DECODER_ERROR_FROM_ERROR (self, err);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -1018,7 +1029,9 @@ gst_d3d11_h264_dec_fill_picture_params (GstD3D11H264Dec * self,
|
|||
params->ContinuationFlag = 1;
|
||||
params->Reserved8BitsA = 0;
|
||||
params->Reserved8BitsB = 0;
|
||||
params->StatusReportFeedbackNumber = 1;
|
||||
/* StatusReportFeedbackNumber should be non-zero */
|
||||
params->StatusReportFeedbackNumber = 1 + self->status_report_feedback_number;
|
||||
self->status_report_feedback_number++;
|
||||
|
||||
gst_d3d11_h264_dec_picture_params_from_sps (self,
|
||||
sps, slice_header->field_pic_flag, params);
|
||||
|
|
|
@ -89,6 +89,8 @@ typedef struct _GstD3D11H265Dec
|
|||
UCHAR ref_pic_set_st_curr_before[8];
|
||||
UCHAR ref_pic_set_st_curr_after[8];
|
||||
UCHAR ref_pic_set_lt_curr[8];
|
||||
|
||||
guint status_report_feedback_number;
|
||||
} GstD3D11H265Dec;
|
||||
|
||||
typedef struct _GstD3D11H265DecClass
|
||||
|
@ -527,6 +529,8 @@ gst_d3d11_h265_dec_new_sequence (GstH265Decoder * decoder,
|
|||
GST_ERROR_OBJECT (self, "Failed to negotiate with downstream");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
self->status_report_feedback_number = 0;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
@ -966,6 +970,8 @@ gst_d3d11_h265_dec_end_picture (GstH265Decoder * decoder,
|
|||
GstH265Picture * picture)
|
||||
{
|
||||
GstD3D11H265Dec *self = GST_D3D11_H265_DEC (decoder);
|
||||
GError *err = NULL;
|
||||
GstDXVAStatus status = { 0, };
|
||||
|
||||
GST_LOG_OBJECT (self, "end picture %p, (poc %d)",
|
||||
picture, picture->pic_order_cnt);
|
||||
|
@ -980,6 +986,11 @@ gst_d3d11_h265_dec_end_picture (GstH265Decoder * decoder,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
if (gst_d3d11_decoder_get_status_report (self->d3d11_decoder,
|
||||
&status, &err) && err) {
|
||||
GST_D3D11_VIDEO_DECODER_ERROR_FROM_ERROR (self, err);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -1126,7 +1137,9 @@ gst_d3d11_h265_dec_fill_picture_params (GstD3D11H265Dec * self,
|
|||
params->NoPicReorderingFlag = 0;
|
||||
params->NoBiPredFlag = 0;
|
||||
params->ReservedBits1 = 0;
|
||||
params->StatusReportFeedbackNumber = 1;
|
||||
/* StatusReportFeedbackNumber should be non-zero */
|
||||
params->StatusReportFeedbackNumber = 1 + self->status_report_feedback_number;
|
||||
self->status_report_feedback_number++;
|
||||
|
||||
gst_d3d11_h265_dec_picture_params_from_sps (self, sps, params);
|
||||
gst_d3d11_h265_dec_picture_params_from_pps (self, pps, params);
|
||||
|
|
|
@ -102,6 +102,8 @@ typedef struct _GstD3D11Vp9Dec
|
|||
GstVideoFormat out_format;
|
||||
|
||||
gboolean use_d3d11_output;
|
||||
|
||||
guint status_report_feedback_number;
|
||||
} GstD3D11Vp9Dec;
|
||||
|
||||
typedef struct _GstD3D11Vp9DecClass
|
||||
|
@ -498,6 +500,8 @@ gst_d3d11_vp9_dec_new_sequence (GstVp9Decoder * decoder,
|
|||
GST_ERROR_OBJECT (self, "Failed to negotiate with downstream");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
self->status_report_feedback_number = 0;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
@ -1179,7 +1183,10 @@ gst_d3d11_vp9_dec_decode_picture (GstVp9Decoder * decoder,
|
|||
pic_params.uncompressed_header_size_byte_aligned =
|
||||
picture->frame_hdr.frame_header_length_in_bytes;
|
||||
pic_params.first_partition_size = picture->frame_hdr.first_partition_size;
|
||||
pic_params.StatusReportFeedbackNumber = 1;
|
||||
/* StatusReportFeedbackNumber should be non-zero */
|
||||
pic_params.StatusReportFeedbackNumber =
|
||||
1 + self->status_report_feedback_number;
|
||||
self->status_report_feedback_number++;
|
||||
|
||||
gst_d3d11_vp9_dec_copy_frame_params (self, picture, &pic_params);
|
||||
gst_d3d11_vp9_dec_copy_reference_frames (self, picture, dpb, &pic_params);
|
||||
|
@ -1195,12 +1202,19 @@ static gboolean
|
|||
gst_d3d11_vp9_dec_end_picture (GstVp9Decoder * decoder, GstVp9Picture * picture)
|
||||
{
|
||||
GstD3D11Vp9Dec *self = GST_D3D11_VP9_DEC (decoder);
|
||||
GError *err = NULL;
|
||||
GstDXVAStatus status = { 0, };
|
||||
|
||||
if (!gst_d3d11_decoder_end_frame (self->d3d11_decoder)) {
|
||||
GST_ERROR_OBJECT (self, "Failed to EndFrame");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (gst_d3d11_decoder_get_status_report (self->d3d11_decoder,
|
||||
&status, &err) && err) {
|
||||
GST_D3D11_VIDEO_DECODER_ERROR_FROM_ERROR (self, err);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue