Need to respect return of gst_video_guess_framerate() to ensure
non-zero denominator.
This patch is to fix below error with an abnormal (but has valid frame) file.
(gst-play-1.0:17940): GStreamer-CRITICAL **: passed '0' as denominator for `GstFraction'
This problem was found in Test. 2 of the YouTube 2018 EME
tests[1]. The code was accidentally not finding an mp4a's esds atom in
the sample description table when the stream was encrypted. It assumed
that if the stream is protected, then only an enca atom will be found
here. What happens with YouTube is they often provide protected
content with a few seconds of clear content, and then switch to the
encrypted stream.
The failure case here was an incorrect codec_data field being sent
into aacparse. The advertisement of stereo audio @ 44.1kHz for the
mp4a (unprotected) stream was incorrect. As usual, the esds contained
the real values here which were mono at 22050 Hz.
Here's what the MP4 tree looks like for these types of files,
demonstrating why the code was making a wrong assumption (or maybe
YouTube is being unusual),
[ftyp] size=8+16
...
[moov] size=8+1571
...
[trak] size=8+559
...
[stsd] size=12+234
entry-count = 2
[enca] size=8+147
channel_count = 2
sample_size = 16
sample_rate = 44100
[esds] size=12+27
...
...
[mp4a] size=8+67
channel_count = 2
sample_size = 16
sample_rate = 44100
[esds] size=12+27
...
In addition to fixing this, the checks for esds atoms in mp4a and mp4v
have been made symmetrical. While I haven't seen a test case for video
with the same problem, it seemed better to make the same checks. This
also fixes a crash reported from another user[2], they also noted the
asymmetry with mp4v and mp4a.
[1] https://yt-dash-mse-test.commondatastorage.googleapis.com/unit-tests/2018.html?test_type=encryptedmedia-test
[2] https://gitlab.freedesktop.org/gstreamer/gst-plugins-good/issues/398
Recent changes in ccextractor were attaching timecode meta to the closed
caption track. We shouldn't write timecode information for the closed
caption trak.
EA608 closed caption tracks are a bit special in that each sample
can contain CCs for multiple frames, and CCs can be omitted and have to
be inferred from the duration of the sample then.
As such we take the framerate from the (first) video track here for
CEA608 as there must be one CC byte pair for every video frame
according to the spec.
For CEA708 all is fine and there is one sample per frame.
The duration field being a uint64, is stored in 8 bytes, not 4. So the offset of
the following field, language code, needs to be updated accordingly so that the
parsed language code is not garbage.
stream.segment should be updated with the values of the current edit
list, also when a new `moov` is received. Unfortunately this was not
being the case because of an early return.
As a consequence of this bugs, no end of movie clipping was being
performed on the new moov and no segment event was being emitted.
When performing stream switching (e.g. in MSE) the new moov may have a
different edit list. This is often the case when switching between
baseline H.264 (which lacks B-frames) and more demanding profiles. For
this reason it's important to emit a new segment in order to be able
to get matching stream times.
This patch moves the initialization of QtDemuxStream.segment from
gst_qtdemux_add_stream() to _create_stream(). This ensures the segment
is always initialized when the stream is created.
Otherwise the segment format is left as GST_FORMAT_UNDEFINED in the case
were a track is reparsed and qtdemux_reuse_and_configure_stream() is
called instead of gst_qtdemux_add_stream(). (See
qtdemux_expose_streams() in the non streams-aware case.)
If ctts (CompositionOffsetBox) has larger sample_offset
(offset between PTS and DTS) than (2 * duration) of the stream,
assume the ctts box to be corrupted and ignore the box.
https://bugzilla.gnome.org/show_bug.cgi?id=797262
This fixes a bug where in some files mehd.fragment_duration is one unit
less than the actual duration of the fragmented movie, as explained below:
mehd.fragment_duration is computed by scaling the end timestamp of
the last frame of the movie in (in nanoseconds) by the movie timescale.
In some situations, the end timestamp is innacurate due to lossy conversion to
fixed point required by GstBuffer upstream.
Take for instance a movie with 3 frames at exactly 3 fps.
$ gst-launch-1.0 -v videotestsrc num-buffers=3 \
! video/x-raw, framerate="(fraction)3/1" \
! x264enc \
! fakesink silent=false
dts: 999:59:59.333333334, pts: 1000:00:00.000000000, duration: 0:00:00.333333333
dts: 999:59:59.666666667, pts: 1000:00:00.666666666, duration: 0:00:00.333333334
dts: 1000:00:00.000000000, pts: 1000:00:00.333333333, duration: 0:00:00.333333333
The end timestamp is calculated by qtmux in this way:
end timestamp = last frame DTS + last frame DUR - first frame DTS =
= 1000:00:00.000000000 + 0:00:00.333333333 - 999:59:59.333333334 =
= 0:00:00.999999999
qtmux needs to round this timestamp to the declared movie timescale, which can
ameliorate this distortion, but it's important that round-neareast is used;
otherwise it would backfire badly.
Take for example a movie with a timescale of 30 units/s.
0.999999999 s * 30 units/s = 29.999999970 units
A round-floor (as it was done before this patch) would set fragment_duration to
29 units, amplifying the original distorsion from 1 nanosecond up to 33
milliseconds less than the correct value. The greatest distortion would occur
in the case where timescale = framerate, where an entire frame duration would
be subtracted.
Also, rounding is added to tkhd duration computation too, which
potentially has the same problem.
https://bugzilla.gnome.org/show_bug.cgi?id=793959
... before the old streams is not exposed yet for MSS stream.
In case of DASH, newly configured streams will be exposed
whenever demux got moov without delay.
Meanwhile, since there is no moov box in MSS stream,
the caps will act like moov. Then, there is delay for exposing new pads
until demux got the first moof.
So, following scenario is possible only for MSS but not for DASH,
STREAM-START -> CAPS -> (configure stream but NOT EXPOSED YET)
-> STREAM-START-> CAPS (configure stream again).
In above scenario, we can reuse old stream without any stream reconfigure.
https://bugzilla.gnome.org/show_bug.cgi?id=797239
qtdemux_update_streams() is only ever called after checking
`qtdemux->streams_aware` is TRUE. There is no need to check for that
condition again.
`qtdemux->streams_aware` is only modified when the demuxer is
hard-resetted, which is mutually exclusive with demuxing, so it cannot
be modified during the call.
https://bugzilla.gnome.org/show_bug.cgi?id=797191
For 59.94 FPS, it's common to set 60000 as timescale. For that
timescale, if the audio is late by as little as 0:00:00.000016666
(definitely less than one audio sample), lateness gets rounded to 1.
Added a safeguard that allows lateness up to 1 sample with the specific
trak's timescale, to make sure that values less than e.g. one audio
sample won't break the prefill mode. What will happen in this case is
that the audio will get squeezed back to the video's timestamp, which in
practice means that the audio will be 0.000016666 seconds early (with
the patch).
https://bugzilla.gnome.org/show_bug.cgi?id=797133
This patch clears the sample table whenever the demuxing of a new
fragment begins. This avoids increasing memory usage for long videos.
This behavior was already present when upstream_format_is_time; this
patch extends it to all push mode operation (e.g. Media Source
Extensions).
https://bugzilla.gnome.org/show_bug.cgi?id=796899
* When receiving a segment in TIME, use that seqnum
* Only reset the stored sequence number when doing HARD reset
(and not when we get a FLUSH event from upstream)