If we don't do that, clients can rely on this signal to see the final pad
topology but it won't be the real one as some of them will disappear after
emitting that signal. This can happen after injecting a different init segment.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4535>
On very quick start/stop, the mainloop may never be run. As a side
effect, our idle stop function is not really being ran, so we can't rely
on that to free the main loop. Simply unref the mainloop when the
thread have completely stop.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4521>
By keeping async to TRUE, a deadlock is avoided where the appsink is
filled with data after a flushing seek but before its PAUSED->PLAYING
state change finishes. If that happens, the appsink is stuck, because
its internal condition variable waits for the appsink to have more room
for data. The basesink's preroll lock is held during this, and it also
tries to acquire that lock during the state change -> deadlock.
By keeping async to TRUE, this flood of data does not happen.
Also, setting the max-buffers property to 1 is unnecessary - the test
runner will anyway detect excess memory usage if it happens.
Other property adjustments turned out to just be redundant.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4200>
While testing the [implementation for insertable streams] in `webrtcsink` &
`webrtcsrc`, I encountered critical warnings, which turned out to result from
two race conditions in `rtpsession`. Both race conditions produce:
> GLib-CRITICAL: g_hash_table_foreach:
> assertion 'version == hash_table->version' failed
This commit fixes one of the race conditions observed.
In its simplest form, the test consists in 2 pipelines and a Signalling server:
* pipelines_sink: audiotestsrc ! webrtcsink
* pipelines_src: webrtcsrc ! appsrc
1. Set `pipelines_sink` to `Playing`.
2. The Signalling server delivers the `producer_id`.
3. Initialize `pipelines_src` to establish a session with `producer_id`.
4. Set `pipelines_src` to `Playing`.
5. Wait for a buffer to be received by the `appsrc`.
6. Set `pipelines_src` to `Null`.
7. Set `pipelines_sink` to `Null`.
The race condition happens in the following sequence:
* `webrtcsink` runs a task to periodically retrieve statistics from `webrtcbin`.
This transitively ends up executing `rtp_session_create_stats`.
* `pipelines_sink` is set to `Null`.
* In `Paused` to `Ready`, `gst_rtp_session_change_state()` calls
`rtp_session_reset()`.
* The assertion failure occurs when `rtp_session_reset` is called while
`rtp_session_create_stats` is executing.
This is because `rtp_session_create_stats` acquires the lock on `session` prior
to calling `g_hash_table_foreach`, but `rtp_session_reset` doesn't acquire the
lock before calling `g_hash_table_remove_all`.
Acquiring the lock in `rtp_session_reset` fixes the issue.
[implementing insertable streams support]: https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1176
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4528>
Unfortunately streamoff does not flush the events, and this can cause all
sort of issues. Flush events on capture queue. We also return
GST_V4L2_FLOW_RESOLUTION_CHANGE in case a resolution change was seen.
This allow skipping streamon(capture) on flush, which could lead to a
configuration miss-match, or failure if the buffers aren't of the right
size.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4437>
Let the driver detects the change and reconfigure the capture side
transparently from there. This avoid reallocation of the output buffers,
and eliminates the need to stop and restart the capture task. This is
only happening if the driver have support for this, otherwise the old
behaviour is maintained.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4437>
Stop doing capture buffer allocation based on guesses
and wait for the source change event when available.
Unlike stateless decoder, the stateful decoder is not aware of
the coded resolution, and this may lead to the wrong result
even when using TRY_FMT.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4437>
In previous implementation that job was split between handle_frame and
the processing loop and it wasn't clear if this mechanism was race
free. The capture setup would also be tried for every buffer, which was
not necessary.
This also simplify the handling of SRC_CH event, dropping the unneeded
atomic boolean.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4437>
When seek flush, gst v4l2 buffer pool flush is not atomic which will
lead double enqueue buffer (qbuf) issue, and v4l2 buffer pool qbuf is
also not atomic which will lead no free buffer found in the pool.
1. add lock for calculate enqueue number in streamon function
2. add lock for v4l2 capture end streamoff in pool flush function
3. lock the whole funciton of v4l2 buffer pool qbuf, then the buffer
pool index and qbuf operation are atomic
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4465>
when regotiation happens, v4l2src will check if it can reuse current caps,
but we need check if current caps is subset of all query caps from downstream
instead of check it with query caps one by one.
Assuming that the current caps is not the subset of first caps from query caps,
it will go to try fmt. when try fmt success, v4l2src will make pending_set_fmt
to TRUE and going to reset.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4500>
This reverts commit f29c19be58. If this is
called for the reference context then we would run into an infinite
loop, which is not really better than an assertion.
By fixing up DTS to never be ahead of the PTS in the previous commit
this situation should be impossible to hit now.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4498>
Fix the following use:
- upstream sends a video with a rotation tag, say 90°
- upstream switches to another video without rotation
- the second video was still rotated by videoflip
Fix this by resetting the orientation when receiving STREAM_START.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4377>
In order to provide build and provide the jack plugin with the prebuilt
binaries of gstreamer we distribute with releases, we can not depend
on an external dependency nor can we ship plugins linking to libraries
we don't provide.
We can also not provide jack ourselves, as it would likely cause a
mismatch with the jack daemon on the host.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4350>
The decoder needs to force another enumeration of the format. For
this it was clearing the v4l2object insternal list, leaving a fmtdesc
pointer pointing to freed memory. This patch clears the fmtdesc pointer
that has just been free. It also makes sure the probe function does not
use the cached formats list. The probe function will restore the current
fmtdesc pointer based on the currently configured pixelformat.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4317>
As we don't have anything smart in the fixation process, we may endup with
a format that has a lower bitdepth, even if downstream can handle higher
depth. it is notably the case when negotiating with deinterlace, which places
is non-passthrough caps before its passthrough one. This makes the generic
fixation prefer the formats natively supported by deinterlace element over
the HW 10bit format. As some HW can downscale 10bit to 8bit, this can break
10bit decoding.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4317>
The previous code would only check if two packets in a row were duplicates. If
not (i.e. a packet is a duplicate of a packet received slightly before) the code
would generate completely bogus FCI because it assumes there were no duplicates
present in the array.
In order to be efficient, just store all received packets and remove the
duplicates just before the FCI is generated once the array of observations have
been sorted by seqnum.
Fixes TWCC usage with moderate to high packet duplication.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4328>
Short-circuit parsing and recreating the playlist URI if
no HLS directives are going to be applied to it.
Fixes problems playing some streams (YouTube) that have
unneeded escaped characters in the URI and then complain
when GStreamer removes the escaping
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4335>
With GST_SEEK_FLAG_SNAP_AFTER present, the previous version would
adjust seek time based on the keyframe farthest away from desired_time.
This was incorrect, because we always want the *earliest* suitable keyframe
to seek to, not the last one.
With this fix, in case of the SNAP_AFTER, we now look for the closest keyframe
that can be found after desired_time. Behaviour for SNAP_BEFORE should remain
unchanged.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4183>
Assuming that V4L2 CAPTURE devices always use one buffer per JPEG image, we can
always mark JPEGs provided by a V4L2 element as parsed.
The V4L2 elements require that JPEG images sent to V4L2 OUTPUT devices must
always be parsed.
This is necessary to link a V4L2 CAPTURE device with a V4L2 OUTPUT device
without explicitly marking the stream as parsed or adding a jpegparse into the
pipeline.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4229>
There's no guarantee it will *actually* be the URI which refered to what we are
downloading. It could be a stream URI or anything else.
Instead of putting something wrong, put no (specific) referer as a better choice
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3972>
The flowcombiner and active_streams shouldn't be cleared in the
mse-bytestream variant, only in the mss-fragmented one. Otherwise the
soft reset leaves qtdemux in a state where it still believes that it has
streams, but they've been cleared. In that case, a null pointer
dereference happens and the app crashes.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4199>
The abort() method of SourceBuffer in Media Source Extensions is
expected to flush the demuxer and discard the current fragment,
if any. The configuration of tracks, if any, should be preserved.
qtdemux has different behavior for flush events depending on the
context.
This patch activates the intended behaviour only for streams of the
VARIANT_MSE_BYTESTREAM type, conformant to the ISO BMFF Bytestream
specification[1]. This flush behaviour is the same as the one
already in use for adaptivedemux sources.
[1] https://www.w3.org/TR/mse-byte-stream-format-isobmff/https://bugzilla.gnome.org/show_bug.cgi?id=795424
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4101>
This patch prevents a possible race condition from taking place between the EOS event handling and rtcp send
function/thread.
The condition starts by getting the GST_EVENT_EOS event on the send_rtp_sink pad, which causes two core things
to happen -- the event gets pushed down to the send_rtp_src pad and all sessions get marked "bye" prior to
completion of the event handler. In another thread the rtp_session_on_timeout function gets called after an
expiration of gst_clock_id_wait in the rtcp_thread function. This results in a call to the
ess->callbacks.send_rtcp(), which is configured as a function pointer to gst_rtp_session_send_rtcp via the
RTPSessionCallbacks structure passed to rtp_session_set_callbacks in the gst_rtp_session_init function.
In the race condition, the call to gst_rtp_session_send_rtcp can have the all_sources_bye boolean set to true
while GST_PAD_IS_EOS(rtpsession->send_rtp_sink) evaluates to false. This is the result of gst_rtp_session_send_rtcp
running before the send_rtp_sink's GST_EVENT_EOS handler completes. The exact point at which this condition occurs
is if there's a context switch to the rtcp_thread right after the call to rtp_session_mark_all_bye in the
GET_EVENT_EOS handler, but before the handler returns.
Normally, this would not be an issue because the rtcp_thread continues to run and indirectly call
gst_rtp_session_send_rtcp. However, the call to rtp_source_reset sets the sent_bye boolean to false, which ends up
causing rtp_session_are_all_sources_bye to return false. This gets passed to gst_rtp_session_send_rtcp and the EOS
event never gets sent.
The race condition results in the EOS event never getting passed to the rtcp_src pad, which prevents the bin and
pipeline from ever completing with EOS.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3798>
Makes "start-bitrate" work without setting "connection-speed" property. Having
another property set as a requirement for this one to work is unexpected.
This commit allows to request some initial bitrate for first segment, then
go into adaptive streaming for the rest of media playback.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3895>
A data offset with an offset smaller than the moof length is wrong
in smooth streaming streams. The samples will not be located and
eventually playback will error out. So compensate assuming data
is in mdat following moof.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3840>
A data offset with an offset smaller than the moof length is wrong
in smooth streaming streams.
The samples will not be located and eventually playback will
error out. So compensate assuming data is in mdat following moof.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3840>
this is an issue seen with musl based linux distros e.g. alpine [1]
musl is not going to change this since it breaks ABI/API interfaces
Newer compilers are stringent ( e.g. clang16 ) which can now detect
signature mismatches in function pointers too, existing code warned but
did not error with older clang
Fixes
gstv4l2object.c:544:23: error: incompatible function pointer types assigning to 'gint (*)(gint, ioctl_req_t, ...)' (aka 'int (*)(int, unsigned long, ...)') from 'int (int, int, ...)' [-Wincompatible-function-pointer-types]
v4l2object->ioctl = ioctl;
^ ~~~~~
[1] https://gitlab.alpinelinux.org/alpine/aports/-/issues/7580
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3950>
The av1C box is optional so dropping parsing does not break anything
fundamentally, and there seems to be no historical record how version 0
even looks like while the comments and the parsing disagreed with each
other.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3882>
When using qtdemux in a pipeline that should only work as a pure demuxer (not
for actual playback), qtdemux shouldn't emit new GstSegments to correct
the start time (jump to the future) to ensure that the user experiences no
playback delay. By doing so, it's generating the wrong segments when an append
of data from the past happens. When that happens, downstream elements such as
parsers (eg: aacparse) may clip those buffers laying before the GstSegment and
create problems on the GStreamer client app (eg: WebKit).
Getting buffers clipped out because of the wrong GstSegments started becoming
a problen when this commit was introduced:
ab6e49e9cc audioparsers: add back segment clipping to parsers that have lost it
This clipping makes test DASH shaka 35 from MVT tests[1] to fail in
WebKitGTK/WPE (at least) and can potentially cause a number of other problems
in the WebKit Media Source Extensions (MSE) code.
Note that this new behaviour of not emitting new GstSegments only makes sense
when qtdemux is being used as a pure demuxer and not as part of a regular
pipeline. This is why the variant field has been added. When equal to
VARIANT_MSE_BYTESTREAM, it will make qtdemux behave differently in push mode,
taking decisions that meet the expectations for an MSE-like processing mode.
This kind of tweaks have been done in the past for MSS streams, for instance.
That code has been refactored to use VARIANT_MSS_FRAGMENTED now, instead of
its own dedicated boolean flag.
Co-authored by: Alicia Boya García <ntrrgc@gmail.com>
...who suggested to use "variant: mse-bytestream" in the caps to identify that
mode, as proposed in her unmerged patch:
https://gitlab.freedesktop.org/gstreamer/gst-plugins-good/-/issues/467
[1] https://github.com/rdkcentral/mvt
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3867>
The live playlists should be updated at a defined interval. The problem is that
this interval was used *after* the playlist was finally received and processed,
which resulted in a gradual shift happening in playlist updates.
Instead store and use the time at which playlists were requested to determine
when the next one should be downloaded.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3883>
The scanning is done in a reverse order, the proper full checks to do are
therefore:
* If the position is beyond half a "segment duration", it's in the following
segment
* If the position is within the first half of a segment, it's in that one
* If the segment is the first one and the position is within half a duration
backwards, we consider the position as being within that first segment
Also handle the case where a "partial only" segment doesn't have a reliable
duration, and therefore use the playlist target duration instead.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3883>
The implementation wouldn't work with regular HLS streams (i.e. the final
fallback).
Now that the implementation uses time to search for the starting
segment (instead of just the n-th from the end), we can specify the correct
hold_back fallback value from the RFC
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3883>
Avoid a deadlock if a downstream seeking query happens while the scheduler
thread is holding the manifest lock (for example during a seek back to live).
Instead, do a more elaborate fix where the external calls that need access to a
'manifest' access a copy that's updated during a manually triggered manifest
update callback.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3883>
Rename track_dequeue_data_locked() to
gst_adaptive_demux_track_dequeue_data_locked(), since it's non-static.
Make find_stream_for_track_locked() static since it's only used in the main
gstadaptivedemux.c file.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3883>
gst_adaptive_demux2_stream_finish_download() will already schedule another
fragment download if it can so don't fall through to the retry code that will
also try and schedule a download (triggering an assert).
Fix the logic in general to retry advancing into the live seek range once.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3883>
When calculating the seek range for a live stream, use the same hold-back logic
as when choosing a starting segment, including low-latency segments if
enabled. Permits seeking closer to the live edge when re-synching or catching
up.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3883>
When playing at the live edge of a live playlist, and a download fails, we don't
expect there to be a next fragment. That case is handled lower down anyway, so
don't retry infinitely on spurious http errors at the live edge.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3883>
gst_hls_demux_stream_has_next_fragment() can be called with a NULL
current_segment if we're past the end of the current playlist. In that case,
just return FALSE instead of hitting a critical in the playlist code.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3883>
When playing LL-HLS playlists in LL-HLS mode, update the playlist more often (on
the partial segment interval) or else we end up downloading them in bursts and
playing further from the live edge than intended.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3883>
When playing a live stream, make the recommended buffering threshold at most the
hold-back distance from live. If we start 3 seconds from the live edge, there's
no point trying to buffer more - we'll just hit the live edge and have to wait
for more data to be available anyway.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3883>
Add a field to the DownloadRequest that reports the most recent time at which
data arrived. Update it in the DownloadHelper.
Add a method to retrieve the GST_BUFFER_OFFSET() for the DownloadRequest's data
buffer (if any).
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3883>
After cancelling a DownloadRequest, the download helper may not do so
immediately, so we can't assert on the in_use flag. Also, since there's no
refcount on the preload hint struct in the download request callback data, make
sure no callbacks will be dispatched when we're going to free the preload hint
struct.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3883>
Implement fulfilment of HTTP requests from the active preload downloads by
finding any preload request that can provide the requested data and feeding
bytes from the internal DownloadRequest to the caller provided target
DownloadRequest.
Doesn't yet calculate timestamps to make the target request have a sensible
apparent bitrate.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3883>
Add download_request_take_buffer_range() and
download_request_get_bytes_available() methods.
download_request_take_buffer_range() takes bytes from the front of the request
that satisfy the requested start/end byterange, and puts any remaining bytes
back into the DownloadRequest
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3883>
Add a helper that submits and handles blocking preload requests for future
PART/MAP data from live playlists. Add handling in the hlsdemux stream to submit
preload requests when hitting the end of the available segments in a live
playlist.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3883>
Add a flag to hlsdemux to enable or disable LL-HLS handling.
When LL-HLS is enabled and an LL-HLS playlist is loaded, use the part-hold-back
threshold to choose a starting segment.
For live streams that aren't LL-HLS, use the provided hold-back attribute, or
fall back to landing 3 segments from the end.
Make the gst_hls_media_playlist_seek() method able to choose a partial segment
within 2 target durations of the end of the playlist when requested.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3883>
Fix an off-by-one in gst_hls_media_playlist_sync_to_playlist() that would ignore
the first fragment in the reference playlist. The error was harmless, since we
expect the reference playlist to be older than the playlist we're
synchronising (so the first/oldest segment in the reference playlist will likely
not exist in the new playlist), so this is just for correctness.
Also fix a segment leak in gst_hls_media_playlist_advance_fragment() when
ignoring the partial_only segment.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3883>
Add a function for synchronising current position with the contents of a
playlist that is specifically for that and can handle synchronising to a partial
segment.
gst_hls_media_playlist_seek() will be used only when performing external seek
requests, to find the best segment or partial segment at which to resume
playback.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3883>
Fixes for stream_time recalculation and handling in partial segments.
Disallow bitrate switching when in the middle of partial segments - only at a
full segment (or right before the first partial segment of a segment).
It's possible but more difficult to switch bitrates in the middle of a partial
segment group, since they are less likely to have aligned keyframes. In any
case, the seek code can't do that right now.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3883>
All the RTP src pads were sharing the same stream-id while each actually
carry a different stream.
This was causing problem for example when funneling the streams together
and then trying to split them using 'streamiddemux'.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3855>
In theory, `dispose()` functions should be idempotent and should be
prepared not to crash or cause a double-free if an unref done from
inside caused a recursive call to `dispose()` of the same object.
https://developer.gnome.org/gobject/stable/howto-gobject-destruction.html
This patch modifies the `dispose()` method to honor these constraints.
Since the double `dispose()` call won't actually occur in qtdemux (there
is no cycle detection mechanism that could invoke it to work that way),
this is more of a code cleanup than a user-facing problem fix.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3822>
Without this, the plugin cannot be loaded in a devenv because the
RPATH is not added to the plugin dylib. This RPATH will be stripped on
install, which is what we want.
When deploying apps, people are supposed to use `macdeployqt` to
create an AppBundle that bundles Qt for you and sets the RPATHs
correctly to point to that bundled Qt.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3708>
Deserialize socket control messages as GstSocketTimestampMessage only
if (level, type) is (SOL_SOCKET, SCM_TIMESTAMPNS).
Without this patch, messages with types SCM_RIGHTS or SCM_CREDENTIALS
could be deserialized as GstSocketTimestampMessage instead of
GUnixFDMessage or GUnixCredentialsMessage from gio.
Fixes#1736
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3777>
AVC-Intra is a range of H.264-compliant intra-only codecs from
Panasonic. The codes and descriptions have been taken from VLC.
The (encumbered) sample I have here produces byte-stream H.264,
including SPS and PPS and no `avcC` box.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3739>
When calculating the presentation offset for CMAF input in live
playback, subtract the stream_time of the fragment from the
calculated presentation offset, so that the first fragment
is played at running time zero.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3680>
This is recommended by various specifications for such framerates, while
for integer framerates we continue using centiframes to allow for some
more accuracy.
Using N means that no rounding error accumulates, eventually leading to
outputting a packet with a different duration.
Some tools such as MediaInfo determine that a stream is variable
framerate if any packet has a different duration than the others, and
there is no reason I can see for not using the full 4 bytes of
resolution that the mp4 timescale offers.
Example problematic pipeline:
```
videotestsrc num-buffers=5001 ! video/x-raw,framerate=60000/1001,width=320,height=240 ! \
videoconvert ! x264enc bitrate=80000 speed-preset=1 tune=zerolatency ! h264parse ! \
video/x-h264,profile=high-10 ! mp4mux ! filesink location="result2.mp4"
```
This results in a media file that MediaInfo detects as variable
framerate because the 5000th packet has duration 99 instead of 100.
With this patch, the timescale is 60000 and all packets have duration
1001.
Related issue for context: https://bugzilla.gnome.org/show_bug.cgi?id=769041
Co-authored-by: Sebastian Dröge <sebastian@centricular.com>
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3049>
This reverts the decision from
https://bugzilla.gnome.org/show_bug.cgi?id=754230
where it was decided that we rather play safe and only use the `tfdt` if
it is "significantly different" to the sum of sample durations.
As the specification says
If the time expressed in the track fragment decode time (‘tfdt’) box
exceeds the sum of the durations of the samples in the preceding
movie and movie fragments, then the duration of the last sample
preceding this track fragment is extended such that the sum now
equals the time given in this box.
we have to use the `tfdt` in general to allow for it to signal gaps in
the stream.
A muxer producing fragments might not yet know the full duration of the
last sample of a previous fragment if the next fragment starts with a
gap, and knowing the actual start of the next fragment would potentially
require to violate latency requirements.
Additionally, the existence of `tfdt` allows to avoid accumulating
rounding errors from summing up the durations.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3586>
The rtpjitterbuffer test drop_messages_interval uses a GstClockTime for
the message drop interval. This property is defined as a guint. On
systems with 64-bit time_t but 32-bit uint, this can cause the
g_object_set function to fail to read the arguments properly.
Fixes: #1656
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3580>
If we keep the old events they can be end up being passed to the app, that could
discard the protection information because it has been seen before.
Drive by improvement: use g_queue_clear_full instead of foreach+clear for
protection events.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3547>
jpegdec is capable to parse input frames, but if jpegparse is before,
there's no need to reparse frames. This patch configure jpegdec as
packetized, skipping parsing, if negotiated sink caps has the boolean
field 'parsed' as true.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2464>
According to comment in gst_pulsering_stream_latency_cb, latency updates
happen every 100 ms. The code in gst_pulsering_stream_latency_cb does
not care about the actual state of the ringbuffer, pbuf->acquired or
not.
Thus, every 100 ms the ringbuf->segdone may be set, even though the
object itself might be in 'destroyed' state. On next
gst_pulseringbuffer_acquire the segdone is not touched, so playback may
resume with invalid/wrong segdone value. This finally leads to a period
of silence playing after resuming the pipeline.
The problem was found on 'not-yet-released'-hardware and so far was not
reproducible on desktop computer.
Removing the callback as long as the ringbuffer is not in 'acquired'
state solves the problem reliably on the hardware device that the issue
was detected on.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3082>
The stream selection is done on the currently outputting tracks, but in order to
(de)activate the backing streams we can only do it if the input and output
period are identical.
Fixes crash when doing stream selection during period migration
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3525>
This regression was introduce by fix for making buffer pool thread safe. When
we renegotiate, the pool will be setup after we set the format. But the code
has been simplified to only get the pool once before, which caused a null
pointer deref.
Fixes 94ba019 ("v4l2: Fix SIGSEGV on 'change state' during 'format change'")
Related to !3481Fixes#1626
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3513>
Currently in rtp_session_send_rtp(), the existing ntp-64 RTP header
extension timestamp is updated with the actual NTP time before sending
the packet. However, there are some circumstances where we would like
to preserve the original timestamp obtained from reference timestamp
buffer metadata.
This commit provides the ability to configure whether or not to update
the ntp-64 header extension timestamp with the actual NTP time via the
update-ntp64-header-ext boolean property. The property is also exposed
via rtpbin. Default property value of TRUE will preserve existing
behavior (update ntp-64 header ext with actual NTP time).
Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/1580
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3451>
- Based heavily on the existing Qt5 integration however:
- The sharing of OpenGL resources is slightly different
- The integration with the scengraph is a bit different
- Wayland, XCB and KMS have been smoke tested. Android, MacOS/iOS,
Windows may or may not work.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3281>
Previously we tried to route an incoming RTCP FB FIR to the correct ssrc
using the "media source" component of the RTCP FB message. However,
according to RFC5104 (section 4.3.1.2) the "media source" SHALL be set
to 0. Instead the ssrc(s) in use are propagated via the FCI data. Now
a specific GstForceKeyUnit event is sent for every ssrc.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3292>
RTP source statistics are tracked for local senders by
treating them as a receiver of their own outbound packets.
Accordingly, track the highest packet seqnum so that the
packets-lost calculation generates a sensible number instead
of always reporting -$number_of_packets_sent
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3454>
When getting a "404 Not Found" response from the DESCRIBE request, the
source produced a "No supported authentication protocol was found" error
instead of passing on the 404, which was confusing.
Only produce this error message when we're handling a response of "401
Unauthorized" without a compatible WWW-Authenticate header.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3414>
In current tile representation, only tiles with power of two
width and height in bytes are supported. This limitation
prevents adding more complex tiles formats.
In this patch, we deprecate tile_ws and tile_hs from GstVideoFormatInfo and
replace if with an array of GstVideoTileInfo. Each plane tiles are then
described with their pixels width/height, line stride and total size.
The helper gst_video_format_info_get_tile_sizes() that depends on the
deprecated API is also being removed. This can simply be removed as it wasn't
in any stable release yet.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3424>
The only case where we definitely need to write a new trun is when the
data_offset value does not match the end of the list of entries.
Needing multiple trun atoms is required when interleaving multiple
streams together.
All other cases can be covered by adding more entries to the existing
trun atom.
Fixes playback of fragemented mp4 in ffplay and chrome.
Using e.g. mp4mux fragment-duration=1000 fragment-mode=dash-or-mss
and
mp4mux fragment-duration=1000 fragment-mode=first-moov-then-finalise
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3426>
Postpone the cleanup of any consecutive sequence of lost frames
which starts at frame 0, until frame 100 is dequeued from driver.
This allows fluster tests JVT/CVWP2_TOSHIBA_E, JVC/CVWP3_TOSHIBA_E
and HEVC/POC_A_Bossen_3 that sends out-of-order frames to successfully
complete (e.g., test of Amphion vpu driver).
Fixes#1569
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3398>
In order to figure out if the "raw" audio contained within the wav
container is actually DTS, wavparse calls the typefinder helper
except that means it runs all typefinders.
Since it only cares about checking for DTS, we should only run the
audio/x-dts typefinder (if present). Commit 858e516 did not really
fix things.
Use the new type helper with the caps to fix this.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3417>
Set udpsrc seqnums on all events sent to the udpsrc's, and before
forwarding events out of rtspsrc set the latest seek seqnum on them if
any.
Also produce a consistent seqnum in rtspsrc from the very beginning.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3409>
Instead of returning a "const gchar" or a "gchar" that should not be freed, always
return a duplicated string as those functions were used together with g_strdup anyway.
This is needed to prepare support for returning modified strings in next commit.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1147>
This is small regression from commit f7abd81a.
When calling `gst_element_query()` no pad is associated with that query, but the
current code always forwards the query to the associated pad, which is NULL in
previous case. This patch checks for the pad before forwarding the query.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3404>
In a few cases throughout qtdemux, the results of QT_UINT32 were being
stored in a signed integer, which could cause subtle bugs in the case of
an integer overflow, even allowing the the result to equal a negative
number!
This patch prevents this by simply storing the results of this function
call properly in an unsigned integer type. Additionally, we fix up the
length checking with stsd parsing to prevent cases of child atoms
exceeding their parent atom sizes.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3344>
Unlike the legacy elements, GstAdaptiveDemuxStream is a GObject now,
so a bunch of things that were actually stream methods on the
parent demux object can directly become stream methods now.
Move the stream class out to a header of its own.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3314>
Sometimes g_input_stream_read_all_finish() can return
0 bytes, but still succeed (return TRUE) and have more
data available later. Only finish the transfer
if it returns 0 bytes *and* FALSE with no error.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3314>
The cancelled flag was only set in the stream finalize()
method, after all activity on the stream has stopped anyway.
Replace uses of cancelled with checks on the stream state.
Remove the replaced flag, which was checked but never set
to TRUE anywhere any more.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3314>
When matching segments across playlists with Program-Date-Times,
use the difference in segment PDTs to adjust the stream time
that's being transferred. This can fix cases where the
segment boundaries don't align across different streams
and the first download gets thrown away once the PTS
is seen and found not to match.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3309>
Check whether the init file / MAP data for a segment
is different to the current data and trigger an
update if so. Previously, the header would only
be checked in HLS after switching bitrate or
after a seek / first download.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3307>
Previously the minimum buffering threshold was hardcoded to a specific
value (10s). This is suboptimal this an actual value will depend on the actual
stream being played.
This commit sets the low watermark threshold in time to 0, which is an automatic
mode. Subclasses can provide a stream `recommended_buffering_threshold` when
update_stream_info() is called.
Currently implemented for HLS, where we recommended 1.5 average segment
duration. This will result in buffering being at 100% when the 2nd segment has
been downloaded (minus a bit already being consumed downstream)
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3240>
In order to figure out if the "raw" audio contained within the wav
container is actually DTS, right now we call the typefinder helper
which runs all typefinders.
Speed up this type finding process by specifying the extension.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3294>
We've seen occasional crashes in the `wavparse` module associated with
referencing a buffer in `gst_wavparse_chain` that's already been freed. The
reference is stolen when the buffer is transferred to the adapter with
`gst_adapter_push` and, IIUC, assuming the source doesn't hold a reference to
the buffer, the buffer could be freed during interaction with the adapter in
`gst_wavparse_stream_headers`.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3179>
in certain ways.
In the case that a test is provided for, the size of the `fmt ` chunk is
changed from 16 bytes to 18 bytes (bytes 17 - 20 below):
```
$ hexdump -C corruptheadertestsrc.wav
00000000 52 49 46 46 e4 fd 00 00 57 41 56 45 66 6d 74 20 |RIFF....WAVEfmt |
00000010 12 00 00 00 01 00 01 00 80 3e 00 00 00 7d 00 00 |.........>...}..|
00000020 02 00 10 00 64 61 74 61 |....data|
00000028
```
(Note that the original file is much larger. This was the smallest sub-file
I could find that would generate the crash.)
Note that, while the same issue doesn't cause a crash in pull mode, there's a
different issue in that the file is processed successfully as if it was a .wav
file with zero samples.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3173>
This is a regression that was introduced in
cca2f555d1 (yes, 9 years ago).
The only place where a demuxer streaming thread should be stopped is when the
sinkpad is deactivated from pull mode (i.e. PAUSED->READY).
Attempting to stop the task in this function would cause this to happen when a
FLUSH_STOP or STREAM_START event is received... which can cause deadlocks.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3109>
If the SETUP request returns an IPv6 server address in the Transport
field, we would generate an incorrect URI, and multiudpsink would fail
to initialize:
```
rtspsrc gstrtspsrc.c:9780:dump_key_value:<source> key: 'Transport', value: 'RTP/AVP;unicast;source=fe80::dc27:25ff:fe5e:bd13:8080;client_port=62696-62697;server_port=4000-4001'
...
rtspsrc gstrtspsrc.c:4595:gst_rtspsrc_stream_configure_udp_sinks:<source> configure RTP UDP sink for fe80::dc27:25ff:fe5e:bd13:8080:4000
...
multiudpsink gstmultiudpsink.c:1229:gst_multiudpsink_configure_client:<udpsink0> error: Invalid address family (got 23)
```
We can't look at stream->is_ipv6 because we can't rely on the server
returning the right value there. In the issue reported about this,
server reported itself as `KuP RTSP Server/0.1`, and the SDP was:
```
c=IN IP4
m=video 54608 RTP/AVP 96
a=rtpmap:96 H264/90000
```
So we need to parse the string value and figure out the family
ourselves.
Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/1058
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1819>
Update unit test for some mpd cases that were reporting
timestamps including the period start time, while
dashdemux2 expects that it needs to add the period
start time itself.
Fix the tests to not expect the period start time
to be included.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3025>
These values will be referred to as timestamp relative to period start
so need to subtract period start time from the values.
Fixes a problem with determining the start position when playing Live content
with SegmentTimeline, presentationTimeOffset and a non-0 period start time.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3025>
Starting with Meson 0.62, meson automatically populates the variables
list in the pkgconfig file if you reference builtin directories in the
pkgconfig file (whether via a custom pkgconfig variable or elsewhere).
We need this, because ${prefix}/libexec is a hard-coded value which is
incorrect on, for example, Debian.
Bump requirement to 0.62, and remove version compares that retained
support for older Meson versions.
Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/1245
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3061>
Change the way streams are woken up to download more data.
Instead of checking the level on tracks that are being
output as data is dequeued, calculate a 'wakeup time'
at which it should download more data, and wake up
the stream when the global output position crosses
that threshold.
For efficiency, compute the earliest wakeup time
for all streams and store it on the period, so the
output loop can quickly check only a single value
to decide if something needs waking up.
Does the same buffering as the previous method,
but ensures that as we approach the end of
one period, the next period continues incrementally
downloading data so that it is fully buffered when
the period starts.
Fixes issues with multi-period VOD content where
download of the second period resumes only after
the first period is completely drained.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3055>
Some servers can return playlists with "old" media playlists and different
Discont Sequence.
In those cases, the segment stream times would be negative when creating a new
time mapping. In order to properly handle such scenarios, shift the values to
stored accordingly to end up with non-negative reference stream time.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3054>
GLib made the unfortunate decision to prevent libgobject from ever being
unloaded, which means that now any library which registers a static type
can't ever be unloaded either (and any library that depends on those,
ad nauseam).
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/778>
When advancing fragment in live, it's normal to return
GST_FLOW_EOS when playing at the live edge of the available
fragments. In that case, we still want to adjust bitrate
dynamically.
Fixes issue with dashdemux2 where the current bitrate of
each adaptation set is changed to the lowest one when
updating the mpd for a live stream.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3020>
Just like for the seconds field, there are no limitations on the hours and
minutes fields. The specification for xml schema duration fields doesn't forbid
specifying durations with only (huge) minutes or hours values.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2951>
When updating a manifest during live playback, preserve the current
representation for each stream.
During update_fragment_info, if the current representation changed
because it couldn't be matched, trigger a caps change and new
header download.
This reverts commit e0e1db212f
and reapplies "dashdemux: Fix issue when manifest update sets slow start
without passing necessary header & caps changes downstream" with
changes.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2920>
Timers for RTX packets are dealt with later in update_rtx_timers(), and
timers for non-RTX packets would potentially also be unscheduled a
second time from there so avoid that.
Also don't shadow the timer variable from the outer scope but instead
make use of it directly.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2973>
libsoup 3.0.x dispatches using a single source attached when the session
is created, so we need to create the session with the same context that
our download thread is later using.
2.74 or 3.1 will dispatch a response using the context which sent the
request. However, for any context other than the one that created the
session, this will also create and destroy sources, so there's still
some slight performance benefit.
Fixes: https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/1384
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2913>
Handle select-streams and seek events in an element
level send_event() vfunc, so they can be received
before any source pads are created.
This allows preferred streams to be selected before
segment downloading starts.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2912>
When stopping the element, make sure the pad task
is stopped before destroying the part readers.
Closes a race where the pad task might access
a freed pointer.
Also add a guard against this sort of thing
by holding a ref to the reader in the pad loop.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2901>
When playing live, it's possible that one stream reaches
the end of the available playback window and goes to sleep
waiting for a manifest update, and the manifest update
introduces a new period. In that case, the sleeping
stream needs to wake up and go 'properly' EOS before we
can advance the input to the new period.
Accordingly, make sure that a stream's last_ret value
is not marked as EOS if it's just sleeping waiting for a live
manifest update.
Also fix the output loop to go back and re-check if it's
time to switch to the next period after dequeuing and
discarding an EOS event.
https://livesim.dashif.org/livesim/periods_20/testpic_2s/Manifest.mpd
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2895>