如何将数据从 v4l2 放入 C++ 向量
How to put data from v4l2 to a c++ vector
我目前正在尝试使用 C++ 从 MJPEG UVC 网络摄像头读取视频。
使用 this tutorial,我能够检索 JPEG 图像并将其保存在磁盘上。现在,我尝试使用 JPEG 图像数据而不将其写入磁盘;我想使用 C++ 向量来存储它,但我找不到如何实现它。
据我了解,该教程映射了 v4l2 用于在内存中存储网络摄像头数据的内存段:
struct v4l2_buffer bufferinfo;
memset(&bufferinfo, 0, sizeof(bufferinfo));
bufferinfo.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
bufferinfo.memory = V4L2_MEMORY_MMAP;
bufferinfo.index = 0;
if(ioctl(fd, VIDIOC_QUERYBUF, &bufferinfo) < 0){
perror("VIDIOC_QUERYBUF");
exit(1);
}
void* buffer_start = mmap(
NULL,
bufferinfo.length,
PROT_READ | PROT_WRITE,
MAP_SHARED,
fd,
bufferinfo.m.offset
);
当我们发送一些命令时,这个内存段由 v4l2 填充:
if(ioctl(fd, VIDIOC_QBUF, &bufferinfo) < 0){
perror("VIDIOC_QBUF");
exit(1);
}
// The buffer's waiting in the outgoing queue.
if(ioctl(fd, VIDIOC_DQBUF, &bufferinfo) < 0){
perror("VIDIOC_QBUF");
exit(1);
}
最后,使用写函数将内存写入磁盘:
int jpgfile;
if((jpgfile = open("/tmp/myimage.jpeg", O_WRONLY | O_CREAT, 0660)) < 0){
perror("open");
exit(1);
}
write(jpgfile, buffer_start, bufferinfo.length);
close(jpgfile);
但是我怎样才能将这个内存段复制到一个向量中呢?
提前致谢。
您可以将 void *
重新解释为 char *
以获得原始数据:
char *char_buffer = reinterpret_cast<char *>(buffer_start);
std::vector<char> jpegdata{char_buffer, char_buffer + bufferinfo.length};
(这使用了向量构造函数的 "iterator pair" 重载。)
您可以考虑改用 std::string
:
std::string jpegdata{reinterpret_cast<char *>(buffer_start), bufferinfo.length};
(std::string
方法最终可能会更快;构造函数可能会 memcpy()
或使用其他一些 blitting 技术比基于迭代器的向量模板构造函数更有效地复制数据。)
我目前正在尝试使用 C++ 从 MJPEG UVC 网络摄像头读取视频。 使用 this tutorial,我能够检索 JPEG 图像并将其保存在磁盘上。现在,我尝试使用 JPEG 图像数据而不将其写入磁盘;我想使用 C++ 向量来存储它,但我找不到如何实现它。
据我了解,该教程映射了 v4l2 用于在内存中存储网络摄像头数据的内存段:
struct v4l2_buffer bufferinfo;
memset(&bufferinfo, 0, sizeof(bufferinfo));
bufferinfo.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
bufferinfo.memory = V4L2_MEMORY_MMAP;
bufferinfo.index = 0;
if(ioctl(fd, VIDIOC_QUERYBUF, &bufferinfo) < 0){
perror("VIDIOC_QUERYBUF");
exit(1);
}
void* buffer_start = mmap(
NULL,
bufferinfo.length,
PROT_READ | PROT_WRITE,
MAP_SHARED,
fd,
bufferinfo.m.offset
);
当我们发送一些命令时,这个内存段由 v4l2 填充:
if(ioctl(fd, VIDIOC_QBUF, &bufferinfo) < 0){
perror("VIDIOC_QBUF");
exit(1);
}
// The buffer's waiting in the outgoing queue.
if(ioctl(fd, VIDIOC_DQBUF, &bufferinfo) < 0){
perror("VIDIOC_QBUF");
exit(1);
}
最后,使用写函数将内存写入磁盘:
int jpgfile;
if((jpgfile = open("/tmp/myimage.jpeg", O_WRONLY | O_CREAT, 0660)) < 0){
perror("open");
exit(1);
}
write(jpgfile, buffer_start, bufferinfo.length);
close(jpgfile);
但是我怎样才能将这个内存段复制到一个向量中呢?
提前致谢。
您可以将 void *
重新解释为 char *
以获得原始数据:
char *char_buffer = reinterpret_cast<char *>(buffer_start);
std::vector<char> jpegdata{char_buffer, char_buffer + bufferinfo.length};
(这使用了向量构造函数的 "iterator pair" 重载。)
您可以考虑改用 std::string
:
std::string jpegdata{reinterpret_cast<char *>(buffer_start), bufferinfo.length};
(std::string
方法最终可能会更快;构造函数可能会 memcpy()
或使用其他一些 blitting 技术比基于迭代器的向量模板构造函数更有效地复制数据。)