You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
zbar/zbar_choose_supported_forma...

129 lines
5.0 KiB

diff -r 60f92d860a1f zbar/convert.c
--- a/zbar/convert.c Sat Dec 25 08:29:33 2010 -0200
+++ b/zbar/convert.c Sat Dec 25 14:36:04 2010 -0200
@@ -1157,6 +1157,42 @@
break;
}
}
+ if(!min_fmt && vdo->emu_formats) {
+ /* As vdo->formats aren't compatible, just free them */
+ free(vdo->formats);
+ vdo->formats = vdo->emu_formats;
+ vdo->emu_formats = NULL;
+
+ /*
+ * Use the same cost algorithm to select emulated formats.
+ * This might select a sub-optimal conversion, but, in practice,
+ * it will select a conversion to YUV at libv4l, and a YUY->Y8
+ * in zbar, with it is OK. Yet, it is better to not select the
+ * most performatic conversion than to not support the webcam.
+ */
+ for(fmt = _zbar_formats; *fmt; fmt++) {
+ /* only consider formats supported by video device */
+ uint32_t win_fmt = 0;
+ int cost;
+ if(!has_format(*fmt, srcs))
+ continue;
+ cost = _zbar_best_format(*fmt, &win_fmt, dsts);
+ if(cost < 0) {
+ zprintf(4, "%.4s(%08" PRIx32 ") -> ? (unsupported)\n",
+ (char*)fmt, *fmt);
+ continue;
+ }
+ zprintf(4, "%.4s(%08" PRIx32 ") -> %.4s(%08" PRIx32 ") (%d)\n",
+ (char*)fmt, *fmt, (char*)&win_fmt, win_fmt, cost);
+ if(min_cost > cost) {
+ min_cost = cost;
+ min_fmt = *fmt;
+ if(!cost)
+ break;
+ }
+ }
+ }
+
if(win)
(void)window_unlock(win);
diff -r 60f92d860a1f zbar/video.c
--- a/zbar/video.c Sat Dec 25 08:29:33 2010 -0200
+++ b/zbar/video.c Sat Dec 25 14:36:04 2010 -0200
@@ -111,6 +111,9 @@
free(vdo->buf);
if(vdo->formats)
free(vdo->formats);
+ if(vdo->emu_formats)
+ free(vdo->emu_formats);
+
err_cleanup(&vdo->err);
_zbar_mutex_destroy(&vdo->qlock);
diff -r 60f92d860a1f zbar/video.h
--- a/zbar/video.h Sat Dec 25 08:29:33 2010 -0200
+++ b/zbar/video.h Sat Dec 25 14:36:04 2010 -0200
@@ -69,6 +69,7 @@
uint32_t format; /* selected fourcc */
unsigned palette; /* v4l1 format index corresponding to format */
uint32_t *formats; /* 0 terminated list of supported formats */
+ uint32_t *emu_formats; /* 0 terminated list of emulated formats */
unsigned long datalen; /* size of image data for selected format */
unsigned long buflen; /* total size of image data buffer */
diff -r 60f92d860a1f zbar/video/v4l2.c
--- a/zbar/video/v4l2.c Sat Dec 25 08:29:33 2010 -0200
+++ b/zbar/video/v4l2.c Sat Dec 25 14:36:04 2010 -0200
@@ -347,6 +347,8 @@
static inline int v4l2_probe_formats (zbar_video_t *vdo)
{
+ int n_formats = 0, n_emu_formats = 0;
+
zprintf(2, "enumerating supported formats:\n");
struct v4l2_fmtdesc desc;
memset(&desc, 0, sizeof(desc));
@@ -354,17 +356,39 @@
for(desc.index = 0; desc.index < V4L2_FORMATS_MAX; desc.index++) {
if(v4l2_ioctl(vdo->fd, VIDIOC_ENUM_FMT, &desc) < 0)
break;
- zprintf(2, " [%d] %.4s : %s%s\n",
+ zprintf(2, " [%d] %.4s : %s%s%s\n",
desc.index, (char*)&desc.pixelformat, desc.description,
- (desc.flags & V4L2_FMT_FLAG_COMPRESSED) ? " COMPRESSED" : "");
- vdo->formats = realloc(vdo->formats,
- (desc.index + 2) * sizeof(uint32_t));
- vdo->formats[desc.index] = desc.pixelformat;
+ (desc.flags & V4L2_FMT_FLAG_COMPRESSED) ? " COMPRESSED" : "",
+ (desc.flags & V4L2_FMT_FLAG_EMULATED) ? " EMULATED" : "");
+ if (desc.flags & V4L2_FMT_FLAG_EMULATED) {
+ vdo->emu_formats = realloc(vdo->emu_formats,
+ (n_emu_formats + 2) * sizeof(uint32_t));
+ vdo->emu_formats[n_emu_formats++] = desc.pixelformat;
+ } else {
+ vdo->formats = realloc(vdo->formats,
+ (n_formats + 2) * sizeof(uint32_t));
+ vdo->formats[n_formats++] = desc.pixelformat;
+ }
}
if(!desc.index)
return(err_capture(vdo, SEV_ERROR, ZBAR_ERR_SYSTEM, __func__,
"enumerating video formats (VIDIOC_ENUM_FMT)"));
- vdo->formats[desc.index] = 0;
+ if(vdo->formats)
+ vdo->formats[n_formats] = 0;
+ if(vdo->emu_formats)
+ vdo->emu_formats[n_emu_formats] = 0;
+ if(!vdo->formats && vdo->emu_formats) {
+ /*
+ * If only emu formats are available, just move them to vdo->formats.
+ * This happens when libv4l detects that the only available fourcc
+ * formats are webcam proprietary formats or bayer formats.
+ */
+ vdo->formats = vdo->emu_formats;
+ vdo->emu_formats = NULL;
+ }
+
+ zprintf(2, "Found %d formats and %d emulated formats.\n",
+ n_formats, n_emu_formats);
struct v4l2_format fmt;
struct v4l2_pix_format *pix = &fmt.fmt.pix;