Closed Bug 1062055 Opened 7 years ago Closed 6 years ago

MSE does not recover from source decoder EOF


(Core :: Audio/Video, defect)

Not set





(Reporter: cajbir, Assigned: cajbir)


(Blocks 1 open bug, )



(1 file)

When a source decoder reaches EOF, either video or audio, there are times when the reader is switched to a new reader containing data but the RequestAudioData and RequestVideoData are no longer called. This means the new reader doesn't get data and ultimately the playback stops waiting for more.

This most often happens when seeking but can happen on other reader switches. Viewing the list of decoders in the MediaSourceReader shows there is a reader containing new data but the EOS for the old reader seems to prevent further decoding.
Blocks: MSE, 1056440
Here is an example from logs of what is happening. After a seek we have these buffers.

Active video reader=7f29f3f6b800

Video decoders listed in SwitchReaders were:

decoder=1 discarded=1 reader=7f29fddab000 ranges=[(0.000000, 5.006000)]
decoder=2 discarded=1 reader=7f29f33da800 ranges=[(5.005000, 10.011000)]
decoder=3 discarded=1 reader=7f29f33f2800 ranges=[(10.010000, 15.016000)]
decoder=4 discarded=1 reader=7f29f3316000 ranges=[(15.015000, 20.021000)]
decoder=6 discarded=1 reader=7f29f3f6b800 ranges=[(75.075000, 80.081000)]
decoder=7 discarded=1 reader=7f29fd0cf800 ranges=[(80.080000, 85.086000)]
decoder=8 discarded=0 reader=7f29fce16000 ranges=[(85.085000, 90.091000)]

We had just received an OnVideoEOS:

MediaSourceReader(7f29fcfb8c00)::OnVideoEOS reader=7f29f3f6b800 (readers=9)

This was due to hitting the end of decoder 6. We should then switch to decoder 7 but we can't because our decodeTarget is 79.712988 which is below the range of that decoder. decodeTarget is mTimeThreshold set on VideoDataRequested. This is never called again as we are end of stream and haven't switched.

decodeTarget would seem to be the wrong time to be using based on offline discussion with k18t and kinetik. This is behind our real decoding time. Need to investigate how to get the correct value here.
In bug 1059058, I added mLast{Audio,Video}Time, which is set to aSample->mTime + aSample->mDuration in On{Audio,Video}Decoded.  That's a pretty simple standalone change you could try without depending on all of 1059058.
There's also a potential issue where the WebMReader drops the last frame when it's trying to calculate the frame duration (possibly not hit since you implemented GetMediaEndTime).

Another possibility is to pass the end buffered range of the EOSed reader to SwitchReaders.
Raised bug 1062101 for the mSample->mDuration being wrong.
Assignee: nobody → cajbir.bugzilla
WIP patch. This uses the end time of the decoded that just reached the end of stream as the time code for switching readers. This gets past the 20s stall point in this video:

And also gets past other EOS stalls that happened in the past.
Testing shows this fixes the case of where we already have a stream to that has buffered data for the new time. There are still issues where we don't have a stream to switch to and wait for data to arrive. In that case the data is appended but the RequestVideoData/OnVideoDEcded functions are never restarted. 

Investigating firing tasks to start these if we are switching away from a stream that is EOS.
Raised bug 1063323 for an issue that came up while writing tests to trigger this bug.
Comment on attachment 8483922 [details] [diff] [review]
Use end time of EOS'd decoded for switching readers

Review of attachment 8483922 [details] [diff] [review]:

This fixes the issue where we have hit EOS on a reader but the current decoding time for switching the reader is not at the point where it can switch to a new stream. It uses the approach suggested in comment 3 to switch to the end time of the reader that hit EOS.

This allows [1] to playback completely whereas before it was getting stuck after about 20 seconds of normal playback. There are still some other EOS issues which need tracking down and debugging. I'll raise separate bugs for those.
Attachment #8483922 - Flags: review?(kinetik)
[1] referred to in comment 8 is video in URL field.
I think this change is okay as a temporary fix, but it feels like it may be hiding a deeper bug.  A buffered range for a given decoder should report the same range that can actually be decoded, by which I mean the end time of the decoder's buffered range should be identical to the end time of the last frame decoded before reaching EOS.  Do you know why that's not the case here?
When a decode hits EOF it doesn't call the media decoder state machines On{Video,Audio}EOS method if the media stream is not endOfStream. As a result hte media decode state machines mVideoRequestPending flag is not set to false. This prevents further video/audio frames from being decoded as it things are request is still pending.
Depends on: 1064699
Depends on: 1064705
Comment on attachment 8483922 [details] [diff] [review]
Use end time of EOS'd decoded for switching readers

Clearing r? because I think bug 1064705 and bug 1064699 cover this.  We'll still need to address comment 11 somehow (either by avoiding EOS and removing the switching code from the EOS callback, or by recovering from the EOS/m{Audio,Video}RequestPending state).
Attachment #8483922 - Flags: review?(kinetik)
Blocks: ship-MSE
No longer blocks: 1000686
Blocks: 1093133
Is this still an issue?
Flags: needinfo?(cajbir.bugzilla)
I have not seen it for some time. I'll close and we can reopen if it comes up again.
Closed: 6 years ago
Flags: needinfo?(cajbir.bugzilla)
Resolution: --- → WORKSFORME
You need to log in before you can comment on or make changes to this bug.