[英]Setting Frame Rate on Logitech C210 webcam in C++ on Raspberry pi using v4l2
[英]Is it possible to get good FPS using Raspberry Pi camera v4l2 in c++?
我正在嘗試使用帶有Raspberry Pi相機的官方V4L2驅動程序在Raspberry Pi上流式傳輸視頻,來自C ++ on raspbian(2015-02發布),我的FPS問題很少。
目前我只是創建一個窗口並將緩沖區復制到屏幕(大約需要30ms),而select()
需要大約140ms(總共5-6 fps)。 我也嘗試睡眠100毫秒,它將select()
時間減少了相似的量(導致相同的fps)。 CPU負載約為5-15%。
我也嘗試從控制台(或system()
)更改驅動程序fps但它只能向下工作(例如,如果我將驅動程序fps設置為1fps,我將獲得1fps但如果我將其設置為90fps我仍然得到5- 6fps,即使驅動程序確認將其設置為90fps)。 此外,當查詢使用分辨率的FPS模式時,我得到90fps。
我包含了與V4L2相關的代碼部分(不同部分之間省略了代碼):
//////////////////
// Open device
//////////////////
mFD = open(mDevName, O_RDWR | O_NONBLOCK, 0);
if (mFD == -1) ErrnoExit("Open device failed");
//////////////////
// Setup format
//////////////////
struct v4l2_format fmt;
memset(&fmt, 0, sizeof(fmt));
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
Xioctl(VIDIOC_G_FMT, &fmt);
mImgWidth = fmt.fmt.pix.width;
mImgHeight = fmt.fmt.pix.height;
cout << "width=" << mImgWidth << " height=" << mImgHeight << "\nbytesperline=" << fmt.fmt.pix.bytesperline << " sizeimage=" << fmt.fmt.pix.sizeimage << "\n";
// For some reason querying the format always sets pixelformat to JPEG
// no matter the input, so set it back to YUYV
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
if (Xioctl(VIDIOC_S_FMT, &fmt) == -1)
{
cout << "Set video format failed : " << strerror(errno) << "\n";
}
//////////////////
// Setup streaming
//////////////////
struct v4l2_requestbuffers req;
memset(&req, 0, sizeof(req));
req.count = 20;
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
req.memory = V4L2_MEMORY_MMAP;
if (-1 == Xioctl(VIDIOC_REQBUFS, &req))
{
ErrnoExit("Reqbufs");
}
if (req.count < 2)
throw "Not enough buffer memory !";
mNBuffers = req.count;
mBuffers = new CBuffer[mNBuffers];
if (!mBuffers) throw "Out of memory !";
for (unsigned int i = 0; i < mNBuffers; i++)
{
struct v4l2_buffer buf;
memset(&buf, 0, sizeof(buf));
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = i;
if (-1 == Xioctl(VIDIOC_QUERYBUF, &buf))
ErrnoExit("Querybuf");
mBuffers[i].mLength = buf.length;
mBuffers[i].pStart = mmap(NULL, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, mFD, buf.m.offset);
if (mBuffers[i].pStart == MAP_FAILED)
ErrnoExit("mmap");
}
//////////////////
// Start streaming
//////////////////
unsigned int i;
enum v4l2_buf_type type;
struct v4l2_buffer buf;
for (i = 0; i < mNBuffers; i++)
{
memset(&buf, 0, sizeof(buf));
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = i;
if (-1 == Xioctl(VIDIOC_QBUF, &buf))
ErrnoExit("QBUF");
}
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if (-1==Xioctl(VIDIOC_STREAMON, &type))
ErrnoExit("STREAMON");
主循環中的最后兩部分:
//////////////////
// Get frame
//////////////////
FD_ZERO(&fds);
FD_SET(mFD, &fds);
tv.tv_sec = 3;
tv.tv_usec = 0;
struct timespec t0, t1;
clock_gettime(CLOCK_REALTIME, &t0);
// This line takes about 140ms which I don't get
r = select(mFD + 1, &fds, NULL, NULL, &tv);
clock_gettime(CLOCK_REALTIME, &t1);
cout << "select time : " << ((float)(t1.tv_sec - t0.tv_sec))*1000.0f + ((float)(t1.tv_nsec - t0.tv_nsec))/1000000.0f << "\n";
if (-1 == r)
{
if (EINTR == errno)
continue;
ErrnoExit("select");
}
if (r == 0)
throw "Select timeout\n";
// Read the frame
//~ struct v4l2_buffer buf;
memset(&mCurBuf, 0, sizeof(mCurBuf));
mCurBuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
mCurBuf.memory = V4L2_MEMORY_MMAP;
// DQBUF about 2ms
if (-1 == Xioctl(VIDIOC_DQBUF, &mCurBuf))
{
if (errno == EAGAIN) continue;
ErrnoExit("DQBUF");
}
clock_gettime(CLOCK_REALTIME, &mCaptureTime);
// Manage frame in mBuffers[buf.index]
mCurBufIndex = mCurBuf.index;
break;
}
//////////////////
// Release frame
//////////////////
if (-1 == Xioctl(VIDIOC_QBUF, &mCurBuf))
ErrnoExit("VIDIOC_QBUF during mainloop");
我一直在研究使用picamera的各種方法,我幾乎不是專家,但似乎默認的相機設置是阻礙你的。 有許多模式和開關。 我不知道他們是通過ioctls暴露還是如何暴露,我剛剛開始。 但我不得不使用一個名為v4l-ctl的程序來為我想要的模式做好准備。 深入了解該來源和一些代碼提升應該可以讓您實現偉大。 哦,我懷疑選擇調用是一個問題,它只是在等待描述符,它很慢變得可讀。 根據模式等,可能會強制等待自動曝光等。編輯:我打算說“默認設置”,因為你已經改變了一些。 還有一些規則沒有在驅動程序中編纂。
像素格式很重要。 我遇到了類似的低fps問題,我花了一些時間使用V4L2 API在Go和C ++中使用我的程序進行測試。 我發現,Rpi Cam Module與H.264 / MJPG pixelformat具有良好的相關性。 我可以輕松獲得640 * 480的60fps,與YUYV / RGB等非壓縮格式相同。 但是JPEG運行速度很慢。 我只能在320 * 240時獲得4fps。 我還發現JPEG的電流更高(> 700mA),而H.264 / MJPG的電流則高於500mA。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.