Try harder to make switching pads work better by
making sure concurrent downloads are finished before exposing
a new set of pads.
Release the manifest lock when signalling no-more-pads, as
that can call back into adaptivedemux again
If other stream fragments are still downloading but new streams
have been scheduled, don't expose them yet - wait until the last
one finishes. Otherwise, we can cancel a partially downloaded
auxilliary stream and cause a gap.
Drop the manifest lock when performing actions that might
call back into adaptivedemux and trigger deadlocks, such
as adding/removing pads or sending in-band events (EOS).
Unlock the manifest lock when changing the child bin state to
NULL, as it might call back to acquire the manifest lock when
shutting down pads.
Drop the manifest lock while pushing events.
In the case of KEY_UNIT and TRICKMODE_KEY_UNITS seeks, we want to
"snap" to the closest fragment.
Without this, we end up pushing out a segment which does not match
the first fragment timestamp being pushed out, resulting in one or
more buffers being eventually dropped because they are out of segment.
The gst_adaptive_demux_wait_until() function can be woken up either
by its end_time being reached, or from other threads that want to
interrupt the waiting thread.
If the thread is interrupted, it needs to cancel its async clock callback
by unscheduling the clock callback. However, the callback task might already
have been activated, but is waiting for the mutex to become available. In this
case, the call to unschedule does not stop the callback from executing.
The solution to this second issue is to use a reference counted object that
is decremented by both the gst_adaptive_demux_wait_until() function and the
call to gst_clock_id_wait_async (). In this way, the GstAdaptiveDemuxTimer
object is only deleted when both the gst_adaptive_demux_wait_until() function
and the async callback are finished with the object.
https://bugzilla.gnome.org/show_bug.cgi?id=765728
There are several places in adaptivedemux where it waits for
time to pass, for example to wait until it should next download
a fragment. The problem with this approach is that it means that
unit tests are forced to execute in realtime.
This commit replaces the use of g_cond_wait_until() with single
shot GstClockID that signals the condition variable. Under normal
usage, this behaves exactly as before. A unit test can replace the
system clock with a GstTestClock, allowing the test to control the
timing in adaptivedemux.
https://bugzilla.gnome.org/show_bug.cgi?id=762147
A realtime clock is used in many places, such as deciding which
fragment to select at start up and deciding how long to sleep
before a fragment becomes available. For example dashdemux needs
sample the client's estimate of UTC when selecting where to start
in a live DASH stream.
The problem with dashdemux calculating the client's idea of UTC is
that it makes it difficult to create unit tests, because the passage
of time is a factor in the test.
This commit changes dashdemux and adaptivedemux to use the
GstSystemClock, so that a unit test can replace the system clock when
it needs to be able to control the clock.
This commit makes no change to the behaviour under normal usage, as
GstSystemClock is based upon the system time.
https://bugzilla.gnome.org/show_bug.cgi?id=762147
Happens e.g. if a RECONFIGURE event is sent from downstream while we're
switching pads at this very moment. The old pad is gone and the stream has a
new pad.
https://bugzilla.gnome.org/show_bug.cgi?id=764404
When the start_type is GST_SEEK_TYPE_NONE for a forward seek
(or stop_type for a reverse) is not set on a snap seeking operation,
the element should use the current position and then snap as requested.
Also fixes uninitialized variable complaint by clang about
'ts' variable.
Adaptive demuxers need to start downloading from specific positions
(fragments) for every stream, this means that all streams can snap-seek
to a different position when requested. Snap seeking in this case will
be done in 2 steps:
1) do the snap seeking on the pad that received the seek event and
get the final position
2) use this position to do a regular seek on the other streams to
make sure they all start from the same position
More arguments were added to the stream_seek function, allowing better control
of how seeking is done. Knowing the flags and the playback direction allows
subclasses to handle snap-seeking.
And also adds a new return parameter to inform of the final
selected seeking position that is used to align the other streams.
https://bugzilla.gnome.org/show_bug.cgi?id=759158
The function gst_adaptive_demux_stream_update_source() function creates
a new GstPad called internal_pad. This pad is not freed when releasing
the stream.
The solution is to set GST_PAD_FLAG_NEED_PARENT so that the chain
functions do not get called when the pad has no parent and then
remove the parent in the gst_adaptive_demux_stream_free() function. This
causes the refcount of the pad to be set to zero.
https://bugzilla.gnome.org/show_bug.cgi?id=760982
Handling the ghostpad and its internal pad was causing more issues
than helping because of their coupled activation/deactivation
actions.
As we have to install custom chain,event and query functions it is
better to use a floating sink pad internally in the demuxer and just
use those pad functions to push through a standard pad in the demuxer
https://bugzilla.gnome.org/show_bug.cgi?id=757951
Fixed adaptivedemux seeking without flushing that just wants
to update stop position. This required protecting the segment
variables with a new mutex so that the seeking thread and the
download threads could safely manipulate the segment and
events related to it.
This contention is only locked/unlocked when starting a new
download, when the first fragment of a segment is received and
when seeking so, hopefully, it won't damage performance.
Avoids downloading and pushing a full segment just to get 1 nanosecond
of data. This happens frequently when seeking is done with flags
that adjust to boundaries or when the start is aligned with segment
starts. The later is common when segment durations is a multiple of
a second.
For reverse, set position to segment.stop when starting and also
don't set the position to fragment end timestamp when it finishes,
just leave it at the fragment start.
This no longer does anything, and it was marked as CONSTRUCT_ONLY
which means someone would really have to go out of their way to
be able to set this, which would only be done in very custom
scenarios, if ever, and those will likely target a specific
version of GStreamer then, so probably not much point keeping
it deprecated for a while before removing it.
Bitrate estimation is now handled through a queue2 element added after
the source element used to download fragments.
Original hlsdemux patch by Duncan Palmer <dpalmer@digisoft.tv>
https://bugzilla.gnome.org/show_bug.cgi?id=733959
The gst_adaptive_demux_stream_free function is trying to stop the stream's
download task. For this, it signals the task. But it fails to also set the
stream->download_finished = TRUE, so the task will go back to sleep and
only exit when the download is finished.
https://bugzilla.gnome.org/show_bug.cgi?id=755121