mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-26 02:00:33 +00:00
tests: add textoverlay passthrough with composition feature unit tests
https://bugzilla.gnome.org/show_bug.cgi?id=721953
This commit is contained in:
parent
ed8e7d4275
commit
c904661dc3
2 changed files with 235 additions and 6 deletions
|
@ -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 = \
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue