1 #include <gst/check/gstcheck.h>
2 #include <gst/base/base.h>
3 #include <gst/isoff/gstisoff.h>
4
5 #include "isoff.h"
6
GST_START_TEST(isoff_box_header_minimal)7 GST_START_TEST (isoff_box_header_minimal)
8 {
9 /* INDENT-OFF */
10 static const guint8 data[] = {
11 16, 32, 64, 128,
12 't', 'e', 's', 't'
13 };
14 /* INDENT-ON */
15 GstByteReader reader = GST_BYTE_READER_INIT (data, sizeof (data));
16 guint32 type;
17 guint8 extended_type[16];
18 guint header_size;
19 guint64 size;
20
21 fail_unless (gst_isoff_parse_box_header (&reader, &type, extended_type,
22 &header_size, &size));
23 fail_unless (type == GST_MAKE_FOURCC ('t', 'e', 's', 't'));
24 fail_unless_equals_int (header_size, 8);
25 fail_unless_equals_uint64 (size, 0x10204080);
26 }
27
28 GST_END_TEST;
29
GST_START_TEST(isoff_box_header_long_size)30 GST_START_TEST (isoff_box_header_long_size)
31 {
32 /* INDENT-OFF */
33 static const guint8 data[] = {
34 0, 0, 0, 1,
35 't', 'e', 's', 't',
36 1, 2, 4, 8, 16, 32, 64, 128
37 };
38 /* INDENT-ON */
39 GstByteReader reader = GST_BYTE_READER_INIT (data, sizeof (data));
40 guint32 type;
41 guint8 extended_type[16];
42 guint header_size;
43 guint64 size;
44
45 fail_unless (gst_isoff_parse_box_header (&reader, &type, extended_type,
46 &header_size, &size));
47 fail_unless (type == GST_MAKE_FOURCC ('t', 'e', 's', 't'));
48 fail_unless_equals_int (header_size, 16);
49 fail_unless_equals_uint64 (size, G_GUINT64_CONSTANT (0x0102040810204080));
50 }
51
52 GST_END_TEST;
53
GST_START_TEST(isoff_box_header_uuid_type)54 GST_START_TEST (isoff_box_header_uuid_type)
55 {
56 /* INDENT-OFF */
57 static const guint8 data[] = {
58 16, 32, 64, 128,
59 'u', 'u', 'i', 'd',
60 'a', 'b', 'c', 'd',
61 'e', 'f', 'g', 'h',
62 'i', 'j', 'k', 'l',
63 'm', 'n', 'o', 'p'
64 };
65 /* INDENT-ON */
66 GstByteReader reader = GST_BYTE_READER_INIT (data, sizeof (data));
67 guint32 type;
68 guint8 extended_type[16];
69 guint header_size;
70 guint64 size;
71
72 fail_unless (gst_isoff_parse_box_header (&reader, &type, extended_type,
73 &header_size, &size));
74 fail_unless (type == GST_MAKE_FOURCC ('u', 'u', 'i', 'd'));
75 fail_unless_equals_int (header_size, 24);
76 fail_unless_equals_uint64 (size, 0x10204080);
77 fail_unless (memcmp (data + 8, extended_type, 16) == 0);
78 }
79
80 GST_END_TEST;
81
GST_START_TEST(isoff_box_header_uuid_type_long_size)82 GST_START_TEST (isoff_box_header_uuid_type_long_size)
83 {
84 /* INDENT-OFF */
85 static const guint8 data[] = {
86 0, 0, 0, 1,
87 'u', 'u', 'i', 'd',
88 1, 2, 4, 8, 16, 32, 64, 128,
89 'a', 'b', 'c', 'd',
90 'e', 'f', 'g', 'h',
91 'i', 'j', 'k', 'l',
92 'm', 'n', 'o', 'p'
93 };
94 /* INDENT-ON */
95 GstByteReader reader = GST_BYTE_READER_INIT (data, sizeof (data));
96 guint32 type;
97 guint8 extended_type[16];
98 guint header_size;
99 guint64 size;
100
101 fail_unless (gst_isoff_parse_box_header (&reader, &type, extended_type,
102 &header_size, &size));
103 fail_unless (type == GST_MAKE_FOURCC ('u', 'u', 'i', 'd'));
104 fail_unless_equals_int (header_size, 32);
105 fail_unless_equals_uint64 (size, G_GUINT64_CONSTANT (0x0102040810204080));
106 fail_unless (memcmp (data + 16, extended_type, 16) == 0);
107 }
108
109 GST_END_TEST;
110
GST_START_TEST(isoff_moof_parse)111 GST_START_TEST (isoff_moof_parse)
112 {
113 /* INDENT-ON */
114 GstByteReader reader = GST_BYTE_READER_INIT (moof1, sizeof (moof1));
115 guint32 type;
116 guint8 extended_type[16];
117 guint header_size;
118 guint64 size;
119 GstMoofBox *moof;
120 GstTrafBox *traf;
121 GstTrunBox *trun;
122 guint i;
123
124 fail_unless (gst_isoff_parse_box_header (&reader, &type, extended_type,
125 &header_size, &size));
126 fail_unless (type == GST_MAKE_FOURCC ('m', 'o', 'o', 'f'));
127 fail_unless_equals_int (header_size, 8);
128 fail_unless_equals_uint64 (size, sizeof (moof1));
129
130 moof = gst_isoff_moof_box_parse (&reader);
131 fail_unless (moof != NULL);
132
133 fail_unless_equals_int (moof->mfhd.sequence_number, 1);
134 fail_unless_equals_int (moof->traf->len, 1);
135
136 traf = &g_array_index (moof->traf, GstTrafBox, 0);
137 fail_unless_equals_int (traf->tfhd.version, 0);
138 fail_unless_equals_int (traf->tfhd.flags,
139 GST_TFHD_FLAGS_DEFAULT_SAMPLE_DURATION_PRESENT);
140 fail_unless_equals_int (traf->tfhd.track_id, 1);
141 fail_unless_equals_uint64 (traf->tfhd.base_data_offset, 0);
142 fail_unless_equals_int (traf->tfhd.sample_description_index, 0);
143 fail_unless_equals_int (traf->tfhd.default_sample_duration, 8);
144 fail_unless_equals_int (traf->tfhd.default_sample_size, 0);
145 fail_unless_equals_int (traf->tfhd.default_sample_flags, 0);
146
147 fail_unless_equals_int (traf->trun->len, 1);
148 trun = &g_array_index (traf->trun, GstTrunBox, 0);
149
150 fail_unless_equals_int (trun->version, 1);
151 fail_unless_equals_int (trun->flags,
152 GST_TRUN_FLAGS_SAMPLE_COMPOSITION_TIME_OFFSETS_PRESENT |
153 GST_TRUN_FLAGS_SAMPLE_FLAGS_PRESENT | GST_TRUN_FLAGS_SAMPLE_SIZE_PRESENT |
154 GST_TRUN_FLAGS_DATA_OFFSET_PRESENT);
155 fail_unless_equals_int (trun->sample_count, 96);
156 fail_unless_equals_int (trun->data_offset, size + header_size);
157 fail_unless_equals_int (trun->first_sample_flags, 0);
158
159 fail_unless_equals_int (trun->samples->len, 96);
160
161 for (i = 0; i < 96; i++) {
162 GstTrunSample *sample = &g_array_index (trun->samples, GstTrunSample, i);
163
164 fail_unless_equals_int (sample->sample_duration, 0);
165 if (i == 0) {
166 /* sample_depends_on = 2 => I-frame */
167 /* sample_is_non_sync_sample = 0 */
168 fail_unless_equals_int (sample->sample_flags, 0x02000000);
169 } else {
170 /* sample_depends_on = 1 => non-I-frame */
171 /* sample_is_non_sync_sample = 1 */
172 fail_unless_equals_int (sample->sample_flags, 0x01010000);
173 }
174
175 /* sample size and CTO is changing for each sample */
176 }
177
178 gst_isoff_moof_box_free (moof);
179 }
180
181 GST_END_TEST;
182
GST_START_TEST(isoff_moof_parse_with_tfdt)183 GST_START_TEST (isoff_moof_parse_with_tfdt)
184 {
185 /* INDENT-ON */
186 GstByteReader reader = GST_BYTE_READER_INIT (seg_2_m4f, sizeof (seg_2_m4f));
187 guint32 type;
188 guint8 extended_type[16];
189 guint header_size;
190 guint64 size;
191 GstMoofBox *moof;
192 GstTrafBox *traf;
193 GstTrunBox *trun;
194 guint i;
195
196 fail_unless (gst_isoff_parse_box_header (&reader, &type, extended_type,
197 &header_size, &size));
198 fail_unless (type == GST_ISOFF_FOURCC_MOOF);
199 fail_unless_equals_int (header_size, 8);
200 fail_unless_equals_uint64 (size, seg_2_m4f_len);
201
202 moof = gst_isoff_moof_box_parse (&reader);
203 fail_unless (moof != NULL);
204
205 fail_unless_equals_int (moof->mfhd.sequence_number, 4);
206 fail_unless_equals_int (moof->traf->len, 1);
207
208 traf = &g_array_index (moof->traf, GstTrafBox, 0);
209 fail_unless_equals_int (traf->tfhd.version, 0);
210 fail_unless_equals_int (traf->tfhd.flags,
211 GST_TFHD_FLAGS_DEFAULT_BASE_IS_MOOF);
212 fail_unless_equals_int (traf->tfhd.track_id, 2);
213 fail_unless_equals_uint64 (traf->tfhd.base_data_offset, 0);
214 fail_unless_equals_int (traf->tfhd.sample_description_index, 0);
215 fail_unless_equals_int (traf->tfhd.default_sample_duration, 0);
216 fail_unless_equals_int (traf->tfhd.default_sample_size, 0);
217 fail_unless_equals_int (traf->tfhd.default_sample_flags, 0);
218
219 fail_unless_equals_uint64 (traf->tfdt.decode_time, 132096);
220
221 fail_unless_equals_int (traf->trun->len, 1);
222 trun = &g_array_index (traf->trun, GstTrunBox, 0);
223
224 fail_unless_equals_int (trun->version, 0);
225 fail_unless_equals_int (trun->flags,
226 GST_TRUN_FLAGS_SAMPLE_SIZE_PRESENT |
227 GST_TRUN_FLAGS_SAMPLE_DURATION_PRESENT |
228 GST_TRUN_FLAGS_DATA_OFFSET_PRESENT);
229 fail_unless_equals_int (trun->sample_count, 129);
230 fail_unless_equals_int (trun->data_offset, size + header_size);
231 fail_unless_equals_int (trun->first_sample_flags, 0);
232
233 fail_unless_equals_int (trun->samples->len, 129);
234
235 for (i = 0; i < 129; i++) {
236 GstTrunSample *sample = &g_array_index (trun->samples, GstTrunSample, i);
237
238 fail_unless_equals_int (sample->sample_duration, seg_sample_duration);
239 fail_unless_equals_int (sample->sample_flags, 0x00000000);
240 fail_unless_equals_int (sample->sample_size, seg_2_sample_sizes[i]);
241 }
242
243 gst_isoff_moof_box_free (moof);
244 }
245
246 GST_END_TEST;
247
GST_START_TEST(isoff_moof_parse_with_tfxd_tfrf)248 GST_START_TEST (isoff_moof_parse_with_tfxd_tfrf)
249 {
250 GstByteReader reader =
251 GST_BYTE_READER_INIT (Fragments_audio, sizeof (Fragments_audio));
252 guint32 type;
253 guint8 extended_type[16];
254 guint header_size;
255 guint64 size;
256 GstMoofBox *moof;
257 GstTrafBox *traf;
258 GstTfxdBox *tfxd;
259 GstTfrfBox *tfrf;
260 GstTfrfBoxEntry *tfrf_entry;
261
262 fail_unless (gst_isoff_parse_box_header (&reader, &type, extended_type,
263 &header_size, &size));
264 fail_unless (type == GST_ISOFF_FOURCC_MOOF);
265 fail_unless_equals_int (header_size, 8);
266 fail_unless_equals_uint64 (size, Fragments_audio_len);
267
268 moof = gst_isoff_moof_box_parse (&reader);
269 fail_unless (moof != NULL);
270
271 fail_unless_equals_int (moof->mfhd.sequence_number, 124);
272 fail_unless_equals_int (moof->traf->len, 1);
273
274 traf = &g_array_index (moof->traf, GstTrafBox, 0);
275 fail_unless_equals_int (traf->tfhd.version, 0);
276 fail_unless_equals_int (traf->tfhd.flags,
277 GST_TFHD_FLAGS_DEFAULT_SAMPLE_FLAGS_PRESENT);
278 fail_unless_equals_int (traf->tfhd.track_id, 1);
279 fail_unless_equals_uint64 (traf->tfhd.base_data_offset, 0);
280 fail_unless_equals_int (traf->tfhd.sample_description_index, 0);
281 fail_unless_equals_int (traf->tfhd.default_sample_duration, 0);
282 fail_unless_equals_int (traf->tfhd.default_sample_size, 0);
283
284 tfxd = traf->tfxd;
285 fail_unless (tfxd != NULL);
286 fail_unless_equals_uint64 (tfxd->time, 1188108174758706);
287 fail_unless_equals_uint64 (tfxd->duration, 19969161);
288
289 tfrf = traf->tfrf;
290 fail_unless (tfrf != NULL);
291 fail_unless_equals_int (tfrf->entries_count, 2);
292 fail_unless_equals_int (tfrf->entries->len, 2);
293
294 tfrf_entry = &g_array_index (tfrf->entries, GstTfrfBoxEntry, 0);
295 fail_unless (tfrf_entry != NULL);
296 fail_unless_equals_uint64 (tfrf_entry->time, 1188108194727867);
297 fail_unless_equals_uint64 (tfrf_entry->duration, 19969160);
298
299 tfrf_entry = &g_array_index (tfrf->entries, GstTfrfBoxEntry, 1);
300 fail_unless (tfrf_entry != NULL);
301 fail_unless_equals_uint64 (tfrf_entry->time, 1188108214697027);
302 fail_unless_equals_uint64 (tfrf_entry->duration, 19969162);
303
304 gst_isoff_moof_box_free (moof);
305 }
306
307 GST_END_TEST;
308
GST_START_TEST(isoff_moov_parse)309 GST_START_TEST (isoff_moov_parse)
310 {
311 /* INDENT-ON */
312 GstByteReader reader = GST_BYTE_READER_INIT (init_mp4, sizeof (init_mp4));
313 guint32 type;
314 guint8 extended_type[16];
315 guint header_size;
316 guint64 size;
317 GstMoovBox *moov;
318 GstTrakBox *trak;
319
320 fail_unless (gst_isoff_parse_box_header (&reader, &type, extended_type,
321 &header_size, &size));
322 fail_unless (type == GST_ISOFF_FOURCC_MOOV);
323 fail_unless_equals_int (header_size, 8);
324 fail_unless_equals_uint64 (size, sizeof (init_mp4));
325
326 moov = gst_isoff_moov_box_parse (&reader);
327 fail_unless (moov != NULL);
328
329 fail_unless_equals_int (moov->trak->len, 1);
330
331 trak = &g_array_index (moov->trak, GstTrakBox, 0);
332 fail_unless_equals_int (trak->tkhd.track_id, 2);
333 fail_unless (trak->mdia.hdlr.handler_type, GST_ISOFF_FOURCC_SOUN);
334 fail_unless_equals_int (trak->mdia.mdhd.timescale, seg_timescale);
335
336 gst_isoff_moov_box_free (moov);
337 }
338
339 GST_END_TEST;
340
341 static Suite *
dash_isoff_suite(void)342 dash_isoff_suite (void)
343 {
344 Suite *s = suite_create ("isoff");
345 TCase *tc_isoff_box = tcase_create ("isoff-box-parsing");
346 TCase *tc_moof = tcase_create ("moof");
347 TCase *tc_moov = tcase_create ("moov");
348
349 tcase_add_test (tc_isoff_box, isoff_box_header_minimal);
350 tcase_add_test (tc_isoff_box, isoff_box_header_long_size);
351 tcase_add_test (tc_isoff_box, isoff_box_header_uuid_type);
352 tcase_add_test (tc_isoff_box, isoff_box_header_uuid_type_long_size);
353
354 suite_add_tcase (s, tc_isoff_box);
355
356 tcase_add_test (tc_moof, isoff_moof_parse);
357 tcase_add_test (tc_moof, isoff_moof_parse_with_tfdt);
358 tcase_add_test (tc_moof, isoff_moof_parse_with_tfxd_tfrf);
359 suite_add_tcase (s, tc_moof);
360
361 tcase_add_test (tc_moov, isoff_moov_parse);
362 suite_add_tcase (s, tc_moov);
363
364 return s;
365 }
366
367 GST_CHECK_MAIN (dash_isoff);
368