3 * Copyright (C) 2002 Ronald Bultje <rbultje@ronald.bitfreak.net>
4 * 2006 Edgard Lima <edgard.lima@indt.org.br>
6 * v4l2src.c - system calls
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
18 * You should have received a copy of the GNU Library General Public
19 * License along with this library; if not, write to the
20 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 * Boston, MA 02111-1307, USA.
29 #include <sys/types.h>
32 #include <sys/ioctl.h>
36 #include "v4l2src_calls.h"
40 /* Needed on older Solaris Nevada builds (72 at least) */
42 #include <sys/ioccom.h>
45 #include "gstv4l2tuner.h"
46 #include "gstv4l2bufferpool.h"
48 #include "gst/gst-i18n-plugin.h"
50 #define GST_CAT_DEFAULT v4l2src_debug
51 GST_DEBUG_CATEGORY_EXTERN (GST_CAT_PERFORMANCE);
54 /******************************************************
55 * gst_v4l2src_grab_frame ():
56 * grab a frame for capturing
57 * return value: GST_FLOW_OK, GST_FLOW_WRONG_STATE or GST_FLOW_ERROR
58 ******************************************************/
60 gst_v4l2src_grab_frame (GstV4l2Src * v4l2src, GstBuffer ** buf)
63 GstV4l2Object *v4l2object;
64 GstV4l2BufferPool *pool;
65 gint32 trials = NUM_TRIALS;
66 GstBuffer *pool_buffer;
70 v4l2object = v4l2src->v4l2object;
71 pool = v4l2object->pool;
75 GST_DEBUG_OBJECT (v4l2src, "grab frame");
78 if (v4l2object->can_poll_device) {
79 ret = gst_poll_wait (v4l2object->poll, GST_CLOCK_TIME_NONE);
80 if (G_UNLIKELY (ret < 0)) {
84 GST_DEBUG_OBJECT (v4l2src,
85 "v4l2 device doesn't support polling. Disabling");
86 v4l2object->can_poll_device = FALSE;
88 if (errno != EAGAIN && errno != EINTR)
94 pool_buffer = gst_v4l2_buffer_pool_dqbuf (pool);
98 GST_WARNING_OBJECT (v4l2src, "trials=%d", trials);
100 /* if the sync() got interrupted, we can retry */
105 return GST_FLOW_ERROR;
111 /* try again, until too many trials */
115 /* check nr. of attempts to capture */
116 if (--trials == -1) {
117 goto too_many_trials;
121 /* if we are handing out the last buffer in the pool, we need to make a
122 * copy and bring the buffer back in the pool. */
123 need_copy = v4l2src->always_copy
124 || !gst_v4l2_buffer_pool_available_buffers (pool);
126 if (G_UNLIKELY (need_copy)) {
127 if (!v4l2src->always_copy) {
128 GST_CAT_LOG_OBJECT (GST_CAT_PERFORMANCE, v4l2src,
129 "running out of buffers, making a copy to reuse current one");
131 *buf = gst_buffer_copy (pool_buffer);
132 /* this will requeue */
133 gst_buffer_unref (pool_buffer);
137 /* we set the buffer metadata in gst_v4l2src_create() */
144 GST_DEBUG ("no buffer pool");
145 return GST_FLOW_WRONG_STATE;
149 GST_ELEMENT_ERROR (v4l2src, RESOURCE, READ, (NULL),
150 ("select error %d: %s (%d)", ret, g_strerror (errno), errno));
151 return GST_FLOW_ERROR;
155 GST_DEBUG ("stop called");
156 return GST_FLOW_WRONG_STATE;
160 GST_ELEMENT_ERROR (v4l2src, RESOURCE, FAILED,
161 (_("Failed trying to get video frames from device '%s'."),
162 v4l2object->videodev),
163 (_("Failed after %d tries. device %s. system error: %s"),
164 NUM_TRIALS, v4l2object->videodev, g_strerror (errno)));
165 return GST_FLOW_ERROR;