pcercuei / kmsgrab

Simple screenshot tool for DRM/KMS drivers.
8 stars 8 forks source link

Output image is very distorted #2

Open scaledteam opened 2 years ago

scaledteam commented 2 years ago

Debian Testing Mesa Intel(R) UHD Graphics (TGL GT1) Gnome X11

Expected: expected

Result: result

KMSGrab in ffmpeg works fine, but not in this tool. It looks like picture was cut to small pieces and rearranged. It will be cool if you will help me to solve this issue.

pcercuei commented 2 years ago

If you have a full blown X11/wayland environment, why use this tool? Gnome's screenshot feature will work much better.

scaledteam commented 2 years ago

Because i want to reuse this code for one very specific purpose. Your code looks so nice and simple, just what i wanted to. Probably i can fix it by myself, but i will try to do it later, when i have time for that.

2play commented 7 months ago

Im posting here since my issue was closed. maybe @scaledteam will come up to an idea of why this happening now In my case i dont use X and have a script that calls kmsgrab and drops a timestamped screenshot to a folder . It was very helpful to make screenshots of a running emu for example from CLi and not X

qte hello @pcercuei Paul i have compiled/installed your great tool on a new Armbian 24.2.4 Jammy installation. So far i tested on similar but arm based installations. This time is on x86 Intel J4125 CPU with above OS Initially I got error "Unable to mmap prime buffer" I made sure all dependencies are installed ( libpng-dev libdrm-dev ) and retried

Today I get below results: printscreen03_26_2024--h09-m13-s22 printscreen03_26_2024--h09-m45-s53

I can attach the binary also. I have been using your tool with success last couple years but cant on this setup Please let me know what to test or update uqte

2play commented 7 months ago

@scaledteam do you think it might be related to the MESA INTEL driver? We seem both to have an Intel GPU

2play commented 7 months ago

drm_buddy              20480  1 i915
drm_display_helper    208896  1 i915
cec                    69632  2 drm_display_helper,i915
drm_kms_helper        241664  2 drm_display_helper,i915
drm                   708608  8 i2c_hid,drm_kms_helper,drm_display_helper,drm_buddy,i915,ttm```
scaledteam commented 7 months ago

@2play , i just tried it in Gnome Wayland, and i only get Failed to get framebuffer 348: Invalid argument error. I think error, present in our screenshots related to PNG saving part, not to extracting image. When image not properly extracted from framebuffer, it looks way more distorted, or it just fails.

I had huge success of implementing KMSGrab in OBS Studio, this is my little addition to VKCapture plugin that adds kmsgrab feature to OBS. (I never made pull request it because it's kinda hacky, don't want to spent time refining it). I had issues in wayland, because Gnome on Wayland switched to multiplane framebuffer, so it needs additional code.

I will post code of my plugin, it's very short, maybe you or original author can combine it with your screenshoting utility. I will look at code of this utility again, with new knowledge, but i'm not promise anything. https://github.com/scaledteam/obs-vkcapture/blob/kmsgrab/src/vkcapture-kmsgrab.c

2play commented 7 months ago

much appreciated. tried older png lib 1.2.54 but no luck. im using gcc 11. both original 1.6.37 and above kmsgrab created same result. How about to use libjpeg-dev? cmake to use this instead of libpng-dev?


cd kmsgrab
cmake .
make
Cloning into 'kmsgrab'...
remote: Enumerating objects: 22, done.
remote: Counting objects: 100% (22/22), done.
remote: Compressing objects: 100% (17/17), done.
remote: Total 22 (delta 6), reused 19 (delta 5), pack-reused 0
Receiving objects: 100% (22/22), 7.46 KiB | 7.46 MiB/s, done.
Resolving deltas: 100% (6/6), done.
-- The C compiler identification is GNU 11.4.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Found ZLIB: /usr/lib/x86_64-linux-gnu/libz.so (found version "1.2.11")
-- Found PNG: /usr/local/lib/libpng.so (found version "1.2.54")
-- Found PkgConfig: /usr/bin/pkg-config (found version "0.29.2")
-- Checking for module 'libdrm'
--   Found libdrm, version 2.4.118
-- Configuring done (0.4s)
-- Generating done (0.0s)
-- Build files have been written to: /home/pi/code/kmsgrab
[ 50%] Building C object CMakeFiles/kmsgrab.dir/kmsgrab.c.o
[100%] Linking C executable kmsgrab
[100%] Built target kmsgrab```
scaledteam commented 7 months ago

@2play , I can't find a way to mmap multiplane buffers yet, but i made a little changes to code, so maybe it will work in your environment. It's partially working for me now. https://github.com/scaledteam/kmsgrab-screenshoter

scaledteam commented 7 months ago

I don't think i can add multi-plane framebuffer support in this code easily. Current code works for linear framebuffers, (X11, virtual console), but don't work for multi-plane framebuffers, used in Wayland. To make situation worse, framebuffer can be encoded in many different ways. To make it work, it might be easier to grab frames, using Headless EGL, then dump them using OpenGL functions, which basically means making creating a new screenshoting program.

2play commented 7 months ago

@2play , I can't find a way to mmap multiplane buffers yet, but i made a little changes to code, so maybe it will work in your environment. It's partially working for me now. https://github.com/scaledteam/kmsgrab-screenshoter @scaledteam first of all thank you for looking into it i have compiled and tested the fork. i used a clean Raspberry Desktop x86

cmake .
-- The C compiler identification is GNU 10.2.1
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Found ZLIB: /usr/lib/i386-linux-gnu/libz.so (found version "1.2.11")
-- Found PNG: /usr/lib/i386-linux-gnu/libpng.so (found version "1.6.37")
-- Found PkgConfig: /usr/bin/pkg-config (found version "0.29.2")
-- Checking for module 'libdrm'
--   Found libdrm, version 2.4.104
-- Configuring done
-- Generating done
-- Build files have been written to: /home/pi/code/kmsgrab-screenshoter
pi@playbox:~/code/kmsgrab-screenshoter $ make
Scanning dependencies of target kmsgrab
[ 50%] Building C object CMakeFiles/kmsgrab.dir/kmsgrab.c.o
[100%] Linking C executable kmsgrab
[100%] Built target kmsgrab

image is messed as before unfortunately. So prob seems to be on x86 setups. ARM I used kmsgrab on Tinker, RockPro64 respectively 32bit and 64bit Armbian RaspberryPi OS Desktop on my mini PC is

Distributor ID: Debian Description: Debian GNU/Linux 11 (bullseye) Release: 11 Codename: bullseye Linux playbox 5.10.0-15-amd64 #1 SMP Debian 5.10.120-1 (2022-06-09) x86_64 GNU/Linux

As Im not a pro dev like you guys, I found below if gives any ideas

https://stackoverflow.com/questions/53237065/using-libpng-1-2-to-write-rgb-image-buffer-to-png-buffer-in-memory-causing-segme https://gist.github.com/dobrokot/10486786

2play commented 7 months ago

@scaledteam on RockPro64 kmsgrab is looking for these /usr/lib/ld-linux-aarch64.so.1 and (symlinks but i provide actual names) image

scaledteam commented 7 months ago

@2play Why not just use FFMpeg, if you need KMSGrab screenshot? For GUI, there is a lot of scriptable screenshoters, for example, gnome-screenshot. Despite it's graphics nature, it's 100% scriptable, you can do any type of screenshots from console.

sudo ffmpeg -device /dev/dri/card0 -re -f kmsgrab -i - -vf 'hwmap=derive_device=vaapi,hwdownload,format=bgr0' -vframes 1 output.png
2play commented 7 months ago

@scaledteam I was thinking to go that way too. I think i tried in the past and i think I preferred the kmsgrab simplicity BUT above is working fine to get the png. Ive tested on the aforementioned RPI OS Desktop I will update my script to use this in meantime. Maybe below will help to adjust the @pcercuei Paul's script or your fork

image

2play commented 7 months ago

so far i was using kmsgrab to get the file with timestamp and in the same script to use convert to change to jpg

2play commented 7 months ago

@scaledteam and here is with jpg output (also ok) image

2play commented 7 months ago

I can use this as its also clean

 sudo ffmpeg -device /dev/dri/card0 -re -f kmsgrab -i - -vf 'hwmap=derive_device=vaapi,hwdownload,format=bgr0' -vframes 1 output.png && convert output.png output.jpg && sudo rm *.png

@scaledteam thank you for the workaround!

scaledteam commented 7 months ago

@2play why convert in jpeg, ffmpeg can render directly in jpeg and any image format.

sudo ffmpeg -device /dev/dri/card0 -re -f kmsgrab -i - -vf 'hwmap=derive_device=vaapi,hwdownload,format=bgr0' -v:frames 1 output.jpg
2play commented 7 months ago

@scaledteam yes yes I did above. I tried to hide the warning which isn't a problem

scaledteam commented 7 months ago

Warning caused by -vframes 1, when you change it to -v:frames 1 it works silently.

2play commented 7 months ago

so clean now! tx vm @scaledteam

2play commented 7 months ago

@scaledteam sorry to bother I tested on clean and get below Armbian 24.2.4 jammy Kernel: Linux 6.6.21-current-x86 and get below

 sudo ffmpeg -device /dev/dri/card0 -re -f kmsgrab -i - -vf 'hwmap=derive_device=vaapi,hwdownload,format=bgr0' -vframes 1 ~/ScreenShots/printscreen$now.jpg
ffmpeg version 4.4.2-0ubuntu0.22.04.1 Copyright (c) 2000-2021 the FFmpeg developers
  built with gcc 11 (Ubuntu 11.2.0-19ubuntu1)
  configuration: --prefix=/usr --extra-version=0ubuntu0.22.04.1 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --enable-gpl --disable-stripping --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libdav1d --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librabbitmq --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libsrt --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzimg --enable-libzmq --enable-libzvbi --enable-lv2 --enable-omx --enable-openal --enable-opencl --enable-opengl --enable-sdl2 --enable-pocketsphinx --enable-librsvg --enable-libmfx --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-libx264 --enable-shared
  libavutil      56. 70.100 / 56. 70.100
  libavcodec     58.134.100 / 58.134.100
  libavformat    58. 76.100 / 58. 76.100
  libavdevice    58. 13.100 / 58. 13.100
  libavfilter     7.110.100 /  7.110.100
  libswscale      5.  9.100 /  5.  9.100
  libswresample   3.  9.100 /  3.  9.100
  libpostproc    55.  9.100 / 55.  9.100
[kmsgrab @ 0x557c5080f780] Using plane 32 to locate framebuffers.
[kmsgrab @ 0x557c5080f780] Template framebuffer is 164: 1920x1080 format 34325258 modifier 100000000000001 flags 2.
Input #0, kmsgrab, from 'pipe:':
  Duration: N/A, start: 1711634713.563778, bitrate: N/A
  Stream #0:0: Video: wrapped_avframe, drm_prime, 1920x1080, 29.83 tbr, 1000k tbn, 1000k tbc
Stream mapping:
  Stream #0:0 -> #0:0 (wrapped_avframe (native) -> mjpeg (native))
[AVHWDeviceContext @ 0x557c5082bcc0] Failed to initialise VAAPI connection: -1 (unknown libva error).
[Parsed_hwmap_0 @ 0x557c5082a000] Failed to created derived device context: -5.
[Parsed_hwmap_0 @ 0x557c5082a000] Failed to configure output pad on Parsed_hwmap_0
Error reinitializing filters!
Failed to inject frame into filter network: Input/output error
Error while processing the decoded data for stream #0:0
Conversion failed!

libva-dev is installed any ideas?

2play commented 7 months ago

some progress installed sudo apt install intel-media-va-driver and vaapi error gone but image exported like this printscreen printscreen

scaledteam commented 7 months ago

@2play

sorry to bother

We already way off-topic. If you want to speak with me personally, check links at my profile.

2play commented 7 months ago

My apologies to all. Will keep related to the issue...