tests: add textoverlay passthrough with composition feature unit tests

https://bugzilla.gnome.org/show_bug.cgi?id=721953
This commit is contained in:
Matthieu Bouron 2014-01-30 15:41:49 +00:00 committed by Sebastian Dröge
parent ed8e7d4275
commit c904661dc3
2 changed files with 235 additions and 6 deletions

View file

@ -492,7 +492,7 @@ elements_audioresample_LDADD = \
$(GST_BASE_LIBS) \
$(LDADD)
elements_textoverlay_LDADD = $(GST_BASE_LIBS) $(LDADD)
elements_textoverlay_LDADD = $(GST_BASE_LIBS) -lgstvideo-@GST_API_VERSION@ $(LDADD)
elements_textoverlay_CFLAGS = $(GST_BASE_CFLAGS) $(AM_CFLAGS)
elements_volume_LDADD = \

View file

@ -21,6 +21,7 @@
#include <unistd.h>
#include <gst/check/gstcheck.h>
#include <gst/video/video-overlay-composition.h>
#define I420_Y_ROWSTRIDE(width) (GST_ROUND_UP_4(width))
#define I420_U_ROWSTRIDE(width) (GST_ROUND_UP_8(width)/2)
@ -51,11 +52,43 @@ static GstPad *myvideosrcpad, *mytextsrcpad, *mysinkpad;
"video/x-raw, " \
"format = (string) I420"
#define VIDEO_CAPS_TEMPLATE_WITH_FEATURE_STRING \
"video/x-raw(" GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION "), " \
"format = (string) I420;" \
"video/x-raw, " \
"format = (string) I420;"
#define UNSUPPORTED_VIDEO_CAPS_STRING \
"video/x-raw(" GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META "), " \
"format = (string) I420, " \
"framerate = (fraction) 1/1, " \
"width = (int) 240, " \
"height = (int) 120"
#define UNSUPPORTED_VIDEO_CAPS_TEMPLATE_STRING \
"video/x-raw(" GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META "), " \
"format = (string) I420"
#define UNSUPPORTED_VIDEO_CAPS_TEMPLATE_WITH_FEATURE_STRING \
"video/x-raw(" GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META "," \
GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION "), " \
"format = (string) I420;" \
"video/x-raw(" GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META "), " \
"format = (string) I420"
static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS (VIDEO_CAPS_TEMPLATE_STRING)
);
static GstStaticPadTemplate sinktemplate_with_features =
GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS (VIDEO_CAPS_TEMPLATE_WITH_FEATURE_STRING)
);
static GstStaticPadTemplate text_srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
@ -68,6 +101,20 @@ static GstStaticPadTemplate video_srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
GST_STATIC_CAPS (VIDEO_CAPS_TEMPLATE_STRING)
);
static GstStaticPadTemplate unsupported_sinktemplate_with_features =
GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS (UNSUPPORTED_VIDEO_CAPS_TEMPLATE_WITH_FEATURE_STRING)
);
static GstStaticPadTemplate unsupported_video_srctemplate =
GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS (UNSUPPORTED_VIDEO_CAPS_TEMPLATE_STRING)
);
static void
gst_check_setup_events_textoverlay (GstPad * srcpad, GstElement * element,
GstCaps * caps, GstFormat format, const gchar * stream_id)
@ -83,6 +130,30 @@ gst_check_setup_events_textoverlay (GstPad * srcpad, GstElement * element,
fail_unless (gst_pad_push_event (srcpad, gst_event_new_segment (&segment)));
}
static gboolean
sink_query_handler (GstPad * pad, GstObject * parent, GstQuery * query)
{
gboolean ret = FALSE;
GstQueryType type = GST_QUERY_TYPE (query);
switch (type) {
case GST_QUERY_ALLOCATION:{
gst_query_add_allocation_meta (query,
GST_VIDEO_OVERLAY_COMPOSITION_META_API_TYPE, NULL);
ret = TRUE;
break;
}
default:{
ret = gst_pad_query_default (pad, parent, query);
break;
}
}
return ret;
}
/* much like gst_check_setup_src_pad(), but with possibility to give a hint
* which sink template of the element to use, if there are multiple ones */
static GstPad *
@ -145,20 +216,28 @@ notgst_check_teardown_src_pad2 (GstElement * element,
}
static GstElement *
setup_textoverlay (gboolean video_only_no_text)
setup_textoverlay_with_templates (GstStaticPadTemplate * srcpad_template,
GstStaticPadTemplate * textpad_template,
GstStaticPadTemplate * sinkpad_template, gboolean enable_allocation_query)
{
GstElement *textoverlay;
GST_DEBUG ("setup_textoverlay");
textoverlay = gst_check_setup_element ("textoverlay");
mysinkpad = gst_check_setup_sink_pad (textoverlay, &sinktemplate);
mysinkpad = gst_check_setup_sink_pad (textoverlay, sinkpad_template);
if (enable_allocation_query) {
GST_PAD_SET_PROXY_ALLOCATION (mysinkpad);
gst_pad_set_query_function (mysinkpad, sink_query_handler);
}
myvideosrcpad =
notgst_check_setup_src_pad2 (textoverlay, &video_srctemplate, NULL,
notgst_check_setup_src_pad2 (textoverlay, srcpad_template, NULL,
"video_sink");
if (!video_only_no_text) {
if (textpad_template) {
mytextsrcpad =
notgst_check_setup_src_pad2 (textoverlay, &text_srctemplate, NULL,
notgst_check_setup_src_pad2 (textoverlay, textpad_template, NULL,
"text_sink");
gst_pad_set_active (mytextsrcpad, TRUE);
} else {
@ -171,6 +250,22 @@ setup_textoverlay (gboolean video_only_no_text)
return textoverlay;
}
static GstElement *
setup_textoverlay (gboolean video_only_no_text)
{
GstStaticPadTemplate *srcpad_template = NULL;
GstStaticPadTemplate *textpad_template = NULL;
GstStaticPadTemplate *sinkpad_template = NULL;
srcpad_template = &video_srctemplate;
if (!video_only_no_text)
textpad_template = &text_srctemplate;
sinkpad_template = &sinktemplate;
return setup_textoverlay_with_templates (srcpad_template,
textpad_template, sinkpad_template, FALSE);
}
static gboolean
buffer_is_all_black (GstBuffer * buf, GstCaps * caps)
{
@ -422,6 +517,137 @@ GST_START_TEST (test_video_passthrough)
GST_END_TEST;
GST_START_TEST (test_video_passthrough_with_feature)
{
GstElement *textoverlay;
GstBuffer *inbuffer, *outbuffer;
GstCaps *incaps, *outcaps;
GstVideoOverlayCompositionMeta *comp_meta;
textoverlay = setup_textoverlay_with_templates (&video_srctemplate,
NULL, &sinktemplate_with_features, TRUE);
/* set static text to render */
g_object_set (textoverlay, "text", "XLX", NULL);
fail_unless (gst_element_set_state (textoverlay,
GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
"could not set to playing");
incaps = create_video_caps (VIDEO_CAPS_STRING);
gst_check_setup_events_textoverlay (myvideosrcpad, textoverlay, incaps,
GST_FORMAT_TIME, "video");
inbuffer = create_black_buffer (incaps);
gst_caps_unref (incaps);
ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
GST_BUFFER_TIMESTAMP (inbuffer) = 0;
GST_BUFFER_DURATION (inbuffer) = GST_SECOND / 10;
/* take additional ref to keep it alive */
gst_buffer_ref (inbuffer);
ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 2);
/* pushing gives away one of the two references we have ... */
fail_unless (gst_pad_push (myvideosrcpad, inbuffer) == GST_FLOW_OK);
/* should have been dropped in favour of a new writable buffer */
ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
fail_unless_equals_int (g_list_length (buffers), 1);
outbuffer = GST_BUFFER_CAST (buffers->data);
outcaps = gst_pad_get_current_caps (mysinkpad);
fail_unless (outbuffer != inbuffer);
/* output buffer should be black */
fail_unless (buffer_is_all_black (outbuffer, outcaps) == TRUE);
gst_caps_unref (outcaps);
/* output buffer should have the composition meta */
comp_meta = gst_buffer_get_video_overlay_composition_meta (outbuffer);
fail_unless (comp_meta != NULL);
fail_unless (GST_BUFFER_TIMESTAMP (outbuffer) == 0);
fail_unless (GST_BUFFER_DURATION (outbuffer) == (GST_SECOND / 10));
/* and clean up */
g_list_foreach (buffers, (GFunc) gst_mini_object_unref, NULL);
g_list_free (buffers);
buffers = NULL;
ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
/* cleanup */
cleanup_textoverlay (textoverlay);
gst_buffer_unref (inbuffer);
}
GST_END_TEST;
GST_START_TEST (test_video_passthrough_with_feature_and_unsupported_caps)
{
GstElement *textoverlay;
GstBuffer *inbuffer, *outbuffer;
GstCaps *incaps, *outcaps;
GstVideoOverlayCompositionMeta *comp_meta;
textoverlay =
setup_textoverlay_with_templates (&unsupported_video_srctemplate, NULL,
&unsupported_sinktemplate_with_features, TRUE);
/* set static text to render */
g_object_set (textoverlay, "text", "XLX", NULL);
fail_unless (gst_element_set_state (textoverlay,
GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
"could not set to playing");
incaps = create_video_caps (UNSUPPORTED_VIDEO_CAPS_STRING);
gst_check_setup_events_textoverlay (myvideosrcpad, textoverlay, incaps,
GST_FORMAT_TIME, "video");
inbuffer = create_black_buffer (incaps);
gst_caps_unref (incaps);
ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
GST_BUFFER_TIMESTAMP (inbuffer) = 0;
GST_BUFFER_DURATION (inbuffer) = GST_SECOND / 10;
/* take additional ref to keep it alive */
gst_buffer_ref (inbuffer);
ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 2);
/* pushing gives away one of the two references we have ... */
fail_unless (gst_pad_push (myvideosrcpad, inbuffer) == GST_FLOW_OK);
/* should have been dropped in favour of a new writable buffer */
ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
fail_unless_equals_int (g_list_length (buffers), 1);
outbuffer = GST_BUFFER_CAST (buffers->data);
outcaps = gst_pad_get_current_caps (mysinkpad);
fail_unless (outbuffer != inbuffer);
/* output buffer should be black */
fail_unless (buffer_is_all_black (outbuffer, outcaps) == TRUE);
gst_caps_unref (outcaps);
/* output buffer should have the composition meta */
comp_meta = gst_buffer_get_video_overlay_composition_meta (outbuffer);
fail_unless (comp_meta != NULL);
fail_unless (GST_BUFFER_TIMESTAMP (outbuffer) == 0);
fail_unless (GST_BUFFER_DURATION (outbuffer) == (GST_SECOND / 10));
/* and clean up */
g_list_foreach (buffers, (GFunc) gst_mini_object_unref, NULL);
g_list_free (buffers);
buffers = NULL;
ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
/* cleanup */
cleanup_textoverlay (textoverlay);
gst_buffer_unref (inbuffer);
}
GST_END_TEST;
GST_START_TEST (test_video_render_static_text)
{
GstElement *textoverlay;
@ -813,6 +1039,9 @@ textoverlay_suite (void)
suite_add_tcase (s, tc_chain);
tcase_add_test (tc_chain, test_video_passthrough);
tcase_add_test (tc_chain, test_video_passthrough_with_feature);
tcase_add_test (tc_chain,
test_video_passthrough_with_feature_and_unsupported_caps);
tcase_add_test (tc_chain, test_video_render_static_text);
tcase_add_test (tc_chain, test_render_continuity);
tcase_add_test (tc_chain, test_video_waits_for_text);