russelltg / wl-screenrec

High performance wlroots screen recording, featuring hardware encoding
Apache License 2.0
321 stars 9 forks source link

screen record lag #50

Open killown opened 10 months ago

killown commented 10 months ago

➜ ~ wl-screenrec -o DP-1 Using output DP-1 Opening libva device from DRM device /dev/dri/renderD128 [h264_vaapi @ 0x55ebd4ab7300] No usable encoding entrypoint found for profile VAProfileH264High (7). failed to open encoder in low_power mode (Function not implemented), trying non low_power mode. if you have an intel iGPU, set enable_guc=2 in the i915 module to use the fixed function encoder. pass --low-power=off to suppress this warning [h264_vaapi @ 0x55ebd4ab7300] Driver does not support some wanted packed headers (wanted 0xd, found 0x1).

https://github.com/russelltg/wl-screenrec/assets/24453/8862ee20-93fd-4cba-b86a-1817f821835a

killown commented 10 months ago

screenshot ➜ ~ vainfo Trying display: wayland vainfo: VA-API version: 1.20 (libva 2.20.1) vainfo: Driver version: Mesa Gallium driver 23.3.2-arch1.2 for AMD Radeon RX 6600 (radeonsi, navi23, LLVM 16.0.6, DRM 3.54, 6.6.9-arch1-1) vainfo: Supported profile and entrypoints VAProfileMPEG2Simple : VAEntrypointVLD VAProfileMPEG2Main : VAEntrypointVLD VAProfileVC1Simple : VAEntrypointVLD VAProfileVC1Main : VAEntrypointVLD VAProfileVC1Advanced : VAEntrypointVLD VAProfileH264ConstrainedBaseline: VAEntrypointVLD VAProfileH264ConstrainedBaseline: VAEntrypointEncSlice VAProfileH264Main : VAEntrypointVLD VAProfileH264Main : VAEntrypointEncSlice VAProfileH264High : VAEntrypointVLD VAProfileH264High : VAEntrypointEncSlice VAProfileHEVCMain : VAEntrypointVLD VAProfileHEVCMain : VAEntrypointEncSlice VAProfileHEVCMain10 : VAEntrypointVLD VAProfileHEVCMain10 : VAEntrypointEncSlice VAProfileJPEGBaseline : VAEntrypointVLD VAProfileVP9Profile0 : VAEntrypointVLD VAProfileVP9Profile2 : VAEntrypointVLD VAProfileAV1Profile0 : VAEntrypointVLD VAProfileNone : VAEntrypointVideoProc

russelltg commented 10 months ago

Interesting, is the weird jumpiness visible on screen while recording, or is it just visiable in the recorded file during playback?

Does wf-recorder -c h264_vaapi -d /dev/dri/renderD128 have the same issue?

killown commented 10 months ago

Interesting, is the weird jumpiness visible on screen while recording, or is it just visiable in the recorded file during playback?

Does wf-recorder -c h264_vaapi -d /dev/dri/renderD128 have the same issue?

only in the record, obs for example works fine with ffmpeg h264 vaapi

russelltg commented 10 months ago

What compositor is this?

killown commented 10 months ago

What compositor is this?

hyprland

ghost commented 9 months ago

@killown Same on Hyprland, NixOS... All was fine, but after update - it's happened.

dominikh commented 9 months ago

I can reproduce the issue on NixOS with Sway, with wl-screenrec 0.1.0. The problem reproduces when using --output or when using -g and specifying an entire output worth. It doesn't happen with -g and geometry that's a single pixel smaller than the entire output.

$ wl-screenrec -g '4000,415 2560x1440' -v
Using output DP-2
Opening libva device from DRM device /dev/dri/renderD128
+----------+
|    in    |default--[3840x2160 0:1 vaapi]--Parsed_crop_0:default
| (buffer) |
+----------+

                                                            +--------------+
Parsed_scale_vaapi_1:default--[3840x2160 0:1 vaapi]--default|     out      |
                                                            | (buffersink) |
                                                            +--------------+

                                          +---------------+
in:default--[3840x2160 0:1 vaapi]--default| Parsed_crop_0 |default--[3840x2160 0:1 vaapi]--Parsed_scale_vaapi_1:default
                                          |    (crop)     |
                                          +---------------+

                                                     +----------------------+
Parsed_crop_0:default--[3840x2160 0:1 vaapi]--default| Parsed_scale_vaapi_1 |default--[3840x2160 0:1 vaapi]--out:default
                                                     |    (scale_vaapi)     |
                                                     +----------------------+

[h264_vaapi @ 0x561718339400] No usable encoding entrypoint found for profile VAProfileH264High (7).
failed to open encoder in low_power mode (Function not implemented), trying non low_power mode. if you have an intel iGPU, set enable_guc=2 in the i915 module to use the fixed function encoder. pass --low-power=off to suppress this warning
[h264_vaapi @ 0x561718339400] Driver does not support some wanted packed headers (wanted 0xd, found 0x1).
Output #0, mp4, to 'screenrecord.mp4':
  Metadata:
    encoder         : Lavf59.27.100
  Stream #0:0: Video: h264 (High) (avc1 / 0x31637661), vaapi, 3840x2160, q=2-31, 40000 kb/s, 90k tbn
50 fps
51 fps
51 fps
51 fps
^C%
$ wl-screenrec -g '4000,415 2560x1439' -v
Using output DP-2
Opening libva device from DRM device /dev/dri/renderD128
+----------+
|    in    |default--[3840x2160 0:1 vaapi]--Parsed_crop_0:default
| (buffer) |
+----------+

                                                            +--------------+
Parsed_scale_vaapi_1:default--[3840x2159 0:1 vaapi]--default|     out      |
                                                            | (buffersink) |
                                                            +--------------+

                                          +---------------+
in:default--[3840x2160 0:1 vaapi]--default| Parsed_crop_0 |default--[3840x2160 0:1 vaapi]--Parsed_scale_vaapi_1:default
                                          |    (crop)     |
                                          +---------------+

                                                     +----------------------+
Parsed_crop_0:default--[3840x2160 0:1 vaapi]--default| Parsed_scale_vaapi_1 |default--[3840x2159 0:1 vaapi]--out:default
                                                     |    (scale_vaapi)     |
                                                     +----------------------+

[h264_vaapi @ 0x555c92e23fc0] No usable encoding entrypoint found for profile VAProfileH264High (7).
failed to open encoder in low_power mode (Function not implemented), trying non low_power mode. if you have an intel iGPU, set enable_guc=2 in the i915 module to use the fixed function encoder. pass --low-power=off to suppress this warning
[h264_vaapi @ 0x555c92e23fc0] Driver does not support some wanted packed headers (wanted 0xd, found 0x1).
Output #0, mp4, to 'screenrecord.mp4':
  Metadata:
    encoder         : Lavf59.27.100
  Stream #0:0: Video: h264 (High) (avc1 / 0x31637661), vaapi, 3840x2159, q=2-31, 40000 kb/s, 90k tbn
42 fps
60 fps
59 fps
60 fps
59 fps
52 fps
60 fps
^C%

https://github.com/russelltg/wl-screenrec/assets/39825/9b532449-709a-4e31-af33-2100bbcf882b

https://github.com/russelltg/wl-screenrec/assets/39825/a407db89-31cd-4b1a-9a8e-d59556fb35c1

An observation that may or may not be relevant: when capturing the 2560x1440 region (which has an unscaled resolution of 3840x2160), the frame rate is a stable 51 fps. When capturing the 2560x1439 region, the frame rate is 60 fps most of the time, but repeatedly dips down to ~50 fps.

russelltg commented 9 months ago

Super interesting to me! We always capture full outputs (dmabuf does not support partial captures), so the issue is with something after that...weird! @varmisa do you know what update broke it? Possible culprits are mesa and ffmpeg.

Could hyprland be giving frames out of order? Also never got an answer to if

wf-recorder -c h264_vaapi -d /dev/dri/renderD128

has the same issue.

ghost commented 9 months ago

@russelltg I don't remember what the update it was, today i will test this command with wf-recorder.

dominikh commented 9 months ago

For me, wf-recorder -c hevc_vaapi -d /dev/dri/renderD128 works fine. wf-recorder -c h264_vaapi -d /dev/dri/renderD128 just hangs indefinitely without producing any video.

In wl-screenrec, the stutter doesn't reproduce for me when using --codec hevc, it only reproduces with auto and avc (I'm not able to test vp8 or vp9, however.)

dominikh commented 9 months ago

Interestingly, the wf-recorder hang can also be fixed by specifying a geometry that's slightly smaller than the actual screen. However, in that case, wf-recorder reproduces the issue that wl-screenrec has when recording the entire screen...

Furthermore, after updating wl-screenrec from a36c5923009b44f2131196d8a3a234948f8e0102 to v0.1.3, the h264 recording is always stuttery, even when specifying different geometries.

dominikh commented 9 months ago

I've bisected the wl-screenrec change in behavior to

commit e0945ebed09be1a819217f7316ddae30fb82989e (HEAD)
Author: Russell Greene <russellgreene8@gmail.com>
Date:   Sat Nov 18 21:16:09 2023 -0700

    fix off-by-one errors in region

    workaround for upstream ffmpeg bug

Before that commit, recording at a geometry smaller than the screen, there is no stutter/time travel. Since that commit, recording at any geometry stutters.

Further testing reveals that it's not any smaller geometry that works, but only those that result in an odd-sized width or height (after considering scaling).

dominikh commented 9 months ago

Disabling b-frames via

diff --git i/src/main.rs w/src/main.rs
index 5ea7e59..a281b19 100644
--- i/src/main.rs
+++ w/src/main.rs
@@ -1181,6 +1181,7 @@ fn make_video_params(
     enc.set_height(encode_h as u32);
     enc.set_time_base(Rational(1, 1_000_000_000));
     enc.set_frame_rate(Some(framerate));
+    enc.set_max_b_frames(0);
     if let Some(gop) = args.gop_size {
         enc.set_gop(gop);
     }

works around the issue. Of course that's not a satisfying solution, but it points towards the nature of the problem.

russelltg commented 9 months ago

@dominikh what hardware do you have?

Definitely a strange issue to be sure, also considering the nature it's surprising I don't see it as well.

I'm trying to find the link between b-frames and exact=1....super strange. exact=1 has to do with handling of odd-positioned or odd-sized crop capture regions. the b-frames lead is quite interesting though, and make me think I'm mishandling PTS/DTS....

dominikh commented 9 months ago

vainfo: Driver version: Mesa Gallium driver 23.3.3 for AMD Radeon RX 6700 XT (radeonsi, navi22, LLVM 16.0.6, DRM 3.54, 6.6.16)

ghost commented 9 months ago

vainfo: Driver version: Mesa Gallium driver 23.3.3 for AMD Radeon RX 6700 XT (radeonsi, navi22, LLVM 16.0.6, DRM 3.54, 6.6.16)

Very interesting, i have same GPU...

kohsine commented 7 months ago

Just wanted to add also experiencing this issue. Issue so far has only affected 6000 series cards? I wonder if any other cards are affected by this bug.

vainfo: Driver version: Mesa Gallium driver 24.0.5-arch1.1 for AMD Radeon RX 6800 XT (radeonsi, navi21, LLVM 17.0.6, DRM 3.57, 6.8.7-zen1-1-zen)

AmazinAxel commented 4 months ago

Just wanted to drop this here too -- this bug is also experienced on integrated Radeon graphics (also using NixOS + Hyprland, occurred after an update) vainfo: Driver version: Mesa Gallium driver 24.0.7 for AMD Radeon Graphics (radeonsi, rembrandt, LLVM 17.0.6, DRM 3.57, 6.9.3) It should also be noted that wf-recorder -c hevc_vaapi -d /dev/dri/renderD128 works completely fine