Webcam recommendations
Andrey V. Elsukov
bu7cher at yandex.ru
Mon Mar 21 15:24:21 UTC 2011
On 21.03.2011 15:01, Hans Petter Selasky wrote:
> Looks like I was too quick about that. Anyway, maybe you could bother to add
> some prints in:
>
> v4l-dvb/linux/drivers/media/video/v4l2-ioctl.c
>
> Because the V4l1 -> V4L2 translation should already be in place.
Hi,
After some time of reading code i understand several things.
webcamd contains a bunch of linux kernel drivers. Also any freebsd's
application can use v4l1 and v4l2 with /dev/videoX, but linux's
binaries can not. They can only use v4l1, because linux.ko supports
only v4l1. Anyway webcamd has some v4l1 to v4l2 translation inside.
But it does not work for my UVC webcam (translation works, but camera
does not) :(
I have not any linux host where i can test my webcam, but i think it
will not work with skype out of the box in linux too. But it seems
linux users can try LD_PRELOAD with libv4l's libraries (v4l1compat.so
or v4l2convert.so). We can not, because we does not have V4L2 support
in linux.ko.
I added these two patches to webcamd port, they enable addition debug.
Also i enabled debug in libcuse4bsd.
When i run skype i have in log:
cuse4bsd: Command = open, flags = 3, arg = 0x00000000, ptr = 0x00000000
uvcvideo: uvc_v4l2_open
cuse4bsd: Command error = 0
cuse4bsd: Command = ioctl, flags = 7, arg = 0x40047601, ptr = 0x00010000
uvcvideo: uvc_v4l2_ioctl(VIDIOCGCAP)
uvcvideo: Unknown ioctl 0x40047601
cuse4bsd: Command error = -3
it seems there skype calls iotctl(VIDOCGCAP) with incorrect argument's
size = 0x04.
cuse4bsd: Command = ioctl, flags = 7, arg = 0x403c7601, ptr = 0x00010000
uvcvideo: uvc_v4l2_ioctl(VIDIOCGCAP)
uvcvideo: Trying format 0x56595559 (YUYV): 10000x10000.
uvcvideo: Using default frame interval 111111.1 us (9.0 fps).
cuse4bsd: copy_out(0x7fffff1f8cf0,0x10000,60), cmd = 5
cuse4bsd: Command error = 0
But second call is correct.
cuse4bsd: Command = close, flags = 3, arg = 0x00000000, ptr = 0x00000000
uvcvideo: uvc_v4l2_release
cuse4bsd: Command error = 0
Now i'm trying to test video in skype's preferences:
cuse4bsd: Command = open, flags = 3, arg = 0x00000000, ptr = 0x00000000
uvcvideo: uvc_v4l2_open
cuse4bsd: Command error = 0
cuse4bsd: Command = ioctl, flags = 7, arg = 0x40047601, ptr = 0x00010000
uvcvideo: uvc_v4l2_ioctl(VIDIOCGCAP)
uvcvideo: Unknown ioctl 0x40047601
cuse4bsd: Command error = -3
cuse4bsd: Command = ioctl, flags = 7, arg = 0x403c7601, ptr = 0x00010000
uvcvideo: uvc_v4l2_ioctl(VIDIOCGCAP)
uvcvideo: Trying format 0x56595559 (YUYV): 10000x10000.
uvcvideo: Using default frame interval 111111.1 us (9.0 fps).
cuse4bsd: copy_out(0x7fffffffd4f0,0x10000,60), cmd = 5
cuse4bsd: Command error = 0
cuse4bsd: Command = ioctl, flags = 7, arg = 0x400e7606, ptr = 0x00010000
uvcvideo: uvc_v4l2_ioctl(VIDIOCGPICT)
cuse4bsd: copy_out(0x7fffff1f8cf0,0x10000,14), cmd = 5
cuse4bsd: Command error = 0
cuse4bsd: Command = ioctl, flags = 7, arg = 0x800e7607, ptr = 0x00010000
uvcvideo: uvc_v4l2_ioctl(VIDIOCSPICT)
cuse4bsd: copy_in(0x10000,0x7ffffeff7cf0,14), cmd = 5
uvcvideo: Trying format 0x32315559 (YU12): 160x120.
uvcvideo: Unsupported format 0x32315559.
v4l1-compat: VIDIOCSPICT / VIDIOC_S_FMT: -22
uvcvideo: Unknown ioctl 0x4030560a
v4l1-compat: VIDIOCSPICT / VIDIOC_G_FBUF: -513
cuse4bsd: Command error = -3
cuse4bsd: Command = ioctl, flags = 7, arg = 0x800e7607, ptr = 0x00010000
uvcvideo: uvc_v4l2_ioctl(VIDIOCSPICT)
cuse4bsd: copy_in(0x10000,0x7ffffebf5cf0,14), cmd = 5
uvcvideo: Unknown ioctl 0x4030560a
v4l1-compat: VIDIOCSPICT / VIDIOC_G_FBUF: -513
cuse4bsd: Command error = 0
cuse4bsd: Command = ioctl, flags = 7, arg = 0x40287609, ptr = 0x00010000
uvcvideo: uvc_v4l2_ioctl(VIDIOCGWIN)
v4l1-compat: VIDIOCGWIN / VIDIOC_G_WIN: -22
cuse4bsd: copy_out(0x7ffffedf6cf0,0x10000,40), cmd = 5
cuse4bsd: Command error = 0
cuse4bsd: Command = ioctl, flags = 7, arg = 0x8028760a, ptr = 0x00010000
uvcvideo: uvc_v4l2_ioctl(VIDIOCSWIN)
cuse4bsd: copy_in(0x10000,0x7fffffffd4f0,40), cmd = 5
uvcvideo: Trying format 0x56595559 (YUYV): 320x240.
uvcvideo: Using default frame interval 33333.3 us (30.0 fps).
v4l1-compat: VIDIOCSWIN / VIDIOC_S_FMT #2: -22
cuse4bsd: Command error = 0
cuse4bsd: Command = poll, flags = 7, arg = 0x00000005, ptr = 0x00000000
uvcvideo: uvc_v4l2_poll
cuse4bsd: Command error = 0
cuse4bsd: Command = poll, flags = 7, arg = 0x00000005, ptr = 0x00000000
uvcvideo: uvc_v4l2_poll
cuse4bsd: Command error = 0
So, as you can see v4l1-compat code works by default.
But camera does not. I looked to pwc driver code and try to reimplement
VIDIOCSPICT and VIDIOCSWIN iocts.
I just call v4l_compat_translate_ioctl and it it success i call
uvc_video_enable(), with this changes skype is able to turn on webcam,
but it still can not get any pictures. I need similar log from
working camera to understand what is needed skype to work with webcam.
--
WBR, Andrey V. Elsukov
-------------- next part --------------
--- v4l-dvb/linux/drivers/media/video/uvc/uvc_driver.c 2011-03-20 02:12:11.280845495 +0300
+++ v4l-dvb/linux/drivers/media/video/uvc/uvc_driver.c 2011-03-20 02:12:15.917841538 +0300
@@ -47,7 +47,7 @@
unsigned int uvc_clock_param = CLOCK_MONOTONIC;
unsigned int uvc_no_drop_param;
static unsigned int uvc_quirks_param = -1;
-unsigned int uvc_trace_param;
+unsigned int uvc_trace_param = UVC_TRACE_FORMAT | UVC_TRACE_CALLS | UVC_TRACE_IOCTL;
unsigned int uvc_timeout_param = UVC_CTRL_STREAMING_TIMEOUT;
/* ------------------------------------------------------------------------
-------------- next part --------------
--- v4l-dvb/linux/drivers/media/video/v4l1-compat.c.orig 2011-03-20 02:13:51.352845149 +0300
+++ v4l-dvb/linux/drivers/media/video/v4l1-compat.c 2011-03-20 02:14:00.641842493 +0300
@@ -37,7 +37,7 @@
#include <asm/pgtable.h>
#include "compat.h"
-static unsigned int debug;
+static unsigned int debug = 1;
module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "enable debug messages");
MODULE_AUTHOR("Bill Dirks");
-------------- next part --------------
--- cuse4bsd_lib.c.orig 2010-05-07 14:33:51.000000000 +0400
+++ cuse4bsd_lib.c 2011-03-21 18:08:42.486322494 +0300
@@ -43,7 +43,7 @@
#include "cuse4bsd.h"
-#if 0
+#if 1
#define CUSE4BSD_DEBUG
#endif
@@ -409,8 +409,12 @@ cuse_wait_and_process(void)
cuse_unlock();
#ifdef CUSE4BSD_DEBUG
- printf("Command = %d, flags = %d, arg = 0x%08x, ptr = 0x%08x\n",
- (int)info.command, (int)info.fflags,
+ const char *cmd[CUSE_CMD_MAX] = {
+ "none", "open", "close", "read", "write", "ioctl", "poll",
+ "signal", "sync"
+ };
+ printf("cuse4bsd: Command = %s, flags = %d, arg = 0x%08x, ptr = 0x%08x\n",
+ cmd[info.command], (int)info.fflags,
(int)info.argument, (int)info.data_pointer);
#endif
@@ -475,7 +479,7 @@ cuse_wait_and_process(void)
case CUSE_CMD_IOCTL:
if (cdev->mtod->cm_ioctl != NULL) {
error = (cdev->mtod->cm_ioctl) (cdev, (int)info.fflags,
- (unsigned long)info.argument, (void *)info.data_pointer);
+ (unsigned int)info.argument, (void *)info.data_pointer);
} else {
error = CUSE_ERR_INVALID;
}
@@ -506,7 +510,7 @@ cuse_wait_and_process(void)
}
#ifdef CUSE4BSD_DEBUG
- printf("Command error = %d\n", error);
+ printf("cuse4bsd: Command error = %d\n", error);
#endif
cuse_lock();
if (info.command < CUSE_CMD_MAX) {
@@ -612,7 +616,7 @@ cuse_copy_out(const void *src, void *use
return (CUSE_ERR_INVALID);
#ifdef CUSE4BSD_DEBUG
- printf("copy_out(%p,%p,%d), cmd = %d\n", src, user_dst, len, cmd);
+ printf("cuse4bsd: copy_out(%p,%p,%d), cmd = %d\n", src, user_dst, len, cmd);
#endif
if (cuse_dev_get_local(cdev, cmd)) {
memcpy(user_dst, src, len);
@@ -624,7 +628,7 @@ cuse_copy_out(const void *src, void *use
error = ioctl(f_cuse, CUSE_IOCTL_WRITE_DATA, &info);
if (error) {
#ifdef CUSE4BSD_DEBUG
- printf("copy_out() error = %d\n", errno);
+ printf("cuse4bsd: copy_out() error = %d\n", errno);
#endif
return (CUSE_ERR_FAULT);
}
@@ -649,7 +653,7 @@ cuse_copy_in(const void *user_src, void
return (CUSE_ERR_INVALID);
#ifdef CUSE4BSD_DEBUG
- printf("copy_in(%p,%p,%d), cmd = %d\n", user_src, dst, len, cmd);
+ printf("cuse4bsd: copy_in(%p,%p,%d), cmd = %d\n", user_src, dst, len, cmd);
#endif
if (cuse_dev_get_local(cdev, cmd)) {
memcpy(dst, user_src, len);
@@ -661,7 +665,7 @@ cuse_copy_in(const void *user_src, void
error = ioctl(f_cuse, CUSE_IOCTL_READ_DATA, &info);
if (error) {
#ifdef CUSE4BSD_DEBUG
- printf("copy_in() error = %d\n", errno);
+ printf("cuse4bsd: copy_in() error = %d\n", errno);
#endif
return (CUSE_ERR_FAULT);
}
More information about the freebsd-multimedia
mailing list