我有一个有效的 V4L2 实现,可以从连接的视频设备捕获图像。到目前为止,这对我尝试过的所有相机都很有效:
bidx=read_frame(data);
if (bidx>-1)
{
if (data->pixelformat==V4L2_PIX_FMT_YUYV) yuv422_to_rgb24(data,(unsigned char*)data->buffers[bidx].start);
else if (data->pixelformat==V4L2_PIX_FMT_YUV422P) yuv422p_to_rgb24(data,(unsigned char*)data->buffers[bidx].start);
else
{
printf("Error: unsupported pixel format 0x%X\n",data->pixelformat);
assert(0);
V4L2_PIX_FMT_YUYV 和 V4L2_PIX_FMT_YUV422P 表示缓冲区中的数据是单个图像,只需使用返回缓冲区的内容即可单独处理每个图像。这正是我想做的。
现在我发现一台设备将数据返回为 MJPG(这可能是由于 Linux 内核的更新而发生的?),因此跳转到上面代码的错误分支。
现在我的问题是:如何从这些 MJPG 数据中获取单个图像?
澄清一下:我想完全以编程方式完成此操作,调用命令行来使用某些外部应用程序对我来说不是一个解决方案。
谢谢!
更新:V4L 的东西可以在 read_frame() 函数中找到:
int read_frame(struct instData *data)
{
struct v4l2_buffer buf;
memset(&buf,0,sizeof(buf));
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
if (-1 == xioctl (data->fd, VIDIOC_DQBUF, &buf))
{
switch (errno)
{
case EAGAIN:
return -1;
case EIO:
/* Could ignore EIO, see spec. */
/* fall through */
default:
return -1;
}
}
xioctl (data->fd, VIDIOC_QBUF, &buf);
return buf.index;
}
最后我找到了答案:MJPEG可以使用libjpeg解码,代码本身可以在如何将MJPEG解码为原始RGB(或YUV)数据
找到