static void _test_flow_aggregation (GstFlowReturn flow, GstFlowReturn flow1, GstFlowReturn flow2, GstFlowReturn demux_flow, gboolean should_fail) { GstPad *srcpad; GstValidateReport *report; GstValidatePadMonitor *pmonitor, *pmonitor1, *pmonitor2; GstElement *demuxer = fake_demuxer_new (); GstBin *pipeline = GST_BIN (gst_pipeline_new ("validate-pipeline")); GList *reports; GstValidateRunner *runner; GstValidateMonitor *monitor; fail_unless (g_setenv ("GST_VALIDATE_REPORTING_DETAILS", "all", TRUE)); runner = gst_validate_runner_new (); monitor = gst_validate_monitor_factory_create (GST_OBJECT (pipeline), runner, NULL); gst_validate_reporter_set_handle_g_logs (GST_VALIDATE_REPORTER (monitor)); gst_bin_add (pipeline, demuxer); fake_demuxer_prepare_pads (pipeline, demuxer, runner); srcpad = gst_pad_new ("srcpad1", GST_PAD_SRC); gst_pad_link (srcpad, demuxer->sinkpads->data); fail_unless (gst_pad_activate_mode (srcpad, GST_PAD_MODE_PUSH, TRUE)); gst_check_setup_events_with_stream_id (srcpad, demuxer, NULL, GST_FORMAT_TIME, "the-stream"); pmonitor = _get_pad_monitor (gst_pad_get_peer (demuxer->srcpads->data)); pmonitor1 = _get_pad_monitor (gst_pad_get_peer (demuxer->srcpads->next->data)); pmonitor2 = _get_pad_monitor (gst_pad_get_peer (demuxer->srcpads->next->next->data)); pmonitor->last_flow_return = flow; pmonitor1->last_flow_return = flow1; pmonitor2->last_flow_return = flow2; FAKE_DEMUXER (demuxer)->return_value = demux_flow; fail_unless_equals_int (gst_pad_push (srcpad, gst_buffer_new ()), demux_flow); reports = gst_validate_runner_get_reports (runner); if (should_fail) { assert_equals_int (g_list_length (reports), 1); report = reports->data; fail_unless_equals_int (report->level, GST_VALIDATE_REPORT_LEVEL_CRITICAL); fail_unless_equals_int (report->issue->issue_id, WRONG_FLOW_RETURN); } else { assert_equals_int (g_list_length (reports), 0); } g_list_free_full (reports, (GDestroyNotify) gst_validate_report_unref); clean_bus (GST_ELEMENT (pipeline)); gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL); ASSERT_OBJECT_REFCOUNT (pipeline, "ours", 1); check_destroyed (pipeline, demuxer, NULL); check_destroyed (monitor, pmonitor, NULL); }
static void gst_validate_monitor_finalize (GObject * object) { gst_validate_reporter_set_name (GST_VALIDATE_REPORTER (object), NULL); G_OBJECT_CLASS (parent_class)->finalize (object); }
static gboolean gst_validate_runner_should_monitor (GstValidateRunner * self, GstElement * element) { gint i; GstValidateMonitor *monitor; if (!GST_IS_PIPELINE (element)) { return FALSE; } if (self->priv->user_created) return FALSE; if (!self->priv->pipeline_names_strv) return TRUE; monitor = gst_validate_get_monitor (G_OBJECT (element)); if (monitor) { GST_ERROR_OBJECT (self, "Pipeline %" GST_PTR_FORMAT " is already" " monitored by %" GST_PTR_FORMAT " using runner: %" GST_PTR_FORMAT " NOT monitoring again.", element, monitor, gst_validate_reporter_get_runner (GST_VALIDATE_REPORTER (monitor))); } for (i = 0; self->priv->pipeline_names_strv[i]; i++) { if (g_pattern_match_simple (self->priv->pipeline_names_strv[i], GST_OBJECT_NAME (element))) return TRUE; } return FALSE; }
gboolean ges_validate_activate (GstPipeline * pipeline, const gchar * scenario, gboolean * needs_setting_state) { GstValidateRunner *runner = NULL; GstValidateMonitor *monitor = NULL; ges_validate_register_action_types (); if (scenario) { if (g_strcmp0 (scenario, "none")) { gchar *scenario_name = g_strconcat (scenario, "->gespipeline*", NULL); g_setenv ("GST_VALIDATE_SCENARIO", scenario_name, TRUE); g_free (scenario_name); } } runner = gst_validate_runner_new (); g_signal_connect (runner, "report-added", G_CALLBACK (_validate_report_added_cb), pipeline); monitor = gst_validate_monitor_factory_create (GST_OBJECT_CAST (pipeline), runner, NULL); gst_validate_reporter_set_handle_g_logs (GST_VALIDATE_REPORTER (monitor)); g_object_get (monitor, "handles-states", needs_setting_state, NULL); *needs_setting_state = !*needs_setting_state; g_object_set_data (G_OBJECT (pipeline), MONITOR_ON_PIPELINE, monitor); g_object_set_data (G_OBJECT (pipeline), RUNNER_ON_PIPELINE, runner); return TRUE; }
static void _get_property (GObject * object, guint property_id, GValue * value, GParamSpec * pspec) { switch (property_id) { case PROP_RUNNER: g_value_set_object (value, gst_validate_reporter_get_runner (GST_VALIDATE_REPORTER (object))); break; default: break; } }
GstValidateSsim * gst_validate_ssim_new (GstValidateRunner * runner, gfloat min_avg_similarity, gfloat min_lowest_similarity) { GstValidateSsim *self = g_object_new (GST_VALIDATE_SSIM_TYPE, "validate-runner", runner, NULL); self->priv->min_avg_similarity = min_avg_similarity; self->priv->min_lowest_similarity = min_lowest_similarity; gst_validate_reporter_set_name (GST_VALIDATE_REPORTER (self), g_strdup ("gst-validate-images-checker")); return self; }
static void gst_validate_ssim_set_property (GObject * object, guint property_id, const GValue * value, GParamSpec * pspec) { switch (property_id) { case PROP_RUNNER: /* we assume the runner is valid as long as this scenario is, * no ref taken */ gst_validate_reporter_set_runner (GST_VALIDATE_REPORTER (object), g_value_get_object (value)); break; default: break; } }
static gboolean _append_accept_caps_failure_details (GstValidatePadMonitor * monitor, GString * str) { gint i, j; GstCaps *refused_caps = gst_caps_copy (monitor->last_refused_caps); GstCaps *possible_caps = gst_pad_query_caps (monitor->pad, NULL); gchar *caps_str = gst_caps_to_string (monitor->last_refused_caps); StructureIncompatibleFieldsInfo info = { .str = str, .found = FALSE }; g_string_append_printf (str, "\n Caps negotiation failed at pad '%s' as it refused caps: %s", gst_validate_reporter_get_name (GST_VALIDATE_REPORTER (monitor)), caps_str); g_free (caps_str); for (i = 0; i < gst_caps_get_size (refused_caps); i++) { GstStructure *refused_struct = gst_caps_get_structure (refused_caps, i); const gchar *filter_name; const gchar *refused_name = gst_structure_get_name (refused_struct); for (j = 0; j < gst_caps_get_size (possible_caps); j++) { info.caps_struct_num = i, info.filter_caps_struct_num = j, info.filter = gst_caps_get_structure (possible_caps, j); filter_name = gst_structure_get_name (info.filter); if (g_strcmp0 (refused_name, filter_name)) { g_string_append_printf (str, "\n -> Downstream caps struct %d name '%s' differs from " "filter caps struct %d name '%s'", i, refused_name, j, filter_name); continue; } gst_structure_foreach (refused_struct, (GstStructureForeachFunc) _find_structure_incompatible_fields, &info); } } gst_caps_unref (possible_caps); return TRUE; }
static void gst_validate_element_monitor_wrap_pad (GstValidateElementMonitor * monitor, GstPad * pad) { GstValidatePadMonitor *pad_monitor; GstValidateRunner *runner = gst_validate_reporter_get_runner (GST_VALIDATE_REPORTER (monitor)); GST_DEBUG_OBJECT (monitor, "Wrapping pad %s:%s", GST_DEBUG_PAD_NAME (pad)); pad_monitor = GST_VALIDATE_PAD_MONITOR (gst_validate_monitor_factory_create (GST_OBJECT (pad), runner, GST_VALIDATE_MONITOR (monitor))); g_return_if_fail (pad_monitor != NULL); GST_VALIDATE_MONITOR_LOCK (monitor); monitor->pad_monitors = g_list_prepend (monitor->pad_monitors, pad_monitor); GST_VALIDATE_MONITOR_UNLOCK (monitor); gst_object_unref (runner); }
static void _determine_reporting_level (GstValidateMonitor * monitor) { GstValidateRunner *runner; GstObject *object, *parent; gchar *object_name; GstValidateReportingDetails level = GST_VALIDATE_SHOW_UNKNOWN; object = gst_validate_monitor_get_target (monitor); runner = gst_validate_reporter_get_runner (GST_VALIDATE_REPORTER (monitor)); do { if (!GST_IS_OBJECT (object)) break; /* Let's allow for singling out pads */ if (GST_IS_PAD (object)) { level = _get_report_level_for_pad (runner, object); if (level != GST_VALIDATE_SHOW_UNKNOWN) break; } object_name = gst_object_get_name (object); level = gst_validate_runner_get_reporting_level_for_name (runner, object_name); parent = gst_object_get_parent (object); gst_object_unref (object); object = parent; g_free (object_name); } while (object && level == GST_VALIDATE_SHOW_UNKNOWN); if (object) gst_object_unref (object); if (runner) gst_object_unref (runner); monitor->level = level; }
static void set_config_properties (GstValidateMonitor * monitor, GstElement * element) { GList *config, *l; config = gst_validate_plugin_get_config (NULL); for (l = config; l != NULL; l = g_list_next (l)) { GstStructure *s = l->data; const gchar *klass; gchar *tmp; const gchar *prop_name; const GValue *prop_value; if (g_strcmp0 (gst_structure_get_string (s, "action"), "set-property") != 0) continue; klass = gst_structure_get_string (s, "target-element-klass"); if (klass && !gst_validate_element_has_klass (element, klass)) continue; prop_name = gst_structure_get_string (s, "property-name"); if (!prop_name || !g_object_class_find_property (G_OBJECT_GET_CLASS (element), prop_name)) continue; prop_value = gst_structure_get_value (s, "property-value"); if (!prop_value) continue; tmp = gst_value_serialize (prop_value); gst_validate_printf (monitor, "Setting %s to %s", prop_name, tmp); g_free (tmp); gst_validate_object_set_property (GST_VALIDATE_REPORTER (monitor), G_OBJECT (element), prop_name, prop_value, FALSE); } }
static void _append_query_caps_failure_details (GstValidatePadMonitor * monitor, GString * str) { gint i, j; gboolean found = FALSE, empty_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; GstStructure *filter_struct, *possible_struct; g_string_append_printf (str, "\n Caps negotiation failed starting from pad '%s'" " as the QUERY_CAPS returned EMPTY caps", gst_validate_reporter_get_name (GST_VALIDATE_REPORTER (monitor))); empty_filter = gst_caps_is_empty (filter); if (empty_filter) { GstPad *peer = _get_peer_pad (monitor->pad); gchar *prev_path = NULL; if (peer) { GstObject *prev = gst_pad_get_parent (peer); if (prev) { prev_path = gst_object_get_path_string (prev); gst_object_unref (prev); } } g_string_append_printf (str, "\n - The QUERY filter caps is EMPTY, this is invalid and is a bug in " " a previous element (probably in: '%s')\n", prev_path ? prev_path : "no suspect"); g_free (prev_path); } for (i = 0; i < gst_caps_get_size (possible_caps); i++) { possible_struct = gst_caps_get_structure (possible_caps, i); possible_name = gst_structure_get_name (possible_struct); for (j = 0; j < gst_caps_get_size (filter); j++) { StructureIncompatibleFieldsInfo info = { .caps_struct_num = i, .filter_caps_struct_num = j, .str = str, .found = found }; info.filter = filter_struct = gst_caps_get_structure (filter, j); filter_name = gst_structure_get_name (filter_struct); if (g_strcmp0 (possible_name, filter_name)) { _incompatible_fields_info_set_found (&info); g_string_append_printf (str, "\n -> Downstream caps struct %d name '%s' differs from " "filter caps struct %d name '%s'", i, possible_name, j, filter_name); continue; } gst_structure_foreach (possible_struct, (GstStructureForeachFunc) _find_structure_incompatible_fields, &info); if (info.found) found = TRUE; } } if (!found && !empty_filter) { gchar *filter_caps_str = gst_caps_to_string (filter); gchar *possible_caps_str = gst_caps_to_string (possible_caps); g_string_append_printf (str, ". The exact reason could not be determined but" " here is the gathered information:\n" " - %s last query caps filter: %s\n" " - %s possible caps (as returned by a query on it without filter): %s\n", gst_validate_reporter_get_name (GST_VALIDATE_REPORTER (monitor)), filter_caps_str, gst_validate_reporter_get_name (GST_VALIDATE_REPORTER (monitor)), possible_caps_str); } gst_caps_unref (possible_caps); gst_caps_unref (filter); }