Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix duplicate segment requests for low-latency contents #1422

Merged
merged 1 commit into from
Apr 9, 2024

Conversation

peaBerberian
Copy link
Collaborator

Based on #1421

Multiple requests for the same segments for some low-latency contents

This fixes a complex issue that may arise for DASH low-latency contents where the RxPlayer could load multiple times the same segment (usually two times at most and only for the last segment).

In low-latency contents, segments might be anounced in an MPD through <S> elements with their duration (d attribute) not set to their final value (less than it, e.g. an estimate of what is currently encoded).

Here, the RxPlayer would load that segment, and it would internally announce through its SegmentSink module that a segment with the corresponding shorter duration should be pushed to a media buffer.

That SegmentSink keeps a SegmentInventory listing all segments it thinks are currently buffered by the browser (for various purposes, including detection of segment's automatic garbage-collection). It will here associate the shorter duration to that segment at first (from that point on, it is difficult to determine if that shorter end will be considered as the true segment's end by the SegmentInventory or if it will put more trust into the presumably bigger announced buffered time range coming from the buffer, as the algorithm gets quite complex).

Then the RxPlayer will at some point update the MPD, potentially now see the true duration of the segment and either:

  • See that the same segment is already being pushed or has already been loaded and not try to re-load it (scenario 1).

    This is the scenario we always want to follow here.

  • That due to the differences between segment durations before/after the MPD update, we are now considering a different segment than before (scenario 2).

    It seems that this scenario was the most frequent.

  • The SegmentInventory could announce that a shorter segment is buffered. The RxPlayer would then think that the older version has been garbage collected (scenario 3).

    This one is only theoretically possible. I fixed it at the same time than the scenario 2 which is the only one I actually observed, so I cannot confirm that this scenario 3 happens.

Here there's multiple fixes to prevent those two last scenarios from happening.

Parsing issue

First, there was an issue where our parser ignored the availabilityTimeComplete attribute when it was on a <SegmentTemplate> element at the <AdaptationSet> level.
This is the attribute announcing that segments might not be fully available right away - a scenario which was already specifically-handled in the RxPlayer.
This is now fixed.

Consider non-complete segments of different durations as the same

A second issue was that we still may have relied on the original segment's duration at multiple places for such segments, especially in the getNeededSegments function, which is the function listing segments we need to request.
As the duration could have changed in-between MPD updates, that code would think that we're encountering another segment.

To fix it, I now just consider the segment's start (and Representation) to check if this is the same segment - though only if the segment could be considered as non-complete (which is true for the last segment of a SegmentTimeline associated to a availabilityTimeComplete attribute set to false). In other cases, the older logic of checking both the start and duration still stands.

Better buffered end estimation

Another fix, was to just better evaluate in the SegmentInventory the end of non-complete segments, by assuming that they may have a much further end in the buffer than expected. Here also, this update is only set for such non-complete segments.

@peaBerberian peaBerberian changed the base branch from fix/maxVideoBufferSize-optimist to dev April 3, 2024 10:39
@peaBerberian peaBerberian added the bug This is an RxPlayer issue (unexpected result when comparing to the API) label Apr 3, 2024
@peaBerberian peaBerberian added this to the 4.1.0 milestone Apr 3, 2024
This fixes a complex issue that may arise for DASH low-latency
contents where the RxPlayer could load multiple times the same segment
(usually two times at most and only for the last segment).

In low-latency contents, segments might be anounced in an MPD through
`<S>` elements with their duration (`d` attribute) not set to their
final value (less than it, e.g. an estimate of what is currently
encoded).

Here, the RxPlayer would load that segment, and it would internally
announce through its `SegmentSink` module that a segment with the
corresponding shorter duration should be pushed to a media buffer.

That `SegmentSink` keeps a `SegmentInventory` listing all segments it
thinks are currently buffered by the browser (for various purposes,
including detection of segment's automatic garbage-collection). It
will here associate the shorter duration to that segment at first (from
that point on, it is difficult to determine if that shorter end will be
considered as the true segment's end by the `SegmentInventory` or if it
will put more trust into the presumably bigger announced buffered time
range coming from the buffer, as the algorithm gets quite complex).

Then the RxPlayer will at some point update the MPD, potentially now see
the true duration of the segment and either:

  - See that the same segment is already being pushed or has already
    been loaded and not try to re-load it (scenario 1).

    This is the scenario we always want to follow here.

  - That due to the differences between segment durations before/after
    the MPD update, we are now considering a different segment than
    before (scenario 2).

    It seems that this scenario was the most frequent.

  - The `SegmentInventory` could announce that a shorter segment is
    buffered. The RxPlayer would then think that the older version has
    been garbage collected (scenario 3).

    This one is only theoretically possible. I fixed it at the same time
    than the scenario 2 which is the only one I actually observed, so I
    cannot confirm that this scenario 3 happens.

Here there's multiple fixes to prevent those two last scenarios from
happening.

---

First, there was an issue where our parser ignored the
`availabilityTimeComplete` attribute when it was on a `<SegmentTemplate>`
element at the `<AdaptationSet>` level.
This is the attribute announcing that segments might not be fully
available right away - a scenario which was already specifically-handled
in the RxPlayer.
This is now fixed.

---

A second issue was that we still may have relied on the original
segment's duration at multiple places for such segments, especially in
the `getNeededSegments` function, which is the function listing
segments we need to request.
As the duration could have changed in-between MPD updates, that code
would think that we're encountering another segment.

To fix it, I now just consider the segment's start (and Representation)
to check if this is the same segment - though only if the segment could
be considered as non-complete (which is true for the last segment of a
`SegmentTimeline` associated to a `availabilityTimeComplete` attribute
set to `false`). In other cases, the older logic of checking both the
start and duration still stands.

---

Another fix, was to just better evaluate in the `SegmentInventory` the
end of non-complete segments, by assuming that they may have a much
further end in the buffer than expected. Here also, this update is only
set for such non-complete segments.
@peaBerberian peaBerberian force-pushed the fix/duplicate-requests-low-latency2 branch from 055083b to 1c11733 Compare April 3, 2024 17:31
@peaBerberian peaBerberian merged commit 76015a2 into dev Apr 9, 2024
6 checks passed
@peaBerberian peaBerberian added DASH Relative to the DASH streaming protocol low-latency Relative to low-latency (live playback close to the live edge) Priority: 0 (Very high) This issue or PR has a very high priority. Efforts should be concentrated on it first. labels Apr 9, 2024
@peaBerberian peaBerberian deleted the fix/duplicate-requests-low-latency2 branch July 26, 2024 16:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug This is an RxPlayer issue (unexpected result when comparing to the API) DASH Relative to the DASH streaming protocol low-latency Relative to low-latency (live playback close to the live edge) Priority: 0 (Very high) This issue or PR has a very high priority. Efforts should be concentrated on it first.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants