All of lore.kernel.org
 help / color / mirror / Atom feed
* hal, udev and video4linux probers
@ 2009-05-08 17:04 Filippo Argiolas
  2009-05-08 20:06 ` Kay Sievers
                   ` (9 more replies)
  0 siblings, 10 replies; 11+ messages in thread
From: Filippo Argiolas @ 2009-05-08 17:04 UTC (permalink / raw)
  To: linux-hotplug

Hi all,
I'm writing here with the Cheese[1] maintainer hat on.
Yesterday I was about to start to port it from HAL to DeviceKit but
talking with David Zeuthen I found out that devkit is going away in
favor of plain libudev + specific abstractions for disks, media,
power, etc [2].
At the moment we use HAL to detect available v4l devices, get the api
version they support and exclude the ones with no capture capability.
All this stuff as far as I can tell is provided by hald video4linux prober [3].
It seems that, with HAL going away sooner or later, we need a new
place for this probing. Probably a dedicated Devicekit-video thing
would be overengineered for a simple task like this, so udev-extras
should be the new place for it.
Is there anyone working or willing to work on it? I could probably
provide a patch myself but I don't really know anything about udev
internals and it will take me more than the time really needed for
such a simple task (btw, if you want to point me where to look in the
source tree I could take a look at it).

Being honest I'm not so sure I will use libudev, I'm currently looking
for a way to do the device probing directly from gstreamer, but it
would be nice to preserve that v4l probing stuff somewhere with HAL
going away (furthermore, I doubt we're the only users of that prober).

Best Regards,
Filippo


1. http://projects.gnome.org/cheese/
2. http://lists.freedesktop.org/archives/devkit-devel/2009-April/000140.html
3. http://cgit.freedesktop.org/hal/tree/hald/linux/probing/probe-video4linux.c

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: hal, udev and video4linux probers
  2009-05-08 17:04 hal, udev and video4linux probers Filippo Argiolas
@ 2009-05-08 20:06 ` Kay Sievers
  2009-05-08 20:25 ` David Zeuthen
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Kay Sievers @ 2009-05-08 20:06 UTC (permalink / raw)
  To: linux-hotplug

[-- Attachment #1: Type: text/plain, Size: 1242 bytes --]

On Fri, 2009-05-08 at 19:04 +0200, Filippo Argiolas wrote:
> Probably a dedicated Devicekit-video thing
> would be overengineered for a simple task like this, so udev-extras
> should be the new place for it.

If you want, try this:
  $ gcc -Wall -o v4l_id v4l_id.c
  $ cp v4l_id /lib/udev
  $ cp 70-v4l_id.rules /lib/udev/rules.d/

After you un-plugged/plugged a device, you will see the properties at
the device:
  /sbin/udevadm info --query=env --name=video0
  ...
  ID_V4L_VERSION=2
  ID_V4L_PRODUCT=UVC Camera (17ef:4807)
  ID_V4L_VIDEO_CAPTURE=1
  ...

> Being honest I'm not so sure I will use libudev, I'm currently looking
> for a way to do the device probing directly from gstreamer, but it
> would be nice to preserve that v4l probing stuff somewhere with HAL
> going away (furthermore, I doubt we're the only users of that prober).

No sure, how else you can get that information. :)

You can query that properties at program startup with libudev, by
"enumerate"-ing all video4linux devices.

You can listen to events for new devices with a "monitor", which
retrieves all new video4linux devices as soon as they are connected.

If the prober is what you are looking for, let me know, and I will put
it in udev-extras.

Cheers,
Kay

[-- Attachment #2: Type: text/x-csrc, Size: 1597 bytes --]

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <linux/videodev.h>
#include <linux/videodev2.h>

int main (int argc, char *argv[])
{
	int fd;
	char *device;
	struct video_capability v1cap;
	struct v4l2_capability v2cap;

	device = argv[1];
	if (device == NULL)
		return 1;
	fd = open (device, O_RDONLY);
	if (fd < 0)
		return 2;

	if (ioctl (fd, VIDIOC_QUERYCAP, &v2cap) == 0) {
		printf("ID_V4L_VERSION=2\n");
		printf("ID_V4L_PRODUCT=%s\n", v2cap.card);
		if ((v2cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) > 0)
			printf("ID_V4L_VIDEO_CAPTURE=1\n");
		if ((v2cap.capabilities & V4L2_CAP_VIDEO_OUTPUT) > 0)
			printf("ID_V4L_VIDEO_OUTPUT=1\n");
		if ((v2cap.capabilities & V4L2_CAP_VIDEO_OVERLAY) > 0)
			printf("ID_V4L_VIDEO_OVERLAY=1\n");
		if ((v2cap.capabilities & V4L2_CAP_AUDIO) > 0)
			printf("ID_V4L_AUDIO=1\n");
		if ((v2cap.capabilities & V4L2_CAP_TUNER) > 0)
			printf("ID_V4L_TUNER=1\n");
		if ((v2cap.capabilities & V4L2_CAP_RADIO) > 0)
			printf("ID_V4L_RADIO=1\n");
	} else if (ioctl (fd, VIDIOCGCAP, &v1cap) == 0) {
		printf("ID_V4L_VERSION=1\n");
		printf("ID_V4L_PRODUCT=%s\n", v1cap.name);
		if ((v1cap.type & VID_TYPE_CAPTURE) > 0)
			printf("ID_V4L_VIDEO_CAPTURE=1\n");
		if ((v1cap.type & VID_TYPE_OVERLAY) > 0)
			printf("ID_V4L_VIDEO_OVERLAY=1\n");
		if (v1cap.audios > 0)
			printf("ID_V4L_AUDIO=1\n");
		if ((v1cap.type & VID_TYPE_TUNER) > 0)
			printf("ID_V4L_TUNER=1\n");
	}

	close (fd);
	return 0;
}

[-- Attachment #3: Type: text/plain, Size: 160 bytes --]

# do not edit this file, it will be overwritten on update

ACTION=="add|change", SUBSYSTEM=="video4linux", ENV{MAJOR}=="?*", IMPORT{program}="v4l_id $tempnode"

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: hal, udev and video4linux probers
  2009-05-08 17:04 hal, udev and video4linux probers Filippo Argiolas
  2009-05-08 20:06 ` Kay Sievers
@ 2009-05-08 20:25 ` David Zeuthen
  2009-05-08 20:38 ` Filippo Argiolas
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: David Zeuthen @ 2009-05-08 20:25 UTC (permalink / raw)
  To: linux-hotplug

Hey,

On Fri, 2009-05-08 at 19:04 +0200, Filippo Argiolas wrote:
> Being honest I'm not so sure I will use libudev, I'm currently looking
> for a way to do the device probing directly from gstreamer, but it
> would be nice to preserve that v4l probing stuff somewhere with HAL
> going away (furthermore, I doubt we're the only users of that prober).

Ideally GStreamer, which is the codebase I believe that you are using to
actually access the device, would provide a mechanism for enumerating
devices and give you events when devices (specifically sinks and
sources) are coming and going. That way, if you care about more than
Linux, the Solaris, FreeBSD and Win32 guys can add support to GStreamer
without you having to change your application.

This is much like GIO in GLib works; we have abstract classes and
interfaces with concrete implementations that depends on what platform
we're running on or are compiled for. E.g. GIO's GVolumeMonitor class
will list all interesting storage devices (and notify you on insertion
and removal) - on Linux it is (indirectly) using libudev, on Solaris
something else, on Win32 it's using the native Win32 API and on OS X
some other native API.

I don't know much about GStreamer, but I suspect it could provide
something like a GstSinkNSourcesMonitor class that works in a similar
way as GVolumeMonitor. On Linux, it would probably use the ID_V4L_*
properties and libudev cf. the mail Kay just sent. 

It seems like the logical thing to do, I think - it would make writing
applications that much easier while still allowing us to change how udev
and Linux in general works. Feel free to include me (and I suppose, Kay
as well) in any discussion with the GStreamer guys about how libudev can
help in doing this.

    David



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: hal, udev and video4linux probers
  2009-05-08 17:04 hal, udev and video4linux probers Filippo Argiolas
  2009-05-08 20:06 ` Kay Sievers
  2009-05-08 20:25 ` David Zeuthen
@ 2009-05-08 20:38 ` Filippo Argiolas
  2009-05-09 11:49 ` Kay Sievers
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Filippo Argiolas @ 2009-05-08 20:38 UTC (permalink / raw)
  To: linux-hotplug

[-- Attachment #1: Type: text/plain, Size: 2356 bytes --]

On Fri, May 8, 2009 at 10:06 PM, Kay Sievers <kay.sievers@vrfy.org> wrote:
> On Fri, 2009-05-08 at 19:04 +0200, Filippo Argiolas wrote:
>> Probably a dedicated Devicekit-video thing
>> would be overengineered for a simple task like this, so udev-extras
>> should be the new place for it.
>
> If you want, try this:
>  $ gcc -Wall -o v4l_id v4l_id.c
>  $ cp v4l_id /lib/udev
>  $ cp 70-v4l_id.rules /lib/udev/rules.d/
>
> After you un-plugged/plugged a device, you will see the properties at
> the device:
>  /sbin/udevadm info --query=env --name=video0
>  ...
>  ID_V4L_VERSION=2
>  ID_V4L_PRODUCT=UVC Camera (17ef:4807)
>  ID_V4L_VIDEO_CAPTURE=1
>  ...

Seems fine to me. Actually I had some spare time this evening and come
up with a similar program myself :P
Glad to see I was almost right on the way to do it. Attaching it here,
feel free to choose the one you like most (yours seems more simple,
probably is better).
Mine lists the capability into a single variable like
ID_V4L_CAPS=capture:radio:tuner and it takes the device path as
argument just because I copied it from usb_id.c :)

>> Being honest I'm not so sure I will use libudev, I'm currently looking
>> for a way to do the device probing directly from gstreamer, but it
>> would be nice to preserve that v4l probing stuff somewhere with HAL
>> going away (furthermore, I doubt we're the only users of that prober).
>
> No sure, how else you can get that information. :)
>
> You can query that properties at program startup with libudev, by
> "enumerate"-ing all video4linux devices.
>
> You can listen to events for new devices with a "monitor", which
> retrieves all new video4linux devices as soon as they are connected.
>
> If the prober is what you are looking for, let me know, and I will put
> it in udev-extras.

Give me some more time to find out if the gstreamer-only way is a
viable one (I'm almost sure I will lose at least the monitor
functionality, I'm not using it at the moment but could be nice).
By the way the HAL prober is copyrighted by Nokia, does anybody know
why they wrote and if there is still anyone using it other than
Cheese?
Maybe it could be worth just adding it into udev-extras anyway so that
there is almost no regression (at least on linux) when HAL will
actually go away.

Cheers,
Filippo

[-- Attachment #2: v4l_caps.c --]
[-- Type: text/x-csrc, Size: 6153 bytes --]

/*
 * v4l_caps - export video4linux capabilities
 *
 * Copyright (c) 2009 Filippo Argiolas
 *
 *	This program is free software; you can redistribute it and/or modify it
 *	under the terms of the GNU General Public License as published by the
 *	Free Software Foundation version 2 of the License.
 */

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include <fcntl.h>
#include <errno.h>
#include <getopt.h>
#include <stdint.h>


#include <sys/types.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <linux/videodev.h>
#include <linux/videodev2.h>

#include "../../udev/udev.h"

int debug;

#define SEP     ":"
#define CAPTURE "capture"
#define OUTPUT  "video_output"
#define OVERLAY "video_overlay"
#define AUDIO   "audio"
#define TUNER   "tuner"
#define RADIO   "radio"

static void log_fn(struct udev *udev, int priority,
		   const char *file, int line, const char *fn,
		   const char *format, va_list args)
{
	if (debug) {
		fprintf(stderr, "%s: ", fn != NULL ? fn : file);
		vfprintf(stderr, format, args);
	} else {
		vsyslog(priority, format, args);
	}
}

int main(int argc, char **argv)
{
	static const struct option options[] = {
		{ "export", no_argument, NULL, 'x' },
		{ "debug", no_argument, NULL, 'd' },
		{ "help", no_argument, NULL, 'h' },
		{}
	};
	struct udev *udev;
	struct udev_device *dev = NULL;
        char syspath[UTIL_PATH_SIZE];
	const char *devpath;
	static int export;
        int fd = -1;
        char device[UTIL_NAME_SIZE];
        char subsystem[UTIL_NAME_SIZE];
	struct video_capability v1cap;
	struct v4l2_capability v2cap;
        char *capability = NULL;
        char caps[512] = "";


	udev = udev_new();
	if (udev == NULL)
		goto exit;

	logging_init("v4l_caps");
	udev_set_log_fn(udev, log_fn);

	while (1) {
		int option;

		option = getopt_long(argc, argv, "dxh", options, NULL);
		if (option == -1)
			break;

		switch (option) {
		case 'd':
			debug = 1;
			if (udev_get_log_priority(udev) < LOG_INFO)
				udev_set_log_priority(udev, LOG_INFO);
			break;
		case 'x':
			export = 1;
			break;
		case 'h':
			printf("Usage: v4l_caps [--export] [--help] <devpath>\n"
			       "  --export    print values as environment keys\n"
			       "  --help      print this help text\n\n");
		default:
			goto exit;
		}
	}

	devpath = argv[optind];
	if (devpath == NULL) {
		fprintf(stderr, "No device specified\n");
		goto exit;
	}

	util_strlcpy(syspath, udev_get_sys_path(udev), sizeof(syspath));
	util_strlcat(syspath, devpath, sizeof(syspath));
	dev = udev_device_new_from_syspath(udev, syspath);
	if (dev == NULL) {
		err(udev, "unable to access '%s'\n", devpath);
		return 1;
	}
        util_strlcpy(device, udev_device_get_devnode (dev), sizeof(device));
        util_strlcpy(subsystem, udev_device_get_subsystem (dev), sizeof(subsystem));

        if (strcmp (subsystem, "video4linux") != 0) {
                err(udev, "not a video4linux device\n");
                goto exit;
        }

        if (!export) goto exit;

        fd = open(device, O_RDONLY);
        if (fd < 0) {
		err(udev, "unable to open %s: %s\n", device, strerror (errno));
		goto exit;
	}
        if (ioctl (fd, VIDIOC_QUERYCAP, &v2cap) == 0) {
                printf("ID_V4L_VERSION=%d\n", 2);
                if ((v2cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) > 0) {
                        capability = (strlen(caps) > 0) ? SEP CAPTURE : CAPTURE;
                        util_strlcat (caps, capability, sizeof(caps));
                }
                if ((v2cap.capabilities & V4L2_CAP_VIDEO_OUTPUT) > 0) {
                        capability = (strlen(caps) > 0) ? SEP OUTPUT : OUTPUT;
                        util_strlcat (caps, capability, sizeof(caps));
                }
		if ((v2cap.capabilities & V4L2_CAP_VIDEO_OVERLAY) > 0) {
                        capability = (strlen(caps) > 0) ? SEP OVERLAY : OVERLAY;
                        util_strlcat (caps, capability, sizeof(caps));
                }
		if ((v2cap.capabilities & V4L2_CAP_AUDIO) > 0) {
                        capability = (strlen(caps) > 0) ? SEP AUDIO : AUDIO;
                        util_strlcat (caps, capability, sizeof(caps));
                }
		if ((v2cap.capabilities & V4L2_CAP_TUNER) > 0) {
                        capability = (strlen(caps) > 0) ? SEP TUNER : TUNER;
                        util_strlcat (caps, capability, sizeof(caps));
                }
		if ((v2cap.capabilities & V4L2_CAP_RADIO) > 0) {
                        capability = (strlen(caps) > 0) ? SEP RADIO : RADIO;
                        util_strlcat (caps, capability, sizeof(caps));
                }
                printf("ID_V4L_CAPABILITIES=%s\n", caps);
        } else {
                info(udev, "VIDIOC_QUERYCAP failed, v4l1 device?\n");
		if (ioctl (fd, VIDIOCGCAP, &v1cap) == 0) {
                        printf("ID_V4L_VERSION=%d\n", 1);
			if ((v1cap.type & VID_TYPE_CAPTURE) > 0) {
                                capability = (strlen(caps) > 0) ? SEP CAPTURE : CAPTURE;
                                util_strlcat (caps, capability, sizeof(caps));
                        }
			if ((v1cap.type & VID_TYPE_OVERLAY) > 0) {
                                capability = (strlen(caps) > 0) ? SEP OVERLAY : OVERLAY;
                                util_strlcat (caps, capability, sizeof(caps));
                        }
			if (v1cap.audios > 0) {
                                capability = (strlen(caps) > 0) ? SEP AUDIO : AUDIO;
                                util_strlcat (caps, capability, sizeof(caps));
                        }
			if ((v1cap.type & VID_TYPE_TUNER) > 0) {
                                capability = (strlen(caps) > 0) ? SEP TUNER : TUNER;
                                util_strlcat (caps, capability, sizeof(caps));
                        }
                        printf("ID_V4L_CAPABILITIES=%s\n", caps);
                }
                else {
                        err(udev, "VIDIOCGCAP failed too. Probably not v4l device\n");
                }
        }

        close (fd);
exit:
	udev_device_unref(dev);
	udev_unref(udev);
	logging_close();
	return 0;
}

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: hal, udev and video4linux probers
  2009-05-08 17:04 hal, udev and video4linux probers Filippo Argiolas
                   ` (2 preceding siblings ...)
  2009-05-08 20:38 ` Filippo Argiolas
@ 2009-05-09 11:49 ` Kay Sievers
  2009-05-09 14:24 ` Filippo Argiolas
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Kay Sievers @ 2009-05-09 11:49 UTC (permalink / raw)
  To: linux-hotplug

On Fri, May 8, 2009 at 22:38, Filippo Argiolas <fargiolas@gnome.org> wrote:
> On Fri, May 8, 2009 at 10:06 PM, Kay Sievers <kay.sievers@vrfy.org> wrote:

> Seems fine to me. Actually I had some spare time this evening and come
> up with a similar program myself :P
> Glad to see I was almost right on the way to do it. Attaching it here,
> feel free to choose the one you like most (yours seems more simple,
> probably is better).
> Mine lists the capability into a single variable like
> ID_V4L_CAPSÊpture:radio:tuner and it takes the device path as
> argument just because I copied it from usb_id.c :)

I've committed a merge of both versions.

We can use the device node directly, so we don't need to look it up.
I've used your all-in-one capability string, just added a leading and
trailing ':", so matches can always use CAP = "*:capture:*" and can
not get confused by other possible variables which start or end with
the same string. We do this in other places like this already.

Thanks,
Kay

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: hal, udev and video4linux probers
  2009-05-08 17:04 hal, udev and video4linux probers Filippo Argiolas
                   ` (3 preceding siblings ...)
  2009-05-09 11:49 ` Kay Sievers
@ 2009-05-09 14:24 ` Filippo Argiolas
  2009-05-09 14:54 ` Filippo Argiolas
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Filippo Argiolas @ 2009-05-09 14:24 UTC (permalink / raw)
  To: linux-hotplug

On Sat, May 9, 2009 at 1:49 PM, Kay Sievers <kay.sievers@vrfy.org> wrote:
> I've committed a merge of both versions.

Great :)
I still don't see it though in the udev (nor udev-extras) git repositories.

> We can use the device node directly, so we don't need to look it up.
> I've used your all-in-one capability string, just added a leading and
> trailing ':", so matches can always use CAP = "*:capture:*" and can
> not get confused by other possible variables which start or end with
> the same string. We do this in other places like this already.

Fine. Now that I looked a bit more into some udev rule I understand
the the need for leading and trailing ":".

> Thanks,

Thanks to you,

Filippo

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: hal, udev and video4linux probers
  2009-05-08 17:04 hal, udev and video4linux probers Filippo Argiolas
                   ` (4 preceding siblings ...)
  2009-05-09 14:24 ` Filippo Argiolas
@ 2009-05-09 14:54 ` Filippo Argiolas
  2009-05-09 16:19 ` Kay Sievers
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Filippo Argiolas @ 2009-05-09 14:54 UTC (permalink / raw)
  To: linux-hotplug

On Sat, May 9, 2009 at 4:24 PM, Filippo Argiolas <fargiolas@gnome.org> wrote:
> On Sat, May 9, 2009 at 1:49 PM, Kay Sievers <kay.sievers@vrfy.org> wrote:
>> I've committed a merge of both versions.
>
> Great :)
> I still don't see it though in the udev (nor udev-extras) git repositories.

Now it's ok. I forgot the email in the copyright line, you can put
<filippo.argiolas@gmail.com> if you want.

Cheers,
Filippo

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: hal, udev and video4linux probers
  2009-05-08 17:04 hal, udev and video4linux probers Filippo Argiolas
                   ` (5 preceding siblings ...)
  2009-05-09 14:54 ` Filippo Argiolas
@ 2009-05-09 16:19 ` Kay Sievers
  2009-05-10 13:58 ` Kay Sievers
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Kay Sievers @ 2009-05-09 16:19 UTC (permalink / raw)
  To: linux-hotplug

On Sat, May 9, 2009 at 16:54, Filippo Argiolas <fargiolas@gnome.org> wrote:
> On Sat, May 9, 2009 at 4:24 PM, Filippo Argiolas <fargiolas@gnome.org> wrote:
>> On Sat, May 9, 2009 at 1:49 PM, Kay Sievers <kay.sievers@vrfy.org> wrote:
>>> I've committed a merge of both versions.
>>
>> Great :)
>> I still don't see it though in the udev (nor udev-extras) git repositories.

Yeah, seems the master -> public rsync is really slow the last days.

> Now it's ok. I forgot the email in the copyright line, you can put
> <filippo.argiolas@gmail.com> if you want.

Done.

Cheers,
Kay

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: hal, udev and video4linux probers
  2009-05-08 17:04 hal, udev and video4linux probers Filippo Argiolas
                   ` (6 preceding siblings ...)
  2009-05-09 16:19 ` Kay Sievers
@ 2009-05-10 13:58 ` Kay Sievers
  2009-05-10 18:50 ` Filippo Argiolas
  2009-05-10 23:59 ` Kay Sievers
  9 siblings, 0 replies; 11+ messages in thread
From: Kay Sievers @ 2009-05-10 13:58 UTC (permalink / raw)
  To: linux-hotplug

On Sat, 2009-05-09 at 18:19 +0200, Kay Sievers wrote:
> On Sat, May 9, 2009 at 16:54, Filippo Argiolas <fargiolas@gnome.org> wrote:
> > On Sat, May 9, 2009 at 4:24 PM, Filippo Argiolas <fargiolas@gnome.org> wrote:
> >> On Sat, May 9, 2009 at 1:49 PM, Kay Sievers <kay.sievers@vrfy.org> wrote:
> >>> I've committed a merge of both versions.
> >>
> >> Great :)
> >> I still don't see it though in the udev (nor udev-extras) git repositories.
> 
> Yeah, seems the master -> public rsync is really slow the last days.
> 
> > Now it's ok. I forgot the email in the copyright line, you can put
> > <filippo.argiolas@gmail.com> if you want.
> 
> Done.

Here is small hack using libudev, that enumerates all capture-capable
video devices, and listens for new devices connected, or devices going
away.

It builds with:
  gcc -Wall -o v4l-monitor v4l-monitor.c -ludev

And prints when started the built-in camera:
  $ ./v4l-monitor
  UVC Camera (17ef:4807) (/dev/video0)
and while new devices are plugged/unplugged:
  UVC Camera (046d:09a4) (/dev/video1) (add)
  OV511+ USB Camera (/dev/video2) (add)
  UVC Camera (046d:09a4) (/dev/video1) (remove)
  OV511+ USB Camera (/dev/video2) (remove)
  OV511+ USB Camera (/dev/video1) (add)
  UVC Camera (046d:09a4) (/dev/video2) (add)
  ...

Cheers,
Kay



/*
 * enumerate and monitor v4l devices
 *
 * Copyright (C) 2009 Kay Sievers <kay.sievers@vrfy.org>
 *
 * 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.
 */

#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <getopt.h>
#include <syslog.h>
#include <fcntl.h>
#include <poll.h>
#include <sys/select.h>

#define LIBUDEV_I_KNOW_THE_API_IS_SUBJECT_TO_CHANGE 1
#include "libudev.h"

int main(int argc, char *argv[])
{
	struct udev *udev;
	struct udev_monitor *monitor;
	struct udev_enumerate *enumerate;
	struct udev_list_entry *list_entry;

	/* libudev context */
	udev = udev_new();

	/* connect to event source */
	monitor = udev_monitor_new_from_netlink(udev, "udev");
	/* install subsytem filter, we will not wake-up for other events */
	udev_monitor_filter_add_match_subsystem_devtype(monitor, "video4linux", NULL);
	/* listen to events, and buffer them */
	udev_monitor_enable_receiving(monitor);

	/* prepare a device scan */
	enumerate = udev_enumerate_new(udev);
	/* filter for video devices */
	udev_enumerate_add_match_subsystem(enumerate,"video4linux");
	/* filter for capture capable devices */
	udev_enumerate_add_match_property(enumerate, "ID_V4L_CAPABILITIES", "*:capture:*");
	/* retrieve the list */
	udev_enumerate_scan_devices(enumerate);
	/* print devices */
	udev_list_entry_foreach(list_entry, udev_enumerate_get_list_entry(enumerate)) {
		struct udev_device *device;

		device = udev_device_new_from_syspath(udev_enumerate_get_udev(enumerate),
						      udev_list_entry_get_name(list_entry));
		if (device = NULL)
			continue;
		printf("%s (%s)\n",
		       udev_device_get_property_value(device, "ID_V4L_PRODUCT"),
		       udev_device_get_devnode(device));
		udev_device_unref(device);
	}
	udev_enumerate_unref(enumerate);

	/* process events */
	while (1) {
		struct pollfd pfd[2];
		struct udev_device *device;

		pfd[0].fd = udev_monitor_get_fd(monitor);
		pfd[0].events = POLLIN;
		pfd[1].fd = STDIN_FILENO;
		pfd[1].events = POLLIN;
		if (poll(pfd, 2, -1) < 1)
			continue;

		if (pfd[0].revents & POLLIN) {
			const char *cap;

			/* get device from event */
			device = udev_monitor_receive_device(monitor);
			if (device = NULL)
				continue;
			/* filter capture-capable devices */
			cap = udev_device_get_property_value(device, "ID_V4L_CAPABILITIES");
			if (cap = NULL || strstr(":capture:", cap) = NULL)
				continue;
			/* print device */
			printf("%s (%s) (%s)\n",
			       udev_device_get_property_value(device, "ID_V4L_PRODUCT"),
			       udev_device_get_devnode(device),
			       udev_device_get_action(device));
			udev_device_unref(device);
		}

		/* exit the loop on console input */
		if (pfd[1].revents & POLLIN)
			break;
	}
	udev_monitor_unref(monitor);

	udev_unref(udev);
	return 0;
}



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: hal, udev and video4linux probers
  2009-05-08 17:04 hal, udev and video4linux probers Filippo Argiolas
                   ` (7 preceding siblings ...)
  2009-05-10 13:58 ` Kay Sievers
@ 2009-05-10 18:50 ` Filippo Argiolas
  2009-05-10 23:59 ` Kay Sievers
  9 siblings, 0 replies; 11+ messages in thread
From: Filippo Argiolas @ 2009-05-10 18:50 UTC (permalink / raw)
  To: linux-hotplug

[-- Attachment #1: Type: text/plain, Size: 531 bytes --]

On Sun, May 10, 2009 at 3:58 PM, Kay Sievers <kay.sievers@vrfy.org> wrote:
> Here is small hack using libudev, that enumerates all capture-capable
> video devices, and listens for new devices connected, or devices going
> away.

Thank you :)
It will surely be quite useful when implementing detection, either
directly in cheese or in gstreamer.
Isn't there a match_property function for udev_monitor too?

Anyway, I just noticed that 70-v4l_id.rules is not being installed at
the moment. Attaching a simple patch.

Cheers,
Filippo

[-- Attachment #2: 0001-Properly-install-v4l-rules.patch --]
[-- Type: text/x-patch, Size: 682 bytes --]

From 6780ddd33ce405aaaabc40a8ab8ebd8ef75599b6 Mon Sep 17 00:00:00 2001
From: Filippo Argiolas <filippo.argiolas@gmail.com>
Date: Sun, 10 May 2009 17:43:50 +0200
Subject: [PATCH] Properly install v4l rules

---
 v4l_id/Makefile.am |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/v4l_id/Makefile.am b/v4l_id/Makefile.am
index 0943496..f0b5144 100644
--- a/v4l_id/Makefile.am
+++ b/v4l_id/Makefile.am
@@ -3,4 +3,8 @@ include $(top_srcdir)/Makefile.am.inc
 udevhomedir = $(udev_prefix)/lib/udev
 udevhome_PROGRAMS = v4l_id
 
+udevrulesdir = $(udev_prefix)/lib/udev/rules.d
+dist_udevrules_DATA = \
+	70-v4l_id.rules
+
 v4l_id_SOURCES = v4l_id.c
-- 
1.6.0.4


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: hal, udev and video4linux probers
  2009-05-08 17:04 hal, udev and video4linux probers Filippo Argiolas
                   ` (8 preceding siblings ...)
  2009-05-10 18:50 ` Filippo Argiolas
@ 2009-05-10 23:59 ` Kay Sievers
  9 siblings, 0 replies; 11+ messages in thread
From: Kay Sievers @ 2009-05-10 23:59 UTC (permalink / raw)
  To: linux-hotplug

On Sun, May 10, 2009 at 20:50, Filippo Argiolas <fargiolas@gnome.org> wrote:
> On Sun, May 10, 2009 at 3:58 PM, Kay Sievers <kay.sievers@vrfy.org> wrote:
>> Here is small hack using libudev, that enumerates all capture-capable
>> video devices, and listens for new devices connected, or devices going
>> away.
>
> Thank you :)
> It will surely be quite useful when implementing detection, either
> directly in cheese or in gstreamer.

Great. Let me know, if you guys have decided anything.

> Isn't there a match_property function for udev_monitor too?

Not now. We could add it but, the filtering would need to happen in
libudev in the client process. Unlike the subsystem matches, where we
compose a Berkeley Packet Filter (BPF) sequence, and push it inside
the kernel to the client socket, and the kernel will do the message
filtering to prevent the listening process to be woken up for messages
not subscribed to.

All more advanced filters, like the free-text properties, we need to
do in the client, because the BPF are very limited. But I can add
that, if its useful. It probably matches nicely to the enumerator
interface, so I guess we should have it.

> Anyway, I just noticed that 70-v4l_id.rules is not being installed at
> the moment. Attaching a simple patch.

Applied. Thanks.

Kay

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2009-05-10 23:59 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-05-08 17:04 hal, udev and video4linux probers Filippo Argiolas
2009-05-08 20:06 ` Kay Sievers
2009-05-08 20:25 ` David Zeuthen
2009-05-08 20:38 ` Filippo Argiolas
2009-05-09 11:49 ` Kay Sievers
2009-05-09 14:24 ` Filippo Argiolas
2009-05-09 14:54 ` Filippo Argiolas
2009-05-09 16:19 ` Kay Sievers
2009-05-10 13:58 ` Kay Sievers
2009-05-10 18:50 ` Filippo Argiolas
2009-05-10 23:59 ` Kay Sievers

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.