- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我有运行 Android 4.2 的 OMAP5432 EVM,带有 4 个 USB 连接的罗技 C270 摄像头。我使用来自 NDK C 代码的 V4L2 驱动程序以 MJPEG 模式从相机中打开和流式传输。一切正常,除了在重新启动相机之后。
在重新启动相机后,其中两个或有时三个正确出现,但一个开始吐出帧缓冲区,缓冲区开头缺少 MJPEG SOI 0xFF、0xD8,而 EOI 0xFF、0xD9 存在。
使用 posix close() 关闭并重新打开有问题的相机文件/dev/videoX 可以解决问题,直到下一次电源循环为止。
连接单个摄像头时永远不会发生这种情况,只有连接 3 或 4 个摄像头时才会发生这种情况。
我试过更换 USB 集线器,直接连接相机都无济于事。
struct v4l2_format fm = {0};
fm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
int r = xioctl(c->fd, VIDIOC_G_FMT, &fm);
if (r != 0) {
printf("VIDIOC_G_FMT %s r=%d error %d, %s", c->name, r, errno, strerror(errno));
return -1;
}
fm.fmt.pix.width = c->width; // 640
fm.fmt.pix.height = c->height; // 480
fm.fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG;
fm.fmt.pix.field = V4L2_FIELD_ANY;
fm.fmt.pix.colorspace = V4L2_COLORSPACE_JPEG;
if (c->fm != V4L2_PIX_FMT_MJPEG) {
unsigned int min = fm.fmt.pix.width * 2;
if (fm.fmt.pix.bytesperline < min) {
fm.fmt.pix.bytesperline = min;
}
min = fm.fmt.pix.bytesperline * fm.fmt.pix.height;
if (fm.fmt.pix.sizeimage < min) {
fm.fmt.pix.sizeimage = min;
}
} else {
fm.fmt.pix.bytesperline = 0;
fm.fmt.pix.sizeimage = 0;
}
r = xioctl(c->fd, VIDIOC_S_FMT, &fm);
其次是
static int init_mmap(camera_t_* c) {
struct v4l2_requestbuffers rq = {0};
rq.count = BUFFERS;
rq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
rq.memory = V4L2_MEMORY_MMAP;
if (xioctl(c->fd, VIDIOC_REQBUFS, &rq) != 0) {
if (EINVAL == errno) {
printf("%s does not support memory mapping", c->name);
return -1;
} else {
printf("VIDIOC_REQBUFS error %d, %s", errno, strerror(errno));
return -1;
}
}
if (rq.count < 2) {
printf("Insufficient buffer memory on %s", c->name);
return -1;
}
c->buffers = malloc(rq.count * sizeof(buffer_t));
if (c->buffers == null) {
printf("out of memory");
return -1;
}
c->n_buffers = rq.count;
for (int i = 0; i < rq.count; i++) {
struct v4l2_buffer b = {0};
b.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
b.memory = V4L2_MEMORY_MMAP;
b.index = i;
if (xioctl(c->fd, VIDIOC_QUERYBUF, &b) != 0) {
printf("VIDIOC_QUERYBUF error %d, %s", errno, strerror(errno));
return -1;
}
c->buffers[i].length = b.length;
c->buffers[i].start = mmap(null, b.length, PROT_READ | PROT_WRITE, MAP_SHARED, c->fd, b.m.offset);
if (c->buffers[i].start == MAP_FAILED) {
printf("mmap error %d, %s", errno, strerror(errno));
return -1;
}
}
return 0;
}
我得到的数据是这样的:
missing FFD8 tag 0x688fb000 bytes=6946 length=213333
0x688fb000: AB 74 10 0C EE FD 34 FB B3 FA 3E D1 60 9D 33 B0 ?t????4???>?`?3?
0x688fb010: F1 83 7B 8A AF B8 F9 BF EF 33 EE FF 89 91 7F 9F ??{??????3?????
0x688fb020: 47 EF A4 B9 73 1C BC FB AD 46 6A D5 22 A2 2C 32 G???s????Fj?"?,2
0x688fb030: 2B A8 71 7E 56 56 73 23 15 7B 11 B2 F0 FA AA D3 +?q~VVs#?{??????
.............
0x688fcae2: 00 A2 80 0A 28 03 FF D5 C6 A2 80 0A 28 00 A2 80 ????(???????(???
0x688fcaf2: 0A 28 00 A2 80 0A 28 00 A2 80 0A 28 00 A2 80 0A ?(????(????(????
0x688fcb02: 28 03 FF D6 C6 A2 80 0A 28 00 A2 80 0A 28 00 A2 (???????(????(??
0x688fcb12: 80 0A 28 00 A2 80 0A 28 00 A2 80 0A 28 03 FF D9 ??(????(????(???
每个出列缓冲区都是相同的数据...
是 C270 或 V4L2 有问题还是我的代码有问题?有人遇到过类似的问题吗?
最佳答案
好的,看起来我已经通过内核日志找到了问题的根源:
adb shell sudo echo 8 > /proc/sys/kernel/printk
adb >/tmp/adb_klog.txt 2>/tmp/adb_klog.txt shell sudo cat /proc/kmsg
命令。看起来 VIDIOC_G_FMT 在 4 个摄像头中有 1 个或 2 个失败,而没有向用户和 ioctl() 调用报告错误:
<7>[ 7274.495178] uvcvideo: uvc_v4l2_open
<7>[ 7274.495239] ehci-omap ehci-omap.0: reused qh ca5bf1c0 schedule
<7>[ 7274.495269] usb 1-2.2.1.2: link qh16-0001/ca5bf1c0 start 1 [1/0 us]
<7>[ 7274.495330] uvcvideo: uvc_v4l2_ioctl(VIDIOC_G_FMT)
<7>[ 7274.495452] uvcvideo: uvc_v4l2_ioctl(VIDIOC_S_FMT)
<7>[ 7274.495483] uvcvideo: Trying format 0x47504a4d (MJPG): 640x480.
<7>[ 7274.495513] uvcvideo: Using default frame interval 33333.3 us (30.0 fps).
<7>[ 7279.495208] usb 1-2.2.1.2: .<process_name> timed out on ep0out len=0/26
<3>[ 7279.495239] uvcvideo: Failed to set UVC probe control : -110 (exp. 26).
<7>[ 7279.502746] uvcvideo: uvc_v4l2_ioctl(VIDIOC_G_FMT)
<7>[ 7279.507080] uvcvideo: uvc_v4l2_ioctl(VIDIOC_LOG_STATUS)
<7>[ 7279.507080] uvcvideo: Unknown ioctl 0x00005646
我想出的最简单的解决方法是在打开相机后开始流式传输,等待(超时)直到帧开始流动,如果损坏的帧出现在附近并重新打开相机。
在我的代码中它看起来像这样:
static bool has_bad_frames(camera_t* camera) {
/* Logitech C270 randomly spits corrupted MJPEGs after power cycle. Known workaround is to reopen camera */
camera_t_* c = (camera_t_*)camera;
camera_set_callback(c, empty_callback); // otherwise MJPEG frames are not going to be decompressed
camera_start(camera);
int retry = 300; // 3 seconds max
while (retry > 0 && c->good_frames == 0 && c->bad_frames == 0) {
nsleep(NANOSECONDS_IN_SECOND / 100); /* 1/100 second */
retry--;
}
bool ok = c->bad_frames == 0 && c->good_frames > 0;
camera_stop(camera);
return !ok;
}
int camera_open(void* that, camera_t* o, int id, int w, int h, int bpp) {
int r = try_to_open(that, o, id, w, h, bpp);
if (r == 0) {
if (has_bad_frames(*o)) {
camera_t_* c = (camera_t_*)*o;
if (c->bad_frames + c->good_frames == 0) {
trace("%s is not streaming; retrying...", c->name);
} else {
trace("%s spits corrupted frames. Probable VIDIOC_S_FMT silently failed; retrying...", c->name);
}
camera_close(*o);
*o = null;
return try_to_open(that, o, id, w, h, bpp);
}
}
return r;
}
关于android - V4L2 驱动程序破坏了 Android OMAP5432 上 4 个 USB 摄像头的缓冲区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26435692/
我正在尝试解析由某些 Ruby 代码 (https://github.com/devrandom/gitian-builder/blob/81bf5d70252363a95cb75eea70f8d1d
我试图从 YAML 文件中删除几个属性,我成功地这样做了,但它在输出文件中有一些额外的字符,不知道如何删除这些。 这是输入的 YAML 文件: Person: Name: John Child
我有一 block Omap5912 板,我愿意在业余时间做一些编码练习。我在 google 上搜索了一些 IDE 和开发工具,但除了 TI Code Composer Studio 之外,我找不到任
来自内核 3.4 code ,我无法确定 UART 基地址映射到哪里?据我所知,映射基地址我们应该使用 request_mem_region 和 io_remap 函数。但我可以在代码中找不到这个。U
我正在为 OMAP3430 开发视频编解码器。我已经有用 C++ 编写的代码,我尝试修改/移植它的某些部分以利用 DSP(我拥有的 SDK (OMAP ZOOM3430 SDK) 有一个额外的 DSP
我的团队正在尝试控制德州仪器 OMAP l138 的频率。默认频率为 300 MHz,我们希望以“完整”的形式将其设置为 372 MHz:我们不仅希望将默认值更改为所需的值(或至少在启动时配置它),而
我想知道我是否可以在 OMAP4430 PandaBoard-ES 中使用 DSP 内核以及在 Linux 操作系统上运行的代码来加速某些进程?我只想通过 DSP 内核在我的代码中进行一些处理,其余的
我有一个 华力士VAR-SOM-AM33 SOM和开发板(VAR-AM33客户板) 我想让UART3和 Sparkfun FTDI基本分接-3.3V TTL UART到USB适配器(http://sf
哪里可以下载适用于内核版本 #2.6.31-rc7-omap1-06331-g757f531 的 OMAP 3530 文件系统,或者如何从源代码创建一个文件系统? TI 提供的文件系统适用于内核版本为
我终于成功地设置了我的 OMAP 3530 以使用 NFS 和 tftpboot 启动嵌入式 Linux。现在是时候开始行动了。编写一个简单的字符驱动程序来切换电路板上的 LED。我现在已经从 Cod
我想知道 DMA 在 Pandaboard 中的工作原理。我已经阅读了 Pandaboard 中使用的 OMPA4460 的 TRM,DMA 系统一次可以管理总共 128 个请求,最多 32 个逻辑
我正在使用 OMAP 3730 开发一个嵌入式 Linux 项目。我们使用的是 3.2.23 版本的内核。 I2C 工作正常,我可以在总线 #2 上看到板上的各种传感器。 I2C 总线 #3 仅连接了
我在为 Caspa mt9v032 omap-isp 获取正确的 media-ctl 命令时遇到问题。我遵循了本教程但未能成功 --> Camera-ISP Driver本教程提供了更多细节但也无法成
我开始分析 TI X-Loader,包括它的 makefile。我在顶部的 makefile 中找到了以下几行: TOPDIR := $(shell if [ "$$PWD" != "" ]; the
我是一名优秀的程序员,十分优秀!