mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-18 22:36:33 +00:00
qtdemux: Add cslg support
The cslg atom provide information about the DTS shift. This is needed in recent version of ctts atom where the offset can be negative. When cslg is missing, we parse the CTTS table as proposed in the spec to calculate these values. In this implementation, we only need to know the shift. As GStreamer cannot transport negative timestamps, we shift the timestamps forward using that value and adapt the segment to compensate. This patch also removes bogus offset of ctts_soffset, this offset shall be included in the edit list. https://bugzilla.gnome.org/show_bug.cgi?id=751103
This commit is contained in:
parent
89104e35bf
commit
dd72267a8d
1 changed files with 50 additions and 6 deletions
|
@ -127,7 +127,7 @@ struct _QtDemuxSample
|
|||
/* timestamp is the DTS */
|
||||
#define QTSAMPLE_DTS(stream,sample) (QTSTREAMTIME_TO_GSTTIME((stream), (sample)->timestamp))
|
||||
/* timestamp + offset is the PTS */
|
||||
#define QTSAMPLE_PTS(stream,sample) (QTSTREAMTIME_TO_GSTTIME((stream), (sample)->timestamp + (sample)->pts_offset))
|
||||
#define QTSAMPLE_PTS(stream,sample) (QTSTREAMTIME_TO_GSTTIME((stream), (sample)->timestamp + (stream)->cslg_shift + (sample)->pts_offset))
|
||||
/* timestamp + duration - dts is the duration */
|
||||
#define QTSAMPLE_DUR_DTS(stream, sample, dts) (QTSTREAMTIME_TO_GSTTIME ((stream), (sample)->timestamp + (sample)->duration) - (dts))
|
||||
|
||||
|
@ -376,6 +376,9 @@ struct _QtDemuxStream
|
|||
guint32 ctts_count;
|
||||
gint32 ctts_soffset;
|
||||
|
||||
/* cslg */
|
||||
guint32 cslg_shift;
|
||||
|
||||
/* fragmented */
|
||||
gboolean parsed_trex;
|
||||
guint32 def_sample_duration;
|
||||
|
@ -3749,10 +3752,10 @@ gst_qtdemux_activate_segment (GstQTDemux * qtdemux, QtDemuxStream * stream,
|
|||
stream->segment.base = qtdemux->segment.base;
|
||||
stream->segment.applied_rate = qtdemux->segment.applied_rate;
|
||||
stream->segment.rate = rate;
|
||||
stream->segment.start = start +
|
||||
QTSTREAMTIME_TO_GSTTIME (stream, stream->ctts_soffset);
|
||||
stream->segment.stop = stop +
|
||||
QTSTREAMTIME_TO_GSTTIME (stream, stream->ctts_soffset);
|
||||
stream->segment.start = start + QTSTREAMTIME_TO_GSTTIME (stream,
|
||||
stream->cslg_shift);
|
||||
stream->segment.stop = stop + QTSTREAMTIME_TO_GSTTIME (stream,
|
||||
stream->cslg_shift);
|
||||
stream->segment.time = time;
|
||||
stream->segment.position = stream->segment.start;
|
||||
|
||||
|
@ -6740,11 +6743,12 @@ qtdemux_stbl_init (GstQTDemux * qtdemux, QtDemuxStream * stream, GNode * stbl)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/* composition time-to-sample */
|
||||
if ((stream->ctts_present =
|
||||
! !qtdemux_tree_get_child_by_type_full (stbl, FOURCC_ctts,
|
||||
&stream->ctts) ? TRUE : FALSE) == TRUE) {
|
||||
GstByteReader cslg = GST_BYTE_READER_INIT (NULL, 0);
|
||||
|
||||
/* copy atom data into a new buffer for later use */
|
||||
stream->ctts.data = g_memdup (stream->ctts.data, stream->ctts.size);
|
||||
|
||||
|
@ -6758,6 +6762,46 @@ qtdemux_stbl_init (GstQTDemux * qtdemux, QtDemuxStream * stream, GNode * stbl)
|
|||
if (!qt_atom_parser_has_chunks (&stream->ctts, stream->n_composition_times,
|
||||
4 + 4))
|
||||
goto corrupt_file;
|
||||
|
||||
/* 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)) {
|
||||
g_free ((gpointer) cslg.data);
|
||||
goto corrupt_file;
|
||||
}
|
||||
} else {
|
||||
gint32 cslg_least = 0;
|
||||
guint num_entries, pos;
|
||||
gint i;
|
||||
|
||||
pos = gst_byte_reader_get_pos (&stream->ctts);
|
||||
num_entries = stream->n_composition_times;
|
||||
|
||||
stream->cslg_shift = 0;
|
||||
|
||||
for (i = 0; i < num_entries; i++) {
|
||||
gint32 offset;
|
||||
|
||||
gst_byte_reader_skip_unchecked (&stream->ctts, 4);
|
||||
offset = gst_byte_reader_get_int32_be_unchecked (&stream->ctts);
|
||||
|
||||
if (offset < cslg_least)
|
||||
cslg_least = offset;
|
||||
}
|
||||
|
||||
if (cslg_least < 0)
|
||||
stream->cslg_shift = ABS (cslg_least);
|
||||
else
|
||||
stream->cslg_shift = 0;
|
||||
|
||||
/* reset the reader so we can generate sample table */
|
||||
gst_byte_reader_set_pos (&stream->ctts, pos);
|
||||
}
|
||||
} else {
|
||||
/* Ensure the cslg_shift value is consistent so we can use it
|
||||
* unconditionnally to produce TS and Segment */
|
||||
stream->cslg_shift = 0;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
|
Loading…
Reference in a new issue