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_memdup (kate_header_0x80, sizeof (kate_header_0x80));
275 GST_BUFFER_OFFSET (buf) = 0;
276
277 caps = gst_type_find_helper_for_buffer (NULL, buf, &prob);
278 fail_unless (caps != NULL);
279 GST_LOG ("Found type: %" GST_PTR_FORMAT, caps);
280
281 type = gst_structure_get_name (gst_caps_get_structure (caps, 0));
282 fail_unless_equals_string (type, "application/x-kate");
283 fail_unless (prob > GST_TYPE_FIND_MINIMUM && prob <= GST_TYPE_FIND_MAXIMUM);
284
285 gst_buffer_unref (buf);
286 gst_caps_unref (caps);
287 }
288
289 GST_END_TEST;
290
GST_START_TEST(test_kate_empty_identification_header)291 GST_START_TEST (test_kate_empty_identification_header)
292 {
293 GstElement *katedec;
294 GstBuffer *inbuffer;
295 GstBus *bus;
296 GstCaps *caps;
297
298 katedec = setup_katedec ();
299 bus = gst_bus_new ();
300
301 fail_unless (gst_element_set_state (katedec,
302 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
303 "could not set to playing");
304
305 caps = gst_caps_new_empty_simple ("subtitle/x-kate");
306 gst_check_setup_events (mydecsrcpad, katedec, caps, GST_FORMAT_TIME);
307 gst_caps_unref (caps);
308
309 inbuffer = gst_buffer_new_and_alloc (0);
310 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
311
312 /* set a bus here so we avoid getting state change messages */
313 gst_element_set_bus (katedec, bus);
314
315 fail_unless_equals_int (gst_pad_push (mydecsrcpad, inbuffer), GST_FLOW_ERROR);
316 /* ... but it ends up being collected on the global buffer list */
317 fail_unless_equals_int (g_list_length (buffers), 0);
318
319 gst_element_set_bus (katedec, NULL);
320
321 /* cleanup */
322 gst_object_unref (GST_OBJECT (bus));
323 cleanup_katedec (katedec);
324 }
325
326 GST_END_TEST;
327
328 /* FIXME: also tests comment header */
GST_START_TEST(test_kate_identification_header)329 GST_START_TEST (test_kate_identification_header)
330 {
331 GstElement *katedec;
332 GstBuffer *inbuffer;
333 GstBus *bus;
334 GstCaps *caps;
335
336 katedec = setup_katedec ();
337 fail_unless (gst_element_set_state (katedec,
338 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
339 "could not set to playing");
340 bus = gst_bus_new ();
341
342 caps = gst_caps_new_empty_simple ("subtitle/x-kate");
343 gst_check_setup_events (mydecsrcpad, katedec, caps, GST_FORMAT_TIME);
344 gst_caps_unref (caps);
345
346 inbuffer =
347 gst_buffer_new_memdup (kate_header_0x80, sizeof (kate_header_0x80));
348 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
349 gst_buffer_ref (inbuffer);
350
351 gst_element_set_bus (katedec, bus);
352 /* pushing gives away my reference ... */
353 fail_unless (gst_pad_push (mydecsrcpad, inbuffer) == GST_FLOW_OK);
354 /* ... and nothing ends up on the global buffer list */
355 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
356 gst_buffer_unref (inbuffer);
357 fail_unless (g_list_length (buffers) == 0);
358
359 inbuffer =
360 gst_buffer_new_memdup (kate_header_0x81, sizeof (kate_header_0x81));
361 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
362 gst_buffer_ref (inbuffer);
363
364 /* pushing gives away my reference ... */
365 fail_unless (gst_pad_push (mydecsrcpad, inbuffer) == GST_FLOW_OK);
366 /* ... and nothing ends up on the global buffer list */
367 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
368 gst_buffer_unref (inbuffer);
369 fail_unless (g_list_length (buffers) == 0);
370
371 /* there should've been a tag event */
372 {
373 gboolean found_tags = FALSE;
374 GList *l;
375
376 for (l = events; l != NULL; l = l->next) {
377 GstEvent *event = GST_EVENT (l->data);
378
379 if (GST_EVENT_TYPE (event) == GST_EVENT_TAG) {
380 GstTagList *tags = NULL;
381 gchar *language;
382 gchar *title;
383
384 found_tags = TRUE;
385 gst_event_parse_tag (event, &tags);
386 fail_unless (tags != NULL);
387 fail_unless (gst_tag_list_get_scope (tags) == GST_TAG_SCOPE_STREAM);
388 fail_unless_equals_int (gst_tag_list_get_tag_size (tags,
389 GST_TAG_LANGUAGE_CODE), 1);
390 fail_unless (gst_tag_list_get_string (tags, GST_TAG_LANGUAGE_CODE,
391 &language));
392 fail_unless_equals_string (language, "en");
393 g_free (language);
394 fail_unless_equals_int (gst_tag_list_get_tag_size (tags, "title"), 1);
395 fail_unless (gst_tag_list_get_string (tags, GST_TAG_TITLE, &title));
396 fail_unless_equals_string (title, "Tiger");
397 g_free (title);
398 }
399 }
400 fail_unless (found_tags);
401 }
402
403 /* cleanup */
404 gst_bus_set_flushing (bus, TRUE);
405 gst_element_set_bus (katedec, NULL);
406 gst_object_unref (GST_OBJECT (bus));
407 cleanup_katedec (katedec);
408 }
409
410 GST_END_TEST;
411
GST_START_TEST(test_kate_encode_nothing)412 GST_START_TEST (test_kate_encode_nothing)
413 {
414 GstElement *kateenc;
415
416 kateenc = setup_kateenc ();
417 fail_unless (gst_element_set_state (kateenc,
418 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
419 "could not set to playing");
420
421 fail_unless (gst_pad_push_event (myencsrcpad, gst_event_new_eos ()) == TRUE);
422
423 fail_unless (gst_element_set_state (kateenc,
424 GST_STATE_READY) == GST_STATE_CHANGE_SUCCESS,
425 "could not set to ready");
426
427 /* cleanup */
428 cleanup_kateenc (kateenc);
429 }
430
431 GST_END_TEST;
432
GST_START_TEST(test_kate_encode_empty)433 GST_START_TEST (test_kate_encode_empty)
434 {
435 GstElement *kateenc;
436 GstBuffer *inbuffer;
437 GstBus *bus;
438 GstCaps *caps;
439
440 kateenc = setup_kateenc ();
441 fail_unless (gst_element_set_state (kateenc,
442 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
443 "could not set to playing");
444 bus = gst_bus_new ();
445
446 inbuffer = gst_buffer_new_and_alloc (0);
447 GST_BUFFER_TIMESTAMP (inbuffer) = GST_BUFFER_OFFSET (inbuffer) =
448 1 * GST_SECOND;
449 GST_BUFFER_DURATION (inbuffer) = 5 * GST_SECOND;
450 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
451
452 caps = gst_caps_from_string ("text/x-raw, format=utf8");
453 fail_unless (caps != NULL);
454 gst_check_setup_events (myencsrcpad, kateenc, caps, GST_FORMAT_TIME);
455 gst_caps_unref (caps);
456
457 gst_element_set_bus (kateenc, bus);
458 /* pushing gives away my reference ... */
459 fail_unless (gst_pad_push (myencsrcpad, inbuffer) == GST_FLOW_ERROR);
460
461 fail_unless (gst_pad_push_event (myencsrcpad, gst_event_new_eos ()) == TRUE);
462
463 fail_unless (gst_element_set_state (kateenc,
464 GST_STATE_READY) == GST_STATE_CHANGE_SUCCESS,
465 "could not set to ready");
466
467 gst_element_set_bus (kateenc, NULL);
468
469 /* cleanup */
470 gst_object_unref (GST_OBJECT (bus));
471 cleanup_kateenc (kateenc);
472 }
473
474 GST_END_TEST;
475
GST_START_TEST(test_kate_encode_simple)476 GST_START_TEST (test_kate_encode_simple)
477 {
478 GstElement *kateenc;
479 GstBuffer *inbuffer;
480 GstBus *bus;
481 const gchar *test_string = "";
482 GstCaps *caps;
483
484 kateenc = setup_kateenc ();
485 g_object_set (kateenc, "category", "subtitles", NULL);
486
487 fail_unless (gst_element_set_state (kateenc,
488 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
489 "could not set to playing");
490 bus = gst_bus_new ();
491
492 inbuffer = gst_buffer_new_memdup (test_string, strlen (test_string) + 1);
493
494 GST_BUFFER_TIMESTAMP (inbuffer) = GST_BUFFER_OFFSET (inbuffer) =
495 1 * GST_SECOND;
496 GST_BUFFER_DURATION (inbuffer) = 5 * GST_SECOND;
497 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
498
499 caps = gst_caps_from_string ("text/x-raw, format=utf8");
500 fail_unless (caps != NULL);
501 gst_check_setup_events (myencsrcpad, kateenc, caps, GST_FORMAT_TIME);
502 gst_caps_unref (caps);
503 gst_buffer_ref (inbuffer);
504
505 gst_element_set_bus (kateenc, bus);
506 /* pushing gives away my reference ... */
507 fail_unless_equals_int (gst_pad_push (myencsrcpad, inbuffer), GST_FLOW_OK);
508 /* ... and nothing ends up on the global buffer list */
509 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
510 gst_buffer_unref (inbuffer);
511 fail_unless (gst_pad_push_event (myencsrcpad, gst_event_new_eos ()) == TRUE);
512
513 fail_unless (gst_element_set_state (kateenc,
514 GST_STATE_READY) == GST_STATE_CHANGE_SUCCESS,
515 "could not set to ready");
516
517 /* at least one data packet and one EOS packet should have been emitted */
518 check_buffers (1 + 1, FALSE);
519
520 /* cleanup */
521 gst_bus_set_flushing (bus, TRUE);
522 gst_element_set_bus (kateenc, NULL);
523 gst_object_unref (GST_OBJECT (bus));
524 cleanup_kateenc (kateenc);
525 gst_check_drop_buffers ();
526 }
527
528 GST_END_TEST;
529
GST_START_TEST(test_kate_encode_spu)530 GST_START_TEST (test_kate_encode_spu)
531 {
532 GstElement *kateenc;
533 GstBuffer *inbuffer;
534 GstBus *bus;
535 GstCaps *caps;
536
537 kateenc = setup_kateenc ();
538 g_object_set (kateenc, "category", "spu-subtitles", NULL);
539
540 fail_unless (gst_element_set_state (kateenc,
541 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
542 "could not set to playing");
543 bus = gst_bus_new ();
544
545 inbuffer = gst_buffer_new_memdup (kate_spu, sizeof (kate_spu));
546
547 GST_BUFFER_TIMESTAMP (inbuffer) = GST_BUFFER_OFFSET (inbuffer) =
548 1 * GST_SECOND;
549 GST_BUFFER_DURATION (inbuffer) = 5 * GST_SECOND;
550 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
551
552 caps = gst_caps_from_string ("subpicture/x-dvd");
553 fail_unless (caps != NULL);
554 gst_check_setup_events (myencsrcpad, kateenc, caps, GST_FORMAT_TIME);
555 gst_caps_unref (caps);
556 gst_buffer_ref (inbuffer);
557
558 gst_element_set_bus (kateenc, bus);
559 /* pushing gives away my reference ... */
560 fail_unless_equals_int (gst_pad_push (myencsrcpad, inbuffer), GST_FLOW_OK);
561 /* ... and nothing ends up on the global buffer list */
562 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
563 gst_buffer_unref (inbuffer);
564 fail_unless (gst_pad_push_event (myencsrcpad, gst_event_new_eos ()) == TRUE);
565
566 fail_unless (gst_element_set_state (kateenc,
567 GST_STATE_READY) == GST_STATE_CHANGE_SUCCESS,
568 "could not set to ready");
569
570 /* at least one data packet and one EOS packet should have been emitted */
571 check_buffers (2, FALSE);
572
573 /* cleanup */
574 gst_bus_set_flushing (bus, TRUE);
575 gst_element_set_bus (kateenc, NULL);
576 gst_object_unref (GST_OBJECT (bus));
577 cleanup_kateenc (kateenc);
578 gst_check_drop_buffers ();
579 }
580
581 GST_END_TEST;
582
GST_START_TEST(test_kate_encode_keepalives)583 GST_START_TEST (test_kate_encode_keepalives)
584 {
585 GstElement *kateenc;
586 GstBus *bus;
587 guint i, round;
588 GstSegment segment;
589 enum
590 { n_keepalives = 1000 };
591 static const struct
592 {
593 gdouble keepalive_min_time;
594 gint packets;
595 } cfg[3] = {
596 {
597 0.5, n_keepalives}, {
598 2.0, n_keepalives / 2}, {
599 5.0, n_keepalives / 5},};
600
601 for (round = 0; round < 3; ++round) {
602 kateenc = setup_kateenc ();
603 /* doesn't matter here, since we never send a packet */
604 g_object_set (kateenc, "category", "subtitles", NULL);
605 fail_unless (gst_element_set_state (kateenc,
606 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
607 "could not set to playing");
608 bus = gst_bus_new ();
609
610 gst_element_set_bus (kateenc, bus);
611
612 g_object_set (kateenc, "keepalive-min-time", cfg[round].keepalive_min_time,
613 NULL);
614
615 gst_pad_push_event (myencsrcpad, gst_event_new_stream_start ("test"));
616
617 /* the second one here should not emit a keepalive since the time since last packet
618 is less than the keepalive delay */
619 for (i = 1; i <= n_keepalives; ++i) {
620 gint64 t = i * GST_SECOND;
621 gst_segment_init (&segment, GST_FORMAT_TIME);
622 segment.start = t;
623 segment.position = 0;
624 fail_unless (gst_pad_push_event (myencsrcpad,
625 gst_event_new_segment (&segment)) == TRUE);
626 }
627
628 fail_unless (gst_pad_push_event (myencsrcpad,
629 gst_event_new_eos ()) == TRUE);
630
631 fail_unless (gst_element_set_state (kateenc,
632 GST_STATE_READY) == GST_STATE_CHANGE_SUCCESS,
633 "could not set to ready");
634
635 /* at least a number data packet and an EOS packet should have been emitted */
636 check_buffers (cfg[round].packets + 1, FALSE);
637
638 /* cleanup */
639 gst_bus_set_flushing (bus, TRUE);
640 gst_element_set_bus (kateenc, NULL);
641 gst_object_unref (GST_OBJECT (bus));
642 cleanup_kateenc (kateenc);
643 gst_check_drop_buffers ();
644 }
645 }
646
647 GST_END_TEST;
648
649 static void
test_kate_send_headers(GstElement * element,GstPad * pad)650 test_kate_send_headers (GstElement * element, GstPad * pad)
651 {
652 GstBuffer *inbuffer;
653 GstCaps *caps;
654 GstMapInfo info;
655 int i;
656
657 caps = gst_caps_new_simple ("subtitle/x-kate", NULL, NULL);
658 gst_check_setup_events (pad, element, caps, GST_FORMAT_TIME);
659 gst_caps_unref (caps);
660
661 /* push headers */
662 inbuffer =
663 gst_buffer_new_memdup (kate_header_0x80, sizeof (kate_header_0x80));
664 GST_BUFFER_OFFSET (inbuffer) = GST_BUFFER_OFFSET_END (inbuffer) = 0;
665 fail_unless_equals_int (gst_pad_push (pad, inbuffer), GST_FLOW_OK);
666
667 inbuffer =
668 gst_buffer_new_memdup (kate_header_0x81, sizeof (kate_header_0x81));
669 GST_BUFFER_OFFSET (inbuffer) = GST_BUFFER_OFFSET_END (inbuffer) = 0;
670 fail_unless_equals_int (gst_pad_push (pad, inbuffer), GST_FLOW_OK);
671
672 for (i = 2; i < 8; ++i) {
673 inbuffer =
674 gst_buffer_new_memdup (kate_header_0x8x, sizeof (kate_header_0x8x));
675 fail_if (gst_buffer_map (inbuffer, &info, GST_MAP_WRITE) != TRUE);
676 info.data[0] = 0x80 | i;
677 gst_buffer_unmap (inbuffer, &info);
678 GST_BUFFER_OFFSET (inbuffer) = GST_BUFFER_OFFSET_END (inbuffer) = 0;
679 fail_unless_equals_int (gst_pad_push (pad, inbuffer), GST_FLOW_OK);
680 }
681
682 inbuffer =
683 gst_buffer_new_memdup (kate_header_0x88, sizeof (kate_header_0x88));
684 GST_BUFFER_OFFSET (inbuffer) = GST_BUFFER_OFFSET_END (inbuffer) = 0;
685 fail_unless_equals_int (gst_pad_push (pad, inbuffer), GST_FLOW_OK);
686 }
687
GST_START_TEST(test_kate_parse)688 GST_START_TEST (test_kate_parse)
689 {
690 GstElement *kateparse;
691 GstBuffer *inbuffer;
692 GstBus *bus;
693
694 kateparse = setup_kateparse ();
695 fail_unless (gst_element_set_state (kateparse,
696 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
697 "could not set to playing");
698 bus = gst_bus_new ();
699
700 gst_element_set_bus (kateparse, bus);
701
702 test_kate_send_headers (kateparse, myparsesrcpad);
703
704 /* push a text packet */
705 inbuffer =
706 gst_buffer_new_memdup (kate_header_0x00, sizeof (kate_header_0x00));
707 GST_BUFFER_TIMESTAMP (inbuffer) = GST_BUFFER_OFFSET (inbuffer) =
708 1 * GST_SECOND;
709 GST_BUFFER_DURATION (inbuffer) = 5 * GST_SECOND;
710 GST_BUFFER_OFFSET_END (inbuffer) = (GST_BUFFER_TIMESTAMP (inbuffer) << 32); /* granpos */
711 fail_unless_equals_int (gst_pad_push (myparsesrcpad, inbuffer), GST_FLOW_OK);
712
713 /* push a eos packet */
714 inbuffer =
715 gst_buffer_new_memdup (kate_header_0x7f, sizeof (kate_header_0x7f));
716 GST_BUFFER_TIMESTAMP (inbuffer) = GST_BUFFER_OFFSET (inbuffer) =
717 6 * GST_SECOND;
718 GST_BUFFER_DURATION (inbuffer) = 0;
719 GST_BUFFER_OFFSET_END (inbuffer) = (GST_BUFFER_TIMESTAMP (inbuffer) << 32); /* granpos */
720 fail_unless_equals_int (gst_pad_push (myparsesrcpad, inbuffer), GST_FLOW_OK);
721
722 /* signal eos */
723 fail_unless (gst_pad_push_event (myparsesrcpad,
724 gst_event_new_eos ()) == TRUE);
725
726 fail_unless (gst_element_set_state (kateparse,
727 GST_STATE_READY) == GST_STATE_CHANGE_SUCCESS,
728 "could not set to ready");
729
730 /* at least one data packet and one EOS packet should have been emitted */
731 check_buffers (2, TRUE);
732
733 /* cleanup */
734 gst_bus_set_flushing (bus, TRUE);
735 gst_element_set_bus (kateparse, NULL);
736 gst_object_unref (GST_OBJECT (bus));
737 cleanup_kateparse (kateparse);
738 g_list_foreach (buffers, (GFunc) gst_buffer_unref, NULL);
739 gst_check_drop_buffers ();
740 }
741
742 GST_END_TEST;
743
GST_START_TEST(test_kate_tag_passthrough)744 GST_START_TEST (test_kate_tag_passthrough)
745 {
746 GstElement *katetag;
747 GstBus *bus;
748 GstBuffer *outbuffer;
749 GList *list;
750 GstMapInfo info;
751
752 katetag = setup_katetag ();
753 fail_unless (gst_element_set_state (katetag,
754 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
755 "could not set to playing");
756 bus = gst_bus_new ();
757
758 gst_element_set_bus (katetag, bus);
759
760 test_kate_send_headers (katetag, mytagsrcpad);
761
762 /* signal eos */
763 fail_unless (gst_pad_push_event (mytagsrcpad, gst_event_new_eos ()) == TRUE);
764
765 fail_unless (gst_element_set_state (katetag,
766 GST_STATE_READY) == GST_STATE_CHANGE_SUCCESS,
767 "could not set to ready");
768
769 /* get the first buffer and check language/category */
770 fail_unless (g_list_length (buffers) >= 2); /* ID header, Vorbis comments header */
771 outbuffer = GST_BUFFER (buffers->data);
772 fail_if (outbuffer == NULL);
773
774 /* check identification header is unchanged */
775 list = g_list_nth (buffers, 0);
776 fail_unless (list != NULL);
777 outbuffer = list->data;
778 fail_if (gst_buffer_map (outbuffer, &info, GST_MAP_READ) != TRUE);
779 fail_unless_equals_int (info.size, sizeof (kate_header_0x80));
780 fail_unless_equals_int (memcmp (info.data, kate_header_0x80,
781 sizeof (kate_header_0x80)), 0);
782 gst_buffer_unmap (outbuffer, &info);
783
784 /* check comment header is unchanged */
785 list = g_list_nth (buffers, 1);
786 fail_unless (list != NULL);
787 outbuffer = list->data;
788 fail_if (gst_buffer_map (outbuffer, &info, GST_MAP_READ) != TRUE);
789 fail_unless_equals_int (info.size, sizeof (kate_header_0x81));
790 fail_unless_equals_int (memcmp (info.data, kate_header_0x81,
791 sizeof (kate_header_0x81)), 0);
792 gst_buffer_unmap (outbuffer, &info);
793
794 /* all headers should have been emitted, but no particular packets */
795 check_buffers (0, TRUE);
796
797 /* cleanup */
798 gst_bus_set_flushing (bus, TRUE);
799 gst_element_set_bus (katetag, NULL);
800 gst_object_unref (GST_OBJECT (bus));
801 cleanup_katetag (katetag);
802 gst_check_drop_buffers ();
803 }
804
805 GST_END_TEST;
806
GST_START_TEST(test_kate_tag)807 GST_START_TEST (test_kate_tag)
808 {
809 GstElement *katetag;
810 GstBus *bus;
811 GstBuffer *outbuffer;
812 GstMapInfo info;
813
814 katetag = setup_katetag ();
815 fail_unless (gst_element_set_state (katetag,
816 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
817 "could not set to playing");
818 bus = gst_bus_new ();
819
820 gst_element_set_bus (katetag, bus);
821
822 g_object_set (katetag, "language", "cy", NULL);
823 g_object_set (katetag, "category", "subtitles", NULL);
824
825 test_kate_send_headers (katetag, mytagsrcpad);
826
827 /* signal eos */
828 fail_unless (gst_pad_push_event (mytagsrcpad, gst_event_new_eos ()) == TRUE);
829
830 fail_unless (gst_element_set_state (katetag,
831 GST_STATE_READY) == GST_STATE_CHANGE_SUCCESS,
832 "could not set to ready");
833
834 /* get the first buffer and check language/category */
835 fail_unless (g_list_length (buffers) >= 1);
836 outbuffer = GST_BUFFER (buffers->data);
837 fail_if (outbuffer == NULL);
838 assert_equals_int (gst_buffer_map (outbuffer, &info, GST_MAP_READ), TRUE);
839 fail_if (info.size != 64);
840 fail_if (strcmp ((const char *) info.data + 32, "cy"));
841 fail_if (strcmp ((const char *) info.data + 48, "subtitles"));
842 gst_buffer_unmap (outbuffer, &info);
843
844 /* all headers should have been emitted, but no particular packets */
845 check_buffers (0, TRUE);
846
847 /* cleanup */
848 gst_bus_set_flushing (bus, TRUE);
849 gst_element_set_bus (katetag, NULL);
850 gst_object_unref (GST_OBJECT (bus));
851 cleanup_katetag (katetag);
852 gst_check_drop_buffers ();
853 }
854
855 GST_END_TEST;
856
857 static Suite *
kate_suite(void)858 kate_suite (void)
859 {
860 Suite *s = suite_create ("kate");
861 TCase *tc_chain = tcase_create ("general");
862
863 suite_add_tcase (s, tc_chain);
864
865 tcase_add_test (tc_chain, test_kate_typefind);
866 tcase_add_test (tc_chain, test_kate_empty_identification_header);
867 tcase_add_test (tc_chain, test_kate_identification_header);
868 tcase_add_test (tc_chain, test_kate_encode_nothing);
869 tcase_add_test (tc_chain, test_kate_encode_empty);
870 tcase_add_test (tc_chain, test_kate_encode_simple);
871 tcase_add_test (tc_chain, test_kate_encode_spu);
872 tcase_add_test (tc_chain, test_kate_encode_keepalives);
873 tcase_add_test (tc_chain, test_kate_parse);
874 tcase_add_test (tc_chain, test_kate_tag_passthrough);
875 tcase_add_test (tc_chain, test_kate_tag);
876
877 return s;
878 }
879
880 GST_CHECK_MAIN (kate);
881