vaapidecodebin: ensure VPP before going to READY
authorVíctor Manuel Jáquez Leal <victorx.jaquez@intel.com>
Thu, 6 Aug 2015 16:48:13 +0000 (18:48 +0200)
committerVíctor Manuel Jáquez Leal <victorx.jaquez@intel.com>
Thu, 13 Aug 2015 15:34:42 +0000 (17:34 +0200)
There are sometimes that the VA-API display context is not shared among the
pipeline, but it is important to know it before going to READY state (when the
pipeline is already linked).

One instance of this case is this:

gst-launch-1.0 filesrc location=media ! decodebin ! vaapipostproc ! vaapisink

This patch adds a new function in gstvaapipluginutil called
gst_vaapi_create_test_display(). Its purpose is to create a disposable VA-API
display, which only will be used for verify if the VAEntrypointVideoProc is
available by the hardware. Afterwards, it should be unrefed.

If the vaapidecodebin is going to READY state, and the element still doesn't
know if VPP is available, the last resort is to create a new instance of the
VA-API display and test for it.

https://bugzilla.gnome.org/show_bug.cgi?id=749554

gst/vaapi/gstvaapidecodebin.c
gst/vaapi/gstvaapipluginutil.c
gst/vaapi/gstvaapipluginutil.h

index 1e72278871ccb37e38d1ccd08b2b1e3e79fa5a34..121bda73a0bcce0737d80f3e349706ca3ed39a5a 100644 (file)
@@ -176,6 +176,30 @@ connect_src_ghost_pad:
   }
 }
 
+static gboolean
+ensure_vpp (GstVaapiDecodeBin * vaapidecbin)
+{
+  GstVaapiDisplay *display;
+
+  if (vaapidecbin->has_vpp != HAS_VPP_UNKNOWN)
+    return TRUE;
+
+  GST_DEBUG_OBJECT (vaapidecbin, "Creating a dummy display to test for vpp");
+  display = gst_vaapi_create_test_display ();
+  if (!display)
+    return FALSE;
+
+  vaapidecbin->has_vpp = gst_vaapi_display_has_video_processing (display) ?
+    HAS_VPP_YES : HAS_VPP_NO;
+
+  gst_vaapi_display_unref (display);
+
+  if (!activate_vpp (vaapidecbin))
+    return FALSE;
+
+  return TRUE;
+}
+
 static void
 gst_vaapi_decode_bin_set_property (GObject * object,
     guint prop_id, const GValue * value, GParamSpec * pspec)
@@ -293,6 +317,35 @@ bail:
       message);
 }
 
+static GstStateChangeReturn
+gst_vaapi_decode_bin_change_state (GstElement * element,
+    GstStateChange transition)
+{
+  GstVaapiDecodeBin *vaapidecbin = GST_VAAPI_DECODE_BIN (element);
+  GstStateChangeReturn ret;
+
+  switch (transition) {
+    default:
+      break;
+  }
+
+  ret = GST_ELEMENT_CLASS (gst_vaapi_decode_bin_parent_class)->change_state
+    (element, transition);
+  if (ret == GST_STATE_CHANGE_FAILURE)
+    return ret;
+
+  switch (transition) {
+    case GST_STATE_CHANGE_NULL_TO_READY:
+      if (!ensure_vpp (vaapidecbin))
+        return GST_STATE_CHANGE_FAILURE;
+      break;
+    default:
+      break;
+  }
+
+  return ret;
+}
+
 static void
 gst_vaapi_decode_bin_class_init (GstVaapiDecodeBinClass * klass)
 {
@@ -307,6 +360,9 @@ gst_vaapi_decode_bin_class_init (GstVaapiDecodeBinClass * klass)
   gobject_class->set_property = gst_vaapi_decode_bin_set_property;
   gobject_class->get_property = gst_vaapi_decode_bin_get_property;
 
+  element_class->change_state =
+      GST_DEBUG_FUNCPTR (gst_vaapi_decode_bin_change_state);
+
   bin_class->handle_message =
       GST_DEBUG_FUNCPTR (gst_vaapi_decode_bin_handle_message);
 
index c23cd160b959a37857a7929661bddda0f50dd17e..ef3c6cffd6f80ac7407d1a379465082a4960e2b3 100644 (file)
@@ -634,3 +634,18 @@ gst_video_info_change_format (GstVideoInfo * vip, GstVideoFormat format,
   vip->fps_n = vi.fps_n;
   vip->fps_d = vi.fps_d;
 }
+
+/**
+ * gst_vaapi_create_test_display:
+ *
+ * Creates a temporal #GstVaapiDisplay instance, just for testing the
+ * supported features.
+ *
+ * Returns: a new #GstVaapiDisplay instances. Free with
+ * gst_vaapi_display_unref () after use.
+ **/
+GstVaapiDisplay *
+gst_vaapi_create_test_display ()
+{
+  return gst_vaapi_create_display (GST_VAAPI_DISPLAY_TYPE_ANY, NULL);
+}
index 3decd059450e46043dce1623c7be3005cac5fe68..94050fb04a54565580e856fe525d4890fa26f3a7 100644 (file)
@@ -122,4 +122,8 @@ void
 gst_video_info_change_format (GstVideoInfo * vip, GstVideoFormat format,
     guint width, guint height);
 
+G_GNUC_INTERNAL
+GstVaapiDisplay *
+gst_vaapi_create_test_display (void);
+
 #endif /* GST_VAAPI_PLUGIN_UTIL_H */