| /* |
| * GStreamer |
| * |
| * unit test for templatematch |
| * |
| * Copyright (C) 2014 Samsung Electronics. All rights reserved. |
| * Author: Thiago Santos <ts.santos@sisa.samsung.com> |
| * |
| * This library is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Library General Public |
| * License as published by the Free Software Foundation; either |
| * version 2 of the License, or (at your option) any later version. |
| * |
| * This library is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Library General Public License for more details. |
| * |
| * You should have received a copy of the GNU Library General Public |
| * License along with this library; if not, write to the |
| * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, |
| * Boston, MA 02110-1301, USA. |
| */ |
| |
| #include <gst/check/gstcheck.h> |
| |
| #define CAPS_TMPL "video/x-raw, format=(string)BGR" |
| |
| GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink", |
| GST_PAD_SINK, |
| GST_PAD_ALWAYS, |
| GST_STATIC_CAPS (CAPS_TMPL) |
| ); |
| GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src", |
| GST_PAD_SRC, |
| GST_PAD_ALWAYS, |
| GST_STATIC_CAPS (CAPS_TMPL) |
| ); |
| |
| /* Create a 16x16 buffer split in 4 equal squares |
| * BG |
| * Rb |
| * |
| * B=Blue, G=Green, R=Red, b=black |
| */ |
| static GstBuffer * |
| create_input_buffer (void) |
| { |
| guint8 *data; |
| gsize size; |
| gint i, j, base; |
| |
| size = 3 * 16 * 16; /* BGR 16x16 */ |
| data = g_malloc0 (size); |
| |
| /* blue and green */ |
| for (j = 0; j < 8; j++) { |
| for (i = 0; i < 8; i++) { |
| base = j * 16; |
| data[base + i] = 255; |
| data[base + i + 1] = 0; |
| data[base + i + 2] = 0; |
| |
| data[base + 8 + i] = 0; |
| data[base + 8 + i + 1] = 255; |
| data[base + 8 + i + 2] = 0; |
| } |
| } |
| /* red */ |
| for (j = 0; j < 8; j++) { |
| for (i = 0; i < 8; i++) { |
| base = 8 * 8 + j * 16; |
| data[base + i] = 0; |
| data[base + i + 1] = 0; |
| data[base + i + 2] = 255; |
| } |
| } |
| |
| return gst_buffer_new_wrapped (data, size); |
| } |
| |
| /* Test to make sure that we are using the same rgb format as opencv expects for |
| * template matching (BGR). |
| * Will use a blue 8x8 square as the template and as input a 16x16 frame divided |
| * evenly in 4 squares: Blue (top-left), Green (top-right), Red (bottom-left) and |
| * Black (bottom-right) |
| * |
| * https://bugzilla.gnome.org/show_bug.cgi?id=678485 |
| */ |
| GST_START_TEST (test_match_blue_square) |
| { |
| GstElement *element; |
| GstPad *sinkpad, *srcpad; |
| GstCaps *caps = |
| gst_caps_from_string (CAPS_TMPL |
| ", width=(int)16, height=(int)16, framerate=1/1"); |
| GstBus *bus; |
| GstMessage *msg; |
| const GstStructure *structure; |
| gchar *path; |
| GstBuffer *buf; |
| guint x, y, width, height; |
| |
| element = gst_check_setup_element ("templatematch"); |
| srcpad = gst_check_setup_src_pad (element, &srctemplate); |
| sinkpad = gst_check_setup_sink_pad (element, &sinktemplate); |
| gst_pad_set_active (srcpad, TRUE); |
| gst_check_setup_events (srcpad, element, caps, GST_FORMAT_TIME); |
| gst_pad_set_active (sinkpad, TRUE); |
| |
| bus = gst_bus_new (); |
| gst_element_set_bus (element, bus); |
| |
| path = g_build_filename (GST_TEST_FILES_PATH, "blue-square.png", NULL); |
| g_object_set (element, "template", path, NULL); |
| g_free (path); |
| |
| fail_unless (gst_element_set_state (element, |
| GST_STATE_PLAYING) != GST_STATE_CHANGE_FAILURE, |
| "could not set to playing"); |
| |
| buf = create_input_buffer (); |
| fail_unless (gst_pad_push (srcpad, buf) == GST_FLOW_OK); |
| |
| /* make sure that the template match message was posted, detecting the |
| * blue area in the top left corner */ |
| msg = gst_bus_pop_filtered (bus, GST_MESSAGE_ELEMENT); |
| fail_unless (msg != NULL); |
| fail_unless (GST_MESSAGE_SRC (msg) == GST_OBJECT_CAST (element)); |
| structure = gst_message_get_structure (msg); |
| fail_unless (gst_structure_has_name (structure, "template_match")); |
| fail_unless (gst_structure_get_uint (structure, "x", &x)); |
| fail_unless (gst_structure_get_uint (structure, "y", &y)); |
| fail_unless (gst_structure_get_uint (structure, "width", &width)); |
| fail_unless (gst_structure_get_uint (structure, "height", &height)); |
| fail_unless (x == 0); |
| fail_unless (y == 0); |
| fail_unless (width == 8); |
| fail_unless (height == 8); |
| |
| gst_message_unref (msg); |
| |
| gst_element_set_state (element, GST_STATE_NULL); |
| gst_bus_set_flushing (bus, TRUE); |
| gst_object_unref (bus); |
| gst_caps_unref (caps); |
| gst_check_drop_buffers (); |
| gst_pad_set_active (srcpad, FALSE); |
| gst_pad_set_active (sinkpad, FALSE); |
| gst_object_unref (srcpad); |
| gst_object_unref (sinkpad); |
| gst_check_teardown_src_pad (element); |
| gst_check_teardown_sink_pad (element); |
| gst_check_teardown_element (element); |
| } |
| |
| GST_END_TEST; |
| |
| static Suite * |
| templatematch_suite (void) |
| { |
| Suite *s = suite_create ("templatematch"); |
| TCase *tc_chain = tcase_create ("general"); |
| |
| suite_add_tcase (s, tc_chain); |
| tcase_add_test (tc_chain, test_match_blue_square); |
| |
| return s; |
| } |
| |
| GST_CHECK_MAIN (templatematch); |