qtdemux: Add support for version 1 cslg boxes

They use 64 bit fields instead of 32 bit.

Also parse offset as a signed integer (in both versions) and clamp it to
a positive value as negative values don't really interest us here.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1294>
This commit is contained in:
Sebastian Dröge 2021-11-02 17:41:01 +02:00 committed by GStreamer Marge Bot
parent 7f105a919a
commit 284dd5443f
3 changed files with 52 additions and 14 deletions

View file

@ -9385,9 +9385,31 @@ qtdemux_stbl_init (GstQTDemux * qtdemux, QtDemuxStream * stream, GNode * stbl)
/* This is optional, if missing we iterate the ctts */
if (qtdemux_tree_get_child_by_type_full (stbl, FOURCC_cslg, &cslg)) {
if (!gst_byte_reader_skip (&cslg, 1 + 3)
|| !gst_byte_reader_get_uint32_be (&cslg, &stream->cslg_shift))
guint8 cslg_version;
/* cslg version 1 has 64 bit fields */
if (!gst_byte_reader_get_uint8 (&cslg, &cslg_version))
goto corrupt_file;
/* skip flags */
if (!gst_byte_reader_skip (&cslg, 3))
goto corrupt_file;
if (cslg_version == 0) {
gint32 composition_to_dts_shift;
if (!gst_byte_reader_get_int32_be (&cslg, &composition_to_dts_shift))
goto corrupt_file;
stream->cslg_shift = MAX (0, composition_to_dts_shift);
} else {
gint64 composition_to_dts_shift;
if (!gst_byte_reader_get_int64_be (&cslg, &composition_to_dts_shift))
goto corrupt_file;
stream->cslg_shift = MAX (0, composition_to_dts_shift);
}
} else {
gint32 cslg_least = 0;
guint num_entries, pos;

View file

@ -478,7 +478,7 @@ struct _QtDemuxStream
gint32 ctts_soffset;
/* cslg */
guint32 cslg_shift;
guint64 cslg_shift;
/* fragmented */
gboolean parsed_trex;

View file

@ -577,21 +577,37 @@ qtdemux_dump_ctts (GstQTDemux * qtdemux, GstByteReader * data, int depth)
gboolean
qtdemux_dump_cslg (GstQTDemux * qtdemux, GstByteReader * data, int depth)
{
guint32 ver_flags = 0, shift = 0;
gint32 least_offset = 0, start_time = 0, end_time = 0;
guint32 ver_flags = 0;
if (!gst_byte_reader_get_uint32_be (data, &ver_flags) ||
!gst_byte_reader_get_uint32_be (data, &shift) ||
!gst_byte_reader_get_int32_be (data, &least_offset) ||
!gst_byte_reader_get_int32_be (data, &start_time) ||
!gst_byte_reader_get_int32_be (data, &end_time))
if (!gst_byte_reader_get_uint32_be (data, &ver_flags))
return FALSE;
GST_LOG ("%*s version/flags: %08x", depth, "", ver_flags);
GST_LOG ("%*s shift: %u", depth, "", shift);
GST_LOG ("%*s least offset: %d", depth, "", least_offset);
GST_LOG ("%*s start time: %d", depth, "", start_time);
GST_LOG ("%*s end time: %d", depth, "", end_time);
if (ver_flags >> 24 == 0) {
gint32 shift = 0, least_offset = 0, start_time = 0, end_time = 0;
if (!gst_byte_reader_get_int32_be (data, &shift) ||
!gst_byte_reader_get_int32_be (data, &least_offset) ||
!gst_byte_reader_get_int32_be (data, &start_time) ||
!gst_byte_reader_get_int32_be (data, &end_time))
return FALSE;
GST_LOG ("%*s shift: %d", depth, "", shift);
GST_LOG ("%*s least offset: %d", depth, "", least_offset);
GST_LOG ("%*s start time: %d", depth, "", start_time);
GST_LOG ("%*s end time: %d", depth, "", end_time);
} else {
gint64 shift = 0, least_offset = 0, start_time = 0, end_time = 0;
if (!gst_byte_reader_get_int64_be (data, &shift) ||
!gst_byte_reader_get_int64_be (data, &least_offset) ||
!gst_byte_reader_get_int64_be (data, &start_time) ||
!gst_byte_reader_get_int64_be (data, &end_time))
return FALSE;
GST_LOG ("%*s shift: %" G_GINT64_FORMAT, depth, "", shift);
GST_LOG ("%*s least offset: %" G_GINT64_FORMAT, depth, "", least_offset);
GST_LOG ("%*s start time: %" G_GINT64_FORMAT, depth, "", start_time);
GST_LOG ("%*s end time: %" G_GINT64_FORMAT, depth, "", end_time);
}
return TRUE;
}