Mailinglist Archive: opensuse-commit (793 mails)

< Previous Next >
commit libv4l for openSUSE:Factory
  • From: root@xxxxxxxxxxxxxxx (h_root)
  • Date: Thu, 10 Sep 2009 13:00:32 +0200
  • Message-id: <20090910110032.C43DC63A0@xxxxxxxxxxxxxxx>

Hello community,

here is the log from the commit of package libv4l for openSUSE:Factory
checked in at Thu Sep 10 13:00:32 CEST 2009.



--------
--- libv4l/libv4l.changes 2009-08-06 20:58:43.000000000 +0200
+++ /mounts/work_src_done/STABLE/libv4l/libv4l.changes 2009-09-01
13:18:15.000000000 +0200
@@ -1,0 +2,14 @@
+Tue Sep 1 13:10:00 CEST 2009 - schaeferf.obs@xxxxxxxxxxxxxx
+
+- Update to v0.6.1
+ - Add more laptop models to the upside down devices table
+ - Bugfix: fixup 320x240 output for pac7302 cameras
+ - Bugfix: fix reqbuf Device or Resource busy error when using v4l2_read()
+ - Some applications want to use jpg format if possible, so do not hide
+ it from the apps (do not assume it always needs conversion)
+ - Change controls shm segment name to include the username, as it is only
+ writable by the user (this means libv4l controls are per user) (Gregor
Jasny)
+ - Add support for decompressing sn9c2028 compressed bayer (Theodore Kilgore)
+ - Report V4L2_FMT_FLAG_EMULATED in v4l2_fmtdesc flags for emulated formats
+
+-------------------------------------------------------------------

calling whatdependson for head-i586


Old:
----
libv4l-0.6.0.tar.gz

New:
----
libv4l-0.6.1.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ libv4l.spec ++++++
--- /var/tmp/diff_new_pack.AE6C4P/_old 2009-09-10 12:59:33.000000000 +0200
+++ /var/tmp/diff_new_pack.AE6C4P/_new 2009-09-10 12:59:33.000000000 +0200
@@ -1,5 +1,5 @@
#
-# spec file for package libv4l (Version 0.6.0)
+# spec file for package libv4l (Version 0.6.1)
#
# Copyright (c) 2009 SUSE LINUX Products GmbH, Nuernberg, Germany.
#
@@ -18,7 +18,7 @@


Name: libv4l
-Version: 0.6.0
+Version: 0.6.1
Release: 1
Summary: collection of video4linux support libraries
Group: System/Libraries

++++++ libv4l-0.6.0.tar.gz -> libv4l-0.6.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/libv4l-0.6.0/ChangeLog new/libv4l-0.6.1/ChangeLog
--- old/libv4l-0.6.0/ChangeLog 2009-07-09 14:10:19.000000000 +0200
+++ new/libv4l-0.6.1/ChangeLog 2009-08-31 16:39:42.000000000 +0200
@@ -1,3 +1,17 @@
+libv4l-0.6.1
+------------
+* Add more laptop models to the upside down devices table
+* Makefile changes to make life easier for the Debian package (Gregor Jasny)
+* Bugfix: fixup 320x240 output for pac7302 cameras
+* README improvements / clarifications (Bifferos)
+* Bugfix: fix reqbuf Device or Resource busy error when using v4l2_read()
+* Some applications want to use jpg format if possible, so do not hide
+ it from the apps (do not assume it always needs conversion)
+* Change controls shm segment name to include the username, as it is only
+ writable by the user (this means libv4l controls are per user) (Gregor Jasny)
+* Add support for decompressing sn9c2028 compressed bayer (Theodore Kilgore)
+* Report V4L2_FMT_FLAG_EMULATED in v4l2_fmtdesc flags for emulated formats
+
libv4l-0.6.0
------------
* Recognize disabled controls and replace with fake equivalents where
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/libv4l-0.6.0/Makefile new/libv4l-0.6.1/Makefile
--- old/libv4l-0.6.0/Makefile 2009-06-24 14:05:49.000000000 +0200
+++ new/libv4l-0.6.1/Makefile 2009-08-05 12:26:03.000000000 +0200
@@ -1,5 +1,5 @@
LIB_RELEASE=0
-V4L2_LIB_VERSION=$(LIB_RELEASE).6.0
+V4L2_LIB_VERSION=$(LIB_RELEASE).6.1

all install:
$(MAKE) -C libv4lconvert V4L2_LIB_VERSION=$(V4L2_LIB_VERSION) $@
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/libv4l-0.6.0/README new/libv4l-0.6.1/README
--- old/libv4l-0.6.0/README 2009-04-13 19:58:52.000000000 +0200
+++ new/libv4l-0.6.1/README 2009-08-05 12:26:03.000000000 +0200
@@ -25,13 +25,13 @@
For more details on the v4lconvert_ functions see libv4lconvert.h.

Later on libv4lconvert was expanded to also be able to do various video
-processing functions improve webcam video quality on a software basis. So
+processing functions to improve webcam video quality on a software basis. So
the name no longer 100% covers the functionality. The video processing is
split in to 2 parts, libv4lconvert/control and libv4lconvert/processing.

The control part is used to offer video controls which can be used to control
the video processing functions made available by libv4lconvert/processing.
-These controls are stored application wide (untill reboot) by using a
+These controls are stored application wide (until reboot) by using a
persistent shared memory object.

libv4lconvert/processing offers the actual video processing functionality.
@@ -80,6 +80,12 @@
$ camorama


+Prerequisites
+-------------
+
+libv4l requires shmem file system support in the kernel (CONFIG_SHMEM).
+
+
Installation Instructions
-------------------------

@@ -88,9 +94,15 @@
make
make install PREFIX=/usr/local

-Note: make install also supports the DESTDIR=... paramter for installation
+Note: make install also supports the DESTDIR=... parameter for installation
into chroots.

+If you require static libraries to also be built, these can be compiled
+along with the dynamic equivalents by defining LINKTYPE to 'static', e.g.:
+
+make LINKTYPE=static
+make install LINKTYPE=static
+

FAQ
---
@@ -117,10 +129,13 @@
allows this code to be used from as many different applications as possible.
Hence libv4l was born.

+
Q: Under which license may I use and distribute libv4l?
-A: All libv4l components are licensed under the GNU Library General Publishing
+A: The libv4l libraries are licensed under the GNU Library General Publishing
License version 2 or (at your option) any later version. See the included
-COPYING.LIB file.
+COPYING.LIB file. The decompression helpers are licensed under the GNU
+Library Publishing License version 2 (as they are derived from kernel code)
+

Q: Okay so I get the use of having a libv4lconvert, but why libv4l1 ?
A: Many v4l2 drivers do not offer full v4l1 compatibility. They often do not
@@ -138,9 +153,8 @@


Q: Why should I use libv4l2 in my app instead of direct device access
-combined with libv4lconvert?
-
-libv4l2 is mainly meant for quickly and easily adding support for more
+ combined with libv4lconvert?
+A: libv4l2 is mainly meant for quickly and easily adding support for more
pixelformats to existing v4l2 applications. So if you feel better directly
accessing the device in combination with libv4lconvert thats fine too.

@@ -151,3 +165,11 @@
data directly to the buffer the application provided to v4l2_read(). Thus
another reason to use liv4l2 is to get the no memcpy advantage of the mmap
capture method combined with the simplicity of making a simple read() call.
+
+
+Q: Where to send bugreports / questions?
+A: Please send libv4l questions / bugreports to the:
+ Linux Media Mailing List <linux-media@xxxxxxxxxxxxxxx>
+ Subscription is not necessary to send mail to this list. If you're not
+ subscribed please put yourself in the CC of your original mail so you
+ will receive replies.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/libv4l-0.6.0/include/libv4l1.h
new/libv4l-0.6.1/include/libv4l1.h
--- old/libv4l-0.6.0/include/libv4l1.h 2009-06-02 14:38:18.000000000 +0200
+++ new/libv4l-0.6.1/include/libv4l1.h 2009-08-05 12:26:03.000000000 +0200
@@ -1,5 +1,5 @@
/*
-# (C) 2008 Hans de Goede <j.w.r.degoede@xxxxxx>
+# (C) 2008 Hans de Goede <hdegoede@xxxxxxxxxx>

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/libv4l-0.6.0/include/libv4l2.h
new/libv4l-0.6.1/include/libv4l2.h
--- old/libv4l-0.6.0/include/libv4l2.h 2009-06-12 10:41:33.000000000 +0200
+++ new/libv4l-0.6.1/include/libv4l2.h 2009-09-01 10:02:27.000000000 +0200
@@ -1,5 +1,5 @@
/*
-# (C) 2008 Hans de Goede <j.w.r.degoede@xxxxxx>
+# (C) 2008 Hans de Goede <hdegoede@xxxxxxxxxx>

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
@@ -51,6 +51,13 @@
Note the device name passed to v4l2_open must be of a video4linux2 device,
if it is anything else (including a video4linux1 device), v4l2_open will
fail.
+
+ Note that the argument to v4l2_ioctl after the request must be a valid
+ memory address of structure of the appropriate type for the request (for
+ v4l2 requests which expect a structure address). Passing in NULL or an
+ invalid memory address will not lead to failure with errno being EFAULT,
+ as it would with a real ioctl, but will cause libv4l2 to break, and you
+ get to keep both pieces.
*/

LIBV4L_PUBLIC int v4l2_open (const char *file, int oflag, ...);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/libv4l-0.6.0/include/libv4lconvert.h
new/libv4l-0.6.1/include/libv4lconvert.h
--- old/libv4l-0.6.0/include/libv4lconvert.h 2009-06-02 14:38:18.000000000
+0200
+++ new/libv4l-0.6.1/include/libv4lconvert.h 2009-08-05 12:26:03.000000000
+0200
@@ -1,5 +1,5 @@
/*
-# (C) 2008 Hans de Goede <j.w.r.degoede@xxxxxx>
+# (C) 2008 Hans de Goede <hdegoede@xxxxxxxxxx>

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/libv4l-0.6.0/libv4l1/Makefile
new/libv4l-0.6.1/libv4l1/Makefile
--- old/libv4l-0.6.0/libv4l1/Makefile 2009-06-08 11:17:55.000000000 +0200
+++ new/libv4l-0.6.1/libv4l1/Makefile 2009-08-05 12:26:03.000000000 +0200
@@ -33,6 +33,10 @@
LIBDIR = $(PREFIX)/lib
endif

+ifeq ($(LIBSUBDIR),)
+LIBSUBDIR = libv4l
+endif
+
all: $(TARGETS)

-include $(V4L1_OBJS:.o=.d)
@@ -60,12 +64,12 @@
mkdir -p $(DESTDIR)$(LIBDIR)
install -m 644 $(V4L1_LIB) $(DESTDIR)$(LIBDIR)
else
- mkdir -p $(DESTDIR)$(LIBDIR)/libv4l
+ mkdir -p $(DESTDIR)$(LIBDIR)/$(LIBSUBDIR)
install -m 755 $(V4L1_LIB).$(LIB_RELEASE) $(DESTDIR)$(LIBDIR)
cd $(DESTDIR)$(LIBDIR) && \
ln -f -s $(V4L1_LIB).$(LIB_RELEASE) $(V4L1_LIB)
install -m 755 $(V4L1COMPAT).$(LIB_RELEASE) \
- $(DESTDIR)$(LIBDIR)/libv4l/$(V4L1COMPAT)
+ $(DESTDIR)$(LIBDIR)/$(LIBSUBDIR)/$(V4L1COMPAT)
endif
mkdir -p $(DESTDIR)$(LIBDIR)/pkgconfig
install -m 644 libv4l1.pc $(DESTDIR)$(LIBDIR)/pkgconfig
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/libv4l-0.6.0/libv4l1/libv4l1-priv.h
new/libv4l-0.6.1/libv4l1/libv4l1-priv.h
--- old/libv4l-0.6.0/libv4l1/libv4l1-priv.h 2009-06-02 14:38:18.000000000
+0200
+++ new/libv4l-0.6.1/libv4l1/libv4l1-priv.h 2009-08-05 12:26:03.000000000
+0200
@@ -1,5 +1,5 @@
/*
-# (C) 2008 Hans de Goede <j.w.r.degoede@xxxxxx>
+# (C) 2008 Hans de Goede <hdegoede@xxxxxxxxxx>

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/libv4l-0.6.0/libv4l1/libv4l1.c
new/libv4l-0.6.1/libv4l1/libv4l1.c
--- old/libv4l-0.6.0/libv4l1/libv4l1.c 2009-06-17 21:55:40.000000000 +0200
+++ new/libv4l-0.6.1/libv4l1/libv4l1.c 2009-08-05 12:26:03.000000000 +0200
@@ -1,7 +1,7 @@
/*
# libv4l1 userspace v4l1 api emulation for v4l2 devices

-# (C) 2008 Hans de Goede <j.w.r.degoede@xxxxxx>
+# (C) 2008 Hans de Goede <hdegoede@xxxxxxxxxx>

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/libv4l-0.6.0/libv4l1/log.c
new/libv4l-0.6.1/libv4l1/log.c
--- old/libv4l-0.6.0/libv4l1/log.c 2009-06-02 14:38:18.000000000 +0200
+++ new/libv4l-0.6.1/libv4l1/log.c 2009-08-05 12:26:03.000000000 +0200
@@ -1,5 +1,5 @@
/*
-# (C) 2008 Hans de Goede <j.w.r.degoede@xxxxxx>
+# (C) 2008 Hans de Goede <hdegoede@xxxxxxxxxx>

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/libv4l-0.6.0/libv4l1/v4l1compat.c
new/libv4l-0.6.1/libv4l1/v4l1compat.c
--- old/libv4l-0.6.0/libv4l1/v4l1compat.c 2009-06-02 14:42:33.000000000
+0200
+++ new/libv4l-0.6.1/libv4l1/v4l1compat.c 2009-08-05 12:26:03.000000000
+0200
@@ -2,7 +2,7 @@
# open/close/ioctl/mmap/munmap library call wrapper doing v4l1 api emulation
# for v4l2 devices

-# (C) 2008 Hans de Goede <j.w.r.degoede@xxxxxx>
+# (C) 2008 Hans de Goede <hdegoede@xxxxxxxxxx>

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/libv4l-0.6.0/libv4l2/Makefile
new/libv4l-0.6.1/libv4l2/Makefile
--- old/libv4l-0.6.0/libv4l2/Makefile 2009-06-08 11:17:55.000000000 +0200
+++ new/libv4l-0.6.1/libv4l2/Makefile 2009-08-05 12:26:03.000000000 +0200
@@ -33,6 +33,10 @@
LIBDIR = $(PREFIX)/lib
endif

+ifeq ($(LIBSUBDIR),)
+LIBSUBDIR = libv4l
+endif
+
all: $(TARGETS)

-include $(V4L2_OBJS:.o=.d)
@@ -60,12 +64,12 @@
mkdir -p $(DESTDIR)$(LIBDIR)
install -m 644 $(V4L2_LIB) $(DESTDIR)$(LIBDIR)
else
- mkdir -p $(DESTDIR)$(LIBDIR)/libv4l
+ mkdir -p $(DESTDIR)$(LIBDIR)/$(LIBSUBDIR)
install -m 755 $(V4L2_LIB).$(LIB_RELEASE) $(DESTDIR)$(LIBDIR)
cd $(DESTDIR)$(LIBDIR) && \
ln -f -s $(V4L2_LIB).$(LIB_RELEASE) $(V4L2_LIB)
install -m 755 $(V4L2CONVERT).$(LIB_RELEASE) \
- $(DESTDIR)$(LIBDIR)/libv4l/$(V4L2CONVERT)
+ $(DESTDIR)$(LIBDIR)/$(LIBSUBDIR)/$(V4L2CONVERT)
endif
mkdir -p $(DESTDIR)$(LIBDIR)/pkgconfig
install -m 644 libv4l2.pc $(DESTDIR)$(LIBDIR)/pkgconfig
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/libv4l-0.6.0/libv4l2/libv4l2-priv.h
new/libv4l-0.6.1/libv4l2/libv4l2-priv.h
--- old/libv4l-0.6.0/libv4l2/libv4l2-priv.h 2009-06-02 14:38:18.000000000
+0200
+++ new/libv4l-0.6.1/libv4l2/libv4l2-priv.h 2009-08-14 09:03:40.000000000
+0200
@@ -1,5 +1,5 @@
/*
-# (C) 2008 Hans de Goede <j.w.r.degoede@xxxxxx>
+# (C) 2008 Hans de Goede <hdegoede@xxxxxxxxxx>

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
@@ -80,6 +80,9 @@
int frame_queued; /* 1 status bit per frame */
/* mapping tracking of our fake (converting mmap) frame buffers */
unsigned char frame_map_count[V4L2_MAX_NO_FRAMES];
+ /* buffer when doing conversion and using read() for read() */
+ int readbuf_size;
+ unsigned char *readbuf;
};

/* From log.c */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/libv4l-0.6.0/libv4l2/libv4l2.c
new/libv4l-0.6.1/libv4l2/libv4l2.c
--- old/libv4l-0.6.0/libv4l2/libv4l2.c 2009-06-17 15:44:32.000000000 +0200
+++ new/libv4l-0.6.1/libv4l2/libv4l2.c 2009-08-20 11:41:15.000000000 +0200
@@ -1,5 +1,5 @@
/*
-# (C) 2008 Hans de Goede <j.w.r.degoede@xxxxxx>
+# (C) 2008 Hans de Goede <hdegoede@xxxxxxxxxx>

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
@@ -77,6 +77,7 @@
#define V4L2_SUPPORTS_READ 0x0800
#define V4L2_IS_UVC 0x1000
#define V4L2_STREAM_TOUCHED 0x2000
+#define V4L2_USE_READ_FOR_READ 0x4000

#define V4L2_MMAP_OFFSET_MAGIC 0xABCDEF00u

@@ -101,7 +102,7 @@
req.memory = V4L2_MEMORY_MMAP;
if ((result = SYS_IOCTL(devices[index].fd, VIDIOC_REQBUFS, &req)) < 0){
int saved_err = errno;
- V4L2_LOG_ERR("requesting %u buffers: %s\n", req.count, strerror(errno));
+ V4L2_LOG("warning reqbuf (%u) failed: %s\n", req.count, strerror(errno));
errno = saved_err;
return result;
}
@@ -305,6 +306,63 @@
return result;
}

+static int v4l2_read_and_convert(int index, unsigned char *dest, int dest_size)
+{
+ const int max_tries = 10;
+ int result, buf_size, tries = max_tries;
+
+ buf_size = devices[index].dest_fmt.fmt.pix.sizeimage;
+ buf_size = (buf_size + 8191) & ~8191;
+
+ if (devices[index].readbuf_size < buf_size) {
+ unsigned char *new_buf;
+
+ new_buf = realloc(devices[index].readbuf, buf_size);
+ if (!new_buf)
+ return -1;
+
+ devices[index].readbuf = new_buf;
+ devices[index].readbuf_size = buf_size;
+ }
+
+ do {
+ result = SYS_READ(devices[index].fd, devices[index].readbuf, buf_size);
+ if (result <= 0) {
+ if (result && errno != EAGAIN) {
+ int saved_err = errno;
+ V4L2_LOG_ERR("reading: %s\n", strerror(errno));
+ errno = saved_err;
+ }
+ return result;
+ }
+
+ result = v4lconvert_convert(devices[index].convert,
+ &devices[index].src_fmt, &devices[index].dest_fmt,
+ devices[index].readbuf, result, dest, dest_size);
+
+ if (result < 0) {
+ int saved_err = errno;
+
+ if(errno == EAGAIN)
+ V4L2_LOG("warning error while converting frame data: %s\n",
+ v4lconvert_get_error_message(devices[index].convert));
+ else
+ V4L2_LOG_ERR("converting / decoding frame data: %s\n",
+ v4lconvert_get_error_message(devices[index].convert));
+
+ errno = saved_err;
+ }
+ tries--;
+ } while (result < 0 && errno == EAGAIN && tries);
+
+ if (result < 0 && errno == EAGAIN) {
+ V4L2_LOG_ERR("got %d consecutive frame decode errors, last error: %s\n",
+ max_tries, v4lconvert_get_error_message(devices[index].convert));
+ }
+
+ return result;
+}
+
static int v4l2_queue_read_buffers(int index)
{
unsigned int i;
@@ -332,6 +390,11 @@
{
int result;

+ if ((devices[index].flags & V4L2_STREAMON) || devices[index].frame_queued) {
+ errno = EBUSY;
+ return -1;
+ }
+
if ((result = v4l2_request_read_buffers(index)))
return result;

@@ -528,6 +591,8 @@
devices[index].frame_map_count[i] = 0;
}
devices[index].frame_queued = 0;
+ devices[index].readbuf = NULL;
+ devices[index].readbuf_size = 0;

if (index >= devices_used)
devices_used = index + 1;
@@ -585,6 +650,9 @@
devices[index].convert_mmap_buf = MAP_FAILED;
}
v4lconvert_destroy(devices[index].convert);
+ free(devices[index].readbuf);
+ devices[index].readbuf = NULL;
+ devices[index].readbuf_size = 0;

/* Remove the fd from our list of managed fds before closing it, because as
soon as we've done the actual close the fd maybe returned by an open in
@@ -1070,7 +1138,6 @@
{
ssize_t result;
int index;
- struct v4l2_buffer buf;

if ((index = v4l2_get_index(fd)) == -1)
return SYS_READ(fd, dest, n);
@@ -1085,23 +1152,33 @@
goto leave;
}

- if (!(devices[index].flags & V4L2_STREAM_CONTROLLED_BY_READ)) {
- if ((devices[index].flags & V4L2_STREAMON) ||
- devices[index].frame_queued) {
- errno = EBUSY;
- result = -1;
- goto leave;
- }
+ /* Since we need to do conversion try to use mmap (streaming) mode under
+ the hood as that safes a memcpy for each frame read.
+
+ Note sometimes this will fail as some drivers (atleast gspca) do not allow
+ switching from read mode to mmap mode and they assume read() mode if a
+ select or poll() is done before any buffers are requested. So using mmap
+ mode under the hood will fail if a select() or poll() is done before the
+ first emulated read() call. */
+ if (!(devices[index].flags & V4L2_STREAM_CONTROLLED_BY_READ) &&
+ !(devices[index].flags & V4L2_USE_READ_FOR_READ)) {
if ((result = v4l2_activate_read_stream(index)))
- goto leave;
+ /* Activating mmap mode failed, use read() instead */
+ devices[index].flags |= V4L2_USE_READ_FOR_READ;
}

- buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- buf.memory = V4L2_MEMORY_MMAP;
- result = v4l2_dequeue_and_convert(index, &buf, dest, n);
+ if (devices[index].flags & V4L2_USE_READ_FOR_READ) {
+ result = v4l2_read_and_convert(index, dest, n);
+ } else {
+ struct v4l2_buffer buf;

- if (result >= 0)
- v4l2_queue_read_buffer(index, buf.index);
+ buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ buf.memory = V4L2_MEMORY_MMAP;
+ result = v4l2_dequeue_and_convert(index, &buf, dest, n);
+
+ if (result >= 0)
+ v4l2_queue_read_buffer(index, buf.index);
+ }

leave:
pthread_mutex_unlock(&devices[index].stream_lock);
@@ -1226,9 +1303,15 @@
{
struct v4l2_queryctrl qctrl = { .id = cid };
struct v4l2_control ctrl = { .id = cid };
- int result;
+ int index, result;
+
+ if ((index = v4l2_get_index(fd)) == -1) {
+ V4L2_LOG_ERR("v4l2_set_control called with invalid fd: %d\n", fd);
+ errno = EBADF;
+ return -1;
+ }

- if ((result = SYS_IOCTL(fd, VIDIOC_QUERYCTRL, &qctrl)))
+ if ((result = v4lconvert_vidioc_queryctrl(devices[index].convert, &qctrl)))
return result;

if (!(qctrl.flags & V4L2_CTRL_FLAG_DISABLED) &&
@@ -1239,7 +1322,7 @@
ctrl.value = (value * (qctrl.maximum - qctrl.minimum) + 32767) / 65535 +
qctrl.minimum;

- result = SYS_IOCTL(fd, VIDIOC_S_CTRL, &ctrl);
+ result = v4lconvert_vidioc_s_ctrl(devices[index].convert, &ctrl);
}

return result;
@@ -1249,14 +1332,21 @@
{
struct v4l2_queryctrl qctrl = { .id = cid };
struct v4l2_control ctrl = { .id = cid };
+ int index;
+
+ if ((index = v4l2_get_index(fd)) == -1) {
+ V4L2_LOG_ERR("v4l2_set_control called with invalid fd: %d\n", fd);
+ errno = EBADF;
+ return -1;
+ }

- if (SYS_IOCTL(fd, VIDIOC_QUERYCTRL, &qctrl))
+ if (v4lconvert_vidioc_queryctrl(devices[index].convert, &qctrl))
return 0;

if (qctrl.flags & V4L2_CTRL_FLAG_DISABLED)
return 0;

- if (SYS_IOCTL(fd, VIDIOC_G_CTRL, &ctrl))
+ if (v4lconvert_vidioc_g_ctrl(devices[index].convert, &ctrl))
return 0;

return ((ctrl.value - qctrl.minimum) * 65535 +
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/libv4l-0.6.0/libv4l2/v4l2convert.c
new/libv4l-0.6.1/libv4l2/v4l2convert.c
--- old/libv4l-0.6.0/libv4l2/v4l2convert.c 2009-06-02 14:38:18.000000000
+0200
+++ new/libv4l-0.6.1/libv4l2/v4l2convert.c 2009-08-05 12:26:03.000000000
+0200
@@ -3,7 +3,7 @@
# for v4l2 applications which want to be able to simply capture bgr24 / yuv420
# from v4l2 devices with more exotic frame formats.

-# (C) 2008 Hans de Goede <j.w.r.degoede@xxxxxx>
+# (C) 2008 Hans de Goede <hdegoede@xxxxxxxxxx>

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/libv4l-0.6.0/libv4lconvert/Makefile
new/libv4l-0.6.1/libv4lconvert/Makefile
--- old/libv4l-0.6.0/libv4lconvert/Makefile 2009-06-12 17:04:09.000000000
+0200
+++ new/libv4l-0.6.1/libv4lconvert/Makefile 2009-08-25 10:45:32.000000000
+0200
@@ -14,10 +14,10 @@

CONVERT_OBJS = libv4lconvert.o tinyjpeg.o sn9c10x.o sn9c20x.o pac207.o \
mr97310a.o flip.o crop.o jidctflt.o spca561-decompress.o \
- rgbyuv.o spca501.o sq905c.o bayer.o hm12.o helper.o \
+ rgbyuv.o sn9c2028-decomp.o spca501.o sq905c.o bayer.o hm12.o \
control/libv4lcontrol.o processing/libv4lprocessing.o \
processing/whitebalance.o processing/autogain.o \
- processing/gamma.o
+ processing/gamma.o helper.o
TARGETS = $(CONVERT_LIB) libv4lconvert.pc ov511-decomp ov518-decomp
INCLUDES = ../include/libv4lconvert.h

@@ -33,7 +33,11 @@
LIBDIR = $(PREFIX)/lib
endif

-override CPPFLAGS += -DLIBDIR=\"$(LIBDIR)\"
+ifeq ($(LIBSUBDIR),)
+LIBSUBDIR = libv4l
+endif
+
+override CPPFLAGS += -DLIBDIR=\"$(LIBDIR)\" -DLIBSUBDIR=\"$(LIBSUBDIR)\"

all: $(TARGETS)

@@ -55,7 +59,7 @@
install: all
mkdir -p $(DESTDIR)$(PREFIX)/include
install -p -m 644 $(INCLUDES) $(DESTDIR)$(PREFIX)/include
- mkdir -p $(DESTDIR)$(LIBDIR)/libv4l
+ mkdir -p $(DESTDIR)$(LIBDIR)/$(LIBSUBDIR)
ifeq ($(LINKTYPE),static)
install -m 644 $(CONVERT_LIB) $(DESTDIR)$(LIBDIR)
else
@@ -63,7 +67,7 @@
cd $(DESTDIR)$(LIBDIR) && \
ln -f -s $(CONVERT_LIB).$(LIB_RELEASE) $(CONVERT_LIB)
endif
- install -m 755 *-decomp $(DESTDIR)$(LIBDIR)/libv4l
+ install -m 755 *-decomp $(DESTDIR)$(LIBDIR)/$(LIBSUBDIR)
mkdir -p $(DESTDIR)$(LIBDIR)/pkgconfig
install -m 644 libv4lconvert.pc $(DESTDIR)$(LIBDIR)/pkgconfig

diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/libv4l-0.6.0/libv4lconvert/bayer.c
new/libv4l-0.6.1/libv4lconvert/bayer.c
--- old/libv4l-0.6.0/libv4lconvert/bayer.c 2009-03-11 13:10:02.000000000
+0100
+++ new/libv4l-0.6.1/libv4lconvert/bayer.c 2009-08-05 12:26:03.000000000
+0200
@@ -1,6 +1,6 @@
/*
* lib4lconvert, video4linux2 format conversion lib
- * (C) 2008 Hans de Goede <j.w.r.degoede@xxxxxx>
+ * (C) 2008 Hans de Goede <hdegoede@xxxxxxxxxx>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/libv4l-0.6.0/libv4lconvert/control/libv4lcontrol-priv.h
new/libv4l-0.6.1/libv4lconvert/control/libv4lcontrol-priv.h
--- old/libv4l-0.6.0/libv4lconvert/control/libv4lcontrol-priv.h 2009-06-21
23:29:48.000000000 +0200
+++ new/libv4l-0.6.1/libv4lconvert/control/libv4lcontrol-priv.h 2009-08-19
15:51:14.000000000 +0200
@@ -25,6 +25,7 @@
#define V4LCONTROL_SHM_SIZE 4096

#define V4LCONTROL_SUPPORTS_NEXT_CTRL 0x01
+#define V4LCONTROL_MEMORY_IS_MALLOCED 0x02

struct v4lcontrol_flags_info;

@@ -52,6 +53,11 @@
/* Some seldom used dmi strings (for notebooks with bogus info in the board
entries, but usefull info elsewhere). We keep this at the end as to not
polute the initalizers for the normal case. */
+ /* System (product) vendor / name */
+ const char *dmi_system_vendor;
+ const char *dmi_system_name;
+ /* Board and System versions */
+ const char *dmi_board_version;
const char *dmi_system_version;
};

diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/libv4l-0.6.0/libv4lconvert/control/libv4lcontrol.c
new/libv4l-0.6.1/libv4lconvert/control/libv4lcontrol.c
--- old/libv4l-0.6.0/libv4lconvert/control/libv4lcontrol.c 2009-07-09
10:59:01.000000000 +0200
+++ new/libv4l-0.6.1/libv4lconvert/control/libv4lcontrol.c 2009-09-01
09:57:39.000000000 +0200
@@ -28,6 +28,7 @@
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
+#include <pwd.h>
#include "libv4lcontrol.h"
#include "libv4lcontrol-priv.h"
#include "../libv4lsyscall-priv.h"
@@ -58,9 +59,7 @@
{ 0x093a, 0x2476, 0, NULL, NULL,
V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED|V4LCONTROL_WANTS_WB, 1500 },
/* Laptops */
- { 0x04f2, 0xb106, 0, "ASUSTeK Computer Inc. ", "N50Vn ",
- V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED },
- { 0x04f2, 0xb106, 0, "ASUSTeK Computer Inc. ", "N51Vg ",
+ { 0x04f2, 0xb012, 0, "ASUSTeK Computer Inc. ", "F7L ",
V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED },
{ 0x04f2, 0xb012, 0, "ASUSTeK Computer Inc. ", "F7SR ",
V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED },
@@ -70,33 +69,75 @@
V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED },
{ 0x04f2, 0xb012, 0, "ASUSTeK Computer Inc. ", "X55SV ",
V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED },
- /* These 2 PACKARD BELL's are Asus notebook in disguise */
+ /* These 3 PACKARD BELL's seem to be Asus notebook in disguise */
+ { 0x04f2, 0xb012, 0, "Packard Bell BV", "T32A ",
+ V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED },
{ 0x04f2, 0xb012, 0, "PACKARD BELL BV ", "EasyNote_BG45",
V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED },
{ 0x04f2, 0xb012, 0, "PACKARD BELL BV ", "EasyNote_BG46",
V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED },
+ { 0x04f2, 0xb036, 0, "ASUSTeK Computer Inc. ", "U6S ",
+ V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED },
+ { 0x04f2, 0xb036, 0, "ASUSTeK Computer Inc. ", "U6V ",
+ V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED },
{ 0x04f2, 0xb071, 0, "ASUSTeK Computer Inc. ", "K40IJ ",
V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED },
+ { 0x04f2, 0xb071, 0, "ASUSTeK Computer Inc. ", "K50IJ ",
+ V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED },
+ { 0x04f2, 0xb071, 0, "ASUSTeK Computer Inc. ", "K50IN ",
+ V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED },
+ { 0x04f2, 0xb071, 0, "ASUSTeK Computer Inc. ", "K70AB ",
+ V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED },
+ { 0x04f2, 0xb071, 0, "ASUSTeK Computer Inc. ", "K70IO ",
+ V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED },
{ 0x04f2, 0xb071, 0, "ASUSTeK Computer Inc. ", "N10J ",
V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED },
+ { 0x04f2, 0xb071, 0, "ASUSTeK Computer Inc. ", "N20A ",
+ V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED },
+ /* Note no whitespace padding for these 2 models, this is not a typo */
+ { 0x04f2, 0xb071, 0, "ASUSTeK Computer INC.", "K50AB",
+ V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED },
+ { 0x04f2, 0xb071, 0, "ASUSTeK Computer INC.", "N5051Tp",
+ V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED },
+ { 0x04f2, 0xb106, 0, "ASUSTeK Computer Inc. ", "N50Vc ",
+ V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED },
+ { 0x04f2, 0xb106, 0, "ASUSTeK Computer Inc. ", "N50Vn ",
+ V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED },
+ { 0x04f2, 0xb106, 0, "ASUSTeK Computer Inc. ", "N51Vf ",
+ V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED },
+ { 0x04f2, 0xb106, 0, "ASUSTeK Computer Inc. ", "N51Vg ",
+ V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED },
+ { 0x04f2, 0xb106, 0, "ASUSTeK Computer Inc. ", "N51Vn ",
+ V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED },
+ { 0x04f2, 0xb16b, 0, "ASUSTeK Computer Inc. ", "U80A ",
+ V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED },
/* Note no whitespace padding for board vendor, this is not a typo */
{ 0x064e, 0xa111, 0, "ASUSTeK Computer Inc.", "F5RL ",
V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED },
/* Another Asus laptop in disguise */
{ 0x064e, 0xa111, 0, "PEGATRON CORPORATION ", "F5SR ",
V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED },
+ { 0x064e, 0xa116, 0, "ASUSTeK Computer Inc. ", "N10Jb ",
+ V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED },
+ { 0x064e, 0xa116, 0, "ASUSTeK Computer Inc. ", "N10Jc ",
+ V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED },
{ 0x064e, 0xa116, 0, "ASUSTeK Computer Inc. ", "N20A ",
V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED },
+ { 0x064e, 0xa116, 0, "ASUSTeK Computer Inc. ", "X58LE ",
+ V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED },
{ 0x090c, 0xe370, 0, "ASUSTeK Computer Inc. ", "U6S ",
V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED },
{ 0x174f, 0x5a35, 0, "ASUSTeK Computer Inc. ", "F3Ke ",
V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED },
+ { 0x174f, 0x5a35, 0, "ASUSTeK Computer Inc. ", "F3Q ",
+ V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED },
{ 0x174f, 0x5a35, 0, "ASUSTeK Computer Inc. ", "F3Sa ",
V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED },
+ { 0x174f, 0x5a35, 0, "ASUSTeK Computer Inc. ", "F3Sg ",
+ V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED },
{ 0x174f, 0x5a35, 0, "ASUSTeK Computer Inc. ", "F3Sr ",
V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED },
- /* The G1S has been seen with 2 different board name strings */
- { 0x174f, 0x5a35, 0, "ASUSTeK Computer Inc. ", "G1S ",
+ { 0x174f, 0x5a35, 0, "ASUSTeK Computer Inc. ", "F5N ",
V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED },
{ 0x174f, 0x5a35, 0, "ASUSTeK Computer Inc. ", "G1S ",
V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED },
@@ -104,8 +145,14 @@
V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED },
{ 0x174f, 0x5a35, 0, "ASUSTeK Computer Inc. ", "G2S ",
V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED },
+ { 0x174f, 0xa311, 0, "ASUSTeK Computer Inc. ", "A3F ",
+ V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED },
+ { 0x5986, 0x0200, 0, "LENOVO", "SPEEDY ",
+ V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED, 0, NULL, NULL, NULL,
+ "Lenovo IdeaPad Y510" },
{ 0x5986, 0x0205, 0, "LENOVO", "Base Board Product Name",
- V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED, 0, "Lenovo IdeaPad U330" },
+ V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED, 0, NULL, NULL, NULL,
+ "Lenovo IdeaPad U330" },

/* Second: devices which should use some software processing by default */
/* Pac207 based devices */
@@ -116,6 +163,8 @@
/* Pac7302 based devices */
{ 0x093a, 0x2620, 0x0f, NULL, NULL,
V4LCONTROL_ROTATED_90_JPEG|V4LCONTROL_WANTS_WB },
+ { 0x06f8, 0x3009, 0, NULL, NULL,
+ V4LCONTROL_ROTATED_90_JPEG|V4LCONTROL_WANTS_WB },
/* Pac7311 based devices */
{ 0x093a, 0x2600, 0x0f, NULL, NULL, V4LCONTROL_WANTS_WB },
/* sq905 devices */
@@ -134,6 +183,33 @@

static const struct v4l2_queryctrl fake_controls[];

+static void v4lcontrol_get_dmi_string(const char *string, char *buf, int size)
+{
+ FILE *f;
+ char *s, sysfs_name[512];
+
+ snprintf(sysfs_name, sizeof(sysfs_name),
+ "/sys/class/dmi/id/%s", string);
+ f = fopen(sysfs_name, "r");
+ if (!f) {
+ /* Try again with a different sysfs path, not sure if this is needed
+ but we used to look under /sys/devices/virtual/dmi/id in older
+ libv4l versions, but this did not work with some kernels */
+ snprintf(sysfs_name, sizeof(sysfs_name),
+ "/sys/devices/virtual/dmi/id/%s", string);
+ f = fopen(sysfs_name, "r");
+ if (!f) {
+ buf[0] = 0;
+ return;
+ }
+ }
+
+ s = fgets(buf, size, f);
+ if (s)
+ s[strlen(s) - 1] = 0;
+ fclose(f);
+}
+
static void v4lcontrol_init_flags(struct v4lcontrol_data *data)
{
struct stat st;
@@ -141,9 +217,8 @@
char sysfs_name[512];
unsigned short vendor_id = 0;
unsigned short product_id = 0;
- char dmi_board_vendor[512] = "";
- char dmi_board_name[512]= "";
- char dmi_system_version[512]= "";
+ char dmi_system_vendor[512], dmi_system_name[512], dmi_system_version[512];
+ char dmi_board_vendor[512], dmi_board_name[512], dmi_board_version[512];
int i, minor;
char c, *s, buf[32];
struct v4l2_input input;
@@ -222,41 +297,39 @@
return; /* Should never happen */
}

- /* Get DMI board vendor and name */
- f = fopen("/sys/devices/virtual/dmi/id/board_vendor", "r");
- if (f) {
- s = fgets(dmi_board_vendor, sizeof(dmi_board_vendor), f);
- if (s)
- s[strlen(s) - 1] = 0;
- fclose(f);
- }
-
- f = fopen("/sys/devices/virtual/dmi/id/board_name", "r");
- if (f) {
- s = fgets(dmi_board_name, sizeof(dmi_board_name), f);
- if (s)
- s[strlen(s) - 1] = 0;
- fclose(f);
- }
-
- f = fopen("/sys/devices/virtual/dmi/id/product_version", "r");
- if (f) {
- s = fgets(dmi_system_version, sizeof(dmi_system_version), f);
- if (s)
- s[strlen(s) - 1] = 0;
- fclose(f);
- }
+ /* Get DMI board and system strings */
+ v4lcontrol_get_dmi_string("sys_vendor", dmi_system_vendor,
+ sizeof(dmi_system_vendor));
+ v4lcontrol_get_dmi_string("product_name", dmi_system_name,
+ sizeof(dmi_system_name));
+ v4lcontrol_get_dmi_string("product_version", dmi_system_version,
+ sizeof(dmi_system_version));
+
+ v4lcontrol_get_dmi_string("board_vendor", dmi_board_vendor,
+ sizeof(dmi_board_vendor));
+ v4lcontrol_get_dmi_string("board_name", dmi_board_name,
+ sizeof(dmi_board_name));
+ v4lcontrol_get_dmi_string("board_version", dmi_board_version,
+ sizeof(dmi_board_version));

for (i = 0; i < ARRAY_SIZE(v4lcontrol_flags); i++)
if (v4lcontrol_flags[i].vendor_id == vendor_id &&
v4lcontrol_flags[i].product_id ==
(product_id & ~v4lcontrol_flags[i].product_mask) &&
+
+ (v4lcontrol_flags[i].dmi_system_vendor == NULL ||
+ !strcmp(v4lcontrol_flags[i].dmi_system_vendor, dmi_system_vendor)) &&
+ (v4lcontrol_flags[i].dmi_system_name == NULL ||
+ !strcmp(v4lcontrol_flags[i].dmi_system_name, dmi_system_name)) &&
+ (v4lcontrol_flags[i].dmi_system_version == NULL ||
+ !strcmp(v4lcontrol_flags[i].dmi_system_version, dmi_system_version)) &&
+
(v4lcontrol_flags[i].dmi_board_vendor == NULL ||
!strcmp(v4lcontrol_flags[i].dmi_board_vendor, dmi_board_vendor)) &&
(v4lcontrol_flags[i].dmi_board_name == NULL ||
!strcmp(v4lcontrol_flags[i].dmi_board_name, dmi_board_name)) &&
- (v4lcontrol_flags[i].dmi_system_version == NULL ||
- !strcmp(v4lcontrol_flags[i].dmi_system_version, dmi_system_version))) {
+ (v4lcontrol_flags[i].dmi_board_version == NULL ||
+ !strcmp(v4lcontrol_flags[i].dmi_board_version, dmi_board_version))) {
data->flags |= v4lcontrol_flags[i].flags;
data->flags_info = &v4lcontrol_flags[i];
break;
@@ -267,14 +340,17 @@
{
int shm_fd;
int i, rc, init = 0;
- char *s, shm_name[256];
+ char *s, shm_name[256], pwd_buf[1024];
struct v4l2_capability cap;
struct v4l2_queryctrl ctrl;
+ struct passwd pwd, *pwd_p;

struct v4lcontrol_data *data = calloc(1, sizeof(struct v4lcontrol_data));

- if (!data)
+ if (!data) {
+ fprintf(stderr, "libv4lcontrol: error: out of memory!\n");
return NULL;
+ }

data->fd = fd;

@@ -310,8 +386,19 @@
if (data->controls == 0)
return data; /* No need to create a shared memory segment */

- SYS_IOCTL(fd, VIDIOC_QUERYCAP, &cap);
- snprintf(shm_name, 256, "/%s:%s", cap.bus_info, cap.card);
+ if (SYS_IOCTL(fd, VIDIOC_QUERYCAP, &cap)) {
+ perror("libv4lcontrol: error querying device capabilities");
+ goto error;
+ }
+
+ if (getpwuid_r(geteuid(), &pwd, pwd_buf, sizeof(pwd_buf), &pwd_p) == 0) {
+ snprintf(shm_name, 256, "/libv4l-%s:%s:%s", pwd.pw_name,
+ cap.bus_info, cap.card);
+ } else {
+ perror("libv4lcontrol: error getting username using uid instead");
+ snprintf(shm_name, 256, "/libv4l-%lu:%s:%s", (unsigned long)geteuid(),
+ cap.bus_info, cap.card);
+ }

/* / is not allowed inside shm names */
for (i = 1; shm_name[i]; i++)
@@ -322,23 +409,41 @@
if ((shm_fd = shm_open(shm_name, (O_CREAT | O_EXCL | O_RDWR),
(S_IREAD | S_IWRITE))) >= 0)
init = 1;
- else if ((shm_fd = shm_open(shm_name, O_RDWR, (S_IREAD | S_IWRITE))) < 0)
- goto error;
-
- /* Set the shared memory size */
- ftruncate(shm_fd, V4LCONTROL_SHM_SIZE);
+ else
+ shm_fd = shm_open(shm_name, O_RDWR, (S_IREAD | S_IWRITE));

- /* Retreive a pointer to the shm object */
- data->shm_values = mmap(NULL, V4LCONTROL_SHM_SIZE, (PROT_READ | PROT_WRITE),
- MAP_SHARED, shm_fd, 0);
- close(shm_fd);
+ if (shm_fd >= 0) {
+ /* Set the shared memory size */
+ ftruncate(shm_fd, V4LCONTROL_SHM_SIZE);
+
+ /* Retreive a pointer to the shm object */
+ data->shm_values = mmap(NULL, V4LCONTROL_SHM_SIZE, (PROT_READ |
PROT_WRITE),
+ MAP_SHARED, shm_fd, 0);
+ close(shm_fd);
+
+ if (data->shm_values == MAP_FAILED) {
+ perror("libv4lcontrol: error shm mmap failed");
+ data->shm_values = NULL;
+ }
+ } else
+ perror("libv4lcontrol: error creating shm segment failed");

- if (data->shm_values == MAP_FAILED)
- goto error;
+ /* Fall back to malloc */
+ if (data->shm_values == NULL) {
+ fprintf(stderr,
+ "libv4lcontrol: falling back to malloc-ed memory for controls\n");
+ data->shm_values = malloc(V4LCONTROL_SHM_SIZE);
+ if (!data->shm_values) {
+ fprintf(stderr, "libv4lcontrol: error: out of memory!\n");
+ goto error;
+ }
+ init = 1;
+ data->priv_flags |= V4LCONTROL_MEMORY_IS_MALLOCED;
+ }

if (init) {
/* Initialize the new shm object we created */
- memset(data->shm_values, 0, sizeof(V4LCONTROL_SHM_SIZE));
+ memset(data->shm_values, 0, V4LCONTROL_SHM_SIZE);

for (i = 0; i < V4LCONTROL_COUNT; i++)
data->shm_values[i] = fake_controls[i].default_value;
@@ -359,12 +464,15 @@

void v4lcontrol_destroy(struct v4lcontrol_data *data)
{
- if (data->controls)
- munmap(data->shm_values, V4LCONTROL_SHM_SIZE);
+ if (data->controls) {
+ if (data->priv_flags & V4LCONTROL_MEMORY_IS_MALLOCED)
+ free(data->shm_values);
+ else
+ munmap(data->shm_values, V4LCONTROL_SHM_SIZE);
+ }
free(data);
}

-/* FIXME get better CID's for normalize */
static const struct v4l2_queryctrl fake_controls[V4LCONTROL_COUNT] = {
{
.id = V4L2_CID_AUTO_WHITE_BALANCE,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/libv4l-0.6.0/libv4lconvert/crop.c
new/libv4l-0.6.1/libv4lconvert/crop.c
--- old/libv4l-0.6.0/libv4lconvert/crop.c 2009-06-16 23:56:45.000000000
+0200
+++ new/libv4l-0.6.1/libv4lconvert/crop.c 2009-08-05 12:26:03.000000000
+0200
@@ -2,7 +2,7 @@

# RGB and YUV crop routines

-# (C) 2008 Hans de Goede <j.w.r.degoede@xxxxxx>
+# (C) 2008 Hans de Goede <hdegoede@xxxxxxxxxx>

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/libv4l-0.6.0/libv4lconvert/flip.c
new/libv4l-0.6.1/libv4lconvert/flip.c
--- old/libv4l-0.6.0/libv4lconvert/flip.c 2009-05-19 20:37:12.000000000
+0200
+++ new/libv4l-0.6.1/libv4lconvert/flip.c 2009-08-05 12:26:03.000000000
+0200
@@ -2,7 +2,7 @@

# RGB / YUV flip/rotate routines

-# (C) 2008 Hans de Goede <j.w.r.degoede@xxxxxx>
+# (C) 2008 Hans de Goede <hdegoede@xxxxxxxxxx>

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
@@ -219,6 +219,7 @@
fmt->fmt.pix.height);
break;
}
+ v4lconvert_fixup_fmt(fmt);
}

void v4lconvert_flip(unsigned char *src, unsigned char *dest,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/libv4l-0.6.0/libv4lconvert/libv4lconvert-priv.h
new/libv4l-0.6.1/libv4lconvert/libv4lconvert-priv.h
--- old/libv4l-0.6.0/libv4lconvert/libv4lconvert-priv.h 2009-07-09
11:57:42.000000000 +0200
+++ new/libv4l-0.6.1/libv4lconvert/libv4lconvert-priv.h 2009-08-31
16:38:15.000000000 +0200
@@ -1,5 +1,5 @@
/*
-# (C) 2008 Hans de Goede <j.w.r.degoede@xxxxxx>
+# (C) 2008 Hans de Goede <hdegoede@xxxxxxxxxx>

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
@@ -52,6 +52,10 @@
#define V4L2_PIX_FMT_MR97310A v4l2_fourcc('M','3','1','0')
#endif

+#ifndef V4L2_PIX_FMT_SN9C2028
+#define V4L2_PIX_FMT_SN9C2028 v4l2_fourcc('S', 'O', 'N', 'X')
+#endif
+
#ifndef V4L2_PIX_FMT_SQ905C
#define V4L2_PIX_FMT_SQ905C v4l2_fourcc('9', '0', '5', 'C')
#endif
@@ -92,6 +96,10 @@
#define V4L2_PIX_FMT_OV518 v4l2_fourcc('O', '5', '1', '8') /* ov518 JPEG */
#endif

+#ifndef V4L2_FMT_FLAG_EMULATED
+#define V4L2_FMT_FLAG_EMULATED 0x0002
+#endif
+
#define ARRAY_SIZE(x) ((int)sizeof(x)/(int)sizeof((x)[0]))

#define V4LCONVERT_ERROR_MSG_SIZE 256
@@ -108,6 +116,7 @@
/* Pixformat flags */
#define V4LCONVERT_COMPRESSED 0x01 /* Compressed format */
#define V4LCONVERT_NEEDS_CONVERSION 0x02 /* Apps likely wont know this */
+#define V4LCONVERT_COMPRESSED_AND_NEEDS_CONVERSION 0x03

struct v4lconvert_data {
int fd;
@@ -218,6 +227,9 @@
void v4lconvert_decode_mr97310a(const unsigned char *src, unsigned char *dst,
int width, int height);

+void v4lconvert_decode_sn9c2028(const unsigned char *src, unsigned char *dst,
+ int width, int height);
+
void v4lconvert_decode_sq905c(const unsigned char *src, unsigned char *dst,
int width, int height);

diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/libv4l-0.6.0/libv4lconvert/libv4lconvert.c
new/libv4l-0.6.1/libv4lconvert/libv4lconvert.c
--- old/libv4l-0.6.0/libv4lconvert/libv4lconvert.c 2009-07-09
14:11:01.000000000 +0200
+++ new/libv4l-0.6.1/libv4lconvert/libv4lconvert.c 2009-08-31
16:38:23.000000000 +0200
@@ -1,5 +1,5 @@
/*
-# (C) 2008 Hans de Goede <j.w.r.degoede@xxxxxx>
+# (C) 2008 Hans de Goede <hdegoede@xxxxxxxxxx>

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
@@ -58,14 +58,15 @@
{ V4L2_PIX_FMT_HM12, V4LCONVERT_NEEDS_CONVERSION },
{ V4L2_PIX_FMT_MJPEG, V4LCONVERT_COMPRESSED },
{ V4L2_PIX_FMT_JPEG, V4LCONVERT_COMPRESSED },
- { V4L2_PIX_FMT_SPCA561, V4LCONVERT_COMPRESSED },
- { V4L2_PIX_FMT_SN9C10X, V4LCONVERT_COMPRESSED },
- { V4L2_PIX_FMT_PAC207, V4LCONVERT_COMPRESSED },
- { V4L2_PIX_FMT_MR97310A, V4LCONVERT_COMPRESSED },
- { V4L2_PIX_FMT_SQ905C, V4LCONVERT_COMPRESSED },
- { V4L2_PIX_FMT_PJPG, V4LCONVERT_COMPRESSED },
- { V4L2_PIX_FMT_OV511, V4LCONVERT_COMPRESSED },
- { V4L2_PIX_FMT_OV518, V4LCONVERT_COMPRESSED },
+ { V4L2_PIX_FMT_SPCA561, V4LCONVERT_COMPRESSED_AND_NEEDS_CONVERSION },
+ { V4L2_PIX_FMT_SN9C10X, V4LCONVERT_COMPRESSED_AND_NEEDS_CONVERSION },
+ { V4L2_PIX_FMT_SN9C2028, V4LCONVERT_COMPRESSED_AND_NEEDS_CONVERSION },
+ { V4L2_PIX_FMT_PAC207, V4LCONVERT_COMPRESSED_AND_NEEDS_CONVERSION },
+ { V4L2_PIX_FMT_MR97310A, V4LCONVERT_COMPRESSED_AND_NEEDS_CONVERSION },
+ { V4L2_PIX_FMT_SQ905C, V4LCONVERT_COMPRESSED_AND_NEEDS_CONVERSION },
+ { V4L2_PIX_FMT_PJPG, V4LCONVERT_COMPRESSED_AND_NEEDS_CONVERSION },
+ { V4L2_PIX_FMT_OV511, V4LCONVERT_COMPRESSED_AND_NEEDS_CONVERSION },
+ { V4L2_PIX_FMT_OV518, V4LCONVERT_COMPRESSED_AND_NEEDS_CONVERSION },
};

static const struct v4lconvert_pixfmt supported_dst_pixfmts[] = {
@@ -95,8 +96,10 @@
processing controls without a performance impact. */
int always_needs_conversion = 1;

- if (!data)
+ if (!data) {
+ fprintf(stderr, "libv4lconvert: error: out of memory!\n");
return NULL;
+ }

data->fd = fd;
data->decompress_pid = -1;
@@ -114,7 +117,7 @@
if (fmt.pixelformat == supported_src_pixfmts[j].fmt) {
data->supported_src_formats |= 1 << j;
v4lconvert_get_framesizes(data, fmt.pixelformat, j);
- if (!supported_src_pixfmts[j].flags)
+ if (!(supported_src_pixfmts[j].flags & V4LCONVERT_NEEDS_CONVERSION))
always_needs_conversion = 0;
break;
}
@@ -216,7 +219,7 @@
return -1;
}

- fmt->flags = 0;
+ fmt->flags = V4L2_FMT_FLAG_EMULATED;
fmt->pixelformat = faked_fmts[i];
fmt->description[0] = faked_fmts[i] & 0xff;
fmt->description[1] = (faked_fmts[i] >> 8) & 0xff;
@@ -491,6 +494,7 @@
case V4L2_PIX_FMT_SN9C10X:
case V4L2_PIX_FMT_PAC207:
case V4L2_PIX_FMT_MR97310A:
+ case V4L2_PIX_FMT_SN9C2028:
case V4L2_PIX_FMT_SQ905C:
case V4L2_PIX_FMT_SBGGR8:
case V4L2_PIX_FMT_SGBRG8:
@@ -672,7 +676,7 @@
v4lconvert_sn9c20x_to_yuv420(src, d, width, height, yvu);
break;
case V4L2_PIX_FMT_OV511:
- if (v4lconvert_helper_decompress(data, LIBDIR "/libv4l/ov511-decomp",
+ if (v4lconvert_helper_decompress(data, LIBDIR "/" LIBSUBDIR
"/ov511-decomp",
src, src_size, d, d_size, width, height, yvu)) {
/* Corrupt frame, better get another one */
errno = EAGAIN;
@@ -680,7 +684,7 @@
}
break;
case V4L2_PIX_FMT_OV518:
- if (v4lconvert_helper_decompress(data, LIBDIR "/libv4l/ov518-decomp",
+ if (v4lconvert_helper_decompress(data, LIBDIR "/" LIBSUBDIR
"/ov518-decomp",
src, src_size, d, d_size, width, height, yvu)) {
/* Corrupt frame, better get another one */
errno = EAGAIN;
@@ -725,6 +729,7 @@
case V4L2_PIX_FMT_SN9C10X:
case V4L2_PIX_FMT_PAC207:
case V4L2_PIX_FMT_MR97310A:
+ case V4L2_PIX_FMT_SN9C2028:
case V4L2_PIX_FMT_SQ905C:
{
unsigned char *tmpbuf;
@@ -757,6 +762,10 @@
v4lconvert_decode_mr97310a(src, tmpbuf, width, height);
tmpfmt.fmt.pix.pixelformat = V4L2_PIX_FMT_SBGGR8;
break;
+ case V4L2_PIX_FMT_SN9C2028:
+ v4lconvert_decode_sn9c2028(src, tmpbuf, width, height);
+ tmpfmt.fmt.pix.pixelformat = V4L2_PIX_FMT_SBGGR8;
+ break;
case V4L2_PIX_FMT_SQ905C:
v4lconvert_decode_sq905c(src, tmpbuf, width, height);
tmpfmt.fmt.pix.pixelformat = V4L2_PIX_FMT_SRGGB8;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/libv4l-0.6.0/libv4lconvert/processing/libv4lprocessing.c
new/libv4l-0.6.1/libv4lconvert/processing/libv4lprocessing.c
--- old/libv4l-0.6.0/libv4lconvert/processing/libv4lprocessing.c
2009-06-24 14:00:32.000000000 +0200
+++ new/libv4l-0.6.1/libv4lconvert/processing/libv4lprocessing.c
2009-08-19 15:56:44.000000000 +0200
@@ -38,8 +38,10 @@
struct v4lprocessing_data *data =
calloc(1, sizeof(struct v4lprocessing_data));

- if (!data)
+ if (!data) {
+ fprintf(stderr, "libv4lprocessing: error: out of memory!\n");
return NULL;
+ }

data->fd = fd;
data->control = control;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/libv4l-0.6.0/libv4lconvert/rgbyuv.c
new/libv4l-0.6.1/libv4lconvert/rgbyuv.c
--- old/libv4l-0.6.0/libv4lconvert/rgbyuv.c 2009-07-03 08:33:15.000000000
+0200
+++ new/libv4l-0.6.1/libv4lconvert/rgbyuv.c 2009-08-05 12:26:03.000000000
+0200
@@ -1,7 +1,7 @@
/*

# RGB <-> YUV conversion routines
-# (C) 2008 Hans de Goede <j.w.r.degoede@xxxxxx>
+# (C) 2008 Hans de Goede <hdegoede@xxxxxxxxxx>

# RGB565 conversion routines
# (C) 2009 Mauro Carvalho Chehab <mchehab@xxxxxxxxxx>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/libv4l-0.6.0/libv4lconvert/sn9c2028-decomp.c
new/libv4l-0.6.1/libv4lconvert/sn9c2028-decomp.c
--- old/libv4l-0.6.0/libv4lconvert/sn9c2028-decomp.c 1970-01-01
01:00:00.000000000 +0100
+++ new/libv4l-0.6.1/libv4lconvert/sn9c2028-decomp.c 2009-08-25
10:41:19.000000000 +0200
@@ -0,0 +1,157 @@
+/*
+ * sn9c2028-decomp.c
+ *
+ * Decompression function for the Sonix SN9C2028 dual-mode cameras.
+ *
+ * Code adapted from libgphoto2/camlibs/sonix, original version of which was
+ * Copyright (c) 2005 Theodore Kilgore <kilgota@xxxxxxxxxx>
+ *
+ * History:
+ *
+ * This decoding algorithm originates from the work of Bertrik Sikken for the
+ * SN9C102 cameras. This version is an adaptation of work done by Mattias
+ * Krauss for the webcam-osx (macam) project. There, it was further adapted
+ * for use with the Vivitar Vivicam 3350B (an SN9C2028 camera) by
+ * Harald Ruda <hrx@xxxxxxxxxxxxxxxxxxxxx>. Harald brought to my attention the
+ * work done in the macam project and suggested that I use it. One improvement
+ * of my own was to notice that the even and odd columns of the image have been
+ * reversed by the decompression algorithm, and this needs to be corrected
+ * during the decompression.
+ *
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "libv4lconvert-priv.h"
+
+/* Four defines for bitstream operations, used in the decode function */
+
+#define PEEK_BITS(num,to) {\
+ if (bitBufCount < num) {\
+ do {\
+ bitBuf = (bitBuf << 8)|(*(src++));\
+ bitBufCount += 8; \
+ } \
+ while\
+ (bitBufCount < 24);\
+ } \
+ to = bitBuf >> (bitBufCount-num);\
+}
+
+/*
+ * PEEK_BITS puts the next <num> bits into the low bits of <to>.
+ * when the buffer is empty, it is completely refilled.
+ * This strategy tries to reduce memory access. Note that the high bits
+ * are NOT set to zero!
+ */
+
+#define EAT_BITS(num) { bitBufCount -= num; bits_eaten += num; }
+
+/*
+ * EAT_BITS consumes <num> bits (PEEK_BITS does not consume anything,
+ * it just peeks)
+ */
+
+#define PARSE_PIXEL(val) {\
+ PEEK_BITS(10, bits);\
+ if ((bits&0x200) == 0) {\
+ EAT_BITS(1);\
+ } \
+ else if ((bits&0x380) == 0x280) {\
+ EAT_BITS(3);\
+ val += 3;\
+ if (val > 255)\
+ val = 255;\
+ } \
+ else if ((bits&0x380) == 0x300) {\
+ EAT_BITS(3);\
+ val -= 3;\
+ if (val < 0)\
+ val = 0;\
+ } \
+ else if ((bits&0x3c0) == 0x200) {\
+ EAT_BITS(4);\
+ val += 8;\
+ if (val > 255)\
+ val = 255;\
+ } \
+ else if ((bits&0x3c0) == 0x240) {\
+ EAT_BITS(4);\
+ val -= 8;\
+ if (val < 0)\
+ val = 0;\
+ } \
+ else if ((bits&0x3c0) == 0x3c0) {\
+ EAT_BITS(4);\
+ val -= 20;\
+ if (val < 0)\
+ val = 0;\
+ } \
+ else if ((bits&0x3e0) == 0x380) {\
+ EAT_BITS(5);\
+ val += 20;\
+ if (val > 255)\
+ val = 255;\
+ } \
+ else {\
+ EAT_BITS(10);\
+ val = 8*(bits&0x1f)+0;\
+ } \
+}
+
+
+#define PUT_PIXEL_PAIR {\
+ long pp;\
+ pp = (c1val<<8)+c2val;\
+ *((unsigned short *) (dst+dst_index)) = pp;\
+ dst_index += 2;\
+}
+
+/* Now the decode function itself */
+
+void v4lconvert_decode_sn9c2028(const unsigned char *src, unsigned char *dst,
+ int width, int height)
+{
+ long dst_index = 0;
+ int starting_row = 0;
+ unsigned short bits;
+ short c1val, c2val;
+ int x, y;
+ unsigned long bitBuf = 0;
+ unsigned long bitBufCount = 0;
+ unsigned long bits_eaten = 0;
+
+ src += 12; /* Remove the header */
+
+ for (y = starting_row; y < height; y++) {
+ PEEK_BITS(8, bits);
+ EAT_BITS(8);
+ c2val = (bits & 0xff);
+ PEEK_BITS(8, bits);
+ EAT_BITS(8);
+ c1val = (bits & 0xff);
+
+ PUT_PIXEL_PAIR;
+
+ for (x = 2; x < width ; x += 2) {
+ /* The compression reversed the even and odd columns.*/
+ PARSE_PIXEL(c2val);
+ PARSE_PIXEL(c1val);
+ PUT_PIXEL_PAIR;
+ }
+ }
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/libv4l-0.6.0/libv4lconvert/spca501.c
new/libv4l-0.6.1/libv4lconvert/spca501.c
--- old/libv4l-0.6.0/libv4lconvert/spca501.c 2009-03-11 13:10:02.000000000
+0100
+++ new/libv4l-0.6.1/libv4lconvert/spca501.c 2009-08-05 12:26:03.000000000
+0200
@@ -1,5 +1,5 @@
/*
-# (C) 2008 Hans de Goede <j.w.r.degoede@xxxxxx>
+# (C) 2008 Hans de Goede <hdegoede@xxxxxxxxxx>

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by


++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++



Remember to have fun...

--
To unsubscribe, e-mail: opensuse-commit+unsubscribe@xxxxxxxxxxxx
For additional commands, e-mail: opensuse-commit+help@xxxxxxxxxxxx

< Previous Next >
This Thread
  • No further messages