| #include <gst/check/gstcheck.h> |
| #include <gst/base/base.h> |
| #include <gst/isoff/gstisoff.h> |
| |
| #include "isoff.h" |
| |
| GST_START_TEST (isoff_box_header_minimal) |
| { |
| /* INDENT-OFF */ |
| static const guint8 data[] = { |
| 16, 32, 64, 128, |
| 't', 'e', 's', 't' |
| }; |
| /* INDENT-ON */ |
| GstByteReader reader = GST_BYTE_READER_INIT (data, sizeof (data)); |
| guint32 type; |
| guint8 extended_type[16]; |
| guint header_size; |
| guint64 size; |
| |
| fail_unless (gst_isoff_parse_box_header (&reader, &type, extended_type, |
| &header_size, &size)); |
| fail_unless (type == GST_MAKE_FOURCC ('t', 'e', 's', 't')); |
| fail_unless_equals_int (header_size, 8); |
| fail_unless_equals_uint64 (size, 0x10204080); |
| } |
| |
| GST_END_TEST; |
| |
| GST_START_TEST (isoff_box_header_long_size) |
| { |
| /* INDENT-OFF */ |
| static const guint8 data[] = { |
| 0, 0, 0, 1, |
| 't', 'e', 's', 't', |
| 1, 2, 4, 8, 16, 32, 64, 128 |
| }; |
| /* INDENT-ON */ |
| GstByteReader reader = GST_BYTE_READER_INIT (data, sizeof (data)); |
| guint32 type; |
| guint8 extended_type[16]; |
| guint header_size; |
| guint64 size; |
| |
| fail_unless (gst_isoff_parse_box_header (&reader, &type, extended_type, |
| &header_size, &size)); |
| fail_unless (type == GST_MAKE_FOURCC ('t', 'e', 's', 't')); |
| fail_unless_equals_int (header_size, 16); |
| fail_unless_equals_uint64 (size, G_GUINT64_CONSTANT (0x0102040810204080)); |
| } |
| |
| GST_END_TEST; |
| |
| GST_START_TEST (isoff_box_header_uuid_type) |
| { |
| /* INDENT-OFF */ |
| static const guint8 data[] = { |
| 16, 32, 64, 128, |
| 'u', 'u', 'i', 'd', |
| 'a', 'b', 'c', 'd', |
| 'e', 'f', 'g', 'h', |
| 'i', 'j', 'k', 'l', |
| 'm', 'n', 'o', 'p' |
| }; |
| /* INDENT-ON */ |
| GstByteReader reader = GST_BYTE_READER_INIT (data, sizeof (data)); |
| guint32 type; |
| guint8 extended_type[16]; |
| guint header_size; |
| guint64 size; |
| |
| fail_unless (gst_isoff_parse_box_header (&reader, &type, extended_type, |
| &header_size, &size)); |
| fail_unless (type == GST_MAKE_FOURCC ('u', 'u', 'i', 'd')); |
| fail_unless_equals_int (header_size, 24); |
| fail_unless_equals_uint64 (size, 0x10204080); |
| fail_unless (memcmp (data + 8, extended_type, 16) == 0); |
| } |
| |
| GST_END_TEST; |
| |
| GST_START_TEST (isoff_box_header_uuid_type_long_size) |
| { |
| /* INDENT-OFF */ |
| static const guint8 data[] = { |
| 0, 0, 0, 1, |
| 'u', 'u', 'i', 'd', |
| 1, 2, 4, 8, 16, 32, 64, 128, |
| 'a', 'b', 'c', 'd', |
| 'e', 'f', 'g', 'h', |
| 'i', 'j', 'k', 'l', |
| 'm', 'n', 'o', 'p' |
| }; |
| /* INDENT-ON */ |
| GstByteReader reader = GST_BYTE_READER_INIT (data, sizeof (data)); |
| guint32 type; |
| guint8 extended_type[16]; |
| guint header_size; |
| guint64 size; |
| |
| fail_unless (gst_isoff_parse_box_header (&reader, &type, extended_type, |
| &header_size, &size)); |
| fail_unless (type == GST_MAKE_FOURCC ('u', 'u', 'i', 'd')); |
| fail_unless_equals_int (header_size, 32); |
| fail_unless_equals_uint64 (size, G_GUINT64_CONSTANT (0x0102040810204080)); |
| fail_unless (memcmp (data + 16, extended_type, 16) == 0); |
| } |
| |
| GST_END_TEST; |
| |
| GST_START_TEST (isoff_moof_parse) |
| { |
| /* INDENT-ON */ |
| GstByteReader reader = GST_BYTE_READER_INIT (moof1, sizeof (moof1)); |
| guint32 type; |
| guint8 extended_type[16]; |
| guint header_size; |
| guint64 size; |
| GstMoofBox *moof; |
| GstTrafBox *traf; |
| GstTrunBox *trun; |
| guint i; |
| |
| fail_unless (gst_isoff_parse_box_header (&reader, &type, extended_type, |
| &header_size, &size)); |
| fail_unless (type == GST_MAKE_FOURCC ('m', 'o', 'o', 'f')); |
| fail_unless_equals_int (header_size, 8); |
| fail_unless_equals_uint64 (size, sizeof (moof1)); |
| |
| moof = gst_isoff_moof_box_parse (&reader); |
| fail_unless (moof != NULL); |
| |
| fail_unless_equals_int (moof->mfhd.sequence_number, 1); |
| fail_unless_equals_int (moof->traf->len, 1); |
| |
| traf = &g_array_index (moof->traf, GstTrafBox, 0); |
| fail_unless_equals_int (traf->tfhd.version, 0); |
| fail_unless_equals_int (traf->tfhd.flags, |
| GST_TFHD_FLAGS_DEFAULT_SAMPLE_DURATION_PRESENT); |
| fail_unless_equals_int (traf->tfhd.track_id, 1); |
| fail_unless_equals_uint64 (traf->tfhd.base_data_offset, 0); |
| fail_unless_equals_int (traf->tfhd.sample_description_index, 0); |
| fail_unless_equals_int (traf->tfhd.default_sample_duration, 8); |
| fail_unless_equals_int (traf->tfhd.default_sample_size, 0); |
| fail_unless_equals_int (traf->tfhd.default_sample_flags, 0); |
| |
| fail_unless_equals_int (traf->trun->len, 1); |
| trun = &g_array_index (traf->trun, GstTrunBox, 0); |
| |
| fail_unless_equals_int (trun->version, 1); |
| fail_unless_equals_int (trun->flags, |
| GST_TRUN_FLAGS_SAMPLE_COMPOSITION_TIME_OFFSETS_PRESENT | |
| GST_TRUN_FLAGS_SAMPLE_FLAGS_PRESENT | GST_TRUN_FLAGS_SAMPLE_SIZE_PRESENT | |
| GST_TRUN_FLAGS_DATA_OFFSET_PRESENT); |
| fail_unless_equals_int (trun->sample_count, 96); |
| fail_unless_equals_int (trun->data_offset, size + header_size); |
| fail_unless_equals_int (trun->first_sample_flags, 0); |
| |
| fail_unless_equals_int (trun->samples->len, 96); |
| |
| for (i = 0; i < 96; i++) { |
| GstTrunSample *sample = &g_array_index (trun->samples, GstTrunSample, i); |
| |
| fail_unless_equals_int (sample->sample_duration, 0); |
| if (i == 0) { |
| /* sample_depends_on = 2 => I-frame */ |
| /* sample_is_non_sync_sample = 0 */ |
| fail_unless_equals_int (sample->sample_flags, 0x02000000); |
| } else { |
| /* sample_depends_on = 1 => non-I-frame */ |
| /* sample_is_non_sync_sample = 1 */ |
| fail_unless_equals_int (sample->sample_flags, 0x01010000); |
| } |
| |
| /* sample size and CTO is changing for each sample */ |
| } |
| |
| gst_isoff_moof_box_free (moof); |
| } |
| |
| GST_END_TEST; |
| |
| GST_START_TEST (isoff_moof_parse_with_tfdt) |
| { |
| /* INDENT-ON */ |
| GstByteReader reader = GST_BYTE_READER_INIT (seg_2_m4f, sizeof (seg_2_m4f)); |
| guint32 type; |
| guint8 extended_type[16]; |
| guint header_size; |
| guint64 size; |
| GstMoofBox *moof; |
| GstTrafBox *traf; |
| GstTrunBox *trun; |
| guint i; |
| |
| fail_unless (gst_isoff_parse_box_header (&reader, &type, extended_type, |
| &header_size, &size)); |
| fail_unless (type == GST_ISOFF_FOURCC_MOOF); |
| fail_unless_equals_int (header_size, 8); |
| fail_unless_equals_uint64 (size, seg_2_m4f_len); |
| |
| moof = gst_isoff_moof_box_parse (&reader); |
| fail_unless (moof != NULL); |
| |
| fail_unless_equals_int (moof->mfhd.sequence_number, 4); |
| fail_unless_equals_int (moof->traf->len, 1); |
| |
| traf = &g_array_index (moof->traf, GstTrafBox, 0); |
| fail_unless_equals_int (traf->tfhd.version, 0); |
| fail_unless_equals_int (traf->tfhd.flags, |
| GST_TFHD_FLAGS_DEFAULT_BASE_IS_MOOF); |
| fail_unless_equals_int (traf->tfhd.track_id, 2); |
| fail_unless_equals_uint64 (traf->tfhd.base_data_offset, 0); |
| fail_unless_equals_int (traf->tfhd.sample_description_index, 0); |
| fail_unless_equals_int (traf->tfhd.default_sample_duration, 0); |
| fail_unless_equals_int (traf->tfhd.default_sample_size, 0); |
| fail_unless_equals_int (traf->tfhd.default_sample_flags, 0); |
| |
| fail_unless_equals_uint64 (traf->tfdt.decode_time, 132096); |
| |
| fail_unless_equals_int (traf->trun->len, 1); |
| trun = &g_array_index (traf->trun, GstTrunBox, 0); |
| |
| fail_unless_equals_int (trun->version, 0); |
| fail_unless_equals_int (trun->flags, |
| GST_TRUN_FLAGS_SAMPLE_SIZE_PRESENT | |
| GST_TRUN_FLAGS_SAMPLE_DURATION_PRESENT | |
| GST_TRUN_FLAGS_DATA_OFFSET_PRESENT); |
| fail_unless_equals_int (trun->sample_count, 129); |
| fail_unless_equals_int (trun->data_offset, size + header_size); |
| fail_unless_equals_int (trun->first_sample_flags, 0); |
| |
| fail_unless_equals_int (trun->samples->len, 129); |
| |
| for (i = 0; i < 129; i++) { |
| GstTrunSample *sample = &g_array_index (trun->samples, GstTrunSample, i); |
| |
| fail_unless_equals_int (sample->sample_duration, seg_sample_duration); |
| fail_unless_equals_int (sample->sample_flags, 0x00000000); |
| fail_unless_equals_int (sample->sample_size, seg_2_sample_sizes[i]); |
| } |
| |
| gst_isoff_moof_box_free (moof); |
| } |
| |
| GST_END_TEST; |
| |
| GST_START_TEST (isoff_moof_parse_with_tfxd_tfrf) |
| { |
| GstByteReader reader = |
| GST_BYTE_READER_INIT (Fragments_audio, sizeof (Fragments_audio)); |
| guint32 type; |
| guint8 extended_type[16]; |
| guint header_size; |
| guint64 size; |
| GstMoofBox *moof; |
| GstTrafBox *traf; |
| GstTfxdBox *tfxd; |
| GstTfrfBox *tfrf; |
| GstTfrfBoxEntry *tfrf_entry; |
| |
| fail_unless (gst_isoff_parse_box_header (&reader, &type, extended_type, |
| &header_size, &size)); |
| fail_unless (type == GST_ISOFF_FOURCC_MOOF); |
| fail_unless_equals_int (header_size, 8); |
| fail_unless_equals_uint64 (size, Fragments_audio_len); |
| |
| moof = gst_isoff_moof_box_parse (&reader); |
| fail_unless (moof != NULL); |
| |
| fail_unless_equals_int (moof->mfhd.sequence_number, 124); |
| fail_unless_equals_int (moof->traf->len, 1); |
| |
| traf = &g_array_index (moof->traf, GstTrafBox, 0); |
| fail_unless_equals_int (traf->tfhd.version, 0); |
| fail_unless_equals_int (traf->tfhd.flags, |
| GST_TFHD_FLAGS_DEFAULT_SAMPLE_FLAGS_PRESENT); |
| fail_unless_equals_int (traf->tfhd.track_id, 1); |
| fail_unless_equals_uint64 (traf->tfhd.base_data_offset, 0); |
| fail_unless_equals_int (traf->tfhd.sample_description_index, 0); |
| fail_unless_equals_int (traf->tfhd.default_sample_duration, 0); |
| fail_unless_equals_int (traf->tfhd.default_sample_size, 0); |
| |
| tfxd = traf->tfxd; |
| fail_unless (tfxd != NULL); |
| fail_unless_equals_uint64 (tfxd->time, 1188108174758706); |
| fail_unless_equals_uint64 (tfxd->duration, 19969161); |
| |
| tfrf = traf->tfrf; |
| fail_unless (tfrf != NULL); |
| fail_unless_equals_int (tfrf->entries_count, 2); |
| fail_unless_equals_int (tfrf->entries->len, 2); |
| |
| tfrf_entry = &g_array_index (tfrf->entries, GstTfrfBoxEntry, 0); |
| fail_unless (tfrf_entry != NULL); |
| fail_unless_equals_uint64 (tfrf_entry->time, 1188108194727867); |
| fail_unless_equals_uint64 (tfrf_entry->duration, 19969160); |
| |
| tfrf_entry = &g_array_index (tfrf->entries, GstTfrfBoxEntry, 1); |
| fail_unless (tfrf_entry != NULL); |
| fail_unless_equals_uint64 (tfrf_entry->time, 1188108214697027); |
| fail_unless_equals_uint64 (tfrf_entry->duration, 19969162); |
| |
| gst_isoff_moof_box_free (moof); |
| } |
| |
| GST_END_TEST; |
| |
| GST_START_TEST (isoff_moov_parse) |
| { |
| /* INDENT-ON */ |
| GstByteReader reader = GST_BYTE_READER_INIT (init_mp4, sizeof (init_mp4)); |
| guint32 type; |
| guint8 extended_type[16]; |
| guint header_size; |
| guint64 size; |
| GstMoovBox *moov; |
| GstTrakBox *trak; |
| |
| fail_unless (gst_isoff_parse_box_header (&reader, &type, extended_type, |
| &header_size, &size)); |
| fail_unless (type == GST_ISOFF_FOURCC_MOOV); |
| fail_unless_equals_int (header_size, 8); |
| fail_unless_equals_uint64 (size, sizeof (init_mp4)); |
| |
| moov = gst_isoff_moov_box_parse (&reader); |
| fail_unless (moov != NULL); |
| |
| fail_unless_equals_int (moov->trak->len, 1); |
| |
| trak = &g_array_index (moov->trak, GstTrakBox, 0); |
| fail_unless_equals_int (trak->tkhd.track_id, 2); |
| fail_unless (trak->mdia.hdlr.handler_type, GST_ISOFF_FOURCC_SOUN); |
| fail_unless_equals_int (trak->mdia.mdhd.timescale, seg_timescale); |
| |
| gst_isoff_moov_box_free (moov); |
| } |
| |
| GST_END_TEST; |
| |
| static Suite * |
| dash_isoff_suite (void) |
| { |
| Suite *s = suite_create ("isoff"); |
| TCase *tc_isoff_box = tcase_create ("isoff-box-parsing"); |
| TCase *tc_moof = tcase_create ("moof"); |
| TCase *tc_moov = tcase_create ("moov"); |
| |
| tcase_add_test (tc_isoff_box, isoff_box_header_minimal); |
| tcase_add_test (tc_isoff_box, isoff_box_header_long_size); |
| tcase_add_test (tc_isoff_box, isoff_box_header_uuid_type); |
| tcase_add_test (tc_isoff_box, isoff_box_header_uuid_type_long_size); |
| |
| suite_add_tcase (s, tc_isoff_box); |
| |
| tcase_add_test (tc_moof, isoff_moof_parse); |
| tcase_add_test (tc_moof, isoff_moof_parse_with_tfdt); |
| tcase_add_test (tc_moof, isoff_moof_parse_with_tfxd_tfrf); |
| suite_add_tcase (s, tc_moof); |
| |
| tcase_add_test (tc_moov, isoff_moov_parse); |
| suite_add_tcase (s, tc_moov); |
| |
| return s; |
| } |
| |
| GST_CHECK_MAIN (dash_isoff); |