Commit a783d447 authored by Haihao Xiang's avatar Haihao Xiang

msdk: fix surface allocation

parent cccf5ed3
......@@ -460,29 +460,6 @@ gst_msdk_context_remove_alloc_response (GstMsdkContext * context,
return TRUE;
}
static gboolean
check_surfaces_available (GstMsdkContext * context, GstMsdkAllocResponse * resp)
{
GList *l;
mfxFrameSurface1 *surface = NULL;
GstMsdkContextPrivate *priv = context->priv;
gboolean ret = FALSE;
g_mutex_lock (&priv->mutex);
for (l = resp->surfaces_locked; l;) {
surface = l->data;
l = l->next;
if (!surface->Data.Locked) {
resp->surfaces_locked = g_list_remove (resp->surfaces_locked, surface);
resp->surfaces_avail = g_list_prepend (resp->surfaces_avail, surface);
ret = TRUE;
}
}
g_mutex_unlock (&priv->mutex);
return ret;
}
/*
* There are 3 lists here in GstMsdkContext as the following:
* 1. surfaces_avail : surfaces which are free and unused anywhere
......@@ -500,41 +477,40 @@ gst_msdk_context_get_surface_available (GstMsdkContext * context,
mfxFrameSurface1 *surface = NULL;
GstMsdkAllocResponse *msdk_resp =
gst_msdk_context_get_cached_alloc_responses (context, resp);
gint retry = 0;
GstMsdkContextPrivate *priv = context->priv;
retry:
g_mutex_lock (&priv->mutex);
for (l = msdk_resp->surfaces_avail; l;) {
surface = l->data;
l = l->next;
if (!surface->Data.Locked) {
while (TRUE) {
g_mutex_lock (&priv->mutex);
for (l = msdk_resp->surfaces_avail; l; l = l->next) {
surface = l->data;
l = l->next;
msdk_resp->surfaces_avail =
g_list_remove (msdk_resp->surfaces_avail, surface);
msdk_resp->surfaces_used =
g_list_prepend (msdk_resp->surfaces_used, surface);
break;
}
}
g_mutex_unlock (&priv->mutex);
/*
* If a msdk context is shared by multiple msdk elements,
* upstream msdk element sometimes needs to wait for a gst buffer
* to be released in downstream.
*
* Poll the pool for a maximum of 20 milisecnds.
*
* FIXME: Is there any better way to handle this case?
*/
if (!surface && retry < 20) {
/* If there's no surface available, find unlocked surfaces in the locked list,
* take it back to the available list and then search again.
*/
check_surfaces_available (context, msdk_resp);
retry++;
g_usleep (1000);
goto retry;
for (l = msdk_resp->surfaces_locked; l && !surface; l = l->next) {
surface = l->data;
if (!surface->Data.Locked) {
msdk_resp->surfaces_locked =
g_list_remove (msdk_resp->surfaces_locked, surface);
msdk_resp->surfaces_avail =
g_list_prepend (msdk_resp->surfaces_used, surface);
} else
surface = NULL;
}
g_mutex_unlock (&priv->mutex);
if (surface == NULL)
g_thread_yield ();
else
break;
}
return surface;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment