videotestsrc: Make snow deterministic

Deterministic generation of snow and smpte is important for tests so
that it's not affected by other videotestsrc elements in current or
possibly previous tests.

https://bugzilla.gnome.org/show_bug.cgi?id=773102
This commit is contained in:
Stian Selnes 2016-10-14 15:18:28 +02:00 committed by Sebastian Dröge
parent ca7e31f80d
commit 22ccb687fa
4 changed files with 84 additions and 8 deletions

View file

@ -304,6 +304,7 @@ gst_video_test_src_init (GstVideoTestSrc * src)
src->foreground_color = DEFAULT_FOREGROUND_COLOR;
src->background_color = DEFAULT_BACKGROUND_COLOR;
src->horizontal_speed = DEFAULT_HORIZONTAL_SPEED;
src->random_state = 0;
/* we operate in time */
gst_base_src_set_format (GST_BASE_SRC (src), GST_FORMAT_TIME);

View file

@ -174,6 +174,9 @@ struct _GstVideoTestSrc {
gint horizontal_offset;
gint horizontal_speed;
/* smpte & snow */
guint random_state;
void (*make_image) (GstVideoTestSrc *v, GstVideoFrame *frame);
/* temporary AYUV/ARGB scanline */

View file

@ -35,13 +35,11 @@
#define TO_16(x) (((x)<<8) | (x))
static unsigned char
random_char (void)
random_char (guint * state)
{
static unsigned int state;
state *= 1103515245;
state += 12345;
return (state >> 16) & 0xff;
*state *= 1103515245;
*state += 12345;
return (*state >> 16) & 0xff;
}
enum
@ -413,7 +411,7 @@ gst_video_test_src_smpte (GstVideoTestSrc * v, GstVideoFrame * frame)
p->color = &color;
for (i = x1; i < w; i++) {
int y = random_char ();
int y = random_char (&v->random_state);
p->tmpline_u8[i] = y;
}
videotestsrc_blend_line (v, p->tmpline + x1 * 4, p->tmpline_u8 + x1,
@ -517,7 +515,7 @@ gst_video_test_src_snow (GstVideoTestSrc * v, GstVideoFrame * frame)
for (j = 0; j < h; j++) {
for (i = 0; i < w; i++) {
int y = random_char ();
int y = random_char (&v->random_state);
p->tmpline_u8[i] = y;
}
videotestsrc_blend_line (v, p->tmpline, p->tmpline_u8,

View file

@ -32,6 +32,7 @@
#include <unistd.h>
#include <gst/check/gstcheck.h>
#include <gst/check/gstharness.h>
/* For ease of programming we use globals to keep refs for our floating
* src and sink pads we create; otherwise we always have to do get_pad,
@ -522,6 +523,78 @@ GST_START_TEST (test_duration_query)
GST_END_TEST;
static gchar *
get_buffer_checksum (GstBuffer *buf)
{
GstMapInfo map = GST_MAP_INFO_INIT;
GChecksum *md5 = g_checksum_new (G_CHECKSUM_MD5);
gchar *ret;
gst_buffer_map (buf, &map, GST_MAP_READ);
g_checksum_update (md5, map.data, map.size);
gst_buffer_unmap (buf, &map);
ret = g_strdup (g_checksum_get_string (md5));
g_checksum_free (md5);
return ret;
}
GST_START_TEST (test_patterns_are_deterministic)
{
GType type;
GEnumClass * enum_class;
gint num_patterns;
GstHarness *h[2];
const gint num_instances = G_N_ELEMENTS (h);
const gint num_frames = 2;
/* Create an element to register types used below */
gst_object_unref (gst_element_factory_make ("videotestsrc", NULL));
/* Find number of patterns to check */
type = g_type_from_name ("GstVideoTestSrcPattern");
fail_unless (type != 0);
enum_class = g_type_class_ref (type);
num_patterns = enum_class->n_values;
fail_unless (num_patterns > 0);
g_type_class_unref (enum_class);
/* For each pattern, make sure that all instances produce identical
* frames */
for (gint pattern = 0; pattern < num_patterns; pattern++) {
for (gint i = 0; i < G_N_ELEMENTS (h); i++) {
h[i] = gst_harness_new ("videotestsrc");
g_object_set (h[i]->element, "pattern", pattern, NULL);
gst_harness_set_blocking_push_mode (h[i]);
gst_harness_play (h[i]);
}
for (gint frame = 0; frame < num_frames; frame++) {
gchar *ref_checksum = NULL;
for (gint i = 0; i < num_instances; i++) {
GstBuffer *buffer = gst_harness_pull (h[i]);
gchar *checksum = get_buffer_checksum (buffer);
if (i == 0)
ref_checksum = g_strdup (checksum);
fail_unless_equals_string (ref_checksum, checksum);
g_free (checksum);
gst_buffer_unref (buffer);
}
g_free (ref_checksum);
}
for (gint i = 0; i < G_N_ELEMENTS (h); i++)
gst_harness_teardown (h[i]);
}
}
GST_END_TEST;
/* FIXME: add tests for YUV formats */
@ -544,6 +617,7 @@ videotestsrc_suite (void)
tcase_add_test (tc_chain, test_rgb_formats);
tcase_add_test (tc_chain, test_backward_playback);
tcase_add_test (tc_chain, test_duration_query);
tcase_add_test (tc_chain, test_patterns_are_deterministic);
return s;
}