3 * Unit tests for protection library.
5 * Copyright (C) <2015> YouView TV Ltd.
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
26 #include <gst/check/gstcheck.h>
27 #include <gst/gstprotection.h>
29 #ifndef GST_PACKAGE_NAME
30 #define GST_PACKAGE_NAME "gstreamer"
33 #ifndef GST_PACKAGE_ORIGIN
34 #define GST_PACKAGE_ORIGIN "https://developer.gnome.org/gstreamer/"
37 static GType gst_protection_test_get_type (void);
39 #define GST_TYPE_PROTECTION_TEST (gst_protection_test_get_type ())
40 #define GST_PROTECTION_TEST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_PROTECTION_TEST, GstProtectionTest))
41 #define GST_PROTECTION_TEST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_PROTECTION_TEST, GstProtectionTestClass))
42 #define GST_IS_PROTECTION_TEST(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_PROTECTION_TEST))
43 #define GST_IS_PROTECTION_TEST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_PROTECTION_TEST))
44 #define GST_PROTECTION_TEST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_PROTECTION_TEST, GstProtectionTestClass))
45 #define GST_PROTECTION_TEST_NAME "protection-test"
47 #define CLEARKEY_SYSTEM_ID "78f32170-d883-11e0-9572-0800200c9a66"
49 typedef struct _GstProtectionTest
56 typedef struct _GstProtectionTestClass
58 GstElementClass parent_class;
59 } GstProtectionTestClass;
61 typedef struct _PluginInitContext
68 static GstStaticPadTemplate gst_decrypt_sink_template =
69 GST_STATIC_PAD_TEMPLATE ("sink",
73 ("application/x-cenc, original-media-type=(string)video/x-h264, "
74 GST_PROTECTION_SYSTEM_ID_CAPS_FIELD "=(string)" CLEARKEY_SYSTEM_ID)
78 gst_protection_test_class_init (GObjectClass * klass)
83 gst_protection_test_base_init (GstProtectionTestClass * klass)
85 GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
87 gst_element_class_add_static_pad_template (element_class,
88 &gst_decrypt_sink_template);
90 gst_element_class_set_metadata (element_class,
91 "Decryptor element for unit tests",
92 GST_ELEMENT_FACTORY_KLASS_DECRYPTOR,
93 "Use in unit tests", "Alex Ashley <alex.ashley@youview.com>");
97 gst_protection_test_get_type (void)
99 static volatile gsize protection_test_type = 0;
101 if (g_once_init_enter (&protection_test_type)) {
103 const GTypeInfo info = {
104 sizeof (GstProtectionTestClass),
105 (GBaseInitFunc) gst_protection_test_base_init, /* base_init */
106 NULL, /* base_finalize */
107 (GClassInitFunc) gst_protection_test_class_init, /* class_init */
108 NULL, /* class_finalize */
109 NULL, /* class_data */
110 sizeof (GstProtectionTest),
112 NULL, /* instance_init */
113 NULL /* value_table */
116 g_type_register_static (GST_TYPE_ELEMENT, "GstProtectionTest", &info,
118 g_once_init_leave (&protection_test_type, type);
120 return protection_test_type;
124 protection_plugin_init_func (GstPlugin * plugin, gpointer user_data)
126 PluginInitContext *context = (PluginInitContext *) user_data;
130 gst_element_register (plugin, context->name, context->rank,
136 protection_create_plugin (GstRegistry * registry, const gchar * name,
140 PluginInitContext context;
143 context.rank = GST_RANK_MARGINAL;
145 ret = gst_plugin_register_static_full (GST_VERSION_MAJOR, /* version */
146 GST_VERSION_MINOR, /* version */
148 "Protection unit test", /* description */
149 protection_plugin_init_func, /* init function */
150 "0.0.0", /* version string */
151 GST_LICENSE_UNKNOWN, /* license */
152 __FILE__, /* source */
153 GST_PACKAGE_NAME, /* package */
154 GST_PACKAGE_ORIGIN, /* origin */
155 &context /* user_data */
163 GstRegistry *registry;
165 registry = gst_registry_get ();
166 protection_create_plugin (registry, GST_PROTECTION_TEST_NAME,
167 GST_TYPE_PROTECTION_TEST);
176 GST_START_TEST (test_decryptor_element_class)
179 const gchar *selected_id;
180 const gchar *sys_ids[] = {
182 "69f908af-4816-46ea-910c-cd5dcccb0a3a",
183 "5e629af5-38da-4063-8977-97ffbd9902d4",
190 list = gst_registry_get_plugin_list (gst_registry_get ());
191 for (walk = list; walk; walk = g_list_next (walk)) {
192 GstPlugin *plugin = (GstPlugin *) walk->data;
193 g_print ("Element %s\n", gst_plugin_get_name (plugin));
197 elem = gst_element_factory_make (GST_PROTECTION_TEST_NAME, NULL);
198 fail_unless (GST_IS_ELEMENT (elem));
200 selected_id = gst_protection_select_system (sys_ids);
201 fail_if (selected_id == NULL);
203 selected_id = gst_protection_select_system (&sys_ids[1]);
204 fail_unless (selected_id == NULL);
206 selected_id = gst_protection_select_system (&sys_ids[3]);
207 fail_unless (selected_id == NULL);
209 gst_object_unref (elem);
214 GST_START_TEST (test_protection_metadata)
216 GstBuffer *buf = NULL;
218 GstBuffer *fetched_iv = NULL, *fetched_key_id = NULL;
219 GstStructure *meta_info;
220 GstProtectionMeta *meta = NULL;
221 const GstMetaInfo *info = NULL;
224 /* Check correct type info is returned */
225 info = gst_protection_meta_get_info ();
226 fail_unless (info != NULL);
227 fail_unless (info->api == GST_PROTECTION_META_API_TYPE);
229 iv = gst_buffer_new_allocate (NULL, 16, NULL);
230 gst_buffer_memset (iv, 0, 'i', 16);
231 ASSERT_MINI_OBJECT_REFCOUNT (iv, "iv", 1);
232 kid = gst_buffer_new_allocate (NULL, 16, NULL);
233 gst_buffer_memset (kid, 0, 'k', 16);
234 ASSERT_MINI_OBJECT_REFCOUNT (kid, "kid", 1);
235 meta_info = gst_structure_new ("application/x-cenc",
236 "encrypted", G_TYPE_BOOLEAN, TRUE,
237 "iv", GST_TYPE_BUFFER, iv,
238 "iv_size", G_TYPE_UINT, 16, "kid", GST_TYPE_BUFFER, kid, NULL);
239 ASSERT_MINI_OBJECT_REFCOUNT (kid, "kid", 2);
240 ASSERT_MINI_OBJECT_REFCOUNT (iv, "iv", 2);
242 buf = gst_buffer_new_allocate (NULL, 1024, NULL);
243 /* Test attaching protection metadata to buffer */
244 meta = gst_buffer_add_protection_meta (buf, meta_info);
245 fail_unless (meta != NULL);
246 /* gst_buffer_new_allocate takes ownership of info GstStructure */
247 ASSERT_MINI_OBJECT_REFCOUNT (buf, "Buffer", 1);
249 /* Test detaching protection metadata from buffer, and check that
250 * contained data is correct */
252 meta = gst_buffer_get_protection_meta (buf);
253 fail_unless (meta != NULL);
254 ASSERT_MINI_OBJECT_REFCOUNT (buf, "Buffer", 1);
255 value = gst_structure_get_value (meta->info, "iv");
256 fail_unless (value != NULL);
257 fetched_iv = gst_value_get_buffer (value);
258 fail_unless (fetched_iv != NULL);
259 fail_unless (gst_buffer_get_size (fetched_iv) == 16);
260 value = gst_structure_get_value (meta->info, "kid");
261 fail_unless (value != NULL);
262 fetched_key_id = gst_value_get_buffer (value);
263 fail_unless (fetched_key_id != NULL);
264 fail_unless (gst_buffer_get_size (fetched_key_id) == 16);
266 gst_buffer_remove_meta (buf, (GstMeta *) meta);
268 /* Check that refcounts are decremented after metadata is freed */
269 ASSERT_MINI_OBJECT_REFCOUNT (buf, "Buffer", 1);
270 ASSERT_MINI_OBJECT_REFCOUNT (iv, "IV", 1);
271 ASSERT_MINI_OBJECT_REFCOUNT (kid, "KID", 1);
273 gst_buffer_unref (buf);
274 gst_buffer_unref (iv);
275 gst_buffer_unref (kid);
281 protection_suite (void)
283 Suite *s = suite_create ("protection library");
284 TCase *tc_chain = tcase_create ("general");
286 suite_add_tcase (s, tc_chain);
287 tcase_add_test (tc_chain, test_decryptor_element_class);
288 tcase_add_test (tc_chain, test_protection_metadata);
289 tcase_add_unchecked_fixture (tc_chain, test_setup, test_teardown);
294 GST_CHECK_MAIN (protection);