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