OMAP5432 EVM で Android 4.2 を実行し、4 台の USB 接続 Logitech C270 カメラを使用しています。NDK C コードの V4L2 ドライバーを使用して、MJPEG モードでカメラを開いてストリーミングします。カメラの電源を入れ直した直後を除いて、すべて正常に動作します。
カメラの電源を入れ直した後、2 台または場合によっては 3 台のカメラが正常に起動しますが、1 台のカメラが、バッファの先頭に MJPEG SOI 0xFF、0xD8 がないフレーム バッファを吐き始めますが、EOI 0xFF、0xD9 は存在します。
問題のあるカメラ ファイル /dev/videoX を posix close() で閉じて再度開くと、次の電源サイクルまで問題が解決されます。
単一のカメラが接続されている場合は決して発生せず、そのうちの 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 に何か問題があるのでしょうか、それとも私のコードに何か問題があるのでしょうか? 誰かが同様の問題を経験していますか?