summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgusi <gusi@df743ca5-7f9a-e211-a948-0013205c9059>2013-10-09 03:04:02 +0800
committergusi <gusi@df743ca5-7f9a-e211-a948-0013205c9059>2013-10-09 03:04:02 +0800
commit9ae9c343182b28c084c5ee99ec5c74317bc45e0f (patch)
treef0415575bf729eeacb7449e3e1105fc1544f0dd1
parent5090a53b85cfd34f01994e94ac90b7a6da28b851 (diff)
downloadmarcuscom-ports-9ae9c343182b28c084c5ee99ec5c74317bc45e0f.tar.gz
marcuscom-ports-9ae9c343182b28c084c5ee99ec5c74317bc45e0f.tar.zst
marcuscom-ports-9ae9c343182b28c084c5ee99ec5c74317bc45e0f.zip
Fix multimedia/cheese3:
- Add patch-libcheese_cheese-camera-device-monitor.c patch which fixes camera detection. [1] - The port needs vpx gstreamer plugin. Add it to the list of gstreamer plugins. - Remove the OMF knob. It does not install omf files anymore. Contributed by: Joe Marcus [1] Reviewed by: kwm git-svn-id: svn://creme-brulee.marcuscom.com/ports/trunk@18779 df743ca5-7f9a-e211-a948-0013205c9059
-rw-r--r--multimedia/cheese3/Makefile3
-rw-r--r--multimedia/cheese3/files/patch-libcheese_cheese-camera-device-monitor.c290
2 files changed, 291 insertions, 2 deletions
diff --git a/multimedia/cheese3/Makefile b/multimedia/cheese3/Makefile
index 38ac58fe7..ff6d47bb2 100644
--- a/multimedia/cheese3/Makefile
+++ b/multimedia/cheese3/Makefile
@@ -31,8 +31,7 @@ USE_GNOME= gnomeprefix intlhack evolutiondataserver3 librsvg2 \
gnomedesktop3 libxml2:build introspection:build
USES= gettext gmake pathfix pkgconfig
# USE_GSTREAMER= bad gconf good jpeg ogg theora v4l2 vorbis
-USE_GSTREAMER1= bad good jpeg ogg theora v4l2
-INSTALLS_OMF= yes
+USE_GSTREAMER1= bad good jpeg ogg theora v4l2 vpx
INSTALLS_ICONS= yes
USE_LDCONFIG= yes
GNU_CONFIGURE= yes
diff --git a/multimedia/cheese3/files/patch-libcheese_cheese-camera-device-monitor.c b/multimedia/cheese3/files/patch-libcheese_cheese-camera-device-monitor.c
new file mode 100644
index 000000000..995cb5d50
--- /dev/null
+++ b/multimedia/cheese3/files/patch-libcheese_cheese-camera-device-monitor.c
@@ -0,0 +1,290 @@
+--- libcheese/cheese-camera-device-monitor.c.orig 2012-08-22 21:04:40.000000000 +0200
++++ libcheese/cheese-camera-device-monitor.c 2013-09-22 23:12:35.072353163 +0200
+@@ -33,6 +33,14 @@
+ #include <fcntl.h>
+ #include <unistd.h>
+ #include <sys/ioctl.h>
++ #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
++ #include <errno.h>
++ #include <sys/param.h>
++ #include <sys/types.h>
++ #include <sys/socket.h>
++ #include <sys/un.h>
++ #include <linux/videodev.h>
++ #endif
+ #if USE_SYS_VIDEOIO_H > 0
+ #include <sys/types.h>
+ #include <sys/videoio.h>
+@@ -302,6 +310,220 @@
+ g_list_free (devices);
+ }
+
++#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
++static void cheese_camera_device_monitor_init_event (CheeseCameraDeviceMonitor *monitor);
++static gboolean cheese_camera_device_monitor_is_camera (const char *devname);
++
++static gboolean cheese_camera_device_monitor_event_inited = FALSE;
++
++static gboolean
++cheese_camera_device_monitor_is_camera (const char *devname){
++ gboolean is_camera = FALSE;
++ int fd;
++ struct v4l2_capability v2cap;
++ g_return_val_if_fail (devname != NULL, FALSE);
++
++ fd = open (devname, O_RDONLY);
++ if (fd < 0)
++ {
++ GST_WARNING("Failed to query: %s", devname);
++ return FALSE;
++ }
++ else{
++ if (ioctl (fd, VIDIOC_QUERYCAP, &v2cap) == 0)
++ {
++ is_camera = ((v2cap.capabilities & 0x00000001)==1);
++ }
++ else{
++ GST_WARNING("Failed to get product name for %s: %s", devname,
++ g_strerror (errno));
++ }
++ }
++
++ close (fd);
++
++ return is_camera;
++}
++
++static char *
++cheese_camera_device_monitor_get_product (const char *devname)
++{
++ int fd;
++ struct v4l2_capability v2cap;
++ char *product = NULL;
++
++ g_return_val_if_fail (devname != NULL, NULL);
++
++ fd = open (devname, O_RDONLY);
++ if (fd < 0)
++ {
++ GST_WARNING("Failed to get product name for %s: %s", devname,
++ g_strerror (errno));
++ return NULL;
++ }
++
++ if (ioctl (fd, VIDIOC_QUERYCAP, &v2cap) == 0)
++ {
++ product = g_strdup ((const char *) v2cap.card);
++ }
++ else
++ {
++ GST_WARNING("Failed to get product name for %s: %s", devname,
++ g_strerror (errno));
++ }
++
++ close (fd);
++
++ return product;
++}
++
++static void
++cheese_camera_device_monitor_process_event (const char *event,
++ CheeseCameraDeviceMonitor *monitor)
++{
++ g_return_if_fail (event != NULL);
++
++ GST_INFO ("Received devd event: %s", event);
++
++ switch (event[0])
++ {
++ case '!':
++ {
++ GRegex *rex;
++ GMatchInfo *info;
++
++ rex = g_regex_new ("subsystem=CDEV type=(CREATE|DESTROY) cdev=(video[0-9]+)", 0, 0, NULL);
++ if (g_regex_match (rex, event, 0, &info))
++ {
++ char *devname, *type, *vdev, *product = NULL;
++ CheeseCameraDevice *device;
++ GError *error = NULL;
++
++ type = g_match_info_fetch (info, 1);
++ vdev = g_match_info_fetch (info, 2);
++
++ devname = g_strdup_printf ("/dev/%s", vdev);
++
++ if (g_strcmp0 (type, "DESTROY") == 0)
++ {
++ g_signal_emit (monitor, monitor_signals[REMOVED], 0,
++ devname);
++ }
++ else
++ {
++ if(cheese_camera_device_monitor_is_camera (devname))
++ {
++ product = cheese_camera_device_monitor_get_product (devname);
++ if (product == NULL)
++ product = g_strdup ("WebCamd Device");
++ device = cheese_camera_device_new (devname, devname,
++ product,
++ 2,
++ &error);
++ if (device == NULL)
++ GST_WARNING ("Device initialization for %s failed: %s",
++ devname,
++ (error != NULL) ? error->message : "Unknown reason");
++ g_signal_emit (monitor, monitor_signals[ADDED], 0, device);
++ }
++
++ g_free (product);
++ }
++ g_free (devname);
++ g_free (vdev);
++ g_free (type);
++ }
++ g_match_info_free (info);
++ g_regex_unref (rex);
++ break;
++ }
++ default:
++ break;
++ }
++}
++
++static gboolean
++cheese_camera_device_monitor_event_cb (GIOChannel *source,
++ GIOCondition condition,
++ gpointer user_data)
++{
++ char *event;
++ gsize terminator;
++ GIOStatus status;
++ CheeseCameraDeviceMonitor *monitor;
++
++ monitor = (CheeseCameraDeviceMonitor *) user_data;
++
++ status = g_io_channel_read_line (source, &event, NULL, &terminator, NULL);
++ if (status == G_IO_STATUS_NORMAL)
++ {
++ event[terminator] = 0;
++ cheese_camera_device_monitor_process_event (event, monitor);
++ g_free (event);
++ }
++ else
++ {
++ if (cheese_camera_device_monitor_event_inited)
++ {
++ int fd;
++
++ cheese_camera_device_monitor_init_event (monitor);
++ fd = g_io_channel_unix_get_fd (source);
++ g_io_channel_shutdown (source, FALSE, NULL);
++ close (fd);
++
++ return FALSE;
++ }
++ }
++
++ return TRUE;
++}
++
++void
++cheese_camera_device_monitor_coldplug (CheeseCameraDeviceMonitor *monitor)
++{
++ GDir *dir;
++ GError *error = NULL;
++ const char *fname;
++
++ dir = g_dir_open ("/dev", 0, &error);
++ if (dir == NULL)
++ {
++ GST_WARNING ("Failed to open /dev for reading: %s",
++ (error != NULL) ? error->message : "Unknown error");
++ return;
++ }
++
++ while ((fname = g_dir_read_name (dir)) != NULL)
++ {
++ if ( strncmp (fname, "video", strlen ("video")) == 0)
++ {
++ char *devname, *product;
++
++ devname = g_strdup_printf ("/dev/%s", fname);
++ if (cheese_camera_device_monitor_is_camera (devname))
++ {
++ CheeseCameraDevice *device;
++ GError *derr = NULL;
++
++ product = cheese_camera_device_monitor_get_product (devname);
++ if (product == NULL)
++ product = g_strdup ("WebCamd Device");
++
++ device = cheese_camera_device_new (devname, devname, product, 2, &derr);
++ if (device == NULL)
++ GST_WARNING ("Device initialization for %s failed: %s", devname,
++ (derr != NULL) ? derr->message : "Unknown reason");
++
++ g_signal_emit (monitor, monitor_signals[ADDED], 0, device);
++
++ g_free (product);
++ }
++ g_free (devname);
++ }
++ }
++ g_dir_close (dir);
++}
+ #else /* HAVE_UDEV */
+ void
+ cheese_camera_device_monitor_coldplug (CheeseCameraDeviceMonitor *monitor)
+@@ -430,6 +652,42 @@
+ g_type_class_add_private (klass, sizeof (CheeseCameraDeviceMonitorPrivate));
+ }
+
++#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
++static void
++cheese_camera_device_monitor_init_event (CheeseCameraDeviceMonitor *monitor)
++{
++ int event_fd;
++ struct sockaddr_un addr;
++
++ event_fd = socket (PF_UNIX, SOCK_STREAM, 0);
++ if (event_fd < 0)
++ {
++ GST_WARNING ("Failed to create devd socket: %s", g_strerror (errno));
++ cheese_camera_device_monitor_event_inited = FALSE;
++ return;
++ }
++
++ addr.sun_family = AF_UNIX;
++ strncpy (addr.sun_path, "/var/run/devd.pipe", sizeof (addr.sun_path));
++ if (connect (event_fd, (struct sockaddr *) &addr, sizeof (addr)) == 0)
++ {
++ GIOChannel *channel;
++
++ channel = g_io_channel_unix_new (event_fd);
++ g_io_add_watch (channel, G_IO_IN, cheese_camera_device_monitor_event_cb, monitor);
++ g_io_channel_unref (channel);
++ cheese_camera_device_monitor_event_inited = TRUE;
++ }
++ else
++ {
++ GST_WARNING("Failed to connect to /var/run/devd.pipe: %s",
++ g_strerror (errno));
++ close (event_fd);
++ cheese_camera_device_monitor_event_inited = FALSE;
++ }
++}
++#endif
++
+ static void
+ cheese_camera_device_monitor_init (CheeseCameraDeviceMonitor *monitor)
+ {
+@@ -440,6 +698,8 @@
+ priv->client = g_udev_client_new (subsystems);
+ g_signal_connect (G_OBJECT (priv->client), "uevent",
+ G_CALLBACK (cheese_camera_device_monitor_uevent_cb), monitor);
++#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
++ cheese_camera_device_monitor_init_event (monitor);
+ #endif /* HAVE_UDEV */
+ }
+