diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 6b24c2d326..c8274829b3 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -160,7 +160,7 @@ static const GstVaapiDecoderMap vaapi_decode_map[] = { }; static GstElementClass *parent_class = NULL; -GST_VAAPI_PLUGIN_BASE_DEFINE_SET_CONTEXT (parent_class); +GST_VAAPI_PLUGIN_BASE_DEFINE_VMETHODS (parent_class); static gboolean gst_vaapidecode_update_sink_caps (GstVaapiDecode * decode, GstCaps * caps); @@ -1265,6 +1265,7 @@ gst_vaapidecode_class_init (GstVaapiDecodeClass * klass) } element_class->set_context = gst_vaapi_base_set_context; + element_class->change_state = GST_DEBUG_FUNCPTR (gst_vaapi_base_change_state); gst_element_class_set_static_metadata (element_class, longname, "Codec/Decoder/Video", GST_PLUGIN_DESC, "Gwenole Beauchesne , " diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index e762e1eec6..2863589fbf 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -35,6 +35,9 @@ /* Default debug category is from the subclass */ #define GST_CAT_DEFAULT (plugin->debug_category) +/* Environment variable for disable driver white-list */ +#define GST_VAAPI_ALL_DRIVERS_ENV "GST_VAAPI_ALL_DRIVERS" + /* GstVideoContext interface */ static void plugin_set_display (GstVaapiPluginBase * plugin, GstVaapiDisplay * display) @@ -76,6 +79,57 @@ gst_vaapi_plugin_base_set_context (GstVaapiPluginBase * plugin, plugin_set_display (plugin, display); } +/** + * gst_vaapi_plugin_base_driver_is_whitelisted: + * @plugin: a #GstVaapiPluginBase instance + * + * Looks the VA-API driver vendors in an internal white-list. + * + * Returns: %TRUE if driver is in the white-list, otherwise %FALSE + **/ +gboolean +gst_vaapi_plugin_base_driver_is_whitelisted (GstVaapiPluginBase * plugin) +{ + const gchar *vendor; + guint i; + GstVaapiDisplay *display; + static const gchar *whitelist[] = { + "Intel i965 driver", + "mesa gallium vaapi", + NULL + }; + + if (g_getenv (GST_VAAPI_ALL_DRIVERS_ENV)) + return TRUE; + + display = GST_VAAPI_PLUGIN_BASE_DISPLAY (plugin); + if (!display) + goto no_display; + vendor = gst_vaapi_display_get_vendor_string (display); + if (!vendor) + goto no_vendor; + for (i = 0; whitelist[i]; i++) { + if (g_ascii_strncasecmp (vendor, whitelist[i], strlen (whitelist[i])) == 0) + return TRUE; + } + + GST_ERROR ("Unsupported VA driver: %s. Export environment variable " + GST_VAAPI_ALL_DRIVERS_ENV " to bypass", vendor); + return FALSE; + + /* ERRORS */ +no_display: + { + GST_WARNING_OBJECT (plugin, "no VA-API display available"); + return FALSE; + } +no_vendor: + { + GST_WARNING_OBJECT (plugin, "no VA-API driver vendor description"); + return FALSE; + } +} + void gst_vaapi_plugin_base_init_interfaces (GType g_define_type_id) { diff --git a/gst/vaapi/gstvaapipluginbase.h b/gst/vaapi/gstvaapipluginbase.h index d51a5dc850..0694bf74c7 100644 --- a/gst/vaapi/gstvaapipluginbase.h +++ b/gst/vaapi/gstvaapipluginbase.h @@ -102,6 +102,10 @@ typedef struct _GstVaapiPluginBaseClass GstVaapiPluginBaseClass; (gst_vaapi_display_replace(&GST_VAAPI_PLUGIN_BASE_DISPLAY(plugin), \ (new_display))) +#define GST_VAAPI_PLUGIN_BASE_DEFINE_VMETHODS(parent_class) \ + GST_VAAPI_PLUGIN_BASE_DEFINE_SET_CONTEXT(parent_class) \ + GST_VAAPI_PLUGIN_BASE_DEFINE_CHANGE_STATE(parent_class) + #define GST_VAAPI_PLUGIN_BASE_DEFINE_SET_CONTEXT(parent_class) \ static void \ gst_vaapi_base_set_context (GstElement * element, GstContext * context) \ @@ -112,6 +116,31 @@ typedef struct _GstVaapiPluginBaseClass GstVaapiPluginBaseClass; GST_ELEMENT_CLASS (parent_class)->set_context (element, context); \ } +#define GST_VAAPI_PLUGIN_BASE_DEFINE_CHANGE_STATE(parent_class) \ + static GstStateChangeReturn \ + gst_vaapi_base_change_state (GstElement * element, \ + GstStateChange transition) \ + { \ + GstStateChangeReturn ret; \ + \ + ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, \ + transition); \ + if (ret == GST_STATE_CHANGE_FAILURE) \ + return ret; \ + \ + switch (transition) { \ + case GST_STATE_CHANGE_NULL_TO_READY:{ \ + GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (element); \ + if (!gst_vaapi_plugin_base_driver_is_whitelisted (plugin)) \ + ret = GST_STATE_CHANGE_FAILURE; \ + break; \ + } \ + default: \ + break; \ + } \ + return ret; \ + } + struct _GstVaapiPluginBase { /*< private >*/ @@ -230,6 +259,10 @@ GstFlowReturn gst_vaapi_plugin_base_get_input_buffer (GstVaapiPluginBase * plugin, GstBuffer * inbuf, GstBuffer ** outbuf_ptr); +G_GNUC_INTERNAL +gboolean +gst_vaapi_plugin_base_driver_is_whitelisted (GstVaapiPluginBase * plugin); + G_GNUC_INTERNAL void gst_vaapi_plugin_base_set_context (GstVaapiPluginBase * plugin,