Closed Bug 1161416 Opened 9 years ago Closed 9 years ago

If decoder initialization failed, SharedDecoderManager will deadlock

Categories

(Core :: Audio/Video, defect)

defect
Not set
normal

Tracking

()

RESOLVED FIXED
mozilla40
Tracking Status
firefox40 --- fixed

People

(Reporter: jya, Assigned: jya)

References

Details

Attachments

(1 file)

Should the decoder failed to be created, the SharedDecoderManager will never attempt to recreate the decoder.

The next call to SharedDecoderManager::SetIdle will deadlock waiting for a DrainComplete() to occur (when it can never arrive)
Two problems here: if MediaDataDecoder::Init() failed we will never attempt to recreate a decoder ever. And if an error occurred in MediaDataDecoder::Drain() SharedDecoderManager::SetIdle still wait for DrainComplete(). This situation can happen when inside a H264/AVC wrapper and platforms where Drain() can return an error.
Attachment #8601301 - Flags: review?(cpearce)
Assignee: nobody → jyavenard
Status: NEW → ASSIGNED
When could MediaDataDecoder::Init() fail?
See Also: → 1161426
One example is when the decoder is wrapped in an H264Converter. Init() will only be called once we have an SPS which for avc3 content may be delayed.

Additionally, on mac or ffmpeg: init will fail with an incorrect init segment.

Or per bug 1160321, with the user disabling windows media foundation.
I have reproduced the dead lock with youtube. They send two init segments ; the first one cause the decoder 's Init() to fail. In this case we issue error/updateend event to the source buffer. They re-send a new init segment. This time SharedDecoderManager::CreateVideoDecoder() will succeed (as it thinks it already has a decoder) and return a video decoder (though incorrect as it's never been initialized).

From that point on, all call to the video decoder returned by the SharedDecoderManager will fail. If you refresh the page right at that time, on mac (and ffmpeg) SharedDecoderManager::SetIdle() will be called which will wait forever on DrainComplete() -> deadlock.
The deadlock is due to the HTMLMediaElement calling MediaDecoder::NotifyOwnerActivityChanged() , attempt to grab the monitor, which is held by the SharedDecoderManager which is waiting for SetIdle() to complete
Blocks: 1161443
Attachment #8601301 - Flags: review?(cpearce) → review+
https://hg.mozilla.org/mozilla-central/rev/5898ca2888e5
Status: ASSIGNED → RESOLVED
Closed: 9 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla40
You need to log in before you can comment on or make changes to this bug.