summaryrefslogtreecommitdiffstats
path: root/debian/transcode/transcode-1.1.7/import/v4l/import_v4l.c
diff options
context:
space:
mode:
authorMichele Calgaro <michele.calgaro@yahoo.it>2020-09-11 14:38:47 +0900
committerMichele Calgaro <michele.calgaro@yahoo.it>2020-09-11 14:38:47 +0900
commit884c8093d63402a1ad0b502244b791e3c6782be3 (patch)
treea600d4ab0d431a2bdfe4c15b70df43c14fbd8dd0 /debian/transcode/transcode-1.1.7/import/v4l/import_v4l.c
parent14e1aa2006796f147f3f4811fb908a6b01e79253 (diff)
downloadextra-dependencies-884c8093d63402a1ad0b502244b791e3c6782be3.tar.gz
extra-dependencies-884c8093d63402a1ad0b502244b791e3c6782be3.zip
Added debian extra dependency packages.
Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
Diffstat (limited to 'debian/transcode/transcode-1.1.7/import/v4l/import_v4l.c')
-rw-r--r--debian/transcode/transcode-1.1.7/import/v4l/import_v4l.c421
1 files changed, 421 insertions, 0 deletions
diff --git a/debian/transcode/transcode-1.1.7/import/v4l/import_v4l.c b/debian/transcode/transcode-1.1.7/import/v4l/import_v4l.c
new file mode 100644
index 00000000..0dc22cda
--- /dev/null
+++ b/debian/transcode/transcode-1.1.7/import/v4l/import_v4l.c
@@ -0,0 +1,421 @@
+/*
+ * import_v4l.c
+ *
+ * Copyright (C) Thomas Oestreich - February 2002
+ *
+ * This file is part of transcode, a video stream processing tool
+ *
+ * transcode 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, or (at your option)
+ * any later version.
+ *
+ * transcode 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 GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include "transcode.h"
+#include "libtc/libtc.h"
+#include "libtc/optstr.h"
+#include "aclib/imgconvert.h"
+
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+
+#include "videodev.h"
+
+#define MOD_NAME "import_v4l.so"
+#define MOD_VERSION "v0.2.0 (2008-10-26)"
+#define MOD_CODEC "(video) v4l"
+
+static int verbose_flag = TC_QUIET;
+static int capability_flag = TC_CAP_RGB|TC_CAP_YUV;
+
+#define MOD_PRE v4l
+#include "import_def.h"
+
+/*************************************************************************/
+
+/*#define MMAP_DEBUG 1*/
+
+#define MAX_BUFFER 32
+
+typedef struct v4lsource V4LSource;
+struct v4lsource {
+ int video_dev;
+
+ int width;
+ int height;
+ int input;
+ int format;
+
+ struct video_mmap vid_mmap[MAX_BUFFER];
+ int grab_buf_idx;
+ int grab_buf_max;
+ struct video_mbuf vid_mbuf;
+ uint8_t *video_mem;
+ int grabbing_active;
+ int have_new_frame;
+ int totalframecount;
+ int image_size;
+ int image_pixels;
+ int framecount;
+ int fps_update_interval;
+ double fps;
+ double lasttime;
+
+ int (*grab)(V4LSource *vs, uint8_t *buf, size_t bufsize);
+ int (*close)(V4LSource *vs);
+};
+
+/*************************************************************************/
+
+static struct v4lsource VS;
+
+/*************************************************************************/
+
+static int v4lsource_mmap_init(V4LSource *vs);
+static int v4lsource_mmap_grab(V4LSource *vs, uint8_t *buffer, size_t bufsize);
+static int v4lsource_mmap_close(V4LSource *vs);
+
+static int v4lsource_read_init(V4LSource *vs);
+static int v4lsource_read_grab(V4LSource *vs, uint8_t *buffer, size_t bufsize);
+static int v4lsource_read_close(V4LSource *vs);
+
+static int v4lsource_generic_close(V4LSource *vs);
+
+/*************************************************************************/
+
+#define RETURN_IF_ERROR(RET, MSG) do { \
+ if (-1 == (RET)) { \
+ tc_log_perror(MOD_NAME, (MSG)); \
+ return TC_ERROR; \
+ } \
+} while (0)
+
+/*************************************************************************/
+
+static int v4lsource_generic_close(V4LSource *vs)
+{
+ int err = close(vs->video_dev);
+ if (err) {
+ return TC_ERROR;
+ }
+ return TC_OK;
+}
+
+/*************************************************************************/
+
+static int v4lsource_read_init(V4LSource *vs)
+{
+ int ret, flag = 1;
+
+ if (verbose_flag)
+ tc_log_info(MOD_NAME, "capture method: read");
+
+ ret = ioctl(vs->video_dev, VIDIOCCAPTURE, &flag);
+ RETURN_IF_ERROR(ret, "error starting the capture");
+
+ vs->grab = v4lsource_read_grab;
+ vs->close = v4lsource_read_close;
+ return TC_OK;
+}
+
+static int v4lsource_read_grab(V4LSource *vs, uint8_t *buffer, size_t bufsize)
+{
+ ssize_t r = read(vs->video_dev, buffer, bufsize);
+ if (r != bufsize) {
+ return TC_ERROR;
+ }
+ return TC_OK;
+}
+
+static int v4lsource_read_close(V4LSource *vs)
+{
+ int ret, flag = 0;
+
+ ret = ioctl(vs->video_dev, VIDIOCCAPTURE, &flag);
+ RETURN_IF_ERROR(ret, "error stopping the capture");
+
+ return v4lsource_generic_close(vs);
+}
+
+/*************************************************************************/
+
+static int v4lsource_mmap_init(V4LSource *vs)
+{
+ int i, ret;
+
+ if (verbose_flag)
+ tc_log_info(MOD_NAME, "capture method: mmap");
+
+ // retrieve buffer size and offsets
+ ret = ioctl(vs->video_dev, VIDIOCGMBUF, &vs->vid_mbuf);
+ RETURN_IF_ERROR(ret, "error requesting capture buffers");
+
+ if (verbose_flag)
+ tc_log_info(MOD_NAME, "%d frame buffer%s available",
+ vs->vid_mbuf.frames, (vs->vid_mbuf.frames > 1) ?"s" :"");
+ vs->grab_buf_max = vs->vid_mbuf.frames;
+
+ if (!vs->grab_buf_max) {
+ tc_log_error(MOD_NAME, "no frame capture buffer(s) available");
+ return TC_ERROR;
+ }
+
+ vs->video_mem = mmap(0, vs->vid_mbuf.size, PROT_READ|PROT_WRITE, MAP_SHARED, vs->video_dev, 0);
+ if ((uint8_t *) -1 == vs->video_mem) {
+ tc_log_perror(MOD_NAME, "error mapping capture buffers in memory");
+ return TC_ERROR;
+ }
+#ifdef MMAP_DEBUG
+ tc_log_msg(MOD_NAME,
+ "(mmap_init) video_mem base address=%p size=%li",
+ vs->video_mem, (long)vs->vid_mbuf.size);
+#endif
+
+ for (i = 0; i < vs->grab_buf_max; i++) {
+ vs->vid_mmap[i].frame = i;
+ vs->vid_mmap[i].format = vs->format;
+ vs->vid_mmap[i].width = vs->width;
+ vs->vid_mmap[i].height = vs->height;
+#ifdef MMAP_DEBUG
+ tc_log_msg(MOD_NAME,
+ "(mmap_init) setup: mmap buf #%i: %ix%i@0x%x",
+ vs->vid_mmap[i].frame,
+ vs->vid_mmap[i].width, vs->vid_mmap[i].height,
+ vs->vid_mmap[i].format);
+#endif
+ }
+
+ for (i = 1; i < vs->grab_buf_max + 1; i++) {
+ ret = ioctl(vs->video_dev, VIDIOCMCAPTURE, &vs->vid_mmap[i % vs->grab_buf_max]);
+ RETURN_IF_ERROR(ret, "error setting up a capture buffer");
+#ifdef MMAP_DEBUG
+ tc_log_msg(MOD_NAME,
+ "(mmap_init) enqueue: mmap buf #%i",
+ i % vs->grab_buf_max);
+#endif
+ }
+
+ vs->grab = v4lsource_mmap_grab;
+ vs->close = v4lsource_mmap_close;
+ return TC_OK;
+}
+
+
+static int v4lsource_mmap_close(V4LSource *vs)
+{
+ // video device
+ munmap(vs->video_mem, vs->vid_mbuf.size);
+ return v4lsource_generic_close(vs);
+}
+
+static int v4lsource_mmap_grab(V4LSource *vs, uint8_t *buffer, size_t bufsize)
+{
+ uint8_t *p, *planes[3] = { NULL, NULL, NULL };
+ int ret = 0, offset = 0;
+
+ vs->grab_buf_idx = ((vs->grab_buf_idx + 1) % vs->grab_buf_max);
+#ifdef MMAP_DEBUG
+ tc_log_msg(MOD_NAME,
+ "(mmap_grab) querying for buffer #%i",
+ vs->grab_buf_idx);
+#endif
+
+ // wait for next image in the sequence to complete grabbing
+ ret = ioctl(vs->video_dev, VIDIOCSYNC, &vs->vid_mmap[vs->grab_buf_idx]);
+ RETURN_IF_ERROR(ret, "error waiting for new video frame (VIDIOCSYNC)");
+
+ //copy frame
+ offset = vs->vid_mbuf.offsets[vs->grab_buf_idx];
+ p = vs->video_mem + offset;
+#ifdef MMAP_DEBUG
+ tc_log_msg(MOD_NAME,
+ "(mmap_grab) got offset=%i frame pointer=%p",
+ offset, p);
+#endif
+
+ switch (vs->format) {
+ case VIDEO_PALETTE_RGB24: /* fallback */
+ case VIDEO_PALETTE_YUV420P:
+ ac_memcpy(buffer, p, vs->image_size);
+ break;
+ case VIDEO_PALETTE_YUV422:
+ YUV_INIT_PLANES(planes, buffer, IMG_YUV_DEFAULT, vs->width, vs->height);
+ ac_imgconvert(&p, IMG_YUY2, planes, IMG_YUV_DEFAULT, vs->width, vs->height);
+ break;
+ }
+
+ vs->totalframecount++;
+
+ // issue new grab command for this buffer
+ ret = ioctl(vs->video_dev, VIDIOCMCAPTURE, &vs->vid_mmap[vs->grab_buf_idx]);
+ RETURN_IF_ERROR(ret, "error acquiring new video frame (VIDIOCMCAPTURE)");
+
+ return TC_OK;
+}
+
+/*************************************************************************/
+
+static int v4lsource_setup_capture(V4LSource *vs, int w, int h, int fmt)
+{
+ struct video_picture pict;
+ struct video_window win;
+ int ret;
+
+ // picture parameter
+ ret = ioctl(VS.video_dev, VIDIOCGPICT, &pict);
+ RETURN_IF_ERROR(ret, "error getting picture parameters (VIDIOCGPICT)");
+
+ // store variables
+ VS.width = w;
+ VS.height = h;
+ VS.format = fmt;
+ // reset grab counter variables
+ VS.grab_buf_idx = 0;
+ VS.totalframecount = 0;
+ // calculate framebuffer size
+ VS.image_pixels = w * h;
+ switch (VS.format) {
+ case VIDEO_PALETTE_RGB24:
+ VS.image_size = VS.image_pixels * 3;
+ break;
+ case VIDEO_PALETTE_YUV420P:
+ VS.image_size = (VS.image_pixels * 3) / 2;
+ break;
+ case VIDEO_PALETTE_YUV422:
+ VS.image_size = VS.image_pixels * 2; // XXX
+ break;
+ }
+
+ if (fmt == VIDEO_PALETTE_RGB24) {
+ pict.depth = 24;
+ }
+ pict.palette = fmt;
+
+ ret = ioctl(VS.video_dev, VIDIOCSPICT, &pict);
+ RETURN_IF_ERROR(ret, "error setting picture parameters (VIDIOCSPICT)");
+
+ ret = ioctl(vs->video_dev, VIDIOCGWIN, &win);
+ RETURN_IF_ERROR(ret, "error getting capture window properties");
+
+ win.width = vs->width;
+ win.height = vs->height;
+ win.flags = 0; /* no flags */
+
+ ret = ioctl(vs->video_dev, VIDIOCSWIN, &win);
+ RETURN_IF_ERROR(ret, "error getting capture window properties");
+
+ return TC_OK;
+}
+
+/*************************************************************************/
+
+static int v4lsource_init(const char *device, const char *options,
+ int w, int h, int fmt)
+{
+ struct video_capability capability;
+ int ret, use_read = TC_FALSE;
+
+ VS.video_dev = open(device, O_RDWR);
+ if (VS.video_dev == -1) {
+ tc_log_perror(MOD_NAME, "error opening grab device");
+ return TC_ERROR;
+ }
+
+ ret = ioctl(VS.video_dev, VIDIOCGCAP, &capability);
+ RETURN_IF_ERROR(ret, "error quering capabilities (VIDIOCGCAP)");
+
+ if (verbose_flag)
+ tc_log_info(MOD_NAME, "capture device: %s", capability.name);
+ if (!(capability.type & VID_TYPE_CAPTURE)) {
+ tc_log_error(MOD_NAME, "device does NOT support capturing!");
+ return TC_ERROR;
+ }
+
+ ret = v4lsource_setup_capture(&VS, w, h, fmt);
+
+ if (options) {
+ if (optstr_lookup(options, "capture_read")) {
+ use_read = TC_TRUE;
+ }
+ }
+
+ if (use_read) {
+ return v4lsource_read_init(&VS);
+ }
+ return v4lsource_mmap_init(&VS);
+}
+
+/*************************************************************************/
+
+MOD_open
+{
+ int fmt = 0;
+
+ if (verbose_flag)
+ tc_log_warn(MOD_NAME, "this module is deprecated: "
+ "please use import_v4l2 instead");
+ if (param->flag == TC_VIDEO) {
+ // print out
+ param->fd = NULL;
+
+ switch (vob->im_v_codec) {
+ case CODEC_RGB:
+ fmt = VIDEO_PALETTE_RGB24;
+ break;
+ case CODEC_YUV422:
+ fmt = VIDEO_PALETTE_YUV422;
+ break;
+ case CODEC_YUV:
+ fmt = VIDEO_PALETTE_YUV420P;
+ break;
+ }
+
+ if (v4lsource_init(vob->video_in_file, vob->im_v_string,
+ vob->im_v_width, vob->im_v_height, fmt) < 0) {
+ tc_log_error(MOD_NAME, "error grab init");
+ return TC_ERROR;
+ }
+ return TC_OK;
+ }
+ return TC_ERROR;
+}
+
+MOD_decode
+{
+ if (param->flag == TC_VIDEO) {
+ return VS.grab(&VS, param->buffer, param->size);
+ return TC_OK;
+ }
+ return TC_ERROR;
+}
+
+MOD_close
+{
+ if (param->flag == TC_VIDEO) {
+ VS.close(&VS);
+ return TC_OK;
+ }
+ return TC_ERROR;
+}
+
+/*************************************************************************/
+
+/*
+ * Local variables:
+ * c-file-style: "stroustrup"
+ * c-file-offsets: ((case-label . *) (statement-case-intro . *))
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vim: expandtab shiftwidth=4:
+ */