From 125c400566e403ddac396ea0377802fb8bc5e23c Mon Sep 17 00:00:00 2001 From: marcus Date: Fri, 29 Feb 2008 22:02:14 +0000 Subject: Fix v4l read support. Tested with: cheese git-svn-id: svn://creme-brulee.marcuscom.com/ports/trunk@10586 df743ca5-7f9a-e211-a948-0013205c9059 --- multimedia/gstreamer-plugins/Makefile | 4 +- .../files/patch-sys_v4l_v4lsrc_calls.c | 127 ++++++++++++++++++--- 2 files changed, 110 insertions(+), 21 deletions(-) diff --git a/multimedia/gstreamer-plugins/Makefile b/multimedia/gstreamer-plugins/Makefile index 4b19f3423..0a674692a 100644 --- a/multimedia/gstreamer-plugins/Makefile +++ b/multimedia/gstreamer-plugins/Makefile @@ -3,12 +3,12 @@ # Whom: Mario Sergio Fujikawa Ferreira # # $FreeBSD$ -# $MCom: ports/multimedia/gstreamer-plugins/Makefile,v 1.105 2008/02/21 16:28:00 kwm Exp $ +# $MCom: ports/multimedia/gstreamer-plugins/Makefile,v 1.106 2008/02/23 20:56:01 marcus Exp $ # PORTNAME= gstreamer PORTVERSION?= ${BASE_PORTVERSION} -PORTREVISION?= 1 +PORTREVISION?= 2 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_v4lsrc_calls.c b/multimedia/gstreamer-plugins/files/patch-sys_v4l_v4lsrc_calls.c index d7a6955f5..379f4c4b2 100644 --- a/multimedia/gstreamer-plugins/files/patch-sys_v4l_v4lsrc_calls.c +++ b/multimedia/gstreamer-plugins/files/patch-sys_v4l_v4lsrc_calls.c @@ -1,5 +1,5 @@ ---- 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 +--- sys/v4l/v4lsrc_calls.c.orig 2008-02-29 16:36:45.000000000 -0500 ++++ sys/v4l/v4lsrc_calls.c 2008-02-29 16:59:19.000000000 -0500 @@ -26,12 +26,14 @@ #include @@ -15,12 +15,42 @@ #include "v4lsrc_calls.h" #include -@@ -87,6 +89,15 @@ gst_v4lsrc_queue_frame (GstV4lSrc * v4ls +@@ -87,6 +89,45 @@ 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) { ++ struct video_picture vp; ++ struct video_window vw; ++ ++ if (ioctl (GST_V4LELEMENT (v4lsrc)->video_fd, VIDIOCGPICT, &vp) == -1) { ++ GST_ELEMENT_ERROR (v4lsrc, RESOURCE, WRITE, (NULL), ++ ("Error getting current picture info for frame (%d): %s", num, g_strerror (errno))); ++ return FALSE; ++ } ++ ++ vp.palette = v4lsrc->mmap.format; ++ if (ioctl (GST_V4LELEMENT (v4lsrc)->video_fd, VIDIOCSPICT, &vp) == -1) { ++ GST_ELEMENT_ERROR (v4lsrc, RESOURCE, WRITE, (NULL), ++ ("Error setting picture info for frame (%d): %s", num, g_strerror (errno))); ++ return FALSE; ++ } ++ ++ if (ioctl (GST_V4LELEMENT (v4lsrc)->video_fd, VIDIOCGWIN, &vw) == -1) { ++ GST_ELEMENT_ERROR (v4lsrc, RESOURCE, WRITE, (NULL), ++ ("Error getting current window properties for frame (%d): %s", num, g_strerror (errno))); ++ return FALSE; ++ } ++ ++ vw.width = v4lsrc->mmap.width; ++ vw.height = v4lsrc->mmap.height; ++ if (ioctl (GST_V4LELEMENT (v4lsrc)->video_fd, VIDIOCSWIN, &vw) == -1) { ++ GST_ELEMENT_ERROR (v4lsrc, RESOURCE, WRITE, (NULL), ++ ("Error setting window properties for frame (%d): %s", num, g_strerror (errno))); ++ return FALSE; ++ } ++ ++ if (read(GST_V4LELEMENT (v4lsrc)->video_fd, GST_V4LELEMENT (v4lsrc)->buffer + (1024 * 768 * 3 * num), 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; @@ -31,7 +61,7 @@ /* 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 +@@ -95,6 +136,7 @@ gst_v4lsrc_queue_frame (GstV4lSrc * v4ls ("Error queueing a buffer (%d): %s", num, g_strerror (errno))); return FALSE; } @@ -39,7 +69,26 @@ v4lsrc->frame_queue_state[num] = QUEUE_STATE_QUEUED; v4lsrc->num_queued++; -@@ -168,13 +180,23 @@ gst_v4lsrc_capture_init (GstV4lSrc * v4l +@@ -117,6 +159,10 @@ gst_v4lsrc_sync_frame (GstV4lSrc * v4lsr + return FALSE; + } + ++ if (GST_V4LELEMENT (v4lsrc)->use_read) { ++ goto done; ++ } ++ + while (ioctl (GST_V4LELEMENT (v4lsrc)->video_fd, VIDIOCSYNC, &num) < 0) { + /* if the sync() got interrupted, we can retry */ + if (errno != EINTR) { +@@ -126,6 +172,7 @@ gst_v4lsrc_sync_frame (GstV4lSrc * v4lsr + } + GST_DEBUG_OBJECT (v4lsrc, "Sync got interrupted"); + } ++done: + GST_LOG_OBJECT (v4lsrc, "VIOIOCSYNC on frame %d done", num); + + v4lsrc->frame_queue_state[num] = QUEUE_STATE_SYNCED; +@@ -168,13 +215,28 @@ gst_v4lsrc_capture_init (GstV4lSrc * v4l GST_V4L_CHECK_OPEN (GST_V4LELEMENT (v4lsrc)); GST_V4L_CHECK_NOT_ACTIVE (GST_V4LELEMENT (v4lsrc)); @@ -49,14 +98,20 @@ * 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), +- 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); ++ int i; ++ ++ GST_V4LELEMENT (v4lsrc)->buffer = (guint8 *) g_malloc0 (sizeof (guint8) * 1024 * 768 * 3 * MIN_BUFFERS_QUEUED); + GST_V4LELEMENT (v4lsrc)->use_read = TRUE; + -+ v4lsrc->frame_queue_state = (gint8 *) g_malloc (sizeof (gint8) * (768 * 3)); ++ v4lsrc->frame_queue_state = (gint8 *) g_malloc (sizeof (gint8) * MIN_BUFFERS_QUEUED); ++ ++ v4lsrc->mbuf.frames = MIN_BUFFERS_QUEUED; ++ for (i = 0; i < MIN_BUFFERS_QUEUED; i++) { ++ v4lsrc->mbuf.offsets[i] = (1024 * 768 * 3 * i); ++ } + + /* lock for the frame_state */ + v4lsrc->mutex_queue_state = g_mutex_new (); @@ -65,7 +120,7 @@ } if (v4lsrc->mbuf.frames < MIN_BUFFERS_QUEUED) { -@@ -205,6 +227,7 @@ gst_v4lsrc_capture_init (GstV4lSrc * v4l +@@ -205,6 +267,7 @@ gst_v4lsrc_capture_init (GstV4lSrc * v4l GST_V4LELEMENT (v4lsrc)->buffer = NULL; return FALSE; } @@ -73,7 +128,7 @@ return TRUE; } -@@ -413,10 +436,14 @@ gst_v4lsrc_capture_deinit (GstV4lSrc * v +@@ -413,10 +476,14 @@ gst_v4lsrc_capture_deinit (GstV4lSrc * v v4lsrc->frame_queue_state = NULL; /* unmap the buffer */ @@ -92,7 +147,7 @@ } GST_V4LELEMENT (v4lsrc)->buffer = NULL; -@@ -446,6 +473,7 @@ gst_v4lsrc_try_capture (GstV4lSrc * v4ls +@@ -446,6 +513,7 @@ gst_v4lsrc_try_capture (GstV4lSrc * v4ls /* so, we need a buffer and some more stuff */ int frame = 0; guint8 *buffer; @@ -100,10 +155,11 @@ struct video_mbuf vmbuf; struct video_mmap vmmap; -@@ -457,16 +485,18 @@ gst_v4lsrc_try_capture (GstV4lSrc * v4ls +@@ -456,17 +524,17 @@ 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), +- GST_ELEMENT_ERROR (v4lsrc, RESOURCE, READ, (NULL), - ("Error getting buffer information: %s", g_strerror (errno))); - return FALSE; - } @@ -114,7 +170,6 @@ - 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 { @@ -129,14 +184,48 @@ } /* now that we have a buffer, let's try out our format */ -@@ -474,6 +504,15 @@ gst_v4lsrc_try_capture (GstV4lSrc * v4ls +@@ -474,6 +542,49 @@ gst_v4lsrc_try_capture (GstV4lSrc * v4ls vmmap.height = height; vmmap.format = palette; vmmap.frame = frame; + if (use_read) { ++ struct video_picture vp; ++ struct video_window vw; ++ ++ if (ioctl (GST_V4LELEMENT (v4lsrc)->video_fd, VIDIOCGPICT, &vp) == -1) { ++ GST_ERROR_OBJECT (v4lsrc, ++ "Error getting current picture info: %s", g_strerror (errno)); ++ g_free (buffer); ++ return FALSE; ++ } ++ ++ vp.palette = palette; ++ if (ioctl (GST_V4LELEMENT (v4lsrc)->video_fd, VIDIOCSPICT, &vp) == -1) { ++ GST_ERROR_OBJECT (v4lsrc, ++ "Error setting picture info: %s", g_strerror (errno)); ++ g_free (buffer); ++ return FALSE; ++ } ++ ++ if (ioctl (GST_V4LELEMENT (v4lsrc)->video_fd, VIDIOCGWIN, &vw) == -1) { ++ GST_ERROR_OBJECT (v4lsrc, ++ "Error getting current window properties: %s", g_strerror (errno)); ++ g_free (buffer); ++ return FALSE; ++ } ++ ++ vw.width = width; ++ vw.height = height; ++ if (ioctl (GST_V4LELEMENT (v4lsrc)->video_fd, VIDIOCSWIN, &vw) == -1) { ++ GST_ERROR_OBJECT (v4lsrc, ++ "Error setting window properties: %s", g_strerror (errno)); ++ g_free (buffer); ++ return FALSE; ++ } ++ + 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)); ++ "Error reading into our try-out buffer: %s", g_strerror (errno)); + g_free (buffer); + return FALSE; + } @@ -145,7 +234,7 @@ 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 +@@ -488,7 +599,11 @@ gst_v4lsrc_try_capture (GstV4lSrc * v4ls return FALSE; } -- cgit v1.2.3