task->decode_only = FALSE;
}
+static void
+gst_msdkdec_frame_corruption_report (GstMsdkDec * thiz, mfxU16 corruption)
+{
+ if (!thiz->report_error || !corruption)
+ return;
+
+ if (corruption & MFX_CORRUPTION_MINOR)
+ GST_ELEMENT_WARNING (thiz, STREAM, DECODE,
+ ("[Corruption] Minor corruption detected!"), (NULL));
+
+ if (corruption & MFX_CORRUPTION_MAJOR)
+ GST_ELEMENT_WARNING (thiz, STREAM, DECODE,
+ ("[Corruption] Major corruption detected!"), (NULL));
+
+ if (corruption & MFX_CORRUPTION_ABSENT_TOP_FIELD)
+ GST_ELEMENT_WARNING (thiz, STREAM, DECODE,
+ ("[Corruption] Absent top field!"), (NULL));
+
+ if (corruption & MFX_CORRUPTION_ABSENT_BOTTOM_FIELD)
+ GST_ELEMENT_WARNING (thiz, STREAM, DECODE,
+ ("[Corruption] Absent bottom field!"), (NULL));
+
+ if (corruption & MFX_CORRUPTION_REFERENCE_FRAME)
+ GST_ELEMENT_WARNING (thiz, STREAM, DECODE,
+ ("[Corruption] Corrupted reference frame!"), (NULL));
+
+ if (corruption & MFX_CORRUPTION_REFERENCE_LIST)
+ GST_ELEMENT_WARNING (thiz, STREAM, DECODE,
+ ("[Corruption] Corrupted reference list!"), (NULL));
+}
+
static GstFlowReturn
gst_msdkdec_finish_task (GstMsdkDec * thiz, MsdkDecTask * task)
{
surface = task->surface;
if (surface) {
+ gst_msdkdec_frame_corruption_report (thiz,
+ surface->surface->Data.Corrupted);
GST_DEBUG_OBJECT (thiz, "Decoded MFX TimeStamp: %" G_GUINT64_FORMAT,
(guint64) surface->surface->Data.TimeStamp);
pts = surface->surface->Data.TimeStamp;
return TRUE;
}
+static void
+gst_msdkdec_error_report (GstMsdkDec * thiz)
+{
+ if (!thiz->report_error)
+ return;
+
+#if (MFX_VERSION >= 1025)
+ else {
+ if (thiz->error_report.ErrorTypes & MFX_ERROR_SPS)
+ GST_ELEMENT_WARNING (thiz, STREAM, DECODE,
+ ("[Error] SPS Error detected!"), (NULL));
+
+ if (thiz->error_report.ErrorTypes & MFX_ERROR_PPS)
+ GST_ELEMENT_WARNING (thiz, STREAM, DECODE,
+ ("[Error] PPS Error detected!"), (NULL));
+
+ if (thiz->error_report.ErrorTypes & MFX_ERROR_SLICEHEADER)
+ GST_ELEMENT_WARNING (thiz, STREAM, DECODE,
+ ("[Error] SliceHeader Error detected!"), (NULL));
+
+ if (thiz->error_report.ErrorTypes & MFX_ERROR_FRAME_GAP)
+ GST_ELEMENT_WARNING (thiz, STREAM, DECODE,
+ ("[Error] Frame Gap Error detected!"), (NULL));
+ }
+#endif
+}
+
static GstFlowReturn
gst_msdkdec_handle_frame (GstVideoDecoder * decoder, GstVideoCodecFrame * frame)
{
* and this information can't be retrieved from the negotiated caps.
* So instead of introducing a codecparser dependency to parse the headers
* inside msdk plugin, we simply use the mfx APIs to extract header information */
+#if (MFX_VERSION >= 1025)
+ if (thiz->report_error)
+ thiz->error_report.ErrorTypes = 0;
+#endif
+
status = MFXVideoDECODE_DecodeHeader (session, &bitstream, &thiz->param);
GST_DEBUG_OBJECT (decoder, "DecodeHeader => %d", status);
+ gst_msdkdec_error_report (thiz);
+
if (status == MFX_ERR_MORE_DATA) {
flow = GST_FLOW_OK;
goto done;
}
}
}
+#if (MFX_VERSION >= 1025)
+ if (thiz->report_error)
+ thiz->error_report.ErrorTypes = 0;
+#endif
status =
MFXVideoDECODE_DecodeFrameAsync (session, &bitstream, surface->surface,
}
GST_DEBUG_OBJECT (decoder, "DecodeFrameAsync => %d", status);
+ gst_msdkdec_error_report (thiz);
/* media-sdk requires complete reset since the surface is inadequate
* for further decoding */
* suitable for the current frame. Call MFXVideoDECODE_DecodeHeader to get
* the current frame size, then do memory re-allocation, otherwise
* MFXVideoDECODE_DecodeFrameAsync will still fail on next call */
+#if (MFX_VERSION >= 1025)
+ if (thiz->report_error)
+ thiz->error_report.ErrorTypes = 0;
+#endif
status = MFXVideoDECODE_DecodeHeader (session, &bitstream, &thiz->param);
GST_DEBUG_OBJECT (decoder, "DecodeHeader => %d", status);
+ gst_msdkdec_error_report (thiz);
+
if (status == MFX_ERR_MORE_DATA) {
flow = GST_FLOW_OK;
goto done;
if (!surface)
return GST_FLOW_ERROR;
}
+#if (MFX_VERSION >= 1025)
+ if (thiz->report_error)
+ thiz->error_report.ErrorTypes = 0;
+#endif
status =
MFXVideoDECODE_DecodeFrameAsync (session, NULL, surface->surface,
}
GST_DEBUG_OBJECT (decoder, "DecodeFrameAsync => %d", status);
+ gst_msdkdec_error_report (thiz);
+
if (G_LIKELY (status == MFX_ERR_NONE)) {
thiz->next_task = (thiz->next_task + 1) % thiz->tasks->len;
surface = NULL;
thiz->do_renego = TRUE;
thiz->do_realloc = TRUE;
thiz->force_reset_on_res_change = TRUE;
+ thiz->report_error = FALSE;
thiz->adapter = gst_adapter_new ();
thiz->input_state = NULL;
thiz->pool = NULL;
* customers still using this for low-latency streaming of non-b-frame
* encoded streams */
decoder->param.mfx.DecodedOrder = h264dec->output_order;
+
+#if (MFX_VERSION >= 1025)
+ if (decoder->report_error) {
+ decoder->error_report.Header.BufferId = MFX_EXTBUFF_DECODE_ERROR_REPORT;
+ decoder->error_report.Header.BufferSz = sizeof (decoder->error_report);
+ decoder->error_report.ErrorTypes = 0;
+ gst_msdkdec_add_bs_extra_param (decoder,
+ (mfxExtBuffer *) & decoder->error_report);
+ }
+#endif
+
return TRUE;
}
const GValue * value, GParamSpec * pspec)
{
GstMsdkH264Dec *thiz = GST_MSDKH264DEC (object);
+#if (MFX_VERSION >= 1025)
+ GstMsdkDec *dec = GST_MSDKDEC (object);
+#endif
GstState state;
GST_OBJECT_LOCK (thiz);
case GST_MSDKDEC_PROP_OUTPUT_ORDER:
thiz->output_order = g_value_get_enum (value);
break;
+#if (MFX_VERSION >= 1025)
+ case GST_MSDKDEC_PROP_ERROR_REPORT:
+ dec->report_error = g_value_get_boolean (value);
+ break;
+#endif
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
GParamSpec * pspec)
{
GstMsdkH264Dec *thiz = GST_MSDKH264DEC (object);
+#if (MFX_VERSION >= 1025)
+ GstMsdkDec *dec = GST_MSDKDEC (object);
+#endif
GST_OBJECT_LOCK (thiz);
switch (prop_id) {
case GST_MSDKDEC_PROP_OUTPUT_ORDER:
g_value_set_enum (value, thiz->output_order);
break;
+#if (MFX_VERSION >= 1025)
+ case GST_MSDKDEC_PROP_ERROR_REPORT:
+ g_value_set_boolean (value, dec->report_error);
+ break;
+#endif
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
gst_msdkdec_prop_install_output_oder_property (gobject_class);
+#if (MFX_VERSION >= 1025)
+ gst_msdkdec_prop_install_error_report_property (gobject_class);
+#endif
+
gst_element_class_add_static_pad_template (element_class, &sink_factory);
}