1 /* GStreamer
2 *
3 * unit test for avisubtitle
4 *
5 * Copyright (C) <2007> Thijs Vermeir <thijsvermeir@gmail.com>
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
16 *
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
21 */
22 /* Element-Checklist-Version: 5 */
23
24 #include <gst/gst.h>
25 #include <gst/check/gstcheck.h>
26
27 GstPad *mysinkpad;
28 GstPad *mysrcpad;
29
30 guint8 avisub_utf_8_with_bom[] = {
31 0x47, 0x41, 0x42, 0x32, 0x00, 0x02, 0x00, 0x10,
32 0x00, 0x00, 0x00, 0x45, 0x00, 0x6e, 0x00, 0x67,
33 0x00, 0x6c, 0x00, 0x69, 0x00, 0x73, 0x00, 0x68,
34 0x00, 0x00, 0x00, 0x04, 0x00, 0x8e, 0x00, 0x00,
35 0x00, 0xef, 0xbb, 0xbf, 0x31, 0x0d, 0x0a, 0x30,
36 0x30, 0x3a, 0x30, 0x30, 0x3a, 0x30, 0x30, 0x2c,
37 0x31, 0x30, 0x30, 0x20, 0x2d, 0x2d, 0x3e, 0x20,
38 0x30, 0x30, 0x3a, 0x30, 0x30, 0x3a, 0x30, 0x32,
39 0x2c, 0x30, 0x30, 0x30, 0x0d, 0x0a, 0x3c, 0x62,
40 0x3e, 0x41, 0x6e, 0x20, 0x55, 0x54, 0x46, 0x38,
41 0x20, 0x53, 0x75, 0x62, 0x74, 0x69, 0x74, 0x6c,
42 0x65, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x42,
43 0x4f, 0x4d, 0x3c, 0x2f, 0x62, 0x3e, 0x0d, 0x0a,
44 0x0d, 0x0a, 0x32, 0x0d, 0x0a, 0x30, 0x30, 0x3a,
45 0x30, 0x30, 0x3a, 0x30, 0x32, 0x2c, 0x31, 0x30,
46 0x30, 0x20, 0x2d, 0x2d, 0x3e, 0x20, 0x30, 0x30,
47 0x3a, 0x30, 0x30, 0x3a, 0x30, 0x34, 0x2c, 0x30,
48 0x30, 0x30, 0x0d, 0x0a, 0x53, 0x6f, 0x6d, 0x65,
49 0x74, 0x68, 0x69, 0x6e, 0x67, 0x20, 0x6e, 0x6f,
50 0x6e, 0x41, 0x53, 0x43, 0x49, 0x49, 0x20, 0x2d,
51 0x20, 0xc2, 0xb5, 0xc3, 0xb6, 0xc3, 0xa4, 0xc3,
52 0xbc, 0xc3, 0x9f, 0x0d, 0x0a, 0x0d, 0x0a
53 };
54
55 static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
56 GST_PAD_SINK,
57 GST_PAD_ALWAYS,
58 GST_STATIC_CAPS ("application/x-subtitle")
59 );
60
61 static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
62 GST_PAD_SRC,
63 GST_PAD_ALWAYS,
64 GST_STATIC_CAPS ("application/x-subtitle-avi")
65 );
66
67 static GstElement *
setup_avisubtitle(void)68 setup_avisubtitle (void)
69 {
70 GstElement *avisubtitle;
71 GstCaps *srccaps;
72
73 GST_DEBUG ("setup_avisubtitle");
74 avisubtitle = gst_check_setup_element ("avisubtitle");
75 mysinkpad = gst_check_setup_sink_pad (avisubtitle, &sink_template);
76 mysrcpad = gst_check_setup_src_pad (avisubtitle, &src_template);
77 gst_pad_set_active (mysinkpad, TRUE);
78 gst_pad_set_active (mysrcpad, TRUE);
79 srccaps = gst_caps_new_empty_simple ("application/x-subtitle-avi");
80 gst_check_setup_events (mysrcpad, avisubtitle, srccaps, GST_FORMAT_TIME);
81 gst_caps_unref (srccaps);
82 return avisubtitle;
83 }
84
85 static void
cleanup_avisubtitle(GstElement * avisubtitle)86 cleanup_avisubtitle (GstElement * avisubtitle)
87 {
88 gst_pad_set_active (mysinkpad, FALSE);
89 gst_pad_set_active (mysrcpad, FALSE);
90 gst_check_teardown_sink_pad (avisubtitle);
91 gst_check_teardown_src_pad (avisubtitle);
92 gst_check_teardown_element (avisubtitle);
93 }
94
95 static void
check_wrong_buffer(guint8 * data,guint length)96 check_wrong_buffer (guint8 * data, guint length)
97 {
98 GstBuffer *buffer = gst_buffer_new_allocate (NULL, length, 0);
99 GstElement *avisubtitle = setup_avisubtitle ();
100
101 gst_buffer_fill (buffer, 0, data, length);
102 fail_unless (gst_element_set_state (avisubtitle,
103 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
104 "could not set to playing");
105 gst_buffer_ref (buffer);
106 ASSERT_BUFFER_REFCOUNT (buffer, "inbuffer", 2);
107 /* push the broken buffer */
108 fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_ERROR,
109 "accepted a broken buffer");
110 /* check if we have unreffed this buffer on failure */
111 ASSERT_BUFFER_REFCOUNT (buffer, "inbuffer", 1);
112 gst_buffer_unref (buffer);
113 fail_unless (gst_element_set_state (avisubtitle,
114 GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS, "could not set to null");
115 cleanup_avisubtitle (avisubtitle);
116 }
117
118 static void
check_correct_buffer(guint8 * src_data,guint src_size,guint8 * dst_data,guint dst_size)119 check_correct_buffer (guint8 * src_data, guint src_size, guint8 * dst_data,
120 guint dst_size)
121 {
122 GstBuffer *buffer = gst_buffer_new_allocate (NULL, src_size, 0);
123 GstBuffer *newBuffer;
124 GstElement *avisubtitle = setup_avisubtitle ();
125 GstEvent *event;
126
127 fail_unless (g_list_length (buffers) == 0, "Buffers list needs to be empty");
128 gst_buffer_fill (buffer, 0, src_data, src_size);
129 fail_unless (gst_element_set_state (avisubtitle,
130 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
131 "could not set to playing");
132 ASSERT_BUFFER_REFCOUNT (buffer, "inbuffer", 1);
133 event = gst_event_new_seek (1.0, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH,
134 GST_SEEK_TYPE_SET, 2 * GST_SECOND, GST_SEEK_TYPE_SET, 5 * GST_SECOND);
135 fail_unless (gst_element_send_event (avisubtitle, event) == FALSE,
136 "Seeking is not possible when there is no buffer yet");
137 fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK,
138 "not accepted a correct buffer");
139 /* we gave away our reference to the buffer, don't assume anything */
140 buffer = NULL;
141 /* a new buffer is created in the list */
142 fail_unless (g_list_length (buffers) == 1,
143 "No new buffer in the buffers list");
144 event = gst_event_new_seek (1.0, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH,
145 GST_SEEK_TYPE_SET, 2 * GST_SECOND, GST_SEEK_TYPE_SET, 5 * GST_SECOND);
146 fail_unless (gst_element_send_event (avisubtitle, event) == TRUE,
147 "seeking should be working now");
148 fail_unless (g_list_length (buffers) == 2,
149 "After seeking we need another buffer in the buffers");
150 newBuffer = GST_BUFFER (buffers->data);
151 buffers = g_list_remove (buffers, newBuffer);
152 fail_unless (g_list_length (buffers) == 1, "Buffers list needs to be empty");
153 fail_unless (gst_buffer_get_size (newBuffer) == dst_size,
154 "size of the new buffer is wrong ( %d != %d)",
155 gst_buffer_get_size (newBuffer), dst_size);
156 fail_unless (gst_buffer_memcmp (newBuffer, 0, dst_data, dst_size) == 0,
157 "data of the buffer is not correct");
158 gst_buffer_unref (newBuffer);
159 /* free the buffer from seeking */
160 gst_buffer_unref (GST_BUFFER (buffers->data));
161 buffers = g_list_remove (buffers, buffers->data);
162 fail_unless (gst_element_set_state (avisubtitle,
163 GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS, "could not set to null");
164 cleanup_avisubtitle (avisubtitle);
165 }
166
167
GST_START_TEST(test_avisubtitle_negative)168 GST_START_TEST (test_avisubtitle_negative)
169 {
170 guint8 wrong_magic[] =
171 { 0x47, 0x41, 0x41, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
172 0x00, 0x00
173 };
174 guint8 wrong_fixed_word_2[] = {
175 0x47, 0x41, 0x42, 0x32, 0x00, 0x02, 0x01, 0x10,
176 0x00, 0x00, 0x00, 0x45, 0x00, 0x6e, 0x00, 0x67,
177 0x00, 0x6c, 0x00, 0x69, 0x00, 0x73, 0x00, 0x68
178 };
179 guint8 wrong_length_after_name[] = {
180 0x47, 0x41, 0x42, 0x32, 0x00, 0x02, 0x00, 0x10,
181 0x00, 0x00, 0x00, 0x45, 0x00, 0x6e, 0x00, 0x67,
182 0x00, 0x6c, 0x00, 0x69, 0x00, 0x73, 0x00, 0x68
183 };
184 guint8 wrong_fixed_word_4[] = {
185 0x47, 0x41, 0x42, 0x32, 0x00, 0x02, 0x00, 0x10,
186 0x00, 0x00, 0x00, 0x45, 0x00, 0x6e, 0x00, 0x67,
187 0x00, 0x6c, 0x00, 0x69, 0x00, 0x73, 0x00, 0x68,
188 0x00, 0x00, 0x00, 0x04, 0x01, 0x8e, 0x00, 0x00,
189 0x00, 0xef, 0xbb, 0xbf, 0x31, 0x0d, 0x0a, 0x30
190 };
191 guint8 wrong_total_length[] = {
192 0x47, 0x41, 0x42, 0x32, 0x00, 0x02, 0x00, 0x10,
193 0x00, 0x00, 0x00, 0x45, 0x00, 0x6e, 0x00, 0x67,
194 0x00, 0x6c, 0x00, 0x69, 0x00, 0x73, 0x00, 0x68,
195 0x00, 0x00, 0x00, 0x04, 0x00, 0x8e, 0x00, 0x00,
196 0x00, 0xef, 0xbb, 0xbf, 0x31, 0x0d, 0x0a, 0x30
197 };
198 /* size of the buffer must be larger than 11 */
199 check_wrong_buffer (avisub_utf_8_with_bom, 11);
200 /* buffer must start with 'GAB2\0' */
201 check_wrong_buffer (wrong_magic, 14);
202 /* next word must be 2 */
203 check_wrong_buffer (wrong_fixed_word_2, 24);
204 /* length must be larger than the length of the name + 17 */
205 check_wrong_buffer (wrong_length_after_name, 24);
206 /* next word must be 4 */
207 check_wrong_buffer (wrong_fixed_word_4, 36);
208 /* check wrong total length */
209 check_wrong_buffer (wrong_total_length, 36);
210 }
211
212 GST_END_TEST;
213
GST_START_TEST(test_avisubtitle_positive)214 GST_START_TEST (test_avisubtitle_positive)
215 {
216 guint8 avisub_utf_8_without_bom[] = {
217 0x47, 0x41, 0x42, 0x32, 0x00, 0x02, 0x00, 0x10,
218 0x00, 0x00, 0x00, 0x45, 0x00, 0x6e, 0x00, 0x67,
219 0x00, 0x6c, 0x00, 0x69, 0x00, 0x73, 0x00, 0x68,
220 0x00, 0x00, 0x00, 0x04, 0x00, 0x8b, 0x00, 0x00,
221 0x00, 0x31, 0x0d, 0x0a, 0x30,
222 0x30, 0x3a, 0x30, 0x30, 0x3a, 0x30, 0x30, 0x2c,
223 0x31, 0x30, 0x30, 0x20, 0x2d, 0x2d, 0x3e, 0x20,
224 0x30, 0x30, 0x3a, 0x30, 0x30, 0x3a, 0x30, 0x32,
225 0x2c, 0x30, 0x30, 0x30, 0x0d, 0x0a, 0x3c, 0x62,
226 0x3e, 0x41, 0x6e, 0x20, 0x55, 0x54, 0x46, 0x38,
227 0x20, 0x53, 0x75, 0x62, 0x74, 0x69, 0x74, 0x6c,
228 0x65, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x42,
229 0x4f, 0x4d, 0x3c, 0x2f, 0x62, 0x3e, 0x0d, 0x0a,
230 0x0d, 0x0a, 0x32, 0x0d, 0x0a, 0x30, 0x30, 0x3a,
231 0x30, 0x30, 0x3a, 0x30, 0x32, 0x2c, 0x31, 0x30,
232 0x30, 0x20, 0x2d, 0x2d, 0x3e, 0x20, 0x30, 0x30,
233 0x3a, 0x30, 0x30, 0x3a, 0x30, 0x34, 0x2c, 0x30,
234 0x30, 0x30, 0x0d, 0x0a, 0x53, 0x6f, 0x6d, 0x65,
235 0x74, 0x68, 0x69, 0x6e, 0x67, 0x20, 0x6e, 0x6f,
236 0x6e, 0x41, 0x53, 0x43, 0x49, 0x49, 0x20, 0x2d,
237 0x20, 0xc2, 0xb5, 0xc3, 0xb6, 0xc3, 0xa4, 0xc3,
238 0xbc, 0xc3, 0x9f, 0x0d, 0x0a, 0x0d, 0x0a
239 };
240 check_correct_buffer (avisub_utf_8_with_bom, 175, avisub_utf_8_with_bom + 36,
241 139);
242 check_correct_buffer (avisub_utf_8_without_bom, 172,
243 avisub_utf_8_without_bom + 33, 139);
244 }
245
246 GST_END_TEST;
247
248 static Suite *
avisubtitle_suite(void)249 avisubtitle_suite (void)
250 {
251 Suite *s = suite_create ("avisubtitle");
252 TCase *tc_chain = tcase_create ("general");
253
254 suite_add_tcase (s, tc_chain);
255 tcase_add_test (tc_chain, test_avisubtitle_negative);
256 tcase_add_test (tc_chain, test_avisubtitle_positive);
257
258 return s;
259 }
260
261 GST_CHECK_MAIN (avisubtitle);
262