1 /*
2 * GStreamer
3 *
4 * unit test for h265parse
5 *
6 * Copyright (C) 2020 Intel Corporation
7 * Author: He Junyan <junyan.he@intel.com>
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Library General Public License for more details.
18 *
19 * You should have received a copy of the GNU Library General Public
20 * License along with this library; if not, write to the
21 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
22 * Boston, MA 02110-1301, USA.
23 */
24
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #endif
28
29 #include <gst/check/gstcheck.h>
30 #include <gst/check/gstharness.h>
31 #include "av1parse.h"
32 #include <string.h>
33
34 static void
check_caps_event(GstHarness * h)35 check_caps_event (GstHarness * h)
36 {
37 GstEvent *event;
38 GstCaps *caps = NULL;
39 GstStructure *s;
40 const gchar *profile;
41 gint width, height;
42 guint depth;
43
44 while ((event = gst_harness_try_pull_event (h))) {
45 GstCaps *event_caps;
46 if (GST_EVENT_TYPE (event) != GST_EVENT_CAPS) {
47 gst_event_unref (event);
48 continue;
49 }
50
51 gst_event_parse_caps (event, &event_caps);
52 gst_caps_replace (&caps, event_caps);
53 gst_event_unref (event);
54 }
55
56 fail_unless (caps != NULL);
57 s = gst_caps_get_structure (caps, 0);
58 fail_unless (gst_structure_get_int (s, "width", &width));
59 fail_unless (gst_structure_get_int (s, "height", &height));
60 fail_unless ((profile = gst_structure_get_string (s, "profile")));
61 fail_unless (gst_structure_get_uint (s, "bit-depth-chroma", &depth));
62
63 fail_unless_equals_int (width, 400);
64 fail_unless_equals_int (height, 300);
65 fail_unless_equals_int (depth, 8);
66 fail_unless_equals_string (profile, "main");
67 gst_caps_unref (caps);
68 }
69
GST_START_TEST(test_byte_to_frame)70 GST_START_TEST (test_byte_to_frame)
71 {
72 GstHarness *h;
73 GstBuffer *in_buf, *out_buf = NULL;
74 GstMapInfo map;
75 GstFlowReturn ret;
76 gint i = 0;
77 guint offset;
78 guint len;
79 guint output_buf_num;
80
81 h = gst_harness_new_parse ("av1parse");
82 fail_unless (h != NULL);
83
84 gst_harness_set_sink_caps_str (h, "video/x-av1,parsed=(boolean)true,"
85 "alignment=(string)frame,stream-format=(string)obu-stream");
86 gst_harness_set_src_caps_str (h, "video/x-av1");
87
88 gst_harness_play (h);
89
90 output_buf_num = 0;
91 offset = 0;
92 len = stream_no_annexb_av1_len / 5;
93 for (i = 0; i < 5; i++) {
94 if (i == 4)
95 len = stream_no_annexb_av1_len - offset;
96
97 in_buf = gst_buffer_new_and_alloc (len);
98 gst_buffer_map (in_buf, &map, GST_MAP_WRITE);
99 memcpy (map.data, stream_no_annexb_av1 + offset, len);
100 gst_buffer_unmap (in_buf, &map);
101 offset += len;
102
103 ret = gst_harness_push (h, in_buf);
104 fail_unless (ret == GST_FLOW_OK, "GstFlowReturn was %s",
105 gst_flow_get_name (ret));
106
107 gst_clear_buffer (&out_buf);
108 while ((out_buf = gst_harness_try_pull (h)) != NULL) {
109 if (output_buf_num == 0)
110 check_caps_event (h);
111
112 fail_unless (gst_buffer_get_size (out_buf) ==
113 stream_av1_frame_size[output_buf_num]);
114
115 gst_clear_buffer (&out_buf);
116 output_buf_num++;
117 }
118 }
119
120 fail_unless (output_buf_num == 14);
121
122 gst_harness_teardown (h);
123
124 }
125
126 GST_END_TEST;
127
GST_START_TEST(test_byte_to_annexb)128 GST_START_TEST (test_byte_to_annexb)
129 {
130 GstHarness *h;
131 GstBuffer *in_buf, *out_buf = NULL;
132 GstMapInfo map;
133 GstFlowReturn ret;
134 gint i = 0;
135 guint offset;
136 guint len;
137 guint output_buf_num;
138
139 h = gst_harness_new_parse ("av1parse");
140 fail_unless (h != NULL);
141
142 gst_harness_set_sink_caps_str (h, "video/x-av1,parsed=(boolean)true,"
143 "alignment=(string)tu,stream-format=(string)annexb");
144 gst_harness_set_src_caps_str (h, "video/x-av1,alignment=(string)byte");
145
146 gst_harness_play (h);
147
148 output_buf_num = 0;
149 offset = 0;
150 len = stream_no_annexb_av1_len / 5;
151 for (i = 0; i < 5; i++) {
152 if (i == 4)
153 len = stream_no_annexb_av1_len - offset;
154
155 in_buf = gst_buffer_new_and_alloc (len);
156 gst_buffer_map (in_buf, &map, GST_MAP_WRITE);
157 memcpy (map.data, stream_no_annexb_av1 + offset, len);
158 gst_buffer_unmap (in_buf, &map);
159 offset += len;
160
161 ret = gst_harness_push (h, in_buf);
162 fail_unless (ret == GST_FLOW_OK, "GstFlowReturn was %s",
163 gst_flow_get_name (ret));
164
165 gst_clear_buffer (&out_buf);
166 while ((out_buf = gst_harness_try_pull (h)) != NULL) {
167 if (output_buf_num == 0)
168 check_caps_event (h);
169
170 fail_unless (gst_buffer_get_size (out_buf) ==
171 stream_annexb_av1_tu_len[output_buf_num]);
172
173 gst_clear_buffer (&out_buf);
174 output_buf_num++;
175 }
176 }
177
178 /* The last TU need EOS */
179 fail_unless (gst_harness_push_event (h, gst_event_new_eos ()));
180 out_buf = gst_harness_try_pull (h);
181 fail_unless (out_buf);
182 fail_unless (gst_buffer_get_size (out_buf) ==
183 stream_annexb_av1_tu_len[output_buf_num]);
184 output_buf_num++;
185 gst_clear_buffer (&out_buf);
186
187 fail_unless (output_buf_num == 10);
188
189 gst_harness_teardown (h);
190 }
191
192 GST_END_TEST;
193
GST_START_TEST(test_annexb_to_frame)194 GST_START_TEST (test_annexb_to_frame)
195 {
196 GstHarness *h;
197 GstBuffer *in_buf, *out_buf = NULL;
198 GstMapInfo map;
199 GstFlowReturn ret;
200 gint i = 0;
201 guint offset;
202 guint output_buf_num;
203
204 h = gst_harness_new_parse ("av1parse");
205 fail_unless (h != NULL);
206
207 gst_harness_set_sink_caps_str (h, "video/x-av1,parsed=(boolean)true,"
208 "alignment=(string)frame,stream-format=(string)obu-stream");
209 gst_harness_set_src_caps_str (h, "video/x-av1,alignment=(string)tu,"
210 "stream-format=(string)annexb");
211
212 gst_harness_play (h);
213
214 output_buf_num = 0;
215 offset = 0;
216 for (i = 0; i < G_N_ELEMENTS (stream_annexb_av1_tu_len); i++) {
217 in_buf = gst_buffer_new_and_alloc (stream_annexb_av1_tu_len[i]);
218 gst_buffer_map (in_buf, &map, GST_MAP_WRITE);
219 memcpy (map.data, stream_annexb_av1 + offset, stream_annexb_av1_tu_len[i]);
220 gst_buffer_unmap (in_buf, &map);
221 offset += stream_annexb_av1_tu_len[i];
222
223 ret = gst_harness_push (h, in_buf);
224 fail_unless (ret == GST_FLOW_OK, "GstFlowReturn was %s",
225 gst_flow_get_name (ret));
226
227 gst_clear_buffer (&out_buf);
228 while ((out_buf = gst_harness_try_pull (h)) != NULL) {
229 if (output_buf_num == 0)
230 check_caps_event (h);
231
232 fail_unless (gst_buffer_get_size (out_buf) ==
233 stream_av1_frame_size[output_buf_num]);
234
235 gst_clear_buffer (&out_buf);
236 output_buf_num++;
237 }
238 }
239
240 fail_unless (output_buf_num == 14);
241
242 gst_harness_teardown (h);
243 }
244
245 GST_END_TEST;
246
GST_START_TEST(test_annexb_to_obu)247 GST_START_TEST (test_annexb_to_obu)
248 {
249 GstHarness *h;
250 GstBuffer *in_buf, *out_buf = NULL;
251 GstMapInfo map;
252 GstFlowReturn ret;
253 gint i = 0;
254 guint offset;
255 guint output_buf_num;
256
257 h = gst_harness_new_parse ("av1parse");
258 fail_unless (h != NULL);
259
260 gst_harness_set_sink_caps_str (h, "video/x-av1,parsed=(boolean)true,"
261 "alignment=(string)obu");
262 gst_harness_set_src_caps_str (h, "video/x-av1,alignment=(string)tu,"
263 "stream-format=(string)annexb");
264
265 gst_harness_play (h);
266
267 output_buf_num = 0;
268 offset = 0;
269 for (i = 0; i < G_N_ELEMENTS (stream_annexb_av1_tu_len); i++) {
270 in_buf = gst_buffer_new_and_alloc (stream_annexb_av1_tu_len[i]);
271 gst_buffer_map (in_buf, &map, GST_MAP_WRITE);
272 memcpy (map.data, stream_annexb_av1 + offset, stream_annexb_av1_tu_len[i]);
273 gst_buffer_unmap (in_buf, &map);
274 offset += stream_annexb_av1_tu_len[i];
275
276 ret = gst_harness_push (h, in_buf);
277 fail_unless (ret == GST_FLOW_OK, "GstFlowReturn was %s",
278 gst_flow_get_name (ret));
279
280 gst_clear_buffer (&out_buf);
281 while ((out_buf = gst_harness_try_pull (h)) != NULL) {
282 if (output_buf_num == 0)
283 check_caps_event (h);
284
285 fail_unless (gst_buffer_get_size (out_buf) ==
286 stream_av1_obu_size[output_buf_num]);
287
288 gst_clear_buffer (&out_buf);
289 output_buf_num++;
290 }
291 }
292
293 fail_unless (output_buf_num == G_N_ELEMENTS (stream_av1_obu_size));
294
295 gst_harness_teardown (h);
296 }
297
298 GST_END_TEST;
299
GST_START_TEST(test_byte_to_obu)300 GST_START_TEST (test_byte_to_obu)
301 {
302 GstHarness *h;
303 GstBuffer *in_buf, *out_buf = NULL;
304 GstMapInfo map;
305 GstFlowReturn ret;
306 gint i = 0;
307 guint offset;
308 guint len;
309 guint output_buf_num;
310
311 h = gst_harness_new_parse ("av1parse");
312 fail_unless (h != NULL);
313
314 gst_harness_set_sink_caps_str (h, "video/x-av1,parsed=(boolean)true,"
315 "alignment=(string)obu,stream-format=(string)obu-stream");
316 gst_harness_set_src_caps_str (h, "video/x-av1");
317
318 gst_harness_play (h);
319
320 output_buf_num = 0;
321 offset = 0;
322 len = stream_no_annexb_av1_len / 5;
323 for (i = 0; i < 5; i++) {
324 if (i == 4)
325 len = stream_no_annexb_av1_len - offset;
326
327 in_buf = gst_buffer_new_and_alloc (len);
328 gst_buffer_map (in_buf, &map, GST_MAP_WRITE);
329 memcpy (map.data, stream_no_annexb_av1 + offset, len);
330 gst_buffer_unmap (in_buf, &map);
331 offset += len;
332
333 ret = gst_harness_push (h, in_buf);
334 fail_unless (ret == GST_FLOW_OK, "GstFlowReturn was %s",
335 gst_flow_get_name (ret));
336
337 gst_clear_buffer (&out_buf);
338 while ((out_buf = gst_harness_try_pull (h)) != NULL) {
339 if (output_buf_num == 0)
340 check_caps_event (h);
341
342 fail_unless (gst_buffer_get_size (out_buf) ==
343 stream_av1_obu_size[output_buf_num]);
344
345 gst_clear_buffer (&out_buf);
346 output_buf_num++;
347 }
348 }
349
350 fail_unless (output_buf_num == G_N_ELEMENTS (stream_av1_obu_size));
351
352 gst_harness_teardown (h);
353
354 }
355
356 GST_END_TEST;
357
358 static Suite *
av1parse_suite(void)359 av1parse_suite (void)
360 {
361 Suite *s;
362 TCase *tc_chain;
363
364 s = suite_create ("av1parse");
365 tc_chain = tcase_create ("general");
366
367 suite_add_tcase (s, tc_chain);
368
369 tcase_add_test (tc_chain, test_byte_to_frame);
370 tcase_add_test (tc_chain, test_byte_to_annexb);
371 tcase_add_test (tc_chain, test_annexb_to_frame);
372 tcase_add_test (tc_chain, test_annexb_to_obu);
373 tcase_add_test (tc_chain, test_byte_to_obu);
374
375 return s;
376 }
377
378 GST_CHECK_MAIN (av1parse);
379