1 /* GStreamer GstTagSetter interface unit tests
2 * Copyright (C) 2007 Tim-Philipp Müller <tim centricular net>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
20 #include <gst/check/gstcheck.h>
24 /* some minimal GstTagSetter object */
25 #define GST_TYPE_DUMMY_ENC gst_dummy_enc_get_type()
27 typedef GstElement GstDummyEnc;
28 typedef GstElementClass GstDummyEncClass;
30 static void gst_dummy_enc_add_interfaces (GType enc_type);
32 GType gst_dummy_enc_get_type (void);
33 GST_BOILERPLATE_FULL (GstDummyEnc, gst_dummy_enc, GstElement,
34 GST_TYPE_ELEMENT, gst_dummy_enc_add_interfaces);
37 gst_dummy_enc_add_interfaces (GType enc_type)
39 static const GInterfaceInfo tag_setter_info = { NULL, NULL, NULL };
41 g_type_add_interface_static (enc_type, GST_TYPE_TAG_SETTER, &tag_setter_info);
45 gst_dummy_enc_base_init (gpointer g_class)
50 gst_dummy_enc_class_init (GstDummyEncClass * klass)
55 gst_dummy_enc_init (GstDummyEnc * enc, GstDummyEncClass * klass)
60 tag_list_foreach (const GstTagList * taglist, const gchar * tag, guint * p_num)
64 tag_size = gst_tag_list_get_tag_size (taglist, tag);
65 GST_LOG ("%u+%u tag = %s", *p_num, tag_size, tag);
70 tag_setter_list_length (GstTagSetter * setter)
74 if (gst_tag_setter_get_tag_list (setter) == NULL)
77 gst_tag_list_foreach (gst_tag_setter_get_tag_list (setter),
78 (GstTagForeachFunc) tag_list_foreach, &len);
83 tag_list_length (const GstTagList * tag_list)
90 gst_tag_list_foreach (tag_list, (GstTagForeachFunc) tag_list_foreach, &len);
94 #define assert_tag_setter_list_length(setter,len) \
95 fail_unless_equals_int (tag_setter_list_length(setter), len);
97 GST_START_TEST (test_merge)
100 GstTagList *list1, *list2;
103 enc = g_object_new (GST_TYPE_DUMMY_ENC, NULL);
104 fail_unless (enc != NULL);
106 setter = GST_TAG_SETTER (enc);
108 list1 = gst_tag_list_new ();
109 gst_tag_list_add (list1, GST_TAG_MERGE_APPEND, GST_TAG_ARTIST, "artist1",
111 gst_tag_setter_merge_tags (setter, list1, GST_TAG_MERGE_APPEND);
112 assert_tag_setter_list_length (setter, 1);
114 list2 = gst_tag_list_new ();
115 gst_tag_list_add (list2, GST_TAG_MERGE_APPEND, GST_TAG_ARTIST, "artist2",
116 GST_TAG_TITLE, "title1", NULL);
117 gst_tag_setter_merge_tags (setter, list2, GST_TAG_MERGE_APPEND);
118 assert_tag_setter_list_length (setter, 3);
120 gst_tag_setter_merge_tags (setter, list2, GST_TAG_MERGE_REPLACE_ALL);
121 assert_tag_setter_list_length (setter, 2);
123 gst_tag_setter_merge_tags (setter, list1, GST_TAG_MERGE_REPLACE_ALL);
124 assert_tag_setter_list_length (setter, 1);
126 gst_tag_setter_add_tags (setter, GST_TAG_MERGE_APPEND, GST_TAG_ALBUM, "xyz",
128 assert_tag_setter_list_length (setter, 2);
130 gst_tag_list_free (list2);
131 gst_tag_list_free (list1);
133 g_object_unref (enc);
137 GST_START_TEST (test_merge_modes)
139 GstTagMergeMode mode;
141 for (mode = GST_TAG_MERGE_REPLACE_ALL; mode < GST_TAG_MERGE_COUNT; mode++) {
144 for (i = 0; i < 4; i++) {
146 GstTagSetter *setter;
147 GstTagList *list1, *list2, *merged;
149 enc = g_object_new (GST_TYPE_DUMMY_ENC, NULL);
150 fail_unless (enc != NULL);
152 setter = GST_TAG_SETTER (enc);
153 list1 = gst_tag_list_new ();
154 list2 = gst_tag_list_new ();
159 * i = 3: list1 list2 */
162 gst_tag_list_add (list1, GST_TAG_MERGE_APPEND, GST_TAG_ARTIST,
166 gst_tag_list_add (list2, GST_TAG_MERGE_APPEND, GST_TAG_ARTIST,
170 gst_tag_setter_merge_tags (setter, list1, GST_TAG_MERGE_APPEND);
171 gst_tag_setter_merge_tags (setter, list2, mode);
173 merged = gst_tag_list_merge (list1, list2, mode);
175 fail_unless_equals_int (tag_list_length (gst_tag_setter_get_tag_list
176 (setter)), tag_list_length (merged));
178 gst_tag_list_free (list1);
179 gst_tag_list_free (list2);
180 gst_tag_list_free (merged);
181 gst_object_unref (enc);
187 GST_START_TEST (test_merge_modes_skip_empty)
189 GstTagMergeMode mode;
191 for (mode = GST_TAG_MERGE_REPLACE_ALL; mode < GST_TAG_MERGE_COUNT; mode++) {
194 for (i = 0; i < 2; i++) {
196 GstTagSetter *setter;
197 GstTagList *list1, *list2, *merged;
199 enc = g_object_new (GST_TYPE_DUMMY_ENC, NULL);
200 fail_unless (enc != NULL);
202 setter = GST_TAG_SETTER (enc);
203 list1 = gst_tag_list_new ();
204 list2 = gst_tag_list_new ();
207 gst_tag_list_add (list2, GST_TAG_MERGE_APPEND, GST_TAG_ARTIST,
211 gst_tag_setter_merge_tags (setter, list2, mode);
213 merged = gst_tag_list_merge (list1, list2, mode);
215 fail_unless_equals_int (tag_list_length (gst_tag_setter_get_tag_list
216 (setter)), tag_list_length (merged));
218 gst_tag_list_free (list1);
219 gst_tag_list_free (list2);
220 gst_tag_list_free (merged);
221 gst_object_unref (enc);
226 GST_END_TEST static int spin_and_wait = 1;
227 static int threads_running = 0;
229 #define THREADS_CYCLES 1000
232 test_threads_thread_func1 (gpointer data)
234 GstTagSetter *setter = GST_TAG_SETTER (data);
237 g_atomic_int_inc (&threads_running);
238 while (g_atomic_int_get (&spin_and_wait))
243 for (i = 0; i < THREADS_CYCLES; ++i) {
244 gst_tag_setter_add_tags (setter, GST_TAG_MERGE_APPEND, GST_TAG_ARTIST,
245 "some artist", GST_TAG_TITLE, "some title", GST_TAG_TRACK_NUMBER, 6,
255 test_threads_thread_func2 (gpointer data)
257 GstTagSetter *setter = GST_TAG_SETTER (data);
260 g_atomic_int_inc (&threads_running);
261 while (g_atomic_int_get (&spin_and_wait))
266 for (i = 0; i < THREADS_CYCLES; ++i) {
267 gst_tag_setter_add_tags (setter, GST_TAG_MERGE_PREPEND, GST_TAG_CODEC,
268 "MP42", GST_TAG_COMMENT, "deep insights go here", GST_TAG_TRACK_COUNT,
278 test_threads_thread_func3 (gpointer data)
280 GstTagSetter *setter = GST_TAG_SETTER (data);
283 g_atomic_int_inc (&threads_running);
284 while (g_atomic_int_get (&spin_and_wait))
289 for (i = 0; i < THREADS_CYCLES; ++i) {
290 gst_tag_setter_reset_tags (setter);
299 GST_START_TEST (test_threads)
301 GstTagSetter *setter;
304 setter = GST_TAG_SETTER (g_object_new (GST_TYPE_DUMMY_ENC, NULL));
306 spin_and_wait = TRUE;
307 threads[0] = g_thread_create (test_threads_thread_func1, setter, TRUE, NULL);
308 threads[1] = g_thread_create (test_threads_thread_func2, setter, TRUE, NULL);
309 threads[2] = g_thread_create (test_threads_thread_func3, setter, TRUE, NULL);
311 while (g_atomic_int_get (&threads_running) < 3)
314 g_atomic_int_set (&spin_and_wait, FALSE);
316 g_thread_join (threads[0]);
317 g_thread_join (threads[1]);
318 g_thread_join (threads[2]);
320 g_object_unref (G_OBJECT (setter));
323 GST_END_TEST static Suite *
324 gst_tag_setter_suite (void)
326 Suite *s = suite_create ("GstTagSetter");
327 TCase *tc_chain = tcase_create ("general");
329 suite_add_tcase (s, tc_chain);
330 tcase_add_test (tc_chain, test_merge);
331 tcase_add_test (tc_chain, test_merge_modes);
332 tcase_add_test (tc_chain, test_merge_modes_skip_empty);
333 tcase_add_test (tc_chain, test_threads);
338 GST_CHECK_MAIN (gst_tag_setter);