summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThibault Saunier <thibault.saunier@collabora.com>2014-09-15 17:27:54 +0200
committerMathieu Duponchelle <mathieu.duponchelle@opencreed.com>2014-10-21 20:21:36 +0200
commitbb93dbb9fb580ece3f505e8d39a53c1e8dbd6d83 (patch)
tree915bef5e997fd6f8e4757248f0faf757f9f6bafd
parentcd9a3640b2a2551c30d858cb5430797c01f10f31 (diff)
validate: Check all buffers when we have the info from MediaDescriptor
We now check that each buffer is the expected one for each buffer that come into the decoder. + Fix some minor leaks in test-utils https://bugzilla.gnome.org/show_bug.cgi?id=736138
-rw-r--r--validate/gst/validate/gst-validate-pad-monitor.c174
-rw-r--r--validate/gst/validate/gst-validate-pad-monitor.h7
-rw-r--r--validate/gst/validate/gst-validate-report.c6
-rw-r--r--validate/gst/validate/gst-validate-report.h1
-rw-r--r--validate/tests/check/validate/padmonitor.c256
-rw-r--r--validate/tests/check/validate/test-utils.c106
-rw-r--r--validate/tests/check/validate/test-utils.h19
-rw-r--r--validate/tools/launcher/apps/gstvalidate.py2
8 files changed, 555 insertions, 16 deletions
diff --git a/validate/gst/validate/gst-validate-pad-monitor.c b/validate/gst/validate/gst-validate-pad-monitor.c
index 159efa8..a5f1557 100644
--- a/validate/gst/validate/gst-validate-pad-monitor.c
+++ b/validate/gst/validate/gst-validate-pad-monitor.c
@@ -1471,6 +1471,94 @@ mark_pads_eos (GstValidatePadMonitor *pad_monitor)
}
}
+static inline gboolean
+_should_check_buffers (GstValidatePadMonitor * pad_monitor,
+ gboolean force_checks)
+{
+ GstPad *pad = GST_VALIDATE_PAD_MONITOR_GET_PAD (pad_monitor);
+ GstValidateMonitor *monitor = GST_VALIDATE_MONITOR (pad_monitor);
+
+ if (pad_monitor->first_buffer || force_checks) {
+ if (pad_monitor->segment.rate != 1.0) {
+ GST_INFO_OBJECT (pad_monitor, "We do not support buffer checking"
+ " for trick modes");
+
+ pad_monitor->check_buffers = FALSE;
+ } else if (!PAD_PARENT_IS_DECODER (pad_monitor)) {
+ GST_DEBUG_OBJECT (pad, "Not on a decoder => no buffer checking");
+
+ pad_monitor->check_buffers = FALSE;
+ } else if (GST_PAD_DIRECTION (pad) != GST_PAD_SINK) {
+ GST_DEBUG_OBJECT (pad, "Not a sinkpad => no buffer checking");
+
+ pad_monitor->check_buffers = FALSE;
+ } else if (!pad_monitor->caps_is_video) {
+ GST_DEBUG_OBJECT (pad, "Not working with video => no buffer checking");
+
+ pad_monitor->check_buffers = FALSE;
+ } else if (monitor->media_descriptor == NULL) {
+ GST_DEBUG_OBJECT (pad, "No media_descriptor set => no buffer checking");
+
+ pad_monitor->check_buffers = FALSE;
+ } else if (!gst_media_descriptor_detects_frames (monitor->media_descriptor)) {
+ GST_DEBUG_OBJECT (pad, "No frame detection media descriptor "
+ "=> not buffer checking");
+ pad_monitor->check_buffers = FALSE;
+ } else if (pad_monitor->all_bufs == NULL &&
+ !gst_media_descriptor_get_buffers (monitor->media_descriptor, pad, NULL,
+ &pad_monitor->all_bufs)) {
+
+ GST_INFO_OBJECT (monitor,
+ "The MediaInfo is marked as detecting frame, but getting frames"
+ " from pad %" GST_PTR_FORMAT " did not work (some format conversion"
+ " might be happening)", pad);
+
+ pad_monitor->check_buffers = FALSE;
+ } else {
+ if (!pad_monitor->current_buf)
+ pad_monitor->current_buf = pad_monitor->all_bufs;
+ pad_monitor->check_buffers = TRUE;
+ }
+ }
+
+ return pad_monitor->check_buffers;
+}
+
+static void
+gst_validate_monitor_find_next_buffer (GstValidatePadMonitor * pad_monitor)
+{
+ GList *tmp;
+ gboolean passed_start = FALSE;
+
+ if (!_should_check_buffers (pad_monitor, TRUE))
+ return;
+
+ for (tmp = g_list_last (pad_monitor->all_bufs); tmp; tmp = tmp->prev) {
+ GstBuffer *cbuf = tmp->data;
+ GstClockTime ts =
+ GST_CLOCK_TIME_IS_VALID (GST_BUFFER_DTS (cbuf)) ? GST_BUFFER_DTS (cbuf)
+ : GST_BUFFER_PTS (cbuf);
+
+ if (!GST_CLOCK_TIME_IS_VALID (ts))
+ continue;
+
+ if (ts <= pad_monitor->segment.start)
+ passed_start = TRUE;
+
+ if (!passed_start)
+ continue;
+
+ if (!GST_BUFFER_FLAG_IS_SET (cbuf, GST_BUFFER_FLAG_DELTA_UNIT)) {
+ break;
+ }
+ }
+
+ if (tmp == NULL)
+ pad_monitor->current_buf = pad_monitor->all_bufs;
+ else
+ pad_monitor->current_buf = tmp;
+}
+
static gboolean
gst_validate_pad_monitor_downstream_event_check (GstValidatePadMonitor *
pad_monitor, GstObject * parent, GstEvent * event,
@@ -1582,6 +1670,7 @@ gst_validate_pad_monitor_downstream_event_check (GstValidatePadMonitor *
}
gst_segment_copy_into (segment, &pad_monitor->segment);
pad_monitor->has_segment = TRUE;
+ gst_validate_monitor_find_next_buffer (pad_monitor);
}
break;
case GST_EVENT_CAPS:{
@@ -1685,6 +1774,90 @@ gst_validate_pad_monitor_src_event_check (GstValidatePadMonitor * pad_monitor,
return ret;
}
+static gboolean
+gst_validate_pad_monitor_check_right_buffer (GstValidatePadMonitor *
+ pad_monitor, GstBuffer * buffer)
+{
+ gchar *checksum;
+ GstBuffer *wanted_buf;
+ GstMapInfo map, wanted_map;
+
+ gboolean ret = TRUE;
+ GstPad *pad = GST_VALIDATE_PAD_MONITOR_GET_PAD (pad_monitor);
+
+ if (_should_check_buffers (pad_monitor, FALSE) == FALSE)
+ return FALSE;
+
+ if (pad_monitor->current_buf == NULL) {
+ GST_INFO_OBJECT (pad, "No current buffer one pad, Why?");
+ return FALSE;
+ }
+
+ wanted_buf = pad_monitor->current_buf->data;
+
+ if (GST_CLOCK_TIME_IS_VALID (GST_BUFFER_PTS (wanted_buf)) &&
+ GST_CLOCK_TIME_IS_VALID (GST_BUFFER_PTS (buffer)) &&
+ GST_BUFFER_PTS (wanted_buf) != GST_BUFFER_PTS (buffer)) {
+
+ GST_VALIDATE_REPORT (pad_monitor, WRONG_BUFFER,
+ "buffer %" GST_PTR_FORMAT " PTS %ld"
+ " different than expected: %ld", buffer,
+ GST_BUFFER_PTS (buffer), GST_BUFFER_PTS (wanted_buf));
+
+ ret = FALSE;
+ }
+
+ if (GST_BUFFER_DTS (wanted_buf) != GST_BUFFER_DTS (buffer)) {
+ GST_VALIDATE_REPORT (pad_monitor, WRONG_BUFFER,
+ "buffer %" GST_PTR_FORMAT " DTS %" GST_TIME_FORMAT
+ " different than expected: %" GST_TIME_FORMAT, buffer,
+ GST_TIME_ARGS (GST_BUFFER_DTS (buffer)),
+ GST_TIME_ARGS (GST_BUFFER_DTS (wanted_buf)));
+ ret = FALSE;
+ }
+
+ if (GST_BUFFER_DURATION (wanted_buf) != GST_BUFFER_DURATION (buffer)) {
+ GST_VALIDATE_REPORT (pad_monitor, WRONG_BUFFER,
+ "buffer %" GST_PTR_FORMAT " DURATION %" GST_TIME_FORMAT
+ " different than expected: %" GST_TIME_FORMAT, buffer,
+ GST_TIME_ARGS (GST_BUFFER_DURATION (buffer)),
+ GST_TIME_ARGS (GST_BUFFER_DURATION (wanted_buf)));
+ ret = FALSE;
+ }
+
+ if (GST_BUFFER_FLAG_IS_SET (wanted_buf, GST_BUFFER_FLAG_DELTA_UNIT) !=
+ GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT)) {
+ GST_VALIDATE_REPORT (pad_monitor, WRONG_BUFFER,
+ "buffer %" GST_PTR_FORMAT " Delta unit is set to %s but expected %s",
+ buffer, GST_BUFFER_FLAG_IS_SET (buffer,
+ GST_BUFFER_FLAG_DELTA_UNIT) ? "True" : "False",
+ GST_BUFFER_FLAG_IS_SET (wanted_buf,
+ GST_BUFFER_FLAG_DELTA_UNIT) ? "True" : "False");
+ ret = FALSE;
+ }
+
+ g_assert (gst_buffer_map (wanted_buf, &wanted_map, GST_MAP_READ));
+ g_assert (gst_buffer_map (buffer, &map, GST_MAP_READ));
+
+ checksum = g_compute_checksum_for_data (G_CHECKSUM_MD5,
+ (const guchar *) map.data, map.size);
+
+ if (g_strcmp0 ((gchar *) wanted_map.data, checksum)) {
+ GST_VALIDATE_REPORT (pad_monitor, WRONG_BUFFER,
+ "buffer %" GST_PTR_FORMAT " checksum %s different from expected: %s",
+ buffer, checksum, wanted_map.data);
+ ret = FALSE;
+ }
+
+ gst_buffer_unmap (wanted_buf, &wanted_map);
+ gst_buffer_unmap (buffer, &map);
+ g_free (checksum);
+
+ pad_monitor->current_buf = pad_monitor->current_buf->next;
+
+ return ret;
+}
+
static GstFlowReturn
gst_validate_pad_monitor_chain_func (GstPad * pad, GstObject * parent,
GstBuffer * buffer)
@@ -1696,6 +1869,7 @@ gst_validate_pad_monitor_chain_func (GstPad * pad, GstObject * parent,
GST_VALIDATE_PAD_MONITOR_PARENT_LOCK (pad_monitor);
GST_VALIDATE_MONITOR_LOCK (pad_monitor);
+ gst_validate_pad_monitor_check_right_buffer (pad_monitor, buffer);
gst_validate_pad_monitor_check_first_buffer (pad_monitor, buffer);
gst_validate_pad_monitor_update_buffer_data (pad_monitor, buffer);
gst_validate_pad_monitor_check_eos (pad_monitor, buffer);
diff --git a/validate/gst/validate/gst-validate-pad-monitor.h b/validate/gst/validate/gst-validate-pad-monitor.h
index 27f9f2f..82737be 100644
--- a/validate/gst/validate/gst-validate-pad-monitor.h
+++ b/validate/gst/validate/gst-validate-pad-monitor.h
@@ -29,6 +29,7 @@ typedef struct _GstValidatePadMonitor GstValidatePadMonitor;
typedef struct _GstValidatePadMonitorClass GstValidatePadMonitorClass;
#include <gst/validate/gst-validate-monitor.h>
+#include <gst/validate/media-descriptor-parser.h>
#include <gst/validate/gst-validate-element-monitor.h>
G_BEGIN_DECLS
@@ -110,6 +111,12 @@ struct _GstValidatePadMonitor {
*/
GstClockTime timestamp_range_start;
GstClockTime timestamp_range_end;
+
+ /* GstMediaCheck related fields */
+ GList *all_bufs;
+ /* The GstBuffer that should arrive next in a GList */
+ GList *current_buf;
+ gboolean check_buffers;
};
/**
diff --git a/validate/gst/validate/gst-validate-report.c b/validate/gst/validate/gst-validate-report.c
index cca74ae..a221165 100644
--- a/validate/gst/validate/gst-validate-report.c
+++ b/validate/gst/validate/gst-validate-report.c
@@ -130,6 +130,12 @@ gst_validate_report_load_issues (void)
REGISTER_VALIDATE_ISSUE (WARNING, FIRST_BUFFER_RUNNING_TIME_IS_NOT_ZERO,
_("first buffer's running time isn't 0"),
_("the first buffer's received running time is expected to be 0"));
+ REGISTER_VALIDATE_ISSUE (WARNING, WRONG_BUFFER,
+ _("Received buffer does not correspond to wanted one."),
+ _("When checking playback of a file against a MediaInfo file"
+ " all buffers coming into the decoders might be checked"
+ " and should have the exact expected metadatas and hash of the"
+ " content"));
REGISTER_VALIDATE_ISSUE (CRITICAL, WRONG_FLOW_RETURN,
_("flow return from pad push doesn't match expected value"),
_("flow return from a 1:1 sink/src pad element is as simple as "
diff --git a/validate/gst/validate/gst-validate-report.h b/validate/gst/validate/gst-validate-report.h
index e9ce167..c80c0ec 100644
--- a/validate/gst/validate/gst-validate-report.h
+++ b/validate/gst/validate/gst-validate-report.h
@@ -77,6 +77,7 @@ typedef enum {
#define GST_VALIDATE_ISSUE_ID_FIRST_BUFFER_RUNNING_TIME_IS_NOT_ZERO (((GstValidateIssueId) GST_VALIDATE_AREA_BUFFER) << GST_VALIDATE_ISSUE_ID_SHIFT | 4)
#define GST_VALIDATE_ISSUE_ID_WRONG_FLOW_RETURN (((GstValidateIssueId) GST_VALIDATE_AREA_BUFFER) << GST_VALIDATE_ISSUE_ID_SHIFT | 5)
#define GST_VALIDATE_ISSUE_ID_BUFFER_AFTER_EOS (((GstValidateIssueId) GST_VALIDATE_AREA_BUFFER) << GST_VALIDATE_ISSUE_ID_SHIFT | 6)
+#define GST_VALIDATE_ISSUE_ID_WRONG_BUFFER (((GstValidateIssueId) GST_VALIDATE_AREA_BUFFER) << GST_VALIDATE_ISSUE_ID_SHIFT | 7)
#define GST_VALIDATE_ISSUE_ID_CAPS_IS_MISSING_FIELD (((GstValidateIssueId) GST_VALIDATE_AREA_CAPS) << GST_VALIDATE_ISSUE_ID_SHIFT | 1)
#define GST_VALIDATE_ISSUE_ID_CAPS_FIELD_HAS_BAD_TYPE (((GstValidateIssueId) GST_VALIDATE_AREA_CAPS) << GST_VALIDATE_ISSUE_ID_SHIFT | 2)
diff --git a/validate/tests/check/validate/padmonitor.c b/validate/tests/check/validate/padmonitor.c
index 73558b1..477a51b 100644
--- a/validate/tests/check/validate/padmonitor.c
+++ b/validate/tests/check/validate/padmonitor.c
@@ -19,6 +19,7 @@
#include <gst/validate/validate.h>
#include <gst/validate/gst-validate-pad-monitor.h>
+#include <gst/validate/media-descriptor-parser.h>
#include <gst/check/gstcheck.h>
#include "test-utils.h"
@@ -545,6 +546,260 @@ GST_START_TEST (issue_concatenation)
check_destroyed (sink, sinkpad, NULL);
check_destroyed (runner, NULL, NULL);
}
+GST_END_TEST;
+
+/* *INDENT-OFF* */
+static const gchar * media_info =
+"<file duration='10031000000' frame-detection='1' uri='file:///I/am/so/fake.fakery' seekable='true'>"
+" <streams caps='video/quicktime'>"
+" <stream type='video' caps='video/x-fake'>"
+" <frame duration='1' id='0' is-keyframe='true' offset='18446744073709551615' offset-end='18446744073709551615' pts='0' dts='0' checksum='cfeb9b47da2bb540cd3fa84cffea4df9'/>" /* buffer1 */
+" <frame duration='1' id='1' is-keyframe='false' offset='18446744073709551615' offset-end='18446744073709551615' pts='1' dts='1' checksum='e40d7cd997bd14462468d201f1e1a3d4'/>" /* buffer2 */
+" <frame duration='1' id='2' is-keyframe='false' offset='18446744073709551615' offset-end='18446744073709551615' pts='2' dts='2' checksum='4136320f0da0738a06c787dce827f034'/>" /* buffer3 */
+" <frame duration='1' id='3' is-keyframe='false' offset='18446744073709551615' offset-end='18446744073709551615' pts='3' dts='3' checksum='sure my dear'/>" /* gonna fail */
+" <frame duration='1' id='4' is-keyframe='true' offset='18446744073709551615' offset-end='18446744073709551615' pts='4' dts='4' checksum='569d8927835c44fd4ff40b8408657f9e'/>" /* buffer4 */
+" <frame duration='1' id='5' is-keyframe='false' offset='18446744073709551615' offset-end='18446744073709551615' pts='5' dts='5' checksum='fcea4caed9b2c610fac1f2a6b38b1d5f'/>" /* buffer5 */
+" <frame duration='1' id='6' is-keyframe='false' offset='18446744073709551615' offset-end='18446744073709551615' pts='6' dts='6' checksum='c7536747446a1503b1d9b02744144fa9'/>" /* buffer6 */
+" <frame duration='1' id='7' is-keyframe='false' offset='18446744073709551615' offset-end='18446744073709551615' pts='7' dts='7' checksum='sure my dear'/>" /* gonna fail */
+" <tags>"
+" </tags>"
+" </stream>"
+" </streams>"
+"</file>";
+/* *INDENT-ON* */
+
+typedef struct _BufferDesc
+{
+ const gchar *content;
+ GstClockTime pts;
+ GstClockTime dts;
+ GstClockTime duration;
+ gboolean keyframe;
+
+ gint num_issues;
+} BufferDesc;
+
+static GstBuffer *
+_create_buffer (BufferDesc * bdesc)
+{
+ gchar *tmp = g_strdup (bdesc->content);
+ GstBuffer *buffer =
+ gst_buffer_new_wrapped (tmp, strlen (tmp) * sizeof (gchar));
+
+ GST_BUFFER_DTS (buffer) = bdesc->dts;
+ GST_BUFFER_PTS (buffer) = bdesc->pts;
+ GST_BUFFER_DURATION (buffer) = bdesc->duration;
+
+ if (bdesc->keyframe)
+ GST_BUFFER_FLAG_UNSET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
+ else
+ GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
+
+ return buffer;
+}
+
+static void
+_check_media_info (GstSegment * segment, BufferDesc * bufs)
+{
+ GList *reports;
+ GstEvent *segev;
+ GstBuffer *buffer;
+ GstElement *decoder;
+ GstPad *srcpad, *sinkpad;
+ GstValidateReport *report;
+ GstValidateMonitor *monitor;
+ GstValidateRunner *runner;
+ GstMediaDescriptor *mdesc;
+
+ GError *err = NULL;
+ gint i, num_issues = 0;
+
+ fail_unless (g_setenv ("GST_VALIDATE_REPORT_LEVEL", "all", TRUE));
+ runner = gst_validate_runner_new ();
+
+ mdesc = (GstMediaDescriptor *)
+ gst_media_descriptor_parser_new_from_xml (runner, media_info, &err);
+
+ decoder = fake_decoder_new ();
+ monitor = gst_validate_monitor_factory_create (GST_OBJECT (decoder),
+ runner, NULL);
+ gst_validate_monitor_set_media_descriptor (monitor, mdesc);
+
+ srcpad = gst_pad_new ("src", GST_PAD_SRC);
+ sinkpad = decoder->sinkpads->data;
+ ASSERT_OBJECT_REFCOUNT (sinkpad, "decoder ref", 1);
+ fail_unless (gst_pad_activate_mode (srcpad, GST_PAD_MODE_PUSH, TRUE));
+ fail_unless_equals_int (gst_element_set_state (decoder, GST_STATE_PLAYING),
+ GST_STATE_CHANGE_SUCCESS);
+
+ assert_equals_string (gst_pad_link_get_name (gst_pad_link (srcpad, sinkpad)),
+ gst_pad_link_get_name (GST_PAD_LINK_OK));
+
+ gst_check_setup_events_with_stream_id (srcpad, decoder,
+ gst_caps_from_string ("video/x-fake"), GST_FORMAT_TIME, "the-stream");
+
+
+ if (segment) {
+ segev = gst_event_new_segment (segment);
+ fail_unless (gst_pad_push_event (srcpad, segev));
+ }
+
+ for (i = 0; bufs[i].content != NULL; i++) {
+ BufferDesc *buf = &bufs[i];
+ buffer = _create_buffer (buf);
+
+ assert_equals_string (gst_flow_get_name (gst_pad_push (srcpad, buffer)),
+ gst_flow_get_name (GST_FLOW_OK));
+ reports = gst_validate_runner_get_reports (runner);
+
+ num_issues += buf->num_issues;
+ assert_equals_int (g_list_length (reports), num_issues);
+
+ if (buf->num_issues) {
+ GList *tmp = g_list_nth (reports, num_issues - buf->num_issues);
+
+ while (tmp) {
+ report = tmp->data;
+
+ fail_unless_equals_int (report->level,
+ GST_VALIDATE_REPORT_LEVEL_WARNING);
+ fail_unless_equals_int (report->issue->issue_id,
+ GST_VALIDATE_ISSUE_ID_WRONG_BUFFER);
+ tmp = tmp->next;
+ }
+ }
+ }
+
+ /* clean up */
+ fail_unless (gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PUSH, FALSE));
+ fail_unless_equals_int (gst_element_set_state (decoder, GST_STATE_NULL),
+ GST_STATE_CHANGE_SUCCESS);
+
+ gst_object_unref (srcpad);
+ check_destroyed (decoder, sinkpad, NULL);
+ check_destroyed (runner, NULL, NULL);
+}
+
+GST_START_TEST (check_media_info)
+{
+ GstSegment segment;
+
+
+/* *INDENT-OFF* */
+ _check_media_info (NULL,
+ (BufferDesc []) {
+ {
+ .content = "buffer1",
+ .pts = 0,
+ .dts = 0,
+ .duration = 1,
+ .keyframe = TRUE,
+ .num_issues = 0
+ },
+ {
+ .content = "buffer2",
+ .pts = 1,
+ .dts = 1,
+ .duration = 1,
+ .keyframe = FALSE,
+ .num_issues = 0
+ },
+ {
+ .content = "buffer3",
+ .pts = 2,
+ .dts = 2,
+ .duration = 1,
+ .keyframe = FALSE,
+ .num_issues = 0
+ },
+ {
+ .content = "fail please",
+ .pts = 3,
+ .dts = 3,
+ .duration = 1,
+ .keyframe = FALSE,
+ .num_issues = 1
+ },
+ { NULL}
+ });
+/* *INDENT-ON* */
+
+ gst_segment_init (&segment, GST_FORMAT_TIME);
+ /* Segment start is 2, the first buffer is expected (first Keyframe) */
+ segment.start = 2;
+
+/* *INDENT-OFF* */
+ _check_media_info (&segment,
+ (BufferDesc []) {
+ {
+ .content = "buffer2", /* Wrong checksum */
+ .pts = 0,
+ .dts = 0,
+ .duration = 1,
+ .keyframe = TRUE,
+ .num_issues = 1
+ },
+ { NULL}
+ });
+/* *INDENT-ON* */
+
+ gst_segment_init (&segment, GST_FORMAT_TIME);
+ /* Segment start is 2, the first buffer is expected (first Keyframe) */
+ segment.start = 2;
+
+/* *INDENT-OFF* */
+ _check_media_info (&segment,
+ (BufferDesc []) {
+ { /* The right first buffer */
+ .content = "buffer1",
+ .pts = 0,
+ .dts = 0,
+ .duration = 1,
+ .keyframe = TRUE,
+ .num_issues = 0
+ },
+ { NULL}
+ });
+/* *INDENT-ON* */
+
+ gst_segment_init (&segment, GST_FORMAT_TIME);
+ /* Segment start is 6, the 4th buffer is expected (first Keyframe) */
+ segment.start = 6;
+
+/* *INDENT-OFF* */
+ _check_media_info (&segment,
+ (BufferDesc []) {
+ { /* The right fourth buffer */
+ .content = "buffer4",
+ .pts = 4,
+ .dts = 4,
+ .duration = 1,
+ .keyframe = TRUE,
+ .num_issues = 0
+ },
+ { NULL}
+ });
+/* *INDENT-ON* */
+
+ gst_segment_init (&segment, GST_FORMAT_TIME);
+ /* Segment start is 6, the 4th buffer is expected (first Keyframe) */
+ segment.start = 6;
+
+/* *INDENT-OFF* */
+ _check_media_info (&segment,
+ (BufferDesc []) {
+ { /* The sixth buffer... all wrong! */
+ .content = "buffer6",
+ .pts = 6,
+ .dts = 6,
+ .duration = 1,
+ .keyframe = FALSE,
+ .num_issues = 1
+ },
+ { NULL}
+ });
+/* *INDENT-ON* */
+}
GST_END_TEST;
@@ -562,6 +817,7 @@ gst_validate_suite (void)
tcase_add_test (tc_chain, first_buffer_running_time);
tcase_add_test (tc_chain, flow_aggregation);
tcase_add_test (tc_chain, issue_concatenation);
+ tcase_add_test (tc_chain, check_media_info);
return s;
}
diff --git a/validate/tests/check/validate/test-utils.c b/validate/tests/check/validate/test-utils.c
index c67f555..5265d96 100644
--- a/validate/tests/check/validate/test-utils.c
+++ b/validate/tests/check/validate/test-utils.c
@@ -102,18 +102,8 @@ GST_STATIC_PAD_TEMPLATE ("sink",
GST_STATIC_CAPS ("something")
);
-static void
-fake_demuxer_dispose (FakeDemuxer * self)
-{
-}
-
-static void
-fake_demuxer_finalize (FakeDemuxer * self)
-{
-}
-
static GstFlowReturn
-_chain (GstPad * pad, GstObject * self, GstBuffer * buffer)
+_demuxer_chain (GstPad * pad, GstObject * self, GstBuffer * buffer)
{
gst_buffer_unref (buffer);
@@ -146,18 +136,14 @@ fake_demuxer_init (FakeDemuxer * self, gpointer * g_class)
self->return_value = GST_FLOW_OK;
- gst_pad_set_chain_function (pad, _chain);
+ gst_pad_set_chain_function (pad, _demuxer_chain);
}
static void
fake_demuxer_class_init (FakeDemuxerClass * self_class)
{
- GObjectClass *object_class = G_OBJECT_CLASS (self_class);
GstElementClass *gstelement_class = GST_ELEMENT_CLASS (self_class);
- object_class->dispose = (void (*)(GObject * object)) fake_demuxer_dispose;
- object_class->finalize = (void (*)(GObject * object)) fake_demuxer_finalize;
-
gst_element_class_add_pad_template (gstelement_class,
gst_static_pad_template_get (&fake_demuxer_src_template));
gst_element_class_add_pad_template (gstelement_class,
@@ -222,3 +208,91 @@ free_element_monitor (GstElement *element)
g_object_unref (G_OBJECT(monitor));
}
+
+static GstStaticPadTemplate fake_decoder_src_template =
+GST_STATIC_PAD_TEMPLATE ("src",
+ GST_PAD_SRC,
+ GST_PAD_SOMETIMES,
+ GST_STATIC_CAPS ("video/x-fake")
+ );
+
+static GstStaticPadTemplate fake_decoder_sink_template =
+GST_STATIC_PAD_TEMPLATE ("sink",
+ GST_PAD_SINK,
+ GST_PAD_ALWAYS,
+ GST_STATIC_CAPS ("video/x-fake")
+ );
+
+static GstFlowReturn
+_decoder_chain (GstPad * pad, GstObject * self, GstBuffer * buffer)
+{
+ gst_buffer_unref (buffer);
+
+ return FAKE_DECODER (self)->return_value;
+}
+
+static void
+fake_decoder_init (FakeDecoder * self, gpointer * g_class)
+{
+ GstPad *pad;
+ GstElement *element = GST_ELEMENT (self);
+ GstPadTemplate *pad_template;
+
+ pad_template =
+ gst_element_class_get_pad_template (GST_ELEMENT_CLASS (g_class), "src");
+ pad = gst_pad_new_from_template (pad_template, "src");
+ gst_element_add_pad (element, pad);
+
+ pad_template =
+ gst_element_class_get_pad_template (GST_ELEMENT_CLASS (g_class), "sink");
+ pad = gst_pad_new_from_template (pad_template, "sink");
+ gst_element_add_pad (element, pad);
+
+ self->return_value = GST_FLOW_OK;
+
+ gst_pad_set_chain_function (pad, _decoder_chain);
+}
+
+static void
+fake_decoder_class_init (FakeDecoderClass * self_class)
+{
+ GstElementClass *gstelement_class = GST_ELEMENT_CLASS (self_class);
+
+ gst_element_class_add_pad_template (gstelement_class,
+ gst_static_pad_template_get (&fake_decoder_src_template));
+ gst_element_class_add_pad_template (gstelement_class,
+ gst_static_pad_template_get (&fake_decoder_sink_template));
+ gst_element_class_set_static_metadata (gstelement_class,
+ "Fake Decoder", "Decoder", "Some decoder", "Thibault Saunier");
+}
+
+GType
+fake_decoder_get_type (void)
+{
+ static volatile gsize type = 0;
+
+ if (g_once_init_enter (&type)) {
+ GType _type;
+ static const GTypeInfo info = {
+ sizeof (FakeDecoderClass),
+ NULL,
+ NULL,
+ (GClassInitFunc) fake_decoder_class_init,
+ NULL,
+ NULL,
+ sizeof (FakeDecoder),
+ 0,
+ (GInstanceInitFunc) fake_decoder_init,
+ };
+
+ _type = g_type_register_static (GST_TYPE_ELEMENT, "FakeDecoder", &info, 0);
+ g_once_init_leave (&type, _type);
+ }
+ return type;
+}
+
+GstElement *
+fake_decoder_new (void)
+{
+ return GST_ELEMENT (g_object_new (FAKE_DECODER_TYPE, NULL));
+}
diff --git a/validate/tests/check/validate/test-utils.h b/validate/tests/check/validate/test-utils.h
index ac6a3a7..1854048 100644
--- a/validate/tests/check/validate/test-utils.h
+++ b/validate/tests/check/validate/test-utils.h
@@ -54,6 +54,25 @@ typedef struct {
GType fake_demuxer_get_type (void);
GstElement * fake_demuxer_new (void);
+typedef struct {
+ GstElement parent;
+
+ GstFlowReturn return_value;
+} FakeDecoder;
+
+typedef struct {
+ GstElementClass parent;
+} FakeDecoderClass;
+
+#define FAKE_DECODER_TYPE (fake_decoder_get_type ())
+#define FAKE_DECODER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FAKE_DECODER_TYPE, FakeDecoder))
+#define FAKE_DECODER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), FAKE_DECODER_TYPE, FakeDecoderClass))
+#define IS_FAKE_DECODER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), FAKE_DECODER_TYPE))
+#define IS_FAKE_DECODER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), FAKE_DECODER_TYPE))
+#define FAKE_DECODER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), FAKE_DECODER_TYPE, FakeDecoderClass))
+
+GType fake_decoder_get_type (void);
+GstElement * fake_decoder_new (void);
G_END_DECLS
diff --git a/validate/tools/launcher/apps/gstvalidate.py b/validate/tools/launcher/apps/gstvalidate.py
index ff8db20..376d60c 100644
--- a/validate/tools/launcher/apps/gstvalidate.py
+++ b/validate/tools/launcher/apps/gstvalidate.py
@@ -294,6 +294,8 @@ class GstValidateLaunchTest(GstValidateTest):
def build_arguments(self):
GstValidateTest.build_arguments(self)
self.add_arguments(self.pipeline_desc)
+ if self.media_descriptor is not None:
+ self.add_arguments("--set-media-info", self.media_descriptor.get_path())
def get_current_value(self):
if self.scenario: