mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 04:36:20 +00:00
decodebin2: Link elements before testing if they can reach the READY state
This is made possible by filtering errors. This is required to let harware accelerated element query the video context. The video context is used to determine if the HW is capable, and thus if the element is supported or not. Fixes bug #662330.
This commit is contained in:
parent
54be243757
commit
cf9da5c280
1 changed files with 72 additions and 24 deletions
|
@ -175,6 +175,8 @@ struct _GstDecodeBin
|
||||||
gboolean expose_allstreams; /* Whether to expose unknow type streams or not */
|
gboolean expose_allstreams; /* Whether to expose unknow type streams or not */
|
||||||
|
|
||||||
gboolean upstream_seekable; /* if upstream is seekable */
|
gboolean upstream_seekable; /* if upstream is seekable */
|
||||||
|
|
||||||
|
GList *filtered; /* elements for which error messages are filtered */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstDecodeBinClass
|
struct _GstDecodeBinClass
|
||||||
|
@ -296,6 +298,7 @@ static void caps_notify_cb (GstPad * pad, GParamSpec * unused,
|
||||||
static GstPad *find_sink_pad (GstElement * element);
|
static GstPad *find_sink_pad (GstElement * element);
|
||||||
static GstStateChangeReturn gst_decode_bin_change_state (GstElement * element,
|
static GstStateChangeReturn gst_decode_bin_change_state (GstElement * element,
|
||||||
GstStateChange transition);
|
GstStateChange transition);
|
||||||
|
static void gst_decode_bin_handle_message (GstBin * bin, GstMessage * message);
|
||||||
|
|
||||||
#define EXPOSE_LOCK(dbin) G_STMT_START { \
|
#define EXPOSE_LOCK(dbin) G_STMT_START { \
|
||||||
GST_LOG_OBJECT (dbin, \
|
GST_LOG_OBJECT (dbin, \
|
||||||
|
@ -588,9 +591,11 @@ gst_decode_bin_class_init (GstDecodeBinClass * klass)
|
||||||
{
|
{
|
||||||
GObjectClass *gobject_klass;
|
GObjectClass *gobject_klass;
|
||||||
GstElementClass *gstelement_klass;
|
GstElementClass *gstelement_klass;
|
||||||
|
GstBinClass *gstbin_klass;
|
||||||
|
|
||||||
gobject_klass = (GObjectClass *) klass;
|
gobject_klass = (GObjectClass *) klass;
|
||||||
gstelement_klass = (GstElementClass *) klass;
|
gstelement_klass = (GstElementClass *) klass;
|
||||||
|
gstbin_klass = (GstBinClass *) klass;
|
||||||
|
|
||||||
parent_class = g_type_class_peek_parent (klass);
|
parent_class = g_type_class_peek_parent (klass);
|
||||||
|
|
||||||
|
@ -937,6 +942,9 @@ gst_decode_bin_class_init (GstDecodeBinClass * klass)
|
||||||
|
|
||||||
gstelement_klass->change_state =
|
gstelement_klass->change_state =
|
||||||
GST_DEBUG_FUNCPTR (gst_decode_bin_change_state);
|
GST_DEBUG_FUNCPTR (gst_decode_bin_change_state);
|
||||||
|
|
||||||
|
gstbin_klass->handle_message =
|
||||||
|
GST_DEBUG_FUNCPTR (gst_decode_bin_handle_message);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Must be called with factories lock! */
|
/* Must be called with factories lock! */
|
||||||
|
@ -1731,6 +1739,21 @@ setup_caps_delay:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
add_error_filter (GstDecodeBin * dbin, GstElement * element)
|
||||||
|
{
|
||||||
|
GST_OBJECT_LOCK (dbin);
|
||||||
|
dbin->filtered = g_list_prepend (dbin->filtered, element);
|
||||||
|
GST_OBJECT_UNLOCK (dbin);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
remove_error_filter (GstDecodeBin * dbin, GstElement * element)
|
||||||
|
{
|
||||||
|
GST_OBJECT_LOCK (dbin);
|
||||||
|
dbin->filtered = g_list_remove (dbin->filtered, element);
|
||||||
|
GST_OBJECT_UNLOCK (dbin);
|
||||||
|
}
|
||||||
|
|
||||||
/* connect_pad:
|
/* connect_pad:
|
||||||
*
|
*
|
||||||
|
@ -1855,45 +1878,52 @@ connect_pad (GstDecodeBin * dbin, GstElement * src, GstDecodePad * dpad,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ... activate it ... We do this before adding it to the bin so that we
|
/* Filter errors, this will prevent the element from causing the pipeline
|
||||||
* don't accidentally make it post error messages that will stop
|
* to error while we test it using READY state. */
|
||||||
* everything. */
|
add_error_filter (dbin, element);
|
||||||
if ((gst_element_set_state (element,
|
|
||||||
GST_STATE_READY)) == GST_STATE_CHANGE_FAILURE) {
|
|
||||||
GST_WARNING_OBJECT (dbin, "Couldn't set %s to READY",
|
|
||||||
GST_ELEMENT_NAME (element));
|
|
||||||
gst_object_unref (element);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 2.3. Find its sink pad, this should work after activating it. */
|
/* ... add it ... */
|
||||||
if (!(sinkpad = find_sink_pad (element))) {
|
|
||||||
GST_WARNING_OBJECT (dbin, "Element %s doesn't have a sink pad",
|
|
||||||
GST_ELEMENT_NAME (element));
|
|
||||||
gst_element_set_state (element, GST_STATE_NULL);
|
|
||||||
gst_object_unref (element);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 2.4 add it ... */
|
|
||||||
if (!(gst_bin_add (GST_BIN_CAST (dbin), element))) {
|
if (!(gst_bin_add (GST_BIN_CAST (dbin), element))) {
|
||||||
GST_WARNING_OBJECT (dbin, "Couldn't add %s to the bin",
|
GST_WARNING_OBJECT (dbin, "Couldn't add %s to the bin",
|
||||||
GST_ELEMENT_NAME (element));
|
GST_ELEMENT_NAME (element));
|
||||||
gst_object_unref (sinkpad);
|
remove_error_filter (dbin, element);
|
||||||
gst_element_set_state (element, GST_STATE_NULL);
|
|
||||||
gst_object_unref (element);
|
gst_object_unref (element);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 2.5 ...and try to link */
|
/* Find its sink pad. */
|
||||||
|
if (!(sinkpad = find_sink_pad (element))) {
|
||||||
|
GST_WARNING_OBJECT (dbin, "Element %s doesn't have a sink pad",
|
||||||
|
GST_ELEMENT_NAME (element));
|
||||||
|
remove_error_filter (dbin, element);
|
||||||
|
gst_bin_remove (GST_BIN (dbin), element);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ... and try to link */
|
||||||
if ((gst_pad_link (pad, sinkpad)) != GST_PAD_LINK_OK) {
|
if ((gst_pad_link (pad, sinkpad)) != GST_PAD_LINK_OK) {
|
||||||
GST_WARNING_OBJECT (dbin, "Link failed on pad %s:%s",
|
GST_WARNING_OBJECT (dbin, "Link failed on pad %s:%s",
|
||||||
GST_DEBUG_PAD_NAME (sinkpad));
|
GST_DEBUG_PAD_NAME (sinkpad));
|
||||||
gst_element_set_state (element, GST_STATE_NULL);
|
remove_error_filter (dbin, element);
|
||||||
gst_object_unref (sinkpad);
|
gst_object_unref (sinkpad);
|
||||||
gst_bin_remove (GST_BIN (dbin), element);
|
gst_bin_remove (GST_BIN (dbin), element);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ... activate it ... */
|
||||||
|
if ((gst_element_set_state (element,
|
||||||
|
GST_STATE_READY)) == GST_STATE_CHANGE_FAILURE) {
|
||||||
|
GST_WARNING_OBJECT (dbin, "Couldn't set %s to READY",
|
||||||
|
GST_ELEMENT_NAME (element));
|
||||||
|
remove_error_filter (dbin, element);
|
||||||
|
gst_object_unref (sinkpad);
|
||||||
|
gst_bin_remove (GST_BIN (dbin), element);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Stop filtering errors. */
|
||||||
|
remove_error_filter (dbin, element);
|
||||||
|
|
||||||
gst_object_unref (sinkpad);
|
gst_object_unref (sinkpad);
|
||||||
GST_LOG_OBJECT (dbin, "linked on pad %s:%s", GST_DEBUG_PAD_NAME (pad));
|
GST_LOG_OBJECT (dbin, "linked on pad %s:%s", GST_DEBUG_PAD_NAME (pad));
|
||||||
|
|
||||||
|
@ -3993,6 +4023,24 @@ activate_failed:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_decode_bin_handle_message (GstBin * bin, GstMessage * msg)
|
||||||
|
{
|
||||||
|
GstDecodeBin *dbin = GST_DECODE_BIN (bin);
|
||||||
|
gboolean drop = FALSE;
|
||||||
|
|
||||||
|
if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR) {
|
||||||
|
GST_OBJECT_LOCK (dbin);
|
||||||
|
drop = (g_list_find (dbin->filtered, GST_MESSAGE_SRC (msg)) != NULL);
|
||||||
|
GST_OBJECT_UNLOCK (dbin);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (drop)
|
||||||
|
gst_message_unref (msg);
|
||||||
|
else
|
||||||
|
GST_BIN_CLASS (parent_class)->handle_message (bin, msg);
|
||||||
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
gst_decode_bin_plugin_init (GstPlugin * plugin)
|
gst_decode_bin_plugin_init (GstPlugin * plugin)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue