diff options
author | Seungha Yang <sh.yang@lge.com> | 2017-05-25 18:14:09 +0900 |
---|---|---|
committer | Reynaldo H. Verdejo Pinochet <reynaldo@osg.samsung.com> | 2017-08-25 17:21:04 -0700 |
commit | 7d06ecb3a4f1344a1ea146c818c73a83ce137661 (patch) | |
tree | e1342a3d5afc088ff70f2b03629746f83f538277 /gst-libs/gst/isoff | |
parent | 4686dc47e4f145a2a50a57fa85fc6c0c5f8464d6 (diff) | |
download | gstreamer-plugins-bad-7d06ecb3a4f1344a1ea146c818c73a83ce137661.tar.gz |
isoff: Move isoff to gst-libs
Also rename unit test dash_isoff to isoff
https://bugzilla.gnome.org/show_bug.cgi?id=777825
Diffstat (limited to 'gst-libs/gst/isoff')
-rw-r--r-- | gst-libs/gst/isoff/Makefile.am | 24 | ||||
-rw-r--r-- | gst-libs/gst/isoff/gstisoff.c | 545 | ||||
-rw-r--r-- | gst-libs/gst/isoff/gstisoff.h | 195 | ||||
-rw-r--r-- | gst-libs/gst/isoff/meson.build | 22 |
4 files changed, 786 insertions, 0 deletions
diff --git a/gst-libs/gst/isoff/Makefile.am b/gst-libs/gst/isoff/Makefile.am new file mode 100644 index 000000000..b99acaed6 --- /dev/null +++ b/gst-libs/gst/isoff/Makefile.am @@ -0,0 +1,24 @@ +lib_LTLIBRARIES = libgstisoff-@GST_API_VERSION@.la + +libgstisoff_@GST_API_VERSION@_la_SOURCES = \ + gstisoff.c + +libgstisoff_@GST_API_VERSION@includedir = \ + $(includedir)/gstreamer-@GST_API_VERSION@/gst/isoff + +libgstisoff_@GST_API_VERSION@include_HEADERS = \ + gstisoff.h + +libgstisoff_@GST_API_VERSION@_la_CFLAGS = \ + $(GST_PLUGINS_BAD_CFLAGS) \ + -DGST_USE_UNSTABLE_API \ + $(GST_CFLAGS) + +libgstisoff_@GST_API_VERSION@_la_LIBADD = \ + $(GST_BASE_LIBS) \ + $(GST_LIBS) + +libgstisoff_@GST_API_VERSION@_la_LDFLAGS = \ + $(GST_LIB_LDFLAGS) \ + $(GST_ALL_LDFLAGS) \ + $(GST_LT_LDFLAGS) diff --git a/gst-libs/gst/isoff/gstisoff.c b/gst-libs/gst/isoff/gstisoff.c new file mode 100644 index 000000000..efb997407 --- /dev/null +++ b/gst-libs/gst/isoff/gstisoff.c @@ -0,0 +1,545 @@ +/* + * ISO File Format parsing library + * + * gstisoff.h + * + * Copyright (C) 2015 Samsung Electronics. All rights reserved. + * Author: Thiago Santos <thiagoss@osg.samsung.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library (COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "gstisoff.h" +#include <gst/base/gstbytereader.h> + +#include <string.h> + +GST_DEBUG_CATEGORY (gst_isoff_debug); +#define GST_CAT_DEFAULT gst_isoff_debug + +static gboolean initialized = FALSE; + +#define INITIALIZE_DEBUG_CATEGORY \ + if (!initialized) { \ + GST_DEBUG_CATEGORY_INIT (gst_isoff_debug, "isoff", 0, \ + "ISO File Format parsing library"); \ + initialized = TRUE; \ + } + +/* gst_isoff_parse_box_header: + * @reader: + * @type: type that was found at the current position + * @extended_type: (allow-none): extended type if type=='uuid' + * @header_size: (allow-none): size of the box header (type, extended type and size) + * @size: size of the complete box including type, extended type and size + * + * Advances the byte reader to the start of the box content. To skip + * over the complete box, skip size - header_size bytes. + * + * Returns: TRUE if a box header could be parsed, FALSE if more data is needed + */ +gboolean +gst_isoff_parse_box_header (GstByteReader * reader, guint32 * type, + guint8 extended_type[16], guint * header_size, guint64 * size) +{ + guint header_start_offset; + guint32 size_field; + + INITIALIZE_DEBUG_CATEGORY; + header_start_offset = gst_byte_reader_get_pos (reader); + + if (gst_byte_reader_get_remaining (reader) < 8) + goto not_enough_data; + + size_field = gst_byte_reader_get_uint32_be_unchecked (reader); + *type = gst_byte_reader_get_uint32_le_unchecked (reader); + + if (size_field == 1) { + if (gst_byte_reader_get_remaining (reader) < 8) + goto not_enough_data; + *size = gst_byte_reader_get_uint64_be_unchecked (reader); + } else { + *size = size_field; + } + + if (*type == GST_ISOFF_FOURCC_UUID) { + if (gst_byte_reader_get_remaining (reader) < 16) + goto not_enough_data; + + if (extended_type) + memcpy (extended_type, gst_byte_reader_get_data_unchecked (reader, 16), + 16); + } + + if (header_size) + *header_size = gst_byte_reader_get_pos (reader) - header_start_offset; + + return TRUE; + +not_enough_data: + gst_byte_reader_set_pos (reader, header_start_offset); + return FALSE; +} + +static void +gst_isoff_trun_box_clear (GstTrunBox * trun) +{ + if (trun->samples) + g_array_free (trun->samples, TRUE); +} + +static void +gst_isoff_traf_box_clear (GstTrafBox * traf) +{ + if (traf->trun) + g_array_free (traf->trun, TRUE); +} + +static gboolean +gst_isoff_mfhd_box_parse (GstMfhdBox * mfhd, GstByteReader * reader) +{ + guint8 version; + guint32 flags; + + if (gst_byte_reader_get_remaining (reader) != 8) + return FALSE; + + version = gst_byte_reader_get_uint8_unchecked (reader); + if (version != 0) + return FALSE; + + flags = gst_byte_reader_get_uint24_be_unchecked (reader); + if (flags != 0) + return FALSE; + + mfhd->sequence_number = gst_byte_reader_get_uint32_be_unchecked (reader); + + return TRUE; +} + +static gboolean +gst_isoff_tfhd_box_parse (GstTfhdBox * tfhd, GstByteReader * reader) +{ + memset (tfhd, 0, sizeof (*tfhd)); + + if (gst_byte_reader_get_remaining (reader) < 4) + return FALSE; + + tfhd->version = gst_byte_reader_get_uint8_unchecked (reader); + if (tfhd->version != 0) + return FALSE; + + tfhd->flags = gst_byte_reader_get_uint24_be_unchecked (reader); + + if (!gst_byte_reader_get_uint32_be (reader, &tfhd->track_id)) + return FALSE; + + if ((tfhd->flags & GST_TFHD_FLAGS_BASE_DATA_OFFSET_PRESENT) && + !gst_byte_reader_get_uint64_be (reader, &tfhd->base_data_offset)) + return FALSE; + + if ((tfhd->flags & GST_TFHD_FLAGS_SAMPLE_DESCRIPTION_INDEX_PRESENT) && + !gst_byte_reader_get_uint32_be (reader, &tfhd->sample_description_index)) + return FALSE; + + if ((tfhd->flags & GST_TFHD_FLAGS_DEFAULT_SAMPLE_DURATION_PRESENT) && + !gst_byte_reader_get_uint32_be (reader, &tfhd->default_sample_duration)) + return FALSE; + + if ((tfhd->flags & GST_TFHD_FLAGS_DEFAULT_SAMPLE_SIZE_PRESENT) && + !gst_byte_reader_get_uint32_be (reader, &tfhd->default_sample_size)) + return FALSE; + + if ((tfhd->flags & GST_TFHD_FLAGS_DEFAULT_SAMPLE_FLAGS_PRESENT) && + !gst_byte_reader_get_uint32_be (reader, &tfhd->default_sample_flags)) + return FALSE; + + return TRUE; +} + +static gboolean +gst_isoff_trun_box_parse (GstTrunBox * trun, GstByteReader * reader) +{ + gint i; + + memset (trun, 0, sizeof (*trun)); + + if (gst_byte_reader_get_remaining (reader) < 4) + return FALSE; + + trun->version = gst_byte_reader_get_uint8_unchecked (reader); + if (trun->version != 0 && trun->version != 1) + return FALSE; + + trun->flags = gst_byte_reader_get_uint24_be_unchecked (reader); + + if (!gst_byte_reader_get_uint32_be (reader, &trun->sample_count)) + return FALSE; + + trun->samples = + g_array_sized_new (FALSE, FALSE, sizeof (GstTrunSample), + trun->sample_count); + + if ((trun->flags & GST_TRUN_FLAGS_DATA_OFFSET_PRESENT) && + !gst_byte_reader_get_uint32_be (reader, (guint32 *) & trun->data_offset)) + return FALSE; + + if ((trun->flags & GST_TRUN_FLAGS_FIRST_SAMPLE_FLAGS_PRESENT) && + !gst_byte_reader_get_uint32_be (reader, &trun->first_sample_flags)) + return FALSE; + + for (i = 0; i < trun->sample_count; i++) { + GstTrunSample sample = { 0, }; + + if ((trun->flags & GST_TRUN_FLAGS_SAMPLE_DURATION_PRESENT) && + !gst_byte_reader_get_uint32_be (reader, &sample.sample_duration)) + goto error; + + if ((trun->flags & GST_TRUN_FLAGS_SAMPLE_SIZE_PRESENT) && + !gst_byte_reader_get_uint32_be (reader, &sample.sample_size)) + goto error; + + if ((trun->flags & GST_TRUN_FLAGS_SAMPLE_FLAGS_PRESENT) && + !gst_byte_reader_get_uint32_be (reader, &sample.sample_flags)) + goto error; + + if ((trun->flags & GST_TRUN_FLAGS_SAMPLE_COMPOSITION_TIME_OFFSETS_PRESENT) + && !gst_byte_reader_get_uint32_be (reader, + &sample.sample_composition_time_offset.u)) + goto error; + + g_array_append_val (trun->samples, sample); + } + + return TRUE; + +error: + gst_isoff_trun_box_clear (trun); + return FALSE; +} + +static gboolean +gst_isoff_traf_box_parse (GstTrafBox * traf, GstByteReader * reader) +{ + gboolean had_tfhd = FALSE; + + memset (traf, 0, sizeof (*traf)); + traf->trun = g_array_new (FALSE, FALSE, sizeof (GstTrunBox)); + g_array_set_clear_func (traf->trun, + (GDestroyNotify) gst_isoff_trun_box_clear); + + while (gst_byte_reader_get_remaining (reader) > 0) { + guint32 fourcc; + guint header_size; + guint64 size; + + if (!gst_isoff_parse_box_header (reader, &fourcc, NULL, &header_size, + &size)) + goto error; + if (gst_byte_reader_get_remaining (reader) < size - header_size) + goto error; + + switch (fourcc) { + case GST_ISOFF_FOURCC_TFHD:{ + GstByteReader sub_reader; + + gst_byte_reader_get_sub_reader (reader, &sub_reader, + size - header_size); + if (!gst_isoff_tfhd_box_parse (&traf->tfhd, &sub_reader)) + goto error; + had_tfhd = TRUE; + break; + } + case GST_ISOFF_FOURCC_TRUN:{ + GstByteReader sub_reader; + GstTrunBox trun; + + gst_byte_reader_get_sub_reader (reader, &sub_reader, + size - header_size); + if (!gst_isoff_trun_box_parse (&trun, &sub_reader)) + goto error; + + g_array_append_val (traf->trun, trun); + break; + } + default: + gst_byte_reader_skip (reader, size - header_size); + break; + } + } + + if (!had_tfhd) + goto error; + + return TRUE; + +error: + gst_isoff_traf_box_clear (traf); + + return FALSE; +} + +GstMoofBox * +gst_isoff_moof_box_parse (GstByteReader * reader) +{ + GstMoofBox *moof; + gboolean had_mfhd = FALSE; + + + INITIALIZE_DEBUG_CATEGORY; + moof = g_new0 (GstMoofBox, 1); + moof->traf = g_array_new (FALSE, FALSE, sizeof (GstTrafBox)); + g_array_set_clear_func (moof->traf, + (GDestroyNotify) gst_isoff_traf_box_clear); + + while (gst_byte_reader_get_remaining (reader) > 0) { + guint32 fourcc; + guint header_size; + guint64 size; + + if (!gst_isoff_parse_box_header (reader, &fourcc, NULL, &header_size, + &size)) + goto error; + if (gst_byte_reader_get_remaining (reader) < size - header_size) + goto error; + + switch (fourcc) { + case GST_ISOFF_FOURCC_MFHD:{ + GstByteReader sub_reader; + + gst_byte_reader_get_sub_reader (reader, &sub_reader, + size - header_size); + if (!gst_isoff_mfhd_box_parse (&moof->mfhd, &sub_reader)) + goto error; + had_mfhd = TRUE; + break; + } + case GST_ISOFF_FOURCC_TRAF:{ + GstByteReader sub_reader; + GstTrafBox traf; + + gst_byte_reader_get_sub_reader (reader, &sub_reader, + size - header_size); + if (!gst_isoff_traf_box_parse (&traf, &sub_reader)) + goto error; + + g_array_append_val (moof->traf, traf); + break; + } + default: + gst_byte_reader_skip (reader, size - header_size); + break; + } + } + + if (!had_mfhd) + goto error; + + return moof; + +error: + gst_isoff_moof_box_free (moof); + return NULL; +} + +void +gst_isoff_moof_box_free (GstMoofBox * moof) +{ + g_array_free (moof->traf, TRUE); + g_free (moof); +} + +void +gst_isoff_sidx_parser_init (GstSidxParser * parser) +{ + parser->status = GST_ISOFF_SIDX_PARSER_INIT; + parser->cumulative_entry_size = 0; + parser->sidx.entries = NULL; + parser->sidx.entries_count = 0; +} + +void +gst_isoff_sidx_parser_clear (GstSidxParser * parser) +{ + g_free (parser->sidx.entries); + memset (parser, 0, sizeof (*parser)); + + gst_isoff_sidx_parser_init (parser); +} + +static void +gst_isoff_parse_sidx_entry (GstSidxBoxEntry * entry, GstByteReader * reader) +{ + guint32 aux; + + aux = gst_byte_reader_get_uint32_be_unchecked (reader); + entry->ref_type = aux >> 31; + entry->size = aux & 0x7FFFFFFF; + entry->duration = gst_byte_reader_get_uint32_be_unchecked (reader); + aux = gst_byte_reader_get_uint32_be_unchecked (reader); + entry->starts_with_sap = aux >> 31; + entry->sap_type = ((aux >> 28) & 0x7); + entry->sap_delta_time = aux & 0xFFFFFFF; +} + +GstIsoffParserResult +gst_isoff_sidx_parser_parse (GstSidxParser * parser, + GstByteReader * reader, guint * consumed) +{ + GstIsoffParserResult res = GST_ISOFF_PARSER_OK; + gsize remaining; + + INITIALIZE_DEBUG_CATEGORY; + switch (parser->status) { + case GST_ISOFF_SIDX_PARSER_INIT: + /* Try again once we have enough data for the FullBox header */ + if (gst_byte_reader_get_remaining (reader) < 4) { + gst_byte_reader_set_pos (reader, 0); + break; + } + parser->sidx.version = gst_byte_reader_get_uint8_unchecked (reader); + parser->sidx.flags = gst_byte_reader_get_uint24_le_unchecked (reader); + + parser->status = GST_ISOFF_SIDX_PARSER_HEADER; + + case GST_ISOFF_SIDX_PARSER_HEADER: + remaining = gst_byte_reader_get_remaining (reader); + if (remaining < 12 + (parser->sidx.version == 0 ? 8 : 16)) { + break; + } + + parser->sidx.ref_id = gst_byte_reader_get_uint32_be_unchecked (reader); + parser->sidx.timescale = gst_byte_reader_get_uint32_be_unchecked (reader); + if (parser->sidx.version == 0) { + parser->sidx.earliest_pts = + gst_byte_reader_get_uint32_be_unchecked (reader); + parser->sidx.first_offset = + gst_byte_reader_get_uint32_be_unchecked (reader); + } else { + parser->sidx.earliest_pts = + gst_byte_reader_get_uint64_be_unchecked (reader); + parser->sidx.first_offset = + gst_byte_reader_get_uint64_be_unchecked (reader); + } + /* skip 2 reserved bytes */ + gst_byte_reader_skip_unchecked (reader, 2); + parser->sidx.entries_count = + gst_byte_reader_get_uint16_be_unchecked (reader); + + GST_LOG ("Timescale: %" G_GUINT32_FORMAT, parser->sidx.timescale); + GST_LOG ("Earliest pts: %" G_GUINT64_FORMAT, parser->sidx.earliest_pts); + GST_LOG ("First offset: %" G_GUINT64_FORMAT, parser->sidx.first_offset); + + parser->cumulative_pts = + gst_util_uint64_scale_int_round (parser->sidx.earliest_pts, + GST_SECOND, parser->sidx.timescale); + + if (parser->sidx.entries_count) { + parser->sidx.entries = + g_malloc (sizeof (GstSidxBoxEntry) * parser->sidx.entries_count); + } + parser->sidx.entry_index = 0; + + parser->status = GST_ISOFF_SIDX_PARSER_DATA; + + case GST_ISOFF_SIDX_PARSER_DATA: + while (parser->sidx.entry_index < parser->sidx.entries_count) { + GstSidxBoxEntry *entry = + &parser->sidx.entries[parser->sidx.entry_index]; + + remaining = gst_byte_reader_get_remaining (reader); + if (remaining < 12) + break; + + entry->offset = parser->cumulative_entry_size; + entry->pts = parser->cumulative_pts; + gst_isoff_parse_sidx_entry (entry, reader); + entry->duration = gst_util_uint64_scale_int_round (entry->duration, + GST_SECOND, parser->sidx.timescale); + parser->cumulative_entry_size += entry->size; + parser->cumulative_pts += entry->duration; + + GST_LOG ("Sidx entry %d) offset: %" G_GUINT64_FORMAT ", pts: %" + GST_TIME_FORMAT ", duration %" GST_TIME_FORMAT " - size %" + G_GUINT32_FORMAT, parser->sidx.entry_index, entry->offset, + GST_TIME_ARGS (entry->pts), GST_TIME_ARGS (entry->duration), + entry->size); + + parser->sidx.entry_index++; + } + + if (parser->sidx.entry_index == parser->sidx.entries_count) + parser->status = GST_ISOFF_SIDX_PARSER_FINISHED; + else + break; + case GST_ISOFF_SIDX_PARSER_FINISHED: + parser->sidx.entry_index = 0; + res = GST_ISOFF_PARSER_DONE; + break; + } + + *consumed = gst_byte_reader_get_pos (reader); + + return res; +} + +GstIsoffParserResult +gst_isoff_sidx_parser_add_buffer (GstSidxParser * parser, GstBuffer * buffer, + guint * consumed) +{ + GstIsoffParserResult res = GST_ISOFF_PARSER_OK; + GstByteReader reader; + GstMapInfo info; + guint32 fourcc; + + INITIALIZE_DEBUG_CATEGORY; + if (!gst_buffer_map (buffer, &info, GST_MAP_READ)) { + *consumed = 0; + return GST_ISOFF_PARSER_ERROR; + } + + gst_byte_reader_init (&reader, info.data, info.size); + + if (parser->status == GST_ISOFF_SIDX_PARSER_INIT) { + if (!gst_isoff_parse_box_header (&reader, &fourcc, NULL, NULL, + &parser->size)) + goto done; + + if (fourcc != GST_ISOFF_FOURCC_SIDX) { + res = GST_ISOFF_PARSER_UNEXPECTED; + gst_byte_reader_set_pos (&reader, 0); + goto done; + } + + if (parser->size == 0) { + res = GST_ISOFF_PARSER_ERROR; + gst_byte_reader_set_pos (&reader, 0); + goto done; + } + + /* Try again once we have enough data for the FullBox header */ + if (gst_byte_reader_get_remaining (&reader) < 4) { + gst_byte_reader_set_pos (&reader, 0); + goto done; + } + } + + res = gst_isoff_sidx_parser_parse (parser, &reader, consumed); + +done: + gst_buffer_unmap (buffer, &info); + return res; +} diff --git a/gst-libs/gst/isoff/gstisoff.h b/gst-libs/gst/isoff/gstisoff.h new file mode 100644 index 000000000..ee160aa10 --- /dev/null +++ b/gst-libs/gst/isoff/gstisoff.h @@ -0,0 +1,195 @@ +/* + * ISO File Format parsing library + * + * gstisoff.h + * + * Copyright (C) 2015 Samsung Electronics. All rights reserved. + * Author: Thiago Santos <thiagoss@osg.samsung.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library (COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GST_ISOFF_H__ +#define __GST_ISOFF_H__ + +#include <gst/gst.h> +#include <gst/base/base.h> + +G_BEGIN_DECLS + +typedef enum { + GST_ISOFF_PARSER_OK, + GST_ISOFF_PARSER_DONE, + GST_ISOFF_PARSER_UNEXPECTED, + GST_ISOFF_PARSER_ERROR +} GstIsoffParserResult; + +gboolean gst_isoff_parse_box_header (GstByteReader * reader, guint32 * type, guint8 extended_type[16], guint * header_size, guint64 * size); + +#define GST_ISOFF_FOURCC_UUID GST_MAKE_FOURCC('u','u','i','d') +#define GST_ISOFF_FOURCC_MOOF GST_MAKE_FOURCC('m','o','o','f') +#define GST_ISOFF_FOURCC_MFHD GST_MAKE_FOURCC('m','f','h','d') +#define GST_ISOFF_FOURCC_TFHD GST_MAKE_FOURCC('t','f','h','d') +#define GST_ISOFF_FOURCC_TRUN GST_MAKE_FOURCC('t','r','u','n') +#define GST_ISOFF_FOURCC_TRAF GST_MAKE_FOURCC('t','r','a','f') +#define GST_ISOFF_FOURCC_MDAT GST_MAKE_FOURCC('m','d','a','t') +#define GST_ISOFF_FOURCC_SIDX GST_MAKE_FOURCC('s','i','d','x') + +#define GST_ISOFF_SAMPLE_FLAGS_IS_LEADING(flags) (((flags) >> 26) & 0x03) +#define GST_ISOFF_SAMPLE_FLAGS_SAMPLE_DEPENDS_ON(flags) (((flags) >> 24) & 0x03) +#define GST_ISOFF_SAMPLE_FLAGS_SAMPLE_IS_DEPENDED_ON(flags) (((flags) >> 22) & 0x03) +#define GST_ISOFF_SAMPLE_FLAGS_SAMPLE_HAS_REDUNDANCY(flags) (((flags) >> 20) & 0x03) +#define GST_ISOFF_SAMPLE_FLAGS_SAMPLE_PADDING_VALUE(flags) (((flags) >> 17) & 0x07) +#define GST_ISOFF_SAMPLE_FLAGS_SAMPLE_IS_NON_SYNC_SAMPLE(flags) (((flags) >> 16) & 0x01) +#define GST_ISOFF_SAMPLE_FLAGS_SAMPLE_DEGRADATION_PRIORITY(flags) (((flags) >> 0) & 0x0f) + +typedef struct _GstMfhdBox +{ + guint32 sequence_number; +} GstMfhdBox; + +typedef enum +{ + GST_TFHD_FLAGS_BASE_DATA_OFFSET_PRESENT = 0x000001, + GST_TFHD_FLAGS_SAMPLE_DESCRIPTION_INDEX_PRESENT = 0x000002, + GST_TFHD_FLAGS_DEFAULT_SAMPLE_DURATION_PRESENT = 0x000008, + GST_TFHD_FLAGS_DEFAULT_SAMPLE_SIZE_PRESENT = 0x000010, + GST_TFHD_FLAGS_DEFAULT_SAMPLE_FLAGS_PRESENT = 0x000020, + GST_TFHD_FLAGS_DURATION_IS_EMPTY = 0x010000, + GST_TFHD_FLAGS_DEFAULT_BASE_IS_MOOF = 0x020000 +} GstTfhdFlags; + +typedef struct _GstTfhdBox +{ + guint8 version; + GstTfhdFlags flags; + + guint32 track_id; + + /* optional */ + guint64 base_data_offset; + guint32 sample_description_index; + guint32 default_sample_duration; + guint32 default_sample_size; + guint32 default_sample_flags; +} GstTfhdBox; + +typedef enum +{ + GST_TRUN_FLAGS_DATA_OFFSET_PRESENT = 0x000001, + GST_TRUN_FLAGS_FIRST_SAMPLE_FLAGS_PRESENT = 0x000004, + GST_TRUN_FLAGS_SAMPLE_DURATION_PRESENT = 0x000100, + GST_TRUN_FLAGS_SAMPLE_SIZE_PRESENT = 0x000200, + GST_TRUN_FLAGS_SAMPLE_FLAGS_PRESENT = 0x000400, + GST_TRUN_FLAGS_SAMPLE_COMPOSITION_TIME_OFFSETS_PRESENT = 0x000800 +} GstTrunFlags; + +typedef struct _GstTrunBox +{ + guint8 version; + GstTrunFlags flags; + + guint32 sample_count; + + /* optional */ + gint32 data_offset; + guint32 first_sample_flags; + GArray *samples; +} GstTrunBox; + +typedef struct _GstTrunSample +{ + guint32 sample_duration; + guint32 sample_size; + guint32 sample_flags; + + union { + guint32 u; /* version 0 */ + gint32 s; /* others */ + } sample_composition_time_offset; +} GstTrunSample; + +typedef struct _GstTrafBox +{ + GstTfhdBox tfhd; + GArray *trun; +} GstTrafBox; + +typedef struct _GstMoofBox +{ + GstMfhdBox mfhd; + GArray *traf; +} GstMoofBox; + +GstMoofBox * gst_isoff_moof_box_parse (GstByteReader *reader); +void gst_isoff_moof_box_free (GstMoofBox *moof); + +typedef struct _GstSidxBoxEntry +{ + gboolean ref_type; + guint32 size; + GstClockTime duration; + gboolean starts_with_sap; + guint8 sap_type; + guint32 sap_delta_time; + + guint64 offset; + GstClockTime pts; +} GstSidxBoxEntry; + +typedef struct _GstSidxBox +{ + guint8 version; + guint32 flags; + + guint32 ref_id; + guint32 timescale; + guint64 earliest_pts; + guint64 first_offset; + + gint entry_index; + gint entries_count; + + GstSidxBoxEntry *entries; +} GstSidxBox; + +typedef enum _GstSidxParserStatus +{ + GST_ISOFF_SIDX_PARSER_INIT, + GST_ISOFF_SIDX_PARSER_HEADER, + GST_ISOFF_SIDX_PARSER_DATA, + GST_ISOFF_SIDX_PARSER_FINISHED +} GstSidxParserStatus; + +typedef struct _GstSidxParser +{ + GstSidxParserStatus status; + + guint64 size; + guint64 cumulative_entry_size; + guint64 cumulative_pts; + + GstSidxBox sidx; +} GstSidxParser; + +void gst_isoff_sidx_parser_init (GstSidxParser * parser); +void gst_isoff_sidx_parser_clear (GstSidxParser * parser); +GstIsoffParserResult gst_isoff_sidx_parser_parse (GstSidxParser * parser, GstByteReader * reader, guint * consumed); +GstIsoffParserResult gst_isoff_sidx_parser_add_buffer (GstSidxParser * parser, GstBuffer * buf, guint * consumed); + +G_END_DECLS + +#endif /* __GST_ISOFF_H__ */ diff --git a/gst-libs/gst/isoff/meson.build b/gst-libs/gst/isoff/meson.build new file mode 100644 index 000000000..97acd0ea1 --- /dev/null +++ b/gst-libs/gst/isoff/meson.build @@ -0,0 +1,22 @@ +isoff_sources = [ + 'gstisoff.c', +] +isoff_headers = [ + 'gstisoff.h', +] +install_headers(isoff_headers, subdir : 'gstreamer-1.0/gst/isoff') + +gstisoff = library('gstisoff-' + api_version, + isoff_sources, + c_args : gst_plugins_bad_args + [ '-DGST_USE_UNSTABLE_API' ], + include_directories : [configinc, libsinc], + version : libversion, + soversion : soversion, + install : true, + dependencies : [gstbase_dep], + vs_module_defs: vs_module_defs_dir + 'libgstisoff.def', +) + +gstisoff_dep = declare_dependency(link_with : gstisoff, + include_directories : [libsinc], + dependencies : [gstbase_dep]) |