diff options
author | Haihao Xiang <haihao.xiang@intel.com> | 2019-02-02 13:26:32 +0800 |
---|---|---|
committer | Haihao Xiang <haihao.xiang@intel.com> | 2019-02-03 13:44:56 +0800 |
commit | 6c953438f5ad9ab78114bf3d9e5a6e9b1d913b80 (patch) | |
tree | 7e386539183e3416b47d1e707bef202aed08d635 /sys/msdk/gstmsdkdec.c | |
parent | 1a96759a342878e0cad1e7777fbd6630cca75bc0 (diff) |
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/msdk/gstmsdkdec.c')
-rw-r--r-- | sys/msdk/gstmsdkdec.c | 14 |
1 files changed, 12 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; |