context: allow dynamic growth of VA surfaces pool.
authorGwenole Beauchesne <gwenole.beauchesne@intel.com>
Sat, 3 May 2014 13:56:51 +0000 (15:56 +0200)
committerGwenole Beauchesne <gwenole.beauchesne@intel.com>
Wed, 21 May 2014 17:59:52 +0000 (19:59 +0200)
Add support for dynamic growth of the VA surfaces pool. For decoding,
this implies the recreation of the underlying VA context, as per the
requirement from VA-API. Besides, only increases are supported, not
shrinks.

gst-libs/gst/vaapi/gstvaapicontext.c

index 27efdd9..185ed7f 100644 (file)
@@ -47,6 +47,9 @@
 /* Define default VA surface chroma format to YUV 4:2:0 */
 #define DEFAULT_CHROMA_TYPE (GST_VAAPI_CHROMA_TYPE_YUV420)
 
+/* Number of scratch surfaces beyond those used as reference */
+#define SCRATCH_SURFACES_COUNT (4)
+
 static void
 unref_surface_cb (GstVaapiSurface * surface)
 {
@@ -106,15 +109,33 @@ context_destroy (GstVaapiContext * context)
 }
 
 static gboolean
-context_create_surfaces (GstVaapiContext * context)
+context_ensure_surfaces (GstVaapiContext * context)
 {
   const GstVaapiContextInfo *const cip = &context->info;
-  GstVideoInfo vi;
+  const guint num_surfaces = cip->ref_frames + SCRATCH_SURFACES_COUNT;
   GstVaapiSurface *surface;
-  guint i, num_surfaces;
+  guint i;
 
-  /* Number of scratch surfaces beyond those used as reference */
-  const guint SCRATCH_SURFACES_COUNT = 4;
+  for (i = context->surfaces->len; i < num_surfaces; i++) {
+    surface = gst_vaapi_surface_new (GST_VAAPI_OBJECT_DISPLAY (context),
+        cip->chroma_type, cip->width, cip->height);
+    if (!surface)
+      return FALSE;
+    gst_vaapi_surface_set_parent_context (surface, context);
+    g_ptr_array_add (context->surfaces, surface);
+    if (!gst_vaapi_video_pool_add_object (context->surfaces_pool, surface))
+      return FALSE;
+  }
+  gst_vaapi_video_pool_set_capacity (context->surfaces_pool, num_surfaces);
+  return TRUE;
+}
+
+static gboolean
+context_create_surfaces (GstVaapiContext * context)
+{
+  const GstVaapiContextInfo *const cip = &context->info;
+  GstVideoInfo vi;
+  guint num_surfaces;
 
   if (!gst_vaapi_context_overlay_reset (context))
     return FALSE;
@@ -135,19 +156,7 @@ context_create_surfaces (GstVaapiContext * context)
     if (!context->surfaces_pool)
       return FALSE;
   }
-  gst_vaapi_video_pool_set_capacity (context->surfaces_pool, num_surfaces);
-
-  for (i = context->surfaces->len; i < num_surfaces; i++) {
-    surface = gst_vaapi_surface_new (GST_VAAPI_OBJECT_DISPLAY (context),
-        cip->chroma_type, cip->width, cip->height);
-    if (!surface)
-      return FALSE;
-    gst_vaapi_surface_set_parent_context (surface, context);
-    g_ptr_array_add (context->surfaces, surface);
-    if (!gst_vaapi_video_pool_add_object (context->surfaces_pool, surface))
-      return FALSE;
-  }
-  return TRUE;
+  return context_ensure_surfaces (context);
 }
 
 static gboolean
@@ -370,6 +379,7 @@ gst_vaapi_context_reset (GstVaapiContext * context,
 {
   GstVaapiContextInfo *const cip = &context->info;
   gboolean reset_surfaces = FALSE, reset_config = FALSE;
+  gboolean grow_surfaces = FALSE;
   GstVaapiChromaType chroma_type;
 
   chroma_type = new_cip->chroma_type ? new_cip->chroma_type :
@@ -392,6 +402,11 @@ gst_vaapi_context_reset (GstVaapiContext * context,
     reset_config = TRUE;
   }
 
+  if (cip->ref_frames < new_cip->ref_frames) {
+    cip->ref_frames = new_cip->ref_frames;
+    grow_surfaces = TRUE;
+  }
+
   if (cip->usage != new_cip->usage) {
     cip->usage = new_cip->usage;
     reset_config = TRUE;
@@ -400,7 +415,7 @@ gst_vaapi_context_reset (GstVaapiContext * context,
     if (context_update_config_encoder (context, &new_cip->config.encoder))
       reset_config = TRUE;
   } else if (new_cip->usage == GST_VAAPI_CONTEXT_USAGE_DECODE) {
-    if (reset_surfaces)
+    if (reset_surfaces || grow_surfaces)
       reset_config = TRUE;
   }
 
@@ -411,6 +426,8 @@ gst_vaapi_context_reset (GstVaapiContext * context,
 
   if (reset_surfaces && !context_create_surfaces (context))
     return FALSE;
+  else if (grow_surfaces && !context_ensure_surfaces (context))
+    return FALSE;
   if (reset_config && !context_create (context))
     return FALSE;
   return TRUE;