Video decoders created while the GPU process restarts use the previous compositor's settings
Categories
(Core :: Audio/Video, defect)
Tracking
()
| Tracking | Status | |
|---|---|---|
| firefox160 | --- | fixed |
People
(Reporter: aosmond, Assigned: aosmond)
References
(Blocks 1 open bug)
Details
Attachments
(4 external files, 1 obsolete file)
When the GPU process crashes and is recreated, a video decoder created in the GPU or RDD process during the restart can be set up with the TextureFactoryIdentifier of the compositor that just went away.
The content process passes its TextureFactoryIdentifier when creating a remote video decoder. That identifier comes from the caller's KnowsCompositor:
- for media elements, a
KnowsCompositorMediaProxysnapshot taken byMediaDecoder::GetCompositor(), and only refreshed when the owner's activity changes; - for WebCodecs, the
ImageBridgeChildsingleton.
Both can be from the old compositor:
- A creation that starts before
ContentChild::RecvReinitRenderingkeeps the snapshot it captured. This applies to creations waiting for the GPU process to come back, falling back from one decoder module to another, waiting inAllocationPolicy, or being recreated byMediaChangeMonitor. ImageBridgeChild::ReinitForContentreplaces the image bridge, so a reference held from before the restart points at the dead one.
The decoder process uses the identifier to decide the compositor backend, whether D3D11 textures can be shared, whether hardware WebRender is in use, and which sync handle to use. With the old identifier, a decoder can:
- make hardware or software decisions that don't match the new compositor, e.g. if the restart came with a fallback from acceleration;
- in the GPU process, open a
SyncObjectClientfor a compositor that no longer exists.
Before GPU decoder creation waited for the GPU process to be recreated, such creations failed and fell back to the RDD process. That fallback received the same old identifier.
There is a related race in the RDD and utility (for MF CDM) processes. After the GPU process restarts, the parent sends them a new video bridge (RDDChild::OnCompositorUnexpectedShutdown -> CreateRddVideoBridge), but nothing orders this against decoder creation requests from content. A decoder created in that window can't reach the new compositor until the video bridge is recreated.
Steps to reproduce (timing-dependent):
- On Windows, with decoding in the GPU process enabled, open a page that plays video.
- Crash the GPU process (e.g. load
about:crashgpu). - While the GPU process is restarting, start new video playback, or trigger decoder recreation (e.g. seek, or a resolution change).
Expected: decoders created during or after the restart are set up for the new compositor.
Actual: they may be set up with the old compositor's TextureFactoryIdentifier.
Proposed fix: have the decoder process ask the compositor for the identifier used by the content process, over its existing PVideoBridge connection, keyed by ContentParentId. Decoders in the GPU, RDD and utility processes then all use the same path. Decoder creation would also wait for a new video bridge when the old one has gone away. The content process would then only need to say whether the decoded frames should be shared with the compositor, so media elements would no longer need to carry a compositor snapshot.
| Assignee | ||
Comment 1•1 month ago
|
||
If a remote video decoder is created after the compositor was lost, but before
its process was given a new video bridge, it cannot share the decoded frames
with the new compositor until the video bridge is recreated. Creation now waits
for the new video bridge.
| Assignee | ||
Comment 2•1 month ago
|
||
Video decoders are given the TextureFactoryIdentifier by the content process,
which may be from a compositor that no longer exists, e.g. if the decoder was
created while the GPU process was being recreated. PVideoBridge now allows the
decoder process to ask the compositor for the identifier used by a content
process instead.
| Assignee | ||
Comment 3•1 month ago
|
||
The identifier given by the content process may be from a compositor which no
longer exists, e.g. if the decoder was created while the GPU process was being
recreated. Remote video decoders now ask the compositor for the identifier used
by the content process over their video bridge, so the content process only
needs to say whether the decoded frames should be shared with the compositor.
If the compositor cannot provide an identifier, decoders in the GPU process fail
so that another process may be used, and decoders elsewhere copy the decoded
frames to the content process instead. The KnowsCompositor for the decoder is
now created when the decoder is constructed, rather than when the actor is
created.
| Assignee | ||
Comment 4•1 month ago
|
||
MediaDecoder gave the reader a KnowsCompositorMediaProxy for the document's
compositor, which kept the TextureFactoryIdentifier and image bridge from when
it was created, and was only updated when the owner's activity changed. The
reader no longer gives a compositor, and PDMFactory instead uses the current
image bridge in the content and parent processes whenever it creates a decoder
that was not given one, as WebCodecs and WebRTC already do, since it is replaced
and given the new identifier when the compositor is reinitialized. This avoids
using a replaced image bridge when the decoder creation parameters are kept
across asynchronous steps, e.g. by MediaChangeMonitor or AllocationPolicy.
This also affects MediaCapabilities, which does not give a compositor when its
document has none, e.g. in workers or tabs that have not been painted yet. Its
decoder probes now use the image bridge, once the content process has a
compositor, and so may now use the GPU process, as media element playback would.
| Assignee | ||
Comment 5•1 month ago
|
||
The identifier given by the content process may be from a compositor which no
longer exists, e.g. if the decoder was created while the GPU process was being
recreated. Remote video decoders now ask the compositor for the identifier used
by the content process over their video bridge, so the content process no
longer gives one.
If the compositor cannot provide an identifier, decoders in the RDD and utility
processes copy the decoded frames back to the content process, as they already
did when the content process did not give an identifier. Decoders in the GPU
process fail instead so that another process may be used, as the content
process previously did not create them there without a compositor. The
KnowsCompositor for the decoder is now created when the decoder is constructed,
rather than when the actor is created.
Updated•1 month ago
|
| Assignee | ||
Updated•28 days ago
|
Comment 7•24 days ago
|
||
| bugherder | ||
https://hg.mozilla.org/mozilla-central/rev/d8070538e5b4
https://hg.mozilla.org/mozilla-central/rev/2db49e516efc
https://hg.mozilla.org/mozilla-central/rev/d71e0e964874
https://hg.mozilla.org/mozilla-central/rev/6fa3eb08b69f
Updated•16 days ago
|
Description
•