mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-25 01:30:38 +00:00
qtdemux: use track fragment decoding time (tfdt) in parse_trun() for interpolation
As fallback if we don't have any existing samples as reference point yet. Based on patch by David Corvoysier <david.corvoysier@orange.com>
This commit is contained in:
parent
e24f903b13
commit
77f37a6b22
1 changed files with 24 additions and 10 deletions
|
@ -2445,8 +2445,9 @@ static gboolean
|
||||||
qtdemux_parse_trun (GstQTDemux * qtdemux, GstByteReader * trun,
|
qtdemux_parse_trun (GstQTDemux * qtdemux, GstByteReader * trun,
|
||||||
QtDemuxStream * stream, guint32 d_sample_duration, guint32 d_sample_size,
|
QtDemuxStream * stream, guint32 d_sample_duration, guint32 d_sample_size,
|
||||||
guint32 d_sample_flags, gint64 moof_offset, gint64 moof_length,
|
guint32 d_sample_flags, gint64 moof_offset, gint64 moof_length,
|
||||||
gint64 * base_offset, gint64 * running_offset)
|
gint64 * base_offset, gint64 * running_offset, gint64 decode_ts)
|
||||||
{
|
{
|
||||||
|
GstClockTime gst_ts;
|
||||||
guint64 timestamp;
|
guint64 timestamp;
|
||||||
gint32 data_offset = 0;
|
gint32 data_offset = 0;
|
||||||
guint32 flags = 0, first_flags = 0, samples_count = 0;
|
guint32 flags = 0, first_flags = 0, samples_count = 0;
|
||||||
|
@ -2457,9 +2458,9 @@ qtdemux_parse_trun (GstQTDemux * qtdemux, GstByteReader * trun,
|
||||||
gboolean ismv = FALSE;
|
gboolean ismv = FALSE;
|
||||||
|
|
||||||
GST_LOG_OBJECT (qtdemux, "parsing trun stream %d; "
|
GST_LOG_OBJECT (qtdemux, "parsing trun stream %d; "
|
||||||
"default dur %d, size %d, flags 0x%x, base offset %" G_GINT64_FORMAT,
|
"default dur %d, size %d, flags 0x%x, base offset %" G_GINT64_FORMAT ", "
|
||||||
stream->track_id, d_sample_duration, d_sample_size, d_sample_flags,
|
"decode ts %" G_GINT64_FORMAT, stream->track_id, d_sample_duration,
|
||||||
*base_offset);
|
d_sample_size, d_sample_flags, *base_offset, decode_ts);
|
||||||
|
|
||||||
/* presence of stss or not can't really tell us much,
|
/* presence of stss or not can't really tell us much,
|
||||||
* and flags and so on tend to be marginally reliable in these files */
|
* and flags and so on tend to be marginally reliable in these files */
|
||||||
|
@ -2572,12 +2573,24 @@ qtdemux_parse_trun (GstQTDemux * qtdemux, GstByteReader * trun,
|
||||||
if (G_UNLIKELY (stream->n_samples == 0)) {
|
if (G_UNLIKELY (stream->n_samples == 0)) {
|
||||||
/* the timestamp of the first sample is also provided by the tfra entry
|
/* the timestamp of the first sample is also provided by the tfra entry
|
||||||
* but we shouldn't rely on it as it is at the end of files */
|
* but we shouldn't rely on it as it is at the end of files */
|
||||||
|
if (decode_ts >= 0) {
|
||||||
|
timestamp = decode_ts;
|
||||||
|
} else {
|
||||||
timestamp = 0;
|
timestamp = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
gst_ts = gst_util_uint64_scale (timestamp, GST_SECOND, stream->timescale);
|
||||||
|
GST_INFO_OBJECT (stream->pad, "first sample ts %" GST_TIME_FORMAT,
|
||||||
|
GST_TIME_ARGS (gst_ts));
|
||||||
} else {
|
} else {
|
||||||
/* subsequent fragments extend stream */
|
/* subsequent fragments extend stream */
|
||||||
timestamp =
|
timestamp =
|
||||||
stream->samples[stream->n_samples - 1].timestamp +
|
stream->samples[stream->n_samples - 1].timestamp +
|
||||||
stream->samples[stream->n_samples - 1].duration;
|
stream->samples[stream->n_samples - 1].duration;
|
||||||
|
|
||||||
|
gst_ts = gst_util_uint64_scale (timestamp, GST_SECOND, stream->timescale);
|
||||||
|
GST_INFO_OBJECT (qtdemux, "first sample ts %" GST_TIME_FORMAT
|
||||||
|
" (extends previous samples)", GST_TIME_ARGS (gst_ts));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sample = stream->samples + stream->n_samples;
|
sample = stream->samples + stream->n_samples;
|
||||||
|
@ -2822,6 +2835,8 @@ qtdemux_parse_moof (GstQTDemux * qtdemux, const guint8 * buffer, guint length,
|
||||||
base_offset = running_offset = -1;
|
base_offset = running_offset = -1;
|
||||||
traf_node = qtdemux_tree_get_child_by_type (moof_node, FOURCC_traf);
|
traf_node = qtdemux_tree_get_child_by_type (moof_node, FOURCC_traf);
|
||||||
while (traf_node) {
|
while (traf_node) {
|
||||||
|
guint64 decode_time = 0;
|
||||||
|
|
||||||
/* Fragment Header node */
|
/* Fragment Header node */
|
||||||
tfhd_node =
|
tfhd_node =
|
||||||
qtdemux_tree_get_child_by_type_full (traf_node, FOURCC_tfhd,
|
qtdemux_tree_get_child_by_type_full (traf_node, FOURCC_tfhd,
|
||||||
|
@ -2835,17 +2850,16 @@ qtdemux_parse_moof (GstQTDemux * qtdemux, const guint8 * buffer, guint length,
|
||||||
qtdemux_tree_get_child_by_type_full (traf_node, FOURCC_tfdt,
|
qtdemux_tree_get_child_by_type_full (traf_node, FOURCC_tfdt,
|
||||||
&tfdt_data);
|
&tfdt_data);
|
||||||
if (tfdt_node) {
|
if (tfdt_node) {
|
||||||
guint64 decode_time = 0;
|
|
||||||
GstClockTime decode_time_ts;
|
GstClockTime decode_time_ts;
|
||||||
|
|
||||||
|
/* We'll use decode_time to interpolate timestamps
|
||||||
|
* in case the input timestamps are missing */
|
||||||
qtdemux_parse_tfdt (qtdemux, &tfdt_data, &decode_time);
|
qtdemux_parse_tfdt (qtdemux, &tfdt_data, &decode_time);
|
||||||
|
|
||||||
/* FIXME, we can use decode_time to interpolate timestamps
|
|
||||||
* in case the input timestamps are missing */
|
|
||||||
decode_time_ts = gst_util_uint64_scale (decode_time, GST_SECOND,
|
decode_time_ts = gst_util_uint64_scale (decode_time, GST_SECOND,
|
||||||
stream->timescale);
|
stream->timescale);
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (qtdemux, "decode time %" G_GUINT64_FORMAT
|
GST_DEBUG_OBJECT (qtdemux, "decode time %" G_GINT64_FORMAT
|
||||||
" (%" GST_TIME_FORMAT ")", decode_time,
|
" (%" GST_TIME_FORMAT ")", decode_time,
|
||||||
GST_TIME_ARGS (decode_time_ts));
|
GST_TIME_ARGS (decode_time_ts));
|
||||||
}
|
}
|
||||||
|
@ -2865,7 +2879,7 @@ qtdemux_parse_moof (GstQTDemux * qtdemux, const guint8 * buffer, guint length,
|
||||||
while (trun_node) {
|
while (trun_node) {
|
||||||
qtdemux_parse_trun (qtdemux, &trun_data, stream,
|
qtdemux_parse_trun (qtdemux, &trun_data, stream,
|
||||||
ds_duration, ds_size, ds_flags, moof_offset, length, &base_offset,
|
ds_duration, ds_size, ds_flags, moof_offset, length, &base_offset,
|
||||||
&running_offset);
|
&running_offset, decode_time);
|
||||||
/* iterate all siblings */
|
/* iterate all siblings */
|
||||||
trun_node = qtdemux_tree_get_sibling_by_type_full (trun_node, FOURCC_trun,
|
trun_node = qtdemux_tree_get_sibling_by_type_full (trun_node, FOURCC_trun,
|
||||||
&trun_data);
|
&trun_data);
|
||||||
|
|
Loading…
Reference in a new issue