Пример #1
0
void vid_free(vid_t vid)
{
    struct vid *v = vid;
    v4l2_stop_capture(v->cam);
    fbd_free(v->fbd);
    if (v->enc)
        jpg_enc_free(v->enc);
    if (v->dec)
        jpg_dec_free(v->dec);
    v4l2_free(v->cam);
    free(v);
}
Пример #2
0
int main(int argc, char *argv[])
{
    app_t a = app_create(0);
    
    v4l2_dev_t v = v4l2_create(a, "/dev/video2", 0, 0);
    v4l2_set_img_proc(v, img_proc, v);
    v4l2_start_capture(v);

    app_exec(a);

    v4l2_stop_capture(v);
    v4l2_free(v);

    app_free(a);

    return 0;
}
Пример #3
0
/**
 * Stops the streaming
 * This could take some time, because the thread is stopped asynchronous.
 */
void video_thread_stop(void)
{
  // Check if not already stopped streaming
  if (!video_thread.is_running) {
    return;
  }

  // Stop the streaming thread
  video_thread.is_running = false;

  // Stop the capturing
  if (!v4l2_stop_capture(video_thread.dev)) {
    printf("[video_thread] Could not stop capture of %s.\n", video_thread.dev->name);
    return;
  }

  // TODO: wait for the thread to finish to be able to start the thread again!
}
Пример #4
0
/**
 * Close the V4L2 device (Thread safe)
 * This needs to be preformed to clean up all the buffers and close the device.
 * Note that this also stops the capturing if it is still capturing.
 * @param[in] *dev The video for linux device to close(cleanup)
 */
void v4l2_close(struct v4l2_device *dev)
{
  uint8_t i;

  // Stop capturing (ignore result as it may already be stopped)
  v4l2_stop_capture(dev);

  // Unmap all buffers
  for (i = 0; i < dev->buffers_cnt; ++i) {
    if (munmap(dev->buffers[i].buf, dev->buffers[i].length) < 0) {
      printf("[v4l2] Could not unmap buffer %d for %s\n", i, dev->name);
    }
  }

  // Close the file pointer and free all memory
  close(dev->fd);
  free(dev->name);
  free(dev);
}
Пример #5
0
int main(int argc, char *argv[])
{
    app_t a = app_create(0);
    jpg_dec_t d = jpg_dec_create();

    v4l2_dev_t v = v4l2_create(a, NULL, 0, 0);
    v4l2_set_img_proc(v, img_proc, d);
    v4l2_start_capture(v);

    app_exec(a);

    v4l2_stop_capture(v);
    v4l2_free(v);
    jpg_dec_free(d);

    app_free(a);

    return 0;
}
Пример #6
0
/*
 * Worker thread to get video data
 */
static void *v4l2_thread(void *vptr)
{
	V4L2_DATA(vptr);
	int r;
	fd_set fds;
	uint8_t *start;
	uint64_t frames;
	uint64_t first_ts;
	struct timeval tv;
	struct v4l2_buffer buf;
	struct obs_source_frame out;
	size_t plane_offsets[MAX_AV_PLANES];

	if (v4l2_start_capture(data->dev, &data->buffers) < 0)
		goto exit;

	frames   = 0;
	first_ts = 0;
	v4l2_prep_obs_frame(data, &out, plane_offsets);

	while (os_event_try(data->event) == EAGAIN) {
		FD_ZERO(&fds);
		FD_SET(data->dev, &fds);
		tv.tv_sec = 1;
		tv.tv_usec = 0;

		r = select(data->dev + 1, &fds, NULL, NULL, &tv);
		if (r < 0) {
			if (errno == EINTR)
				continue;
			blog(LOG_DEBUG, "select failed");
			break;
		} else if (r == 0) {
			blog(LOG_DEBUG, "select timeout");
			continue;
		}

		buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
		buf.memory = V4L2_MEMORY_MMAP;

		if (v4l2_ioctl(data->dev, VIDIOC_DQBUF, &buf) < 0) {
			if (errno == EAGAIN)
				continue;
			blog(LOG_DEBUG, "failed to dequeue buffer");
			break;
		}

		out.timestamp = timeval2ns(buf.timestamp);
		if (!frames)
			first_ts = out.timestamp;
		out.timestamp -= first_ts;

		start = (uint8_t *) data->buffers.info[buf.index].start;
		for (uint_fast32_t i = 0; i < MAX_AV_PLANES; ++i)
			out.data[i] = start + plane_offsets[i];
		obs_source_output_video(data->source, &out);

		if (v4l2_ioctl(data->dev, VIDIOC_QBUF, &buf) < 0) {
			blog(LOG_DEBUG, "failed to enqueue buffer");
			break;
		}

		frames++;
	}

	blog(LOG_INFO, "Stopped capture after %"PRIu64" frames", frames);

exit:
	v4l2_stop_capture(data->dev);
	return NULL;
}