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
This commit is contained in:
Víctor Manuel Jáquez Leal 2015-08-06 18:48:13 +02:00
parent 1e061c54e1
commit ee5d8ee202
3 changed files with 75 additions and 0 deletions

View 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);

View 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);
}

View 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 */