validate: Use GWeakRefs on monitor target and pipeline

Making it thread safe and more future proof (though having them point
to NULL might not be handled all around).

https://bugzilla.gnome.org/show_bug.cgi?id=782784
This commit is contained in:
Thibault Saunier 2017-05-30 16:13:08 -04:00
parent 8cc1b39919
commit 86e9135b56
12 changed files with 398 additions and 236 deletions

View file

@ -129,10 +129,15 @@ static void
gst_validate_bin_monitor_dispose (GObject * object) gst_validate_bin_monitor_dispose (GObject * object)
{ {
GstValidateBinMonitor *monitor = GST_VALIDATE_BIN_MONITOR_CAST (object); GstValidateBinMonitor *monitor = GST_VALIDATE_BIN_MONITOR_CAST (object);
GstElement *bin = GST_VALIDATE_ELEMENT_MONITOR_GET_ELEMENT (monitor); GstElement *bin =
GST_ELEMENT (gst_validate_monitor_get_target (GST_VALIDATE_MONITOR_CAST
(monitor)));
if (bin && monitor->element_added_id) if (bin) {
g_signal_handler_disconnect (bin, monitor->element_added_id); if (monitor->element_added_id)
g_signal_handler_disconnect (bin, monitor->element_added_id);
gst_object_unref (bin);
}
if (monitor->scenario) { if (monitor->scenario) {
gst_validate_reporter_purge_reports (GST_VALIDATE_REPORTER gst_validate_reporter_purge_reports (GST_VALIDATE_REPORTER
@ -186,11 +191,14 @@ gst_validate_bin_monitor_new (GstBin * bin, GstValidateRunner * runner,
GstValidateBinMonitor *monitor = GstValidateBinMonitor *monitor =
g_object_new (GST_TYPE_VALIDATE_BIN_MONITOR, "object", g_object_new (GST_TYPE_VALIDATE_BIN_MONITOR, "object",
bin, "validate-runner", runner, "validate-parent", parent, NULL); bin, "validate-runner", runner, "validate-parent", parent, NULL);
GstObject *target =
gst_validate_monitor_get_target (GST_VALIDATE_MONITOR (monitor));
if (GST_VALIDATE_MONITOR_GET_OBJECT (monitor) == NULL) { if (target == NULL) {
g_object_unref (monitor); g_object_unref (monitor);
return NULL; return NULL;
} }
gst_object_unref (target);
return monitor; return monitor;
} }
@ -202,12 +210,12 @@ gst_validate_bin_monitor_setup (GstValidateMonitor * monitor)
gboolean done; gboolean done;
GstElement *element; GstElement *element;
GstValidateBinMonitor *bin_monitor = GST_VALIDATE_BIN_MONITOR_CAST (monitor); GstValidateBinMonitor *bin_monitor = GST_VALIDATE_BIN_MONITOR_CAST (monitor);
GstBin *bin = GST_VALIDATE_BIN_MONITOR_GET_BIN (bin_monitor); GstBin *bin = GST_BIN_CAST (gst_validate_monitor_get_target (monitor));
if (!GST_IS_BIN (bin)) { if (!GST_IS_BIN (bin)) {
GST_WARNING_OBJECT (monitor, "Trying to create bin monitor with other " GST_WARNING_OBJECT (monitor, "Trying to create bin monitor with other "
"type of object"); "type of object");
return FALSE; goto fail;
} }
GST_DEBUG_OBJECT (bin_monitor, "Setting up monitor for bin %" GST_PTR_FORMAT, GST_DEBUG_OBJECT (bin_monitor, "Setting up monitor for bin %" GST_PTR_FORMAT,
@ -216,7 +224,7 @@ gst_validate_bin_monitor_setup (GstValidateMonitor * monitor)
if (g_object_get_data ((GObject *) bin, "validate-monitor")) { if (g_object_get_data ((GObject *) bin, "validate-monitor")) {
GST_DEBUG_OBJECT (bin_monitor, GST_DEBUG_OBJECT (bin_monitor,
"Bin already has a validate-monitor associated"); "Bin already has a validate-monitor associated");
return FALSE; goto fail;
} }
bin_monitor->element_added_id = bin_monitor->element_added_id =
@ -247,8 +255,14 @@ gst_validate_bin_monitor_setup (GstValidateMonitor * monitor)
} }
} }
gst_iterator_free (iterator); gst_iterator_free (iterator);
gst_object_unref (bin);
return TRUE; return TRUE;
fail:
if (bin)
gst_object_unref (bin);
return FALSE;
} }
static void static void
@ -274,7 +288,11 @@ static void
_validate_bin_element_added (GstBin * bin, GstElement * element, _validate_bin_element_added (GstBin * bin, GstElement * element,
GstValidateBinMonitor * monitor) GstValidateBinMonitor * monitor)
{ {
g_return_if_fail (GST_VALIDATE_ELEMENT_MONITOR_GET_ELEMENT (monitor) == GstObject *target =
GST_ELEMENT_CAST (bin)); gst_validate_monitor_get_target (GST_VALIDATE_MONITOR (monitor));
g_return_if_fail (GST_ELEMENT_CAST (target) == GST_ELEMENT_CAST (bin));
gst_object_unref (target);
gst_validate_bin_monitor_wrap_element (monitor, element); gst_validate_bin_monitor_wrap_element (monitor, element);
} }

View file

@ -39,8 +39,6 @@ G_BEGIN_DECLS
#define GST_VALIDATE_BIN_MONITOR_CAST(obj) ((GstValidateBinMonitor*)(obj)) #define GST_VALIDATE_BIN_MONITOR_CAST(obj) ((GstValidateBinMonitor*)(obj))
#define GST_VALIDATE_BIN_MONITOR_CLASS_CAST(klass) ((GstValidateBinMonitorClass*)(klass)) #define GST_VALIDATE_BIN_MONITOR_CLASS_CAST(klass) ((GstValidateBinMonitorClass*)(klass))
#define GST_VALIDATE_BIN_MONITOR_GET_BIN(m) (GST_BIN_CAST (GST_VALIDATE_ELEMENT_MONITOR_GET_ELEMENT (m)))
typedef struct _GstValidateBinMonitor GstValidateBinMonitor; typedef struct _GstValidateBinMonitor GstValidateBinMonitor;
typedef struct _GstValidateBinMonitorClass GstValidateBinMonitorClass; typedef struct _GstValidateBinMonitorClass GstValidateBinMonitorClass;

View file

@ -64,10 +64,10 @@ gst_validate_element_set_media_descriptor (GstValidateMonitor * monitor,
GstPad *pad; GstPad *pad;
GstValidateMonitor *pmonitor; GstValidateMonitor *pmonitor;
GstIterator *iterator; GstIterator *iterator;
GstElement *elem = GST_ELEMENT (gst_validate_monitor_get_target (monitor));
iterator = iterator = gst_element_iterate_pads (elem);
gst_element_iterate_pads (GST_ELEMENT (GST_VALIDATE_MONITOR_GET_OBJECT gst_object_unref (elem);
(monitor)));
done = FALSE; done = FALSE;
while (!done) { while (!done) {
GValue value = { 0, }; GValue value = { 0, };
@ -112,10 +112,14 @@ gst_validate_element_monitor_dispose (GObject * object)
{ {
GstValidateElementMonitor *monitor = GstValidateElementMonitor *monitor =
GST_VALIDATE_ELEMENT_MONITOR_CAST (object); GST_VALIDATE_ELEMENT_MONITOR_CAST (object);
GstObject *target =
gst_validate_monitor_get_target (GST_VALIDATE_MONITOR (monitor));
if (GST_VALIDATE_MONITOR_GET_OBJECT (monitor) && monitor->pad_added_id) if (target) {
g_signal_handler_disconnect (GST_VALIDATE_MONITOR_GET_OBJECT (monitor), if (monitor->pad_added_id)
monitor->pad_added_id); g_signal_handler_disconnect (target, monitor->pad_added_id);
gst_object_unref (target);
}
g_list_free_full (monitor->pad_monitors, purge_and_unref_reporter); g_list_free_full (monitor->pad_monitors, purge_and_unref_reporter);
@ -154,24 +158,30 @@ gst_validate_element_monitor_new (GstElement * element,
GstValidateRunner * runner, GstValidateMonitor * parent) GstValidateRunner * runner, GstValidateMonitor * parent)
{ {
GstValidateElementMonitor *monitor; GstValidateElementMonitor *monitor;
GstElement *target;
g_return_val_if_fail (element != NULL, NULL); g_return_val_if_fail (element != NULL, NULL);
monitor = g_object_new (GST_TYPE_VALIDATE_ELEMENT_MONITOR, "object", element, monitor = g_object_new (GST_TYPE_VALIDATE_ELEMENT_MONITOR, "object", element,
"validate-runner", runner, "validate-parent", parent, NULL); "validate-runner", runner, "validate-parent", parent, NULL);
if (GST_VALIDATE_ELEMENT_MONITOR_GET_ELEMENT (monitor) == NULL) { target =
GST_ELEMENT (gst_validate_monitor_get_target (GST_VALIDATE_MONITOR
(monitor)));
if (!target) {
g_object_unref (monitor); g_object_unref (monitor);
return NULL; return NULL;
} }
gst_object_unref (target);
return monitor; return monitor;
} }
static GstElement * static GstElement *
gst_validate_element_monitor_get_element (GstValidateMonitor * monitor) gst_validate_element_monitor_get_element (GstValidateMonitor * monitor)
{ {
return GST_VALIDATE_ELEMENT_MONITOR_GET_ELEMENT (monitor); return GST_ELEMENT (gst_validate_monitor_get_target (monitor));
} }
static void static void
@ -181,7 +191,9 @@ gst_validate_element_monitor_inspect (GstValidateElementMonitor * monitor)
GstElementClass *klass; GstElementClass *klass;
const gchar *klassname; const gchar *klassname;
element = GST_VALIDATE_ELEMENT_MONITOR_GET_ELEMENT (monitor); element =
GST_ELEMENT_CAST (gst_validate_monitor_get_target (GST_VALIDATE_MONITOR
(monitor)));
klass = GST_ELEMENT_CLASS (G_OBJECT_GET_CLASS (element)); klass = GST_ELEMENT_CLASS (G_OBJECT_GET_CLASS (element));
@ -194,6 +206,9 @@ gst_validate_element_monitor_inspect (GstValidateElementMonitor * monitor)
monitor->is_converter = strstr (klassname, "Converter") != NULL; monitor->is_converter = strstr (klassname, "Converter") != NULL;
} else } else
GST_ERROR_OBJECT (element, "no klassname"); GST_ERROR_OBJECT (element, "no klassname");
if (element)
gst_object_unref (element);
} }
static void static void
@ -237,8 +252,10 @@ gst_validate_element_monitor_do_setup (GstValidateMonitor * monitor)
GstPad *pad; GstPad *pad;
GstValidateElementMonitor *elem_monitor; GstValidateElementMonitor *elem_monitor;
GstElement *element; GstElement *element;
GstObject *target = gst_validate_monitor_get_target (monitor);
if (!GST_IS_ELEMENT (GST_VALIDATE_MONITOR_GET_OBJECT (monitor))) { if (!GST_IS_ELEMENT (target)) {
gst_object_unref (target);
GST_WARNING_OBJECT (monitor, "Trying to create element monitor with other " GST_WARNING_OBJECT (monitor, "Trying to create element monitor with other "
"type of object"); "type of object");
return FALSE; return FALSE;
@ -247,12 +264,13 @@ gst_validate_element_monitor_do_setup (GstValidateMonitor * monitor)
elem_monitor = GST_VALIDATE_ELEMENT_MONITOR_CAST (monitor); elem_monitor = GST_VALIDATE_ELEMENT_MONITOR_CAST (monitor);
GST_DEBUG_OBJECT (monitor, "Setting up monitor for element %" GST_PTR_FORMAT, GST_DEBUG_OBJECT (monitor, "Setting up monitor for element %" GST_PTR_FORMAT,
GST_VALIDATE_MONITOR_GET_OBJECT (monitor)); target);
element = GST_VALIDATE_ELEMENT_MONITOR_GET_ELEMENT (monitor); element = GST_ELEMENT_CAST (target);
if (g_object_get_data ((GObject *) element, "validate-monitor")) { if (g_object_get_data ((GObject *) element, "validate-monitor")) {
GST_DEBUG_OBJECT (elem_monitor, GST_DEBUG_OBJECT (elem_monitor,
"Pad already has a validate-monitor associated"); "Pad already has a validate-monitor associated");
gst_object_unref (target);
return FALSE; return FALSE;
} }
@ -285,6 +303,7 @@ gst_validate_element_monitor_do_setup (GstValidateMonitor * monitor)
} }
} }
gst_iterator_free (iterator); gst_iterator_free (iterator);
gst_object_unref (target);
set_config_properties (monitor, element); set_config_properties (monitor, element);
@ -313,7 +332,10 @@ static void
_validate_element_pad_added (GstElement * element, GstPad * pad, _validate_element_pad_added (GstElement * element, GstPad * pad,
GstValidateElementMonitor * monitor) GstValidateElementMonitor * monitor)
{ {
g_return_if_fail (GST_VALIDATE_ELEMENT_MONITOR_GET_ELEMENT (monitor) == GstObject *target =
element); gst_validate_monitor_get_target (GST_VALIDATE_MONITOR (monitor));
g_return_if_fail (target == (GstObject *) element);
gst_object_unref (target);
gst_validate_element_monitor_wrap_pad (monitor, pad); gst_validate_element_monitor_wrap_pad (monitor, pad);
} }

View file

@ -38,7 +38,6 @@ G_BEGIN_DECLS
#define GST_VALIDATE_ELEMENT_MONITOR_CAST(obj) ((GstValidateElementMonitor*)(obj)) #define GST_VALIDATE_ELEMENT_MONITOR_CAST(obj) ((GstValidateElementMonitor*)(obj))
#define GST_VALIDATE_ELEMENT_MONITOR_CLASS_CAST(klass) ((GstValidateElementMonitorClass*)(klass)) #define GST_VALIDATE_ELEMENT_MONITOR_CLASS_CAST(klass) ((GstValidateElementMonitorClass*)(klass))
#define GST_VALIDATE_ELEMENT_MONITOR_GET_ELEMENT(m) (GST_ELEMENT_CAST (GST_VALIDATE_MONITOR_GET_OBJECT (m)))
#define GST_VALIDATE_ELEMENT_MONITOR_ELEMENT_IS_DECODER(m) (GST_VALIDATE_ELEMENT_MONITOR_CAST (m)->is_decoder) #define GST_VALIDATE_ELEMENT_MONITOR_ELEMENT_IS_DECODER(m) (GST_VALIDATE_ELEMENT_MONITOR_CAST (m)->is_decoder)
#define GST_VALIDATE_ELEMENT_MONITOR_ELEMENT_IS_ENCODER(m) (GST_VALIDATE_ELEMENT_MONITOR_CAST (m)->is_encoder) #define GST_VALIDATE_ELEMENT_MONITOR_ELEMENT_IS_ENCODER(m) (GST_VALIDATE_ELEMENT_MONITOR_CAST (m)->is_encoder)
#define GST_VALIDATE_ELEMENT_MONITOR_ELEMENT_IS_DEMUXER(m) (GST_VALIDATE_ELEMENT_MONITOR_CAST (m)->is_demuxer) #define GST_VALIDATE_ELEMENT_MONITOR_ELEMENT_IS_DEMUXER(m) (GST_VALIDATE_ELEMENT_MONITOR_CAST (m)->is_demuxer)

View file

@ -70,18 +70,35 @@ _get_reporting_level (GstValidateReporter * monitor)
return GST_VALIDATE_MONITOR (monitor)->level; return GST_VALIDATE_MONITOR (monitor)->level;
} }
/**
* gst_validate_monitor_get_pipeline:
* @monitor: The monitor to get the pipeline from
*
* Returns: (transfer full): The pipeline in which @monitor
* target is in.
*/
GstPipeline *
gst_validate_monitor_get_pipeline (GstValidateMonitor * monitor)
{
return g_weak_ref_get (&monitor->pipeline);
}
/**
* gst_validate_monitor_get_target:
* @monitor: The monitor to get the target from
*
* Returns: (transfer full): The target object
*/
GstObject *
gst_validate_monitor_get_target (GstValidateMonitor * monitor)
{
return g_weak_ref_get (&monitor->target);
}
static GstPipeline * static GstPipeline *
_get_pipeline (GstValidateReporter * monitor) _get_pipeline (GstValidateReporter * monitor)
{ {
GstPipeline *pipeline; return g_weak_ref_get (&(GST_VALIDATE_MONITOR (monitor)->pipeline));
GST_OBJECT_LOCK (monitor);
pipeline = GST_VALIDATE_MONITOR (monitor)->pipeline;
if (pipeline)
gst_object_ref (pipeline);
GST_OBJECT_UNLOCK (monitor);
return pipeline;
} }
static void static void
@ -96,26 +113,6 @@ _reporter_iface_init (GstValidateReporterInterface * iface)
G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GstValidateMonitor, gst_validate_monitor, G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GstValidateMonitor, gst_validate_monitor,
GST_TYPE_OBJECT, _do_init); GST_TYPE_OBJECT, _do_init);
static void
_target_freed_cb (GstValidateMonitor * monitor, GObject * where_the_object_was)
{
GST_DEBUG_OBJECT (monitor, "Target was freed");
monitor->target = NULL;
GST_OBJECT_LOCK (monitor);
monitor->pipeline = NULL;
GST_OBJECT_UNLOCK (monitor);
}
static void
_pipeline_freed_cb (GstValidateMonitor * monitor,
GObject * where_the_object_was)
{
GST_DEBUG_OBJECT (monitor, "Pipeline was freed");
GST_OBJECT_LOCK (monitor);
monitor->pipeline = NULL;
GST_OBJECT_UNLOCK (monitor);
}
static void static void
gst_validate_monitor_dispose (GObject * object) gst_validate_monitor_dispose (GObject * object)
{ {
@ -125,13 +122,8 @@ gst_validate_monitor_dispose (GObject * object)
g_mutex_clear (&monitor->overrides_mutex); g_mutex_clear (&monitor->overrides_mutex);
g_queue_clear (&monitor->overrides); g_queue_clear (&monitor->overrides);
if (monitor->target) g_weak_ref_clear (&monitor->pipeline);
g_object_weak_unref (G_OBJECT (monitor->target), g_weak_ref_clear (&monitor->target);
(GWeakNotify) _target_freed_cb, monitor);
if (monitor->pipeline)
g_object_weak_unref (G_OBJECT (monitor->pipeline),
(GWeakNotify) _pipeline_freed_cb, monitor);
if (monitor->media_descriptor) if (monitor->media_descriptor)
gst_object_unref (monitor->media_descriptor); gst_object_unref (monitor->media_descriptor);
@ -195,16 +187,17 @@ gst_validate_monitor_constructor (GType type, guint n_construct_params,
construct_params)); construct_params));
if (monitor->parent) { if (monitor->parent) {
GstPipeline *parent_pipeline =
gst_validate_monitor_get_pipeline (monitor->parent);
gst_validate_monitor_set_media_descriptor (monitor, gst_validate_monitor_set_media_descriptor (monitor,
monitor->parent->media_descriptor); monitor->parent->media_descriptor);
GST_OBJECT_LOCK (monitor); if (parent_pipeline) {
if (monitor->parent->pipeline) { g_weak_ref_init (&monitor->pipeline, parent_pipeline);
g_object_weak_ref (G_OBJECT (monitor->parent->pipeline),
(GWeakNotify) _pipeline_freed_cb, monitor); gst_object_unref (parent_pipeline);
monitor->pipeline = monitor->parent->pipeline;
} }
GST_OBJECT_UNLOCK (monitor);
} }
gst_validate_monitor_setup (monitor); gst_validate_monitor_setup (monitor);
@ -252,7 +245,7 @@ _determine_reporting_level (GstValidateMonitor * monitor)
gchar *object_name; gchar *object_name;
GstValidateReportingDetails level = GST_VALIDATE_SHOW_UNKNOWN; GstValidateReportingDetails level = GST_VALIDATE_SHOW_UNKNOWN;
object = gst_object_ref (monitor->target); object = gst_validate_monitor_get_target (monitor);
runner = gst_validate_reporter_get_runner (GST_VALIDATE_REPORTER (monitor)); runner = gst_validate_reporter_get_runner (GST_VALIDATE_REPORTER (monitor));
do { do {
@ -267,8 +260,8 @@ _determine_reporting_level (GstValidateMonitor * monitor)
} }
object_name = gst_object_get_name (object); object_name = gst_object_get_name (object);
level = level = gst_validate_runner_get_reporting_level_for_name (runner,
gst_validate_runner_get_reporting_level_for_name (runner, object_name); object_name);
parent = gst_object_get_parent (object); parent = gst_object_get_parent (object);
gst_object_unref (object); gst_object_unref (object);
object = parent; object = parent;
@ -309,15 +302,19 @@ gst_validate_monitor_get_element (GstValidateMonitor * monitor)
return element; return element;
} }
const gchar * gchar *
gst_validate_monitor_get_element_name (GstValidateMonitor * monitor) gst_validate_monitor_get_element_name (GstValidateMonitor * monitor)
{ {
gchar *res = NULL;
GstElement *element; GstElement *element;
element = gst_validate_monitor_get_element (monitor); element = gst_validate_monitor_get_element (monitor);
if (element) if (element) {
return GST_ELEMENT_NAME (element); res = g_strdup (GST_ELEMENT_NAME (element));
return NULL; gst_object_unref (element);
}
return res;
} }
/* Check if any of our overrides wants to change the report severity */ /* Check if any of our overrides wants to change the report severity */
@ -375,22 +372,22 @@ gst_validate_monitor_set_property (GObject * object, guint prop_id,
switch (prop_id) { switch (prop_id) {
case PROP_OBJECT: case PROP_OBJECT:
g_assert (monitor->target == NULL); {
monitor->target = g_value_get_object (value); GstObject *target;
g_object_weak_ref (G_OBJECT (monitor->target),
(GWeakNotify) _target_freed_cb, monitor);
if (monitor->target) target = g_value_get_object (value);
g_assert (gst_validate_monitor_get_target (monitor) == NULL);
g_weak_ref_init (&monitor->target, target);
if (target)
gst_validate_reporter_set_name (GST_VALIDATE_REPORTER (monitor), gst_validate_reporter_set_name (GST_VALIDATE_REPORTER (monitor),
g_strdup (GST_OBJECT_NAME (monitor->target))); gst_object_get_name (target));
break; break;
}
case PROP_PIPELINE: case PROP_PIPELINE:
GST_OBJECT_LOCK (monitor); g_weak_ref_init (&monitor->pipeline, g_value_get_object (value));
monitor->pipeline = g_value_get_object (value);
if (monitor->pipeline)
g_object_weak_ref (G_OBJECT (monitor->pipeline),
(GWeakNotify) _pipeline_freed_cb, monitor);
GST_OBJECT_UNLOCK (monitor);
case PROP_RUNNER: case PROP_RUNNER:
gst_validate_reporter_set_runner (GST_VALIDATE_REPORTER (monitor), gst_validate_reporter_set_runner (GST_VALIDATE_REPORTER (monitor),
g_value_get_object (value)); g_value_get_object (value));
@ -414,10 +411,10 @@ gst_validate_monitor_get_property (GObject * object, guint prop_id,
switch (prop_id) { switch (prop_id) {
case PROP_OBJECT: case PROP_OBJECT:
g_value_set_object (value, GST_VALIDATE_MONITOR_GET_OBJECT (monitor)); g_value_take_object (value, gst_validate_monitor_get_target (monitor));
break; break;
case PROP_PIPELINE: case PROP_PIPELINE:
g_value_set_object (value, monitor->pipeline); g_value_take_object (value, gst_validate_monitor_get_pipeline (monitor));
break; break;
case PROP_RUNNER: case PROP_RUNNER:
g_value_set_object (value, GST_VALIDATE_MONITOR_GET_RUNNER (monitor)); g_value_set_object (value, GST_VALIDATE_MONITOR_GET_RUNNER (monitor));
@ -437,7 +434,7 @@ gst_validate_monitor_set_media_descriptor (GstValidateMonitor * monitor,
{ {
GstValidateMonitorClass *klass = GST_VALIDATE_MONITOR_GET_CLASS (monitor); GstValidateMonitorClass *klass = GST_VALIDATE_MONITOR_GET_CLASS (monitor);
GST_DEBUG_OBJECT (monitor->target, "Set media desc: %" GST_PTR_FORMAT, GST_DEBUG_OBJECT (monitor, "Set media desc: %" GST_PTR_FORMAT,
media_descriptor); media_descriptor);
if (monitor->media_descriptor) if (monitor->media_descriptor)
gst_object_unref (monitor->media_descriptor); gst_object_unref (monitor->media_descriptor);

View file

@ -45,7 +45,6 @@ G_BEGIN_DECLS
#define GST_VALIDATE_MONITOR_CAST(obj) ((GstValidateMonitor*)(obj)) #define GST_VALIDATE_MONITOR_CAST(obj) ((GstValidateMonitor*)(obj))
#define GST_VALIDATE_MONITOR_CLASS_CAST(klass) ((GstValidateMonitorClass*)(klass)) #define GST_VALIDATE_MONITOR_CLASS_CAST(klass) ((GstValidateMonitorClass*)(klass))
#define GST_VALIDATE_MONITOR_GET_OBJECT(m) (GST_VALIDATE_MONITOR_CAST (m)->target)
#define GST_VALIDATE_MONITOR_GET_RUNNER(m) (gst_validate_reporter_get_runner (GST_VALIDATE_REPORTER_CAST (m))) #define GST_VALIDATE_MONITOR_GET_RUNNER(m) (gst_validate_reporter_get_runner (GST_VALIDATE_REPORTER_CAST (m)))
#define GST_VALIDATE_MONITOR_GET_PARENT(m) (GST_VALIDATE_MONITOR_CAST (m)->parent) #define GST_VALIDATE_MONITOR_GET_PARENT(m) (GST_VALIDATE_MONITOR_CAST (m)->parent)
@ -83,8 +82,8 @@ G_BEGIN_DECLS
struct _GstValidateMonitor { struct _GstValidateMonitor {
GstObject object; GstObject object;
GstObject *target; GWeakRef target;
GstPipeline *pipeline; GWeakRef pipeline;
GMutex mutex; GMutex mutex;
gchar *target_name; gchar *target_name;
@ -122,9 +121,11 @@ void gst_validate_monitor_attach_override (GstValidateMonitor * moni
GstValidateOverride * override); GstValidateOverride * override);
GstElement * gst_validate_monitor_get_element (GstValidateMonitor * monitor); GstElement * gst_validate_monitor_get_element (GstValidateMonitor * monitor);
const gchar * gst_validate_monitor_get_element_name (GstValidateMonitor * monitor); gchar * gst_validate_monitor_get_element_name (GstValidateMonitor * monitor);
void gst_validate_monitor_set_media_descriptor (GstValidateMonitor * monitor, void gst_validate_monitor_set_media_descriptor (GstValidateMonitor * monitor,
GstValidateMediaDescriptor *media_descriptor); GstValidateMediaDescriptor *media_descriptor);
GstPipeline * gst_validate_monitor_get_pipeline (GstValidateMonitor * monitor);
GstObject * gst_validate_monitor_get_target (GstValidateMonitor * monitor);
G_END_DECLS G_END_DECLS
#endif /* __GST_VALIDATE_MONITOR_H__ */ #endif /* __GST_VALIDATE_MONITOR_H__ */

View file

@ -175,7 +175,7 @@ static void
{ {
GstValidateOverrideRegistryNameEntry *entry; GstValidateOverrideRegistryNameEntry *entry;
GList *iter; GList *iter;
const gchar *name; gchar *name;
name = gst_validate_monitor_get_element_name (monitor); name = gst_validate_monitor_get_element_name (monitor);
for (iter = registry->name_overrides.head; iter; iter = g_list_next (iter)) { for (iter = registry->name_overrides.head; iter; iter = g_list_next (iter)) {
@ -186,6 +186,8 @@ static void
gst_validate_monitor_attach_override (monitor, entry->override); gst_validate_monitor_attach_override (monitor, entry->override);
} }
} }
g_free (name);
} }
static void static void
@ -206,6 +208,7 @@ static void
gst_validate_monitor_attach_override (monitor, entry->override); gst_validate_monitor_attach_override (monitor, entry->override);
} }
} }
gst_object_unref (element);
} }
static void static void
@ -228,6 +231,7 @@ static void
gst_validate_monitor_attach_override (monitor, entry->override); gst_validate_monitor_attach_override (monitor, entry->override);
} }
} }
gst_object_unref (element);
} }
void void

View file

@ -189,8 +189,12 @@ _find_master_report_for_sink_pad (GstValidatePadMonitor * pad_monitor,
{ {
GstPad *peerpad; GstPad *peerpad;
gboolean result = FALSE; gboolean result = FALSE;
GstPad *pad =
GST_PAD_CAST (gst_validate_monitor_get_target (GST_VALIDATE_MONITOR
(pad_monitor)));
peerpad = gst_pad_get_peer (pad_monitor->pad); peerpad = gst_pad_get_peer (pad);
gst_object_unref (pad);
/* If the peer src pad already has a similar report no need to look /* If the peer src pad already has a similar report no need to look
* any further */ * any further */
@ -209,18 +213,19 @@ _find_master_report_for_src_pad (GstValidatePadMonitor * pad_monitor,
{ {
GstIterator *iter; GstIterator *iter;
gboolean done; gboolean done;
GstPad *pad;
gboolean result = FALSE; gboolean result = FALSE;
GstPad *target =
GST_PAD (gst_validate_monitor_get_target (GST_VALIDATE_MONITOR
(pad_monitor)));
iter = iter = gst_pad_iterate_internal_links (target);
gst_pad_iterate_internal_links (GST_VALIDATE_PAD_MONITOR_GET_PAD
(pad_monitor));
done = FALSE; done = FALSE;
while (!done) { while (!done) {
GValue value = { 0, }; GValue value = { 0, };
switch (gst_iterator_next (iter, &value)) { switch (gst_iterator_next (iter, &value)) {
case GST_ITERATOR_OK: case GST_ITERATOR_OK:
pad = g_value_get_object (&value); {
GstPad *pad = g_value_get_object (&value);
if (_find_master_report_on_pad (pad, report)) { if (_find_master_report_on_pad (pad, report)) {
result = TRUE; result = TRUE;
@ -229,12 +234,12 @@ _find_master_report_for_src_pad (GstValidatePadMonitor * pad_monitor,
g_value_reset (&value); g_value_reset (&value);
break; break;
}
case GST_ITERATOR_RESYNC: case GST_ITERATOR_RESYNC:
gst_iterator_resync (iter); gst_iterator_resync (iter);
break; break;
case GST_ITERATOR_ERROR: case GST_ITERATOR_ERROR:
GST_WARNING_OBJECT (pad_monitor->pad, GST_WARNING_OBJECT (target, "Internal links pad iteration error");
"Internal links pad iteration error");
done = TRUE; done = TRUE;
break; break;
case GST_ITERATOR_DONE: case GST_ITERATOR_DONE:
@ -242,6 +247,7 @@ _find_master_report_for_src_pad (GstValidatePadMonitor * pad_monitor,
break; break;
} }
} }
gst_object_unref (target);
gst_iterator_free (iter); gst_iterator_free (iter);
return result; return result;
@ -251,13 +257,21 @@ static GstValidateInterceptionReturn
_concatenate_issues (GstValidatePadMonitor * pad_monitor, _concatenate_issues (GstValidatePadMonitor * pad_monitor,
GstValidateReport * report) GstValidateReport * report)
{ {
if (GST_PAD_IS_SINK (pad_monitor->pad) GstPad *pad =
&& _find_master_report_for_sink_pad (pad_monitor, report)) GST_PAD_CAST (gst_validate_monitor_get_target (GST_VALIDATE_MONITOR
return GST_VALIDATE_REPORTER_KEEP; (pad_monitor)));
else if (GST_PAD_IS_SRC (pad_monitor->pad)
&& _find_master_report_for_src_pad (pad_monitor, report))
return GST_VALIDATE_REPORTER_KEEP;
if (GST_PAD_IS_SINK (pad)
&& _find_master_report_for_sink_pad (pad_monitor, report)) {
gst_object_unref (pad);
return GST_VALIDATE_REPORTER_KEEP;
} else if (GST_PAD_IS_SRC (pad)
&& _find_master_report_for_src_pad (pad_monitor, report)) {
gst_object_unref (pad);
return GST_VALIDATE_REPORTER_KEEP;
}
gst_object_unref (pad);
return GST_VALIDATE_REPORTER_REPORT; return GST_VALIDATE_REPORTER_REPORT;
} }
@ -441,7 +455,7 @@ gst_validate_pad_monitor_check_caps_complete (GstValidatePadMonitor * monitor,
GstStructure *structure; GstStructure *structure;
gint i; gint i;
GST_DEBUG_OBJECT (monitor->pad, "Checking caps %" GST_PTR_FORMAT, caps); GST_DEBUG_OBJECT (monitor, "Checking caps %" GST_PTR_FORMAT, caps);
for (i = 0; i < gst_caps_get_size (caps); i++) { for (i = 0; i < gst_caps_get_size (caps); i++) {
structure = gst_caps_get_structure (caps, i); structure = gst_caps_get_structure (caps, i);
@ -466,10 +480,11 @@ gst_validate_pad_monitor_get_othercaps (GstValidatePadMonitor * monitor,
gboolean done; gboolean done;
GstPad *otherpad; GstPad *otherpad;
GstCaps *peercaps; GstCaps *peercaps;
GstPad *pad =
GST_PAD (gst_validate_monitor_get_target (GST_VALIDATE_MONITOR
(monitor)));
iter = iter = gst_pad_iterate_internal_links (pad);
gst_pad_iterate_internal_links (GST_VALIDATE_PAD_MONITOR_GET_PAD
(monitor));
done = FALSE; done = FALSE;
while (!done) { while (!done) {
GValue value = { 0, }; GValue value = { 0, };
@ -491,7 +506,7 @@ gst_validate_pad_monitor_get_othercaps (GstValidatePadMonitor * monitor,
caps = gst_caps_new_empty (); caps = gst_caps_new_empty ();
break; break;
case GST_ITERATOR_ERROR: case GST_ITERATOR_ERROR:
GST_WARNING_OBJECT (monitor->pad, "Internal links pad iteration error"); GST_WARNING_OBJECT (pad, "Internal links pad iteration error");
done = TRUE; done = TRUE;
break; break;
case GST_ITERATOR_DONE: case GST_ITERATOR_DONE:
@ -499,9 +514,10 @@ gst_validate_pad_monitor_get_othercaps (GstValidatePadMonitor * monitor,
break; break;
} }
} }
gst_iterator_free (iter); GST_DEBUG_OBJECT (pad, "Otherpad caps: %" GST_PTR_FORMAT, caps);
GST_DEBUG_OBJECT (monitor->pad, "Otherpad caps: %" GST_PTR_FORMAT, caps); gst_iterator_free (iter);
gst_object_unref (pad);
return caps; return caps;
} }
@ -673,17 +689,20 @@ gst_validate_pad_monitor_transform_caps (GstValidatePadMonitor * monitor,
gboolean done; gboolean done;
GstPad *otherpad; GstPad *otherpad;
GstCaps *template_caps; GstCaps *template_caps;
GstPad *pad;
GST_DEBUG_OBJECT (monitor->pad, "Transform caps %" GST_PTR_FORMAT, caps);
GST_DEBUG_OBJECT (monitor, "Transform caps %" GST_PTR_FORMAT, caps);
if (caps == NULL) if (caps == NULL)
return NULL; return NULL;
othercaps = gst_caps_new_empty (); othercaps = gst_caps_new_empty ();
iter = pad =
gst_pad_iterate_internal_links (GST_VALIDATE_PAD_MONITOR_GET_PAD GST_PAD (gst_validate_monitor_get_target (GST_VALIDATE_MONITOR
(monitor)); (monitor)));
iter = gst_pad_iterate_internal_links (pad);
done = FALSE; done = FALSE;
while (!done) { while (!done) {
GValue value = { 0, }; GValue value = { 0, };
@ -709,7 +728,7 @@ gst_validate_pad_monitor_transform_caps (GstValidatePadMonitor * monitor,
othercaps = gst_caps_new_empty (); othercaps = gst_caps_new_empty ();
break; break;
case GST_ITERATOR_ERROR: case GST_ITERATOR_ERROR:
GST_WARNING_OBJECT (monitor->pad, "Internal links pad iteration error"); GST_WARNING_OBJECT (pad, "Internal links pad iteration error");
done = TRUE; done = TRUE;
break; break;
case GST_ITERATOR_DONE: case GST_ITERATOR_DONE:
@ -719,8 +738,8 @@ gst_validate_pad_monitor_transform_caps (GstValidatePadMonitor * monitor,
} }
gst_iterator_free (iter); gst_iterator_free (iter);
GST_DEBUG_OBJECT (monitor->pad, "Transformed caps: %" GST_PTR_FORMAT, GST_DEBUG_OBJECT (pad, "Transformed caps: %" GST_PTR_FORMAT, othercaps);
othercaps); gst_object_unref (pad);
return othercaps; return othercaps;
} }
@ -805,18 +824,23 @@ gst_validate_pad_monitor_check_late_serialized_events (GstValidatePadMonitor *
monitor, GstClockTime ts) monitor, GstClockTime ts)
{ {
gint i; gint i;
GstPad *pad;
if (!GST_CLOCK_TIME_IS_VALID (ts)) if (!GST_CLOCK_TIME_IS_VALID (ts))
return; return;
GST_DEBUG_OBJECT (monitor->pad, "Timestamp to check %" GST_TIME_FORMAT, pad =
GST_PAD (gst_validate_monitor_get_target (GST_VALIDATE_MONITOR
(monitor)));
GST_DEBUG_OBJECT (pad, "Timestamp to check %" GST_TIME_FORMAT,
GST_TIME_ARGS (ts)); GST_TIME_ARGS (ts));
for (i = 0; i < monitor->serialized_events->len; i++) { for (i = 0; i < monitor->serialized_events->len; i++) {
SerializedEventData *data = SerializedEventData *data =
g_ptr_array_index (monitor->serialized_events, i); g_ptr_array_index (monitor->serialized_events, i);
GST_DEBUG_OBJECT (monitor->pad, "Event #%d (%s) ts: %" GST_TIME_FORMAT, GST_DEBUG_OBJECT (pad, "Event #%d (%s) ts: %" GST_TIME_FORMAT,
i, GST_EVENT_TYPE_NAME (data->event), GST_TIME_ARGS (data->timestamp)); i, GST_EVENT_TYPE_NAME (data->event), GST_TIME_ARGS (data->timestamp));
if (GST_CLOCK_TIME_IS_VALID (data->timestamp) && data->timestamp < ts) { if (GST_CLOCK_TIME_IS_VALID (data->timestamp) && data->timestamp < ts) {
@ -825,8 +849,7 @@ gst_validate_pad_monitor_check_late_serialized_events (GstValidatePadMonitor *
GST_VALIDATE_REPORT (monitor, SERIALIZED_EVENT_WASNT_PUSHED_IN_TIME, GST_VALIDATE_REPORT (monitor, SERIALIZED_EVENT_WASNT_PUSHED_IN_TIME,
"Serialized event %s wasn't pushed before expected timestamp %" "Serialized event %s wasn't pushed before expected timestamp %"
GST_TIME_FORMAT " on pad %s:%s", event_str, GST_TIME_FORMAT " on pad %s:%s", event_str,
GST_TIME_ARGS (data->timestamp), GST_TIME_ARGS (data->timestamp), GST_DEBUG_PAD_NAME (pad));
GST_DEBUG_PAD_NAME (GST_VALIDATE_PAD_MONITOR_GET_PAD (monitor)));
g_free (event_str); g_free (event_str);
} else { } else {
@ -836,20 +859,25 @@ gst_validate_pad_monitor_check_late_serialized_events (GstValidatePadMonitor *
} }
if (i) { if (i) {
debug_pending_event (monitor->pad, monitor->serialized_events); debug_pending_event (pad, monitor->serialized_events);
g_ptr_array_remove_range (monitor->serialized_events, 0, i); g_ptr_array_remove_range (monitor->serialized_events, 0, i);
} }
gst_object_unref (pad);
} }
static void static void
gst_validate_pad_monitor_dispose (GObject * object) gst_validate_pad_monitor_dispose (GObject * object)
{ {
GstValidatePadMonitor *monitor = GST_VALIDATE_PAD_MONITOR_CAST (object); GstValidatePadMonitor *monitor = GST_VALIDATE_PAD_MONITOR_CAST (object);
GstPad *pad = GST_VALIDATE_PAD_MONITOR_GET_PAD (monitor); GstPad *pad =
GST_PAD (gst_validate_monitor_get_target (GST_VALIDATE_MONITOR
(monitor)));
if (pad) { if (pad) {
if (monitor->pad_probe_id) if (monitor->pad_probe_id)
gst_pad_remove_probe (pad, monitor->pad_probe_id); gst_pad_remove_probe (pad, monitor->pad_probe_id);
gst_object_unref (pad);
} }
if (monitor->expected_segment) if (monitor->expected_segment)
@ -910,20 +938,29 @@ gst_validate_pad_monitor_new (GstPad * pad, GstValidateRunner * runner,
GstValidatePadMonitor *monitor = g_object_new (GST_TYPE_VALIDATE_PAD_MONITOR, GstValidatePadMonitor *monitor = g_object_new (GST_TYPE_VALIDATE_PAD_MONITOR,
"object", pad, "validate-runner", runner, "validate-parent", "object", pad, "validate-runner", runner, "validate-parent",
parent, NULL); parent, NULL);
GstObject *target =
gst_validate_monitor_get_target (GST_VALIDATE_MONITOR (monitor));
if (GST_VALIDATE_PAD_MONITOR_GET_PAD (monitor) == NULL) { if (target == NULL) {
g_object_unref (monitor); g_object_unref (monitor);
return NULL; return NULL;
} }
gst_object_unref (target);
return monitor; return monitor;
} }
static GstElement * static GstElement *
gst_validate_pad_monitor_get_element (GstValidateMonitor * monitor) gst_validate_pad_monitor_get_element (GstValidateMonitor * monitor)
{ {
GstPad *pad = GST_VALIDATE_PAD_MONITOR_GET_PAD (monitor); GstPad *pad =
GST_PAD (gst_validate_monitor_get_target (GST_VALIDATE_MONITOR
(monitor)));
GstElement *parent = GST_ELEMENT (gst_pad_get_parent (pad));
return GST_PAD_PARENT (pad); gst_object_unref (pad);
return parent;
} }
static void static void
@ -1016,13 +1053,19 @@ static gboolean
gst_validate_pad_monitor_timestamp_is_in_received_range (GstValidatePadMonitor * gst_validate_pad_monitor_timestamp_is_in_received_range (GstValidatePadMonitor *
monitor, GstClockTime ts, GstClockTime tolerance) monitor, GstClockTime ts, GstClockTime tolerance)
{ {
GST_DEBUG_OBJECT (monitor->pad, "Checking if timestamp %" GST_TIME_FORMAT GstPad *pad =
" is in range: %" GST_TIME_FORMAT " - %" GST_TIME_FORMAT " for pad " GST_PAD (gst_validate_monitor_get_target (GST_VALIDATE_MONITOR
(monitor)));
GST_DEBUG_OBJECT (pad,
"Checking if timestamp %" GST_TIME_FORMAT " is in range: %"
GST_TIME_FORMAT " - %" GST_TIME_FORMAT " for pad "
"%s:%s with tolerance: %" GST_TIME_FORMAT, GST_TIME_ARGS (ts), "%s:%s with tolerance: %" GST_TIME_FORMAT, GST_TIME_ARGS (ts),
GST_TIME_ARGS (monitor->timestamp_range_start), GST_TIME_ARGS (monitor->timestamp_range_start),
GST_TIME_ARGS (monitor->timestamp_range_end), GST_TIME_ARGS (monitor->timestamp_range_end), GST_DEBUG_PAD_NAME (pad),
GST_DEBUG_PAD_NAME (GST_VALIDATE_PAD_MONITOR_GET_PAD (monitor)),
GST_TIME_ARGS (tolerance)); GST_TIME_ARGS (tolerance));
gst_object_unref (pad);
return !GST_CLOCK_TIME_IS_VALID (monitor->timestamp_range_start) || return !GST_CLOCK_TIME_IS_VALID (monitor->timestamp_range_start) ||
!GST_CLOCK_TIME_IS_VALID (monitor->timestamp_range_end) || !GST_CLOCK_TIME_IS_VALID (monitor->timestamp_range_end) ||
((monitor->timestamp_range_start >= tolerance ? ((monitor->timestamp_range_start >= tolerance ?
@ -1046,25 +1089,26 @@ static void
gboolean done; gboolean done;
GstPad *otherpad; GstPad *otherpad;
GstValidatePadMonitor *othermonitor; GstValidatePadMonitor *othermonitor;
GstPad *pad =
GST_PAD (gst_validate_monitor_get_target (GST_VALIDATE_MONITOR
(monitor)));
if (!GST_CLOCK_TIME_IS_VALID (GST_BUFFER_TIMESTAMP (buffer)) if (!GST_CLOCK_TIME_IS_VALID (GST_BUFFER_TIMESTAMP (buffer))
|| !GST_CLOCK_TIME_IS_VALID (GST_BUFFER_DURATION (buffer))) { || !GST_CLOCK_TIME_IS_VALID (GST_BUFFER_DURATION (buffer))) {
GST_DEBUG_OBJECT (monitor->pad, GST_DEBUG_OBJECT (pad,
"Can't check buffer timestamps range as " "Can't check buffer timestamps range as "
"buffer has no valid timestamp/duration"); "buffer has no valid timestamp/duration");
return; goto done;
} }
ts = GST_BUFFER_TIMESTAMP (buffer); ts = GST_BUFFER_TIMESTAMP (buffer);
ts_end = ts + GST_BUFFER_DURATION (buffer); ts_end = ts + GST_BUFFER_DURATION (buffer);
iter = iter = gst_pad_iterate_internal_links (pad);
gst_pad_iterate_internal_links (GST_VALIDATE_PAD_MONITOR_GET_PAD
(monitor));
if (iter == NULL) { if (iter == NULL) {
GST_WARNING_OBJECT (GST_VALIDATE_PAD_MONITOR_GET_PAD (monitor), GST_WARNING_OBJECT (pad, "No iterator available");
"No iterator available"); goto done;
return;
} }
done = FALSE; done = FALSE;
@ -1073,7 +1117,7 @@ static void
switch (gst_iterator_next (iter, &value)) { switch (gst_iterator_next (iter, &value)) {
case GST_ITERATOR_OK: case GST_ITERATOR_OK:
otherpad = g_value_get_object (&value); otherpad = g_value_get_object (&value);
GST_DEBUG_OBJECT (monitor->pad, "Checking pad %s:%s input timestamps", GST_DEBUG_OBJECT (pad, "Checking pad %s:%s input timestamps",
GST_DEBUG_PAD_NAME (otherpad)); GST_DEBUG_PAD_NAME (otherpad));
othermonitor = othermonitor =
g_object_get_data ((GObject *) otherpad, "validate-monitor"); g_object_get_data ((GObject *) otherpad, "validate-monitor");
@ -1096,7 +1140,7 @@ static void
found = FALSE; found = FALSE;
break; break;
case GST_ITERATOR_ERROR: case GST_ITERATOR_ERROR:
GST_WARNING_OBJECT (monitor->pad, "Internal links pad iteration error"); GST_WARNING_OBJECT (pad, "Internal links pad iteration error");
done = TRUE; done = TRUE;
break; break;
case GST_ITERATOR_DONE: case GST_ITERATOR_DONE:
@ -1107,9 +1151,9 @@ static void
gst_iterator_free (iter); gst_iterator_free (iter);
if (!has_one) { if (!has_one) {
GST_DEBUG_OBJECT (monitor->pad, "Skipping timestamp in range check as no " GST_DEBUG_OBJECT (pad, "Skipping timestamp in range check as no "
"internal linked pad was found"); "internal linked pad was found");
return; goto done;
} }
if (!found) { if (!found) {
GST_VALIDATE_REPORT (monitor, BUFFER_TIMESTAMP_OUT_OF_RECEIVED_RANGE, GST_VALIDATE_REPORT (monitor, BUFFER_TIMESTAMP_OUT_OF_RECEIVED_RANGE,
@ -1117,6 +1161,9 @@ static void
" is out of range of received input", GST_TIME_ARGS (ts), " is out of range of received input", GST_TIME_ARGS (ts),
GST_TIME_ARGS (ts_end)); GST_TIME_ARGS (ts_end));
} }
done:
if (pad)
gst_object_unref (pad);
} }
static void static void
@ -1135,22 +1182,26 @@ static void
gst_validate_pad_monitor_check_first_buffer (GstValidatePadMonitor * gst_validate_pad_monitor_check_first_buffer (GstValidatePadMonitor *
pad_monitor, GstBuffer * buffer) pad_monitor, GstBuffer * buffer)
{ {
GstPad *pad =
GST_PAD (gst_validate_monitor_get_target (GST_VALIDATE_MONITOR
(pad_monitor)));
if (G_UNLIKELY (pad_monitor->first_buffer)) { if (G_UNLIKELY (pad_monitor->first_buffer)) {
pad_monitor->first_buffer = FALSE; pad_monitor->first_buffer = FALSE;
if (!pad_monitor->has_segment if (!pad_monitor->has_segment && PAD_IS_IN_PUSH_MODE (pad)) {
&& PAD_IS_IN_PUSH_MODE (GST_VALIDATE_PAD_MONITOR_GET_PAD (pad_monitor)))
{
GST_VALIDATE_REPORT (pad_monitor, BUFFER_BEFORE_SEGMENT, GST_VALIDATE_REPORT (pad_monitor, BUFFER_BEFORE_SEGMENT,
"Received buffer before Segment event"); "Received buffer before Segment event");
} }
GST_DEBUG_OBJECT (pad_monitor->pad, GST_DEBUG_OBJECT (pad,
"Checking first buffer (pts:%" GST_TIME_FORMAT " dts:%" GST_TIME_FORMAT "Checking first buffer (pts:%" GST_TIME_FORMAT " dts:%" GST_TIME_FORMAT
")", GST_TIME_ARGS (GST_BUFFER_PTS (buffer)), ")", GST_TIME_ARGS (GST_BUFFER_PTS (buffer)),
GST_TIME_ARGS (GST_BUFFER_DTS (buffer))); GST_TIME_ARGS (GST_BUFFER_DTS (buffer)));
} }
gst_object_unref (pad);
} }
static void static void
@ -1167,6 +1218,9 @@ static void
gst_validate_pad_monitor_update_buffer_data (GstValidatePadMonitor * gst_validate_pad_monitor_update_buffer_data (GstValidatePadMonitor *
pad_monitor, GstBuffer * buffer) pad_monitor, GstBuffer * buffer)
{ {
GstPad *pad =
GST_PAD (gst_validate_monitor_get_target (GST_VALIDATE_MONITOR
(pad_monitor)));
pad_monitor->current_timestamp = GST_BUFFER_TIMESTAMP (buffer); pad_monitor->current_timestamp = GST_BUFFER_TIMESTAMP (buffer);
pad_monitor->current_duration = GST_BUFFER_DURATION (buffer); pad_monitor->current_duration = GST_BUFFER_DURATION (buffer);
if (GST_CLOCK_TIME_IS_VALID (GST_BUFFER_TIMESTAMP (buffer))) { if (GST_CLOCK_TIME_IS_VALID (GST_BUFFER_TIMESTAMP (buffer))) {
@ -1189,10 +1243,12 @@ gst_validate_pad_monitor_update_buffer_data (GstValidatePadMonitor *
} }
} }
} }
GST_DEBUG_OBJECT (pad_monitor->pad, "Current stored range: %" GST_TIME_FORMAT GST_DEBUG_OBJECT (pad, "Current stored range: %" GST_TIME_FORMAT
" - %" GST_TIME_FORMAT, " - %" GST_TIME_FORMAT,
GST_TIME_ARGS (pad_monitor->timestamp_range_start), GST_TIME_ARGS (pad_monitor->timestamp_range_start),
GST_TIME_ARGS (pad_monitor->timestamp_range_end)); GST_TIME_ARGS (pad_monitor->timestamp_range_end));
gst_object_unref (pad);
} }
static GstFlowReturn static GstFlowReturn
@ -1222,7 +1278,9 @@ gst_validate_pad_monitor_check_aggregated_return (GstValidatePadMonitor *
GstValidatePadMonitor *othermonitor; GstValidatePadMonitor *othermonitor;
GstFlowReturn aggregated = GST_FLOW_NOT_LINKED; GstFlowReturn aggregated = GST_FLOW_NOT_LINKED;
gboolean found_a_pad = FALSE; gboolean found_a_pad = FALSE;
GstPad *pad = GST_VALIDATE_PAD_MONITOR_GET_PAD (monitor); GstPad *pad =
GST_PAD (gst_validate_monitor_get_target (GST_VALIDATE_MONITOR
(monitor)));
iter = gst_pad_iterate_internal_links (pad); iter = gst_pad_iterate_internal_links (pad);
done = FALSE; done = FALSE;
@ -1251,7 +1309,7 @@ gst_validate_pad_monitor_check_aggregated_return (GstValidatePadMonitor *
gst_iterator_resync (iter); gst_iterator_resync (iter);
break; break;
case GST_ITERATOR_ERROR: case GST_ITERATOR_ERROR:
GST_WARNING_OBJECT (monitor->pad, "Internal links pad iteration error"); GST_WARNING_OBJECT (pad, "Internal links pad iteration error");
done = TRUE; done = TRUE;
break; break;
case GST_ITERATOR_DONE: case GST_ITERATOR_DONE:
@ -1262,7 +1320,7 @@ gst_validate_pad_monitor_check_aggregated_return (GstValidatePadMonitor *
gst_iterator_free (iter); gst_iterator_free (iter);
if (!found_a_pad) { if (!found_a_pad) {
/* no peer pad found, nothing to do */ /* no peer pad found, nothing to do */
return; goto done;
} }
if (aggregated == GST_FLOW_OK || aggregated == GST_FLOW_EOS) { if (aggregated == GST_FLOW_OK || aggregated == GST_FLOW_EOS) {
GstState state, pending; GstState state, pending;
@ -1270,7 +1328,7 @@ gst_validate_pad_monitor_check_aggregated_return (GstValidatePadMonitor *
/* those are acceptable situations */ /* those are acceptable situations */
if (GST_PAD_IS_FLUSHING (pad) && ret == GST_FLOW_FLUSHING) { if (GST_PAD_IS_FLUSHING (pad) && ret == GST_FLOW_FLUSHING) {
/* pad is flushing, always acceptable to return flushing */ /* pad is flushing, always acceptable to return flushing */
return; goto done;
} }
gst_element_get_state (GST_ELEMENT (parent), &state, &pending, 0); gst_element_get_state (GST_ELEMENT (parent), &state, &pending, 0);
@ -1278,17 +1336,17 @@ gst_validate_pad_monitor_check_aggregated_return (GstValidatePadMonitor *
|| pending < GST_STATE_PAUSED)) { || pending < GST_STATE_PAUSED)) {
/* Element is being teared down, accept FLOW_FLUSHING */ /* Element is being teared down, accept FLOW_FLUSHING */
return; goto done;
} }
if (monitor->is_eos && ret == GST_FLOW_EOS) { if (monitor->is_eos && ret == GST_FLOW_EOS) {
/* this element received eos and returned eos */ /* this element received eos and returned eos */
return; goto done;
} }
if (PAD_PARENT_IS_DEMUXER (monitor) && ret == GST_FLOW_EOS) { if (PAD_PARENT_IS_DEMUXER (monitor) && ret == GST_FLOW_EOS) {
/* a demuxer can return EOS when the samples end */ /* a demuxer can return EOS when the samples end */
return; goto done;
} }
} }
@ -1298,6 +1356,9 @@ gst_validate_pad_monitor_check_aggregated_return (GstValidatePadMonitor *
gst_flow_get_name (ret), ret, gst_flow_get_name (aggregated), gst_flow_get_name (ret), ret, gst_flow_get_name (aggregated),
aggregated); aggregated);
} }
done:
gst_object_unref (pad);
} }
static void static void
@ -1308,19 +1369,23 @@ static void
gboolean done; gboolean done;
GstPad *otherpad; GstPad *otherpad;
GstValidatePadMonitor *othermonitor; GstValidatePadMonitor *othermonitor;
GstPad *pad;
if (!GST_EVENT_IS_SERIALIZED (event)) if (!GST_EVENT_IS_SERIALIZED (event))
return; return;
iter = pad =
gst_pad_iterate_internal_links (GST_VALIDATE_PAD_MONITOR_GET_PAD GST_PAD (gst_validate_monitor_get_target (GST_VALIDATE_MONITOR
(monitor)); (monitor)));
iter = gst_pad_iterate_internal_links (pad);
if (iter == NULL) { if (iter == NULL) {
/* inputselector will return NULL if the sinkpad is not the active one .... */ /* inputselector will return NULL if the sinkpad is not the active one .... */
GST_FIXME_OBJECT (GST_VALIDATE_PAD_MONITOR_GET_PAD GST_FIXME_OBJECT (pad, "No iterator");
(monitor), "No iterator"); gst_object_unref (pad);
return; return;
} }
done = FALSE; done = FALSE;
while (!done) { while (!done) {
GValue value = { 0, }; GValue value = { 0, };
@ -1334,7 +1399,7 @@ static void
data->timestamp = last_ts; data->timestamp = last_ts;
data->event = gst_event_ref (event); data->event = gst_event_ref (event);
GST_VALIDATE_MONITOR_LOCK (othermonitor); GST_VALIDATE_MONITOR_LOCK (othermonitor);
GST_DEBUG_OBJECT (monitor->pad, "Storing for pad %s:%s event %p %s", GST_DEBUG_OBJECT (pad, "Storing for pad %s:%s event %p %s",
GST_DEBUG_PAD_NAME (otherpad), event, GST_DEBUG_PAD_NAME (otherpad), event,
GST_EVENT_TYPE_NAME (event)); GST_EVENT_TYPE_NAME (event));
g_ptr_array_add (othermonitor->serialized_events, data); g_ptr_array_add (othermonitor->serialized_events, data);
@ -1347,7 +1412,7 @@ static void
gst_iterator_resync (iter); gst_iterator_resync (iter);
break; break;
case GST_ITERATOR_ERROR: case GST_ITERATOR_ERROR:
GST_WARNING_OBJECT (monitor->pad, "Internal links pad iteration error"); GST_WARNING_OBJECT (pad, "Internal links pad iteration error");
done = TRUE; done = TRUE;
break; break;
case GST_ITERATOR_DONE: case GST_ITERATOR_DONE:
@ -1356,6 +1421,7 @@ static void
} }
} }
gst_iterator_free (iter); gst_iterator_free (iter);
gst_object_unref (pad);
} }
static void static void
@ -1367,17 +1433,21 @@ gst_validate_pad_monitor_otherpad_add_pending_field (GstValidatePadMonitor *
GstPad *otherpad; GstPad *otherpad;
GstValidatePadMonitor *othermonitor; GstValidatePadMonitor *othermonitor;
const GValue *v; const GValue *v;
GstPad *pad;
v = gst_structure_get_value (structure, field); v = gst_structure_get_value (structure, field);
pad =
GST_PAD (gst_validate_monitor_get_target (GST_VALIDATE_MONITOR
(monitor)));
if (v == NULL) { if (v == NULL) {
GST_DEBUG_OBJECT (monitor->pad, "Not adding pending field %s as it isn't " GST_DEBUG_OBJECT (pad, "Not adding pending field %s as it isn't "
"present on structure %" GST_PTR_FORMAT, field, structure); "present on structure %" GST_PTR_FORMAT, field, structure);
gst_object_unref (pad);
return; return;
} }
iter = iter = gst_pad_iterate_internal_links (pad);
gst_pad_iterate_internal_links (GST_VALIDATE_PAD_MONITOR_GET_PAD
(monitor));
done = FALSE; done = FALSE;
while (!done) { while (!done) {
GValue value = { 0, }; GValue value = { 0, };
@ -1399,7 +1469,7 @@ gst_validate_pad_monitor_otherpad_add_pending_field (GstValidatePadMonitor *
gst_iterator_resync (iter); gst_iterator_resync (iter);
break; break;
case GST_ITERATOR_ERROR: case GST_ITERATOR_ERROR:
GST_WARNING_OBJECT (monitor->pad, "Internal links pad iteration error"); GST_WARNING_OBJECT (pad, "Internal links pad iteration error");
done = TRUE; done = TRUE;
break; break;
case GST_ITERATOR_DONE: case GST_ITERATOR_DONE:
@ -1408,6 +1478,7 @@ gst_validate_pad_monitor_otherpad_add_pending_field (GstValidatePadMonitor *
} }
} }
gst_iterator_free (iter); gst_iterator_free (iter);
gst_object_unref (pad);
} }
static void static void
@ -1419,11 +1490,13 @@ gst_validate_pad_monitor_otherpad_clear_pending_fields (GstValidatePadMonitor *
GstPad *otherpad; GstPad *otherpad;
GstValidatePadMonitor *othermonitor; GstValidatePadMonitor *othermonitor;
iter = GstPad *pad =
gst_pad_iterate_internal_links (GST_VALIDATE_PAD_MONITOR_GET_PAD GST_PAD (gst_validate_monitor_get_target (GST_VALIDATE_MONITOR
(monitor)); (monitor)));
iter = gst_pad_iterate_internal_links (pad);
if (iter == NULL) { if (iter == NULL) {
gst_object_unref (pad);
GST_DEBUG_OBJECT (monitor, "No internally linked pad"); GST_DEBUG_OBJECT (monitor, "No internally linked pad");
return; return;
@ -1451,7 +1524,7 @@ gst_validate_pad_monitor_otherpad_clear_pending_fields (GstValidatePadMonitor *
gst_iterator_resync (iter); gst_iterator_resync (iter);
break; break;
case GST_ITERATOR_ERROR: case GST_ITERATOR_ERROR:
GST_WARNING_OBJECT (monitor->pad, "Internal links pad iteration error"); GST_WARNING_OBJECT (pad, "Internal links pad iteration error");
done = TRUE; done = TRUE;
break; break;
case GST_ITERATOR_DONE: case GST_ITERATOR_DONE:
@ -1459,6 +1532,7 @@ gst_validate_pad_monitor_otherpad_clear_pending_fields (GstValidatePadMonitor *
break; break;
} }
} }
gst_object_unref (pad);
gst_iterator_free (iter); gst_iterator_free (iter);
} }
@ -1470,13 +1544,14 @@ gst_validate_pad_monitor_add_expected_newsegment (GstValidatePadMonitor *
gboolean done; gboolean done;
GstPad *otherpad; GstPad *otherpad;
GstValidatePadMonitor *othermonitor; GstValidatePadMonitor *othermonitor;
GstPad *pad =
GST_PAD (gst_validate_monitor_get_target (GST_VALIDATE_MONITOR
(monitor)));
iter = iter = gst_pad_iterate_internal_links (pad);
gst_pad_iterate_internal_links (GST_VALIDATE_PAD_MONITOR_GET_PAD
(monitor));
if (iter == NULL) { if (iter == NULL) {
GST_DEBUG_OBJECT (monitor, "No internally linked pad"); GST_DEBUG_OBJECT (monitor, "No internally linked pad");
gst_object_unref (pad);
return; return;
} }
@ -1499,7 +1574,7 @@ gst_validate_pad_monitor_add_expected_newsegment (GstValidatePadMonitor *
gst_iterator_resync (iter); gst_iterator_resync (iter);
break; break;
case GST_ITERATOR_ERROR: case GST_ITERATOR_ERROR:
GST_WARNING_OBJECT (monitor->pad, "Internal links pad iteration error"); GST_WARNING_OBJECT (pad, "Internal links pad iteration error");
done = TRUE; done = TRUE;
break; break;
case GST_ITERATOR_DONE: case GST_ITERATOR_DONE:
@ -1508,6 +1583,7 @@ gst_validate_pad_monitor_add_expected_newsegment (GstValidatePadMonitor *
} }
} }
gst_iterator_free (iter); gst_iterator_free (iter);
gst_object_unref (pad);
} }
static void static void
@ -1600,9 +1676,13 @@ static void
mark_pads_eos (GstValidatePadMonitor * pad_monitor) mark_pads_eos (GstValidatePadMonitor * pad_monitor)
{ {
GstValidatePadMonitor *peer_monitor; GstValidatePadMonitor *peer_monitor;
GstPad *peer = gst_pad_get_peer (pad_monitor->pad);
GstPad *real_peer; GstPad *real_peer;
GstPad *pad =
GST_PAD (gst_validate_monitor_get_target (GST_VALIDATE_MONITOR
(pad_monitor)));
GstPad *peer = gst_pad_get_peer (pad);
gst_object_unref (pad);
pad_monitor->is_eos = TRUE; pad_monitor->is_eos = TRUE;
if (peer) { if (peer) {
real_peer = _get_actual_pad (peer); real_peer = _get_actual_pad (peer);
@ -1619,7 +1699,9 @@ static inline gboolean
_should_check_buffers (GstValidatePadMonitor * pad_monitor, _should_check_buffers (GstValidatePadMonitor * pad_monitor,
gboolean force_checks) gboolean force_checks)
{ {
GstPad *pad = GST_VALIDATE_PAD_MONITOR_GET_PAD (pad_monitor); GstPad *pad =
GST_PAD (gst_validate_monitor_get_target (GST_VALIDATE_MONITOR
(pad_monitor)));
GstValidateMonitor *monitor = GST_VALIDATE_MONITOR (pad_monitor); GstValidateMonitor *monitor = GST_VALIDATE_MONITOR (pad_monitor);
if (pad_monitor->first_buffer || force_checks) { if (pad_monitor->first_buffer || force_checks) {
@ -1666,6 +1748,7 @@ _should_check_buffers (GstValidatePadMonitor * pad_monitor,
pad_monitor->check_buffers = TRUE; pad_monitor->check_buffers = TRUE;
} }
} }
gst_object_unref (pad);
return pad_monitor->check_buffers; return pad_monitor->check_buffers;
} }
@ -1738,7 +1821,9 @@ gst_validate_pad_monitor_downstream_event_check (GstValidatePadMonitor *
GstFlowReturn ret = GST_FLOW_OK; GstFlowReturn ret = GST_FLOW_OK;
const GstSegment *segment; const GstSegment *segment;
guint32 seqnum = gst_event_get_seqnum (event); guint32 seqnum = gst_event_get_seqnum (event);
GstPad *pad = GST_VALIDATE_PAD_MONITOR_GET_PAD (pad_monitor); GstPad *pad =
GST_PAD (gst_validate_monitor_get_target (GST_VALIDATE_MONITOR
(pad_monitor)));
gst_validate_pad_monitor_common_event_check (pad_monitor, event); gst_validate_pad_monitor_common_event_check (pad_monitor, event);
@ -1752,8 +1837,7 @@ gst_validate_pad_monitor_downstream_event_check (GstValidatePadMonitor *
/* parse segment data to be used if event is handled */ /* parse segment data to be used if event is handled */
gst_event_parse_segment (event, &segment); gst_event_parse_segment (event, &segment);
GST_DEBUG_OBJECT (pad_monitor->pad, "Got segment %" GST_SEGMENT_FORMAT, GST_DEBUG_OBJECT (pad, "Got segment %" GST_SEGMENT_FORMAT, segment);
segment);
/* Reset expected flush start/stop values, we have a segment */ /* Reset expected flush start/stop values, we have a segment */
pad_monitor->pending_flush_start_seqnum = 0; pad_monitor->pending_flush_start_seqnum = 0;
@ -1904,6 +1988,7 @@ gst_validate_pad_monitor_downstream_event_check (GstValidatePadMonitor *
if (handler) if (handler)
gst_event_unref (event); gst_event_unref (event);
gst_object_unref (pad);
return ret; return ret;
} }
@ -1918,7 +2003,9 @@ gst_validate_pad_monitor_src_event_check (GstValidatePadMonitor * pad_monitor,
GstSeekFlags seek_flags; GstSeekFlags seek_flags;
GstSeekType start_type, stop_type; GstSeekType start_type, stop_type;
guint32 seqnum = gst_event_get_seqnum (event); guint32 seqnum = gst_event_get_seqnum (event);
GstPad *pad = GST_VALIDATE_PAD_MONITOR_GET_PAD (pad_monitor); GstPad *pad =
GST_PAD (gst_validate_monitor_get_target (GST_VALIDATE_MONITOR
(pad_monitor)));
gst_validate_pad_monitor_common_event_check (pad_monitor, event); gst_validate_pad_monitor_common_event_check (pad_monitor, event);
@ -1948,7 +2035,7 @@ gst_validate_pad_monitor_src_event_check (GstValidatePadMonitor * pad_monitor,
/* Safely store pending accurate seek values */ /* Safely store pending accurate seek values */
if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK) { if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK) {
if (seek_flags & GST_SEEK_FLAG_ACCURATE) { if (seek_flags & GST_SEEK_FLAG_ACCURATE) {
GST_DEBUG_OBJECT (pad_monitor->pad, GST_DEBUG_OBJECT (pad,
"Storing expected accurate seek time %" GST_TIME_FORMAT, "Storing expected accurate seek time %" GST_TIME_FORMAT,
GST_TIME_ARGS (start)); GST_TIME_ARGS (start));
pad_monitor->pending_seek_accurate_time = start; pad_monitor->pending_seek_accurate_time = start;
@ -1969,7 +2056,7 @@ gst_validate_pad_monitor_src_event_check (GstValidatePadMonitor * pad_monitor,
* expected accurate seek value */ * expected accurate seek value */
if (ret && pad_monitor->has_segment if (ret && pad_monitor->has_segment
&& seqnum == pad_monitor->pending_eos_seqnum) { && seqnum == pad_monitor->pending_eos_seqnum) {
GST_DEBUG_OBJECT (pad_monitor->pad, GST_DEBUG_OBJECT (pad,
"Resetting expected accurate seek value, was already handled"); "Resetting expected accurate seek value, was already handled");
pad_monitor->pending_seek_accurate_time = GST_CLOCK_TIME_NONE; pad_monitor->pending_seek_accurate_time = GST_CLOCK_TIME_NONE;
} else if (!ret) { } else if (!ret) {
@ -1999,6 +2086,7 @@ gst_validate_pad_monitor_src_event_check (GstValidatePadMonitor * pad_monitor,
if (handler) if (handler)
gst_event_unref (event); gst_event_unref (event);
gst_object_unref (pad);
return ret; return ret;
} }
@ -2011,13 +2099,18 @@ gst_validate_pad_monitor_check_right_buffer (GstValidatePadMonitor *
GstMapInfo map, wanted_map; GstMapInfo map, wanted_map;
gboolean ret = TRUE; gboolean ret = TRUE;
GstPad *pad = GST_VALIDATE_PAD_MONITOR_GET_PAD (pad_monitor); GstPad *pad;
if (_should_check_buffers (pad_monitor, FALSE) == FALSE) if (_should_check_buffers (pad_monitor, FALSE) == FALSE)
return FALSE; return FALSE;
pad =
GST_PAD (gst_validate_monitor_get_target (GST_VALIDATE_MONITOR
(pad_monitor)));
if (pad_monitor->current_buf == NULL) { if (pad_monitor->current_buf == NULL) {
GST_INFO_OBJECT (pad, "No current buffer one pad, Why?"); GST_INFO_OBJECT (pad, "No current buffer one pad, Why?");
gst_object_unref (pad);
return FALSE; return FALSE;
} }
@ -2081,6 +2174,7 @@ gst_validate_pad_monitor_check_right_buffer (GstValidatePadMonitor *
gst_buffer_unmap (wanted_buf, &wanted_map); gst_buffer_unmap (wanted_buf, &wanted_map);
gst_buffer_unmap (buffer, &map); gst_buffer_unmap (buffer, &map);
g_free (checksum); g_free (checksum);
gst_object_unref (pad);
pad_monitor->current_buf = pad_monitor->current_buf->next; pad_monitor->current_buf = pad_monitor->current_buf->next;
@ -2533,12 +2627,14 @@ gst_validate_pad_monitor_setcaps_pre (GstValidatePadMonitor * pad_monitor,
GstCaps * caps) GstCaps * caps)
{ {
GstStructure *structure; GstStructure *structure;
GstPad *pad =
GST_PAD (gst_validate_monitor_get_target (GST_VALIDATE_MONITOR
(pad_monitor)));
/* Check if caps are identical to last caps and complain if so /* Check if caps are identical to last caps and complain if so
* Only checked for sink pads as src pads might push the same caps * Only checked for sink pads as src pads might push the same caps
* multiple times during unlinked/autoplugging scenarios */ * multiple times during unlinked/autoplugging scenarios */
if (GST_PAD_IS_SINK (GST_VALIDATE_PAD_MONITOR_GET_PAD (pad_monitor)) && if (GST_PAD_IS_SINK (pad) && pad_monitor->last_caps
pad_monitor->last_caps
&& gst_caps_is_equal (caps, pad_monitor->last_caps)) { && gst_caps_is_equal (caps, pad_monitor->last_caps)) {
gchar *caps_str = gst_caps_to_string (caps); gchar *caps_str = gst_caps_to_string (caps);
@ -2586,10 +2682,10 @@ gst_validate_pad_monitor_setcaps_pre (GstValidatePadMonitor * pad_monitor,
} }
} }
if (GST_PAD_IS_SINK (GST_VALIDATE_PAD_MONITOR_GET_PAD (pad_monitor)) && if (GST_PAD_IS_SINK (pad) &&
gst_validate_pad_monitor_pad_should_proxy_othercaps (pad_monitor)) { gst_validate_pad_monitor_pad_should_proxy_othercaps (pad_monitor)) {
if (_structure_is_video (structure)) { if (_structure_is_video (structure)) {
GST_DEBUG_OBJECT (GST_VALIDATE_PAD_MONITOR_GET_PAD (pad_monitor), GST_DEBUG_OBJECT (pad,
"Adding video common pending fields to other pad: %" GST_PTR_FORMAT, "Adding video common pending fields to other pad: %" GST_PTR_FORMAT,
structure); structure);
gst_validate_pad_monitor_otherpad_add_pending_field (pad_monitor, gst_validate_pad_monitor_otherpad_add_pending_field (pad_monitor,
@ -2601,7 +2697,7 @@ gst_validate_pad_monitor_setcaps_pre (GstValidatePadMonitor * pad_monitor,
gst_validate_pad_monitor_otherpad_add_pending_field (pad_monitor, gst_validate_pad_monitor_otherpad_add_pending_field (pad_monitor,
structure, "pixel-aspect-ratio"); structure, "pixel-aspect-ratio");
} else if (_structure_is_audio (structure)) { } else if (_structure_is_audio (structure)) {
GST_DEBUG_OBJECT (GST_VALIDATE_PAD_MONITOR_GET_PAD (pad_monitor), GST_DEBUG_OBJECT (pad,
"Adding audio common pending fields to other pad: %" GST_PTR_FORMAT, "Adding audio common pending fields to other pad: %" GST_PTR_FORMAT,
structure); structure);
gst_validate_pad_monitor_otherpad_add_pending_field (pad_monitor, gst_validate_pad_monitor_otherpad_add_pending_field (pad_monitor,
@ -2615,6 +2711,7 @@ gst_validate_pad_monitor_setcaps_pre (GstValidatePadMonitor * pad_monitor,
gst_structure_free (pad_monitor->pending_setcaps_fields); gst_structure_free (pad_monitor->pending_setcaps_fields);
pad_monitor->pending_setcaps_fields = pad_monitor->pending_setcaps_fields =
gst_structure_new_empty (PENDING_FIELDS); gst_structure_new_empty (PENDING_FIELDS);
gst_object_unref (pad);
gst_validate_pad_monitor_setcaps_overrides (pad_monitor, caps); gst_validate_pad_monitor_setcaps_overrides (pad_monitor, caps);
} }
@ -2638,25 +2735,24 @@ static gboolean
gst_validate_pad_monitor_do_setup (GstValidateMonitor * monitor) gst_validate_pad_monitor_do_setup (GstValidateMonitor * monitor)
{ {
GstValidatePadMonitor *pad_monitor = GST_VALIDATE_PAD_MONITOR_CAST (monitor); GstValidatePadMonitor *pad_monitor = GST_VALIDATE_PAD_MONITOR_CAST (monitor);
GstPad *pad; GstPad *pad = (gpointer) gst_validate_monitor_get_target (monitor);
if (!GST_IS_PAD (GST_VALIDATE_MONITOR_GET_OBJECT (monitor))) {
if (!GST_IS_PAD (pad)) {
GST_WARNING_OBJECT (monitor, "Trying to create pad monitor with other " GST_WARNING_OBJECT (monitor, "Trying to create pad monitor with other "
"type of object"); "type of object");
gst_object_unref (pad);
return FALSE; return FALSE;
} }
pad = GST_VALIDATE_PAD_MONITOR_GET_PAD (pad_monitor);
if (g_object_get_data ((GObject *) pad, "validate-monitor")) { if (g_object_get_data ((GObject *) pad, "validate-monitor")) {
GST_WARNING_OBJECT (pad_monitor, GST_WARNING_OBJECT (pad_monitor,
"Pad already has a validate-monitor associated"); "Pad already has a validate-monitor associated");
gst_object_unref (pad);
return FALSE; return FALSE;
} }
g_object_set_data ((GObject *) pad, "validate-monitor", pad_monitor); g_object_set_data ((GObject *) pad, "validate-monitor", pad_monitor);
pad_monitor->pad = pad;
pad_monitor->event_func = GST_PAD_EVENTFUNC (pad); pad_monitor->event_func = GST_PAD_EVENTFUNC (pad);
pad_monitor->event_full_func = GST_PAD_EVENTFULLFUNC (pad); pad_monitor->event_full_func = GST_PAD_EVENTFULLFUNC (pad);
pad_monitor->query_func = GST_PAD_QUERYFUNC (pad); pad_monitor->query_func = GST_PAD_QUERYFUNC (pad);
@ -2698,5 +2794,6 @@ gst_validate_pad_monitor_do_setup (GstValidateMonitor * monitor)
if (G_UNLIKELY (GST_PAD_PARENT (pad) == NULL)) if (G_UNLIKELY (GST_PAD_PARENT (pad) == NULL))
GST_FIXME ("Saw a pad not belonging to any object"); GST_FIXME ("Saw a pad not belonging to any object");
gst_object_unref (pad);
return TRUE; return TRUE;
} }

View file

@ -43,8 +43,6 @@ G_BEGIN_DECLS
#define GST_VALIDATE_PAD_MONITOR_CAST(obj) ((GstValidatePadMonitor*)(obj)) #define GST_VALIDATE_PAD_MONITOR_CAST(obj) ((GstValidatePadMonitor*)(obj))
#define GST_VALIDATE_PAD_MONITOR_CLASS_CAST(klass) ((GstValidatePadMonitorClass*)(klass)) #define GST_VALIDATE_PAD_MONITOR_CLASS_CAST(klass) ((GstValidatePadMonitorClass*)(klass))
#define GST_VALIDATE_PAD_MONITOR_GET_PAD(m) (GST_PAD_CAST (GST_VALIDATE_MONITOR_GET_OBJECT (m)))
/** /**
* GstValidatePadMonitor: * GstValidatePadMonitor:
@ -59,7 +57,6 @@ struct _GstValidatePadMonitor {
GstValidateElementMonitor *element_monitor; GstValidateElementMonitor *element_monitor;
gboolean setup; gboolean setup;
GstPad *pad;
GstPadChainFunction chain_func; GstPadChainFunction chain_func;
GstPadEventFunction event_func; GstPadEventFunction event_func;

View file

@ -92,7 +92,7 @@ print_position (GstValidateMonitor * monitor)
gint64 position, duration; gint64 position, duration;
JsonBuilder *jbuilder; JsonBuilder *jbuilder;
GstElement *pipeline = GstElement *pipeline =
GST_ELEMENT (GST_VALIDATE_MONITOR_GET_OBJECT (monitor)); GST_ELEMENT (gst_validate_monitor_get_pipeline (monitor));
gdouble rate = 1.0; gdouble rate = 1.0;
GstFormat format = GST_FORMAT_TIME; GstFormat format = GST_FORMAT_TIME;
@ -100,14 +100,14 @@ print_position (GstValidateMonitor * monitor)
if (!gst_element_query_position (pipeline, format, &position)) { if (!gst_element_query_position (pipeline, format, &position)) {
GST_DEBUG_OBJECT (monitor, "Could not query position"); GST_DEBUG_OBJECT (monitor, "Could not query position");
return TRUE; goto done;
} }
format = GST_FORMAT_TIME; format = GST_FORMAT_TIME;
if (!gst_element_query_duration (pipeline, format, &duration)) { if (!gst_element_query_duration (pipeline, format, &duration)) {
GST_DEBUG_OBJECT (monitor, "Could not query duration"); GST_DEBUG_OBJECT (monitor, "Could not query duration");
return TRUE; goto done;
} }
query = gst_query_new_segment (GST_FORMAT_DEFAULT); query = gst_query_new_segment (GST_FORMAT_DEFAULT);
@ -134,6 +134,8 @@ print_position (GstValidateMonitor * monitor)
"<position: %" GST_TIME_FORMAT " duration: %" GST_TIME_FORMAT "<position: %" GST_TIME_FORMAT " duration: %" GST_TIME_FORMAT
" speed: %f />\r", GST_TIME_ARGS (position), GST_TIME_ARGS (duration), " speed: %f />\r", GST_TIME_ARGS (position), GST_TIME_ARGS (duration),
rate); rate);
done:
gst_object_unref (pipeline);
return TRUE; return TRUE;
} }
@ -283,9 +285,12 @@ _append_query_caps_failure_details (GstValidatePadMonitor * monitor,
gint i, j; gint i, j;
gboolean found = FALSE, empty_filter; gboolean found = FALSE, empty_filter;
GstCaps *filter = gst_caps_copy (monitor->last_query_filter); GstCaps *filter = gst_caps_copy (monitor->last_query_filter);
GstCaps *possible_caps = gst_pad_query_caps (monitor->pad, NULL);
const gchar *filter_name, *possible_name; const gchar *filter_name, *possible_name;
GstStructure *filter_struct, *possible_struct; GstStructure *filter_struct, *possible_struct;
GstPad *pad =
GST_PAD (gst_validate_monitor_get_target (GST_VALIDATE_MONITOR
(monitor)));
GstCaps *possible_caps = gst_pad_query_caps (pad, NULL);
g_string_append_printf (str, g_string_append_printf (str,
"\n Caps negotiation failed starting from pad '%s'" "\n Caps negotiation failed starting from pad '%s'"
@ -294,7 +299,7 @@ _append_query_caps_failure_details (GstValidatePadMonitor * monitor,
empty_filter = gst_caps_is_empty (filter); empty_filter = gst_caps_is_empty (filter);
if (empty_filter) { if (empty_filter) {
GstPad *peer = _get_peer_pad (monitor->pad); GstPad *peer = _get_peer_pad (pad);
gchar *prev_path = NULL; gchar *prev_path = NULL;
if (peer) { if (peer) {
@ -362,6 +367,7 @@ _append_query_caps_failure_details (GstValidatePadMonitor * monitor,
gst_caps_unref (possible_caps); gst_caps_unref (possible_caps);
gst_caps_unref (filter); gst_caps_unref (filter);
gst_object_unref (pad);
} }
@ -371,7 +377,10 @@ _append_accept_caps_failure_details (GstValidatePadMonitor * monitor,
{ {
gint i, j; gint i, j;
GstCaps *refused_caps = gst_caps_copy (monitor->last_refused_caps); GstCaps *refused_caps = gst_caps_copy (monitor->last_refused_caps);
GstCaps *possible_caps = gst_pad_query_caps (monitor->pad, NULL); GstPad *pad =
GST_PAD (gst_validate_monitor_get_target (GST_VALIDATE_MONITOR
(monitor)));
GstCaps *possible_caps = gst_pad_query_caps (pad, NULL);
gchar *caps_str = gst_caps_to_string (monitor->last_refused_caps); gchar *caps_str = gst_caps_to_string (monitor->last_refused_caps);
StructureIncompatibleFieldsInfo info = { StructureIncompatibleFieldsInfo info = {
.str = str, .str = str,
@ -409,6 +418,7 @@ _append_accept_caps_failure_details (GstValidatePadMonitor * monitor,
} }
gst_caps_unref (possible_caps); gst_caps_unref (possible_caps);
gst_object_unref (pad);
return TRUE; return TRUE;
} }
@ -494,7 +504,9 @@ _bus_handler (GstBus * bus, GstMessage * message,
break; break;
case GST_MESSAGE_STATE_CHANGED: case GST_MESSAGE_STATE_CHANGED:
{ {
if (GST_MESSAGE_SRC (message) == GST_VALIDATE_MONITOR (monitor)->target) { GstObject *target =
gst_validate_monitor_get_target (GST_VALIDATE_MONITOR (monitor));
if (GST_MESSAGE_SRC (message) == target) {
GstState oldstate, newstate, pending; GstState oldstate, newstate, pending;
gst_message_parse_state_changed (message, &oldstate, &newstate, gst_message_parse_state_changed (message, &oldstate, &newstate,
@ -512,6 +524,9 @@ _bus_handler (GstBus * bus, GstMessage * message,
} }
} }
if (target)
gst_object_unref (target);
break; break;
} }
case GST_MESSAGE_BUFFERING: case GST_MESSAGE_BUFFERING:
@ -597,7 +612,9 @@ gst_validate_pipeline_monitor_create_scenarios (GstValidateBinMonitor * monitor)
{ {
/* scenarios currently only make sense for pipelines */ /* scenarios currently only make sense for pipelines */
const gchar *scenarios_names; const gchar *scenarios_names;
gchar **scenarios; gchar **scenarios = NULL;
GstObject *target =
gst_validate_monitor_get_target (GST_VALIDATE_MONITOR (monitor));
if ((scenarios_names = g_getenv ("GST_VALIDATE_SCENARIO"))) { if ((scenarios_names = g_getenv ("GST_VALIDATE_SCENARIO"))) {
gint i; gint i;
@ -606,27 +623,24 @@ gst_validate_pipeline_monitor_create_scenarios (GstValidateBinMonitor * monitor)
for (i = 0; scenarios[i]; i++) { for (i = 0; scenarios[i]; i++) {
gchar **scenario_v = g_strsplit (scenarios[i], "->", 2); gchar **scenario_v = g_strsplit (scenarios[i], "->", 2);
if (scenario_v[1] && GST_VALIDATE_MONITOR_GET_OBJECT (monitor)) { if (scenario_v[1] && target) {
if (!g_pattern_match_simple (scenario_v[1], if (!g_pattern_match_simple (scenario_v[1], GST_OBJECT_NAME (target))) {
GST_OBJECT_NAME (GST_VALIDATE_MONITOR_GET_OBJECT (monitor)))) {
GST_INFO_OBJECT (monitor, "Not attaching to pipeline %" GST_PTR_FORMAT GST_INFO_OBJECT (monitor, "Not attaching to pipeline %" GST_PTR_FORMAT
" as not matching pattern %s", " as not matching pattern %s", target, scenario_v[1]);
GST_VALIDATE_MONITOR_GET_OBJECT (monitor), scenario_v[1]);
g_strfreev (scenario_v); goto done;
return;
} }
} }
monitor->scenario = monitor->scenario =
gst_validate_scenario_factory_create (GST_VALIDATE_MONITOR_GET_RUNNER gst_validate_scenario_factory_create (GST_VALIDATE_MONITOR_GET_RUNNER
(monitor), (monitor), GST_ELEMENT_CAST (target), scenario_v[0]);
GST_ELEMENT_CAST (GST_VALIDATE_MONITOR_GET_OBJECT (monitor)),
scenario_v[0]);
g_strfreev (scenario_v); g_strfreev (scenario_v);
} }
g_strfreev (scenarios);
} }
done:
g_strfreev (scenarios);
if (target)
gst_object_unref (target);
} }
/** /**
@ -642,8 +656,10 @@ gst_validate_pipeline_monitor_new (GstPipeline * pipeline,
g_object_new (GST_TYPE_VALIDATE_PIPELINE_MONITOR, "object", g_object_new (GST_TYPE_VALIDATE_PIPELINE_MONITOR, "object",
pipeline, "validate-runner", runner, "validate-parent", parent, pipeline, "validate-runner", runner, "validate-parent", parent,
"pipeline", pipeline, NULL); "pipeline", pipeline, NULL);
GstObject *target =
gst_validate_monitor_get_target (GST_VALIDATE_MONITOR (monitor));
if (GST_VALIDATE_MONITOR_GET_OBJECT (monitor) == NULL) { if (target == NULL) {
g_object_unref (monitor); g_object_unref (monitor);
return NULL; return NULL;
} }
@ -661,6 +677,7 @@ gst_validate_pipeline_monitor_new (GstPipeline * pipeline,
monitor->is_playbin = TRUE; monitor->is_playbin = TRUE;
else if (g_strcmp0 (G_OBJECT_TYPE_NAME (pipeline), "GstPlayBin3") == 0) else if (g_strcmp0 (G_OBJECT_TYPE_NAME (pipeline), "GstPlayBin3") == 0)
monitor->is_playbin3 = TRUE; monitor->is_playbin3 = TRUE;
gst_object_unref (target);
return monitor; return monitor;
} }

View file

@ -235,7 +235,6 @@ struct _GstValidateScenarioClass
/** /**
* GstValidateScenario: * GstValidateScenario:
* @pipeline: The #GstPipeline on which the scenario is being executed.
*/ */
struct _GstValidateScenario struct _GstValidateScenario
{ {

View file

@ -25,7 +25,7 @@
* @short_description: GstValidate plugin to detect frame corruptions * @short_description: GstValidate plugin to detect frame corruptions
* *
* GstValidate plugin to run the ssim algorithm on the buffers flowing in the * GstValidate plugin to run the ssim algorithm on the buffers flowing in the
* pipeline to find regressions and detect frame corruptions. * pipeline to find regressions and detect frame corruptions.
* It allows you to generate image files from the buffers flowing in the pipeline * It allows you to generate image files from the buffers flowing in the pipeline
* (either as raw in the many formats supported by GStreamer or as png) and then * (either as raw in the many formats supported by GStreamer or as png) and then
* check them against pre generated, reference images. * check them against pre generated, reference images.
@ -355,29 +355,30 @@ static gboolean
_can_attach (GstValidateOverride * override, GstValidateMonitor * monitor) _can_attach (GstValidateOverride * override, GstValidateMonitor * monitor)
{ {
guint i; guint i;
GstPad *pad; GstPad *pad = NULL;
GstCaps *template_caps; GstCaps *template_caps;
GstElement *element; GstElement *element = NULL;
GstStructure *structure; GstStructure *structure;
gboolean res = TRUE;
if (VALIDATE_SSIM_OVERRIDE (override)->priv->is_attached) { if (VALIDATE_SSIM_OVERRIDE (override)->priv->is_attached) {
GST_ERROR_OBJECT (override, "Already attached"); GST_ERROR_OBJECT (override, "Already attached");
return FALSE; goto fail;
} }
if (!GST_IS_VALIDATE_PAD_MONITOR (monitor)) { if (!GST_IS_VALIDATE_PAD_MONITOR (monitor)) {
return FALSE; goto fail;
} }
pad = GST_VALIDATE_PAD_MONITOR_GET_PAD (monitor); pad = GST_PAD (gst_validate_monitor_get_target (monitor));
element = gst_validate_monitor_get_element (monitor); element = gst_validate_monitor_get_element (monitor);
if ((gst_validate_element_has_klass (element, "Converter") || if ((gst_validate_element_has_klass (element, "Converter") ||
gst_validate_element_has_klass (element, "Filter")) && gst_validate_element_has_klass (element, "Filter")) &&
GST_PAD_IS_SINK (pad)) { GST_PAD_IS_SINK (pad)) {
GST_INFO_OBJECT (override, "Not attaching on filter sinkpads"); GST_INFO_OBJECT (override, "Not attaching on filter sinkpads");
return FALSE; goto fail;
} }
template_caps = GST_PAD_TEMPLATE_CAPS (GST_PAD_PAD_TEMPLATE (pad)); template_caps = GST_PAD_TEMPLATE_CAPS (GST_PAD_PAD_TEMPLATE (pad));
@ -391,11 +392,20 @@ _can_attach (GstValidateOverride * override, GstValidateMonitor * monitor)
gst_validate_reporter_get_name (GST_VALIDATE_REPORTER gst_validate_reporter_get_name (GST_VALIDATE_REPORTER
(monitor)))); (monitor))));
return TRUE; goto done;
} }
} }
return FALSE; done:
if (pad)
gst_object_unref (pad);
if (element)
gst_object_unref (element);
return res;
fail:
res = FALSE;
goto done;
} }
static void static void
@ -469,9 +479,12 @@ _set_videoconvert (ValidateSsimOverride * o,
GstCaps *caps; GstCaps *caps;
GstVideoFormat format; GstVideoFormat format;
ValidateSsimOverridePriv *priv = o->priv; ValidateSsimOverridePriv *priv = o->priv;
GstPad *pad = GST_VALIDATE_PAD_MONITOR_GET_PAD (pad_monitor); GstPad *pad =
GST_PAD (gst_validate_monitor_get_target (GST_VALIDATE_MONITOR
(pad_monitor)));
caps = gst_pad_get_current_caps (pad); caps = gst_pad_get_current_caps (pad);
gst_object_unref (pad);
gst_caps_replace (&priv->last_caps, caps); gst_caps_replace (&priv->last_caps, caps);
gst_video_info_init (&priv->in_info); gst_video_info_init (&priv->in_info);