In the scenario of "mdat | moov (with fragmented artifacts)" qtdemux
could read the moov again after the mdat because it was considering the
media as a fragmented one.
To avoid this loop this patch makes it store
the last processed moov_offset to avoid parsing it again.
And it also checks if there are any samples to play before
resturning to the mdat, so that it knows there is new data to be played.
https://bugzilla.gnome.org/show_bug.cgi?id=691570
When parsing a trak only free streams on failures if those streams
were created locally. They could have been created from a previous
fragment, in this case we they have valid info from the other fragment.
Including pads.
https://bugzilla.gnome.org/show_bug.cgi?id=691570
As for text subtitles and as suggested in #712643, throw
away the 2 byte terminator packets that some encoders insert.
This will make things better when remuxing and causes generation
of gap events.
Clean up the handling of mp4s streams. Use the generic esds
descriptor function to extract the palette, instead of hard coding
a wrong magic offset.
Add some more size safety checks when parsing ES descriptors, and
replace magic numbers with the descriptive constants that are already
defined.
Enhance dump output for stsd atoms.
Streams from both bug 712643 and historic bug 568278 now both work
correctly.
Fixes: #712643
Assume a file with atoms in the following order: moov, mdat, moof,
mdat, moof ...
The first moov usually doesn't contain any sample entries atoms (or
they are all set to 0 length), because the real samples are signaled
at the moofs. In push mode, qtdemux parses the moov and then finds the mdat,
but then it has 0 entries and assumes it is EOS.
This patch makes it continue parsing in case it is a fragmented file so that
it might find the moofs and play the media.
https://bugzilla.gnome.org/show_bug.cgi?id=710623
In push mode, when qtdemux can't use a seek to skip the mdat buffer it has
to buffer it for later use.
The issue is that after parsing the next moov/moof, there might be some
trailing bytes from the next atom in the file. This data was being discarded
along with the already parsed moov/moof and playback would fail to continue
after the contents of this moov/moof are played.
This is particularly bad on fragmented files that have the mdat before the
corresponding moof. So you'd get:
mdat|moof|mdat|moof ...
When a moof was received, it usually came with some extra bytes that would
belong to the next mdat (because upstream doesn't care about atoms alignment).
So those bytes were being discarded and playback would fail.
This patch makes qtdemux store those extra bytes to reuse them later after the
mdat is emptied.
https://bugzilla.gnome.org/show_bug.cgi?id=710623
Doing so would be a regression over 1.0 and breaks the unit test.
However the result will be most likely unusable, so let's post
a warning message on the bus.
Use g_date_time seconds manipulation to allow to cover the quicktime
spec for creation_time. It uses seconds since 1904.
Both paths could be done using the generic approach of seconds since
1904 with GDateTime handling, but the first path using seconds from
1970 should be more commonly found and avoids a few objects creation and
ref/unref, so keep it there for performance.
Additionally, the code for handling seconds since 1970 changed from >
to >= because having 0 seconds since 1970 is also a valid case for that
path to handle.
https://bugzilla.gnome.org/show_bug.cgi?id=707975
The streamable property only make sense for fragmented formats.
For regular MP4, when downstream is not seekable we can't rewrite
the headers, so qtmux can only work with fast-start=TRUE, where
the headers are written finishing the file.
For fragmented MP4, when streamable is not seekable and the streamable
property is FALSE, we must enforce streamable=TRUE warning the user
about this change
https://bugzilla.gnome.org/show_bug.cgi?id=707242
The most common use case for fragmented MP4 (Dash and Smooth Streaming)
is producing streamable content (even for VOD). streamable=FALSE would only
be used to generate fragmented MP4 with and index of MOOF's that could
be reproduced without a playlist/manifest
https://bugzilla.gnome.org/show_bug.cgi?id=707242
Check for GST_SEEK_TYPE_NONE for stop poistion and only update
the stop time if it is requested. Otherwise just maintain whatever
was stored at the segment
https://bugzilla.gnome.org/show_bug.cgi?id=707530
When the segment has a defined stop position, qtdemux should check
when streams reach this position and mark those as EOS. When all
streams are EOS it will return GST_FLOW_EOS to upstream to allow
the pipeline to finish instead of continuously consume buffers
from upstream that are not useful for the segment.
https://bugzilla.gnome.org/show_bug.cgi?id=707530
When handling seeks in push mode, qtdemux converts the seek to bytes
and pushes upstream. It needs to keep track of the seek and the
subsequent segment to be able to map them back to the requested
seek time and properly preserve the segment stop of the seek.
This is done by using the start offset in bytes of the seek,
that should be the same of the segment from upstream. And this
is also backwards compatible with what qtdemux already was using.
https://bugzilla.gnome.org/show_bug.cgi?id=707530
Amendment 2 of ISO/IEC 14496-15 (AVC file format) is defining a new
structure for fragmented MP4 called "avc3". The principal difference
between AVC1 and AVC3 is the location of the codec initialisation
data (e.g. SPS, PPS). In AVC1 this data is placed in the initial
MOOV box (moov.trak.mdia.minf.stbl.stsd.avc1) but in AVC3 this data
goes in the first sample of every fragment (i.e. the first sample in
each mdat box). The principal reason for avc3 is to make it easier
for client implementations, because it removes the requirement to
insert the SPS+PPS in to the decoder pipeline every time there is a
representation change.
This commit adds support for the "avc3" atom, which is almost identical
to the "avc1" atom, except it does not contain any SPS or PPS data.
https://bugzilla.gnome.org/show_bug.cgi?id=702004
This should make decoders able to precisely push buffers until the stop
time in case they need the next keyframe to do it.
Also, according to gst_segment_clip, it should only push a buffer that
the starting ts is strictly smaller than the segment stop, so we change
the min < comparison for <=
Use the same seqnum on messages and events for derived events.
Fixed for flushes / stream-start / segment after a seek, and segment
after a segment.
Fixes#676242
cca2f555d1 introduces a regression, where the demux segment is not
reset on flush stop, so the next upstream segment event will calculate
an invalid base time on the new segment to be sent downstream.
https://bugzilla.gnome.org/show_bug.cgi?id=704255
This can only reliably work if demuxers have a
separate streaming thread per srcpad. This should be
done in a demuxer base class, which integrates parts
of multiqueue
https://bugzilla.gnome.org/show_bug.cgi?id=701856
bug #700505
Following a representation change that causes a resolution change,
the video decoder fails to decode correctly. Dashdemux detects the
representation change and pushes a new caps event and an
initialization segment (a new moov atom) to the downstream qtdemux,
but it doesn't handle this new moov yet, it will only parse the
first one it receives.
This commit changes qtdemux to accept a new moov in a dash bitstream
switching scenario.
In case qtdemux is handling a mss stream, do not mark the stream to wait
for EOS after a segment. Even if it seems to be the last one according to
the current streams information.
MSS handling is different here because there is another demuxer driving
the pipeline
The samplerate field in the STSD atom is not right for some ALAC files
(usually when audio is 96kHz/24bits), so the audio caps must be
extracted from the codec data.
https://bugzilla.gnome.org/show_bug.cgi?id=700382
Whenever the demuxer has a new caps on a stream, it should set the
new_caps variable to true and a new caps event will be pushed before
the next buffer
qtdemux takes its buffers from a GstAdapter. Those buffers are created
from the larger buffer that it obtained from upstream and they carry
the same flags, including DISCONT if it is set. In these cases, all
buffers that qtdemux is going to push would be marked as DISCONT.
This scenario can make parsers/decoders flush on every buffer leading
to no decoding at all hapenning. This patch prevents this by unsetting
the flag if it shouldn't be set.
* Explicitly init variables for fragmented formats at init
* Do not use GstClockTime type if the variable isn't a timestamp
* Fix a style/readability issue at an if block
* Group 2 mss mode conditional blocks together to improve readability
Conflicts:
gst/isomp4/qtdemux.c
This can confuse downstream when they get a byte segment after receiving
the natural time segment from qtdemux that it sends when starting to
push buffers. This is specially the case with parsers that try to
convert the position from byte to time format and might miss the
correct position for playback to start.
Reset different variables on state changes to ready and when
handling a flush-stop. For handling flush stops we should check
if there is an upstream adaptive demuxer driving the pipeline as this
means that qtdemux will get a new moov atom. For 'standard' isomedia
streams this isn't true and qtdemux should keep the previous moov
information around.
Conflicts:
gst/isomp4/qtdemux.c
Whenever dashdemux switches bitrates it sends a new moov with the
new stream configuration. qtdemux should now handle this by splitting
the exposing and configuration of streams into separate functions. When
the stream is new it is configured and exposed, when it is a new bitrate
of an existing stream it is only reconfigured.
Conflicts:
gst/isomp4/qtdemux.c
smoothstreaming streams should be handled as a special kind of
fragmented isomedia. In MSS the fragments will not contain a
'moov' atom with the media descriptions, this has to be extracted
from the caps.
Additionally, there should be another demuxer upstream that is likely
going to be the one to answer/act on queries and events, so qtdemux has
to forward those upstream.