qtdemux: fix computation of first_duration for fragmented files in push mode

Since ca068865c3 the duration of the first
frame is not used for estimating the frame rate.

For this purpose, stream->first_duration was initialized with the
duration of the first frame. In fragmented files, this was previously
done by peeking the first moof, but that can only be done in pull mode.

Fortunately, we don't really need to do that, at least with the current
design: When we are estimating the frame rate we already have the
sample table, regardless of the scheduling mode and whether the file is
fragmented or not, so we can obtain first_duration there much more
reliably.

This fixes frame rate estimation for fragmented files in push mode.

https://bugzilla.gnome.org/show_bug.cgi?id=796384
This commit is contained in:
Alicia Boya García 2018-05-24 12:58:00 +02:00 committed by Thibault Saunier
parent d11339d616
commit 5388d6e6a2

View file

@ -310,8 +310,6 @@ struct _QtDemuxStream
guint32 n_samples; guint32 n_samples;
QtDemuxSample *samples; QtDemuxSample *samples;
gboolean all_keyframe; /* TRUE when all samples are keyframes (no stss) */ gboolean all_keyframe; /* TRUE when all samples are keyframes (no stss) */
guint32 first_duration; /* duration in timescale of first sample, used for figuring out
the framerate */
guint32 n_samples_moof; /* sample count in a moof */ guint32 n_samples_moof; /* sample count in a moof */
guint64 duration_moof; /* duration in timescale of a moof, used for figure out guint64 duration_moof; /* duration in timescale of a moof, used for figure out
* the framerate of fragmented format stream */ * the framerate of fragmented format stream */
@ -8201,8 +8199,12 @@ gst_qtdemux_configure_stream (GstQTDemux * qtdemux, QtDemuxStream * stream)
/* fps is calculated base on the duration of the average framerate since /* fps is calculated base on the duration of the average framerate since
* qt does not have a fixed framerate. */ * qt does not have a fixed framerate. */
gboolean fps_available = TRUE; gboolean fps_available = TRUE;
guint32 first_duration = 0;
if ((stream->n_samples == 1 && stream->first_duration == 0) if (stream->n_samples > 0)
first_duration = stream->samples[0].duration;
if ((stream->n_samples == 1 && first_duration == 0)
|| (qtdemux->fragmented && stream->n_samples_moof == 1)) { || (qtdemux->fragmented && stream->n_samples_moof == 1)) {
/* still frame */ /* still frame */
CUR_STREAM (stream)->fps_n = 0; CUR_STREAM (stream)->fps_n = 0;
@ -8232,14 +8234,14 @@ gst_qtdemux_configure_stream (GstQTDemux * qtdemux, QtDemuxStream * stream)
/* stream->duration is guint64, timescale, n_samples are guint32 */ /* stream->duration is guint64, timescale, n_samples are guint32 */
avg_duration = avg_duration =
gst_util_uint64_scale_round (duration - gst_util_uint64_scale_round (duration -
stream->first_duration, GST_SECOND, first_duration, GST_SECOND,
(guint64) (stream->timescale) * (n_samples - 1)); (guint64) (stream->timescale) * (n_samples - 1));
GST_LOG_OBJECT (qtdemux, GST_LOG_OBJECT (qtdemux,
"Calculating avg sample duration based on stream (or moof) duration %" "Calculating avg sample duration based on stream (or moof) duration %"
G_GUINT64_FORMAT G_GUINT64_FORMAT
" minus first sample %u, leaving %d samples gives %" " minus first sample %u, leaving %d samples gives %"
GST_TIME_FORMAT, duration, stream->first_duration, GST_TIME_FORMAT, duration, first_duration,
n_samples - 1, GST_TIME_ARGS (avg_duration)); n_samples - 1, GST_TIME_ARGS (avg_duration));
gst_video_guess_framerate (avg_duration, &CUR_STREAM (stream)->fps_n, gst_video_guess_framerate (avg_duration, &CUR_STREAM (stream)->fps_n,
@ -12264,11 +12266,6 @@ qtdemux_prepare_streams (GstQTDemux * qtdemux)
break; break;
++sample_num; ++sample_num;
} }
if (stream->n_samples > 0 && stream->stbl_index >= 0) {
stream->first_duration = stream->samples[0].duration;
GST_LOG_OBJECT (qtdemux, "track-id %u first duration %u",
stream->track_id, stream->first_duration);
}
} }
return ret; return ret;