1 /* GStreamer
2 *
3 * unit test for kate
4 *
5 * Copyright (C) <2007> Stefan Kost <ensonic@users.sf.net>
6 * Copyright (C) <2008> ogg.k.ogg.k <ogg.k.ogg.k@googlemail.com>
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
17 *
18 * You should have received a copy of the GNU Library General Public
19 * License along with this library; if not, write to the
20 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
22 */
23
24 #include <unistd.h>
25
26 #include <gst/check/gstcheck.h>
27 #include <gst/base/gsttypefindhelper.h>
28
29
30 static const guint8 kate_header_0x80[64] = {
31 0x80, 0x6b, 0x61, 0x74, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x09, 0x00, 0x00, 0x00, 0x20, /* .kate...... ... */
32 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, /* ................ */
33 0x65, 0x6e, 0x5f, 0x47, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* en_GB........... */
34 0x6e, 0x6f, 0x6e, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* none............ */
35 };
36
37 static const guint8 kate_header_0x81[53] = {
38 0x81, 0x6b, 0x61, 0x74, 0x65, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x6c, 0x69, 0x62, /* .kate........lib */
39 0x6b, 0x61, 0x74, 0x65, 0x20, 0x30, 0x2e, 0x31, 0x2e, 0x30, 0x20, 0x28, 0x54, 0x69, 0x67, 0x65, /* kate 0.1.0 (Tige */
40 0x72, 0x29, 0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x54, 0x49, 0x54, 0x4c, 0x45, 0x3d, /* r)........TITLE= */
41 0x54, 0x69, 0x67, 0x65, 0x72, /* Tiger */
42 };
43
44 static const guint8 kate_header_0x8x[10] = {
45 0x80, 0x6b, 0x61, 0x74, 0x65, 0x00, 0x00, 0x00, 0x00
46 };
47
48 static const guint8 kate_header_0x88[11] = {
49 0x88, 0x6b, 0x61, 0x74, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00
50 };
51
52 static const guint8 kate_header_0x00[45] = {
53 0x00, 0xe8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, /* ................ */
54 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x70, 0x6c, 0x61, /* .............pla */
55 0x69, 0x6e, 0x20, 0x6f, 0x6c, 0x64, 0x20, 0x74, 0x65, 0x78, 0x74, 0x08, 0x00 /* in old text.. */
56 };
57
58 static const guint8 kate_header_0x7f[1] = {
59 0x7f
60 };
61
62 static const unsigned char kate_spu[] = {
63 0x00, 0x1b, /* size */
64 0x00, 0x06, /* commands at offset 6 */
65 0x45, /* first line data - 2 pixels of colors 0 and 1 */
66 0x76, /* first line data - 2 pixels of colors 3 and 2 */
67 0x00, 0x00, /* timestamp */
68 0x00, 0x06, /* link to next command sequence - points back to the current one to mark no more */
69 0x06, 0x00, 0x04, 0x00, 0x05, /* pointers to data */
70 0x05, 0x00, 0x30, 0x04, 0x00, 0x10, 0x02, /* area: 3x1 -> 4x2 */
71 0x04, 0x0f, 0xff, /* alpha: color 0 transparent, all others opaque */
72 0x01, /* show */
73 0xff /* end */
74 };
75
76 /* A lot of these taken from the vorbisdec test */
77
78 /* For ease of programming we use globals to keep refs for our floating
79 * src and sink pads we create; otherwise we always have to do get_pad,
80 * get_peer, and then remove references in every test function */
81 static GstPad *mydecsrcpad, *mydecsinkpad;
82 static GstPad *myencsrcpad, *myencsinkpad;
83 static GstPad *myparsesrcpad, *myparsesinkpad;
84 static GstPad *mytagsrcpad, *mytagsinkpad;
85
86 static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
87 GST_PAD_SINK,
88 GST_PAD_ALWAYS,
89 GST_STATIC_CAPS_ANY);
90 static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
91 GST_PAD_SRC,
92 GST_PAD_ALWAYS,
93 GST_STATIC_CAPS_ANY);
94
95 static GList *events = NULL;
96
97 static gboolean
collect_events_func(GstPad * pad,GstObject * parent,GstEvent * event)98 collect_events_func (GstPad * pad, GstObject * parent, GstEvent * event)
99 {
100 GST_LOG ("event: %" GST_PTR_FORMAT, event);
101 events = g_list_append (events, gst_event_ref (event));
102 return gst_pad_event_default (pad, parent, event);
103 }
104
105 static GstElement *
setup_katedec(void)106 setup_katedec (void)
107 {
108 GstElement *katedec;
109
110 GST_DEBUG ("setup_katedec");
111 katedec = gst_check_setup_element ("katedec");
112 mydecsrcpad = gst_check_setup_src_pad (katedec, &srctemplate);
113 mydecsinkpad = gst_check_setup_sink_pad (katedec, &sinktemplate);
114 gst_pad_set_event_function (mydecsinkpad, collect_events_func);
115 gst_pad_set_active (mydecsrcpad, TRUE);
116 gst_pad_set_active (mydecsinkpad, TRUE);
117
118 return katedec;
119 }
120
121 static void
cleanup_katedec(GstElement * katedec)122 cleanup_katedec (GstElement * katedec)
123 {
124 GList *l;
125
126 GST_DEBUG ("cleanup_katedec");
127 gst_element_set_state (katedec, GST_STATE_NULL);
128
129 for (l = events; l != NULL; l = l->next)
130 gst_event_unref (GST_EVENT (l->data));
131 g_list_free (events);
132 events = NULL;
133
134 gst_pad_set_active (mydecsrcpad, FALSE);
135 gst_pad_set_active (mydecsinkpad, FALSE);
136 gst_check_teardown_src_pad (katedec);
137 gst_check_teardown_sink_pad (katedec);
138 gst_check_teardown_element (katedec);
139 }
140
141 static GstElement *
setup_kateenc(void)142 setup_kateenc (void)
143 {
144 GstElement *kateenc;
145
146 GST_DEBUG ("setup_kateenc");
147 kateenc = gst_check_setup_element ("kateenc");
148 myencsrcpad = gst_check_setup_src_pad (kateenc, &srctemplate);
149 myencsinkpad = gst_check_setup_sink_pad (kateenc, &sinktemplate);
150 gst_pad_set_active (myencsrcpad, TRUE);
151 gst_pad_set_active (myencsinkpad, TRUE);
152
153 return kateenc;
154 }
155
156 static void
cleanup_kateenc(GstElement * kateenc)157 cleanup_kateenc (GstElement * kateenc)
158 {
159 GST_DEBUG ("cleanup_kateenc");
160 gst_element_set_state (kateenc, GST_STATE_NULL);
161
162 gst_pad_set_active (myencsrcpad, FALSE);
163 gst_pad_set_active (myencsinkpad, FALSE);
164 gst_check_teardown_src_pad (kateenc);
165 gst_check_teardown_sink_pad (kateenc);
166 gst_check_teardown_element (kateenc);
167 }
168
169 static GstElement *
setup_kateparse(void)170 setup_kateparse (void)
171 {
172 GstElement *kateparse;
173
174 GST_DEBUG ("setup_kateparse");
175 kateparse = gst_check_setup_element ("kateparse");
176 myparsesrcpad = gst_check_setup_src_pad (kateparse, &srctemplate);
177 myparsesinkpad = gst_check_setup_sink_pad (kateparse, &sinktemplate);
178 gst_pad_set_active (myparsesrcpad, TRUE);
179 gst_pad_set_active (myparsesinkpad, TRUE);
180
181 return kateparse;
182 }
183
184 static void
cleanup_kateparse(GstElement * kateparse)185 cleanup_kateparse (GstElement * kateparse)
186 {
187 GST_DEBUG ("cleanup_kateparse");
188 gst_element_set_state (kateparse, GST_STATE_NULL);
189
190 gst_pad_set_active (myparsesrcpad, FALSE);
191 gst_pad_set_active (myparsesinkpad, FALSE);
192 gst_check_teardown_src_pad (kateparse);
193 gst_check_teardown_sink_pad (kateparse);
194 gst_check_teardown_element (kateparse);
195 }
196
197 static GstElement *
setup_katetag(void)198 setup_katetag (void)
199 {
200 GstElement *katetag;
201
202 GST_DEBUG ("setup_katetag");
203 katetag = gst_check_setup_element ("katetag");
204 mytagsrcpad = gst_check_setup_src_pad (katetag, &srctemplate);
205 mytagsinkpad = gst_check_setup_sink_pad (katetag, &sinktemplate);
206 gst_pad_set_active (mytagsrcpad, TRUE);
207 gst_pad_set_active (mytagsinkpad, TRUE);
208
209 return katetag;
210 }
211
212 static void
cleanup_katetag(GstElement * katetag)213 cleanup_katetag (GstElement * katetag)
214 {
215 GST_DEBUG ("cleanup_katetag");
216 gst_element_set_state (katetag, GST_STATE_NULL);
217
218 gst_pad_set_active (mytagsrcpad, FALSE);
219 gst_pad_set_active (mytagsinkpad, FALSE);
220 gst_check_teardown_src_pad (katetag);
221 gst_check_teardown_sink_pad (katetag);
222 gst_check_teardown_element (katetag);
223 }
224
225 static void
check_buffers(guint expected,gboolean headers_in_caps)226 check_buffers (guint expected, gboolean headers_in_caps)
227 {
228 GstBuffer *outbuffer;
229 GstMapInfo info;
230 guint i, num_buffers;
231 const int num_headers = 9;
232 unsigned char packet_type;
233
234 /* check buffers are the type we expect */
235 num_buffers = g_list_length (buffers);
236 fail_unless (num_buffers >= num_headers + expected); /* at least 9 headers, plus a variable number of data packets */
237 for (i = 0; i < num_buffers; ++i) {
238 outbuffer = GST_BUFFER (buffers->data);
239 fail_if (outbuffer == NULL);
240 fail_if (gst_buffer_get_size (outbuffer) == 0);
241
242 assert_equals_int (gst_buffer_map (outbuffer, &info, GST_MAP_READ), TRUE);
243 if (i < num_headers) {
244 /* different headers packets */
245 packet_type = (0x80 | i);
246 fail_unless (info.data[0] == packet_type);
247 /* headers could be in caps, so would have an extra ref */
248 } else if (i == num_buffers - 1) {
249 /* eos data packet */
250 packet_type = 0x7f;
251 fail_unless (info.data[0] == packet_type);
252 } else {
253 /* data packet */
254 packet_type = 0;
255 fail_unless (info.data[0] >= 0 && info.data[0] < 0x7f);
256 }
257 gst_buffer_unmap (outbuffer, &info);
258
259 buffers = g_list_remove (buffers, outbuffer);
260
261 ASSERT_BUFFER_REFCOUNT (outbuffer, "outbuffer", 1);
262 gst_buffer_unref (outbuffer);
263 outbuffer = NULL;
264 }
265 }
266
GST_START_TEST(test_kate_typefind)267 GST_START_TEST (test_kate_typefind)
268 {
269 GstTypeFindProbability prob;
270 const gchar *type;
271 GstBuffer *buf;
272 GstCaps *caps = NULL;
273
274 buf = gst_buffer_new_wrapped (g_memdup (kate_header_0x80,
275 sizeof (kate_header_0x80)), sizeof (kate_header_0x80));
276 GST_BUFFER_OFFSET (buf) = 0;
277
278 caps = gst_type_find_helper_for_buffer (NULL, buf, &prob);
279 fail_unless (caps != NULL);
280 GST_LOG ("Found type: %" GST_PTR_FORMAT, caps);
281
282 type = gst_structure_get_name (gst_caps_get_structure (caps, 0));
283 fail_unless_equals_string (type, "application/x-kate");
284 fail_unless (prob > GST_TYPE_FIND_MINIMUM && prob <= GST_TYPE_FIND_MAXIMUM);
285
286 gst_buffer_unref (buf);
287 gst_caps_unref (caps);
288 }
289
290 GST_END_TEST;
291
GST_START_TEST(test_kate_empty_identification_header)292 GST_START_TEST (test_kate_empty_identification_header)
293 {
294 GstElement *katedec;
295 GstBuffer *inbuffer;
296 GstBus *bus;
297 GstCaps *caps;
298
299 katedec = setup_katedec ();
300 bus = gst_bus_new ();
301
302 fail_unless (gst_element_set_state (katedec,
303 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
304 "could not set to playing");
305
306 caps = gst_caps_new_empty_simple ("subtitle/x-kate");
307 gst_check_setup_events (mydecsrcpad, katedec, caps, GST_FORMAT_TIME);
308 gst_caps_unref (caps);
309
310 inbuffer = gst_buffer_new_and_alloc (0);
311 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
312
313 /* set a bus here so we avoid getting state change messages */
314 gst_element_set_bus (katedec, bus);
315
316 fail_unless_equals_int (gst_pad_push (mydecsrcpad, inbuffer), GST_FLOW_ERROR);
317 /* ... but it ends up being collected on the global buffer list */
318 fail_unless_equals_int (g_list_length (buffers), 0);
319
320 gst_element_set_bus (katedec, NULL);
321
322 /* cleanup */
323 gst_object_unref (GST_OBJECT (bus));
324 cleanup_katedec (katedec);
325 }
326
327 GST_END_TEST;
328
329 /* FIXME: also tests comment header */
GST_START_TEST(test_kate_identification_header)330 GST_START_TEST (test_kate_identification_header)
331 {
332 GstElement *katedec;
333 GstBuffer *inbuffer;
334 GstBus *bus;
335 GstCaps *caps;
336
337 katedec = setup_katedec ();
338 fail_unless (gst_element_set_state (katedec,
339 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
340 "could not set to playing");
341 bus = gst_bus_new ();
342
343 caps = gst_caps_new_empty_simple ("subtitle/x-kate");
344 gst_check_setup_events (mydecsrcpad, katedec, caps, GST_FORMAT_TIME);
345 gst_caps_unref (caps);
346
347 inbuffer = gst_buffer_new_wrapped (g_memdup (kate_header_0x80,
348 sizeof (kate_header_0x80)), sizeof (kate_header_0x80));
349 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
350 gst_buffer_ref (inbuffer);
351
352 gst_element_set_bus (katedec, bus);
353 /* pushing gives away my reference ... */
354 fail_unless (gst_pad_push (mydecsrcpad, inbuffer) == GST_FLOW_OK);
355 /* ... and nothing ends up on the global buffer list */
356 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
357 gst_buffer_unref (inbuffer);
358 fail_unless (g_list_length (buffers) == 0);
359
360 inbuffer = gst_buffer_new_wrapped (g_memdup (kate_header_0x81,
361 sizeof (kate_header_0x81)), sizeof (kate_header_0x81));
362 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
363 gst_buffer_ref (inbuffer);
364
365 /* pushing gives away my reference ... */
366 fail_unless (gst_pad_push (mydecsrcpad, inbuffer) == GST_FLOW_OK);
367 /* ... and nothing ends up on the global buffer list */
368 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
369 gst_buffer_unref (inbuffer);
370 fail_unless (g_list_length (buffers) == 0);
371
372 /* there should've been a tag event */
373 {
374 gboolean found_tags = FALSE;
375 GList *l;
376
377 for (l = events; l != NULL; l = l->next) {
378 GstEvent *event = GST_EVENT (l->data);
379
380 if (GST_EVENT_TYPE (event) == GST_EVENT_TAG) {
381 GstTagList *tags = NULL;
382 gchar *language;
383 gchar *title;
384
385 found_tags = TRUE;
386 gst_event_parse_tag (event, &tags);
387 fail_unless (tags != NULL);
388 fail_unless (gst_tag_list_get_scope (tags) == GST_TAG_SCOPE_STREAM);
389 fail_unless_equals_int (gst_tag_list_get_tag_size (tags,
390 GST_TAG_LANGUAGE_CODE), 1);
391 fail_unless (gst_tag_list_get_string (tags, GST_TAG_LANGUAGE_CODE,
392 &language));
393 fail_unless_equals_string (language, "en");
394 g_free (language);
395 fail_unless_equals_int (gst_tag_list_get_tag_size (tags, "title"), 1);
396 fail_unless (gst_tag_list_get_string (tags, GST_TAG_TITLE, &title));
397 fail_unless_equals_string (title, "Tiger");
398 g_free (title);
399 }
400 }
401 fail_unless (found_tags);
402 }
403
404 /* cleanup */
405 gst_bus_set_flushing (bus, TRUE);
406 gst_element_set_bus (katedec, NULL);
407 gst_object_unref (GST_OBJECT (bus));
408 cleanup_katedec (katedec);
409 }
410
411 GST_END_TEST;
412
GST_START_TEST(test_kate_encode_nothing)413 GST_START_TEST (test_kate_encode_nothing)
414 {
415 GstElement *kateenc;
416
417 kateenc = setup_kateenc ();
418 fail_unless (gst_element_set_state (kateenc,
419 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
420 "could not set to playing");
421
422 fail_unless (gst_pad_push_event (myencsrcpad, gst_event_new_eos ()) == TRUE);
423
424 fail_unless (gst_element_set_state (kateenc,
425 GST_STATE_READY) == GST_STATE_CHANGE_SUCCESS,
426 "could not set to ready");
427
428 /* cleanup */
429 cleanup_kateenc (kateenc);
430 }
431
432 GST_END_TEST;
433
GST_START_TEST(test_kate_encode_empty)434 GST_START_TEST (test_kate_encode_empty)
435 {
436 GstElement *kateenc;
437 GstBuffer *inbuffer;
438 GstBus *bus;
439 GstCaps *caps;
440
441 kateenc = setup_kateenc ();
442 fail_unless (gst_element_set_state (kateenc,
443 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
444 "could not set to playing");
445 bus = gst_bus_new ();
446
447 inbuffer = gst_buffer_new_and_alloc (0);
448 GST_BUFFER_TIMESTAMP (inbuffer) = GST_BUFFER_OFFSET (inbuffer) =
449 1 * GST_SECOND;
450 GST_BUFFER_DURATION (inbuffer) = 5 * GST_SECOND;
451 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
452
453 caps = gst_caps_from_string ("text/x-raw, format=utf8");
454 fail_unless (caps != NULL);
455 gst_check_setup_events (myencsrcpad, kateenc, caps, GST_FORMAT_TIME);
456 gst_caps_unref (caps);
457
458 gst_element_set_bus (kateenc, bus);
459 /* pushing gives away my reference ... */
460 fail_unless (gst_pad_push (myencsrcpad, inbuffer) == GST_FLOW_ERROR);
461
462 fail_unless (gst_pad_push_event (myencsrcpad, gst_event_new_eos ()) == TRUE);
463
464 fail_unless (gst_element_set_state (kateenc,
465 GST_STATE_READY) == GST_STATE_CHANGE_SUCCESS,
466 "could not set to ready");
467
468 gst_element_set_bus (kateenc, NULL);
469
470 /* cleanup */
471 gst_object_unref (GST_OBJECT (bus));
472 cleanup_kateenc (kateenc);
473 }
474
475 GST_END_TEST;
476
GST_START_TEST(test_kate_encode_simple)477 GST_START_TEST (test_kate_encode_simple)
478 {
479 GstElement *kateenc;
480 GstBuffer *inbuffer;
481 GstBus *bus;
482 const gchar *test_string = "";
483 GstCaps *caps;
484
485 kateenc = setup_kateenc ();
486 g_object_set (kateenc, "category", "subtitles", NULL);
487
488 fail_unless (gst_element_set_state (kateenc,
489 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
490 "could not set to playing");
491 bus = gst_bus_new ();
492
493 inbuffer = gst_buffer_new_wrapped (g_memdup (test_string,
494 strlen (test_string) + 1), strlen (test_string) + 1);
495
496 GST_BUFFER_TIMESTAMP (inbuffer) = GST_BUFFER_OFFSET (inbuffer) =
497 1 * GST_SECOND;
498 GST_BUFFER_DURATION (inbuffer) = 5 * GST_SECOND;
499 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
500
501 caps = gst_caps_from_string ("text/x-raw, format=utf8");
502 fail_unless (caps != NULL);
503 gst_check_setup_events (myencsrcpad, kateenc, caps, GST_FORMAT_TIME);
504 gst_caps_unref (caps);
505 gst_buffer_ref (inbuffer);
506
507 gst_element_set_bus (kateenc, bus);
508 /* pushing gives away my reference ... */
509 fail_unless_equals_int (gst_pad_push (myencsrcpad, inbuffer), GST_FLOW_OK);
510 /* ... and nothing ends up on the global buffer list */
511 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
512 gst_buffer_unref (inbuffer);
513 fail_unless (gst_pad_push_event (myencsrcpad, gst_event_new_eos ()) == TRUE);
514
515 fail_unless (gst_element_set_state (kateenc,
516 GST_STATE_READY) == GST_STATE_CHANGE_SUCCESS,
517 "could not set to ready");
518
519 /* at least one data packet and one EOS packet should have been emitted */
520 check_buffers (1 + 1, FALSE);
521
522 /* cleanup */
523 gst_bus_set_flushing (bus, TRUE);
524 gst_element_set_bus (kateenc, NULL);
525 gst_object_unref (GST_OBJECT (bus));
526 cleanup_kateenc (kateenc);
527 gst_check_drop_buffers ();
528 }
529
530 GST_END_TEST;
531
GST_START_TEST(test_kate_encode_spu)532 GST_START_TEST (test_kate_encode_spu)
533 {
534 GstElement *kateenc;
535 GstBuffer *inbuffer;
536 GstBus *bus;
537 GstCaps *caps;
538
539 kateenc = setup_kateenc ();
540 g_object_set (kateenc, "category", "spu-subtitles", NULL);
541
542 fail_unless (gst_element_set_state (kateenc,
543 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
544 "could not set to playing");
545 bus = gst_bus_new ();
546
547 inbuffer = gst_buffer_new_wrapped (g_memdup (kate_spu, sizeof (kate_spu)),
548 sizeof (kate_spu));
549
550 GST_BUFFER_TIMESTAMP (inbuffer) = GST_BUFFER_OFFSET (inbuffer) =
551 1 * GST_SECOND;
552 GST_BUFFER_DURATION (inbuffer) = 5 * GST_SECOND;
553 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
554
555 caps = gst_caps_from_string ("subpicture/x-dvd");
556 fail_unless (caps != NULL);
557 gst_check_setup_events (myencsrcpad, kateenc, caps, GST_FORMAT_TIME);
558 gst_caps_unref (caps);
559 gst_buffer_ref (inbuffer);
560
561 gst_element_set_bus (kateenc, bus);
562 /* pushing gives away my reference ... */
563 fail_unless_equals_int (gst_pad_push (myencsrcpad, inbuffer), GST_FLOW_OK);
564 /* ... and nothing ends up on the global buffer list */
565 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
566 gst_buffer_unref (inbuffer);
567 fail_unless (gst_pad_push_event (myencsrcpad, gst_event_new_eos ()) == TRUE);
568
569 fail_unless (gst_element_set_state (kateenc,
570 GST_STATE_READY) == GST_STATE_CHANGE_SUCCESS,
571 "could not set to ready");
572
573 /* at least one data packet and one EOS packet should have been emitted */
574 check_buffers (2, FALSE);
575
576 /* cleanup */
577 gst_bus_set_flushing (bus, TRUE);
578 gst_element_set_bus (kateenc, NULL);
579 gst_object_unref (GST_OBJECT (bus));
580 cleanup_kateenc (kateenc);
581 gst_check_drop_buffers ();
582 }
583
584 GST_END_TEST;
585
GST_START_TEST(test_kate_encode_keepalives)586 GST_START_TEST (test_kate_encode_keepalives)
587 {
588 GstElement *kateenc;
589 GstBus *bus;
590 guint i, round;
591 GstSegment segment;
592 enum
593 { n_keepalives = 1000 };
594 static const struct
595 {
596 gdouble keepalive_min_time;
597 gint packets;
598 } cfg[3] = {
599 {
600 0.5, n_keepalives}, {
601 2.0, n_keepalives / 2}, {
602 5.0, n_keepalives / 5},};
603
604 for (round = 0; round < 3; ++round) {
605 kateenc = setup_kateenc ();
606 /* doesn't matter here, since we never send a packet */
607 g_object_set (kateenc, "category", "subtitles", NULL);
608 fail_unless (gst_element_set_state (kateenc,
609 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
610 "could not set to playing");
611 bus = gst_bus_new ();
612
613 gst_element_set_bus (kateenc, bus);
614
615 g_object_set (kateenc, "keepalive-min-time", cfg[round].keepalive_min_time,
616 NULL);
617
618 gst_pad_push_event (myencsrcpad, gst_event_new_stream_start ("test"));
619
620 /* the second one here should not emit a keepalive since the time since last packet
621 is less than the keepalive delay */
622 for (i = 1; i <= n_keepalives; ++i) {
623 gint64 t = i * GST_SECOND;
624 gst_segment_init (&segment, GST_FORMAT_TIME);
625 segment.start = t;
626 segment.position = 0;
627 fail_unless (gst_pad_push_event (myencsrcpad,
628 gst_event_new_segment (&segment)) == TRUE);
629 }
630
631 fail_unless (gst_pad_push_event (myencsrcpad,
632 gst_event_new_eos ()) == TRUE);
633
634 fail_unless (gst_element_set_state (kateenc,
635 GST_STATE_READY) == GST_STATE_CHANGE_SUCCESS,
636 "could not set to ready");
637
638 /* at least a number data packet and an EOS packet should have been emitted */
639 check_buffers (cfg[round].packets + 1, FALSE);
640
641 /* cleanup */
642 gst_bus_set_flushing (bus, TRUE);
643 gst_element_set_bus (kateenc, NULL);
644 gst_object_unref (GST_OBJECT (bus));
645 cleanup_kateenc (kateenc);
646 gst_check_drop_buffers ();
647 }
648 }
649
650 GST_END_TEST;
651
652 static void
test_kate_send_headers(GstElement * element,GstPad * pad)653 test_kate_send_headers (GstElement * element, GstPad * pad)
654 {
655 GstBuffer *inbuffer;
656 GstCaps *caps;
657 GstMapInfo info;
658 int i;
659
660 caps = gst_caps_new_simple ("subtitle/x-kate", NULL, NULL);
661 gst_check_setup_events (pad, element, caps, GST_FORMAT_TIME);
662 gst_caps_unref (caps);
663
664 /* push headers */
665 inbuffer = gst_buffer_new_wrapped (g_memdup (kate_header_0x80,
666 sizeof (kate_header_0x80)), sizeof (kate_header_0x80));
667 GST_BUFFER_OFFSET (inbuffer) = GST_BUFFER_OFFSET_END (inbuffer) = 0;
668 fail_unless_equals_int (gst_pad_push (pad, inbuffer), GST_FLOW_OK);
669
670 inbuffer = gst_buffer_new_wrapped (g_memdup (kate_header_0x81,
671 sizeof (kate_header_0x81)), sizeof (kate_header_0x81));
672 GST_BUFFER_OFFSET (inbuffer) = GST_BUFFER_OFFSET_END (inbuffer) = 0;
673 fail_unless_equals_int (gst_pad_push (pad, inbuffer), GST_FLOW_OK);
674
675 for (i = 2; i < 8; ++i) {
676 inbuffer = gst_buffer_new_wrapped (g_memdup (kate_header_0x8x,
677 sizeof (kate_header_0x8x)), sizeof (kate_header_0x8x));
678 fail_if (gst_buffer_map (inbuffer, &info, GST_MAP_WRITE) != TRUE);
679 info.data[0] = 0x80 | i;
680 gst_buffer_unmap (inbuffer, &info);
681 GST_BUFFER_OFFSET (inbuffer) = GST_BUFFER_OFFSET_END (inbuffer) = 0;
682 fail_unless_equals_int (gst_pad_push (pad, inbuffer), GST_FLOW_OK);
683 }
684
685 inbuffer = gst_buffer_new_wrapped (g_memdup (kate_header_0x88,
686 sizeof (kate_header_0x88)), sizeof (kate_header_0x88));
687 GST_BUFFER_OFFSET (inbuffer) = GST_BUFFER_OFFSET_END (inbuffer) = 0;
688 fail_unless_equals_int (gst_pad_push (pad, inbuffer), GST_FLOW_OK);
689 }
690
GST_START_TEST(test_kate_parse)691 GST_START_TEST (test_kate_parse)
692 {
693 GstElement *kateparse;
694 GstBuffer *inbuffer;
695 GstBus *bus;
696
697 kateparse = setup_kateparse ();
698 fail_unless (gst_element_set_state (kateparse,
699 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
700 "could not set to playing");
701 bus = gst_bus_new ();
702
703 gst_element_set_bus (kateparse, bus);
704
705 test_kate_send_headers (kateparse, myparsesrcpad);
706
707 /* push a text packet */
708 inbuffer = gst_buffer_new_wrapped (g_memdup (kate_header_0x00,
709 sizeof (kate_header_0x00)), sizeof (kate_header_0x00));
710 GST_BUFFER_TIMESTAMP (inbuffer) = GST_BUFFER_OFFSET (inbuffer) =
711 1 * GST_SECOND;
712 GST_BUFFER_DURATION (inbuffer) = 5 * GST_SECOND;
713 GST_BUFFER_OFFSET_END (inbuffer) = (GST_BUFFER_TIMESTAMP (inbuffer) << 32); /* granpos */
714 fail_unless_equals_int (gst_pad_push (myparsesrcpad, inbuffer), GST_FLOW_OK);
715
716 /* push a eos packet */
717 inbuffer = gst_buffer_new_wrapped (g_memdup (kate_header_0x7f,
718 sizeof (kate_header_0x7f)), sizeof (kate_header_0x7f));
719 GST_BUFFER_TIMESTAMP (inbuffer) = GST_BUFFER_OFFSET (inbuffer) =
720 6 * GST_SECOND;
721 GST_BUFFER_DURATION (inbuffer) = 0;
722 GST_BUFFER_OFFSET_END (inbuffer) = (GST_BUFFER_TIMESTAMP (inbuffer) << 32); /* granpos */
723 fail_unless_equals_int (gst_pad_push (myparsesrcpad, inbuffer), GST_FLOW_OK);
724
725 /* signal eos */
726 fail_unless (gst_pad_push_event (myparsesrcpad,
727 gst_event_new_eos ()) == TRUE);
728
729 fail_unless (gst_element_set_state (kateparse,
730 GST_STATE_READY) == GST_STATE_CHANGE_SUCCESS,
731 "could not set to ready");
732
733 /* at least one data packet and one EOS packet should have been emitted */
734 check_buffers (2, TRUE);
735
736 /* cleanup */
737 gst_bus_set_flushing (bus, TRUE);
738 gst_element_set_bus (kateparse, NULL);
739 gst_object_unref (GST_OBJECT (bus));
740 cleanup_kateparse (kateparse);
741 g_list_foreach (buffers, (GFunc) gst_buffer_unref, NULL);
742 gst_check_drop_buffers ();
743 }
744
745 GST_END_TEST;
746
GST_START_TEST(test_kate_tag_passthrough)747 GST_START_TEST (test_kate_tag_passthrough)
748 {
749 GstElement *katetag;
750 GstBus *bus;
751 GstBuffer *outbuffer;
752 GList *list;
753 GstMapInfo info;
754
755 katetag = setup_katetag ();
756 fail_unless (gst_element_set_state (katetag,
757 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
758 "could not set to playing");
759 bus = gst_bus_new ();
760
761 gst_element_set_bus (katetag, bus);
762
763 test_kate_send_headers (katetag, mytagsrcpad);
764
765 /* signal eos */
766 fail_unless (gst_pad_push_event (mytagsrcpad, gst_event_new_eos ()) == TRUE);
767
768 fail_unless (gst_element_set_state (katetag,
769 GST_STATE_READY) == GST_STATE_CHANGE_SUCCESS,
770 "could not set to ready");
771
772 /* get the first buffer and check language/category */
773 fail_unless (g_list_length (buffers) >= 2); /* ID header, Vorbis comments header */
774 outbuffer = GST_BUFFER (buffers->data);
775 fail_if (outbuffer == NULL);
776
777 /* check identification header is unchanged */
778 list = g_list_nth (buffers, 0);
779 fail_unless (list != NULL);
780 outbuffer = list->data;
781 fail_if (gst_buffer_map (outbuffer, &info, GST_MAP_READ) != TRUE);
782 fail_unless_equals_int (info.size, sizeof (kate_header_0x80));
783 fail_unless_equals_int (memcmp (info.data, kate_header_0x80,
784 sizeof (kate_header_0x80)), 0);
785 gst_buffer_unmap (outbuffer, &info);
786
787 /* check comment header is unchanged */
788 list = g_list_nth (buffers, 1);
789 fail_unless (list != NULL);
790 outbuffer = list->data;
791 fail_if (gst_buffer_map (outbuffer, &info, GST_MAP_READ) != TRUE);
792 fail_unless_equals_int (info.size, sizeof (kate_header_0x81));
793 fail_unless_equals_int (memcmp (info.data, kate_header_0x81,
794 sizeof (kate_header_0x81)), 0);
795 gst_buffer_unmap (outbuffer, &info);
796
797 /* all headers should have been emitted, but no particular packets */
798 check_buffers (0, TRUE);
799
800 /* cleanup */
801 gst_bus_set_flushing (bus, TRUE);
802 gst_element_set_bus (katetag, NULL);
803 gst_object_unref (GST_OBJECT (bus));
804 cleanup_katetag (katetag);
805 gst_check_drop_buffers ();
806 }
807
808 GST_END_TEST;
809
GST_START_TEST(test_kate_tag)810 GST_START_TEST (test_kate_tag)
811 {
812 GstElement *katetag;
813 GstBus *bus;
814 GstBuffer *outbuffer;
815 GstMapInfo info;
816
817 katetag = setup_katetag ();
818 fail_unless (gst_element_set_state (katetag,
819 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
820 "could not set to playing");
821 bus = gst_bus_new ();
822
823 gst_element_set_bus (katetag, bus);
824
825 g_object_set (katetag, "language", "cy", NULL);
826 g_object_set (katetag, "category", "subtitles", NULL);
827
828 test_kate_send_headers (katetag, mytagsrcpad);
829
830 /* signal eos */
831 fail_unless (gst_pad_push_event (mytagsrcpad, gst_event_new_eos ()) == TRUE);
832
833 fail_unless (gst_element_set_state (katetag,
834 GST_STATE_READY) == GST_STATE_CHANGE_SUCCESS,
835 "could not set to ready");
836
837 /* get the first buffer and check language/category */
838 fail_unless (g_list_length (buffers) >= 1);
839 outbuffer = GST_BUFFER (buffers->data);
840 fail_if (outbuffer == NULL);
841 assert_equals_int (gst_buffer_map (outbuffer, &info, GST_MAP_READ), TRUE);
842 fail_if (info.size != 64);
843 fail_if (strcmp ((const char *) info.data + 32, "cy"));
844 fail_if (strcmp ((const char *) info.data + 48, "subtitles"));
845 gst_buffer_unmap (outbuffer, &info);
846
847 /* all headers should have been emitted, but no particular packets */
848 check_buffers (0, TRUE);
849
850 /* cleanup */
851 gst_bus_set_flushing (bus, TRUE);
852 gst_element_set_bus (katetag, NULL);
853 gst_object_unref (GST_OBJECT (bus));
854 cleanup_katetag (katetag);
855 gst_check_drop_buffers ();
856 }
857
858 GST_END_TEST;
859
860 static Suite *
kate_suite(void)861 kate_suite (void)
862 {
863 Suite *s = suite_create ("kate");
864 TCase *tc_chain = tcase_create ("general");
865
866 suite_add_tcase (s, tc_chain);
867
868 tcase_add_test (tc_chain, test_kate_typefind);
869 tcase_add_test (tc_chain, test_kate_empty_identification_header);
870 tcase_add_test (tc_chain, test_kate_identification_header);
871 tcase_add_test (tc_chain, test_kate_encode_nothing);
872 tcase_add_test (tc_chain, test_kate_encode_empty);
873 tcase_add_test (tc_chain, test_kate_encode_simple);
874 tcase_add_test (tc_chain, test_kate_encode_spu);
875 tcase_add_test (tc_chain, test_kate_encode_keepalives);
876 tcase_add_test (tc_chain, test_kate_parse);
877 tcase_add_test (tc_chain, test_kate_tag_passthrough);
878 tcase_add_test (tc_chain, test_kate_tag);
879
880 return s;
881 }
882
883 GST_CHECK_MAIN (kate);
884