Not enough buffers provided by V4L2VideoDevice

I get this error when changing the resolution to maximum 9152x6944 with this example GitHub - edward-ardu/libcamera-cpp-demo: libcamera c++ demo. Works fine with smaller resolutions. Also the libcamera-still utility also works fine capturing picture with max resolution.

[email protected]:~/libcamera-cpp-demo/build $ ./libcamera-demo 
[0:09:29.626550460] [3199]  INFO Camera camera_manager.cpp:299 libcamera v0.0.0+4226-8689dd6b-dirty (2023-05-14T15:40:26+03:00)
[0:09:29.667717204] [3200]  WARN CameraSensorProperties camera_sensor_properties.cpp:243 No static properties available for 'arducam_64mp'
[0:09:29.668152881] [3200]  WARN CameraSensorProperties camera_sensor_properties.cpp:245 Please consider updating the camera sensor properties database
[0:09:29.902760322] [3200]  WARN RPI raspberrypi.cpp:1366 Mismatch between Unicam and CamHelper for embedded data usage!
[0:09:29.907371567] [3200]  INFO RPI raspberrypi.cpp:1485 Registered camera /base/soc/i2c0mux/[email protected]/[email protected] to Unicam device /dev/media0 and ISP device /dev/media3
[0:09:29.912976144] [3200]  WARN CameraSensorProperties camera_sensor_properties.cpp:243 No static properties available for 'arducam_64mp'
[0:09:29.913310304] [3200]  WARN CameraSensorProperties camera_sensor_properties.cpp:245 Please consider updating the camera sensor properties database
[0:09:30.039218952] [3200]  WARN RPI raspberrypi.cpp:1366 Mismatch between Unicam and CamHelper for embedded data usage!
[0:09:30.042396317] [3200]  INFO RPI raspberrypi.cpp:1485 Registered camera /base/soc/i2c0mux/[email protected]/[email protected] to Unicam device /dev/media1 and ISP device /dev/media4
Configuring still capture...
Stream configuration adjusted
Still capture setup complete
here1here2[0:09:30.046303019] [3199]  INFO Camera camera.cpp:1028 configuring streams: (0) 9152x6944-RGB888
[0:09:30.047686530] [3200]  INFO RPI raspberrypi.cpp:851 Sensor: /base/soc/i2c0mux/[email protected]/[email protected] - Selected sensor format: 9152x6944-SRGGB10_1X10 - Selected unicam format: 9152x6944-pRAA
[0:09:30.222518512] [3200] ERROR V4L2 v4l2_videodevice.cpp:1248 /dev/video14[15:cap]: Not enough buffers provided by V4L2VideoDevice
Can't allocate buffers
at /proc/meminfo | grep -i cma
CmaTotal:         524288 kB
CmaFree:          477168 kB

Hardware:
Pi4 CM4, 8GB, 2GB RAM
one quad arducam 64mp hat connected and one single arducam 64mp
Linux pi 6.1.21-v8+ #1642 SMP PREEMPT Mon Apr 3 17:24:16 BST 2023 aarch64 GNU/Linux

Also when i make 2 camera instances in my custom qt project that i built on this eduards libcamera-cpp-demo example and set the resolution to 4624x3472 and try to capture images from both cameras at the same time then i slightly diferent error:

"capture picture /base/soc/i2c0mux/[email protected]/[email protected]"
TRACE 2023-05-21T18:27:37.287 Capturing picture from the camera. 
TRACE 2023-05-21T18:27:37.288 Temporary file for captured arducam image: "/home/pi/DigiCandy/[email protected][email protected]" 
Stream configuration adjusted
Still capture setup complete
[0:21:13.851824512] [4502]  INFO Camera camera.cpp:1028 configuring streams: (0) 4624x3472-RGB888
[0:21:13.853292029] [4514]  INFO RPI raspberrypi.cpp:851 Sensor: /base/soc/i2c0mux/[email protected]/[email protected] - Selected sensor format: 4624x3472-SRGGB10_1X10 - Selected unicam format: 4624x3472-pRAA
frame read success
here2
"capture picture /base/soc/i2c0mux/[email protected]/[email protected]"
TRACE 2023-05-21T18:27:39.355 Capturing picture from the camera. 
TRACE 2023-05-21T18:27:39.355 Acquiring lock for taking a picture. 
copyPicture filename= "[email protected][email protected]" target= "/home/pi/DigiCandy/[email protected][email protected]" target= "[email protected][email protected]"
TRACE 2023-05-21T18:27:39.356 Temporary file for captured arducam image: "/home/pi/DigiCandy/[email protected][email protected]" 
[0:21:15.918567404] [4502]  INFO Camera camera.cpp:1028 configuring streams: (0) 4624x3472-RGB888
[0:21:15.919464040] [4514]  INFO RPI raspberrypi.cpp:851 Sensor: /base/soc/i2c0mux/[email protected]/arducam_64mp[email protected] - Selected sensor format: 4624x3472-SRGGB10_1X10 - Selected unicam format: 4624x3472-pRAA
Configuring still capture...
Stream configuration adjusted
Still capture setup complete
[0:21:15.988949137] [4514] ERROR V4L2 v4l2_videodevice.cpp:1248 /dev/video21[44:cap]: Not enough buffers provided by V4L2VideoDevice
Can't allocate buffers

First camera can take the picture but the second camera gives the same error. If i decrease resolution further then both can take picture.

Just reminding this that with these commands capturing pictures works at max res
libcamera-still --camera 0 --width 9152 --height 6944 -o L.jpg -n
libcamera-still --camera 1 --width 9152 --height 6944 -o R.jpg -n

How can i fix this for the GitHub - edward-ardu/libcamera-cpp-demo: libcamera c++ demo example project so it would also work with max res?

Ok i decrased the buffer count to 1 at

cam.configureStill(width, height, formats::RGB888, 1, 0);

was 4 before. now the first camera can capture at max res but the second one still gives similar error. when attempting to capture with both cameras at the same time

"capture picture /base/soc/i2c0mux/[email protected]/[email protected]"
TRACE 2023-05-21T18:39:14.289 Capturing picture from the camera. 
TRACE 2023-05-21T18:39:14.290 Temporary file for captured arducam image: "/home/pi/DigiCandy/[email protected][email protected]" 
Stream configuration adjusted
Still capture setup complete
[0:32:50.857012633] [5353]  INFO Camera camera.cpp:1028 configuring streams: (0) 9152x6944-RGB888
[0:32:50.859709532] [5365]  INFO RPI raspberrypi.cpp:851 Sensor: /base/soc/i2c0mux/[email protected]/[email protected] - Selected sensor format: 9152x6944-SRGGB10_1X10 - Selected unicam format: 9152x6944-pRAA
frame read success
here2
"capture picture /base/soc/i2c0mux/[email protected]/[email protected]"
TRACE 2023-05-21T18:39:20.764 Acquiring lock for taking a picture. 
TRACE 2023-05-21T18:39:20.764 Capturing picture from the camera. 
copyPicture filename= "[email protected][email protected]" target= "/home/pi/DigiCandy/[email protected][email protected]" target= "[email protected][email protected]"
TRACE 2023-05-21T18:39:20.764 Temporary file for captured arducam image: "/home/pi/DigiCandy/[email protected][email protected]" 
[0:32:57.327364878] [5353]  INFO Camera camera.cpp:1028 configuring streams: (0) 9152x6944-RGB888
[0:32:57.328435589] [5365]  INFO RPI raspberrypi.cpp:851 Sensor: /base/soc/i2c0mux/[email protected]/[email protected] - Selected sensor format: 9152x6944-SRGGB10_1X10 - Selected unicam format: 9152x6944-pRAA
Configuring still capture...
Stream configuration adjusted
Still capture setup complete
[0:32:57.331721150] [5365] ERROR V4L2 v4l2_videodevice.cpp:1241 /dev/video21[44:cap]: Unable to request 1 buffers: Cannot allocate memory
Can't allocate buffers

@henri

The operation you performed is correct.

Based on our testing, we’ve found that saving a picture from one camera is consuming a significant amount of buffer resources. As a result, attempting to store pictures from two cameras simultaneously is causing a bottleneck in the system and resulting in insufficient buffer resources.

Currently saving two cameras at the same time is difficult, even if you use libcamera-still , you can use multithreading to save verification at the same time.

" you can use multithreading to save verification at the same time." - What does this mean?

@henri

You can run the libcamera-still command with python using two threads to use two cameras at the same time to verify whether it is possible to save two cameras at the same time. I just want you to verify that it is not theoretically possible.

yes, i think u are right. the code i had wasnt really capturing images from 2 cameras at the same time but rather in series. when i tried to run them in separate threads. the first time I ran it actually captured from 2 cameras at the same time but didnt to so later so it was either a fluke or i dont know what happened. anyways i havent been able to repeat it.

Anyhow can you help me fixing the stride issue in my code that i mentioned in another forum thread? We have already bought 6 arducam 64mp cameras. We are developing a low-cost semi-automatic bookscanning machine. If we succeed with the development then it will go into production and we will be buying a lot more arducam cameras.

@henri

I have reviewed your code, but it’s difficult to diagnose what’s going on. Currently, my energy is limited as I have to maintain the existing warehouse and there is also a lot of development work to be done. I’m afraid I may not have enough time to assist you in finding out the reason.

ok, no worries. ill see if i can simplify the question and perhaps fork your sample code and recreate my problem there so it will be something u can simply compile and run.

i had to add if(!cam.camera_started_) cam.startCamera();
cause i called startCamera before making each picture
i found it out by experimenting with your libcamera-cpp-example. I think stopcamera is bugged.

        cam.startCamera();
        cam.VideoStream(&width, &height, &stride);
        while (true) {
            flag = cam.readFrame(&frameData);
            if (!flag)
                continue;
            Mat im(height, width, CV_8UC3, frameData.imageData, stride);

            imshow("libcamera-demo", im);
            key = waitKey(1);
            if (key == 'q') {
                break;
            } else if (key == 'f') {
                ControlList controls;
                controls.set(controls::AfMode, controls::AfModeAuto);
                controls.set(controls::AfTrigger, 0);
                cam.set(controls);
            } else if (key == 'a' || key == 'A') {
                lens_position += focus_step;
            } else if (key == 'd' || key == 'D') {
                lens_position -= focus_step;
            }

            // To use the manual focus function, libcamera-dev needs to be updated to version 0.0.10 and above.
            if (key == 'a' || key == 'A' || key == 'd' || key == 'D') {
                ControlList controls;
                controls.set(controls::AfMode, controls::AfModeManual);
				controls.set(controls::LensPosition, lens_position);
                cam.set(controls);
            }

            frame_count++;
            if ((time(0) - start_time) >= 1){
                printf("fps: %d\n", frame_count);
                frame_count = 0;
                start_time = time(0);
            }
            cam.returnFrameBuffer(frameData);
            break;
        }
        destroyAllWindows();
        
/*      //uncomment this and it doesent work
        cam.stopCamera();
        cam.startCamera();
        */
        
        /*      //uncomment this and it doesent work either
        cam.startCamera();
        */

        while (true) {
            flag = cam.readFrame(&frameData);
            if (!flag)
                continue;
            Mat im(height, width, CV_8UC3, frameData.imageData, stride);

            imshow("libcamera-demo", im);
            key = waitKey(1);
            if (key == 'q') {
                break;
            } else if (key == 'f') {
                ControlList controls;
                controls.set(controls::AfMode, controls::AfModeAuto);
                controls.set(controls::AfTrigger, 0);
                cam.set(controls);
            } else if (key == 'a' || key == 'A') {
                lens_position += focus_step;
            } else if (key == 'd' || key == 'D') {
                lens_position -= focus_step;
            }

            // To use the manual focus function, libcamera-dev needs to be updated to version 0.0.10 and above.
            if (key == 'a' || key == 'A' || key == 'd' || key == 'D') {
                ControlList controls;
                controls.set(controls::AfMode, controls::AfModeManual);
				controls.set(controls::LensPosition, lens_position);
                cam.set(controls);
            }

            frame_count++;
            if ((time(0) - start_time) >= 1){
                printf("fps: %d\n", frame_count);
                frame_count = 0;
                start_time = time(0);
            }
            cam.returnFrameBuffer(frameData);
            break;
        }
        destroyAllWindows();
        cam.stopCamera();

anyways i managed to fix the issue where i couldnt capture any pictures after first picture. but now the issue i face is that all following pictures are exact copy of the first one. so i added a counter that would only capture picture after reading certain amount of frames - this seems to be path to a solution

I forked your code and recreated there the error i get when attempting to capture images in series (not parallel) from 2 different arducam_64mp cameras at max resolution. I kept the imshow cause it doesent make a difference to write it in file with imwrite to demonstrate the error.
U can grab the code from

https://github.com/henrihallik/libcamera-cpp-demo-dual-cam/blob/main/main.cpp

How to fix this? Capturing images in series at max res using libcamera-still command line works fine but not in you cpp-demo.
Now i tested again with your code i modified, im not getting the error anymore… very strange. But I still get the error in my QT application. could it be related to that my QT application is a lot larger and using a lot more memory on its own.

ok, i think its my QT code thats buggy not your code. i think im not doing everything in series instead im doing somethings still in paralell thats why i get this error. will figure this out tomorrow.

1 Like

also we have figured out a solution how to capture 2 images at the same time at max res - we can just use 2 separate RPIs for each camera. one will run our QT app and the second one modified version of your libcamera-cpp-demo to capture second picture.