static gboolean bus_message_cb (InsanityGstPipelineTest * ptest, GstMessage * msg) { InsanityTest *test = INSANITY_TEST (ptest); switch (GST_MESSAGE_TYPE (msg)) { case GST_MESSAGE_EOS: { /* If we are waiting for a segment, keep waiting for it */ if (glob_waiting_segment) { LOG (test, "EOS but waiting for a new segment... keep waiting"); return FALSE; } LOG (test, "EOS... current %s next test", test_get_name (glob_in_progress)); next_test (test); return FALSE; } default: break; } return TRUE; }
static gboolean seek_mode_testing (InsanityTest * test) { gboolean res; GstEvent *event; GstSeekFlags flags = GST_SEEK_FLAG_FLUSH; GstSeekType stop_type = GST_SEEK_TYPE_NONE; /* Reset global seek props */ glob_seek_first_buf_ts = GST_CLOCK_TIME_NONE; glob_seek_stop_ts = GST_CLOCK_TIME_NONE; glob_seek_segment_seektime = 0; /* Set seeking arguments */ switch (glob_in_progress) { case TEST_BACKWARD_PLAYBACK: glob_seek_rate = -1; glob_seek_stop_ts = glob_duration; stop_type = GST_SEEK_TYPE_SET; break; case TEST_FAST_FORWARD: glob_seek_rate = 2; glob_seek_stop_ts = glob_duration / 2; break; case TEST_FAST_BACKWARD: glob_seek_rate = -2; glob_seek_stop_ts = glob_duration; stop_type = GST_SEEK_TYPE_SET; break; default: return FALSE; } glob_seek_got_segment = FALSE; event = gst_event_new_seek (glob_seek_rate, GST_FORMAT_TIME, flags, GST_SEEK_TYPE_SET, glob_seek_segment_seektime, stop_type, glob_seek_stop_ts); /* We didn't find any event/message with the seqnum we previously set */ if (glob_seqnum != 0 && glob_seqnum_found == FALSE) glob_wrong_seqnum = TRUE; glob_seqnum_found = FALSE; glob_seqnum = gst_util_seqnum_next (); gst_event_set_seqnum (event, glob_seqnum); res = gst_element_send_event (glob_pipeline, event); global_last_seek = g_get_monotonic_time (); if (!res) { validate_current_test (test, FALSE, "Could not send seek event"); glob_seek_rate = 0; glob_seqnum = 0; /* ... Next test */ next_test (test); } return FALSE; }
void test_finished_() { dbg(2, "... passed=%i", passed); if(passed) app.n_passed++; else n_failed++; //log_print(passed ? LOG_OK : LOG_FAIL, "%s", current_test_name); if(!passed && abort_on_fail) current_test = 1000; next_test(); }
/* compares got to expect as memory areas */ int cmp(const char* got, const char* expect, const unsigned int len, const char* name) { unsigned int i, l; next_test(); if (0 == memcmp(got, expect, len)) { printf ("# ok %i - %s\n", test, name); return 1; } printf ("# not ok %i - %s\n", test, name); if (len <= 16) { printf ("# # Failed test '%s':\n", name); hexdump_fancy ("# # got: ", "", got, len, "", " ", " ", 0, 0); hexdump_fancy ("# # expected: ", "", expect, len, "", " ", " ", 0, 0); } else { printf ("# # Failed test '%s' - differences are marked with '-->':\n", name); printf ("# # got:\n"); for (i = 0; i < len; i += 16) { l = 16; if ((len - i) < l) { l = len - i; } if (0 == memcmp(&got[i], &expect[i], l) ) { printf ("# # %04x ", i); hexdump_fancy ("", "", &got[i], l, "", " ", " ", 0, 0); } else { printf ("# # --> %04x ", i); hexdump_fancy ("", "", &got[i], l, "", " ", " ", 0, 0); } } printf ("# # expected:\n"); for (i = 0; i < len; i += 16) { l = 16; if ((len - i) < l) { l = len - i; } if (0 == memcmp(&got[i], &expect[i], l) ) { printf ("# # %04x ", i); hexdump_fancy ("", "", &expect[i], l, "", " ", " ", 0, 0); } else { printf ("# # --> %04x ", i); hexdump_fancy ("", "", &expect[i], l, "", " ", " ", 0, 0); } } } return 0; }
static void test_position (InsanityTest * test, GstBuffer * buf) { GstQuery *query; GstClockTimeDiff diff; if (GST_BUFFER_PTS_IS_VALID (buf) == FALSE) return; if (GST_CLOCK_TIME_IS_VALID (glob_first_pos_point) == FALSE) { glob_first_pos_point = gst_segment_to_stream_time (&glob_last_segment, glob_last_segment.format, GST_BUFFER_PTS (buf)); } glob_expected_pos = gst_segment_to_stream_time (&glob_last_segment, glob_last_segment.format, GST_BUFFER_PTS (buf)); diff = ABS (GST_CLOCK_DIFF (glob_expected_pos, glob_first_pos_point)); if (diff < glob_playback_duration * GST_SECOND) return; query = gst_query_new_position (GST_FORMAT_TIME); if (gst_element_query (glob_pipeline, query)) { gint64 pos; GstFormat fmt; GstClockTimeDiff diff; gst_query_parse_position (query, &fmt, &pos); diff = ABS (GST_CLOCK_DIFF (glob_expected_pos, pos)); if (diff <= POSITION_THRESHOLD) { insanity_test_validate_checklist_item (test, "position-detection", TRUE, NULL); } else { gchar *validate_msg = g_strdup_printf ("Found position: %" GST_TIME_FORMAT " expected: %" GST_TIME_FORMAT, GST_TIME_ARGS (pos), GST_TIME_ARGS (glob_expected_pos)); insanity_test_validate_checklist_item (test, "position-detection", FALSE, validate_msg); g_free (validate_msg); } } else { LOG (test, "%s Does not handle position queries (position-detection \"SKIP\")", gst_element_factory_get_metadata (gst_element_get_factory (glob_demuxer), GST_ELEMENT_METADATA_LONGNAME)); } next_test (test); }
/* assert the pointer is not null */ int non_null(const void* p, const char* name) { next_test(); if (NULL != p) { printf ("# ok %i - %s is not NULL\n", test, name); return 1; } printf ("# not ok %i - %s\n", test, name); printf ("# # Failed test - pointer '%s' was NULL.\n", name); return 0; }
/* compares got to expect as integers */ int equals(const int got, const int expect, const char* name) { next_test(); if (got == expect) { printf ("# ok %i - %s\n", test, name); return 1; } printf ("# not ok %i - %s\n", test, name); printf ("# # Failed test '%s'\n", name); printf ("# # got: %i\n# # expected: %i\n", got, expect); return 0; }
static size_t perform_tests (guestfs_h *g) { size_t test_num; size_t nr_failed = 0; struct test *t; for (test_num = 0; test_num < nr_tests; ++test_num) { t = &tests[test_num]; next_test (g, test_num, t->name); if (t->test_fn (g) == -1) { printf ("FAIL: %s\n", t->name); nr_failed++; } } return nr_failed; }
static gboolean bus_message_cb (InsanityGstPipelineTest * ptest, GstMessage * msg) { InsanityTest *test = INSANITY_TEST (ptest); switch (GST_MESSAGE_TYPE (msg)) { case GST_MESSAGE_EOS: { LOG (test, "Got EOS"); if (glob_in_progress == TEST_SUBTTILE_DESCRIPTOR_GENERATION) next_test (test); /* Keep testing anyway */ return FALSE; } default: break; } return TRUE; }
static gboolean fn(gpointer user_data) { next_test(); return G_SOURCE_REMOVE; }
static gboolean probe_cb (InsanityGstTest * ptest, GstPad * pad, GstMiniObject * object, gpointer userdata) { InsanityTest *test = INSANITY_TEST (ptest); global_last_probe = g_get_monotonic_time (); if (GST_IS_BUFFER (object)) { GstClockTime buf_start, buf_end; GstBuffer *next_sub, *buf = GST_BUFFER (object); buf_start = gst_segment_to_stream_time (&glob_suboverlay_src_probe->last_segment, glob_suboverlay_src_probe->last_segment.format, GST_BUFFER_PTS (buf)); buf_end = buf_start + GST_BUFFER_DURATION (buf); if (glob_in_progress == TEST_SUBTTILE_DESCRIPTOR_GENERATION) { if (glob_pipeline_restarted == TRUE) { gboolean has_subs; if (glob_duration > 0 && buf_end > glob_duration) { /* Done according to the duration previously found by the * discoverer */ next_test (test); } has_subs = frame_contains_subtitles (buf); if (GST_CLOCK_TIME_IS_VALID (glob_last_subtitled_frame)) { if (has_subs == FALSE) { GstBuffer *nbuf = gst_buffer_new (); GST_BUFFER_PTS (nbuf) = glob_last_subtitled_frame; GST_BUFFER_DURATION (nbuf) = buf_end - glob_last_subtitled_frame; media_descriptor_writer_add_frame (glob_writer, pad, nbuf); glob_last_subtitled_frame = GST_CLOCK_TIME_NONE; gst_buffer_unref (nbuf); } } else if (has_subs) { glob_last_subtitled_frame = buf_start; } } goto done; } /* We played enough... next test */ if (GST_CLOCK_TIME_IS_VALID (glob_first_subtitle_ts) && buf_start >= glob_first_subtitle_ts + glob_playback_duration * GST_SECOND) { next_test (test); } switch (glob_in_progress) { case TEST_NONE: { if (glob_suboverlay_src_probe->waiting_first_segment == TRUE) { insanity_test_validate_checklist_item (test, "first-segment", FALSE, "Got a buffer before the first segment"); } next_test (test); } default: break; } if (glob_subtitled_frames != NULL) { GstClockTime sub_start, sub_end; next_sub = GST_BUFFER (glob_subtitled_frames->data); sub_start = GST_BUFFER_PTS (next_sub); sub_end = GST_BUFFER_DURATION_IS_VALID (next_sub) ? GST_BUFFER_DURATION (next_sub) + sub_start : -1; if (buf_start >= sub_start && buf_end < sub_end) { if (frame_contains_subtitles (buf) == TRUE) { glob_sub_render_found = TRUE; insanity_test_validate_checklist_item (test, "subtitle-rendered", TRUE, NULL); } else { gchar *msg = g_strdup_printf ("Subtitle start %" GST_TIME_FORMAT " end %" GST_TIME_FORMAT " received buffer with no sub start %" GST_TIME_FORMAT " end %" GST_TIME_FORMAT, GST_TIME_ARGS (sub_start), GST_TIME_ARGS (sub_end), GST_TIME_ARGS (buf_start), GST_TIME_ARGS (buf_end)); insanity_test_validate_checklist_item (test, "subtitle-rendered", FALSE, msg); glob_wrong_rendered_buf = TRUE; g_free (msg); } } else if (buf_end > sub_end) { /* We got a buffer that is after the subtitle we were waiting for * remove that buffer as not waiting for it anymore */ gst_buffer_unref (next_sub); glob_subtitled_frames = g_list_remove (glob_subtitled_frames, next_sub); } } } else if (GST_IS_EVENT (object)) { GstEvent *event = GST_EVENT (object); switch (GST_EVENT_TYPE (event)) { case GST_EVENT_SEGMENT: { gst_event_copy_segment (event, &glob_suboverlay_src_probe->last_segment); if (glob_suboverlay_src_probe->waiting_first_segment == TRUE) { insanity_test_validate_checklist_item (test, "first-segment", TRUE, NULL); glob_suboverlay_src_probe->waiting_first_segment = FALSE; } if (glob_suboverlay_src_probe->waiting_segment == FALSE) /* Cache the segment as it will be our reference but don't look * further */ goto done; if (glob_suboverlay_src_probe->waiting_first_segment == TRUE) { /* Make sure that a new segment has been received for each stream */ glob_suboverlay_src_probe->waiting_first_segment = FALSE; glob_suboverlay_src_probe->waiting_segment = FALSE; } glob_suboverlay_src_probe->waiting_segment = FALSE; break; } default: break; } } done: return TRUE; }
/* Pipeline Callbacks */ static gboolean probe_cb (InsanityGstTest * ptest, GstPad * pad, GstMiniObject * object, gpointer userdata) { InsanityTest *test = INSANITY_TEST (ptest); global_last_probe = g_get_monotonic_time (); DECODER_TEST_LOCK (); if (GST_IS_BUFFER (object)) { GstBuffer *buf; GstClockTime ts; buf = GST_BUFFER (object); ts = GST_BUFFER_PTS (buf); /* First check clipping */ if (glob_testing_parser == FALSE && GST_CLOCK_TIME_IS_VALID (ts) && glob_waiting_segment == FALSE) { GstClockTime ts_end, cstart, cstop; /* Check if buffer is completely outside the segment */ ts_end = ts; if (GST_BUFFER_DURATION_IS_VALID (buf)) ts_end += GST_BUFFER_DURATION (buf); /* Check if buffer is completely outside the segment */ ts_end = ts; if (!gst_segment_clip (&glob_last_segment, glob_last_segment.format, ts, ts_end, &cstart, &cstop)) { char *msg = g_strdup_printf ("Got timestamp %" GST_TIME_FORMAT " -- %" GST_TIME_FORMAT ", outside configured segment (%" GST_TIME_FORMAT " -- %" GST_TIME_FORMAT "), method %s", GST_TIME_ARGS (ts), GST_TIME_ARGS (ts_end), GST_TIME_ARGS (glob_last_segment.start), GST_TIME_ARGS (glob_last_segment.stop), test_get_name (glob_in_progress)); insanity_test_validate_checklist_item (INSANITY_TEST (ptest), "segment-clipping", FALSE, msg); g_free (msg); glob_bad_segment_clipping = TRUE; } } switch (glob_in_progress) { case TEST_NONE: if (glob_waiting_first_segment == TRUE) insanity_test_validate_checklist_item (test, "first-segment", FALSE, "Got a buffer before the first segment"); /* Got the first buffer, starting testing dance */ next_test (test); break; case TEST_POSITION: test_position (test, buf); break; case TEST_FAST_FORWARD: case TEST_BACKWARD_PLAYBACK: case TEST_FAST_BACKWARD: { gint64 stime_ts; if (GST_CLOCK_TIME_IS_VALID (ts) == FALSE || glob_waiting_segment == TRUE) { break; } stime_ts = gst_segment_to_stream_time (&glob_last_segment, glob_last_segment.format, ts); if (GST_CLOCK_TIME_IS_VALID (glob_seek_first_buf_ts) == FALSE) { GstClockTime expected_ts = gst_segment_to_stream_time (&glob_last_segment, glob_last_segment.format, glob_seek_rate < 0 ? glob_seek_stop_ts : glob_seek_segment_seektime); GstClockTimeDiff diff = ABS (GST_CLOCK_DIFF (stime_ts, expected_ts)); if (diff > SEEK_THRESHOLD) { gchar *valmsg = g_strdup_printf ("Received buffer timestamp %" GST_TIME_FORMAT " Seeek wanted %" GST_TIME_FORMAT "", GST_TIME_ARGS (stime_ts), GST_TIME_ARGS (expected_ts)); validate_current_test (test, FALSE, valmsg); next_test (test); g_free (valmsg); } else glob_seek_first_buf_ts = stime_ts; } else { GstClockTimeDiff diff = GST_CLOCK_DIFF (stime_ts, glob_seek_first_buf_ts); if (diff < 0) diff = -diff; if (diff >= glob_playback_duration * GST_SECOND) { validate_current_test (test, TRUE, NULL); next_test (test); } } break; } default: break; } } else if (GST_IS_EVENT (object)) { GstEvent *event = GST_EVENT (object); guint seqnum = gst_event_get_seqnum (event); if (G_LIKELY (glob_seqnum_found == FALSE) && seqnum == glob_seqnum) glob_seqnum_found = TRUE; if (glob_seqnum_found == TRUE && seqnum != glob_seqnum) { gchar *message = g_strdup_printf ("Current seqnum %i != " "received %i", glob_seqnum, seqnum); insanity_test_validate_checklist_item (test, "seqnum-management", FALSE, message); glob_wrong_seqnum = TRUE; g_free (message); } switch (GST_EVENT_TYPE (event)) { case GST_EVENT_SEGMENT: { gst_event_copy_segment (event, &glob_last_segment); if (glob_waiting_segment == FALSE) /* Cache the segment as it will be our reference but don't look * further */ goto done; glob_last_segment_start_time = glob_last_segment.start; if (glob_waiting_first_segment == TRUE) { insanity_test_validate_checklist_item (test, "first-segment", TRUE, NULL); glob_waiting_first_segment = FALSE; } else if (glob_in_progress >= TEST_FAST_FORWARD && glob_in_progress <= TEST_FAST_BACKWARD) { GstClockTimeDiff diff; gboolean valid_stop = TRUE; GstClockTimeDiff wdiff, rdiff; rdiff = ABS (GST_CLOCK_DIFF (glob_last_segment.stop, glob_last_segment.start)) * ABS (glob_last_segment.rate * glob_last_segment.applied_rate); wdiff = ABS (GST_CLOCK_DIFF (glob_seek_stop_ts, glob_seek_segment_seektime)); diff = GST_CLOCK_DIFF (glob_last_segment.position, glob_seek_segment_seektime); if (diff < 0) diff = -diff; /* Now compare with the expected segment */ if ((glob_last_segment.rate * glob_last_segment.applied_rate) == glob_seek_rate && diff <= SEEK_THRESHOLD && valid_stop) { glob_seek_got_segment = TRUE; } else { GstClockTime stopdiff = ABS (GST_CLOCK_DIFF (rdiff, wdiff)); gchar *validate_msg = g_strdup_printf ("Wrong segment received, Rate %f expected " "%f, start time diff %" GST_TIME_FORMAT " stop diff %" GST_TIME_FORMAT, (glob_last_segment.rate * glob_last_segment.applied_rate), glob_seek_rate, GST_TIME_ARGS (diff), GST_TIME_ARGS (stopdiff)); validate_current_test (test, FALSE, validate_msg); next_test (test); g_free (validate_msg); } } glob_waiting_segment = FALSE; break; } default: break; } } done: DECODER_TEST_UNLOCK (); return TRUE; }
static void test_queries (InsanityTest * test) { GstQuery *query = gst_query_new_seeking (GST_FORMAT_TIME); if (gst_element_query (glob_pipeline, query)) { GstFormat fmt; gboolean seekable, known_seekable; gst_query_parse_seeking (query, &fmt, &seekable, NULL, NULL); if (glob_media_desc_parser == NULL) { insanity_test_validate_checklist_item (test, "seekable-detection", TRUE, "No media-descriptor file, result not verified against it"); glob_seekable = seekable; } else { known_seekable = media_descriptor_parser_get_seekable (glob_media_desc_parser); insanity_test_validate_checklist_item (test, "seekable-detection", known_seekable == seekable, NULL); glob_seekable = known_seekable; } } else { if (glob_media_desc_parser != NULL) glob_seekable = media_descriptor_parser_get_seekable (glob_media_desc_parser); LOG (test, "%s Does not handle seeking queries (seekable-detection \"SKIP\")", gst_element_factory_get_metadata (gst_element_get_factory (glob_demuxer), GST_ELEMENT_METADATA_LONGNAME)); } gst_query_unref (query); query = gst_query_new_duration (GST_FORMAT_TIME); if (gst_element_query (glob_pipeline, query)) { GstFormat fmt; gchar *validate_msg = NULL; gint64 duration; if (glob_media_desc_parser == NULL) { gst_query_parse_duration (query, &fmt, &duration); validate_msg = g_strdup_printf ("Found duration %" GST_TIME_FORMAT " No media-descriptor file, result not verified against it", GST_TIME_ARGS (duration)); insanity_test_validate_checklist_item (test, "duration-detection", TRUE, validate_msg); g_free (validate_msg); glob_duration = duration; } else { glob_duration = media_descriptor_parser_get_duration (glob_media_desc_parser); gst_query_parse_duration (query, &fmt, &duration); if (glob_duration != duration) { validate_msg = g_strdup_printf ("Found time %" GST_TIME_FORMAT "-> %" GST_TIME_FORMAT, GST_TIME_ARGS (duration), GST_TIME_ARGS (glob_duration)); insanity_test_validate_checklist_item (test, "duration-detection", glob_duration == duration, validate_msg); g_free (validate_msg); } else { insanity_test_validate_checklist_item (test, "duration-detection", TRUE, NULL); } } } else { if (glob_media_desc_parser != NULL) glob_duration = media_descriptor_parser_get_seekable (glob_media_desc_parser); LOG (test, "%s Does not handle duration queries " "(duration-detection \"SKIP\")", gst_element_factory_get_metadata (gst_element_get_factory (glob_demuxer), GST_ELEMENT_METADATA_LONGNAME)); } if (GST_CLOCK_TIME_IS_VALID (glob_duration) && glob_playback_duration > glob_duration) { LOG (test, "playback_duration > media duration, setting it" "to media_duration != 2"); glob_playback_duration = glob_duration / 2; } gst_query_unref (query); next_test (test); }