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.
23 #include <gst/check/gstcheck.h>
24 #include <gst/gstprotection.h>
26 #ifndef GST_PACKAGE_NAME
27 #define GST_PACKAGE_NAME "gstreamer"
30 #ifndef GST_PACKAGE_ORIGIN
31 #define GST_PACKAGE_ORIGIN "https://developer.gnome.org/gstreamer/"
34 static GType gst_protection_test_get_type (void);
36 #define GST_TYPE_PROTECTION_TEST (gst_protection_test_get_type ())
37 #define GST_PROTECTION_TEST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_PROTECTION_TEST, GstProtectionTest))
38 #define GST_PROTECTION_TEST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_PROTECTION_TEST, GstProtectionTestClass))
39 #define GST_IS_PROTECTION_TEST(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_PROTECTION_TEST))
40 #define GST_IS_PROTECTION_TEST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_PROTECTION_TEST))
41 #define GST_PROTECTION_TEST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_PROTECTION_TEST, GstProtectionTestClass))
42 #define GST_PROTECTION_TEST_NAME "protection-test"
44 #define CLEARKEY_SYSTEM_ID "78f32170-d883-11e0-9572-0800200c9a66"
46 typedef struct _GstProtectionTest
53 typedef struct _GstProtectionTestClass
55 GstElementClass parent_class;
56 } GstProtectionTestClass;
58 typedef struct _PluginInitContext
65 static GstStaticPadTemplate gst_decrypt_sink_template =
66 GST_STATIC_PAD_TEMPLATE ("sink",
70 ("application/x-cenc, original-media-type=(string)video/x-h264, "
71 GST_PROTECTION_SYSTEM_ID_CAPS_FIELD "=(string)" CLEARKEY_SYSTEM_ID)
75 gst_protection_test_class_init (GObjectClass * klass)
80 gst_protection_test_base_init (GstProtectionTestClass * klass)
82 GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
84 gst_element_class_add_static_pad_template (element_class,
85 &gst_decrypt_sink_template);
87 gst_element_class_set_metadata (element_class,
88 "Decryptor element for unit tests",
89 GST_ELEMENT_FACTORY_KLASS_DECRYPTOR,
90 "Use in unit tests", "Alex Ashley <alex.ashley@youview.com>");
94 gst_protection_test_get_type (void)
96 static volatile gsize protection_test_type = 0;
98 if (g_once_init_enter (&protection_test_type)) {
100 const GTypeInfo info = {
101 sizeof (GstProtectionTestClass),
102 (GBaseInitFunc) gst_protection_test_base_init, /* base_init */
103 NULL, /* base_finalize */
104 (GClassInitFunc) gst_protection_test_class_init, /* class_init */
105 NULL, /* class_finalize */
106 NULL, /* class_data */
107 sizeof (GstProtectionTest),
109 NULL, /* instance_init */
110 NULL /* value_table */
113 g_type_register_static (GST_TYPE_ELEMENT, "GstProtectionTest", &info,
115 g_once_init_leave (&protection_test_type, type);
117 return protection_test_type;
121 protection_plugin_init_func (GstPlugin * plugin, gpointer user_data)
123 PluginInitContext *context = (PluginInitContext *) user_data;
127 gst_element_register (plugin, context->name, context->rank,
133 protection_create_plugin (GstRegistry * registry, const gchar * name,
137 PluginInitContext context;
140 context.rank = GST_RANK_MARGINAL;
142 ret = gst_plugin_register_static_full (GST_VERSION_MAJOR, /* version */
143 GST_VERSION_MINOR, /* version */
145 "Protection unit test", /* description */
146 protection_plugin_init_func, /* init function */
147 "0.0.0", /* version string */
148 GST_LICENSE_UNKNOWN, /* license */
149 __FILE__, /* source */
150 GST_PACKAGE_NAME, /* package */
151 GST_PACKAGE_ORIGIN, /* origin */
152 &context /* user_data */
160 GstRegistry *registry;
162 registry = gst_registry_get ();
163 protection_create_plugin (registry, GST_PROTECTION_TEST_NAME,
164 GST_TYPE_PROTECTION_TEST);
173 GST_START_TEST (test_decryptor_element_class)
176 const gchar *selected_id;
177 const gchar *sys_ids[] = {
179 "69f908af-4816-46ea-910c-cd5dcccb0a3a",
180 "5e629af5-38da-4063-8977-97ffbd9902d4",
187 list = gst_registry_get_plugin_list (gst_registry_get ());
188 for (walk = list; walk; walk = g_list_next (walk)) {
189 GstPlugin *plugin = (GstPlugin *) walk->data;
190 g_print ("Element %s\n", gst_plugin_get_name (plugin));
194 elem = gst_element_factory_make (GST_PROTECTION_TEST_NAME, NULL);
195 fail_unless (GST_IS_ELEMENT (elem));
197 selected_id = gst_protection_select_system (sys_ids);
198 fail_if (selected_id == NULL);
200 selected_id = gst_protection_select_system (&sys_ids[1]);
201 fail_unless (selected_id == NULL);
203 selected_id = gst_protection_select_system (&sys_ids[3]);
204 fail_unless (selected_id == NULL);
206 gst_object_unref (elem);
211 GST_START_TEST (test_protection_metadata)
213 GstBuffer *buf = NULL;
215 GstBuffer *fetched_iv = NULL, *fetched_key_id = NULL;
216 GstStructure *meta_info;
217 GstProtectionMeta *meta = NULL;
218 const GstMetaInfo *info = NULL;
221 /* Check correct type info is returned */
222 info = gst_protection_meta_get_info ();
223 fail_unless (info != NULL);
224 fail_unless (info->api == GST_PROTECTION_META_API_TYPE);
226 iv = gst_buffer_new_allocate (NULL, 16, NULL);
227 gst_buffer_memset (iv, 0, 'i', 16);
228 ASSERT_MINI_OBJECT_REFCOUNT (iv, "iv", 1);
229 kid = gst_buffer_new_allocate (NULL, 16, NULL);
230 gst_buffer_memset (kid, 0, 'k', 16);
231 ASSERT_MINI_OBJECT_REFCOUNT (kid, "kid", 1);
232 meta_info = gst_structure_new ("application/x-cenc",
233 "encrypted", G_TYPE_BOOLEAN, TRUE,
234 "iv", GST_TYPE_BUFFER, iv,
235 "iv_size", G_TYPE_UINT, 16, "kid", GST_TYPE_BUFFER, kid, NULL);
236 ASSERT_MINI_OBJECT_REFCOUNT (kid, "kid", 2);
237 ASSERT_MINI_OBJECT_REFCOUNT (iv, "iv", 2);
239 buf = gst_buffer_new_allocate (NULL, 1024, NULL);
240 /* Test attaching protection metadata to buffer */
241 meta = gst_buffer_add_protection_meta (buf, meta_info);
242 fail_unless (meta != NULL);
243 /* gst_buffer_new_allocate takes ownership of info GstStructure */
244 ASSERT_MINI_OBJECT_REFCOUNT (buf, "Buffer", 1);
246 /* Test detaching protection metadata from buffer, and check that
247 * contained data is correct */
249 meta = gst_buffer_get_protection_meta (buf);
250 fail_unless (meta != NULL);
251 ASSERT_MINI_OBJECT_REFCOUNT (buf, "Buffer", 1);
252 value = gst_structure_get_value (meta->info, "iv");
253 fail_unless (value != NULL);
254 fetched_iv = gst_value_get_buffer (value);
255 fail_unless (fetched_iv != NULL);
256 fail_unless (gst_buffer_get_size (fetched_iv) == 16);
257 value = gst_structure_get_value (meta->info, "kid");
258 fail_unless (value != NULL);
259 fetched_key_id = gst_value_get_buffer (value);
260 fail_unless (fetched_key_id != NULL);
261 fail_unless (gst_buffer_get_size (fetched_key_id) == 16);
263 gst_buffer_remove_meta (buf, (GstMeta *) meta);
265 /* Check that refcounts are decremented after metadata is freed */
266 ASSERT_MINI_OBJECT_REFCOUNT (buf, "Buffer", 1);
267 ASSERT_MINI_OBJECT_REFCOUNT (iv, "IV", 1);
268 ASSERT_MINI_OBJECT_REFCOUNT (kid, "KID", 1);
270 gst_buffer_unref (buf);
271 gst_buffer_unref (iv);
272 gst_buffer_unref (kid);
278 protection_suite (void)
280 Suite *s = suite_create ("protection library");
281 TCase *tc_chain = tcase_create ("general");
283 suite_add_tcase (s, tc_chain);
284 tcase_add_test (tc_chain, test_decryptor_element_class);
285 tcase_add_test (tc_chain, test_protection_metadata);
286 tcase_add_unchecked_fixture (tc_chain, test_setup, test_teardown);
291 GST_CHECK_MAIN (protection);