コード例 #1
0
static GstStateChangeReturn
gst_v4l2sink_change_state (GstElement * element, GstStateChange transition)
{
    GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
    GstV4l2Sink *v4l2sink = GST_V4L2SINK (element);

    GST_DEBUG_OBJECT (v4l2sink, "%d -> %d",
                      GST_STATE_TRANSITION_CURRENT (transition),
                      GST_STATE_TRANSITION_NEXT (transition));

    switch (transition) {
    case GST_STATE_CHANGE_NULL_TO_READY:
        /* open the device */
        if (!gst_v4l2_object_start (v4l2sink->v4l2object))
            return GST_STATE_CHANGE_FAILURE;
        break;
    default:
        break;
    }

    ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);

    switch (transition) {
    case GST_STATE_CHANGE_PAUSED_TO_READY:
        if (v4l2sink->state == STATE_STREAMING) {
            if (!gst_v4l2_object_stop_streaming (v4l2sink->v4l2object)) {
                return GST_STATE_CHANGE_FAILURE;
            }
            v4l2sink->state = STATE_PENDING_STREAMON;
        }
        break;
    case GST_STATE_CHANGE_READY_TO_NULL:
        if (NULL != v4l2sink->pool)
            gst_v4l2_buffer_pool_destroy (v4l2sink->pool);
        v4l2sink->pool = NULL;
        /* close the device */
        if (!gst_v4l2_object_stop (v4l2sink->v4l2object))
            return GST_STATE_CHANGE_FAILURE;
        v4l2sink->state = STATE_OFF;
        break;
    default:
        break;
    }

    return ret;
}
コード例 #2
0
/******************************************************
 * gst_v4l2src_capture_deinit():
 *   deinitialize the capture system
 * return value: TRUE on success, FALSE on error
 ******************************************************/
gboolean
gst_v4l2src_capture_deinit (GstV4l2Src * v4l2src)
{
  GST_DEBUG_OBJECT (v4l2src, "deinitting capture system");

  if (!GST_V4L2_IS_OPEN (v4l2src->v4l2object)) {
    return TRUE;
  }
  if (!GST_V4L2_IS_ACTIVE (v4l2src->v4l2object)) {
    return TRUE;
  }

  if (v4l2src->pool) {
    gst_v4l2_buffer_pool_destroy (v4l2src->pool);
    v4l2src->pool = NULL;
  }

  GST_V4L2_SET_INACTIVE (v4l2src->v4l2object);

  return TRUE;
}
コード例 #3
0
/**
 * gst_v4l2_buffer_pool_new:
 * @v4l2elem:  the v4l2 element (src or sink) that owns this pool
 * @fd:   the video device file descriptor
 * @num_buffers:  the requested number of buffers in the pool
 * @caps:  the caps to set on the buffer
 * @requeuebuf: if %TRUE, and if the pool is still in the running state, a
 *  buffer with no remaining references is immediately passed back to v4l2
 *  (VIDIOC_QBUF), otherwise it is returned to the pool of available buffers
 *  (which can be accessed via gst_v4l2_buffer_pool_get().
 *
 * Construct a new buffer pool.
 *
 * Returns: the new pool, use gst_v4l2_buffer_pool_destroy() to free resources
 */
GstV4l2BufferPool *
gst_v4l2_buffer_pool_new (GstElement * v4l2elem, gint fd, gint num_buffers,
    GstCaps * caps, gboolean requeuebuf, enum v4l2_buf_type type)
{
  GstV4l2BufferPool *pool;
  gint n;
  struct v4l2_requestbuffers breq;

  pool = (GstV4l2BufferPool *) gst_mini_object_new (GST_TYPE_V4L2_BUFFER_POOL);

  pool->video_fd = v4l2_dup (fd);
  if (pool->video_fd < 0)
    goto dup_failed;


  /* first, lets request buffers, and see how many we can get: */
  GST_DEBUG_OBJECT (v4l2elem, "STREAMING, requesting %d MMAP buffers",
      num_buffers);

  memset (&breq, 0, sizeof (struct v4l2_requestbuffers));
  breq.type = type;
  breq.count = num_buffers;
  breq.memory = V4L2_MEMORY_MMAP;

  if (v4l2_ioctl (fd, VIDIOC_REQBUFS, &breq) < 0)
    goto reqbufs_failed;

  GST_LOG_OBJECT (v4l2elem, " count:  %u", breq.count);
  GST_LOG_OBJECT (v4l2elem, " type:   %d", breq.type);
  GST_LOG_OBJECT (v4l2elem, " memory: %d", breq.memory);

  if (breq.count < GST_V4L2_MIN_BUFFERS)
    goto no_buffers;

  if (num_buffers != breq.count) {
    GST_WARNING_OBJECT (v4l2elem, "using %u buffers instead", breq.count);
    num_buffers = breq.count;
  }

  pool->v4l2elem = v4l2elem;
  pool->requeuebuf = requeuebuf;
  pool->type = type;
  pool->buffer_count = num_buffers;
  pool->buffers = g_new0 (GstV4l2Buffer *, num_buffers);
  pool->avail_buffers = g_async_queue_new ();

  /* now, map the buffers: */
  for (n = 0; n < num_buffers; n++) {
    pool->buffers[n] = gst_v4l2_buffer_new (pool, n, caps);
    if (!pool->buffers[n])
      goto buffer_new_failed;
    pool->num_live_buffers++;
    g_async_queue_push (pool->avail_buffers, pool->buffers[n]);
  }

  return pool;

  /* ERRORS */
dup_failed:
  {
    gint errnosave = errno;

    gst_mini_object_unref (GST_MINI_OBJECT (pool));

    errno = errnosave;

    return NULL;
  }
reqbufs_failed:
  {
    GstV4l2Object *v4l2object = get_v4l2_object (v4l2elem);
    GST_ELEMENT_ERROR (v4l2elem, RESOURCE, READ,
        (_("Could not get buffers from device '%s'."),
            v4l2object->videodev),
        ("error requesting %d buffers: %s", num_buffers, g_strerror (errno)));
    return NULL;
  }
no_buffers:
  {
    GstV4l2Object *v4l2object = get_v4l2_object (v4l2elem);
    GST_ELEMENT_ERROR (v4l2elem, RESOURCE, READ,
        (_("Could not get enough buffers from device '%s'."),
            v4l2object->videodev),
        ("we received %d from device '%s', we want at least %d",
            breq.count, v4l2object->videodev, GST_V4L2_MIN_BUFFERS));
    return NULL;
  }
buffer_new_failed:
  {
    gint errnosave = errno;

    gst_v4l2_buffer_pool_destroy (pool);

    errno = errnosave;

    return NULL;
  }
}