Code: Select all
v4l2-ctl -v width=1024,height=768,pixelformat=I420
v4l2-ctl --set-ctrl=white_balance_auto_preset=0,red_balance=5000,blue_balance=1500
v4l2-ctl --set-ctrl=brightness=55,contrast=15,saturation=0,horizontal_flip=1,vertical_flip=1,power_line_frequency=1,sharpness=0,color_effects=0,rotate=0,color_effects_cbcr=32896
v4l2-ctl --set-ctrl=auto_exposure=1,exposure_time_absolute=300,auto_exposure_bias=12,iso_sensitivity=1
v4l2-ctl -p 10
v4l2-ctl --stream-mmap=3 --stream-skip=2 --stream-to=./test.yuv --stream-count=4
split -d -b $((3*1024*768/2)) ./test.yuv ./test-
for i in ./test-??; do mv $i $i.yuv;convert -size 1024x768 -depth 8 -quality 100 $i.yuv $i.jpg;done
Code: Select all
[ 9119.801453] CPU: 1 PID: 1573 Comm: v4l2-ctl Not tainted 4.1.7-v7+ #817
[ 9119.801466] Hardware name: BCM2709
[ 9119.801511] [<80018440>] (unwind_backtrace) from [<80013e0c>] (show_stack+0x20/0x24)
[ 9119.801542] [<80013e0c>] (show_stack) from [<80558548>] (dump_stack+0x98/0xe0)
[ 9119.801571] [<80558548>] (dump_stack) from [<80026a4c>] (warn_slowpath_common+0x8c/0xc8)
[ 9119.801600] [<80026a4c>] (warn_slowpath_common) from [<80026b44>] (warn_slowpath_null+0x2c/0x34)
[ 9119.801634] [<80026b44>] (warn_slowpath_null) from [<7f2f5274>] (__vb2_queue_cancel+0xf8/0x15c [videobuf2_core])
[ 9119.801695] [<7f2f5274>] (__vb2_queue_cancel [videobuf2_core]) from [<7f2f74dc>] (vb2_internal_streamoff+0x40/0xd8 [videobuf2_core])
[ 9119.801739] [<7f2f74dc>] (vb2_internal_streamoff [videobuf2_core]) from [<7f2f75b0>] (vb2_streamoff+0x3c/0x60 [videobuf2_core])
[ 9119.801784] [<7f2f75b0>] (vb2_streamoff [videobuf2_core]) from [<7f2f7624>] (vb2_ioctl_streamoff+0x50/0x54 [videobuf2_core])
[ 9119.801840] [<7f2f7624>] (vb2_ioctl_streamoff [videobuf2_core]) from [<7f2c1b7c>] (v4l_streamoff+0x28/0x2c [videodev])
[ 9119.801915] [<7f2c1b7c>] (v4l_streamoff [videodev]) from [<7f2c4ed4>] (__video_do_ioctl+0x270/0x30c [videodev])
[ 9119.801993] [<7f2c4ed4>] (__video_do_ioctl [videodev]) from [<7f2c4870>] (video_usercopy+0x180/0x550 [videodev])
[ 9119.802071] [<7f2c4870>] (video_usercopy [videodev]) from [<7f2c4c5c>] (video_ioctl2+0x1c/0x24 [videodev])
[ 9119.802136] [<7f2c4c5c>] (video_ioctl2 [videodev]) from [<7f2c06d8>] (v4l2_ioctl+0xb0/0xd0 [videodev])
[ 9119.802182] [<7f2c06d8>] (v4l2_ioctl [videodev]) from [<801566cc>] (do_vfs_ioctl+0x420/0x618)
[ 9119.802208] [<801566cc>] (do_vfs_ioctl) from [<80156908>] (SyS_ioctl+0x44/0x6c)
[ 9119.802234] [<80156908>] (SyS_ioctl) from [<8000f980>] (ret_fast_syscall+0x0/0x54)
[ 9119.802249] ---[ end trace d0054e83a240323d ]---
Generally bcm2835-v42l behaves incorrectly in no-preview state. It connects preview output port of camera component to NULL value. But it should redirect it to NULL_SINK component. There is no such component in current implementation in use.The preview display is optional, but can be used full screen or directed to a specific rectangular area on the display. If preview is disabled, the null_sink component is used to 'absorb' the preview frames. It is necessary for the camera to produce preview frames even if not required for display, as they are used for calculating exposure and white balance settings.
Sorry, I never replied here as the discussion was on the issue raised on github instead.Vdl wrote:Hello All,
Racer asked me for some help and we investigated this problem together. The result is issue I've raised: https://github.com/raspberrypi/linux/issues/1196
We tried to use suggested solutions:
1) call ctrl_set_awb_mode from start_streaming doesn't help at all
2) bm2835_mmal_set_all_camera_controls doesn't help also
....
From V4L2's point of view, there is no difference between capturing images and H264 frames - they're just different pixel formats to it, and it'll pass buffers of any sort around.Crymes wrote:Hi, I want to stream video from the RasPI Camera to an other computer. The project is written in C/C++.
Can anyone suggest a book or a tutorial how to use V4L2 to capture h.264 frames/video ?
All tutorials I found only describe how to capture images.
Code: Select all
v4l2-ctl --set-fmt-video=width=1920,height=1088,pixelformat=4
v4l2-ctl --stream-mmap=3 --stream-count=100 --stream-to=somefile.264
Not really.Crymes wrote:I have studied the V4L2 specification and have got a few questions left:
- Is it right that the fps of my video capture are only controlled by queuing the buffers via ioctl to the kernel ?
- For example I want to capture 10 fps. In this case more than 1 buffer wouldn't give me any advantage because as soon as I enqueue a buffer it gets filled up with an image and has to wait for dequeuing which gives me an older image as if I would enqueue --> wait a little time ( less than 1/30 second ? ) --> dequeue --> wait 1/10s --> enqueue ... . Am I right ?
They get allocated and then sit there unused and unloved, until they get released.Crymes wrote:Thank you for your reply.
The program runs fine if I set up the mmap mode with only one buffer. However, the v4l2-requestbuffers structure contains the value 3 for 'count' after the ioctl 'VIDIOC_REQBUFS' function.
What happens with the other two buffers which I do not enqueue ?
Safe in this case, but suboptimal.Crymes wrote:Is it safe to run v4l2 this way ?
The driver gets to specify a minimum number of buffers that it views as required. This driver sets that to 3 (https://github.com/raspberrypi/linux/bl ... era.c#L261): one buffer being filled by the camera, one being displayed, and one in flight.Crymes wrote:What would you recommend on how many buffers do I need ? ( I think two would be perfect but I also saw 4 in an example or should I take the three which the driver allocates automatically ?)
I mainly want to stream video in 720p with 20-30 fps if that matters.
no need for 'nc' there. Mplayer can read the stream directly. As a welcome side effect this avoids fiddling with mplayer -cache size argument.racer993 wrote: View with mplayer on a linux pc
nc 192.168.1.144 8554 | mplayer -fps 30 -cache 1024 -
Code: Select all
raspivid -v -n -fps 30 -ih -t 0 -o - | nc -k -l -p 8554
Code: Select all
mplayer -fps 30 -demuxer h264es ffmpeg://tcp://192.168.1.144:8554
I had tried it using QV4L2 a month or so back - https://github.com/raspberrypi/linux/issues/1196Luckk93 wrote:Hello, I'm having the same problem as racer993, I can't remove auto white balance, and if I pick the frames from the v4l2 buffer when overlay is active the frames are completely black.
Exist any way to remove (also completely) the auto white balance setting, so I can at least do a manual white balance on my program?
yes, sorry you are right, was that the problem,6by9 wrote:I had tried it using QV4L2 a month or so back - https://github.com/raspberrypi/linux/issues/1196Luckk93 wrote:Hello, I'm having the same problem as racer993, I can't remove auto white balance, and if I pick the frames from the v4l2 buffer when overlay is active the frames are completely black.
Exist any way to remove (also completely) the auto white balance setting, so I can at least do a manual white balance on my program?
Found an issue and fixed it. Assuming R4C3R on Github is the same person as racer993 here, then he confirmed it worked.
If you're still seeing issues then please ensure your firmware is more recent than December 2015 ("vcgencmd version").
Code: Select all
#include <iostream>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/mman.h> //mmap
#include <fcntl.h>
#include <unistd.h>
#include <linux/videodev2.h>
using namespace std;
#define numbuffers 3
struct picturebuffer
{
void *startadress;
size_t length;
};
//array in which the buffer pointer are beeing stored
picturebuffer pb[numbuffers];
int main()
{
//open camera
int fd;
fd = open("/dev/video0", O_RDWR);
if(fd < 0)
{
cout << "error during opening the camera device!";
cout.flush();
}
cout << "camera opened";
//read capabilities
struct v4l2_capability caps;
if(ioctl(fd, VIDIOC_QUERYCAP, &caps) < 0)
{
cout << "error while reading the capabilities!";
cout.flush();
}
cout << "Capabilities " << caps.capabilities << endl;
//ToDo: check for required capabilities
//set image data
struct v4l2_format format;
format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
format.fmt.pix.pixelformat = V4L2_PIX_FMT_H264;
format.fmt.pix.width = 1920;
format.fmt.pix.height = 1080;
if(ioctl(fd, VIDIOC_S_FMT, &format) < 0)
{
cout << "error in the image format";
}
cout << "Bilddaten eingestellt" << endl;
//Todo: check if width and height fit together (VIDIOC_ENUM_FRAMESIZES)
//set extended Controls
struct v4l2_ext_controls ecs1;
struct v4l2_ext_control ec1;
memset(&ecs1, 0, sizeof(ecs1));
memset(&ec1, 0, sizeof(ec1));
ec1.id = V4L2_CID_MPEG_VIDEO_BITRATE_MODE;
ec1.value = V4L2_MPEG_VIDEO_BITRATE_MODE_CBR;
ec1.size = 0;
ecs1.controls = &ec1;
ecs1.count = 1;
ecs1.ctrl_class = V4L2_CTRL_CLASS_MPEG;
if(ioctl(fd, VIDIOC_S_EXT_CTRLS, &ecs1) < 0)
{
cout << "error in extended controls bitrate mode";
cout.flush();
}
struct v4l2_ext_controls ecs;
struct v4l2_ext_control ec;
memset(&ecs, 0, sizeof(ecs));
memset(&ec, 0, sizeof(ec));
ec.id = V4L2_CID_MPEG_VIDEO_BITRATE_PEAK;
ec.value = 50000;
ec.size = 0;
ecs.controls = &ec;
ecs.count = 1;
ecs.ctrl_class = V4L2_CTRL_CLASS_MPEG;
if(ioctl(fd, VIDIOC_S_EXT_CTRLS, &ecs) < 0)
{
cout << "error in extended controls bitrate";
cout.flush();
}
//allocate buffer in the kernel
struct v4l2_requestbuffers req;
req.count = numbuffers;
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
req.memory = V4L2_MEMORY_MMAP;
if(ioctl(fd, VIDIOC_REQBUFS, &req) < 0)
{
cout << "errro while allocating buffer";
cout.flush();
}
cout << "number of buffers: " << req.count << endl;
cout.flush();
//map buffers into userspace
for(int i=0; i<numbuffers; i++)
{
struct v4l2_buffer bufferinfo;
memset(&bufferinfo, 0, sizeof(bufferinfo));
bufferinfo.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
bufferinfo.memory = V4L2_MEMORY_MMAP;
bufferinfo.index = i;
if(ioctl(fd, VIDIOC_QUERYBUF, &bufferinfo) < 0)
{
cout << "error while quering bufferinfo";
cout.flush();
}
pb[i].startadress = mmap(NULL, bufferinfo.length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, bufferinfo.m.offset);
pb[i].length = bufferinfo.length;
if(pb[i].startadress == MAP_FAILED)
{
cout << "error during mmap" << endl;
}
memset(pb[i].startadress, 0, bufferinfo.length);
cout << "size of buffer: " << bufferinfo.length << endl;
}
cout << "buffers mapped into userspace" << endl;
cout.flush();
//queue in the buffers
for(int i=0; i<numbuffers; i++)
{
struct v4l2_buffer bufferinfo;
memset(&bufferinfo, 0, sizeof(bufferinfo));
bufferinfo.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
bufferinfo.memory = V4L2_MEMORY_MMAP;
bufferinfo.index = i;
if(ioctl(fd, VIDIOC_QBUF, &bufferinfo) < 0)
{
cout << "error while queueing the buffers in" << endl;
}
}
//since that point the driver starts capturing the pics
int type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if(ioctl(fd, VIDIOC_STREAMON, &type) < 0)
{
cout << "error while starting the stream" << endl;
}
int file;
if((file = open("/home/pi/image.h264", O_WRONLY | O_CREAT, 0660)) < 0)
{
cout << "error while writing the file";
}
//loop for managing the pics
for(int i=0; i<100; i++)
{
struct v4l2_buffer bufferinfo;
memset(&bufferinfo, 0, sizeof(bufferinfo));
bufferinfo.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
bufferinfo.memory = V4L2_MEMORY_MMAP;
if(ioctl(fd, VIDIOC_DQBUF, &bufferinfo) < 0)
{
cout << "error while getting the buffer!" << endl;
}
//do anything with the pic
char buf[pb[bufferinfo.index].length];
memcpy(&buf, pb[bufferinfo.index].startadress, pb[bufferinfo.index].length);
cout << bufferinfo.index << endl;
cout.flush();
//write picture into the file
write(file, pb[bufferinfo.index].startadress, pb[bufferinfo.index].length);
if(ioctl(fd, VIDIOC_QBUF, &bufferinfo) < 0)
{
cout << "error while enqueuing the buffer" << endl;
}
}
close(file);
if(ioctl(fd, VIDIOC_STREAMOFF, &type) < 0)
{
cout << "error while stopping the stream" << endl;
}
//clean up
for(int i=0; i<numbuffers; i++)
{
if(munmap(pb[i].startadress, pb[i].length) < 0)
{
cout << "error during unmap";
}
}
//close camera file
close(fd);
cout << "!!!Hello World!!!" << endl;
cout.flush();
return 0;
}
That are the parameters which I can change, right?Codec Controls
video_bitrate_mode (menu) : min=0 max=1 default=0 value=0 flags=update
video_bitrate (int) : min=25000 max=25000000 step=25000 default=10000000 value=10000000
repeat_sequence_header (bool) : default=0 value=0
h264_i_frame_period (int) : min=0 max=2147483647 step=1 default=60 value=60
h264_level (menu) : min=0 max=11 default=11 value=11
h264_profile (menu) : min=0 max=4 default=4 value=4
I indeed confirmed that the AWB issue has been fixed and the official v4l2 is almost perfect thanks to your efforts. However the latest issue I mentioned above is a different issue. Which I have not been able to demonstrate yet, I guess the issues become more subtle and harder to detect as the driver matures. The brightness seemed to fluctuate with color of the object in the picture, despite everything being in manual mode.6by9 wrote:I had tried it using QV4L2 a month or so back - https://github.com/raspberrypi/linux/issues/1196Luckk93 wrote:Hello, I'm having the same problem as racer993, I can't remove auto white balance, and if I pick the frames from the v4l2 buffer when overlay is active the frames are completely black.
Exist any way to remove (also completely) the auto white balance setting, so I can at least do a manual white balance on my program?
Found an issue and fixed it. Assuming R4C3R on Github is the same person as racer993 here, then he confirmed it worked.
If you're still seeing issues then please ensure your firmware is more recent than December 2015 ("vcgencmd version").
I think you've just chosen the wrong IOCTL. Use VIDIOC_S_CTRL instead of VIDIOC_S_EXT_CTRLS. All those parameters that you've listed should be available via VIDIOC_S_CTRL.Crymes wrote:Does anyone know how I can control the h.264 Codec data in V4L2?
<snip>
It is all about the two blocks after the comment "//set extended controls" (I think I have to do it via the extended controls in V4L2).
Actually my ioctl fails and the error gets printed but last week when I tested the program it always produces a output file with the same suze no matter what bitrate I set.
- Is it right to use the extended controls api ?
- Does anyone know what I did wrong ?
The c4l2-ctl --all output prints the following lines:That are the parameters which I can change, right?Codec Controls
video_bitrate_mode (menu) : min=0 max=1 default=0 value=0 flags=update
video_bitrate (int) : min=25000 max=25000000 step=25000 default=10000000 value=10000000
repeat_sequence_header (bool) : default=0 value=0
h264_i_frame_period (int) : min=0 max=2147483647 step=1 default=60 value=60
h264_level (menu) : min=0 max=11 default=11 value=11
h264_profile (menu) : min=0 max=4 default=4 value=4
I haven't investigated this one at all.fnoop wrote:Hi, I can't seem to get h264 out of v4l2src in gstreamer, it hangs with a kernel entry:
May 13 07:52:33 raspberrypi kernel: [ 263.336191] bcm2835-v4l2: error 0 waiting for frame completion
x-raw and image/jpeg v4l2src pipelines work just fine, including passing x-raw through to omxh264enc and successfully getting h264 out the other end. So it's specific to v4l2 and h264, which seems to be a bit of a problem as it's the most efficient way to stream data (at least using streamer).
Taking a quite search around it looks like quite a few other people have hit the same problem, and there is an open github issue:
https://github.com/raspberrypi/linux/issues/849
Any suggestions for workarounds, settings or debugging, or is this just some low level bug that we have to wait until someone has time to look at and fix?
Code: Select all
v4l2-ctl --set-fmt-video=width=2592,height=1944,pixelformat=3
v4l2-ctl --stream-mmap=3 --stream-count=1 --stream-to=./testaujourdhui.jpg
If I try withoutVIDIOC_ENUM_FMT: failed: Invalid argument
everything okpixelformat=3
There are 14 different image formats that the camera can produce. If you run "v4l2-ctl --list-formats-ext" it should list them all out. pixelformat is specifying which of those 14 modes to use, and also show the resolutions that each can support.j79 wrote:I try to take a picture with the original RPI camera using this two lines :But the first command returnCode: Select all
v4l2-ctl --set-fmt-video=width=2592,height=1944,pixelformat=3 v4l2-ctl --stream-mmap=3 --stream-count=1 --stream-to=./testaujourdhui.jpg
If I try withoutVIDIOC_ENUM_FMT: failed: Invalid argumenteverything okpixelformat=3
So my first question is about why this argument is refused and the second is about the use of pixelformat. I've made some searches about pixelformat and its different value but I do not find my answers.
very interesting to hear that standard Motion with v4l2-auto_brightness works at all for any resolution.kehall wrote:Using standard Motion with the /dev/video0 device and width/height of 640x480, autoexposure works perfectly.
Code: Select all
0-59/10 * * * * root pgrep motion > /dev/null && systemctl restart motion
It's the longstanding issue that stills mode locks AE and AWB. V4L2 takes anything above 1280x720 (in either direction) to be a still capture.sparkie777 wrote:very interesting to hear that standard Motion with v4l2-auto_brightness works at all for any resolution.kehall wrote:Using standard Motion with the /dev/video0 device and width/height of 640x480, autoexposure works perfectly.
I tested with 1920x1080 only yet and as you say auto_brightness of v4l2 appears to work only at the time of device open. BTW: the Motion-'auto_brightness' internal option of Motion does not work either.
Great! I thought I once already tested this (but with no success) after reading this thread:6by9 wrote:Set the module parameters max_video_width and max_video_height to 2592 and 1944 respectively when loading bcm2835-v4l2, and it'll treat all captures as video mode.
Code: Select all
modprobe bcm2835-v4l2 max_video_width=2592 max_video_height=1944
more /sys/module/bcm2835_v4l2/parameters/*
::::::::::::::
/sys/module/bcm2835_v4l2/parameters/max_video_height
::::::::::::::
1944
::::::::::::::
/sys/module/bcm2835_v4l2/parameters/max_video_width
::::::::::::::
2592
/var/log/messages:
Jun 2 13:18:46 rpi-0 kernel: [1741556.083639] bcm2835-v4l2: scene mode selected 0, was 0
Jun 2 13:18:46 rpi-0 kernel: [1741556.084128] bcm2835-v4l2: V4L2 device registered as video0 - stills mode > 2592x1944
Jun 2 13:18:46 rpi-0 kernel: [1741556.093044] bcm2835-v4l2: Broadcom 2835 MMAL video capture ver 0.0.2 loaded.