Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Linux v4l2 Camera troubles in X11 w/ SDL_PIXELFORMAT_YUY2 #9263

Open
Simulacrum0 opened this issue Mar 13, 2024 · 8 comments
Open

Linux v4l2 Camera troubles in X11 w/ SDL_PIXELFORMAT_YUY2 #9263

Simulacrum0 opened this issue Mar 13, 2024 · 8 comments
Assignees
Milestone

Comments

@Simulacrum0
Copy link

SDL3 has an excellent Camera API, but for the sample and our own implementation of using it, it can see any of our 4 test cameras on Ubuntu 23.10 using X11 (Nvidia GPU driver) via the "v4l2" driver. Have tried 1 camera at a time or many. All report name strings, all formats, and 'CAMERA_APPROVAL' and CAMERA_ADDED events as expected.

If i SDL_OpenCameraDevice w/ SDL_PIXELFORMAT_YUY2, which is the ONLY format provided by all cameras (Logitech, CreativeLabs, Generic ), then "AcquireFrame" only returns a 'WHITE' surface and it hangs in WaitForThread inside of SDL_Camera Thread inside a call to v4l2, which gdb does not name.

If i open the device w/ SDL_PIXELFORMAT_RGBA8888, it consistently acquires frame and closes without hanging.

Have tried builds with SDL_TIMER_INIT on/off, with OpenCameraDevice after CAMERA_ADDED event or at SDL startup, and have polled at 1fps, 5fps, 30fps and unlimited loop of polling.

Am posting this in case helpful.
#love_SDL3!

@Simulacrum0 Simulacrum0 changed the title Linux X11 Camera Hangs on Close Linux v4l2 Camera troubles in X11 w/ SDL_PIXELFORMAT_YUY2 Mar 13, 2024
@Simulacrum0
Copy link
Author

Also found that SDL_CameraSpec seems to match the interval numerator/denominator (refresh-rate) 'near' the requested values but it does not report the actual value chosen ( it returns whatever you put into OpenCameraDevice as a request...from denominators of 2 to 144, its just copied over? ). Posting if helpful?

@icculus icculus self-assigned this Mar 14, 2024
@icculus icculus added this to the 3.2.0 milestone Mar 14, 2024
@icculus
Copy link
Collaborator

icculus commented Mar 14, 2024

It shouldn't just be copied over, it should be finding the closest values the camera reported as supported. So it's probably an SDL bug. I'll dig in.

@Simulacrum0
Copy link
Author

Thanks Icculus!
I can test or help if useful.

#SDL3_Rocks!

@Kaktus514
Copy link

Kaktus514 commented Apr 9, 2024

If i SDL_OpenCameraDevice w/ SDL_PIXELFORMAT_YUY2, which is the ONLY format provided by all cameras (Logitech, CreativeLabs, Generic ), then "AcquireFrame" only returns a 'WHITE' surface

When passing NULL to SDL_OpenCameraDevice I also experience a similar issue but only if I use SDL_BlitSurface to draw to the "window surface". If I instead convert the surface to a texture and use the render api then it displays correctly so I wonder if this is not just an effect of SDL_BlitSurface not supporting the YUY2 format?

@slouken
Copy link
Collaborator

slouken commented Apr 15, 2024

I believe that's correct. Are you checking SDL_BlitSurface() for errors?

@Green-Sky
Copy link
Contributor

Green-Sky commented Apr 26, 2024

it hangs in WaitForThread inside of SDL_Camera Thread inside a call to v4l2, which gdb does not name.

I ran into the same issue when I was reading the frames slower than they where provided (according to camera spec). It went away when acquiring and releasing frames until there are non left directly before closing the camera, so I suspect it locks up waiting for all existing frames to be read.

@Green-Sky
Copy link
Contributor

Green-Sky commented Apr 26, 2024

I suspect the YUY2 frame is not fully created, because I sometimes (every ~100th) hit a heap-buffer-overlow when blitting from the aquired frame:

### found cameras:
  - Camera #0: Chicony USB2.0 Camera: Chicony
    - 1280x720@10 SDL_PIXELFORMAT_YUY2
    - 640x480@30 SDL_PIXELFORMAT_YUY2
    - 640x360@30 SDL_PIXELFORMAT_YUY2
    - 352x288@30 SDL_PIXELFORMAT_YUY2
    - 320x240@30 SDL_PIXELFORMAT_YUY2
    - 176x144@30 SDL_PIXELFORMAT_YUY2
    - 160x120@30 SDL_PIXELFORMAT_YUY2
camera interval: 100ms
camera format: SDL_PIXELFORMAT_YUY2
video frame was 1280x720 1367496316ns
video frame was 1280x720 1467500316ns
video frame was 1280x720 1567504316ns
video frame was 1280x720 1667506316ns
video frame was 1280x720 1763510316ns
video frame was 1280x720 1863513316ns
video frame was 1280x720 1963517316ns
=================================================================
==1484947==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x7fcf019d1000 at pc 0x000001d9d8c9 bp 0x7fcf003bdbc0 sp 0x7fcf003bdbb8
READ of size 4 at 0x7fcf019d1000 thread T2
    #0 0x1d9d8c8 in ReadFloatPixel /home/green/workspace/tox/tomato/build/_deps/sdl3-src/src/video/SDL_blit_slow.c:383
    #1 0x1db350f in SDL_Blit_Slow_Float /home/green/workspace/tox/tomato/build/_deps/sdl3-src/src/video/SDL_blit_slow.c:841
    #2 0x1ae06f0 in SDL_SoftBlit /home/green/workspace/tox/tomato/build/_deps/sdl3-src/src/video/SDL_blit.c:86
    #3 0x17f1503 in SDL_BlitSurface_REAL /home/green/workspace/tox/tomato/build/_deps/sdl3-src/src/video/SDL_surface.c:845
    #4 0xfe2bdc in operator() /home/green/workspace/tox/tomato/src/content/sdl_video_frame_stream2.cpp:81


0x7fcf019d1000 is located 6144 bytes to the left of 1228872-byte region [0x7fcf019d2800,0x7fcf01afe848)
allocated by thread T0 here:
    #0 0x7fcf04cbc3ff in __interceptor_malloc (/nix/store/a3zlvnswi1p8cg7i9w4lpnvaankc7dxx-gcc-12.3.0-lib/lib/libasan.so.8+0xbc3ff)
    #1 0x17aa1c2 in SDL_malloc_REAL /home/green/workspace/tox/tomato/build/_deps/sdl3-src/src/stdlib/SDL_malloc.c:5287

Thread T2 created by T0 here:
    #0 0x7fcf04c4d136 in __interceptor_pthread_create (/nix/store/a3zlvnswi1p8cg7i9w4lpnvaankc7dxx-gcc-12.3.0-lib/lib/libasan.so.8+0x4d136)
    #1 0x7fcf044e0698 in std::thread::_M_start_thread(std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State> >, void (*)()) (/nix/store/a3zlvnswi1p8cg7i9w4lpnvaankc7dxx-gcc-12.3.0-lib/lib/libstdc++.so.6+0xe0698)

SUMMARY: AddressSanitizer: heap-buffer-overflow /home/green/workspace/tox/tomato/build/_deps/sdl3-src/src/video/SDL_blit_slow.c:383 in ReadFloatPixel

I also know from OBS, that the camera has some funky jpeg stream that supports higher fps at 720p.

(whole application compiled with asan and sdl staticly linked, log shortened)

@Green-Sky
Copy link
Contributor

I turned on DEBUG_CAMERA:

startup
INFO: CAMERA: V4L2 camera path='/dev/video0' bus_info='usb-0000:09:00.3-4' name='Chicony USB2.0 Camera: Chicony '
INFO: CAMERA:   - Has format 'SDL_PIXELFORMAT_UNKNOWN' [COMPRESSED]
INFO: CAMERA:   - Has format 'SDL_PIXELFORMAT_YUY2'
INFO: CAMERA:     * Has discrete size 1280x720
INFO: CAMERA:       * Has discrete frame interval (1 / 10), fps=10.000000
INFO: CAMERA:       * Has discrete frame interval (1 / 10), fps=10.000000
INFO: CAMERA:     * Has discrete size 640x480
INFO: CAMERA:       * Has discrete frame interval (1 / 30), fps=30.000000
INFO: CAMERA:     * Has discrete size 640x360
INFO: CAMERA:       * Has discrete frame interval (1 / 30), fps=30.000000
INFO: CAMERA:     * Has discrete size 352x288
INFO: CAMERA:       * Has discrete frame interval (1 / 30), fps=30.000000
INFO: CAMERA:     * Has discrete size 320x240
INFO: CAMERA:       * Has discrete frame interval (1 / 30), fps=30.000000
INFO: CAMERA:     * Has discrete size 176x144
INFO: CAMERA:       * Has discrete frame interval (1 / 30), fps=30.000000
INFO: CAMERA:     * Has discrete size 160x120
INFO: CAMERA:       * Has discrete frame interval (1 / 30), fps=30.000000
INFO: CAMERA:     * Has discrete size 1280x720
INFO: CAMERA:       * Has discrete frame interval (1 / 10), fps=10.000000
INFO: CAMERA:       * Has discrete frame interval (1 / 10), fps=10.000000
INFO: CAMERA: (total specs: 10)
INFO: CAMERA: Adding device 'Chicony USB2.0 Camera: Chicony ' (unknown position) with 7 specs:
INFO: CAMERA:   - fmt=SDL_PIXELFORMAT_YUY2, w=1280, h=720, numerator=1, denominator=10
INFO: CAMERA:   - fmt=SDL_PIXELFORMAT_YUY2, w=640, h=480, numerator=1, denominator=30
INFO: CAMERA:   - fmt=SDL_PIXELFORMAT_YUY2, w=640, h=360, numerator=1, denominator=30
INFO: CAMERA:   - fmt=SDL_PIXELFORMAT_YUY2, w=352, h=288, numerator=1, denominator=30
INFO: CAMERA:   - fmt=SDL_PIXELFORMAT_YUY2, w=320, h=240, numerator=1, denominator=30
INFO: CAMERA:   - fmt=SDL_PIXELFORMAT_YUY2, w=176, h=144, numerator=1, denominator=30
INFO: CAMERA:   - fmt=SDL_PIXELFORMAT_YUY2, w=160, h=120, numerator=1, denominator=30
INFO: CAMERA: App wanted [(-1x-1) fmt=(null) interval=-1/-1], chose [(1280x720) fmt=SDL_PIXELFORMAT_YUY2 interval=1/10]
INFO: CAMERA: set SDL format SDL_PIXELFORMAT_YUY2
INFO: CAMERA: set format V4L2_format=1448695129  YUYV
a frame
INFO: CAMERA: debug mmap: image 3/8  data[0]=0x7f56f01a2000
INFO: CAMERA: New frame available! pixels=0x7f56f01a2000 pitch=2560
INFO: CAMERA: Frame is going through without conversion!
video frame was 1280x720 4260183097ns

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants