Remove an old check from atom_stsc_add_new_entry() that
extends the last entry in the STSC if the samples per chunk
matches, as the new interleave merging logic requires that
the final entry by updateable. There's already code
below which simply merges the final entry into the previous
one when needed, so rely on that instead.
Fixes asserts like:
ERROR:atoms.c:2940:atom_stsc_update_entry: assertion failed:
(atom_array_index (&stsc->entries, len - 1).first_chunk == first_chunk)
We can't simply assume that the length of the tag value as given
inside the stream is correct but should also check against the amount of
data we have actually available.
https://bugzilla.gnome.org/show_bug.cgi?id=775451
qtdemux.c: In function ‘qtdemux_parse_trak’:
qtdemux.c:10184:38: error: format ‘%lu’ expects argument of type ‘long unsigned int’, but argument 9 has type ‘gint {aka const int}’ [-Werror=format=]
GST_DEBUG_OBJECT (qtdemux, "Found jpeg: len %u, need %lu", len,
^
39f7e52266 was setting the buffer duration
to 0 if is not valid, under the assumption that this is "the last"
buffer and no others are coming next. This is wrong, last_buf is the
previous buffer and not the very last one.
4e3c13c87c was setting DTS to 0 if there
was none. This will set DTS to 0 for all e.g. audio streams, completely
messing up calculations if streams don't start at 0.
https://bugzilla.gnome.org/show_bug.cgi?id=774840
| ../../../git/gst/isomp4/qtdemux.c: In function 'qtdemux_parse_tree':
| ../../../git/gst/isomp4/qtdemux.c:10224:24: error: 'size' may be used uninitialized in this function [-Werror=maybe-uninitialized]
| offset += size;
| ^~
| ../../../git/gst/isomp4/qtdemux.c:10197:25: note: 'size' was declared here
| guint32 size, tag;
| ^~~~
https://bugzilla.gnome.org/show_bug.cgi?id=774747
Always write an edit list for the whole track. In general this is not
necessary except for the case of having a gap or DTS adjustment but
it allows to give the whole track's duration in the usually more
accurate media timescale.
https://bugzilla.gnome.org/show_bug.cgi?id=774403
TIME segment implies that stream/running time is being handled by upstream.
So, we shouldn't override it without any clue.
This patch is for fixing seek in DASH streaming.
https://bugzilla.gnome.org/show_bug.cgi?id=774196
qtdemux.c: In function ‘qtdemux_parse_tree’:
qtdemux.c:10139:16: error: ‘color_table_id’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
if (color_table_id != 0) {
^
qtdemux.c:10121:19: note: ‘color_table_id’ was declared here
guint16 color_table_id;
^~~~~~~~~~~~~~
The ProRes guidelines suggest an interleave of 0.5s is common, but
specifies that for ProRes at most 2MB (for SD) and 4MB (for HD) should
be used per chunk.
It might also make sense to use similar numbers in general.
https://bugzilla.gnome.org/show_bug.cgi?id=773217
Previously we were switching from one chunk to another on every single
buffer. This wastes some space in the headers and, depending on the
software, might depend in more reads (e.g. if the software is reading
multiple samples in one go if they're in the same chunk).
The ProRes guidelines suggest an interleave of 0.5s is common, but
specifies that for ProRes at most 2MB (for SD) and 4MB (for HD) should
be used per chunk. This will be handled in a follow-up commit.
https://bugzilla.gnome.org/show_bug.cgi?id=773217
It's required for ProRes to work with other software.
It is also in the MP4 standard, but inventing values here seems a bit
tricky for the general case and it does not really give any extra
information.
https://bugzilla.gnome.org/show_bug.cgi?id=769048
Use the number of milliframes per second for integral and drop-frame
framerates, as suggested by the QT file format specification and other
places. We already did that for integral framerates before, but not for
drop-frame framerates. This now keeps precision better.
For all other framerates, check if it's close to a well-known framerate
and use that instead.
https://bugzilla.gnome.org/show_bug.cgi?id=769041
We consider there's a sifnificant difference when it's larger than on second
or than half the duration of the last processed fragment in case the latter is
larger.
https://bugzilla.gnome.org/show_bug.cgi?id=754230
https://github.com/mesonbuild/meson
With contributions from:
Tim-Philipp Müller <tim@centricular.com>
Jussi Pakkanen <jpakkane@gmail.com> (original port)
Highlights of the features provided are:
* Faster builds on Linux (~40-50% faster)
* The ability to build with MSVC on Windows
* Generate Visual Studio project files
* Generate XCode project files
* Much faster builds on Windows (on-par with Linux)
* Seriously fast configure and building on embedded
... and many more. For more details see:
http://blog.nirbheek.in/2016/05/gstreamer-and-meson-new-hope.htmlhttp://blog.nirbheek.in/2016/07/building-and-developing-gstreamer-using.html
Building with Meson should work on both Linux and Windows, but may
need a few more tweaks on other operating systems.
And don't just reset everything. This makes sure that we can continue to
handle data in the following scenario:
moov: discont
moof: discont
mdat: continuous
Previously this would fail because the offset would be the accumulated offset
from moov and moof at the mdat position, while the buffer offset might be
something completely different.
As seen in the parent switch for object_type_id, the 4 possible values are
0x40, 0x66, 0x67 and 0x68. Fixing the nested switch to match these values.
Looks like it was a typo making them decimal instead of hexadecimal.
CID 1363328
Without, raw AAC can't be handled and we have some information available in
the decoder that most likely allows us to decode the stream in one way or
another. This is the same code already used by matroskademux for the same
reasons, and ffmpeg/vlc play such files just fine too by guesswork.
This is to handle cases where upstream handles the fragmented streaming in TIME
segments and sends us data with gaps within fragments. This would happen when dealing
with trick-modes.
When upstream (push-based, TIME SEGMENT) wishes to send discontinuous samples,
it must obey the following rules:
* The buffer containing the [moof] must have a valid GST_BUFFER_OFFSET
* The buffers containing the first sample after a gap:
* MUST start at the beginning of a sample,
* MUST have the DISCONT flag set,
* MUST have a valid GST_BUFFER_OFFSET relative to the beginning of the fragment.
https://bugzilla.gnome.org/show_bug.cgi?id=767354
No variables were added/removed. This was just a good excuse to:
* Comment what most variables are used for (and when)
* Order them in such a way as to show first the common variables used
in all cases, followed by those only used in push-mode
We shouldn't go through segment activation as we will only have a limited
understanding of how the whole stream timeline looks like from the moof. We
only know about the current fragment, while upstream knows about the whole
stream.
This fixes seeking in DASH streams, both for seeks after the current moof and
for seeks into the current moof. The former would fail because the moof ends
and we can't activate any segment, the latter would cause a segment that stops
at the moof end, and no further fragments would be played because we end up
being EOS.
https://bugzilla.gnome.org/show_bug.cgi?id=767071
segment_duration and media_time should be parsed based on version
of elst box. Specification defines that an elst box with version 1
has uint64 and int64 values for segment_duration and media_time,
respectively.
https://bugzilla.gnome.org/show_bug.cgi?id=766301
Properly handle edts segments for push-based operation seeking.
We only support edts that a single segment that has media at the end,
being preceeded by any number of gap segments.
This also allows the qt segment rate to be respected after seeks
https://bugzilla.gnome.org/show_bug.cgi?id=765669
Via the MPEG-4 Part 3 spec we can support the other layers too.
Also correct the samples per frame calculation for MP3 if it's MPEG-2 or
MPEG-2.5.
https://bugzilla.gnome.org/show_bug.cgi?id=765725
timescale/1 is unreliable value for framerate. Due to downstream
element usually use framerate generated by qtdemux, let it be omitted
until the framerate can be reliably calculated.
https://bugzilla.gnome.org/show_bug.cgi?id=764733
When playing a stream that has been protected by DASH CENC, playback
will fail if a seek is performed. Qtdemux produces the error "stream
is protected using cenc, but no cenc protection system information
has been found" and playback stops.
The problem is that gst_qtdemux_reset() gets called as part of the
FLUSH during a seek. This function frees the protection_system_ids
array. When gst_qtdemux_configure_protected_caps() is called after the
seek has completed, the protection_system_ids array is empty and
qtdemux is unable to create the correct output caps for the protected
stream.
This commit changes it to only free the protection_system_ids on
hard resets.
https://bugzilla.gnome.org/show_bug.cgi?id=761787
qtdemux->streams is an array, it will never evaluate to true when comparing
to NULL. Instead we want to check the number of streams to make sure the
stream is available.
https://bugzilla.gnome.org/show_bug.cgi?id=753614
CID 1358389
The PIFF data is stored in a custom UUID box which is parsed and the
crypto_info of the element is updated accordingly. This allows
downstream decryptors to process and decrypt the protected content.
https://bugzilla.gnome.org/show_bug.cgi?id=753614
If we don't find the index of the sample correctly in src_convert function,
we have to unref about the qtdemux before returning value.
So, I have modify it about instead pass qtdemux as a parameter into
src_convert function.
https://bugzilla.gnome.org/show_bug.cgi?id=763973
Currently, get_duration function always return the TRUE even though
it can't be set duration correctly. So, we need to add the else condition
about the fail case. Also, we already set the GST_CLOCK_TIME_NONE
in this function. So I have modify it which is related code in some
function.
https://bugzilla.gnome.org/show_bug.cgi?id=763968
When upstream is running in bytes in push-mode, qtdemux will
convert seeks from time to bytes and send it upstream. Upstream
element will perform a byte seek and send a byte segment to qtdemux
that will convert it to time and push it downstream.
There is, however, the pending_segment variable that stores a new
segment event to be pushed before the next data. When handling seeks
as mentioned above this variable was being ignored and, if it contained
some segment event, it would override the one resulting from the seek.
This would restore a previous segment and would cause the seek segment
to be discarded downstream.
This patch fixes this issue by unrefing any pending segment as the
seek from upstream should contain the latest one that should be
used, as requested by the application.
https://bugzilla.gnome.org/show_bug.cgi?id=763165
In some cases the stream configuration can fail, for instance if the
stream is protected and no decryptor was found. For those situations
the demuxer shouldn't emit any data on the corresponding source pad of
the stream and bail out.
https://bugzilla.gnome.org/show_bug.cgi?id=762516
When the cenc metadata is stored outside of the moof box and the
stream is exposed it is possible that the cenc metadata hasn't been
processed yet while the first buffer is being pushed. When this
happens the buffer can't possibly be decrypted downstream so don't
push it.
https://bugzilla.gnome.org/show_bug.cgi?id=762516
Commit 7873bede31
(https://bugzilla.gnome.org/show_bug.cgi?id=760774) changed the
behaviour of qtdemux to call gst_qtdemux_configure_stream() for
every new moof.
When playing a protected stream, gst_qtdemux_configure_stream()
calls gst_qtdemux_configure_protected_caps(). The
gst_qtdemux_configure_protected_caps() function takes the original
media format, puts this in a field called "original-media-type"
and then changes the caps to "application/x-cenc".
The gst_qtdemux_configure_protected_caps() did not handle the case
of being called multiple times, causing it to incorrectly set the
caps. The second call was causing the caps to be set to:
application/x-cenc, original-media-type"application/x-cenc"
This commit makes gst_qtdemux_configure_protected_caps() check that
the caps have already been transformed, so that it only gets
changed once.
https://bugzilla.gnome.org/show_bug.cgi?id=761769
qtdemux calculates framerate using duration and the number of sample.
In case of fragmented mp4 format, however, the number of sample can
be figure out after parsing every moof box. Because qtdemux does not
parse every moof in QTDEMUX_STATE_HEADER state, it will cause incorrect
framerate calculation.
This patch will triger gst_qtdemux_configure_stream() for every new moof.
Then, framerate will be calculated by using duration and n_samples of the moof.
https://bugzilla.gnome.org/show_bug.cgi?id=760774
Based on document ISO_IEC_14496-12, edit list box can have
segment duration as zero. It does not imply that media_start equals to
media_stop. But, it just indicates a sample which should be presented
at the first. This patch derives segment duration using media_time
and duration of file. And set derived duration to segment-duration.
https://bugzilla.gnome.org/show_bug.cgi?id=760781
In case of push mode, qtdemux expose streams after got moov box.
We can not guarantee that a moov box has sample data such as sample duration
and the number of sample in stbl box for fragmented format case.
So, if a moov has no sample data, streams will not be exposed until get the first moof.
https://bugzilla.gnome.org/show_bug.cgi?id=760779
Prevents downstream from receiving flushes for a seek only in
upstream. Those seeks are only to start reading from the right
offset when skipping or returning to qt atoms.
https://bugzilla.gnome.org/show_bug.cgi?id=758928
Avoid writing a negative number as a large positive
integer in an edit list when the first_ts is smaller
than the first_dts - which can happen when the first
packet received has a PTS but no DTS.
https://bugzilla.gnome.org/show_bug.cgi?id=759615
When working in push-mode, we attempt to push out everything currently
buffered in the adapter.
This has two pitfalls:
* We could stop earlier (the moment we get a non-ok or non-not-linked)
* We return the last combined flow return, which might be completely
different from the previous combined flow return
When seeking back to restore the mdat position a flush is pushed
through and it resets downstream segment information. Make sure
that after the flush (that does a soft reset) a segment will
be pushed again
Fixes regressions spotted at
https://ci.gstreamer.net/job/GStreamer-master-validate/2100/
10 FourCCs generated with GST_MAKE_FOURCC() in gstqtmux.c and atoms.c
already exist in fourcc.h. Don't duplicate these and use them directly.
Plus moving 6 to fourcc.h, to centralize them all.
This fixes seeking if the first entries in the samples table are negative. The
binary search would always fail on this as the array would not be sorted if
interpreting the negative numbers as huge positive numbers. This caused us to
always output buffers from the beginning after a seek instead of close to the
seek position.
Also add a case to the comparison function for equality.
It would be unusual to have the header segment with an 'edts' atom
indicating gaps at the beginning when handling fragmented streams.
The header usually doesn't contain any timestamping information, this
should come from the playlist/manifest and the segments with media
in those scenarios.
https://bugzilla.gnome.org/show_bug.cgi?id=758171
In push-mode it is hard to support qt segments overall but it is
possible to support when the file isn't heavily edited but just contain
a segment to indicate a gap at the beginning. This also allows properly
timestamping data that has negative DTS in push-mode.
It is relevant to support those for 2 scenarios:
1) fragmented streaming
2) HTTP playback of 'regular' mp4
https://bugzilla.gnome.org/show_bug.cgi?id=753484
If the QtDemuxStream are re-used they may already have caps which used
to be leaked.
Reproduced using the
validate.dash.playback.seek_forward.dash_exMPD_BIP_TC1 validate
scenario.
https://bugzilla.gnome.org/show_bug.cgi?id=756561
Negotiation to audio/x-raw,format=S8 was not possible because S8 does
not have a bit order so we ended up doing `if (!entry.fourcc) goto refuse_caps;`
https://bugzilla.gnome.org/show_bug.cgi?id=756387
If seeking targets an empty segment skip it as there is no media
offset to get from it. Instead look for the next one.
This doesn't make seeking in push-mode work if you seek to an
empty segment but at least won't get you to wrong offsets.
https://bugzilla.gnome.org/show_bug.cgi?id=753484
eceb2ccc73 broke segment seeks by always
accumulating segments manually when activating a segment. This is only
needed when handling edit lists, not when activating a segment because of a
seek. Do the accumulation when switching edit list segments instead.
This fixes segment seeks again, while keeping edit lists playback working.
https://bugzilla.gnome.org/show_bug.cgi?id=755471
Commit 7d7e54ce68 added support for
DASH common encryption, however commit
bb336840c0 that went onto master
shortly before the CENC commit caused the calculation of the CENC
aux info offset to be incorrect.
The base_offset was being added if present, but if the base_offset
is relative to the start of the moof, the offset was being added twice.
The correct approach is to calculate the offset from the start of the
moof and use that offset when parsing the CENC aux info.