summaryrefslogtreecommitdiff
path: root/ext/smoothstreaming
diff options
context:
space:
mode:
Diffstat (limited to 'ext/smoothstreaming')
-rw-r--r--ext/smoothstreaming/Makefile.am1
-rw-r--r--ext/smoothstreaming/gstmssfragmentparser.c226
-rw-r--r--ext/smoothstreaming/gstmssfragmentparser.h37
-rw-r--r--ext/smoothstreaming/gstmssmanifest.c19
4 files changed, 55 insertions, 228 deletions
diff --git a/ext/smoothstreaming/Makefile.am b/ext/smoothstreaming/Makefile.am
index cbf782c38..b32d0bb2e 100644
--- a/ext/smoothstreaming/Makefile.am
+++ b/ext/smoothstreaming/Makefile.am
@@ -7,6 +7,7 @@ libgstsmoothstreaming_la_CFLAGS = $(GST_PLUGINS_BAD_CFLAGS) \
libgstsmoothstreaming_la_LIBADD = \
$(top_builddir)/gst-libs/gst/codecparsers/libgstcodecparsers-$(GST_API_VERSION).la \
$(top_builddir)/gst-libs/gst/adaptivedemux/libgstadaptivedemux-@GST_API_VERSION@.la \
+ $(top_builddir)/gst-libs/gst/isoff/libgstisoff-@GST_API_VERSION@.la \
$(GST_PLUGINS_BASE_LIBS) \
-lgsttag-$(GST_API_VERSION) \
$(GST_BASE_LIBS) $(GST_LIBS) $(ZLIB_LIBS) $(LIBXML2_LIBS)
diff --git a/ext/smoothstreaming/gstmssfragmentparser.c b/ext/smoothstreaming/gstmssfragmentparser.c
index b554d4f31..5cbd3e041 100644
--- a/ext/smoothstreaming/gstmssfragmentparser.c
+++ b/ext/smoothstreaming/gstmssfragmentparser.c
@@ -34,101 +34,15 @@ void
gst_mss_fragment_parser_init (GstMssFragmentParser * parser)
{
parser->status = GST_MSS_FRAGMENT_HEADER_PARSER_INIT;
- parser->tfrf.entries_count = 0;
}
void
gst_mss_fragment_parser_clear (GstMssFragmentParser * parser)
{
- parser->tfrf.entries_count = 0;
- if (parser->tfrf.entries) {
- g_free (parser->tfrf.entries);
- parser->tfrf.entries = 0;
- }
-}
-
-static gboolean
-_parse_tfrf_box (GstMssFragmentParser * parser, GstByteReader * reader)
-{
- guint8 version;
- guint32 flags = 0;
- guint8 fragment_count = 0;
- guint8 index = 0;
-
- 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;
- }
-
- gst_byte_reader_get_uint8 (reader, &fragment_count);
- parser->tfrf.entries_count = fragment_count;
- parser->tfrf.entries =
- g_malloc (sizeof (GstTfrfBoxEntry) * parser->tfrf.entries_count);
- for (index = 0; index < fragment_count; index++) {
- guint64 absolute_time = 0;
- guint64 absolute_duration = 0;
- 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);
- time = ~time;
- duration = ~duration;
- absolute_time = ~time;
- absolute_duration = ~duration;
- }
- parser->tfrf.entries[index].time = absolute_time;
- parser->tfrf.entries[index].duration = absolute_duration;
- }
-
- GST_LOG ("tfrf box parsed");
- return TRUE;
-}
-
-static gboolean
-_parse_tfxd_box (GstMssFragmentParser * parser, GstByteReader * reader)
-{
- guint8 version;
- guint32 flags = 0;
- guint64 absolute_time = 0;
- guint64 absolute_duration = 0;
-
- 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;
- }
-
- 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);
- time = ~time;
- duration = ~duration;
- absolute_time = ~time;
- absolute_duration = ~duration;
- }
-
- parser->tfxd.time = absolute_time;
- parser->tfxd.duration = absolute_duration;
- GST_LOG ("tfxd box parsed");
- return TRUE;
+ if (parser->moof)
+ gst_isoff_moof_box_free (parser->moof);
+ parser->moof = NULL;
+ parser->current_fourcc = 0;
}
gboolean
@@ -137,26 +51,10 @@ gst_mss_fragment_parser_add_buffer (GstMssFragmentParser * parser,
{
GstByteReader reader;
GstMapInfo info;
- guint32 size;
+ guint64 size;
guint32 fourcc;
- const guint8 *uuid;
+ guint header_size;
gboolean error = FALSE;
- gboolean mdat_box_found = FALSE;
-
- 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
- };
-
- static const guint8 piff_uuid[] = {
- 0xa2, 0x39, 0x4f, 0x52, 0x5a, 0x9b, 0x4f, 0x14,
- 0xa2, 0x44, 0x6c, 0x42, 0x7c, 0x64, 0x8d, 0xf4
- };
if (!gst_buffer_map (buffer, &info, GST_MAP_READ)) {
return FALSE;
@@ -165,98 +63,56 @@ gst_mss_fragment_parser_add_buffer (GstMssFragmentParser * parser,
gst_byte_reader_init (&reader, info.data, info.size);
GST_TRACE ("Total buffer size: %u", gst_byte_reader_get_size (&reader));
- size = gst_byte_reader_get_uint32_be_unchecked (&reader);
- fourcc = gst_byte_reader_get_uint32_le_unchecked (&reader);
- if (fourcc == GST_MSS_FRAGMENT_FOURCC_MOOF) {
- GST_TRACE ("moof box found");
- size = gst_byte_reader_get_uint32_be_unchecked (&reader);
- fourcc = gst_byte_reader_get_uint32_le_unchecked (&reader);
- if (fourcc == GST_MSS_FRAGMENT_FOURCC_MFHD) {
- gst_byte_reader_skip_unchecked (&reader, size - 8);
+ do {
+ parser->current_fourcc = 0;
- size = gst_byte_reader_get_uint32_be_unchecked (&reader);
- fourcc = gst_byte_reader_get_uint32_le_unchecked (&reader);
- if (fourcc == GST_MSS_FRAGMENT_FOURCC_TRAF) {
- size = gst_byte_reader_get_uint32_be_unchecked (&reader);
- fourcc = gst_byte_reader_get_uint32_le_unchecked (&reader);
- if (fourcc == GST_MSS_FRAGMENT_FOURCC_TFHD) {
- gst_byte_reader_skip_unchecked (&reader, size - 8);
-
- size = gst_byte_reader_get_uint32_be_unchecked (&reader);
- fourcc = gst_byte_reader_get_uint32_le_unchecked (&reader);
- if (fourcc == GST_MSS_FRAGMENT_FOURCC_TRUN) {
- GST_TRACE ("trun box found, size: %" G_GUINT32_FORMAT, size);
- if (!gst_byte_reader_skip (&reader, size - 8)) {
- GST_WARNING ("Failed to skip trun box, enough data?");
- error = TRUE;
- goto beach;
- }
- }
- }
- }
- }
- }
-
- while (!mdat_box_found) {
- GST_TRACE ("remaining data: %u", gst_byte_reader_get_remaining (&reader));
- if (!gst_byte_reader_get_uint32_be (&reader, &size)) {
- GST_WARNING ("Failed to get box size, enough data?");
- error = TRUE;
+ if (!gst_isoff_parse_box_header (&reader, &fourcc, NULL, &header_size,
+ &size)) {
break;
}
- GST_TRACE ("box size: %" G_GUINT32_FORMAT, size);
- if (!gst_byte_reader_get_uint32_le (&reader, &fourcc)) {
- GST_WARNING ("Failed to get fourcc, enough data?");
- error = TRUE;
- break;
- }
+ parser->current_fourcc = fourcc;
- if (fourcc == GST_MSS_FRAGMENT_FOURCC_MDAT) {
- GST_LOG ("mdat box found");
- mdat_box_found = TRUE;
- break;
- }
+ GST_LOG ("box %" GST_FOURCC_FORMAT " size %" G_GUINT64_FORMAT,
+ GST_FOURCC_ARGS (fourcc), size);
- if (fourcc != GST_MSS_FRAGMENT_FOURCC_UUID) {
- GST_ERROR ("invalid UUID fourcc: %" GST_FOURCC_FORMAT,
- GST_FOURCC_ARGS (fourcc));
- error = TRUE;
- break;
- }
+ parser->current_fourcc = fourcc;
- if (!gst_byte_reader_peek_data (&reader, 16, &uuid)) {
- GST_ERROR ("not enough data in UUID box");
- error = TRUE;
- break;
- }
-
- if (memcmp (uuid, piff_uuid, 16) == 0) {
- gst_byte_reader_skip_unchecked (&reader, size - 8);
- GST_LOG ("piff box detected");
- }
+ if (parser->current_fourcc == GST_ISOFF_FOURCC_MOOF) {
+ GstByteReader sub_reader;
- if (memcmp (uuid, tfrf_uuid, 16) == 0) {
- gst_byte_reader_get_data (&reader, 16, &uuid);
- if (!_parse_tfrf_box (parser, &reader)) {
- GST_ERROR ("txrf box parsing error");
+ g_assert (parser->moof == NULL);
+ gst_byte_reader_get_sub_reader (&reader, &sub_reader, size - header_size);
+ parser->moof = gst_isoff_moof_box_parse (&sub_reader);
+ if (parser->moof == NULL) {
+ GST_ERROR ("Failed to parse moof");
error = TRUE;
- break;
}
+ } else if (parser->current_fourcc == GST_ISOFF_FOURCC_MDAT) {
+ goto beach;
+ } else {
+ gst_byte_reader_skip (&reader, size - header_size);
}
+ } while (gst_byte_reader_get_remaining (&reader) > 0);
- if (memcmp (uuid, tfxd_uuid, 16) == 0) {
- gst_byte_reader_get_data (&reader, 16, &uuid);
- if (!_parse_tfxd_box (parser, &reader)) {
- GST_ERROR ("tfrf box parsing error");
- error = TRUE;
- break;
- }
+beach:
+
+ /* Do sanity check */
+ if (parser->current_fourcc != GST_ISOFF_FOURCC_MDAT || !parser->moof ||
+ parser->moof->traf->len == 0)
+ error = TRUE;
+
+ if (!error) {
+ GstTrafBox *traf = &g_array_index (parser->moof->traf, GstTrafBox, 0);
+ if (!traf->tfxd) {
+ GST_ERROR ("no tfxd box");
+ error = TRUE;
+ } else if (!traf->tfrf) {
+ GST_ERROR ("no tfrf box");
+ error = TRUE;
}
}
-beach:
-
if (!error)
parser->status = GST_MSS_FRAGMENT_HEADER_PARSER_FINISHED;
diff --git a/ext/smoothstreaming/gstmssfragmentparser.h b/ext/smoothstreaming/gstmssfragmentparser.h
index cf4711865..3ae2484aa 100644
--- a/ext/smoothstreaming/gstmssfragmentparser.h
+++ b/ext/smoothstreaming/gstmssfragmentparser.h
@@ -27,41 +27,10 @@
#define __GST_MSS_FRAGMENT_PARSER_H__
#include <gst/gst.h>
+#include <gst/isoff/gstisoff.h>
G_BEGIN_DECLS
-#define GST_MSS_FRAGMENT_FOURCC_MOOF GST_MAKE_FOURCC('m','o','o','f')
-#define GST_MSS_FRAGMENT_FOURCC_MFHD GST_MAKE_FOURCC('m','f','h','d')
-#define GST_MSS_FRAGMENT_FOURCC_TRAF GST_MAKE_FOURCC('t','r','a','f')
-#define GST_MSS_FRAGMENT_FOURCC_TFHD GST_MAKE_FOURCC('t','f','h','d')
-#define GST_MSS_FRAGMENT_FOURCC_TRUN GST_MAKE_FOURCC('t','r','u','n')
-#define GST_MSS_FRAGMENT_FOURCC_UUID GST_MAKE_FOURCC('u','u','i','d')
-#define GST_MSS_FRAGMENT_FOURCC_MDAT GST_MAKE_FOURCC('m','d','a','t')
-
-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;
- GstTfrfBoxEntry *entries;
-} GstTfrfBox;
-
typedef enum _GstFragmentHeaderParserStatus
{
GST_MSS_FRAGMENT_HEADER_PARSER_INIT,
@@ -71,8 +40,8 @@ typedef enum _GstFragmentHeaderParserStatus
typedef struct _GstMssFragmentParser
{
GstFragmentHeaderParserStatus status;
- GstTfxdBox tfxd;
- GstTfrfBox tfrf;
+ GstMoofBox *moof;
+ guint32 current_fourcc;
} GstMssFragmentParser;
void gst_mss_fragment_parser_init (GstMssFragmentParser * parser);
diff --git a/ext/smoothstreaming/gstmssmanifest.c b/ext/smoothstreaming/gstmssmanifest.c
index fb1eb0df8..2085b364d 100644
--- a/ext/smoothstreaming/gstmssmanifest.c
+++ b/ext/smoothstreaming/gstmssmanifest.c
@@ -1600,9 +1600,10 @@ gst_mss_stream_fragment_parsing_needed (GstMssStream * stream)
void
gst_mss_stream_parse_fragment (GstMssStream * stream, GstBuffer * buffer)
{
- GstMssStreamFragment *current_fragment = NULL;
const gchar *stream_type_name;
guint8 index;
+ GstMoofBox *moof;
+ GstTrafBox *traf;
if (!stream->has_live_fragments)
return;
@@ -1610,20 +1611,20 @@ gst_mss_stream_parse_fragment (GstMssStream * stream, GstBuffer * buffer)
if (!gst_mss_fragment_parser_add_buffer (&stream->fragment_parser, buffer))
return;
- current_fragment = stream->current_fragment->data;
- current_fragment->time = stream->fragment_parser.tfxd.time;
- current_fragment->duration = stream->fragment_parser.tfxd.duration;
+ moof = stream->fragment_parser.moof;
+ traf = &g_array_index (moof->traf, GstTrafBox, 0);
stream_type_name =
gst_mss_stream_type_name (gst_mss_stream_get_type (stream));
- for (index = 0; index < stream->fragment_parser.tfrf.entries_count; index++) {
+ for (index = 0; index < traf->tfrf->entries_count; index++) {
+ GstTfrfBoxEntry *entry =
+ &g_array_index (traf->tfrf->entries, GstTfrfBoxEntry, index);
GList *l = g_list_last (stream->fragments);
GstMssStreamFragment *last;
GstMssStreamFragment *fragment;
- guint64 parsed_time = stream->fragment_parser.tfrf.entries[index].time;
- guint64 parsed_duration =
- stream->fragment_parser.tfrf.entries[index].duration;
+ guint64 parsed_time = entry->time;
+ guint64 parsed_duration = entry->duration;
if (l == NULL)
break;
@@ -1632,7 +1633,7 @@ gst_mss_stream_parse_fragment (GstMssStream * stream, GstBuffer * buffer)
/* only add the fragment to the list if it's outside the time in the
* current list */
- if (last->time >= stream->fragment_parser.tfrf.entries[index].time)
+ if (last->time >= entry->time)
continue;
fragment = g_new (GstMssStreamFragment, 1);