From ee5d8ee2023df8b3983bde199f513d48c87f951b Mon Sep 17 00:00:00 2001 From: =?utf8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 6 Aug 2015 18:48:13 +0200 Subject: [PATCH] vaapidecodebin: ensure VPP before going to READY 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 | 56 ++++++++++++++++++++++++++++++++++++++++++ gst/vaapi/gstvaapipluginutil.c | 15 +++++++++++ gst/vaapi/gstvaapipluginutil.h | 4 +++ 3 files changed, 75 insertions(+) diff --git a/gst/vaapi/gstvaapidecodebin.c b/gst/vaapi/gstvaapidecodebin.c index 1e72278..121bda7 100644 --- a/gst/vaapi/gstvaapidecodebin.c +++ b/gst/vaapi/gstvaapidecodebin.c @@ -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); diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c index c23cd16..ef3c6cf 100644 --- a/gst/vaapi/gstvaapipluginutil.c +++ b/gst/vaapi/gstvaapipluginutil.c @@ -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); +} diff --git a/gst/vaapi/gstvaapipluginutil.h b/gst/vaapi/gstvaapipluginutil.h index 3decd05..94050fb 100644 --- a/gst/vaapi/gstvaapipluginutil.h +++ b/gst/vaapi/gstvaapipluginutil.h @@ -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 */ -- 2.7.4