You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Improve default live quality increase settings to work with live streams playing at ~3 segments live offset. #9784
I'm reproducing an issue with all versions of ExoPlayer from 2.13.0 to 2.16.1 where ExoPlayer does not switch to a higher resolution on a Live DASH stream with AVC video tracks.
ExoPlayer starts playing the 896x504 track then never chooses 1280x720 or 1920x1080 even if there is enough network bandwidth.
As stream URL and DRM info are sensitive, I'll provide you by email a sample code hosted on a private GitHub repository to help you reproduce the issue. Please let me know if you need anything else.
The short answer is that there is not enough buffered data to safely switch up to a higher quality.
The manifest is configured with a suggested presentation delay of 9.6 seconds, which is exactly 3 segments (as one segment duration is 3.2 seconds). So at the point where the player needs to select a newly available segment, it has at most 6.4 seconds (=2 segments) of media buffered. The actual value I observed with my network was between 5 and 6 seconds.
The AdaptiveTrackSelection default configuration has two relevant values for switching up:
minDurationForQualityIncreaseMs (set to 10 seconds by default)
bufferedFractionToLiveEdgeForQualityIncrease (set to 0.75 by default) => effective threshold: 0.75 * 9.6 seconds = 7.2 seconds, or slightly less, depending on actual timing
The buffered duration needs to be more than one of these two values for the player to switch up to a higher quality. This never happens (as it is between 5 and 6 seconds), and so the player stays at the lower quality although the bandwidth measurements support switching up. If you change the setting of either value it'll work (for example bufferedFractionToLiveEdgeForQualityIncrease to 0.5 or minDurationForQualityIncreaseMs to 5 seconds).
The issue has come up multiple times now for live streams that have a reasonable configuration of playing about 3 segments away from the live edge (e.g. #9643). A live offset of 3 segments is also recommended by default for HLS. So we should ensure our default configuration allows such streams to increase the quality under good conditions.
There are two options to implement this:
We could change the default of bufferedFractionToLiveEdgeForQualityIncrease to 0.5. This would ensure that live playbacks with a configured live offset of 3 segments get a chance to switch up (because the actual buffered fraction will be between 0.5 and 0.66 under good network conditions).
We can change the definition of availableDurationUs in AdaptiveTrackSelection.updateSelectedTrack to only include the time that was actually available for buffering before calling this method. So in the example above, this would be 6.4 seconds instead of 9.6 seconds. This would ensure the default parameters work as intended again (0.75 *6.4 seconds = 4.8 seconds < 5-6 seconds of buffered duration).
changed the title [-]No adaptive track selection on Live DASH stream with AVC[/-][+]Improve default live quality increase settings to work with live streams playing at ~3 segments live offset.[/+]on Dec 14, 2021
Hi @tonihei , I encountered same issue and tested the above fix commit. It improves the behaviour but I can still reproduce this for some cases where I have 4 seconds segments and 4 seconds as MPD update period. Below is my observation. Each MPD update contains 4 segments with a new segment added and oldest segment removed every MPD update(4 seconds).
The available duration is constantly > 12 seconds, so minDurationForQualityIncrease is returned as 10 seconds.
Buffered duration goes above 10 seconds threshold only when all segments in MPD are downloaded.
At this point there are no more segments to download. So even if download rate is much higher, and a higher bitrate rendition is selected to downloaded next but the switch up does not occur.
By the time next MPD update occurs(after approx. 3-4 seconds), one more segment is added and oldest one removed. The available duration remains > 10 seconds but buffered duration reduces < 10 seconds as approx. 3-4 seconds have elapsed since last download and the buffer level has come done to around 8 seconds. As buffer level(approx. 8 seconds) is < minDurationForQualityIncrease (10 seconds), so no switch up occurs. The newly added segment is downloaded for older quality.
Now buffer duration > 10 seconds after segment download but there is no next segment to download yet. The above sequence repeats with next manifest update e.i when segment becomes available bufferDuration < 10 seconds and when bufferDuration > 10 seconds, next segment is not available yet for download.
Hi @tonihei with the above insight provided against this issue still being present for 4 Second segments with a 4 second update period can I ask would you be able to reopen this ticket to handle this permutation also?
Can I also ask in the interim of this issue not being merged and the above 4sec segment issue observed what would recommend for segment update and segment length to not encounter this issue? Do you see an issue with 2Sec segments with a 4second update for example.
What you describe above is exactly the problem we solved I believe.
By the time next MPD update occurs(after approx. 3-4 seconds), one more segment is added and oldest one removed. The available duration remains > 10 seconds but buffered duration reduces < 10 seconds as approx. 3-4 seconds have elapsed since last download and the buffer level has come done to around 8 seconds.
In this scenario, we have bufferedDuration=8 sec, availableDuration= 11 sec, chunkDuration = 4 sec, so the calculated threshold will be minDurationForQualityIncrease = (11 - 4) * 0.75 = 5.25 sec and because bufferedDuration > minDurationForQualityIncrease, the player will be allowed to switch up.
If this doesn't happen, then the measured bandwidth is potentially not high enough for the up-switch? If that's not what you are seeing, please provide a concrete example for values used during the computation or reproduction steps with a specific stream.
can I ask would you be able to reopen this ticket to handle this permutation also
Do you see an issue with 2Sec segments with a 4second update for example.
The new logic works independent of the actual chunk duration, so there is no need to solve it for any particular permutation. But it generally assumes that the MPD update period is the same as the chunk duration to work nicely, so it wouldn't work as well with 2 sec segment and a 4 sec update period.
In this scenario, we have bufferedDuration=8 sec, availableDuration= 11 sec, chunkDuration = 4 sec, so the calculated threshold will be minDurationForQualityIncrease = (11 - 4) * 0.75 = 5.25 sec and because bufferedDuration > minDurationForQualityIncrease, the player will be allowed to switch up.
Above does not happen as availableDuration = 11 seconds is greater than default minDurationForQualityIncreaseUs which is 10 seconds. Due to this isAvailableDurationTooShort is calculated as false and the method minDurationForQualityIncreaseUs returns default value(10 seconds) as as the minimum required duration which is greater than buffered duration(8 seconds). The first check for isAvailableDurationTooShort does not account chunkDurationUs and compares the full available duration with default minimum required duration value of 10 seconds.
private long minDurationForQualityIncreaseUs(long availableDurationUs, long chunkDurationUs) {
boolean isAvailableDurationTooShort =
availableDurationUs != C.TIME_UNSET
&& availableDurationUs <= minDurationForQualityIncreaseUs;
if (!isAvailableDurationTooShort) {
return minDurationForQualityIncreaseUs;
}
..........
I see, thanks for pointing this out! This edge case only applies if availableDurationUs > configured configured minDurationForQualityIncreaseUs, but the adjusted minDurationForQualityIncreaseUs < configured minDurationForQualityIncreaseUs. Will update the condition to always choose the minimum of adjusted and configured minDurationForQualityIncreaseUs.
Activity
tonihei commentedon Dec 14, 2021
The short answer is that there is not enough buffered data to safely switch up to a higher quality.
The manifest is configured with a suggested presentation delay of 9.6 seconds, which is exactly 3 segments (as one segment duration is 3.2 seconds). So at the point where the player needs to select a newly available segment, it has at most 6.4 seconds (=2 segments) of media buffered. The actual value I observed with my network was between 5 and 6 seconds.
The
AdaptiveTrackSelectiondefault configuration has two relevant values for switching up:minDurationForQualityIncreaseMs(set to 10 seconds by default)bufferedFractionToLiveEdgeForQualityIncrease(set to 0.75 by default) => effective threshold: 0.75 * 9.6 seconds = 7.2 seconds, or slightly less, depending on actual timingThe buffered duration needs to be more than one of these two values for the player to switch up to a higher quality. This never happens (as it is between 5 and 6 seconds), and so the player stays at the lower quality although the bandwidth measurements support switching up. If you change the setting of either value it'll work (for example
bufferedFractionToLiveEdgeForQualityIncreaseto 0.5 orminDurationForQualityIncreaseMsto 5 seconds).The issue has come up multiple times now for live streams that have a reasonable configuration of playing about 3 segments away from the live edge (e.g. #9643). A live offset of 3 segments is also recommended by default for HLS. So we should ensure our default configuration allows such streams to increase the quality under good conditions.
There are two options to implement this:
bufferedFractionToLiveEdgeForQualityIncreaseto 0.5. This would ensure that live playbacks with a configured live offset of 3 segments get a chance to switch up (because the actual buffered fraction will be between 0.5 and 0.66 under good network conditions).availableDurationUsinAdaptiveTrackSelection.updateSelectedTrackto only include the time that was actually available for buffering before calling this method. So in the example above, this would be 6.4 seconds instead of 9.6 seconds. This would ensure the default parameters work as intended again (0.75 *6.4 seconds = 4.8 seconds < 5-6 seconds of buffered duration).[-]No adaptive track selection on Live DASH stream with AVC[/-][+]Improve default live quality increase settings to work with live streams playing at ~3 segments live offset.[/+]cdongieux commentedon Dec 14, 2021
Thanks a lot for your detailed answer!
Exclude last chunk when applying fraction for live quality increase
Exclude last chunk when applying fraction for live quality increase
tonihei commentedon Jan 31, 2022
Implemented by the commit above.
luckygoyal-bitmovin commentedon Feb 7, 2022
Hi @tonihei , I encountered same issue and tested the above fix commit. It improves the behaviour but I can still reproduce this for some cases where I have 4 seconds segments and 4 seconds as MPD update period. Below is my observation. Each MPD update contains 4 segments with a new segment added and oldest segment removed every MPD update(4 seconds).
jamesdavidholding commentedon Feb 8, 2022
Hi @tonihei with the above insight provided against this issue still being present for 4 Second segments with a 4 second update period can I ask would you be able to reopen this ticket to handle this permutation also?
Can I also ask in the interim of this issue not being merged and the above 4sec segment issue observed what would recommend for segment update and segment length to not encounter this issue? Do you see an issue with 2Sec segments with a 4second update for example.
tonihei commentedon Feb 10, 2022
@luckygoyal-bitmovin
What you describe above is exactly the problem we solved I believe.
In this scenario, we have
bufferedDuration=8 sec, availableDuration= 11 sec, chunkDuration = 4 sec, so the calculated threshold will beminDurationForQualityIncrease = (11 - 4) * 0.75 = 5.25 secand becausebufferedDuration > minDurationForQualityIncrease, the player will be allowed to switch up.If this doesn't happen, then the measured bandwidth is potentially not high enough for the up-switch? If that's not what you are seeing, please provide a concrete example for values used during the computation or reproduction steps with a specific stream.
@jamesdavidholding
The new logic works independent of the actual chunk duration, so there is no need to solve it for any particular permutation. But it generally assumes that the MPD update period is the same as the chunk duration to work nicely, so it wouldn't work as well with 2 sec segment and a 4 sec update period.
luckygoyal-bitmovin commentedon Feb 10, 2022
thanks @tonihei for your reply.
Above does not happen as
availableDuration = 11 secondsis greater than defaultminDurationForQualityIncreaseUswhich is 10 seconds. Due to thisisAvailableDurationTooShortis calculated asfalseand the methodminDurationForQualityIncreaseUsreturns default value(10 seconds) as as the minimum required duration which is greater than buffered duration(8 seconds). The first check forisAvailableDurationTooShortdoes not accountchunkDurationUsand compares the full available duration with default minimum required duration value of 10 seconds.tonihei commentedon Feb 10, 2022
I see, thanks for pointing this out! This edge case only applies if
availableDurationUs > configured configured minDurationForQualityIncreaseUs, but theadjusted minDurationForQualityIncreaseUs < configured minDurationForQualityIncreaseUs. Will update the condition to always choose the minimum of adjusted and configuredminDurationForQualityIncreaseUs.Make usage of live minDurationForQualityIncrease more consistent
Make usage of live minDurationForQualityIncrease more consistent
Make usage of live minDurationForQualityIncrease more consistent
Make usage of live minDurationForQualityIncrease more consistent