From 9ae9c343182b28c084c5ee99ec5c74317bc45e0f Mon Sep 17 00:00:00 2001 From: gusi Date: Tue, 8 Oct 2013 19:04:02 +0000 Subject: 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 --- multimedia/cheese3/Makefile | 3 +- .../patch-libcheese_cheese-camera-device-monitor.c | 290 +++++++++++++++++++++ 2 files changed, 291 insertions(+), 2 deletions(-) create mode 100644 multimedia/cheese3/files/patch-libcheese_cheese-camera-device-monitor.c 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 + #include + #include ++ #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) ++ #include ++ #include ++ #include ++ #include ++ #include ++ #include ++ #endif + #if USE_SYS_VIDEOIO_H > 0 + #include + #include +@@ -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 */ + } + -- cgit