summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormarcus <marcus@df743ca5-7f9a-e211-a948-0013205c9059>2008-02-24 04:56:02 +0800
committermarcus <marcus@df743ca5-7f9a-e211-a948-0013205c9059>2008-02-24 04:56:02 +0800
commitde985cc1890b143f7f1477220da56ba784c384b3 (patch)
tree4e2a3ca46941e39874488f7ea0335d312f33e04c
parentdd394bc271a5d1eff7a3deaabaea3ec9dd99809e (diff)
downloadmarcuscom-ports-de985cc1890b143f7f1477220da56ba784c384b3.tar
marcuscom-ports-de985cc1890b143f7f1477220da56ba784c384b3.tar.gz
marcuscom-ports-de985cc1890b143f7f1477220da56ba784c384b3.tar.bz2
marcuscom-ports-de985cc1890b143f7f1477220da56ba784c384b3.tar.lz
marcuscom-ports-de985cc1890b143f7f1477220da56ba784c384b3.tar.xz
marcuscom-ports-de985cc1890b143f7f1477220da56ba784c384b3.tar.zst
marcuscom-ports-de985cc1890b143f7f1477220da56ba784c384b3.zip
Add conditional support for v4l read operations (as opposed to mmap). This
should allow gst's v4l driver to work with all FreeBSD webcam drivers. This is based on work by luigi for linphone. git-svn-id: svn://creme-brulee.marcuscom.com/ports/trunk@10483 df743ca5-7f9a-e211-a948-0013205c9059
-rw-r--r--multimedia/gstreamer-plugins/Makefile4
-rw-r--r--multimedia/gstreamer-plugins/files/patch-sys_v4l_gstv4lelement.h11
-rw-r--r--multimedia/gstreamer-plugins/files/patch-sys_v4l_v4lsrc_calls.c160
3 files changed, 173 insertions, 2 deletions
diff --git a/multimedia/gstreamer-plugins/Makefile b/multimedia/gstreamer-plugins/Makefile
index ed209a208..4b19f3423 100644
--- a/multimedia/gstreamer-plugins/Makefile
+++ b/multimedia/gstreamer-plugins/Makefile
@@ -3,12 +3,12 @@
# Whom: Mario Sergio Fujikawa Ferreira <lioux@FreeBSD.org>
#
# $FreeBSD$
-# $MCom: ports/multimedia/gstreamer-plugins/Makefile,v 1.104 2008/02/21 15:33:19 kwm Exp $
+# $MCom: ports/multimedia/gstreamer-plugins/Makefile,v 1.105 2008/02/21 16:28:00 kwm Exp $
#
PORTNAME= gstreamer
PORTVERSION?= ${BASE_PORTVERSION}
-PORTREVISION?= 0
+PORTREVISION?= 1
PORTEPOCH= 3
CATEGORIES?= multimedia audio
MASTER_SITES= http://gstreamer.freedesktop.org/src/gst-plugins-base/:base \
diff --git a/multimedia/gstreamer-plugins/files/patch-sys_v4l_gstv4lelement.h b/multimedia/gstreamer-plugins/files/patch-sys_v4l_gstv4lelement.h
new file mode 100644
index 000000000..d2f6ac436
--- /dev/null
+++ b/multimedia/gstreamer-plugins/files/patch-sys_v4l_gstv4lelement.h
@@ -0,0 +1,11 @@
+--- sys/v4l/gstv4lelement.h.orig 2008-02-23 15:31:39.000000000 -0500
++++ sys/v4l/gstv4lelement.h 2008-02-23 15:32:00.000000000 -0500
+@@ -91,6 +91,8 @@ struct _GstV4lElement {
+ /* X-overlay */
+ GstV4lXv *xv;
+ gulong xwindow_id;
++
++ gboolean use_read;
+ };
+
+ struct _GstV4lElementClass {
diff --git a/multimedia/gstreamer-plugins/files/patch-sys_v4l_v4lsrc_calls.c b/multimedia/gstreamer-plugins/files/patch-sys_v4l_v4lsrc_calls.c
new file mode 100644
index 000000000..d7a6955f5
--- /dev/null
+++ b/multimedia/gstreamer-plugins/files/patch-sys_v4l_v4lsrc_calls.c
@@ -0,0 +1,160 @@
+--- sys/v4l/v4lsrc_calls.c.orig 2008-02-23 14:41:56.000000000 -0500
++++ sys/v4l/v4lsrc_calls.c 2008-02-23 15:52:06.000000000 -0500
+@@ -26,12 +26,14 @@
+
+ #include <stdlib.h>
+ #include <sys/types.h>
++#include <sys/uio.h>
+ #include <sys/stat.h>
+ #include <fcntl.h>
+ #include <sys/ioctl.h>
+ #include <sys/mman.h>
+ #include <string.h>
+ #include <errno.h>
++#include <unistd.h>
+ #include "v4lsrc_calls.h"
+ #include <sys/time.h>
+
+@@ -87,6 +89,15 @@ gst_v4lsrc_queue_frame (GstV4lSrc * v4ls
+ return FALSE;
+ }
+
++ if (GST_V4LELEMENT (v4lsrc)->use_read) {
++ if (read(GST_V4LELEMENT (v4lsrc)->video_fd, GST_V4LELEMENT (v4lsrc)->buffer, v4lsrc->mmap.width * v4lsrc->mmap.height * 3/2) < 0) {
++ GST_ELEMENT_ERROR (v4lsrc, RESOURCE, WRITE, (NULL),
++ ("Error queueing a buffer (%d): %s", num, g_strerror (errno)));
++ return FALSE;
++ }
++ goto done;
++ }
++
+ /* instruct the driver to prepare capture using buffer frame num */
+ v4lsrc->mmap.frame = num;
+ if (ioctl (GST_V4LELEMENT (v4lsrc)->video_fd,
+@@ -95,6 +106,7 @@ gst_v4lsrc_queue_frame (GstV4lSrc * v4ls
+ ("Error queueing a buffer (%d): %s", num, g_strerror (errno)));
+ return FALSE;
+ }
++done:
+
+ v4lsrc->frame_queue_state[num] = QUEUE_STATE_QUEUED;
+ v4lsrc->num_queued++;
+@@ -168,13 +180,23 @@ gst_v4lsrc_capture_init (GstV4lSrc * v4l
+ GST_V4L_CHECK_OPEN (GST_V4LELEMENT (v4lsrc));
+ GST_V4L_CHECK_NOT_ACTIVE (GST_V4LELEMENT (v4lsrc));
+
++ GST_V4LELEMENT (v4lsrc)->use_read = FALSE;
++
+ /* request the mmap buffer info:
+ * total size of mmap buffer, number of frames, offsets of frames */
+ if (ioctl (GST_V4LELEMENT (v4lsrc)->video_fd, VIDIOCGMBUF,
+ &(v4lsrc->mbuf)) < 0) {
+ GST_ELEMENT_ERROR (v4lsrc, RESOURCE, READ, (NULL),
+- ("Error getting buffer information: %s", g_strerror (errno)));
+- return FALSE;
++ ("Error getting buffer information: %s, trying with read", g_strerror (errno)));
++ GST_V4LELEMENT (v4lsrc)->buffer = (guint8 *) g_malloc0 (sizeof (guint8) * 1024 * 768 * 3);
++ GST_V4LELEMENT (v4lsrc)->use_read = TRUE;
++
++ v4lsrc->frame_queue_state = (gint8 *) g_malloc (sizeof (gint8) * (768 * 3));
++
++ /* lock for the frame_state */
++ v4lsrc->mutex_queue_state = g_mutex_new ();
++ v4lsrc->cond_queue_state = g_cond_new ();
++ goto done;
+ }
+
+ if (v4lsrc->mbuf.frames < MIN_BUFFERS_QUEUED) {
+@@ -205,6 +227,7 @@ gst_v4lsrc_capture_init (GstV4lSrc * v4l
+ GST_V4LELEMENT (v4lsrc)->buffer = NULL;
+ return FALSE;
+ }
++done:
+
+ return TRUE;
+ }
+@@ -413,10 +436,14 @@ gst_v4lsrc_capture_deinit (GstV4lSrc * v
+ v4lsrc->frame_queue_state = NULL;
+
+ /* unmap the buffer */
+- if (munmap (GST_V4LELEMENT (v4lsrc)->buffer, v4lsrc->mbuf.size) == -1) {
+- GST_ELEMENT_ERROR (v4lsrc, RESOURCE, CLOSE, (NULL),
+- ("error munmap'ing capture buffer: %s", g_strerror (errno)));
+- return FALSE;
++ if (GST_V4LELEMENT (v4lsrc)->use_read) {
++ g_free (GST_V4LELEMENT (v4lsrc)->buffer);
++ } else {
++ if (munmap (GST_V4LELEMENT (v4lsrc)->buffer, v4lsrc->mbuf.size) == -1) {
++ GST_ELEMENT_ERROR (v4lsrc, RESOURCE, CLOSE, (NULL),
++ ("error munmap'ing capture buffer: %s", g_strerror (errno)));
++ return FALSE;
++ }
+ }
+ GST_V4LELEMENT (v4lsrc)->buffer = NULL;
+
+@@ -446,6 +473,7 @@ gst_v4lsrc_try_capture (GstV4lSrc * v4ls
+ /* so, we need a buffer and some more stuff */
+ int frame = 0;
+ guint8 *buffer;
++ gboolean use_read = FALSE;
+ struct video_mbuf vmbuf;
+ struct video_mmap vmmap;
+
+@@ -457,16 +485,18 @@ gst_v4lsrc_try_capture (GstV4lSrc * v4ls
+ /* let's start by requesting a buffer and mmap()'ing it */
+ if (ioctl (GST_V4LELEMENT (v4lsrc)->video_fd, VIDIOCGMBUF, &vmbuf) < 0) {
+ GST_ELEMENT_ERROR (v4lsrc, RESOURCE, READ, (NULL),
+- ("Error getting buffer information: %s", g_strerror (errno)));
+- return FALSE;
+- }
+- /* Map the buffers */
+- buffer = mmap (0, vmbuf.size, PROT_READ | PROT_WRITE,
+- MAP_SHARED, GST_V4LELEMENT (v4lsrc)->video_fd, 0);
+- if (buffer == MAP_FAILED) {
+- GST_ELEMENT_ERROR (v4lsrc, RESOURCE, OPEN_READ_WRITE, (NULL),
+- ("Error mapping our try-out buffer: %s", g_strerror (errno)));
+- return FALSE;
++ ("Error getting buffer information: %s, trying read", g_strerror (errno)));
++ buffer = (gint8 *) g_malloc0 (sizeof (gint8) * 1024 * 768 * 3);
++ use_read = TRUE;
++ } else {
++ /* Map the buffers */
++ buffer = mmap (0, vmbuf.size, PROT_READ | PROT_WRITE,
++ MAP_SHARED, GST_V4LELEMENT (v4lsrc)->video_fd, 0);
++ if (buffer == MAP_FAILED) {
++ GST_ELEMENT_ERROR (v4lsrc, RESOURCE, OPEN_READ_WRITE, (NULL),
++ ("Error mapping our try-out buffer: %s", g_strerror (errno)));
++ return FALSE;
++ }
+ }
+
+ /* now that we have a buffer, let's try out our format */
+@@ -474,6 +504,15 @@ gst_v4lsrc_try_capture (GstV4lSrc * v4ls
+ vmmap.height = height;
+ vmmap.format = palette;
+ vmmap.frame = frame;
++ if (use_read) {
++ if (read (GST_V4LELEMENT (v4lsrc)->video_fd, buffer, width * height * 3/2) < 0) {
++ GST_ERROR_OBJECT (v4lsrc,
++ "Error reading into our ty-out buffer: %s", g_strerror (errno));
++ g_free (buffer);
++ return FALSE;
++ }
++ goto done;
++ }
+ if (ioctl (GST_V4LELEMENT (v4lsrc)->video_fd, VIDIOCMCAPTURE, &vmmap) < 0) {
+ if (errno != EINVAL) /* our format failed! */
+ GST_ERROR_OBJECT (v4lsrc,
+@@ -488,7 +527,11 @@ gst_v4lsrc_try_capture (GstV4lSrc * v4ls
+ return FALSE;
+ }
+
+- munmap (buffer, vmbuf.size);
++done:
++ if (use_read)
++ g_free (buffer);
++ else
++ munmap (buffer, vmbuf.size);
+
+ /* if we got here, it worked! woohoo, the format is supported! */
+ return TRUE;