So the issue is the MediaCache is evicting data that the MediaDecoderStateMachine uses to trigger entering a buffering state, and if this coincides with the MDSM's decoded sample queues being full, there's nothing to cause us to re-download that evicted data, and we end up getting indefinitely stuck in a buffering state.
What happens is our audio and video demuxers advance with different read cursors; the audio runs ahead 2 seconds. The MediaCache tries to keep a record of whether a "block" in the cache is a "read ahead" block, or a "played" block. The MediaCache records the offset at which each MediaCacheStream was last read in MediaCacheStream::mStreamOffset, and assumes blocks before that offset are "played" and can be evicted.
The MDSM assumes that it needs to start buffering if the lesser of the end of the decoded audio and end of the decoded video data isn't in our buffered ranges. https://searchfox.org/mozilla-central/rev/f0ef51bfafc8ad0c3a2f523bf076edc57dc4891a/dom/media/MediaDecoderStateMachine.cpp#3282
In practice the lesser will be the video demuxer's read cursor. However when the MediaCache is full it will evict data before the last read on the stream. If the last read on the stream was a read from the audio demuxer, this will end up being the greater of the end of the decoded audio and end of the decoded video data, as we run the audio decoder about 2 seconds ahead.
Thus the MediaCache will evict the data which causes the MDSM to go into buffering mode, and also the data the MDSM would need to get out of buffering mode.
If the MDSM's happens to have full decoded sample queues, or if all data required to fill the MDSM's sample queues are cached in MediaResourceIndex's, the MediaResource won't be read from, and so the MediaCache won't update and re-download the data around the current playback position, and so we won't ever get out of buffering state, and playback will stall indefinitely.
Re-downloading the evicted data would be bad, we're better off not evicting it in the first place.
I think the solution here is to tweak MediaCache::PredictNextUse such that it assumes the read offset is the lesser of the read cursors of the MediaResourceIndex's as well as MediaCacheStream::mStreamOffset. Then we'll have the same assumption as the MDSM's logic. Then we won't evict data which the MDSM's buffering logic uses to enter/exit buffering state.