summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorHaihao Xiang <haihao.xiang@intel.com>2019-02-02 13:26:32 +0800
committerHaihao Xiang <haihao.xiang@intel.com>2019-02-03 13:44:56 +0800
commit6c953438f5ad9ab78114bf3d9e5a6e9b1d913b80 (patch)
tree7e386539183e3416b47d1e707bef202aed08d635 /sys
parent1a96759a342878e0cad1e7777fbd6630cca75bc0 (diff)
downloadgstreamer-plugins-bad-6c953438f5ad9ab78114bf3d9e5a6e9b1d913b80.tar.gz
msdkdec: Release occupied surface for MFX_ERR_MORE_DATA
An output surface is returned but without sync point when when MFXVideoDECODE_DecodeFrameAsync () returns MFX_ERR_MORE_DATA, this surface should be released too, otherwise the surface is occupied and it is easy to exhaust all pre-allocated mfx surfaces. Example pipeline (input_vp8.webm contains lots of frame with show_frame set to 0): gst-launch-1.0 filesrc location=input_vp8.webm ! matroskademux ! msdkvp8dec ! msdkvpp ! fakesink 0:00:05.995959693 19866 0x563f30f14590 ERROR default gstmsdkvideomemory.c:77:gst_msdk_video_allocator_get_surface: failed to get surface available ERROR: from element /GstPipeline:pipeline0/GstMatroskaDemux:matroskademux0: Internal data stream error.
Diffstat (limited to 'sys')
-rw-r--r--sys/msdk/gstmsdkdec.c14
-rw-r--r--sys/msdk/gstmsdkdec.h2
2 files changed, 14 insertions, 2 deletions
diff --git a/sys/msdk/gstmsdkdec.c b/sys/msdk/gstmsdkdec.c
index 9cc5e28cd..db58112a3 100644
--- a/sys/msdk/gstmsdkdec.c
+++ b/sys/msdk/gstmsdkdec.c
@@ -611,9 +611,12 @@ gst_msdkdec_finish_task (GstMsdkDec * thiz, MsdkDecTask * task)
GST_ERROR_OBJECT (thiz, "failed to do sync operation");
return GST_FLOW_ERROR;
}
+ }
+
+ if (G_LIKELY (task->sync_point || (task->surface && task->decode_only))) {
+ gboolean decode_only = task->decode_only;
frame = gst_msdkdec_get_oldest_frame (decoder);
- task->sync_point = NULL;
l = g_list_find_custom (thiz->decoded_msdk_surfaces, task->surface,
_find_msdk_surface);
@@ -634,11 +637,16 @@ gst_msdkdec_finish_task (GstMsdkDec * thiz, MsdkDecTask * task)
}
free_surface (thiz, surface);
+ task->sync_point = NULL;
+ task->surface = NULL;
+ task->decode_only = FALSE;
if (!frame)
return GST_FLOW_FLUSHING;
gst_video_codec_frame_unref (frame);
+ if (decode_only)
+ GST_VIDEO_CODEC_FRAME_SET_DECODE_ONLY (frame);
flow = gst_video_decoder_finish_frame (decoder, frame);
return flow;
}
@@ -1017,9 +1025,11 @@ gst_msdkdec_handle_frame (GstVideoDecoder * decoder, GstVideoCodecFrame * frame)
break;
}
} else if (status == MFX_ERR_MORE_DATA) {
+ task->decode_only = TRUE;
+ thiz->next_task = (thiz->next_task + 1) % thiz->tasks->len;
if (surface->surface->Data.Locked > 0)
surface = NULL;
- flow = GST_FLOW_OK;
+ flow = GST_VIDEO_DECODER_FLOW_NEED_DATA;
break;
} else if (status == MFX_ERR_MORE_SURFACE) {
surface = NULL;
diff --git a/sys/msdk/gstmsdkdec.h b/sys/msdk/gstmsdkdec.h
index 36f73e6a9..fc82415ac 100644
--- a/sys/msdk/gstmsdkdec.h
+++ b/sys/msdk/gstmsdkdec.h
@@ -113,6 +113,8 @@ struct _MsdkDecTask
{
mfxFrameSurface1 *surface;
mfxSyncPoint sync_point;
+
+ gboolean decode_only;
};
GType gst_msdkdec_get_type (void);