在Android上使用v4l2捕获视频时获取所有0数据

时间:2013-10-17 08:43:17

标签: android android-ndk camera java-native-interface v4l2

我正在尝试使用jni下的v4l2在Android上捕获视频。我找到了一些指南并按照步骤进行了操作:

fd = open("/dev/video0", O_RDWR);

/* init part */
ioctl(fd, VIDIOC_QUERYCAP, &caps);
ioctl(fd, VIDIOC_ENUM_FMT, &fmtdesc);
ioctl(fd, VIDIOC_S_FMT, &fmt);
ioctl(fd, VIDIOC_REQBUFS, &req);
ioctl(fd, VIDIOC_QUERYBUF, &buf);
ioctl(fd, VIDIOC_QBUF, &buf);

/* capture part */
FILE *fp = fopen("/sdcard/img.yuv", "wb");
for (i = 0; i < 20; i++)
{
    ioctl(fd, VIDIOC_DQBUF, &buf);
    fwrite(buffers[buf.index].start, 1, buf.bytesused, fp);
    ioctl(fd, VIDIOC_QBUF, &buf);
}
fclose(fp);

这是我的代码的主要结构。所有函数都正确运行并返回0.但是,当我用二进制查看器打开输出文件时,我发现所有数据都是0。

我的代码有问题吗?我感到困惑,因为所有的函数都返回0。

谢谢!

1 个答案:

答案 0 :(得分:0)

您正在使用名为buffers []的数组。但是,我无法看到它宣告的位置或它代表什么。如果上面没有代码丢失,你将总是得到零,因为你正在写缓冲区[]到文件,而不是你从v4l2得到的东西。 此外,ioctl命令之前的caps,fmtdesc,fmt,req和buf的初始值也很有趣。根据其初始值,您将拥有不同的通信接口。问题可能隐藏在这些部分中。

正如您在问题中所写,所有ioctl命令都会返回0,应该没有错误。如果一切都像预期的那样。另一种检查问题的方法是调用

perror("<your comment or hint to line above>");

在每个ioctl命令之后。这将打印出有关std-out错误的更多信息。 (关于perror的更多细节可以在这个帖子中找到When should I use perror("...") and fprintf(stderr, "...")?

您是否想要从相机获取图像? (在上面使用的某些手机上的视频0是后置摄像头)在某些Android设备上,除了videoXY之外,还必须使用其他设备驱动程序通过复杂的程序启动相机。在官方相机应用程序运行时尝试从video0获取图像可能很困难。官方的v4l2 api说:

  

V4L2驱动程序不应支持多个应用程序通过复制缓冲区,时间复用或类似方法在设备上读取或写入相同的数据流。这可以通过用户空间中的代理应用程序更好地处理。

来自:http://linuxtv.org/downloads/v4l-dvb-apis/common.html#idp18553208

您可以发布更多(详细)代码吗?我也许可以提供帮助,因为我做的事非常相似。

为了能够重现它,你正在使用哪个Android设备(类型/型号/安卓版)会非常有趣。