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

SwitchHistoryRule limits quality incorrectly #2115

Closed
twdkeule opened this issue Aug 6, 2017 · 5 comments
Closed

SwitchHistoryRule limits quality incorrectly #2115

twdkeule opened this issue Aug 6, 2017 · 5 comments

Comments

@twdkeule
Copy link
Contributor

twdkeule commented Aug 6, 2017

The check drops + noDrops >= SAMPLE_SIZE is placed incorrectly.
If quality starts at level 1, drops to lvl 0 and then rises to lvl 4 and stays there, quality will sometimes we limited to lvl 3, which makes no sense.

In the for loop there is in this order:

  • a nodrop at lvl 0 => MAX_SWITCHOK, but not enough samples
  • a drop at lvl 1 => MAX_SWITCH not OK , but not enough samples
  • 4 nodrops at lvl 4 => enough samples, but MAX_SWITCH is still not OK from the previous drop at lvl 1 => limit quality to level 3. Which, again, makes no sense.
     for (let i = 0; i < switchRequests.length; i++) {
            if (switchRequests[i] !== undefined) {
                drops += switchRequests[i].drops;
                noDrops += switchRequests[i].noDrops;
                dropSize += switchRequests[i].dropSize;

                if (drops + noDrops >= SAMPLE_SIZE && (drops / noDrops > MAX_SWITCH)) {
                    switchRequest.value = i > 0 ? i - 1 : 0;
                    switchRequest.reason = {index: switchRequest.value, drops: drops, noDrops: noDrops, dropSize: dropSize};
                    log('Switch history rule index: ' + switchRequest.value + ' samples: ' + (drops + noDrops) + ' drops: ' + drops);
                    break;
                }
            }
        }
@twdkeule
Copy link
Contributor Author

twdkeule commented Aug 6, 2017

Related to #1892.
I will probably file a PR somewhere in September.

@spiterikevin
Copy link
Contributor

I'm not sure the issue is with the loop order. If I understood the code correctly, the SwitchRequestsRule behaviour is described by the following pseudocode:

dropFrom = lowest quality immediately followed by a lower quality during last 8 segment downloads
if dropFrom exists {
    forbidden = lowest quality q such that
        a) q >= dropFrom AND
        b) there are at least 6 segments during last 8 segments with quality not better than q
}
return forbidden exists ? forbidden - 1 : NO_CHANGE

Note that the rule only considers segment order when figuring out if a quality change is a drop, otherwise the segment order within the last eight segment download does not matter.

In your example dropFrom = 1, but there are less than six segments at level 0 and level 1. Thus level 4 segments are needed to make up the six segments in condition b, leading to level 4 being forbidden.

My suggestion is that if we used extra segments at some level (4 in the example) to satisfy condition b, then that should be the highest allowed level rather than the forbidden level. I think that can be achieved by changing one line:
switchRequest.value = (i > 0 && switchRequests[i].drops > 0) ? i - 1 : i;

spiterikevin added a commit to spiterikevin/dash.js that referenced this issue Aug 9, 2017
dsparacio pushed a commit that referenced this issue Aug 18, 2017
issue #2115 - do not disallow quality that did not cause drop
@Douina
Copy link

Douina commented Apr 18, 2021

please can any one explain to me the SwitchHistoryRule ,please i didn't undrestrand it and i need it

@spiterikevin
Copy link
Contributor

SwitchRequestHistory stores switch history for the last SWITCH_REQUEST_HISTORY_DEPTH=8 switchRequests. If a switchRequest changes the quality from oldValue to newValue such that newValue is a lower quality than oldValue, then it counts as a drop. Otherwise it counts as a noDrop.

switchRequests[i] contains a sum of the drop and noDrop counts for each swithRequest in the last 8 for which oldValue was i.

SwitchHistoryRule starts from the lowest quality 0 counting up. Let us say we are counting up and reached quality 2. If there are at least SAMPLE_SIZE=6 samples for oldValues between 0 and 2 inclusive, and drop/noDrop > 0.075 for those 6+ samples, then SwitchHistoryRule returns a maximum quality of 2-1 = 1. The point is to avoid downloading at quality 2 because recent history suggests it is likely to have to drop back to quality 1 or 0 causing excessive switches.

Note that since the history depth is 8, just 1 drop is sufficient to block a quality because drop/noDrop is always going to be larger than 0.075 if drop is 1. However, recall that this is always subject to having a minimum of 6 samples.

@Douina
Copy link

Douina commented Apr 21, 2021

SWITCH_REQUEST_HISTORY_DEPTH=8
and what about 8 segments ,8 segs that we are already readed it , or of the buffer ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants