Closed Bug 1958036 Opened 1 year ago Closed 1 year ago

Regression in 1850615 breaks V4L2 h264 decoding

Categories

(Core :: Audio/Video, defect)

Firefox 137
defect

Tracking

()

RESOLVED FIXED
139 Branch
Tracking Status
firefox-esr128 --- fixed
firefox137 --- wontfix
firefox138 --- fixed
firefox139 --- fixed

People

(Reporter: david.turner, Assigned: karlt)

References

(Regression)

Details

(Keywords: regression)

Attachments

(6 external files)

Steps to reproduce:

I've found that h264 hw hardware decode (using v4l2 stateful via ffmpeg) is broken on Raspberry Pi 4 with the firefox 137 release. I've bisected the breakage down to https://phabricator.services.mozilla.com/D239857 / bug 1850615.

I haven't had a chance to debug further yet what exactly is going wrong, but please could I be given permission to see bug 1850615 so I can find out the logic behind that patch?

Testing on Raspberry Pi OS bookworm, 64-bit, Raspberry Pi 4 (aarch64)

Actual results:

VP9 video plays correctly. If I try to play an h264 video it just shows black and never starts playing. After attempting to play h264 video, I can't even play vp9 videos any more until I restart the browser.

Expected results:

h264 video playback should work, and should not break playback of all other videos.

The Bugbug bot thinks this bug should belong to the 'Core::Audio/Video' component, and is moving the bug to that component. Please correct in case you think the bot is wrong.

Component: Untriaged → Audio/Video
Product: Firefox → Core
Keywords: regression
Regressed by: 1850615

:karlt, since you are the author of the regressor, bug 1850615, could you take a look? Also, could you set the severity field?

For more information, please visit BugBot documentation.

Flags: needinfo?(karlt)

With MOZ_LOG=FFmpegVideo:4, in the working case I see:

[RDD 46514: MediaSupervisor #1]: D/FFmpegVideo FFMPEG: FFmpegVideoDecoder::FFmpegVideoDecoder MIME video/avc Codec ID 27
[RDD 46514: MediaSupervisor #1]: D/FFmpegVideo FFMPEG: Initialising VA-API FFmpeg decoder
[RDD 46514: MediaSupervisor #1]: D/FFmpegVideo FFMPEG:   codec h264 : H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10
libva info: VA-API version 1.17.0
libva info: Trying to open /usr/lib/aarch64-linux-gnu/dri/v3d_drv_video.so
libva info: va_openDriver() returns -1
[RDD 46514: MediaSupervisor #1]: D/FFmpegVideo FFMPEG:   vaInitialize failed.
[RDD 46514: MediaSupervisor #1]: D/FFmpegVideo FFMPEG:   Failed to create VA-API device context
[RDD 46514: MediaSupervisor #1]: D/FFmpegVideo FFMPEG: Initialising V4L2-DRM FFmpeg decoder
[RDD 46514: MediaSupervisor #1]: D/FFmpegVideo FFMPEG:   V4L2 codec h264_v4l2m2m : V4L2 mem2mem H.264 decoder wrapper
<snip>

Whereas in the non-working case, it just stops after the va_openDriver() returns -1 line, I don't see vaInitialize failed. So it seems like what is broken is specifically vaapi failing and falling back to v4l2 (and thence software). (Does this mean it's broken video on all systems without working vaapi?)

Done some more digging. There's something odd going on in VADisplayHolder::GetSingleton() - I see the call to vaInitialize fails, and we get into the if (status != VA_STATUS_SUCCESS) { branch, but it doesn't seem to ever return to CreateVAAPIDeviceContext().

If I throw in a return nullptr; in GetSingleton() before the new VADisplayHolder line then everything works fine, if I put the GetSingleton() after the new VADisplayHolder line then it fails with the original issue. So either there's something weird happening with the ~VADisplayHolder destructor or the stack is getting screwed up. I put some logs in MaybeDestroy() and ~VADisplayHolder() and we never get there.

Will investigate further next week.

Thank you for the analysis.
VADisplayHolder::MaybeDestroy() would be waiting to take the lock already held by GetSingleton().

Assignee: nobody → karlt
Status: UNCONFIRMED → ASSIGNED
Ever confirmed: true
Flags: needinfo?(karlt)

This now closes even when vaGetDisplayDRM() fails.

This avoids a deadlock attempting to acquire sDisplayHolderMutex in
MaybeDestroy() on releasing the last reference during GetSingleton() after
vaInitialize() failure.

Pushed by ktomlinson@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/c27e68d60e42 use UniqueFileHandle to close DRM file descriptor r=media-playback-reviewers,stransky
Pushed by ktomlinson@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/c50f774fe5d3 delay VADisplayHolder construction until it is known usable r=media-playback-reviewers,stransky
Status: ASSIGNED → RESOLVED
Closed: 1 year ago
Resolution: --- → FIXED
Target Milestone: --- → 139 Branch

I've confirmed that this patch fixes V4L2 playback on latest nightlies, thanks for the speedy fix!

I think this would be worth uplift to 138 beta. I don't mind for Raspberry Pi OS as I can backport the fix downstream, but I'd expect this issue to affect all other aarch64/SBC users.

Attachment #9477419 - Flags: approval-mozilla-beta?

This avoids a deadlock attempting to acquire sDisplayHolderMutex in
MaybeDestroy() on releasing the last reference during GetSingleton() after
vaInitialize() failure.

Original Revision: https://phabricator.services.mozilla.com/D244464

Attachment #9477420 - Flags: approval-mozilla-beta?

beta Uplift Approval Request

  • User impact if declined: Video playback stops for all videos in some Linux system configurations.
  • Code covered by automated testing: no
  • Fix verified in Nightly: yes
  • Needs manual QE test: no
  • Steps to reproduce for manual QE testing: n/a
  • Risk associated with taking this patch: Lower.
  • Explanation of risk level: Smaller patches affecting Linux-only video playback.
  • String changes made/needed: None.
  • Is Android affected?: no

A "workaround" for those affected could be to set "media.hardware-video-decoding.enabled" to false, but that would of course mean software decoding.

Duplicate of this bug: 1958848
Attachment #9477419 - Flags: approval-mozilla-beta? → approval-mozilla-beta+
Attachment #9477420 - Flags: approval-mozilla-beta? → approval-mozilla-beta+
Attachment #9478507 - Flags: approval-mozilla-esr128?

This avoids a deadlock attempting to acquire sDisplayHolderMutex in
MaybeDestroy() on releasing the last reference during GetSingleton() after
vaInitialize() failure.

Original Revision: https://phabricator.services.mozilla.com/D244464

Attachment #9478508 - Flags: approval-mozilla-esr128?

esr128 Uplift Approval Request

  • User impact if declined: Playback stops for all videos and audio elements in some Linux system configurations.
  • Code covered by automated testing: no
  • Fix verified in Nightly: yes
  • Needs manual QE test: no
  • Steps to reproduce for manual QE testing: n/a
  • Risk associated with taking this patch: Lower
  • Explanation of risk level: Smaller patches affecting Linux-only video playback
  • String changes made/needed: none
  • Is Android affected?: no
Attachment #9478507 - Flags: approval-mozilla-esr128? → approval-mozilla-esr128+
Attachment #9478508 - Flags: approval-mozilla-esr128? → approval-mozilla-esr128+
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: