mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-03 15:06:34 +00:00
msdkdec: postpone surface free for VC1
For a skipped frame in VC1, MSDK returns the mfx surface of the reference frame, so we have to make sure the corresponding surface for the reference frame is not freed. In this fix, we postpone surface free because we don't know whether a surface is referenced Before this fix, the error is like as below: New clock: GstSystemClock 0:00:00.181793130 23098 0x55f8a9d622d0 ERROR msdkdec gstmsdkdec.c:622:gst_msdkdec_finish_task:<msdkvc1dec0> Couldn't find the cached MSDK surface Sample pipeline: gst-launch-1.0 filesrc location=input_has_skipped_frame.wmv ! asfdemux ! vc1parse ! msdkvc1dec ! glimagesink
This commit is contained in:
parent
c689c94458
commit
f840e304f3
3 changed files with 26 additions and 1 deletions
|
@ -589,6 +589,22 @@ _find_msdk_surface (gconstpointer msdk_surface, gconstpointer comp_surface)
|
|||
return cached_surface ? cached_surface->surface != _surface : -1;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_msdkdec_free_unlocked_msdk_surfaces (GstMsdkDec * thiz,
|
||||
MsdkSurface * curr_surface)
|
||||
{
|
||||
GList *l;
|
||||
MsdkSurface *surface;
|
||||
|
||||
for (l = thiz->decoded_msdk_surfaces; l;) {
|
||||
surface = l->data;
|
||||
l = l->next;
|
||||
|
||||
if (surface != curr_surface && surface->surface->Data.Locked == 0)
|
||||
free_surface (thiz, surface);
|
||||
}
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
gst_msdkdec_finish_task (GstMsdkDec * thiz, MsdkDecTask * task)
|
||||
{
|
||||
|
@ -632,7 +648,8 @@ gst_msdkdec_finish_task (GstMsdkDec * thiz, MsdkDecTask * task)
|
|||
}
|
||||
}
|
||||
|
||||
free_surface (thiz, surface);
|
||||
if (!thiz->postpone_free_surface)
|
||||
free_surface (thiz, surface);
|
||||
task->sync_point = NULL;
|
||||
task->surface = NULL;
|
||||
task->decode_only = FALSE;
|
||||
|
@ -995,6 +1012,8 @@ gst_msdkdec_handle_frame (GstVideoDecoder * decoder, GstVideoCodecFrame * frame)
|
|||
}
|
||||
|
||||
for (;;) {
|
||||
if (thiz->postpone_free_surface)
|
||||
gst_msdkdec_free_unlocked_msdk_surfaces (thiz, surface);
|
||||
task = &g_array_index (thiz->tasks, MsdkDecTask, thiz->next_task);
|
||||
flow = gst_msdkdec_finish_task (thiz, task);
|
||||
if (flow != GST_FLOW_OK)
|
||||
|
@ -1376,6 +1395,8 @@ gst_msdkdec_drain (GstVideoDecoder * decoder)
|
|||
session = gst_msdk_context_get_session (thiz->context);
|
||||
|
||||
for (;;) {
|
||||
if (thiz->postpone_free_surface)
|
||||
gst_msdkdec_free_unlocked_msdk_surfaces (thiz, surface);
|
||||
task = &g_array_index (thiz->tasks, MsdkDecTask, thiz->next_task);
|
||||
if ((flow = gst_msdkdec_finish_task (thiz, task)) != GST_FLOW_OK) {
|
||||
if (flow != GST_FLOW_FLUSHING)
|
||||
|
@ -1599,5 +1620,6 @@ gst_msdkdec_init (GstMsdkDec * thiz)
|
|||
thiz->do_renego = TRUE;
|
||||
thiz->do_realloc = TRUE;
|
||||
thiz->force_reset_on_res_change = TRUE;
|
||||
thiz->postpone_free_surface = FALSE;
|
||||
thiz->adapter = gst_adapter_new ();
|
||||
}
|
||||
|
|
|
@ -86,6 +86,8 @@ struct _GstMsdkDec
|
|||
* include downstream requirement, msdk suggestion and extra
|
||||
* surface allocation for smooth display in render pipeline */
|
||||
guint min_prealloc_buffers;
|
||||
/* postpone surface free */
|
||||
gboolean postpone_free_surface;
|
||||
|
||||
/* MFX context */
|
||||
GstMsdkContext *context;
|
||||
|
|
|
@ -82,6 +82,7 @@ gst_msdkvc1dec_configure (GstMsdkDec * decoder)
|
|||
if (!structure)
|
||||
return FALSE;
|
||||
|
||||
decoder->postpone_free_surface = TRUE;
|
||||
decoder->param.mfx.CodecId = MFX_CODEC_VC1;
|
||||
|
||||
profile_str = gst_structure_get_string (structure, "profile");
|
||||
|
|
Loading…
Reference in a new issue