• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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