1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
|
/*
* Copyright 1994-2022 Olivier Girondel
*
* This file is part of lebiniou.
*
* lebiniou is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* lebiniou 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with lebiniou. If not, see <http://www.gnu.org/licenses/>.
*/
#include "context.h"
#if HAVE_LINUX_VIDEODEV2_H
#include <linux/videodev2.h>
#endif
#if HAVE_SYS_VIDEOIO_H
#include <sys/videoio.h>
#endif
#include "pthread_utils.h"
uint32_t options = BO_NONE;
uint32_t version = 0;
#define DEFAULT_VIDEO_DEVICE "/dev/video2"
static int fdwr = 0;
static void
print_format(const struct v4l2_format* vid_format)
{
#ifdef DEBUG
printf(" vid_format->type : %d\n", vid_format->type);
printf(" vid_format->fmt.pix.width : %d\n", vid_format->fmt.pix.width);
printf(" vid_format->fmt.pix.height : %d\n", vid_format->fmt.pix.height);
printf(" vid_format->fmt.pix.pixelformat : %d\n", vid_format->fmt.pix.pixelformat);
printf(" vid_format->fmt.pix.sizeimage : %d\n", vid_format->fmt.pix.sizeimage);
printf(" vid_format->fmt.pix.field : %d\n", vid_format->fmt.pix.field);
printf(" vid_format->fmt.pix.bytesperline: %d\n", vid_format->fmt.pix.bytesperline);
printf(" vid_format->fmt.pix.colorspace : %d\n\n", vid_format->fmt.pix.colorspace);
#endif
}
int8_t
create(Context_t *ctx)
{
int ret_code;
const char *device = NULL;
struct v4l2_capability vid_caps;
struct v4l2_format vid_format;
if (NULL == (device = getenv("LEBINIOU_V4L2LOOPBACK"))) {
device = DEFAULT_VIDEO_DEVICE;
}
fdwr = open(device, O_WRONLY);
if (fdwr < 0) {
return 0;
}
if ((ret_code = ioctl(fdwr, VIDIOC_QUERYCAP, &vid_caps)) == -1) {
xperror("ioctl(VIDIOC_QUERYCAP)");
}
memset(&vid_format, 0, sizeof(vid_format));
vid_format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
vid_format.fmt.pix.width = WIDTH;
vid_format.fmt.pix.height = HEIGHT;
vid_format.fmt.pix.pixelformat = V4L2_PIX_FMT_RGB24;
vid_format.fmt.pix.field = V4L2_FIELD_NONE;
vid_format.fmt.pix.colorspace = V4L2_COLORSPACE_SRGB;
if ((ret_code = ioctl(fdwr, VIDIOC_S_FMT, &vid_format)) == -1) {
xperror("ioctl(VIDIOC_S_FMT)");
}
print_format(&vid_format);
return 1;
}
void
destroy(Context_t *ctx)
{
close(fdwr);
}
void
run(Context_t *ctx)
{
if (!xpthread_mutex_lock(&ctx->frame_mutex)) {
int ret = write(fdwr, ctx->frame, RGB_BUFFSIZE * sizeof(Pixel_t));
if (ret == -1) {
fprintf(stderr, "%s:%s: write failed\n", __FILE__, __func__);
}
xpthread_mutex_unlock(&ctx->frame_mutex);
}
}
|