Storing it per-stream requires taking the manifest lock which can apparenly be
hold for aeons. And since the QoS event comes from the video rendering thread
we *really* do not want to do that.
Storing it as-is in the element is fine, the important part is knowing the
earliest time downstream.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/1021>
Worst case it will be empty. This fixes a crash when the base class
calls data_received() when the stream is neither is_isobmff or
has_isoff_ondemand_profile.
https://bugzilla.gnome.org/show_bug.cgi?id=796745
In some cases, it is possible that we need to update the manifest before
pads have been exposed at all. If there are no current pads, just expose
the next prepared streams. This doesn't handle the case where a manifest
update would happen while a live streams is changing periods, which is a
type of use case that we're unaware of real usages yet.
https://bugzilla.gnome.org/show_bug.cgi?id=783028
This is wrong because:
* If the rate is negative we should check for the *previous* period
* adaptivedemux already does the proper checks before calling this
method
This ensures smoother playback. It looks weird if we first do a big
jump, then play a couple of consecutive frames, just to again skip ahead
quite a bit because we ran late again.
Far enough here means more than 500ms or 4 times the average keyframe
download time. There is no need to jump ahead by one average keyframe
download time in this case.
This makes playback smooth if the network is fast enough.
When dealing with key-unit trick mode downloads, the goal is to
provide the best "Quality of Experience". This is achieved by:
1) maximizing the number of frames displayed per second
2) avoiding "stalling" as much as possible (i.e. not downloading and
decoding frames fast enough)
This implementation achives this by:
1) Knowing very precisely the current keyframe being download (i.e
more accurate than at the fragment level which might contain more
than one keyfram). This is the new "actual_position" variable
introduced by this commit
2) Knowing the position of downstream (provided by QoS and stored
in the adaptivedemuxstream qos_earliest_time variable)
3) Knowing how long it takes to request and fully download a keyframe
(the average_download_time variable)
Taking those 3 variables into account, whenever a keyframe has been
pushed downstream we calculate a "target time" (target_time variable)
which is the ideal next keyframe time to request so that:
1) It will be requested/downloaded/demuxed/decoded in time to be
displayed without being too late
2) It will not be too far ahead that it would cause too few frames
per second to be displayed.
How far ahead we will request is inversily proportional to how close
the actual position (actual_position) is from the downstream
position (qos_earliest_time). The more is buffered between the source
and the sink, the "closer" the target time will be, and therefore
the more frames per seconds will be displayed (up to the limit
of keyframes_per_second * absolute_rate).
If a manifest has non-zero presentation time offset
(i.e., earliest presentation time specified by sidx box is not zero),
the initial sidx position shouldn't be zero. Since we cannot define
exact sidx position until parsing sidx box, set the value to unknown.
https://bugzilla.gnome.org/show_bug.cgi?id=782693
The previous code was handling both as separate steps and then tried to
combine the results, but this resulted in all kinds of bugs which showed
themselves as failures during seeking and offset tracking getting wrong.
This also showed itself with gst-validate on the sample stream.
The rewritten code now parses everything in one go and tracks the
current offset only once, and as a side effect simplifies the code a
lot.
Also added is detection of SIDX that point to other SIDX instead of
actual media segments, e.g. with this stream:
http://dash.akamaized.net/dash264/TestCases/1a/sony/SNE_DASH_SD_CASE1A_REVISED.mpd
Support for this will have to be added at some point but that should
also be easier with the rewritten code.
https://bugzilla.gnome.org/show_bug.cgi?id=781233
This reverts commit c9fbf3459a.
The representation ID comparision here was wrong and triggering always
if the ID did *not* change, causing needless redownloading of the
header. The sample stream provided in the bug does not exist anymore.
Otherwise we'll get into an infinite loop here. Now this is still not
correct and will cause a clean error, but at least it won't hang forever
anymore.
For each period, media presentation is the relative to the
period-start time. So SIDX seek position should be target seek
position minus period-start. Also, if presentationTimeOffset
is defined, the value should be compensated
https://bugzilla.gnome.org/show_bug.cgi?id=780397
Instead of just going to the first or last fragment, report if we're
going outside the index. This should never happen unless there's a bug
or the stream is broken.
Allow some possibility for inaccuracies here though.
There is no guarantee that the index positions are the same between
representations, and assuming this easily causes us to get into invalid
index positions.
If a MPD is On-Demand profile and no index described, demux will terminate
download loop after parsing inband SIDX with flow return custom-success.
At this moment, SIDX index is excat target position, but finish_fragment()
might cause re-advancing subfragment depending on MPD structure.
https://bugzilla.gnome.org/show_bug.cgi?id=776200
SIDX's base offset (i.e., byte offset of SIDX + sidx.first_offset)
mostly vary as per fragment. Also, target SIDX index must be zero for the
new fragment.
https://bugzilla.gnome.org/show_bug.cgi?id=776200
Try to find fragment using MPD first, then do refinement to find
target subframgnet using SIDX if possible. Note that, if target fragment
was moved from the previously activated one, we should assume that
the last SIDX is invalid for new fragment.
https://bugzilla.gnome.org/show_bug.cgi?id=776200