Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
7
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
Justin Kim
gst-plugins-bad
Commits
0f1de502
Commit
0f1de502
authored
May 17, 2017
by
Seungha Yang
Committed by
Reynaldo H. Verdejo Pinochet
Aug 25, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
smoothstreaming: Use isoff to parse tfxd/tfrf
https://bugzilla.gnome.org/show_bug.cgi?id=777825
parent
98576325
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
55 additions
and
228 deletions
+55
-228
ext/smoothstreaming/Makefile.am
ext/smoothstreaming/Makefile.am
+1
-0
ext/smoothstreaming/gstmssfragmentparser.c
ext/smoothstreaming/gstmssfragmentparser.c
+41
-185
ext/smoothstreaming/gstmssfragmentparser.h
ext/smoothstreaming/gstmssfragmentparser.h
+3
-34
ext/smoothstreaming/gstmssmanifest.c
ext/smoothstreaming/gstmssmanifest.c
+10
-9
No files found.
ext/smoothstreaming/Makefile.am
View file @
0f1de502
...
...
@@ -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)
...
...
ext/smoothstreaming/gstmssfragmentparser.c
View file @
0f1de502
...
...
@@ -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
;
guint
32
size
;
guint
64
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
;
...
...
ext/smoothstreaming/gstmssfragmentparser.h
View file @
0f1de502
...
...
@@ -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
;
Gst
TfxdBox
tfxd
;
GstTfrfBox
tfrf
;
Gst
MoofBox
*
moof
;
guint32
current_fourcc
;
}
GstMssFragmentParser
;
void
gst_mss_fragment_parser_init
(
GstMssFragmentParser
*
parser
);
...
...
ext/smoothstreaming/gstmssmanifest.c
View file @
0f1de502
...
...
@@ -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
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment