Commit cde8c8bd authored by Andy Wingo Wingo's avatar Andy Wingo Wingo
Browse files

sys/v4l2/v4l2src_calls.c (gst_v4l2_buffer_finalize)...

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.
parent e359a415
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.
2007-06-11 Wim Taymans <wim@fluendo.com>
Patch by: daniel fischer <dan at f3c dot com>
......
......@@ -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
......
......@@ -54,18 +54,22 @@ typedef struct _GstV4l2SrcClass GstV4l2SrcClass;
/* global info */
struct _GstV4l2BufferPool
{
gint refcount; /* number of users: 1 for every buffer, 1 for element */
gint video_fd;
GstMiniObject parent;
GMutex *lock;
gboolean running; /* with lock */
gint num_live_buffers; /* with lock */
gint video_fd; /* a dup(2) of the v4l2object's video_fd */
guint buffer_count;
GstV4l2Buffer *buffers;
GstV4l2Buffer **buffers; /* with lock; buffers[n] is NULL that buffer has been
* dequeued and pushed out */
};
struct _GstV4l2Buffer
{
struct v4l2_buffer buffer;
guint8 *start;
guint length;
gint refcount; /* add 1 if in use by element, add 1 if in use by GstBuffer */
struct _GstV4l2Buffer {
GstBuffer buffer;
struct v4l2_buffer vbuffer;
GstV4l2BufferPool *pool;
};
......
This diff is collapsed.
......@@ -33,11 +33,10 @@ gboolean gst_v4l2src_set_capture (GstV4l2Src * v4l2src,
guint32 width, guint32 height,
guint32 fps_n, guint32 fps_d);
gboolean gst_v4l2src_capture_init (GstV4l2Src * v4l2src);
gboolean gst_v4l2src_capture_init (GstV4l2Src * v4l2src, GstCaps *caps);
gboolean gst_v4l2src_capture_start (GstV4l2Src * v4l2src);
gint gst_v4l2src_grab_frame (GstV4l2Src * v4l2src);
gboolean gst_v4l2src_queue_frame (GstV4l2Src * v4l2src, guint i);
GstFlowReturn gst_v4l2src_grab_frame (GstV4l2Src * v4l2src, GstBuffer **buf);
gboolean gst_v4l2src_capture_stop (GstV4l2Src * v4l2src);
gboolean gst_v4l2src_capture_deinit (GstV4l2Src * v4l2src);
......@@ -52,11 +51,5 @@ gboolean gst_v4l2src_get_size_limits (GstV4l2Src * v4l2src,
struct v4l2_fmtdesc *fmt,
gint * min_w, gint * max_w,
gint * min_h, gint * max_h);
/* buffers */
GstBuffer* gst_v4l2src_buffer_new (GstV4l2Src * v4l2src,
guint size, guint8 * data,
GstV4l2Buffer * srcbuf);
void gst_v4l2src_free_buffer (GstBuffer * buffer);
#endif /* __V4L2SRC_CALLS_H__ */
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment