2 * Copyright (C) 2008 Nokia Corporation. (contact <stefan.kost@nokia.com>)
3 * Copyright (C) 2010 Thiago Santos <thiago.sousa.santos@collabora.co.uk>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
21 #include <gst/check/gstcheck.h>
23 static GstTagList *received_tags = NULL;
26 bus_handler (GstBus * bus, GstMessage * message, gpointer data)
28 GMainLoop *loop = (GMainLoop *) data;
30 switch (message->type) {
32 g_main_loop_quit (loop);
34 case GST_MESSAGE_WARNING:
35 case GST_MESSAGE_ERROR:{
40 gst_message_parse_error (message, &gerror, &debug);
41 gst_object_default_error (GST_MESSAGE_SRC (message), gerror, debug);
42 g_error_free (gerror);
44 g_main_loop_quit (loop);
47 case GST_MESSAGE_TAG:{
48 if (received_tags == NULL) {
49 gst_message_parse_tag (message, &received_tags);
51 GstTagList *tl = NULL, *ntl = NULL;
53 gst_message_parse_tag (message, &tl);
55 ntl = gst_tag_list_merge (received_tags, tl, GST_TAG_MERGE_PREPEND);
57 GST_LOG ("taglists merged: %" GST_PTR_FORMAT, ntl);
58 gst_tag_list_free (received_tags);
61 gst_tag_list_free (tl);
74 * Creates a pipeline in the form:
75 * fakesrc num-buffers=1 ! caps ! muxer ! filesink location=file
77 * And sets the tags in tag_str into the muxer via tagsetter.
80 test_mux_tags (const gchar * tag_str, const gchar * caps,
81 const gchar * muxer, const gchar * file)
86 GstTagList *sent_tags;
92 GST_DEBUG ("testing xmp muxing on : %s", muxer);
94 launch_str = g_strdup_printf ("fakesrc num-buffers=1 ! %s ! %s name=mux ! "
95 "filesink location=%s name=sink", caps, muxer, file);
96 pipeline = gst_parse_launch (launch_str, NULL);
98 fail_unless (pipeline != NULL);
100 mux = gst_bin_get_by_name (GST_BIN (pipeline), "mux");
101 fail_unless (mux != NULL);
103 loop = g_main_loop_new (NULL, TRUE);
104 fail_unless (loop != NULL);
106 bus = gst_element_get_bus (pipeline);
107 fail_unless (bus != NULL);
108 bus_watch = gst_bus_add_watch (bus, bus_handler, loop);
109 gst_object_unref (bus);
111 gst_element_set_state (pipeline, GST_STATE_READY);
113 setter = GST_TAG_SETTER (mux);
114 fail_unless (setter != NULL);
115 sent_tags = gst_structure_from_string (tag_str, NULL);
116 fail_unless (sent_tags != NULL);
117 gst_tag_setter_merge_tags (setter, sent_tags, GST_TAG_MERGE_REPLACE);
118 gst_tag_list_free (sent_tags);
120 gst_element_set_state (pipeline, GST_STATE_PLAYING);
121 g_main_loop_run (loop);
123 gst_element_set_state (pipeline, GST_STATE_NULL);
125 g_main_loop_unref (loop);
126 g_object_unref (mux);
127 g_object_unref (pipeline);
128 g_source_remove (bus_watch);
132 * Makes a pipeline in the form:
133 * filesrc location=file ! demuxer ! fakesink
135 * And gets the tags that are posted on the bus to compare
136 * with the tags in 'tag_str'
139 test_demux_tags (const gchar * tag_str, const gchar * demuxer,
142 GstElement *pipeline;
145 GstTagList *sent_tags;
146 gint i, j, n_recv, n_sent;
147 const gchar *name_sent, *name_recv;
148 const GValue *value_sent, *value_recv;
155 GST_DEBUG ("testing tags : %s", tag_str);
158 gst_tag_list_free (received_tags);
159 received_tags = NULL;
162 launch_str = g_strdup_printf ("filesrc location=%s ! %s name=demux ! "
163 "fakesink", file, demuxer);
164 pipeline = gst_parse_launch (launch_str, NULL);
166 fail_unless (pipeline != NULL);
168 demux = gst_bin_get_by_name (GST_BIN (pipeline), "demux");
169 fail_unless (demux != NULL);
171 loop = g_main_loop_new (NULL, TRUE);
172 fail_unless (loop != NULL);
174 bus = gst_element_get_bus (pipeline);
175 fail_unless (bus != NULL);
176 bus_watch = gst_bus_add_watch (bus, bus_handler, loop);
177 gst_object_unref (bus);
179 sent_tags = gst_structure_from_string (tag_str, NULL);
180 fail_unless (sent_tags != NULL);
182 gst_element_set_state (pipeline, GST_STATE_PLAYING);
183 g_main_loop_run (loop);
185 GST_DEBUG ("mainloop done : %p", received_tags);
188 fail_unless (received_tags != NULL);
189 n_recv = gst_structure_n_fields (received_tags);
190 n_sent = gst_structure_n_fields (sent_tags);
191 fail_unless (n_recv >= n_sent);
192 /* FIXME: compare taglits values */
193 for (i = 0; i < n_sent; i++) {
194 name_sent = gst_structure_nth_field_name (sent_tags, i);
195 value_sent = gst_structure_get_value (sent_tags, name_sent);
197 for (j = 0; j < n_recv; j++) {
198 name_recv = gst_structure_nth_field_name (received_tags, j);
199 if (!strcmp (name_sent, name_recv)) {
200 value_recv = gst_structure_get_value (received_tags, name_recv);
201 comparison = gst_value_compare (value_sent, value_recv);
202 if (comparison != GST_VALUE_EQUAL) {
203 gchar *vs = g_strdup_value_contents (value_sent);
204 gchar *vr = g_strdup_value_contents (value_recv);
205 GST_DEBUG ("sent = %s:'%s', recv = %s:'%s'",
206 G_VALUE_TYPE_NAME (value_sent), vs,
207 G_VALUE_TYPE_NAME (value_recv), vr);
211 fail_unless (comparison == GST_VALUE_EQUAL,
212 "tag item %s has been received with different type or value",
218 fail_unless (found, "tag item %s is lost", name_sent);
221 gst_tag_list_free (received_tags);
222 received_tags = NULL;
223 gst_tag_list_free (sent_tags);
225 gst_element_set_state (pipeline, GST_STATE_NULL);
227 g_main_loop_unref (loop);
228 g_object_unref (demux);
229 g_object_unref (pipeline);
230 g_source_remove (bus_watch);
234 * Tests if the muxer/demuxer pair can serialize the tags in 'tag_str'
235 * to a file and recover them correctly.
237 * 'caps' are used to assure the muxer accepts the fake buffer fakesrc
241 test_tags (const gchar * tag_str, const gchar * caps, const gchar * muxer,
242 const gchar * demuxer)
247 tmp = g_strdup_printf ("%s%d", "gst-check-xmp-test-", g_random_int ());
248 tmpfile = g_build_filename (g_get_tmp_dir (), tmp, NULL);
251 GST_DEBUG ("testing tags : %s", tag_str);
252 test_mux_tags (tag_str, caps, muxer, tmpfile);
253 test_demux_tags (tag_str, demuxer, tmpfile);
257 #define H264_CAPS "video/x-h264, width=(int)320, height=(int)240," \
258 " framerate=(fraction)30/1, codec_data=(buffer)" \
259 "01401592ffe10017674d401592540a0fd8088000000300" \
260 "8000001e478b175001000468ee3c80, stream-format=(string)avc"
262 #define COMMON_TAGS \
263 "taglist,title=test_title," \
264 "artist=test_artist," \
265 "keywords=\"key1,key2\"," \
266 "description=test_desc"
268 GST_START_TEST (test_common_tags)
270 if (!gst_default_registry_check_feature_version ("qtdemux", 0, 10, 23)) {
271 GST_INFO ("Skipping test, qtdemux either not available or too old");
274 test_tags (COMMON_TAGS, H264_CAPS, "qtmux", "qtdemux");
275 test_tags (COMMON_TAGS, H264_CAPS, "mp4mux", "qtdemux");
276 test_tags (COMMON_TAGS, H264_CAPS, "gppmux", "qtdemux");
281 #define GEO_LOCATION_TAGS \
282 "taglist,geo-location-country=Brazil," \
283 "geo-location-city=\"Campina Grande\"," \
284 "geo-location-sublocation=Bodocongo," \
285 "geo-location-latitude=-12.125," \
286 "geo-location-longitude=56.75," \
287 "geo-location-elevation=327.5"
289 GST_START_TEST (test_geo_location_tags)
291 if (!gst_default_registry_check_feature_version ("qtdemux", 0, 10, 23)) {
292 GST_INFO ("Skipping test, qtdemux either not available or too old");
295 test_tags (GEO_LOCATION_TAGS, H264_CAPS, "qtmux", "qtdemux");
296 test_tags (GEO_LOCATION_TAGS, H264_CAPS, "mp4mux", "qtdemux");
297 test_tags (GEO_LOCATION_TAGS, H264_CAPS, "gppmux", "qtdemux");
304 "taglist,user-rating=(uint)85"
306 GST_START_TEST (test_user_tags)
308 if (!gst_default_registry_check_feature_version ("qtdemux", 0, 10, 23)) {
309 GST_INFO ("Skipping test, qtdemux either not available or too old");
313 test_tags (USER_TAGS, H264_CAPS, "qtmux", "qtdemux");
314 test_tags (USER_TAGS, H264_CAPS, "mp4mux", "qtdemux");
315 test_tags (USER_TAGS, H264_CAPS, "gppmux", "qtdemux");
321 metadata_suite (void)
323 Suite *s = suite_create ("tagschecking");
325 TCase *tc_chain = tcase_create ("general");
327 /* time out after 60s, not the default 3 */
328 tcase_set_timeout (tc_chain, 60);
330 suite_add_tcase (s, tc_chain);
331 tcase_add_test (tc_chain, test_common_tags);
332 tcase_add_test (tc_chain, test_geo_location_tags);
333 tcase_add_test (tc_chain, test_user_tags);
339 main (int argc, char **argv)
343 Suite *s = metadata_suite ();
345 SRunner *sr = srunner_create (s);
347 gst_check_init (&argc, &argv);
349 srunner_run_all (sr, CK_NORMAL);
350 nf = srunner_ntests_failed (sr);