mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-21 13:36:39 +00:00
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.
This commit is contained in:
parent
1a96759a34
commit
6c953438f5
2 changed files with 14 additions and 2 deletions
|
@ -611,9 +611,12 @@ gst_msdkdec_finish_task (GstMsdkDec * thiz, MsdkDecTask * task)
|
||||||
GST_ERROR_OBJECT (thiz, "failed to do sync operation");
|
GST_ERROR_OBJECT (thiz, "failed to do sync operation");
|
||||||
return GST_FLOW_ERROR;
|
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);
|
frame = gst_msdkdec_get_oldest_frame (decoder);
|
||||||
task->sync_point = NULL;
|
|
||||||
|
|
||||||
l = g_list_find_custom (thiz->decoded_msdk_surfaces, task->surface,
|
l = g_list_find_custom (thiz->decoded_msdk_surfaces, task->surface,
|
||||||
_find_msdk_surface);
|
_find_msdk_surface);
|
||||||
|
@ -634,11 +637,16 @@ gst_msdkdec_finish_task (GstMsdkDec * thiz, MsdkDecTask * task)
|
||||||
}
|
}
|
||||||
|
|
||||||
free_surface (thiz, surface);
|
free_surface (thiz, surface);
|
||||||
|
task->sync_point = NULL;
|
||||||
|
task->surface = NULL;
|
||||||
|
task->decode_only = FALSE;
|
||||||
|
|
||||||
if (!frame)
|
if (!frame)
|
||||||
return GST_FLOW_FLUSHING;
|
return GST_FLOW_FLUSHING;
|
||||||
gst_video_codec_frame_unref (frame);
|
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);
|
flow = gst_video_decoder_finish_frame (decoder, frame);
|
||||||
return flow;
|
return flow;
|
||||||
}
|
}
|
||||||
|
@ -1017,9 +1025,11 @@ gst_msdkdec_handle_frame (GstVideoDecoder * decoder, GstVideoCodecFrame * frame)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else if (status == MFX_ERR_MORE_DATA) {
|
} 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)
|
if (surface->surface->Data.Locked > 0)
|
||||||
surface = NULL;
|
surface = NULL;
|
||||||
flow = GST_FLOW_OK;
|
flow = GST_VIDEO_DECODER_FLOW_NEED_DATA;
|
||||||
break;
|
break;
|
||||||
} else if (status == MFX_ERR_MORE_SURFACE) {
|
} else if (status == MFX_ERR_MORE_SURFACE) {
|
||||||
surface = NULL;
|
surface = NULL;
|
||||||
|
|
|
@ -113,6 +113,8 @@ struct _MsdkDecTask
|
||||||
{
|
{
|
||||||
mfxFrameSurface1 *surface;
|
mfxFrameSurface1 *surface;
|
||||||
mfxSyncPoint sync_point;
|
mfxSyncPoint sync_point;
|
||||||
|
|
||||||
|
gboolean decode_only;
|
||||||
};
|
};
|
||||||
|
|
||||||
GType gst_msdkdec_get_type (void);
|
GType gst_msdkdec_get_type (void);
|
||||||
|
|
Loading…
Reference in a new issue