[Sumover-dev] [svn commit] r4328 - vic/branches/mpeg4/video
sumover-dev at cs.ucl.ac.uk
sumover-dev at cs.ucl.ac.uk
Thu Nov 20 03:35:55 GMT 2008
Author: douglask
Date: Thu Nov 20 03:35:51 2008
New Revision: 4328
Modified:
vic/branches/mpeg4/video/grabber-v4l2.cpp
Log:
Made code more tolerant of capture devices that don't support CIF capture resolution.
Also made the pixelformat checking code stricter.
Modified: vic/branches/mpeg4/video/grabber-v4l2.cpp
==============================================================================
--- vic/branches/mpeg4/video/grabber-v4l2.cpp (original)
+++ vic/branches/mpeg4/video/grabber-v4l2.cpp Thu Nov 20 03:35:51 2008
@@ -361,53 +361,61 @@
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
v4l2_ioctl(fd_, VIDIOC_G_FMT, &fmt);
- fmt.fmt.pix.width = CIF_WIDTH;
- fmt.fmt.pix.height = CIF_HEIGHT;
- fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV420;
- if (-1 != v4l2_ioctl(fd_, VIDIOC_S_FMT, &fmt) ) {
- if (fmt.fmt.pix.height == CIF_HEIGHT) {
- have_YUV420P = 1;
- debug_msg("\nDevice supports V4L2_PIX_FMT_YUV420\n");
+ unsigned int test_width[] = {CIF_WIDTH, 320};
+ unsigned int test_height[] = {CIF_HEIGHT, 240};
+ for (unsigned int i = 0; i < sizeof(test_width); i++) {
+ fmt.fmt.pix.width = test_width[i];
+ fmt.fmt.pix.height = test_height[i];
+ fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV420;
+ if (-1 != v4l2_ioctl(fd_, VIDIOC_S_FMT, &fmt) ) {
+ if (fmt.fmt.pix.height == test_height[i] && fmt.fmt.pix.width == test_width[i]) {
+ have_YUV420P = 1;
+ debug_msg("Device supports V4L2_PIX_FMT_YUV420 capture at %dx%d\n",test_width[i],test_height[i]);
+ }
}
- }
- fmt.fmt.pix.width = CIF_WIDTH;
- fmt.fmt.pix.height = CIF_HEIGHT;
- fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV422P;
- if (-1 != v4l2_ioctl(fd_, VIDIOC_S_FMT, &fmt) ) {
- if (fmt.fmt.pix.height == CIF_HEIGHT) {
- have_YUV422P = 1;
- debug_msg("\nDevice supports V4L2_PIX_FMT_YUV422\n");
+ fmt.fmt.pix.width = test_width[i];
+ fmt.fmt.pix.height = test_height[i];
+ fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV422P;
+ if (-1 != v4l2_ioctl(fd_, VIDIOC_S_FMT, &fmt) ) {
+ if (fmt.fmt.pix.height == test_height[i] && fmt.fmt.pix.width == test_width[i]) {
+ have_YUV422P = 1;
+ debug_msg("Device supports V4L2_PIX_FMT_YUV422 capture at %dx%d\n",test_width[i],test_height[i]);
+ }
}
- }
- fmt.fmt.pix.width = CIF_WIDTH;
- fmt.fmt.pix.height = CIF_HEIGHT;
- fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
- if (-1 != v4l2_ioctl(fd_, VIDIOC_S_FMT, &fmt) ) {
- if (fmt.fmt.pix.height == CIF_HEIGHT) {
- have_YUV422 = 1;
- debug_msg("\nDevice supports V4L2_PIX_FMT_YUYV (YUV 4:2:2)\n");
+ fmt.fmt.pix.width = test_width[i];
+ fmt.fmt.pix.height = test_height[i];
+ fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
+ if (-1 != v4l2_ioctl(fd_, VIDIOC_S_FMT, &fmt) ) {
+ if (fmt.fmt.pix.height == test_height[i] && fmt.fmt.pix.width == test_width[i]) {
+ have_YUV422 = 1;
+ debug_msg("Device supports V4L2_PIX_FMT_YUYV (YUV 4:2:2) capture at %dx%d\n",test_width[i],test_height[i]);
+ }
}
- }
#ifdef HAVE_LIBV4L
- fmt.fmt.pix.width = CIF_WIDTH;
- fmt.fmt.pix.height = CIF_HEIGHT;
- fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG;
- if (-1 != v4l2_ioctl(fd_, VIDIOC_S_FMT, &fmt) ) {
- have_MJPEG = 1;
- debug_msg("\nDevice supports V4L2_PIX_FMT_MJPEG\n");
- }
+ fmt.fmt.pix.width = test_width[i];
+ fmt.fmt.pix.height = test_height[i];
+ fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG;
+ if (-1 != v4l2_ioctl(fd_, VIDIOC_S_FMT, &fmt) ) {
+ if (fmt.fmt.pix.height == test_height[i] && fmt.fmt.pix.width == test_width[i]) {
+ have_MJPEG = 1;
+ debug_msg("Device supports V4L2_PIX_FMT_MJPEG capture at %dx%d\n",test_width[i],test_height[i]);
+ }
+ }
- fmt.fmt.pix.width = CIF_WIDTH;
- fmt.fmt.pix.height = CIF_HEIGHT;
- fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_JPEG;
- if (-1 != v4l2_ioctl(fd_, VIDIOC_S_FMT, &fmt) ) {
- have_MJPEG = 1;
- debug_msg("\nDevice supports V4L2_PIX_FMT_JPEG\n");
- }
+ fmt.fmt.pix.width = test_width[i];
+ fmt.fmt.pix.height = test_height[i];
+ fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_JPEG;
+ if (-1 != v4l2_ioctl(fd_, VIDIOC_S_FMT, &fmt) ) {
+ if (fmt.fmt.pix.height == test_height[i] && fmt.fmt.pix.width == test_width[i]) {
+ have_MJPEG = 1;
+ debug_msg("Device supports V4L2_PIX_FMT_JPEG capture at %dx%d\n",test_width[i],test_height[i]);
+ }
+ }
#endif
+ }
if( !( have_YUV422P || have_YUV422 || have_YUV420P || have_MJPEG || have_JPEG)){
debug_msg("No suitable pixelformat found\n");
@@ -658,15 +666,15 @@
vimage[i].vidbuf.memory = V4L2_MEMORY_MMAP;
err = v4l2_ioctl(fd_, VIDIOC_QUERYBUF, &vimage[i].vidbuf);
if (err < 0) {
- debug_msg("QUERYBUF returned error %d\n",errno);
+ debug_msg("QUERYBUF returned error %d\n", errno);
return;
}
vimage[i].data = (typeof(vimage[0].data)) v4l2_mmap(0, vimage[i].vidbuf.length, PROT_READ|PROT_WRITE, MAP_SHARED, fd_, vimage[i].vidbuf.m.offset);
if ((long)vimage[i].data == -1) {
- debug_msg("V4L2: mmap() returned error %l\n", errno);
+ debug_msg("V4L2: mmap() returned error %d\n", errno);
return;
- } else debug_msg("V4L2: mmap()'ed buffer at 0x%x (%d bytes)\n", (long)vimage[i].data, vimage[i].vidbuf.length);
+ } else debug_msg("V4L2: mmap()'ed buffer at 0x%lx (%u bytes)\n", (unsigned long)vimage[i].data, vimage[i].vidbuf.length);
}
for (i = 0; i < (int)req.count; ++i)
@@ -685,7 +693,7 @@
if (vimage[0].data == NULL) {
debug_msg("malloc(%d) failed\n", fmt.fmt.pix.sizeimage);
return;
- } else debug_msg("V4L2: malloc()'ed buffer (%d bytes)\n", fmt.fmt.pix.sizeimage);
+ } else debug_msg("V4L2: malloc()'ed buffer (%d bytes)\n", fmt.fmt.pix.sizeimage);
}
Grabber::start();
@@ -1091,6 +1099,7 @@
int i, err;
int input;
int format_ok = 0;
+ int try_ntsc = 0;
switch (cformat_) {
case CF_420:
@@ -1122,24 +1131,22 @@
}
while ( !format_ok ) {
- if (decimate_ > 0) {
- width_ = CIF_WIDTH *2 / decimate_;
- height_ = CIF_HEIGHT *2 / decimate_;
- }
+ width_ = CIF_WIDTH *2 / decimate_;
+ height_ = CIF_HEIGHT *2 / decimate_;
debug_msg("V4L2: format");
switch (cformat_) {
case CF_CIF:
set_size_420(width_, height_);
- debug_msg(" cif");
+ debug_msg(" cif\n");
break;
case CF_420:
set_size_420(width_, height_);
- debug_msg(" 420");
+ debug_msg(" 420\n");
break;
case CF_422:
set_size_422(width_, height_);
- debug_msg(" 422");
+ debug_msg(" 422\n");
break;
}
debug_msg("decimate: %d\n",decimate_);
@@ -1164,8 +1171,9 @@
fmtd.index = i;
fmtd.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
err = v4l2_ioctl(fd_, VIDIOC_ENUM_FMT, &fmtd);
- if (!err) {
-
+ if (err) {
+ debug_msg("VIDIOC_ENUM_FMT returned error %d\n",errno);
+ } else {
if (fmtd.pixelformat == pixelformat) {
memset(&fmt,0,sizeof(fmt));
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
@@ -1183,25 +1191,43 @@
debug_msg("V4L2: failed to set format! requested %dx%d, got %dx%d\n", width_, height_, fmt.fmt.pix.width, fmt.fmt.pix.height);
-
switch(decimate_) {
- case 2:
- debug_msg("V4L2: trying resolution under ...\n");
- decimate_ = 4;
- break;
case 1:
- debug_msg("V4L2: trying NTSC resolution ...\n");
- decimate_ = 0;
- width_ = NTSC_WIDTH;
- height_ = NTSC_HEIGHT;
+ if (!try_ntsc) {
+ debug_msg("V4L2: trying NTSC resolution ...\n");
+ width_ = NTSC_WIDTH;
+ height_ = NTSC_HEIGHT;
+ try_ntsc = 1;
+ } else {
+ debug_msg("V4L2: trying resolution under ...\n");
+ decimate_ = 2;
+ try_ntsc = 0;
+ }
break;
- case 0:
- debug_msg("V4L2: trying resolution under ...\n");
- decimate_ = 2;
+ case 2:
+ if (!try_ntsc) {
+ debug_msg("V4L2: trying 1/4 NTSC resolution ...\n");
+ width_ = NTSC_WIDTH / 2;
+ height_ = NTSC_HEIGHT / 2;
+ try_ntsc = 1;
+ } else {
+ debug_msg("V4L2: trying resolution under ...\n");
+ decimate_ = 4;
+ try_ntsc = 0;
+ }
break;
default:
- debug_msg("V4L2: giving up ...\n");
- format_ok = 1;
+ if (!try_ntsc) {
+ debug_msg("V4L2: trying 1/16 NTSC resolution ...\n");
+ width_ = NTSC_WIDTH / 4;
+ height_ = NTSC_HEIGHT / 4;
+ try_ntsc = 0;
+ } else {
+ debug_msg("V4L2: giving up ...\n");
+ format_ok = 1;
+ }
+ break;
+
}
} else {
More information about the Sumover-dev
mailing list