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