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
This commit is contained in:
Thibault Saunier 2014-09-15 17:27:54 +02:00 committed by Mathieu Duponchelle
parent cd9a3640b2
commit bb93dbb9fb
8 changed files with 555 additions and 16 deletions

View file

@ -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 static gboolean
gst_validate_pad_monitor_downstream_event_check (GstValidatePadMonitor * gst_validate_pad_monitor_downstream_event_check (GstValidatePadMonitor *
pad_monitor, GstObject * parent, GstEvent * event, 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); gst_segment_copy_into (segment, &pad_monitor->segment);
pad_monitor->has_segment = TRUE; pad_monitor->has_segment = TRUE;
gst_validate_monitor_find_next_buffer (pad_monitor);
} }
break; break;
case GST_EVENT_CAPS:{ case GST_EVENT_CAPS:{
@ -1685,6 +1774,90 @@ gst_validate_pad_monitor_src_event_check (GstValidatePadMonitor * pad_monitor,
return ret; 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 static GstFlowReturn
gst_validate_pad_monitor_chain_func (GstPad * pad, GstObject * parent, gst_validate_pad_monitor_chain_func (GstPad * pad, GstObject * parent,
GstBuffer * buffer) 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_PAD_MONITOR_PARENT_LOCK (pad_monitor);
GST_VALIDATE_MONITOR_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_check_first_buffer (pad_monitor, buffer);
gst_validate_pad_monitor_update_buffer_data (pad_monitor, buffer); gst_validate_pad_monitor_update_buffer_data (pad_monitor, buffer);
gst_validate_pad_monitor_check_eos (pad_monitor, buffer); gst_validate_pad_monitor_check_eos (pad_monitor, buffer);

View file

@ -29,6 +29,7 @@ typedef struct _GstValidatePadMonitor GstValidatePadMonitor;
typedef struct _GstValidatePadMonitorClass GstValidatePadMonitorClass; typedef struct _GstValidatePadMonitorClass GstValidatePadMonitorClass;
#include <gst/validate/gst-validate-monitor.h> #include <gst/validate/gst-validate-monitor.h>
#include <gst/validate/media-descriptor-parser.h>
#include <gst/validate/gst-validate-element-monitor.h> #include <gst/validate/gst-validate-element-monitor.h>
G_BEGIN_DECLS G_BEGIN_DECLS
@ -110,6 +111,12 @@ struct _GstValidatePadMonitor {
*/ */
GstClockTime timestamp_range_start; GstClockTime timestamp_range_start;
GstClockTime timestamp_range_end; 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;
}; };
/** /**

View file

@ -130,6 +130,12 @@ gst_validate_report_load_issues (void)
REGISTER_VALIDATE_ISSUE (WARNING, FIRST_BUFFER_RUNNING_TIME_IS_NOT_ZERO, REGISTER_VALIDATE_ISSUE (WARNING, FIRST_BUFFER_RUNNING_TIME_IS_NOT_ZERO,
_("first buffer's running time isn't 0"), _("first buffer's running time isn't 0"),
_("the first buffer's received running time is expected to be 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, REGISTER_VALIDATE_ISSUE (CRITICAL, WRONG_FLOW_RETURN,
_("flow return from pad push doesn't match expected value"), _("flow return from pad push doesn't match expected value"),
_("flow return from a 1:1 sink/src pad element is as simple as " _("flow return from a 1:1 sink/src pad element is as simple as "

View file

@ -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_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_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_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_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) #define GST_VALIDATE_ISSUE_ID_CAPS_FIELD_HAS_BAD_TYPE (((GstValidateIssueId) GST_VALIDATE_AREA_CAPS) << GST_VALIDATE_ISSUE_ID_SHIFT | 2)

View file

@ -19,6 +19,7 @@
#include <gst/validate/validate.h> #include <gst/validate/validate.h>
#include <gst/validate/gst-validate-pad-monitor.h> #include <gst/validate/gst-validate-pad-monitor.h>
#include <gst/validate/media-descriptor-parser.h>
#include <gst/check/gstcheck.h> #include <gst/check/gstcheck.h>
#include "test-utils.h" #include "test-utils.h"
@ -545,6 +546,260 @@ GST_START_TEST (issue_concatenation)
check_destroyed (sink, sinkpad, NULL); check_destroyed (sink, sinkpad, NULL);
check_destroyed (runner, NULL, 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; 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, first_buffer_running_time);
tcase_add_test (tc_chain, flow_aggregation); tcase_add_test (tc_chain, flow_aggregation);
tcase_add_test (tc_chain, issue_concatenation); tcase_add_test (tc_chain, issue_concatenation);
tcase_add_test (tc_chain, check_media_info);
return s; return s;
} }

View file

@ -102,18 +102,8 @@ GST_STATIC_PAD_TEMPLATE ("sink",
GST_STATIC_CAPS ("something") GST_STATIC_CAPS ("something")
); );
static void
fake_demuxer_dispose (FakeDemuxer * self)
{
}
static void
fake_demuxer_finalize (FakeDemuxer * self)
{
}
static GstFlowReturn static GstFlowReturn
_chain (GstPad * pad, GstObject * self, GstBuffer * buffer) _demuxer_chain (GstPad * pad, GstObject * self, GstBuffer * buffer)
{ {
gst_buffer_unref (buffer); gst_buffer_unref (buffer);
@ -146,18 +136,14 @@ fake_demuxer_init (FakeDemuxer * self, gpointer * g_class)
self->return_value = GST_FLOW_OK; self->return_value = GST_FLOW_OK;
gst_pad_set_chain_function (pad, _chain); gst_pad_set_chain_function (pad, _demuxer_chain);
} }
static void static void
fake_demuxer_class_init (FakeDemuxerClass * self_class) fake_demuxer_class_init (FakeDemuxerClass * self_class)
{ {
GObjectClass *object_class = G_OBJECT_CLASS (self_class);
GstElementClass *gstelement_class = GST_ELEMENT_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_element_class_add_pad_template (gstelement_class,
gst_static_pad_template_get (&fake_demuxer_src_template)); gst_static_pad_template_get (&fake_demuxer_src_template));
gst_element_class_add_pad_template (gstelement_class, gst_element_class_add_pad_template (gstelement_class,
@ -222,3 +208,91 @@ free_element_monitor (GstElement *element)
g_object_unref (G_OBJECT(monitor)); 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));
}

View file

@ -54,6 +54,25 @@ typedef struct {
GType fake_demuxer_get_type (void); GType fake_demuxer_get_type (void);
GstElement * fake_demuxer_new (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 G_END_DECLS

View file

@ -294,6 +294,8 @@ class GstValidateLaunchTest(GstValidateTest):
def build_arguments(self): def build_arguments(self):
GstValidateTest.build_arguments(self) GstValidateTest.build_arguments(self)
self.add_arguments(self.pipeline_desc) 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): def get_current_value(self):
if self.scenario: if self.scenario: