v4l2: move capture code to device object
authorWim Taymans <wim.taymans@collabora.co.uk>
Wed, 13 Jul 2011 16:32:00 +0000 (18:32 +0200)
committerWim Taymans <wim.taymans@collabora.co.uk>
Wed, 13 Jul 2011 16:32:00 +0000 (18:32 +0200)
Move the details of how to capture to the device object. Remove the
v4l2src_calls.[ch] files because they are empty now.
Provide two simple methods to get and return a buffer to the device.
Also do a slow copy when the buffer is not from our pool.

sys/v4l2/Makefile.am
sys/v4l2/gstv4l2object.c
sys/v4l2/gstv4l2object.h
sys/v4l2/gstv4l2sink.c
sys/v4l2/gstv4l2src.c
sys/v4l2/gstv4l2src.h
sys/v4l2/gstv4l2tuner.c
sys/v4l2/gstv4l2vidorient.c
sys/v4l2/v4l2src_calls.c [deleted file]
sys/v4l2/v4l2src_calls.h [deleted file]

index 9cebead..edf336e 100644 (file)
@@ -17,7 +17,6 @@ libgstvideo4linux2_la_SOURCES = gstv4l2.c \
                                gstv4l2tuner.c \
                                gstv4l2vidorient.c \
                                v4l2_calls.c \
-                               v4l2src_calls.c \
                                $(xv_source)
 libgstvideo4linux2_la_SOURCES += gstv4l2sink.c
 
@@ -53,5 +52,4 @@ noinst_HEADERS = \
        gstv4l2tuner.h \
        gstv4l2vidorient.h \
        gstv4l2xoverlay.h \
-       v4l2_calls.h \
-       v4l2src_calls.h
+       v4l2_calls.h
index 583a094..243edc2 100644 (file)
@@ -52,9 +52,9 @@
 #endif
 
 GST_DEBUG_CATEGORY_EXTERN (v4l2_debug);
+GST_DEBUG_CATEGORY_EXTERN (GST_CAT_PERFORMANCE);
 #define GST_CAT_DEFAULT v4l2_debug
 
-
 #define DEFAULT_PROP_DEVICE_NAME       NULL
 #define DEFAULT_PROP_DEVICE_FD          -1
 #define DEFAULT_PROP_FLAGS              0
@@ -2430,3 +2430,264 @@ stop_failed:
     return FALSE;
   }
 }
+
+static GstFlowReturn
+gst_v4l2_object_get_read (GstV4l2Object * v4l2object, GstBuffer ** buf)
+{
+  GstFlowReturn res;
+  gint amount;
+  gint ret;
+  gpointer data;
+  gint buffersize;
+
+  buffersize = v4l2object->size;
+
+  /* In case the size per frame is unknown assume it's a streaming format (e.g.
+   * mpegts) and grab a reasonable default size instead */
+  if (buffersize == 0)
+    buffersize = 4096;
+
+  *buf = gst_buffer_new_and_alloc (buffersize);
+  data = gst_buffer_map (*buf, NULL, NULL, GST_MAP_WRITE);
+
+  do {
+    ret = gst_poll_wait (v4l2object->poll, GST_CLOCK_TIME_NONE);
+    if (G_UNLIKELY (ret < 0)) {
+      if (errno == EBUSY)
+        goto stopped;
+      if (errno == ENXIO) {
+        GST_DEBUG_OBJECT (v4l2object->element,
+            "v4l2 device doesn't support polling. Disabling");
+        v4l2object->can_poll_device = FALSE;
+      } else {
+        if (errno != EAGAIN && errno != EINTR)
+          goto select_error;
+      }
+    }
+    amount = v4l2_read (v4l2object->video_fd, data, buffersize);
+
+    if (amount == buffersize) {
+      break;
+    } else if (amount == -1) {
+      if (errno == EAGAIN || errno == EINTR) {
+        continue;
+      } else
+        goto read_error;
+    } else {
+      /* short reads can happen if a signal interrupts the read */
+      continue;
+    }
+  } while (TRUE);
+
+  gst_buffer_unmap (*buf, data, amount);
+
+  return GST_FLOW_OK;
+
+  /* ERRORS */
+select_error:
+  {
+    GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, READ, (NULL),
+        ("select error %d: %s (%d)", ret, g_strerror (errno), errno));
+    res = GST_FLOW_ERROR;
+    goto cleanup;
+  }
+stopped:
+  {
+    GST_DEBUG ("stop called");
+    res = GST_FLOW_WRONG_STATE;
+    goto cleanup;
+  }
+read_error:
+  {
+    GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, READ,
+        (_("Error reading %d bytes from device '%s'."),
+            buffersize, v4l2object->videodev), GST_ERROR_SYSTEM);
+    res = GST_FLOW_ERROR;
+    goto cleanup;
+  }
+cleanup:
+  {
+    gst_buffer_unmap (*buf, data, 0);
+    gst_buffer_unref (*buf);
+    return res;
+  }
+}
+
+static GstFlowReturn
+gst_v4l2_object_grab_frame (GstV4l2Object * v4l2object, GstBuffer ** buf)
+{
+#define NUM_TRIALS 50
+  GstV4l2BufferPool *pool;
+  gint32 trials = NUM_TRIALS;
+  GstBuffer *pool_buffer;
+  gboolean need_copy;
+  gint ret;
+
+  pool = v4l2object->pool;
+  if (!pool)
+    goto no_buffer_pool;
+
+  GST_DEBUG_OBJECT (v4l2object->element, "grab frame");
+
+  for (;;) {
+    if (v4l2object->can_poll_device) {
+      ret = gst_poll_wait (v4l2object->poll, GST_CLOCK_TIME_NONE);
+      if (G_UNLIKELY (ret < 0)) {
+        if (errno == EBUSY)
+          goto stopped;
+        if (errno == ENXIO) {
+          GST_DEBUG_OBJECT (v4l2object->element,
+              "v4l2 device doesn't support polling. Disabling");
+          v4l2object->can_poll_device = FALSE;
+        } else {
+          if (errno != EAGAIN && errno != EINTR)
+            goto select_error;
+        }
+      }
+    }
+
+    pool_buffer = gst_v4l2_buffer_pool_dqbuf (pool);
+    if (pool_buffer)
+      break;
+
+    GST_WARNING_OBJECT (v4l2object->element, "trials=%d", trials);
+
+    /* if the sync() got interrupted, we can retry */
+    switch (errno) {
+      case EINVAL:
+      case ENOMEM:
+        /* fatal */
+        return GST_FLOW_ERROR;
+
+      case EAGAIN:
+      case EIO:
+      case EINTR:
+      default:
+        /* try again, until too many trials */
+        break;
+    }
+
+    /* check nr. of attempts to capture */
+    if (--trials == -1) {
+      goto too_many_trials;
+    }
+  }
+
+  /* if we are handing out the last buffer in the pool, we need to make a
+   * copy and bring the buffer back in the pool. */
+  need_copy = v4l2object->always_copy
+      || !gst_v4l2_buffer_pool_available_buffers (pool);
+
+  if (G_UNLIKELY (need_copy)) {
+    if (!v4l2object->always_copy) {
+      GST_CAT_LOG_OBJECT (GST_CAT_PERFORMANCE, v4l2object->element,
+          "running out of buffers, making a copy to reuse current one");
+    }
+    *buf = gst_buffer_copy (pool_buffer);
+    /* this will requeue */
+    gst_buffer_unref (pool_buffer);
+  } else {
+    *buf = pool_buffer;
+  }
+
+  return GST_FLOW_OK;
+
+  /* ERRORS */
+no_buffer_pool:
+  {
+    GST_DEBUG_OBJECT (v4l2object->element, "no buffer pool");
+    return GST_FLOW_WRONG_STATE;
+  }
+select_error:
+  {
+    GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, READ, (NULL),
+        ("select error %d: %s (%d)", ret, g_strerror (errno), errno));
+    return GST_FLOW_ERROR;
+  }
+stopped:
+  {
+    GST_DEBUG ("stop called");
+    return GST_FLOW_WRONG_STATE;
+  }
+too_many_trials:
+  {
+    GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, FAILED,
+        (_("Failed trying to get video frames from device '%s'."),
+            v4l2object->videodev),
+        (_("Failed after %d tries. device %s. system error: %s"),
+            NUM_TRIALS, v4l2object->videodev, g_strerror (errno)));
+    return GST_FLOW_ERROR;
+  }
+}
+
+static GstFlowReturn
+gst_v4l2_object_get_mmap (GstV4l2Object * v4l2object, GstBuffer ** buf)
+{
+  GstBuffer *temp;
+  GstFlowReturn ret;
+  guint size;
+  guint count = 0;
+
+again:
+  ret = gst_v4l2_object_grab_frame (v4l2object, &temp);
+  if (G_UNLIKELY (ret != GST_FLOW_OK))
+    goto done;
+
+  if (v4l2object->size > 0) {
+    size = gst_buffer_get_size (temp);
+
+    /* if size does not match what we expected, try again */
+    if (size != v4l2object->size) {
+      GST_ELEMENT_WARNING (v4l2object->element, RESOURCE, READ,
+          (_("Got unexpected frame size of %u instead of %u."),
+              size, v4l2object->size), (NULL));
+      gst_buffer_unref (temp);
+      if (count++ > 50)
+        goto size_error;
+
+      goto again;
+    }
+  }
+
+  *buf = temp;
+done:
+  return ret;
+
+  /* ERRORS */
+size_error:
+  {
+    GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, READ,
+        (_("Error reading %d bytes on device '%s'."),
+            v4l2object->size, v4l2object->videodev), (NULL));
+    return GST_FLOW_ERROR;
+  }
+}
+
+GstFlowReturn
+gst_v4l2_object_get_buffer (GstV4l2Object * v4l2object, GstBuffer ** buf)
+{
+  GstFlowReturn ret;
+
+  switch (v4l2object->type) {
+    case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+      if (v4l2object->use_mmap) {
+        ret = gst_v4l2_object_get_mmap (v4l2object, buf);
+      } else {
+        ret = gst_v4l2_object_get_read (v4l2object, buf);
+      }
+      break;
+    case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+      ret = GST_FLOW_ERROR;
+      break;
+    default:
+      ret = GST_FLOW_ERROR;
+      break;
+  }
+  return ret;
+}
+
+GstFlowReturn
+gst_v4l2_object_output_buffer (GstV4l2Object * v4l2object, GstBuffer * buf)
+{
+  return GST_FLOW_ERROR;
+}
index 555d2b4..218d43f 100644 (file)
@@ -116,6 +116,7 @@ struct _GstV4l2Object {
 
   /* optional pool */
   guint32 num_buffers;
+  gboolean always_copy;
   gboolean use_mmap;
   GstV4l2BufferPool *pool;
 
@@ -215,8 +216,14 @@ GstStructure* gst_v4l2_object_v4l2fourcc_to_structure (guint32 fourcc);
 
 gboolean      gst_v4l2_object_set_format (GstV4l2Object *v4l2object, GstCaps * caps);
 
-gboolean      gst_v4l2_object_start     (GstV4l2Object *v4l2object);
-gboolean      gst_v4l2_object_stop      (GstV4l2Object *v4l2object);
+gboolean      gst_v4l2_object_start       (GstV4l2Object *v4l2object);
+gboolean      gst_v4l2_object_stop        (GstV4l2Object *v4l2object);
+
+
+/* capture returns a filled buffer, output returns an empty buffer */
+GstFlowReturn gst_v4l2_object_get_buffer     (GstV4l2Object * v4l2object, GstBuffer ** buf);
+/* output the filled buffer */
+GstFlowReturn gst_v4l2_object_output_buffer  (GstV4l2Object * v4l2object, GstBuffer * buf);
 
 
 #define GST_IMPLEMENT_V4L2_PROBE_METHODS(Type_Class, interface_as_function)                 \
index 3ba2fbc..6c9ffb4 100644 (file)
@@ -675,7 +675,7 @@ gst_v4l2sink_show_frame (GstBaseSink * bsink, GstBuffer * buf)
 
   meta = GST_META_V4L2_GET (buf);
 
-  if (meta == NULL) {
+  if (meta == NULL || meta->pool != obj->pool) {
     guint8 *data;
     gsize size;
 
index 6e6e95a..dac2d6a 100644 (file)
 
 #include <string.h>
 #include <sys/time.h>
-#include "v4l2src_calls.h"
 #include <unistd.h>
 
+#include "gstv4l2src.h"
+
 #include "gstv4l2colorbalance.h"
 #include "gstv4l2tuner.h"
 #ifdef HAVE_XVIDEO
@@ -129,12 +130,6 @@ static void gst_v4l2src_set_property (GObject * object, guint prop_id,
 static void gst_v4l2src_get_property (GObject * object, guint prop_id,
     GValue * value, GParamSpec * pspec);
 
-/* get_frame io methods */
-static GstFlowReturn
-gst_v4l2src_get_read (GstV4l2Src * v4l2src, GstBuffer ** buf);
-static GstFlowReturn
-gst_v4l2src_get_mmap (GstV4l2Src * v4l2src, GstBuffer ** buf);
-
 static void
 gst_v4l2src_class_init (GstV4l2SrcClass * klass)
 {
@@ -217,7 +212,7 @@ gst_v4l2src_init (GstV4l2Src * v4l2src)
   /* number of buffers requested */
   v4l2src->v4l2object->num_buffers = PROP_DEF_QUEUE_SIZE;
 
-  v4l2src->always_copy = PROP_DEF_ALWAYS_COPY;
+  v4l2src->v4l2object->always_copy = PROP_DEF_ALWAYS_COPY;
   v4l2src->decimate = PROP_DEF_DECIMATE;
 
   gst_base_src_set_format (GST_BASE_SRC (v4l2src), GST_FORMAT_TIME);
@@ -259,7 +254,7 @@ gst_v4l2src_set_property (GObject * object,
         v4l2src->v4l2object->num_buffers = g_value_get_uint (value);
         break;
       case PROP_ALWAYS_COPY:
-        v4l2src->always_copy = g_value_get_boolean (value);
+        v4l2src->v4l2object->always_copy = g_value_get_boolean (value);
         break;
       case PROP_DECIMATE:
         v4l2src->decimate = g_value_get_int (value);
@@ -284,7 +279,7 @@ gst_v4l2src_get_property (GObject * object,
         g_value_set_uint (value, v4l2src->v4l2object->num_buffers);
         break;
       case PROP_ALWAYS_COPY:
-        g_value_set_boolean (value, v4l2src->always_copy);
+        g_value_set_boolean (value, v4l2src->v4l2object->always_copy);
         break;
       case PROP_DECIMATE:
         g_value_set_int (value, v4l2src->decimate);
@@ -526,12 +521,6 @@ gst_v4l2src_set_caps (GstBaseSrc * src, GstCaps * caps)
     /* error already posted */
     return FALSE;
 
-  if (obj->use_mmap) {
-    v4l2src->get_frame = gst_v4l2src_get_mmap;
-  } else {
-    v4l2src->get_frame = gst_v4l2src_get_read;
-  }
-
   if (!gst_v4l2_object_start (obj))
     return FALSE;
 
@@ -690,151 +679,23 @@ gst_v4l2src_change_state (GstElement * element, GstStateChange transition)
 }
 
 static GstFlowReturn
-gst_v4l2src_get_read (GstV4l2Src * v4l2src, GstBuffer ** buf)
-{
-  GstFlowReturn res;
-  gint amount;
-  gint ret;
-  gpointer data;
-  gint buffersize;
-
-  buffersize = v4l2src->frame_byte_size;
-  /* In case the size per frame is unknown assume it's a streaming format (e.g.
-   * mpegts) and grab a reasonable default size instead */
-  if (buffersize == 0)
-    buffersize = GST_BASE_SRC (v4l2src)->blocksize;
-
-  *buf = gst_buffer_new_and_alloc (buffersize);
-  data = gst_buffer_map (*buf, NULL, NULL, GST_MAP_WRITE);
-
-  do {
-    ret = gst_poll_wait (v4l2src->v4l2object->poll, GST_CLOCK_TIME_NONE);
-    if (G_UNLIKELY (ret < 0)) {
-      if (errno == EBUSY)
-        goto stopped;
-      if (errno == ENXIO) {
-        GST_DEBUG_OBJECT (v4l2src,
-            "v4l2 device doesn't support polling. Disabling");
-        v4l2src->v4l2object->can_poll_device = FALSE;
-      } else {
-        if (errno != EAGAIN && errno != EINTR)
-          goto select_error;
-      }
-    }
-    amount = v4l2_read (v4l2src->v4l2object->video_fd, data, buffersize);
-
-    if (amount == buffersize) {
-      break;
-    } else if (amount == -1) {
-      if (errno == EAGAIN || errno == EINTR) {
-        continue;
-      } else
-        goto read_error;
-    } else {
-      /* short reads can happen if a signal interrupts the read */
-      continue;
-    }
-  } while (TRUE);
-
-  gst_buffer_unmap (*buf, data, amount);
-
-  /* we set the buffer metadata in gst_v4l2src_create() */
-
-  return GST_FLOW_OK;
-
-  /* ERRORS */
-select_error:
-  {
-    GST_ELEMENT_ERROR (v4l2src, RESOURCE, READ, (NULL),
-        ("select error %d: %s (%d)", ret, g_strerror (errno), errno));
-    res = GST_FLOW_ERROR;
-    goto cleanup;
-  }
-stopped:
-  {
-    GST_DEBUG ("stop called");
-    res = GST_FLOW_WRONG_STATE;
-    goto cleanup;
-  }
-read_error:
-  {
-    GST_ELEMENT_ERROR (v4l2src, RESOURCE, READ,
-        (_("Error reading %d bytes from device '%s'."),
-            buffersize, v4l2src->v4l2object->videodev), GST_ERROR_SYSTEM);
-    res = GST_FLOW_ERROR;
-    goto cleanup;
-  }
-cleanup:
-  {
-    gst_buffer_unmap (*buf, data, 0);
-    gst_buffer_unref (*buf);
-    return res;
-  }
-}
-
-static GstFlowReturn
-gst_v4l2src_get_mmap (GstV4l2Src * v4l2src, GstBuffer ** buf)
-{
-  GstBuffer *temp;
-  GstFlowReturn ret;
-  guint size;
-  guint count = 0;
-
-again:
-  ret = gst_v4l2src_grab_frame (v4l2src, &temp);
-  if (G_UNLIKELY (ret != GST_FLOW_OK))
-    goto done;
-
-  if (v4l2src->frame_byte_size > 0) {
-    size = gst_buffer_get_size (temp);
-
-    /* if size does not match what we expected, try again */
-    if (size != v4l2src->frame_byte_size) {
-      GST_ELEMENT_WARNING (v4l2src, RESOURCE, READ,
-          (_("Got unexpected frame size of %u instead of %u."),
-              size, v4l2src->frame_byte_size), (NULL));
-      gst_buffer_unref (temp);
-      if (count++ > 50)
-        goto size_error;
-
-      goto again;
-    }
-  }
-
-  *buf = temp;
-done:
-  return ret;
-
-  /* ERRORS */
-size_error:
-  {
-    GST_ELEMENT_ERROR (v4l2src, RESOURCE, READ,
-        (_("Error reading %d bytes on device '%s'."),
-            v4l2src->frame_byte_size, v4l2src->v4l2object->videodev), (NULL));
-    return GST_FLOW_ERROR;
-  }
-}
-
-static GstFlowReturn
 gst_v4l2src_create (GstPushSrc * src, GstBuffer ** buf)
 {
   GstV4l2Src *v4l2src = GST_V4L2SRC (src);
+  GstV4l2Object *obj = v4l2src->v4l2object;
   int i;
   GstFlowReturn ret;
 
-  if (v4l2src->get_frame == NULL)
-    goto not_negotiated;
-
   /* decimate, just capture and throw away frames */
   for (i = 0; i < v4l2src->decimate - 1; i++) {
-    ret = v4l2src->get_frame (v4l2src, buf);
+    ret = gst_v4l2_object_get_buffer (obj, buf);
     if (ret != GST_FLOW_OK) {
       return ret;
     }
     gst_buffer_unref (*buf);
   }
 
-  ret = v4l2src->get_frame (v4l2src, buf);
+  ret = gst_v4l2_object_get_buffer (obj, buf);
 
   /* set buffer metadata */
   if (G_LIKELY (ret == GST_FLOW_OK && *buf)) {
@@ -857,7 +718,7 @@ gst_v4l2src_create (GstPushSrc * src, GstBuffer ** buf)
     }
     GST_OBJECT_UNLOCK (v4l2src);
 
-    duration = v4l2src->v4l2object->duration;
+    duration = obj->duration;
 
     if (G_LIKELY (clock)) {
       /* the time now is the time of the clock minus the base time */
@@ -891,13 +752,6 @@ gst_v4l2src_create (GstPushSrc * src, GstBuffer ** buf)
     GST_BUFFER_DURATION (*buf) = duration;
   }
   return ret;
-
-  /* ERRORS */
-not_negotiated:
-  {
-    GST_DEBUG_OBJECT (src, "we are not negotiated");
-    return GST_FLOW_NOT_NEGOTIATED;
-  }
 }
 
 
index 95aaaf3..03fd0dd 100644 (file)
@@ -45,8 +45,6 @@ G_BEGIN_DECLS
 typedef struct _GstV4l2Src GstV4l2Src;
 typedef struct _GstV4l2SrcClass GstV4l2SrcClass;
 
-typedef GstFlowReturn (*GstV4l2SrcGetFunc)(GstV4l2Src * v4l2src, GstBuffer ** buf);
-
 /**
  * GstV4l2Src:
  *
@@ -64,16 +62,11 @@ struct _GstV4l2Src
 
   guint32 frame_byte_size;
 
-  /* if the buffer will be or not used from directly mmap */
-  gboolean always_copy;
-
   int decimate;
 
   guint64 offset;
 
   GstClockTime ctrl_time;
-
-  GstV4l2SrcGetFunc get_frame;
 };
 
 struct _GstV4l2SrcClass
index a805396..c885dc6 100644 (file)
@@ -30,7 +30,6 @@
 #include "gstv4l2tuner.h"
 #include "gstv4l2object.h"
 #include "v4l2_calls.h"
-#include "v4l2src_calls.h"
 
 static void gst_v4l2_tuner_channel_class_init (GstV4l2TunerChannelClass *
     klass);
index 1fa47e7..ee765b6 100644 (file)
@@ -29,7 +29,6 @@
 #include "gstv4l2vidorient.h"
 #include "gstv4l2object.h"
 #include "v4l2_calls.h"
-#include "v4l2src_calls.h"
 
 GST_DEBUG_CATEGORY_STATIC (v4l2vo_debug);
 #define GST_CAT_DEFAULT v4l2vo_debug
diff --git a/sys/v4l2/v4l2src_calls.c b/sys/v4l2/v4l2src_calls.c
deleted file mode 100644 (file)
index 148a5b7..0000000
+++ /dev/null
@@ -1,167 +0,0 @@
-/* GStreamer
- *
- * Copyright (C) 2002 Ronald Bultje <rbultje@ronald.bitfreak.net>
- *               2006 Edgard Lima <edgard.lima@indt.org.br>
- *
- * v4l2src.c - system calls
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-#include <sys/mman.h>
-#include <string.h>
-#include <errno.h>
-#include "v4l2src_calls.h"
-#include <sys/time.h>
-#include <unistd.h>
-#ifdef __sun
-/* Needed on older Solaris Nevada builds (72 at least) */
-#include <stropts.h>
-#include <sys/ioccom.h>
-#endif
-
-#include "gstv4l2tuner.h"
-#include "gstv4l2bufferpool.h"
-
-#include "gst/gst-i18n-plugin.h"
-
-#define GST_CAT_DEFAULT v4l2src_debug
-GST_DEBUG_CATEGORY_EXTERN (GST_CAT_PERFORMANCE);
-
-
-/******************************************************
- * gst_v4l2src_grab_frame ():
- *   grab a frame for capturing
- * return value: GST_FLOW_OK, GST_FLOW_WRONG_STATE or GST_FLOW_ERROR
- ******************************************************/
-GstFlowReturn
-gst_v4l2src_grab_frame (GstV4l2Src * v4l2src, GstBuffer ** buf)
-{
-#define NUM_TRIALS 50
-  GstV4l2Object *v4l2object;
-  GstV4l2BufferPool *pool;
-  gint32 trials = NUM_TRIALS;
-  GstBuffer *pool_buffer;
-  gboolean need_copy;
-  gint ret;
-
-  v4l2object = v4l2src->v4l2object;
-  pool = v4l2object->pool;
-  if (!pool)
-    goto no_buffer_pool;
-
-  GST_DEBUG_OBJECT (v4l2src, "grab frame");
-
-  for (;;) {
-    if (v4l2object->can_poll_device) {
-      ret = gst_poll_wait (v4l2object->poll, GST_CLOCK_TIME_NONE);
-      if (G_UNLIKELY (ret < 0)) {
-        if (errno == EBUSY)
-          goto stopped;
-        if (errno == ENXIO) {
-          GST_DEBUG_OBJECT (v4l2src,
-              "v4l2 device doesn't support polling. Disabling");
-          v4l2object->can_poll_device = FALSE;
-        } else {
-          if (errno != EAGAIN && errno != EINTR)
-            goto select_error;
-        }
-      }
-    }
-
-    pool_buffer = gst_v4l2_buffer_pool_dqbuf (pool);
-    if (pool_buffer)
-      break;
-
-    GST_WARNING_OBJECT (v4l2src, "trials=%d", trials);
-
-    /* if the sync() got interrupted, we can retry */
-    switch (errno) {
-      case EINVAL:
-      case ENOMEM:
-        /* fatal */
-        return GST_FLOW_ERROR;
-
-      case EAGAIN:
-      case EIO:
-      case EINTR:
-      default:
-        /* try again, until too many trials */
-        break;
-    }
-
-    /* check nr. of attempts to capture */
-    if (--trials == -1) {
-      goto too_many_trials;
-    }
-  }
-
-  /* if we are handing out the last buffer in the pool, we need to make a
-   * copy and bring the buffer back in the pool. */
-  need_copy = v4l2src->always_copy
-      || !gst_v4l2_buffer_pool_available_buffers (pool);
-
-  if (G_UNLIKELY (need_copy)) {
-    if (!v4l2src->always_copy) {
-      GST_CAT_LOG_OBJECT (GST_CAT_PERFORMANCE, v4l2src,
-          "running out of buffers, making a copy to reuse current one");
-    }
-    *buf = gst_buffer_copy (pool_buffer);
-    /* this will requeue */
-    gst_buffer_unref (pool_buffer);
-  } else {
-    *buf = pool_buffer;
-  }
-  /* we set the buffer metadata in gst_v4l2src_create() */
-
-  return GST_FLOW_OK;
-
-  /* ERRORS */
-no_buffer_pool:
-  {
-    GST_DEBUG ("no buffer pool");
-    return GST_FLOW_WRONG_STATE;
-  }
-select_error:
-  {
-    GST_ELEMENT_ERROR (v4l2src, RESOURCE, READ, (NULL),
-        ("select error %d: %s (%d)", ret, g_strerror (errno), errno));
-    return GST_FLOW_ERROR;
-  }
-stopped:
-  {
-    GST_DEBUG ("stop called");
-    return GST_FLOW_WRONG_STATE;
-  }
-too_many_trials:
-  {
-    GST_ELEMENT_ERROR (v4l2src, RESOURCE, FAILED,
-        (_("Failed trying to get video frames from device '%s'."),
-            v4l2object->videodev),
-        (_("Failed after %d tries. device %s. system error: %s"),
-            NUM_TRIALS, v4l2object->videodev, g_strerror (errno)));
-    return GST_FLOW_ERROR;
-  }
-}
diff --git a/sys/v4l2/v4l2src_calls.h b/sys/v4l2/v4l2src_calls.h
deleted file mode 100644 (file)
index 5aa1d23..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/* GStreamer
- *
- * Copyright (C) 2002 Ronald Bultje <rbultje@ronald.bitfreak.net>
- *               2006 Edgard Lima <edgard.lima@indt.org.br>
- *
- * v4l2src.h - system calls
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __V4L2SRC_CALLS_H__
-#define __V4L2SRC_CALLS_H__
-
-#include "gstv4l2src.h"
-#include "v4l2_calls.h"
-
-GstFlowReturn gst_v4l2src_grab_frame     (GstV4l2Src * v4l2src, GstBuffer **buf);
-
-#endif /* __V4L2SRC_CALLS_H__ */