summaryrefslogtreecommitdiffstats
path: root/sys/v4l2/gstv4l2src.c
diff options
context:
space:
mode:
authorAndy Wingo <wingo@pobox.com>2007-06-12 11:23:01 +0000
committerAndy Wingo <wingo@pobox.com>2007-06-12 11:23:01 +0000
commitcde8c8bdc4b856bcb3a4ac40ad4b48c7180f3526 (patch)
tree76101a54266d81392ba72bcdd95cb8b84cde7d63 /sys/v4l2/gstv4l2src.c
parente359a4151702e89a27742d3905c2f59e821fbf23 (diff)
sys/v4l2/v4l2src_calls.c (gst_v4l2_buffer_finalize) (gst_v4l2_buffer_class_init, gst_v4l2_buffer_get_type)
Original commit message from CVS: 2007-06-12 Andy Wingo <wingo@pobox.com> * sys/v4l2/v4l2src_calls.c (gst_v4l2_buffer_finalize) (gst_v4l2_buffer_class_init, gst_v4l2_buffer_get_type) (gst_v4l2_buffer_new): Behave more like ximagesink's buffers, with finalization and resuscitation. No longer public. (gst_v4l2_buffer_pool_finalize, gst_v4l2_buffer_pool_init) (gst_v4l2_buffer_pool_class_init, gst_v4l2_buffer_pool_get_type) (gst_v4l2_buffer_pool_new, gst_v4l2_buffer_pool_activate) (gst_v4l2_buffer_pool_destroy): Make the pool follow common miniobject semantics, and be threadsafe. (gst_v4l2src_queue_frame): Remove this function, as we just call the ioctls directly in the two places where we queue buffers. (gst_v4l2src_grab_frame): Return a flowreturn and fill the buffer directly. (gst_v4l2src_capture_init): Use the new buffer_pool_new function to allocate the pool, which also preallocates the GstBuffers. (gst_v4l2src_capture_start): Call buffer_pool_activate instead of queueing the frames directly. * sys/v4l2/gstv4l2src.h (struct _GstV4l2BufferPool): Make this a real MiniObject instead of rolling our own refcounting and finalizing. Give it a lock. (struct _GstV4l2Buffer): Remove one intermediary object, having the buffers hold the struct v4l2_buffer directly. * sys/v4l2/gstv4l2src.c (gst_v4l2src_set_caps): Pass the caps to capture_init so that it can set them on the buffers that it will create. (gst_v4l2src_get_read): For better or for worse, include the timestamping and offsetting code here; really we should be using bufferalloc though. (gst_v4l2src_get_mmap): Just make grab_frame return one of our preallocated, mmap'd buffers.
Diffstat (limited to 'sys/v4l2/gstv4l2src.c')
-rw-r--r--sys/v4l2/gstv4l2src.c79
1 files changed, 31 insertions, 48 deletions
diff --git a/sys/v4l2/gstv4l2src.c b/sys/v4l2/gstv4l2src.c
index 67be44e9..d3599483 100644
--- a/sys/v4l2/gstv4l2src.c
+++ b/sys/v4l2/gstv4l2src.c
@@ -817,7 +817,7 @@ gst_v4l2src_set_caps (GstBaseSrc * src, GstCaps * caps)
/* error already posted */
return FALSE;
- if (!gst_v4l2src_capture_init (v4l2src))
+ if (!gst_v4l2src_capture_init (v4l2src, caps))
return FALSE;
if (!gst_v4l2src_capture_start (v4l2src))
@@ -873,7 +873,7 @@ gst_v4l2src_get_read (GstV4l2Src * v4l2src, GstBuffer ** buf)
buffersize = v4l2src->frame_byte_size;
- *buf = gst_v4l2src_buffer_new (v4l2src, buffersize, NULL, NULL);
+ *buf = gst_buffer_new_and_alloc (buffersize);
do {
amount =
@@ -892,6 +892,34 @@ gst_v4l2src_get_read (GstV4l2Src * v4l2src, GstBuffer ** buf)
}
} while (TRUE);
+ GST_BUFFER_OFFSET (*buf) = v4l2src->offset++;
+ GST_BUFFER_OFFSET_END (*buf) = v4l2src->offset;
+ /* timestamps, LOCK to get clock and base time. */
+ {
+ GstClock *clock;
+ GstClockTime timestamp;
+
+ GST_OBJECT_LOCK (v4l2src);
+ if ((clock = GST_ELEMENT_CLOCK (v4l2src))) {
+ /* we have a clock, get base time and ref clock */
+ timestamp = GST_ELEMENT (v4l2src)->base_time;
+ gst_object_ref (clock);
+ } else {
+ /* no clock, can't set timestamps */
+ timestamp = GST_CLOCK_TIME_NONE;
+ }
+ GST_OBJECT_UNLOCK (v4l2src);
+
+ if (clock) {
+ /* the time now is the time of the clock minus the base time */
+ timestamp = gst_clock_get_time (clock) - timestamp;
+ gst_object_unref (clock);
+ }
+
+ /* FIXME: use the timestamp from the buffer itself! */
+ GST_BUFFER_TIMESTAMP (*buf) = timestamp;
+ }
+
return GST_FLOW_OK;
/* ERRORS */
@@ -908,52 +936,7 @@ read_error:
static GstFlowReturn
gst_v4l2src_get_mmap (GstV4l2Src * v4l2src, GstBuffer ** buf)
{
- gint i, num;
-
- /* grab a frame from the device, post an error */
- num = gst_v4l2src_grab_frame (v4l2src);
- if (num == -1)
- goto grab_failed;
-
- i = v4l2src->frame_byte_size;
-
- /* check if this is the last buffer in the queue. If so do a memcpy to put it back asap
- to avoid framedrops and deadlocks because of stupid elements */
- /* FIXME: we should use the userptr interface instead, will remove this
- problem */
- if (g_atomic_int_get (&v4l2src->pool->refcount) == v4l2src->num_buffers) {
- GST_LOG_OBJECT (v4l2src, "using memcpy'd buffer");
-
- *buf = gst_v4l2src_buffer_new (v4l2src, i, NULL, NULL);
- memcpy (GST_BUFFER_DATA (*buf), v4l2src->pool->buffers[num].start, i);
-
- /* posts an error message if something went wrong */
- if (!gst_v4l2src_queue_frame (v4l2src, num))
- goto queue_failed;
- } else {
- GST_LOG_OBJECT (v4l2src, "using mmap'd buffer");
- *buf =
- gst_v4l2src_buffer_new (v4l2src, i, v4l2src->pool->buffers[num].start,
- &v4l2src->pool->buffers[num]);
-
- /* no need to be careful here, both are > 0, because the element uses them */
- g_atomic_int_inc (&v4l2src->pool->buffers[num].refcount);
- g_atomic_int_inc (&v4l2src->pool->refcount);
- }
- return GST_FLOW_OK;
-
- /* ERRORS */
-grab_failed:
- {
- GST_DEBUG_OBJECT (v4l2src, "failed to grab a frame");
- return GST_FLOW_ERROR;
- }
-queue_failed:
- {
- GST_DEBUG_OBJECT (v4l2src, "failed to queue frame");
- gst_buffer_unref (*buf);
- return GST_FLOW_ERROR;
- }
+ return gst_v4l2src_grab_frame (v4l2src, buf);
}
static GstFlowReturn