diff options
author | Seungha Yang <sh.yang@lge.com> | 2017-05-17 22:09:48 +0900 |
---|---|---|
committer | Reynaldo H. Verdejo Pinochet <reynaldo@osg.samsung.com> | 2017-08-25 17:21:41 -0700 |
commit | 0f1de50222e7fb5b738ad89dd060701add450699 (patch) | |
tree | 6cf44048ebc02745e93d22f2f066cfd3cc60e78d /ext/smoothstreaming | |
parent | 98576325e31fe355022bb2d9bfaffd12f5c02c46 (diff) | |
download | gstreamer-plugins-bad-0f1de50222e7fb5b738ad89dd060701add450699.tar.gz |
smoothstreaming: Use isoff to parse tfxd/tfrf
https://bugzilla.gnome.org/show_bug.cgi?id=777825
Diffstat (limited to 'ext/smoothstreaming')
-rw-r--r-- | ext/smoothstreaming/Makefile.am | 1 | ||||
-rw-r--r-- | ext/smoothstreaming/gstmssfragmentparser.c | 226 | ||||
-rw-r--r-- | ext/smoothstreaming/gstmssfragmentparser.h | 37 | ||||
-rw-r--r-- | ext/smoothstreaming/gstmssmanifest.c | 19 |
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); |