summaryrefslogtreecommitdiff
path: root/gst-libs/gst/isoff
diff options
context:
space:
mode:
authorSeungha Yang <sh.yang@lge.com>2017-07-02 14:27:33 +0900
committerReynaldo H. Verdejo Pinochet <reynaldo@osg.samsung.com>2017-08-25 17:21:32 -0700
commit98576325e31fe355022bb2d9bfaffd12f5c02c46 (patch)
tree853b0bfed9fd40c27b1e08bd53f8db4787006096 /gst-libs/gst/isoff
parent3db9152ec6a9a55b009dcc9d5f02ec60080af4db (diff)
downloadgstreamer-plugins-bad-98576325e31fe355022bb2d9bfaffd12f5c02c46.tar.gz
isoff: Add parsing mss specific tfrf and tfxd boxes
This code is imported from mssdemux's tfxd/tfrf parsing function https://bugzilla.gnome.org/show_bug.cgi?id=777825
Diffstat (limited to 'gst-libs/gst/isoff')
-rw-r--r--gst-libs/gst/isoff/gstisoff.c165
-rw-r--r--gst-libs/gst/isoff/gstisoff.h30
2 files changed, 193 insertions, 2 deletions
diff --git a/gst-libs/gst/isoff/gstisoff.c b/gst-libs/gst/isoff/gstisoff.c
index 7aef9b4cc..5baed0946 100644
--- a/gst-libs/gst/isoff/gstisoff.c
+++ b/gst-libs/gst/isoff/gstisoff.c
@@ -39,6 +39,16 @@ static gboolean initialized = FALSE;
initialized = TRUE; \
}
+static const guint8 tfrf_uuid[] = {
+ 0xd4, 0x80, 0x7e, 0xf2, 0xca, 0x39, 0x46, 0x95,
+ 0x8e, 0x54, 0x26, 0xcb, 0x9e, 0x46, 0xa7, 0x9f
+};
+
+static const guint8 tfxd_uuid[] = {
+ 0x6d, 0x1d, 0x9b, 0x05, 0x42, 0xd5, 0x44, 0xe6,
+ 0x80, 0xe2, 0x14, 0x1d, 0xaf, 0xf7, 0x57, 0xb2
+};
+
/* gst_isoff_parse_box_header:
* @reader:
* @type: type that was found at the current position
@@ -102,10 +112,27 @@ gst_isoff_trun_box_clear (GstTrunBox * trun)
}
static void
+gst_isoff_tfrf_box_free (GstTfrfBox * tfrf)
+{
+ if (tfrf->entries)
+ g_array_free (tfrf->entries, TRUE);
+
+ g_free (tfrf);
+}
+
+static void
gst_isoff_traf_box_clear (GstTrafBox * traf)
{
if (traf->trun)
g_array_free (traf->trun, TRUE);
+
+ if (traf->tfrf)
+ gst_isoff_tfrf_box_free (traf->tfrf);
+
+ g_free (traf->tfxd);
+ traf->trun = NULL;
+ traf->tfrf = NULL;
+ traf->tfxd = NULL;
}
static gboolean
@@ -260,6 +287,118 @@ gst_isoff_tfdt_box_parse (GstTfdtBox * tfdt, GstByteReader * reader)
}
static gboolean
+gst_isoff_tfxd_box_parse (GstTfxdBox * tfxd, GstByteReader * reader)
+{
+ guint8 version;
+ guint32 flags = 0;
+ guint64 absolute_time = 0;
+ guint64 absolute_duration = 0;
+
+ memset (tfxd, 0, sizeof (*tfxd));
+
+ if (gst_byte_reader_get_remaining (reader) < 4)
+ return FALSE;
+
+ if (!gst_byte_reader_get_uint8 (reader, &version)) {
+ GST_ERROR ("Error getting box's version field");
+ return FALSE;
+ }
+
+ if (!gst_byte_reader_get_uint24_be (reader, &flags)) {
+ GST_ERROR ("Error getting box's flags field");
+ return FALSE;
+ }
+
+ tfxd->version = version;
+ tfxd->flags = flags;
+
+ if (gst_byte_reader_get_remaining (reader) < ((version & 0x01) ? 16 : 8))
+ return FALSE;
+
+ if (version & 0x01) {
+ gst_byte_reader_get_uint64_be (reader, &absolute_time);
+ gst_byte_reader_get_uint64_be (reader, &absolute_duration);
+ } else {
+ guint32 time = 0;
+ guint32 duration = 0;
+ gst_byte_reader_get_uint32_be (reader, &time);
+ gst_byte_reader_get_uint32_be (reader, &duration);
+ absolute_time = time;
+ absolute_duration = duration;
+ }
+
+ tfxd->time = absolute_time;
+ tfxd->duration = absolute_duration;
+
+ return TRUE;
+}
+
+static gboolean
+gst_isoff_tfrf_box_parse (GstTfrfBox * tfrf, GstByteReader * reader)
+{
+ guint8 version;
+ guint32 flags = 0;
+ guint8 fragment_count = 0;
+ guint8 index = 0;
+
+ memset (tfrf, 0, sizeof (*tfrf));
+
+ if (gst_byte_reader_get_remaining (reader) < 4)
+ return FALSE;
+
+ if (!gst_byte_reader_get_uint8 (reader, &version)) {
+ GST_ERROR ("Error getting box's version field");
+ return FALSE;
+ }
+
+ if (!gst_byte_reader_get_uint24_be (reader, &flags)) {
+ GST_ERROR ("Error getting box's flags field");
+ return FALSE;
+ }
+
+ tfrf->version = version;
+ tfrf->flags = flags;
+
+ if (!gst_byte_reader_get_uint8 (reader, &fragment_count))
+ return FALSE;
+
+ tfrf->entries_count = fragment_count;
+ tfrf->entries =
+ g_array_sized_new (FALSE, FALSE, sizeof (GstTfrfBoxEntry),
+ tfrf->entries_count);
+
+ for (index = 0; index < fragment_count; index++) {
+ GstTfrfBoxEntry entry = { 0, };
+ guint64 absolute_time = 0;
+ guint64 absolute_duration = 0;
+ if (gst_byte_reader_get_remaining (reader) < ((version & 0x01) ? 16 : 8))
+ return FALSE;
+
+ if (version & 0x01) {
+ if (!gst_byte_reader_get_uint64_be (reader, &absolute_time) ||
+ !gst_byte_reader_get_uint64_be (reader, &absolute_duration)) {
+ return FALSE;
+ }
+ } else {
+ guint32 time = 0;
+ guint32 duration = 0;
+ if (!gst_byte_reader_get_uint32_be (reader, &time) ||
+ !gst_byte_reader_get_uint32_be (reader, &duration)) {
+ return FALSE;
+ }
+ absolute_time = time;
+ absolute_duration = duration;
+ }
+ entry.time = absolute_time;
+ entry.duration = absolute_duration;
+
+ g_array_append_val (tfrf->entries, entry);
+ }
+
+ return TRUE;
+}
+
+static gboolean
gst_isoff_traf_box_parse (GstTrafBox * traf, GstByteReader * reader)
{
gboolean had_tfhd = FALSE;
@@ -276,9 +415,10 @@ gst_isoff_traf_box_parse (GstTrafBox * traf, GstByteReader * reader)
guint header_size;
guint64 size;
GstByteReader sub_reader;
+ guint8 extended_type[16] = { 0, };
- if (!gst_isoff_parse_box_header (reader, &fourcc, NULL, &header_size,
- &size))
+ if (!gst_isoff_parse_box_header (reader, &fourcc, extended_type,
+ &header_size, &size))
goto error;
if (gst_byte_reader_get_remaining (reader) < size - header_size)
goto error;
@@ -310,6 +450,27 @@ gst_isoff_traf_box_parse (GstTrafBox * traf, GstByteReader * reader)
g_array_append_val (traf->trun, trun);
break;
}
+ case GST_ISOFF_FOURCC_UUID:{
+ /* smooth-streaming specific */
+ if (memcmp (extended_type, tfrf_uuid, 16) == 0) {
+ traf->tfrf = g_new0 (GstTfrfBox, 1);
+ gst_byte_reader_get_sub_reader (reader, &sub_reader,
+ size - header_size);
+
+ if (!gst_isoff_tfrf_box_parse (traf->tfrf, &sub_reader))
+ goto error;
+ } else if (memcmp (extended_type, tfxd_uuid, 16) == 0) {
+ traf->tfxd = g_new0 (GstTfxdBox, 1);
+ gst_byte_reader_get_sub_reader (reader, &sub_reader,
+ size - header_size);
+
+ if (!gst_isoff_tfxd_box_parse (traf->tfxd, &sub_reader))
+ goto error;
+ } else {
+ gst_byte_reader_skip (reader, size - header_size);
+ }
+ break;
+ }
default:
gst_byte_reader_skip (reader, size - header_size);
break;
diff --git a/gst-libs/gst/isoff/gstisoff.h b/gst-libs/gst/isoff/gstisoff.h
index c2f03909b..8904571af 100644
--- a/gst-libs/gst/isoff/gstisoff.h
+++ b/gst-libs/gst/isoff/gstisoff.h
@@ -67,6 +67,32 @@ gboolean gst_isoff_parse_box_header (GstByteReader * reader, guint32 * type, gui
#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)
+/* Smooth-Streaming specific boxes */
+typedef struct _GstTfxdBox
+{
+ guint8 version;
+ guint32 flags;
+
+ guint64 time;
+ guint64 duration;
+} GstTfxdBox;
+
+typedef struct _GstTfrfBoxEntry
+{
+ guint64 time;
+ guint64 duration;
+} GstTfrfBoxEntry;
+
+typedef struct _GstTfrfBox
+{
+ guint8 version;
+ guint32 flags;
+
+ gint entries_count;
+ GArray *entries;
+} GstTfrfBox;
+
+/* Common boxes */
typedef struct _GstMfhdBox
{
guint32 sequence_number;
@@ -143,6 +169,10 @@ typedef struct _GstTrafBox
GstTfhdBox tfhd;
GstTfdtBox tfdt;
GArray *trun;
+
+ /* smooth-streaming specific */
+ GstTfrfBox *tfrf;
+ GstTfxdBox *tfxd;
} GstTrafBox;
typedef struct _GstMoofBox