gboolean gst_media_descriptors_compare (GstMediaDescriptor * ref, GstMediaDescriptor * compared) { GList *rstream_list; FileNode *rfilenode = ref->filenode, *cfilenode = compared->filenode; if (rfilenode->duration != cfilenode->duration) { GST_VALIDATE_REPORT (ref, FILE_DURATION_INCORRECT, "Duration %" GST_TIME_FORMAT " is different from the reference %" GST_TIME_FORMAT, GST_TIME_ARGS (cfilenode->duration), GST_TIME_ARGS (rfilenode->duration)); } if (rfilenode->seekable != cfilenode->seekable) { GST_VALIDATE_REPORT (ref, FILE_SEEKABLE_INCORRECT, "File known as %s but is reported %s now", rfilenode->seekable ? "seekable" : "not seekable", cfilenode->seekable ? "seekable" : "not seekable"); } if (g_list_length (rfilenode->streams) != g_list_length (cfilenode->streams)) { GST_VALIDATE_REPORT (ref, FILE_PROFILE_INCORRECT, "Reference descriptor has %i streams != compared which has %i streams", g_list_length (rfilenode->streams), g_list_length (cfilenode->streams)); return FALSE; } for (rstream_list = rfilenode->streams; rstream_list; rstream_list = rstream_list->next) { GList *cstream_list; gint sfound = -1; for (cstream_list = cfilenode->streams; cstream_list; cstream_list = cstream_list->next) { sfound = comparse_stream (ref, rstream_list->data, cstream_list->data); if (sfound == 0) { return FALSE; } else if (sfound == 1) { break; } } if (sfound == FALSE) { GST_VALIDATE_REPORT (ref, FILE_PROFILE_INCORRECT, "Could not find stream %s in the compared descriptor", ((StreamNode *) rstream_list->data)->id); return FALSE; } } return TRUE; }
static gboolean gst_validate_ssim_convert (GstValidateSsim * self, SSimConverterInfo * info, GstVideoFrame * frame, GstVideoFrame * converted_frame) { gboolean res = TRUE; GstBuffer *outbuf = NULL; g_return_val_if_fail (info != NULL, FALSE); outbuf = gst_buffer_new_allocate (NULL, info->out_info.size, NULL); if (!gst_video_frame_map (converted_frame, &info->out_info, outbuf, GST_MAP_WRITE)) { GST_VALIDATE_REPORT (self, GENERAL_INPUT_ERROR, "Could not map output converted_frame"); goto fail; } gst_video_converter_frame (info->converter, frame, converted_frame); done: if (outbuf) gst_buffer_unref (outbuf); return res; fail: res = FALSE; goto done; }
static void _check_message_level (const gchar * factoryname, GstValidateReportLevel level, const gchar * message_id) { GList *reports; GstElement *element; GstValidateRunner *runner; GstValidateMonitor *monitor; element = gst_element_factory_make (factoryname, NULL); fail_unless (g_setenv ("GST_VALIDATE_REPORTING_DETAILS", "all", TRUE)); runner = gst_validate_runner_new (); monitor = gst_validate_monitor_factory_create (GST_OBJECT (element), runner, NULL); GST_VALIDATE_REPORT (monitor, g_quark_from_string (message_id), "Just some fakery"); reports = gst_validate_runner_get_reports (runner); fail_unless_equals_int (g_list_length (reports), 1); fail_unless_equals_int (((GstValidateReport *) reports->data)->level, level); g_list_free_full (reports, (GDestroyNotify) gst_validate_report_unref); gst_object_unref (element); gst_object_unref (monitor); }
static void bin_element_added (GstTracer * runner, GstClockTime ts, GstBin * bin, GstElement * element, gboolean result) { GstObject *parent; GstValidateElementMonitor *monitor = g_object_get_data (G_OBJECT (element), "validate-monitor"); if (!monitor) return; if (!monitor->is_decoder) return; parent = gst_object_get_parent (GST_OBJECT (element)); do { if (GES_IS_TRACK (parent)) { GstElementClass *klass = GST_ELEMENT_CLASS (G_OBJECT_GET_CLASS (element)); const gchar *klassname = gst_element_class_get_metadata (klass, GST_ELEMENT_METADATA_KLASS); if (GES_IS_AUDIO_TRACK (parent) && strstr (klassname, "Audio") == NULL) { GST_VALIDATE_REPORT (monitor, WRONG_DECODER_ADDED, "Adding non audio decoder %s in audio track %s.", GST_OBJECT_NAME (element), GST_OBJECT_NAME (parent)); } else if (GES_IS_VIDEO_TRACK (parent) && strstr (klassname, "Video") == NULL && strstr (klassname, "Image") == NULL) { GST_VALIDATE_REPORT (monitor, WRONG_DECODER_ADDED, "Adding non video decoder %s in video track %s.", GST_OBJECT_NAME (element), GST_OBJECT_NAME (parent)); } gst_object_unref (parent); break; } gst_object_unref (parent); parent = gst_object_get_parent (parent); } while (parent); }
static gboolean gst_validate_ssim_get_frame_from_png (GstValidateSsim * self, const char *file, GstVideoFrame * frame) { guint8 *data; GstBuffer *buf; GstVideoInfo info; cairo_surface_t *surface = NULL; surface = cairo_image_surface_create_from_png (file); if (surface == NULL || (cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS)) { GST_VALIDATE_REPORT (self, GENERAL_INPUT_ERROR, "Could not open %s: %s", file, cairo_status_to_string (cairo_surface_status (surface))); return FALSE; } gst_video_info_init (&info); gst_video_info_set_format (&info, _get_format_from_surface (surface), cairo_image_surface_get_width (surface), cairo_image_surface_get_height (surface)); data = cairo_image_surface_get_data (surface); buf = gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY, data, info.size, 0, info.size, surface, (GDestroyNotify) cairo_surface_destroy); if (!gst_video_frame_map (frame, &info, buf, GST_MAP_READ)) { gst_buffer_unref (buf); GST_VALIDATE_REPORT (self, GENERAL_INPUT_ERROR, "Could not map input frame"); return FALSE; } gst_buffer_unref (buf); return TRUE; }
gboolean gst_validate_ssim_compare_image_files (GstValidateSsim * self, const gchar * ref_file, const gchar * file, gfloat * mean, gfloat * lowest, gfloat * highest, const gchar * outfolder) { if (g_file_test (ref_file, G_FILE_TEST_IS_DIR)) { if (!g_file_test (file, G_FILE_TEST_IS_DIR)) { GST_VALIDATE_REPORT (self, GENERAL_INPUT_ERROR, "%s is a directory but %s is not", ref_file, file); return FALSE; } return _check_directory (self, ref_file, file, mean, lowest, highest, outfolder); } else { return gst_validate_ssim_compare_image_file (self, ref_file, file, mean, lowest, highest, outfolder); } }
/* Return -1 if not found 1 if OK 0 if an error occured */ static gint comparse_stream (GstMediaDescriptor * ref, StreamNode * rstream, StreamNode * cstream) { if (g_strcmp0 (rstream->id, cstream->id) == 0) { if (!gst_caps_is_equal (rstream->caps, cstream->caps)) { gchar *rcaps = gst_caps_to_string (rstream->caps), *ccaps = gst_caps_to_string (cstream->caps); GST_VALIDATE_REPORT (ref, FILE_PROFILE_INCORRECT, "Reference descriptor for stream %s has caps: %s" " but compared stream %s has caps: %s", rstream->id, rcaps, cstream->id, ccaps); g_free (rcaps); g_free (ccaps); return 0; } compare_tags (ref, rstream, cstream); return 1; } return -1; }
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 gboolean gst_validate_ssim_compare_image_file (GstValidateSsim * self, const gchar * ref_file, const gchar * file, gfloat * mean, gfloat * lowest, gfloat * highest, const gchar * outfolder) { GstBuffer *outbuf = NULL, **poutbuf = NULL; gboolean res = TRUE; GstVideoFrame ref_frame, frame; gchar *real_ref_file = NULL; real_ref_file = _get_ref_file_path (self, ref_file, file, FALSE); if (!real_ref_file) { GST_VALIDATE_REPORT (self, GENERAL_INPUT_ERROR, "Could find ref file for %s", ref_file); goto fail; } if (!gst_validate_ssim_get_frame_from_file (self, real_ref_file, &ref_frame)) goto fail; if (!gst_validate_ssim_get_frame_from_file (self, file, &frame)) { gst_video_frame_unmap (&ref_frame); goto fail; } if (outfolder) { poutbuf = &outbuf; } gst_validate_ssim_compare_frames (self, &ref_frame, &frame, poutbuf, mean, lowest, highest); if (*mean < self->priv->min_avg_similarity) { gst_video_frame_unmap (&ref_frame); gst_video_frame_unmap (&frame); if (g_strcmp0 (ref_file, real_ref_file)) { gchar *tmpref = real_ref_file; real_ref_file = _get_ref_file_path (self, ref_file, file, TRUE); GST_VALIDATE_REPORT (self, SIMILARITY_ISSUE_WITH_PREVIOUS, "\nComparing %s with %s failed, (mean %f " " min %f), checking next %s\n", tmpref, file, *mean, *lowest, real_ref_file); g_free (tmpref); res = gst_validate_ssim_compare_image_file (self, real_ref_file, file, mean, lowest, highest, outfolder); goto done; } GST_VALIDATE_REPORT (self, SIMILARITY_ISSUE, "Average similarity '%f' between %s and %s inferior" " than the minimum average: %f", *mean, real_ref_file, file, self->priv->min_avg_similarity); goto fail; } if (*lowest < self->priv->min_lowest_similarity) { GST_VALIDATE_REPORT (self, SIMILARITY_ISSUE, "Lowest similarity '%f' between %s and %s inferior" " than the minimum lowest similarity: %f", *lowest, real_ref_file, file, self->priv->min_lowest_similarity); gst_video_frame_unmap (&ref_frame); gst_video_frame_unmap (&frame); goto fail; } gst_video_frame_unmap (&ref_frame); gst_video_frame_unmap (&frame); done: g_free (real_ref_file); if (outbuf) gst_buffer_unref (outbuf); return res; fail: res = FALSE; if (outbuf) gst_validate_ssim_save_out (self, outbuf, real_ref_file, file, outfolder); goto done; }
static gboolean gst_validate_ssim_get_frame_from_file (GstValidateSsim * self, const char *file, GstVideoFrame * frame) { gchar *data; gsize length; GstBuffer *buf; GstVideoInfo info; GstVideoFormat format; gint strv_length, width, height; gboolean res = TRUE; gchar **splited_name = NULL, **splited_size = NULL, *strformat; GError *error = NULL; if (g_str_has_suffix (file, ".png")) { return gst_validate_ssim_get_frame_from_png (self, file, frame); } splited_name = g_strsplit (file, ".", -1); strv_length = g_strv_length (splited_name); strformat = splited_name[strv_length - 1]; format = gst_video_format_from_string (strformat); if (format == GST_VIDEO_FORMAT_UNKNOWN) { GST_VALIDATE_REPORT (self, WRONG_FORMAT, "Unknown format: %s", strformat); goto fail; } splited_size = g_strsplit (splited_name[strv_length - 2], "x", -1); if (g_strv_length (splited_size) != 2) { GST_VALIDATE_REPORT (self, WRONG_FORMAT, "Can not determine video size from filename: %s ", file); goto fail; } errno = 0; width = g_ascii_strtoull (splited_size[0], NULL, 10); if (errno) { GST_VALIDATE_REPORT (self, WRONG_FORMAT, "Can not determine video size from filename: %s ", file); goto fail; } errno = 0; height = g_ascii_strtoull (splited_size[1], NULL, 10); if (errno) { GST_VALIDATE_REPORT (self, WRONG_FORMAT, "Can not determine video size from filename: %s ", file); goto fail; } gst_video_info_init (&info); gst_video_info_set_format (&info, format, width, height); if (!g_file_get_contents (file, &data, &length, &error)) { GST_VALIDATE_REPORT (self, GENERAL_INPUT_ERROR, "Could not open %s: %s", file, error->message); g_error_free (error); goto fail; } buf = gst_buffer_new_wrapped (data, length); if (!gst_video_frame_map (frame, &info, buf, GST_MAP_READ)) { gst_buffer_unref (buf); GST_VALIDATE_REPORT (self, GENERAL_INPUT_ERROR, "Could not map input frame"); goto fail; } gst_buffer_unref (buf); done: g_strfreev (splited_name); g_strfreev (splited_size); return res; fail: res = FALSE; goto done; }
void gst_validate_ssim_compare_frames (GstValidateSsim * self, GstVideoFrame * ref_frame, GstVideoFrame * frame, GstBuffer ** outbuf, gfloat * mean, gfloat * lowest, gfloat * highest) { gboolean reconf; guint8 *outdata = NULL; GstMapInfo map1, map2, outmap; GstVideoFrame converted_frame1, converted_frame2; SSimConverterInfo *convinfo1, *convinfo2; reconf = gst_validate_ssim_configure (self, ref_frame->info.width, ref_frame->info.height); gst_validate_ssim_configure_converter (self, 0, reconf, ref_frame->info.finfo->format, ref_frame->info.width, ref_frame->info.height); gst_validate_ssim_configure_converter (self, 1, reconf, frame->info.finfo->format, frame->info.width, frame->info.height); convinfo1 = (SSimConverterInfo *) g_list_nth_data (self->priv->converters, 0); if (convinfo1->converter) gst_validate_ssim_convert (self, convinfo1, ref_frame, &converted_frame1); else converted_frame1 = *ref_frame; convinfo2 = (SSimConverterInfo *) g_list_nth_data (self->priv->converters, 1); if (convinfo2->converter) gst_validate_ssim_convert (self, convinfo2, frame, &converted_frame2); else converted_frame2 = *frame; if (!gst_buffer_map (converted_frame1.buffer, &map1, GST_MAP_READ)) { GST_VALIDATE_REPORT (self, GENERAL_INPUT_ERROR, "Could not map reference frame"); return; } if (!gst_buffer_map (converted_frame2.buffer, &map2, GST_MAP_READ)) { gst_buffer_unmap (converted_frame1.buffer, &map1); GST_VALIDATE_REPORT (self, GENERAL_INPUT_ERROR, "Could not map compared frame"); return; } if (outbuf) { *outbuf = gst_buffer_new_and_alloc (GST_ROUND_UP_4 (self->priv->width) * self->priv->height); if (!gst_buffer_map (*outbuf, &outmap, GST_MAP_WRITE)) { GST_VALIDATE_REPORT (self, GENERAL_INPUT_ERROR, "Could not map output frame"); gst_buffer_unref (*outbuf); gst_buffer_unmap (converted_frame1.buffer, &map1); gst_buffer_unmap (converted_frame2.buffer, &map2); *outbuf = NULL; return; } outdata = outmap.data; } gssim_compare (self->priv->ssim, map1.data, map2.data, outdata, mean, lowest, highest); gst_buffer_unmap (ref_frame->buffer, &map1); gst_buffer_unmap (frame->buffer, &map2); if (convinfo1->converter) gst_video_frame_unmap (&converted_frame1); if (convinfo2->converter) gst_video_frame_unmap (&converted_frame2); if (outbuf) gst_buffer_unmap (*outbuf, &outmap); }
static void gst_validate_ssim_save_out (GstValidateSsim * self, GstBuffer * buffer, const gchar * ref_file, const gchar * file, const gchar * outfolder) { GstVideoFrame frame, converted; if (!g_file_test (outfolder, G_FILE_TEST_IS_DIR)) { if (g_mkdir_with_parents (outfolder, 0755) != 0) { GST_VALIDATE_REPORT (self, GENERAL_INPUT_ERROR, "Could not create output directory %s", outfolder); return; } } if (self->priv->outconverter_info.converter == NULL || self->priv->width != self->priv->outconverter_info.out_info.width || self->priv->height != self->priv->outconverter_info.out_info.height) { if (self->priv->outconverter_info.converter) gst_video_converter_free (self->priv->outconverter_info.converter); gst_video_info_init (&self->priv->outconverter_info.in_info); gst_video_info_set_format (&self->priv->outconverter_info.in_info, GST_VIDEO_FORMAT_GRAY8, self->priv->width, self->priv->height); gst_video_info_init (&self->priv->outconverter_info.out_info); gst_video_info_set_format (&self->priv->outconverter_info.out_info, GST_VIDEO_FORMAT_RGBx, self->priv->width, self->priv->height); self->priv->outconverter_info.converter = gst_video_converter_new (&self->priv->outconverter_info.in_info, &self->priv->outconverter_info.out_info, NULL); } if (!gst_video_frame_map (&frame, &self->priv->outconverter_info.in_info, buffer, GST_MAP_READ)) { GST_VALIDATE_REPORT (self, GENERAL_INPUT_ERROR, "Could not map output frame"); return; } if (gst_validate_ssim_convert (self, &self->priv->outconverter_info, &frame, &converted)) { cairo_status_t status; cairo_surface_t *surface; gchar *bn1 = g_path_get_basename (ref_file); gchar *bn2 = g_path_get_basename (file); gchar *fname = g_strdup_printf ("%s.VS.%s.result.png", bn1, bn2); gchar *outfile = g_build_path (G_DIR_SEPARATOR_S, outfolder, fname, NULL); surface = cairo_image_surface_create_for_data (GST_VIDEO_FRAME_PLANE_DATA (&converted, 0), CAIRO_FORMAT_RGB24, GST_VIDEO_FRAME_WIDTH (&converted), GST_VIDEO_FRAME_HEIGHT (&converted), GST_VIDEO_FRAME_PLANE_STRIDE (&converted, 0)); if ((status = cairo_surface_write_to_png (surface, outfile)) != CAIRO_STATUS_SUCCESS) { GST_VALIDATE_REPORT (self, GENERAL_INPUT_ERROR, "Could not save '%s', cairo status is '%s'", outfile, cairo_status_to_string (status)); } cairo_surface_destroy (surface); gst_video_frame_unmap (&frame); gst_video_frame_unmap (&converted); g_free (bn1); g_free (bn2); g_free (fname); g_free (outfile); } }
static gint compare_tags (GstMediaDescriptor * ref, StreamNode * rstream, StreamNode * cstream) { gboolean found; TagNode *rtag, *ctag; GList *rtag_list, *ctag_list; TagsNode *rtags, *ctags; rtags = rstream->tags; ctags = cstream->tags; if (rtags == NULL && ctags) return 1; else if (!rtags && ctags) { GList *taglist; GString *all_tags = g_string_new (NULL); for (taglist = ctags->tags; taglist; taglist = taglist->next) { gchar *stags = gst_tag_list_to_string (((TagNode *) taglist->data)->taglist); g_string_append_printf (all_tags, "%s\n", stags); g_free (stags); } GST_VALIDATE_REPORT (ref, FILE_TAG_DETECTION_INCORRECT, "Reference descriptor for stream %s has NO tags" " but tags found: %s", all_tags->str); g_string_free (all_tags, TRUE); return 0; } else if (rtags && !ctags) { GList *taglist; GString *all_tags = g_string_new (NULL); for (taglist = rtags->tags; taglist; taglist = taglist->next) { gchar *stags = gst_tag_list_to_string (((TagNode *) taglist->data)->taglist); g_string_append_printf (all_tags, "%s\n", stags); g_free (stags); } GST_VALIDATE_REPORT (ref, FILE_TAG_DETECTION_INCORRECT, "Reference descriptor for stream %s has tags:\n %s\n" " but NO tags found on the stream"); g_string_free (all_tags, TRUE); return 0; } for (rtag_list = rtags->tags; rtag_list; rtag_list = rtag_list->next) { rtag = rtag_list->data; found = FALSE; for (ctag_list = ctags->tags; ctag_list; ctag_list = ctag_list->next) { ctag = ctag_list->data; if (gst_tag_list_is_equal (rtag->taglist, ctag->taglist)) { found = TRUE; break; } } if (found == FALSE) { gchar *rtaglist = gst_tag_list_to_string (rtag->taglist); GST_VALIDATE_REPORT (ref, FILE_TAG_DETECTION_INCORRECT, "Reference descriptor for stream %s has tags %s" " but no equivalent taglist was found on the compared stream", rstream->id, rtaglist); g_free (rtaglist); return 0; } } return 1; }
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; } }