From 284dd5443f8c21f767301fb0de141c24015e418e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Tue, 2 Nov 2021 17:41:01 +0200 Subject: [PATCH] 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: --- .../gst-plugins-good/gst/isomp4/qtdemux.c | 26 ++++++++++++- .../gst-plugins-good/gst/isomp4/qtdemux.h | 2 +- .../gst/isomp4/qtdemux_dump.c | 38 +++++++++++++------ 3 files changed, 52 insertions(+), 14 deletions(-) diff --git a/subprojects/gst-plugins-good/gst/isomp4/qtdemux.c b/subprojects/gst-plugins-good/gst/isomp4/qtdemux.c index ae30290291..ccbc68b63d 100644 --- a/subprojects/gst-plugins-good/gst/isomp4/qtdemux.c +++ b/subprojects/gst-plugins-good/gst/isomp4/qtdemux.c @@ -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; diff --git a/subprojects/gst-plugins-good/gst/isomp4/qtdemux.h b/subprojects/gst-plugins-good/gst/isomp4/qtdemux.h index 742915cb01..e61deb6c21 100644 --- a/subprojects/gst-plugins-good/gst/isomp4/qtdemux.h +++ b/subprojects/gst-plugins-good/gst/isomp4/qtdemux.h @@ -478,7 +478,7 @@ struct _QtDemuxStream gint32 ctts_soffset; /* cslg */ - guint32 cslg_shift; + guint64 cslg_shift; /* fragmented */ gboolean parsed_trex; diff --git a/subprojects/gst-plugins-good/gst/isomp4/qtdemux_dump.c b/subprojects/gst-plugins-good/gst/isomp4/qtdemux_dump.c index 25921dfe2e..7f1aaa5eab 100644 --- a/subprojects/gst-plugins-good/gst/isomp4/qtdemux_dump.c +++ b/subprojects/gst-plugins-good/gst/isomp4/qtdemux_dump.c @@ -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; }