Closed Bug 1703522 Opened 5 years ago Closed 4 years ago

Video from Screen Capture API has low frame rate

Categories

(Core :: WebRTC: Audio/Video, defect, P2)

Firefox 87
Desktop
macOS
defect

Tracking

()

RESOLVED FIXED
106 Branch
Tracking Status
relnote-firefox --- 106+
firefox106 --- fixed

People

(Reporter: koen.francois, Assigned: jib)

References

(Depends on 1 open bug)

Details

Attachments

(2 files)

Attached video Recording Firefox.mov —

User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 11_2_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36

Steps to reproduce:

System information:
Macbook Pro 2018 2.6GHz, 16gb, Radeon Pro 560X
OSX 11.2.3
No external devices/displays connected.

Actual results:

Frames seem to be dropped. Not all mouse movements are captured, resulting in a choppy video.

Expected results:

Video should be smooth. You can compare the resulting videos between Chrome & Firefox.

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

Component: Untriaged → WebRTC: Audio/Video
Product: Firefox → Core
Component: WebRTC: Audio/Video → Audio/Video: Recording
Component: Audio/Video: Recording → WebRTC: Audio/Video

Hi Francois, thanks for reporting! What dimensions and frame rate do you see if you run https://jsfiddle.net/jib1/5e1cbpyt/show ?

I get 3072 x 1920 x ~8 in Firefox. In Chrome I get 1536 x 960 x ~18, which may partly explain the frame rate difference (Firefox returns full Retina res).

This does not appear to be a regression.

Flags: needinfo?(koen.francois)
See Also: → 1604671
Depends on: 1703991

Hi Jan-Ivar,

On Firefox I get 3840 x 2400 x ~4 compared to 1920 x 1200 x ~24 on Chrome.
When recording a smaller window of 1600 x 1000 in Firefox I get improved frame rates of ~12-14 which seems low still.

I understand that this may not be a performance regression, perhaps this can move to an enhancement (or an OSX or hardware-related defect) if you agree?
If not, 1703991 should already be a big improvement. 🙌

Thank you for creating that ticket & for your efforts in reproducing this!

Flags: needinfo?(koen.francois)

This is a performance issue we've always had. I'm trying to find time to have a look and overhaul our usage of surfaces. For now we're doing to many copies and it causes this issue.

Severity: -- → S1
Priority: -- → P2
Assignee: nobody → jib
See Also: → 1703991

Sorry I meant to assign myself to bug 1703991 instead, thinking that was the cause of this bug, which on closer examination appears unlikely.

I can still try to take a look. Paul, do you have more info on where in the code you think the problem you allude to in comment 4 lies?

Flags: needinfo?(padenot)

I only see smoke, not the cause of the fire. On Linux: sudo perf top --sort comm,dso shows that the capture thread takes a lot of CPU, and also Xorg, when capturing. On macOS with Instruments, something similar is shown, full of libyuv scaling/memcpy/allocator. In general the allocator and memcpy use lots of CPU, and it should not be the case, we should retain the frames, maybe scaling them in the process. The frame rate is always single digit, even on computers that are impossibly fast (28 threads core i9 linux box, 12 threads core i9 macbook pro).

The Firefox profiler cannot be used to measure this, because the threads aren't registered. We should do it, but that's a separate concern, and it might well be that the CPU being used is in other processes, because we're not using system-level APIs correctly.

Flags: needinfo?(padenot) → needinfo?(jib)

It's smoother when the machine is intentionally almost idle, but there is some latency though.

Severity: S1 → S2
Flags: needinfo?(jib)
OS: Unspecified → macOS
Hardware: Unspecified → Desktop

I had a look at this in Instruments with "Record Waiting Threads" and "Record Kernel Callstacks" turned on. In this profile I see 63% of the CaptureFrame time being spent waiting in CGDisplayCreateImage/SLDisplayCreateImage. Much of the rest of the time is spent in memcpy. Some of it likely doing zero-fault-on-demand.

While looking more closely I realized that we don't have the IOSurface capture path enabled. Chrome enabled since 2018: https://source.chromium.org/chromium/chromium/src/+/09cd5826e743af9dbcbde8ab36f73f5e0bd55f6c

Turning that on cuts the time spent CaptureFrame from ~80ms to ~22ms.

The code in DesktopCaptureImpl::ProcessIter() is also a bit weird. _maxFPSNeeded is actually 1000 / _requestedCapability.maxFPS so a better name would might be minimumCaptureIntervalMs. We currently wait for max(minimumCaptureIntervalMs, sleepTime) which prevents us from being able to hit the maxFPS if capturing takes a non-zero amount of time.

This should instead probably be max(minimumCaptureIntervalMs - processTime, sleepTime)

This cuts the time spent in CaptureFrame for me from ~80ms to ~22ms.
It was enable by default in Chromium in 2018 via
https://source.chromium.org/chromium/chromium/src/+/09cd5826e743af9dbcbde8ab36f73f5e0bd55f6c

When using the IOSurfaces, half of the capture time is now in ConvertToI420 mostly servicing page faults presumably from zero-fill-on-demand because we allocate a fresh buffer every frame: https://searchfox.org/mozilla-central/rev/9769b513e38ee4f5df9d5d1eff55ff7cdc8cbf81/dom/media/systemservices/video_engine/desktop_capture_impl.cc#479

With the remaining time mostly in copies and buffer allocation/deallocation

Pushed by jmuizelaar@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/4efaf464a679 Allow IOSurface capture by default. r=pehrsons
Status: UNCONFIRMED → RESOLVED
Closed: 4 years ago
Resolution: --- → FIXED
Target Milestone: --- → 106 Branch

Release Note Request (optional, but appreciated)
[Why is this notable]: Screencapture in WebRTC on macOS can now capture at higher frame rates
[Affects Firefox for Android]: Nope
[Suggested wording]: Lower CPU usage and increased frame rates during WebRTC screen capture on macOS

relnote-firefox: --- → ?
QA Whiteboard: [qa-106b-p2]

Should that note be merged with the existing note about general improvements in WebRTC following the libwebrtc upgrade or should it be separate?
https://www.mozilla.org/en-US/firefox/106.0beta/releasenotes/

Currently we have:

Major improvements of our WebRTC capabilities (libwebrtc library upgraded from version 86 to 103) with multiple improvements:

  • Many RTP performance and reliability improvements.
  • Windows and Wayland screen sharing improvements.
  • Richer statistics.
Flags: needinfo?(jmuizelaar)

I think it's fine to fold it in

Flags: needinfo?(jmuizelaar)

Note folded into the existing webrtc note on Beta.

You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: