ammen99 / wf-recorder

MIT License
872 stars 63 forks source link

v4l2 regression #164

Closed git-bruh closed 2 years ago

git-bruh commented 2 years ago

Hi, commit 5384bc9f3691833b5bf63e97afb953eadfbbec90 seems to have broken recording with v4l2:

λ yes | wf-recorder --muxer=v4l2 --codec=rawvideo --pixel-format=yuv420p --file=/dev/video0
Output file "/dev/video0" exists. Overwrite? Y/n: selected region 0,0 0x0
Using video filter: null
Output #0, video4linux2,v4l2, to '/dev/video0':
  Stream #0:0: Video: rawvideo (RGB[0] / 0x424752), rgb0(pc), 1920x1080 [SAR 1:1 DAR 16:9], q=2-31, 49766400000 kb/s
[video4linux2,v4l2 @ 0x7fba24000d00] Unknown V4L2 pixel format equivalent for rgb0
Failed to write file header
Invalid argument

Previously:

Output file "/dev/video0" exists. Overwrite? Y/n: selected region 0,0 0x0
Choosing pixel format yuv420p
Output #0, video4linux2,v4l2, to '/dev/video0':
  Stream #0:0: Unknown: none (rawvideo)
[video4linux2,v4l2 @ 0x7f0110000d00] Using AVStream.codec to pass codec parameters to muxers is deprecated, use AVStream.codecpar instead.

Running https://github.com/umlaeute/v4l2loopback/commit/567aa9552c70ea2014dd867ace1bca93c71357f8 with modprobe v4l2loopback exclusive_caps=1

ammen99 commented 2 years ago

Just tried and it works on my machine. Can you try running with -l to get more debug messages? Also, a quick google search shows this: https://github.com/umlaeute/v4l2loopback/issues/247

It could be outdated v4l2 module, or using the wrong device (for some reason my old setup required me to use /dev/video2, but now I have to use /dev/video0), or something else which I cannot guess at the moment.

git-bruh commented 2 years ago

Output with broken wf-recorder:

Output file "/dev/video0" exists. Overwrite? Y/n: selected region 0,0 0x0
detected 12 logical cores
[Source @ 0x7fe3b4004700] Setting 'video_size' to value '1920x1080'
[Source @ 0x7fe3b4004700] Setting 'pix_fmt' to value '121'
[Source @ 0x7fe3b4004700] Setting 'time_base' to value '1/1000000'
[Source @ 0x7fe3b4004700] Setting 'pixel_aspect' to value '1/1'
[Source @ 0x7fe3b4004700] w:1920 h:1080 pixfmt:rgb0 tb:1/1000000 fr:0/1 sar:1/1
Using video filter: null
[AVFilterGraph @ 0x7fe3b4002d00] query_formats: 3 queried, 2 merged, 0 already done, 0 delayed
################################################################################
+----------+
|  Source  |default--[1920x1080 1:1 rgb0]--Parsed_null_0:default
| (buffer) |
+----------+

                                                    +--------------+
Parsed_null_0:default--[1920x1080 1:1 rgb0]--default|     Sink     |
                                                    | (buffersink) |
                                                    +--------------+

                                             +---------------+
Source:default--[1920x1080 1:1 rgb0]--default| Parsed_null_0 |default--[1920x1080 1:1 rgb0]--Sink:default
                                             |    (null)     |
                                             +---------------+

################################################################################
Output #0, video4linux2,v4l2, to '/dev/video0':
  Stream #0:0, 0, 0/0: Video: rawvideo, 1 reference frame (RGB[0] / 0x424752), rgb0(pc), 1920x1080 (0x0) [SAR 1:1 DAR 16:9], 0/1, q=2-31, 49766400000 kb/s
[file @ 0x7fe3b40060c0] Setting default whitelist 'file,crypto,data'
[video4linux2,v4l2 @ 0x7fe3b4000d00] Unknown V4L2 pixel format equivalent for rgb0
Failed to write file header
Invalid argument

Output with working wf-recorder:

Output file "/dev/video0" exists. Overwrite? Y/n: selected region 0,0 0x0
Choosing pixel format yuv420p
Output #0, video4linux2,v4l2, to '/dev/video0':
  Stream #0:0, 0, 0/0: Unknown: none (rawvideo)
[file @ 0x7f3324021f00] Setting default whitelist 'file,crypto,data'
[video4linux2,v4l2 @ 0x7f3324000d00] Using AVStream.codec to pass codec parameters to muxers is deprecated, use AVStream.codecpar instead.

I only have a single /dev/video0 device, not others like video1, and v4l2 is latest.

soreau commented 2 years ago

I can reproduce this with amdgpu/mesa. @ammen99 I'm guessing you're testing on intel? Perhaps it's not a problem on intel because the driver does implicit rgb0->yuv420 conversion unlike its gallium counterparts.

soreau commented 2 years ago

With this patch you can add the -t option to do the conversion on the cpu.

soreau commented 2 years ago

And it also works with vaapi without the patch..

wf-recorder -f /dev/video2 --muxer=v4l2 -d /dev/dri/renderD128 --codec=h264_vaapi --pixel-format=yuv420p
ammen99 commented 2 years ago

@soreau Yeah I'm testing on intel, I don't have any other hw.. Is your patch basically hardcoding a special case? Why is it not enough to check the supported formats?

soreau commented 2 years ago

@ammen99 In this case the supported formats pointer is null and just a null check alone doesn't seem like a good plan so yes, I made a special case so -t doesn't segfault.

ammen99 commented 2 years ago

I just pushed @soreau's fix to master, @git-bruh can you try with latest master again and see whether there is still an error (with the -t flag)

git-bruh commented 2 years ago

Thanks @soreau and @ammen99, works fine now!

punk-dev-robot commented 2 years ago

Thank you for this fix, I was experiencing the same issue. I'm using wf-recorder so i can share my screen in zoom (sharing second camera) It looks like running it with -t flag works again but is not using hw acceleration.

Running it with vaapi uses hw acceleration, and I can also play it with mpv, but zoom sees it as black screen :(