msdk: manage child sessions on parent GstMsdkContext

Sometimes parent context is released before its children get released.
In this case MFXClose of parent session fails.

To make sure that child sessions are closed before closing a parent
session,
Parent context needs to manage child sessions and close them first when
it's released.

https://bugzilla.gnome.org/show_bug.cgi?id=793412
diff --git a/sys/msdk/gstmsdkcontext.c b/sys/msdk/gstmsdkcontext.c
index 352148f..4447474 100644
--- a/sys/msdk/gstmsdkcontext.c
+++ b/sys/msdk/gstmsdkcontext.c
@@ -59,6 +59,7 @@
   GstMsdkContextJobType job_type;
   gint shared_async_depth;
   GMutex mutex;
+  GList *child_session_list;
 #ifndef _WIN32
   gint fd;
   VADisplay dpy;
@@ -214,15 +215,28 @@
 }
 
 static void
+release_child_session (gpointer session)
+{
+  mfxStatus status;
+
+  mfxSession _session = session;
+  status = MFXDisjoinSession (_session);
+  if (status != MFX_ERR_NONE)
+    GST_WARNING ("failed to disjoin (%s)", msdk_status_to_string (status));
+  msdk_close_session (_session);
+}
+
+static void
 gst_msdk_context_finalize (GObject * obj)
 {
   GstMsdkContext *context = GST_MSDK_CONTEXT_CAST (obj);
   GstMsdkContextPrivate *priv = context->priv;
 
-  if (priv->is_joined) {
-    MFXDisjoinSession (priv->session);
+  /* child sessions will be closed when the parent session is closed */
+  if (priv->is_joined)
     goto done;
-  }
+  else
+    g_list_free_full (priv->child_session_list, release_child_session);
 
   msdk_close_session (priv->session);
   g_mutex_clear (&priv->mutex);
@@ -284,6 +298,8 @@
   priv->is_joined = TRUE;
   priv->hardware = parent_priv->hardware;
   priv->job_type = parent_priv->job_type;
+  parent_priv->child_session_list =
+      g_list_prepend (parent_priv->child_session_list, priv->session);
 #ifndef _WIN32
   priv->dpy = parent_priv->dpy;
   priv->fd = parent_priv->fd;