static void gst_validate_element_monitor_inspect (GstValidateElementMonitor * monitor) { GstElement *element; GstElementClass *klass; const gchar *klassname; element = GST_ELEMENT_CAST (gst_validate_monitor_get_target (GST_VALIDATE_MONITOR (monitor))); klass = GST_ELEMENT_CLASS (G_OBJECT_GET_CLASS (element)); klassname = gst_element_class_get_metadata (klass, GST_ELEMENT_METADATA_KLASS); if (klassname) { monitor->is_decoder = strstr (klassname, "Decoder") != NULL; monitor->is_encoder = strstr (klassname, "Encoder") != NULL; monitor->is_demuxer = strstr (klassname, "Demuxer") != NULL; monitor->is_converter = strstr (klassname, "Converter") != NULL; } else GST_ERROR_OBJECT (element, "no klassname"); gst_object_unref (element); }
static void _validate_element_pad_added (GstElement * element, GstPad * pad, GstValidateElementMonitor * monitor) { GstObject *target = 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); }
static void gst_validate_element_monitor_dispose (GObject * object) { GstValidateElementMonitor *monitor = GST_VALIDATE_ELEMENT_MONITOR_CAST (object); GstObject *target = gst_validate_monitor_get_target (GST_VALIDATE_MONITOR (monitor)); if (target) { if (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_OBJECT_CLASS (parent_class)->dispose (object); }
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); }
/** * gst_validate_element_monitor_new: * @element: (transfer none): a #GstElement to run Validate on */ GstValidateElementMonitor * gst_validate_element_monitor_new (GstElement * element, GstValidateRunner * runner, GstValidateMonitor * parent) { GstValidateElementMonitor *monitor; GstElement *target; g_return_val_if_fail (element != NULL, NULL); monitor = g_object_new (GST_TYPE_VALIDATE_ELEMENT_MONITOR, "object", element, "validate-runner", runner, "validate-parent", parent, NULL); target = GST_ELEMENT (gst_validate_monitor_get_target (GST_VALIDATE_MONITOR (monitor))); if (!target) { g_object_unref (monitor); return NULL; } gst_object_unref (target); return monitor; }
static void _bus_handler (GstBus * bus, GstMessage * message, GstValidatePipelineMonitor * monitor) { GError *err = NULL; gchar *debug = NULL; const GstStructure *details = NULL; gint error_flow = GST_FLOW_OK; switch (GST_MESSAGE_TYPE (message)) { case GST_MESSAGE_ERROR: gst_message_parse_error (message, &err, &debug); gst_message_parse_error_details (message, &details); if (g_error_matches (err, GST_CORE_ERROR, GST_CORE_ERROR_MISSING_PLUGIN)) { GST_VALIDATE_REPORT (monitor, MISSING_PLUGIN, "Error: %s -- Debug message: %s", err->message, debug); } else if ((g_error_matches (err, GST_STREAM_ERROR, GST_STREAM_ERROR_FAILED) && details && gst_structure_get_int (details, "flow-return", &error_flow) && error_flow == GST_FLOW_NOT_NEGOTIATED) || g_error_matches (err, GST_STREAM_ERROR, GST_STREAM_ERROR_FORMAT)) { gchar *report = _generate_not_negotiated_error_report (message); GST_VALIDATE_REPORT (monitor, NOT_NEGOTIATED, "%s", report); g_free (report); } else { GST_VALIDATE_REPORT (monitor, ERROR_ON_BUS, "Got error: %s -- Debug message: %s", err->message, debug); } GST_VALIDATE_MONITOR_LOCK (monitor); monitor->got_error = TRUE; GST_VALIDATE_MONITOR_UNLOCK (monitor); g_error_free (err); g_free (debug); break; case GST_MESSAGE_WARNING: gst_message_parse_warning (message, &err, &debug); GST_VALIDATE_REPORT (monitor, WARNING_ON_BUS, "Got warning: %s -- Debug message: %s", err->message, debug); g_error_free (err); g_free (debug); break; case GST_MESSAGE_STATE_CHANGED: { if (GST_MESSAGE_SRC (message) == GST_VALIDATE_MONITOR (monitor)->target) { GstState oldstate, newstate, pending; gst_message_parse_state_changed (message, &oldstate, &newstate, &pending); if (oldstate == GST_STATE_READY && newstate == GST_STATE_PAUSED) { monitor->print_pos_srcid = g_timeout_add (PRINT_POSITION_TIMEOUT, (GSourceFunc) print_position, monitor); } else if (oldstate >= GST_STATE_PAUSED && newstate <= GST_STATE_READY) { if (monitor->print_pos_srcid && g_source_remove (monitor->print_pos_srcid)) monitor->print_pos_srcid = 0; monitor->got_error = FALSE; } } break; } case GST_MESSAGE_BUFFERING: { JsonBuilder *jbuilder = json_builder_new (); GstBufferingMode mode; gint percent; gst_message_parse_buffering (message, &percent); gst_message_parse_buffering_stats (message, &mode, NULL, NULL, NULL); json_builder_begin_object (jbuilder); json_builder_set_member_name (jbuilder, "type"); json_builder_add_string_value (jbuilder, "buffering"); json_builder_set_member_name (jbuilder, "state"); if (percent == 100) { /* a 100% message means buffering is done */ gst_validate_printf (NULL, "\nDone buffering\n"); json_builder_add_string_value (jbuilder, "done"); if (monitor->buffering) { monitor->print_pos_srcid = g_timeout_add (PRINT_POSITION_TIMEOUT, (GSourceFunc) print_position, monitor); monitor->buffering = FALSE; } } else { /* buffering... */ if (!monitor->buffering) { monitor->buffering = TRUE; gst_validate_printf (NULL, "\nStart buffering\n"); json_builder_add_string_value (jbuilder, "started"); if (monitor->print_pos_srcid && g_source_remove (monitor->print_pos_srcid)) { monitor->print_pos_srcid = 0; } } else { json_builder_add_string_value (jbuilder, "progress"); } gst_validate_printf (NULL, "%s %d%% \r", "Buffering...", percent); } json_builder_set_member_name (jbuilder, "position"); json_builder_add_int_value (jbuilder, percent); json_builder_end_object (jbuilder); gst_validate_send (json_builder_get_root (jbuilder)); g_object_unref (jbuilder); break; } case GST_MESSAGE_STREAM_COLLECTION: { GstStreamCollection *collection = NULL; gst_message_parse_stream_collection (message, &collection); gst_object_replace ((GstObject **) & monitor->stream_collection, (GstObject *) collection); gst_object_unref (collection); break; } case GST_MESSAGE_STREAMS_SELECTED: { guint i; if (monitor->streams_selected) { g_list_free_full (monitor->streams_selected, gst_object_unref); monitor->streams_selected = NULL; } for (i = 0; i < gst_message_streams_selected_get_size (message); i++) { GstStream *stream = gst_message_streams_selected_get_stream (message, i); monitor->streams_selected = g_list_append (monitor->streams_selected, stream); } break; } default: break; } }
static GstValidateReportingDetails _get_reporting_level (GstValidateReporter * monitor) { return GST_VALIDATE_MONITOR (monitor)->level; }
static GstPipeline * _get_pipeline (GstValidateReporter * monitor) { return g_weak_ref_get (&(GST_VALIDATE_MONITOR (monitor)->pipeline)); }
static void _bus_handler (GstBus * bus, GstMessage * message, GstValidatePipelineMonitor * monitor) { GError *err = NULL; gchar *debug = NULL; switch (GST_MESSAGE_TYPE (message)) { case GST_MESSAGE_ERROR: gst_message_parse_error (message, &err, &debug); if (g_error_matches (err, GST_CORE_ERROR, GST_CORE_ERROR_MISSING_PLUGIN)) { GST_VALIDATE_REPORT (monitor, MISSING_PLUGIN, "Error: %s -- Debug message: %s", err->message, debug); } else { GST_VALIDATE_REPORT (monitor, ERROR_ON_BUS, "Got error: %s -- Debug message: %s", err->message, debug); } GST_VALIDATE_MONITOR_LOCK (monitor); monitor->got_error = TRUE; GST_VALIDATE_MONITOR_UNLOCK (monitor); g_error_free (err); g_free (debug); break; case GST_MESSAGE_WARNING: gst_message_parse_warning (message, &err, &debug); GST_VALIDATE_REPORT (monitor, WARNING_ON_BUS, "Got warning: %s -- Debug message: %s", err->message, debug); g_error_free (err); g_free (debug); break; case GST_MESSAGE_STATE_CHANGED: { if (GST_MESSAGE_SRC (message) == GST_VALIDATE_MONITOR (monitor)->target) { GstState oldstate, newstate, pending; gst_message_parse_state_changed (message, &oldstate, &newstate, &pending); if (oldstate == GST_STATE_READY && newstate == GST_STATE_PAUSED) { monitor->print_pos_srcid = g_timeout_add (PRINT_POSITION_TIMEOUT, (GSourceFunc) print_position, monitor); } else if (oldstate >= GST_STATE_PAUSED && newstate <= GST_STATE_READY) { if (monitor->print_pos_srcid && g_source_remove (monitor->print_pos_srcid)) monitor->print_pos_srcid = 0; monitor->got_error = FALSE; } } break; } case GST_MESSAGE_BUFFERING: { GstBufferingMode mode; gint percent; gst_message_parse_buffering (message, &percent); gst_message_parse_buffering_stats (message, &mode, NULL, NULL, NULL); if (percent == 100) { /* a 100% message means buffering is done */ if (monitor->buffering) { monitor->print_pos_srcid = g_timeout_add (PRINT_POSITION_TIMEOUT, (GSourceFunc) print_position, monitor); monitor->buffering = FALSE; } } else { /* buffering... */ if (!monitor->buffering) { monitor->buffering = TRUE; if (monitor->print_pos_srcid && g_source_remove (monitor->print_pos_srcid)) monitor->print_pos_srcid = 0; } } break; } default: break; } }