From: Sebastian Dröge Date: Fri, 12 Nov 2021 11:00:56 +0000 (+0200) Subject: qtdemux: Use a composition time offset of 0 for "no decode samples" for the time... X-Git-Tag: 1.20.0~290 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=12e918428aa9658d23b082fe8378362ff8b118ee;p=platform%2Fupstream%2Fgstreamer.git qtdemux: Use a composition time offset of 0 for "no decode samples" for the time being This needs codec-specific handling, but using 0 instead of G_MININT32 at least gives somewhat reasonable behaviour. See https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/883 Part-of: --- diff --git a/subprojects/gst-plugins-good/gst/isomp4/qtdemux.c b/subprojects/gst-plugins-good/gst/isomp4/qtdemux.c index 1847f46..6da4796 100644 --- a/subprojects/gst-plugins-good/gst/isomp4/qtdemux.c +++ b/subprojects/gst-plugins-good/gst/isomp4/qtdemux.c @@ -3425,6 +3425,11 @@ qtdemux_parse_trun (GstQTDemux * qtdemux, GstByteReader * trun, * high offsets are unlikely and there are files out there that use * version=0 truns with negative offsets */ ct = QT_UINT32 (data + ct_offset); + + /* FIXME: Set offset to 0 for "no decode samples". This needs + * to be handled in a codec specific manner ideally. */ + if (ct == G_MININT32) + ct = 0; } else { ct = 0; } @@ -9457,18 +9462,21 @@ qtdemux_stbl_init (GstQTDemux * qtdemux, QtDemuxStream * stream, GNode * stbl) offset = gst_byte_reader_get_int32_be_unchecked (&stream->ctts); /* HACK: if sample_offset is larger than 2 * duration, ignore the box. * slightly inaccurate PTS could be more usable than corrupted one */ - if (G_UNLIKELY ((ABS (offset) / 2) > stream->duration)) { + if (G_UNLIKELY ((ctts_version == 0 || offset != G_MININT32) + && ABS (offset) / 2 > stream->duration)) { GST_WARNING_OBJECT (qtdemux, "Ignore corrupted ctts, sample_offset %" G_GINT32_FORMAT - " larger than duration %" G_GUINT64_FORMAT, - offset, stream->duration); + " larger than duration %" G_GUINT64_FORMAT, offset, + stream->duration); stream->cslg_shift = 0; stream->ctts_present = FALSE; goto done; } - if (offset < cslg_least) + /* Don't consider "no decode samples" with offset G_MININT32 + * for the DTS/PTS shift */ + if (offset != G_MININT32 && offset < cslg_least) cslg_least = offset; } @@ -9496,11 +9504,12 @@ qtdemux_stbl_init (GstQTDemux * qtdemux, QtDemuxStream * stream, GNode * stbl) offset = gst_byte_reader_get_int32_be_unchecked (&stream->ctts); /* HACK: if sample_offset is larger than 2 * duration, ignore the box. * slightly inaccurate PTS could be more usable than corrupted one */ - if (G_UNLIKELY ((ABS (offset) / 2) > stream->duration)) { + if (G_UNLIKELY ((ctts_version == 0 || offset != G_MININT32) + && ABS (offset) / 2 > stream->duration)) { GST_WARNING_OBJECT (qtdemux, "Ignore corrupted ctts, sample_offset %" G_GINT32_FORMAT - " larger than duration %" G_GUINT64_FORMAT, - offset, stream->duration); + " larger than duration %" G_GUINT64_FORMAT, offset, + stream->duration); stream->cslg_shift = 0; stream->ctts_present = FALSE; @@ -9938,6 +9947,11 @@ ctts: ctts_count = stream->ctts_count; ctts_soffset = stream->ctts_soffset; + /* FIXME: Set offset to 0 for "no decode samples". This needs + * to be handled in a codec specific manner ideally. */ + if (ctts_soffset == G_MININT32) + ctts_soffset = 0; + for (j = stream->ctts_sample_index; j < ctts_count; j++) { cur->pts_offset = ctts_soffset; cur++;