summaryrefslogtreecommitdiff
path: root/modules/vidbridge
diff options
context:
space:
mode:
authorJonas Smedegaard <dr@jones.dk>2018-01-08 22:22:59 +0530
committerJonas Smedegaard <dr@jones.dk>2018-01-08 22:22:59 +0530
commit766bb4acdda738e450630c92d9c37e6cb42d9423 (patch)
tree8277c899ed928c69dfd1251bf889af6c78400f84 /modules/vidbridge
Import baresip_0.5.7.orig.tar.gz
[dgit import orig baresip_0.5.7.orig.tar.gz]
Diffstat (limited to 'modules/vidbridge')
-rw-r--r--modules/vidbridge/disp.c94
-rw-r--r--modules/vidbridge/module.mk11
-rw-r--r--modules/vidbridge/src.c93
-rw-r--r--modules/vidbridge/vidbridge.c78
-rw-r--r--modules/vidbridge/vidbridge.h47
5 files changed, 323 insertions, 0 deletions
diff --git a/modules/vidbridge/disp.c b/modules/vidbridge/disp.c
new file mode 100644
index 0000000..be1e8e5
--- /dev/null
+++ b/modules/vidbridge/disp.c
@@ -0,0 +1,94 @@
+/**
+ * @file vidbridge/disp.c Video bridge -- display
+ *
+ * Copyright (C) 2010 Creytiv.com
+ */
+#include <re.h>
+#include <rem.h>
+#include <baresip.h>
+#include "vidbridge.h"
+
+
+static void destructor(void *arg)
+{
+ struct vidisp_st *st = arg;
+
+ if (st->vidsrc)
+ st->vidsrc->vidisp = NULL;
+
+ list_unlink(&st->le);
+ mem_deref(st->device);
+}
+
+
+int vidbridge_disp_alloc(struct vidisp_st **stp, const struct vidisp *vd,
+ struct vidisp_prm *prm, const char *dev,
+ vidisp_resize_h *resizeh, void *arg)
+{
+ struct vidisp_st *st;
+ int err = 0;
+ (void)prm;
+ (void)resizeh;
+ (void)arg;
+
+ if (!stp || !vd || !dev)
+ return EINVAL;
+
+ st = mem_zalloc(sizeof(*st), destructor);
+ if (!st)
+ return ENOMEM;
+
+ st->vd = vd;
+
+ err = str_dup(&st->device, dev);
+ if (err)
+ goto out;
+
+ /* find the vidsrc with the same device-name */
+ st->vidsrc = vidbridge_src_find(dev);
+ if (st->vidsrc) {
+ st->vidsrc->vidisp = st;
+ }
+
+ hash_append(ht_disp, hash_joaat_str(dev), &st->le, st);
+
+ out:
+ if (err)
+ mem_deref(st);
+ else
+ *stp = st;
+
+ return err;
+}
+
+
+static bool list_apply_handler(struct le *le, void *arg)
+{
+ struct vidisp_st *st = le->data;
+
+ return 0 == str_cmp(st->device, arg);
+}
+
+
+int vidbridge_disp_display(struct vidisp_st *st, const char *title,
+ const struct vidframe *frame)
+{
+ int err = 0;
+ (void)title;
+
+ if (st->vidsrc)
+ vidbridge_src_input(st->vidsrc, frame);
+ else {
+ debug("vidbridge: display: dropping frame (%u x %u)\n",
+ frame->size.w, frame->size.h);
+ }
+
+ return err;
+}
+
+
+struct vidisp_st *vidbridge_disp_find(const char *device)
+{
+ return list_ledata(hash_lookup(ht_disp, hash_joaat_str(device),
+ list_apply_handler, (void *)device));
+}
diff --git a/modules/vidbridge/module.mk b/modules/vidbridge/module.mk
new file mode 100644
index 0000000..13000b6
--- /dev/null
+++ b/modules/vidbridge/module.mk
@@ -0,0 +1,11 @@
+#
+# module.mk
+#
+# Copyright (C) 2010 Creytiv.com
+#
+
+MOD := vidbridge
+$(MOD)_SRCS += vidbridge.c src.c disp.c
+$(MOD)_LFLAGS +=
+
+include mk/mod.mk
diff --git a/modules/vidbridge/src.c b/modules/vidbridge/src.c
new file mode 100644
index 0000000..5e7d08a
--- /dev/null
+++ b/modules/vidbridge/src.c
@@ -0,0 +1,93 @@
+/**
+ * @file vidbridge/src.c Video bridge -- source
+ *
+ * Copyright (C) 2010 Creytiv.com
+ */
+#include <re.h>
+#include <rem.h>
+#include <baresip.h>
+#include "vidbridge.h"
+
+
+static void destructor(void *arg)
+{
+ struct vidsrc_st *st = arg;
+
+ if (st->vidisp)
+ st->vidisp->vidsrc = NULL;
+
+ list_unlink(&st->le);
+ mem_deref(st->device);
+}
+
+
+int vidbridge_src_alloc(struct vidsrc_st **stp, const struct vidsrc *vs,
+ struct media_ctx **ctx, struct vidsrc_prm *prm,
+ const struct vidsz *size, const char *fmt,
+ const char *dev, vidsrc_frame_h *frameh,
+ vidsrc_error_h *errorh, void *arg)
+{
+ struct vidsrc_st *st;
+ int err;
+ (void)ctx;
+ (void)prm;
+ (void)fmt;
+ (void)errorh;
+
+ if (!stp || !size || !frameh)
+ return EINVAL;
+
+ st = mem_zalloc(sizeof(*st), destructor);
+ if (!st)
+ return ENOMEM;
+
+ st->vs = vs;
+ st->frameh = frameh;
+ st->arg = arg;
+
+ err = str_dup(&st->device, dev);
+ if (err)
+ goto out;
+
+ /* find a vidisp device with same name */
+ st->vidisp = vidbridge_disp_find(dev);
+ if (st->vidisp) {
+ st->vidisp->vidsrc = st;
+ }
+
+ hash_append(ht_src, hash_joaat_str(dev), &st->le, st);
+
+ out:
+ if (err)
+ mem_deref(st);
+ else
+ *stp = st;
+
+ return err;
+}
+
+
+static bool list_apply_handler(struct le *le, void *arg)
+{
+ struct vidsrc_st *st = le->data;
+
+ return 0 == str_cmp(st->device, arg);
+}
+
+
+struct vidsrc_st *vidbridge_src_find(const char *device)
+{
+ return list_ledata(hash_lookup(ht_src, hash_joaat_str(device),
+ list_apply_handler, (void *)device));
+}
+
+
+void vidbridge_src_input(const struct vidsrc_st *st,
+ const struct vidframe *frame)
+{
+ if (!st || !frame)
+ return;
+
+ if (st->frameh)
+ st->frameh((struct vidframe *)frame, st->arg);
+}
diff --git a/modules/vidbridge/vidbridge.c b/modules/vidbridge/vidbridge.c
new file mode 100644
index 0000000..557e175
--- /dev/null
+++ b/modules/vidbridge/vidbridge.c
@@ -0,0 +1,78 @@
+/**
+ * @file vidbridge.c Video bridge
+ *
+ * Copyright (C) 2010 Creytiv.com
+ */
+#include <re.h>
+#include <rem.h>
+#include <baresip.h>
+#include "vidbridge.h"
+
+
+/**
+ * @defgroup vidbridge vidbridge
+ *
+ * Video bridge module
+ *
+ * This module can be used to connect two video devices together,
+ * so that all output to VIDISP device is bridged as the input to
+ * a VIDSRC device.
+ *
+ * Sample config:
+ *
+ \verbatim
+ video_display vidbridge,pseudo0
+ video_source vidbridge,pseudo0
+ \endverbatim
+ */
+
+
+static struct vidisp *vidisp;
+static struct vidsrc *vidsrc;
+
+struct hash *ht_src;
+struct hash *ht_disp;
+
+
+static int module_init(void)
+{
+ int err;
+
+ err = hash_alloc(&ht_src, 32);
+ err |= hash_alloc(&ht_disp, 32);
+ if (err)
+ return err;
+
+ err = vidisp_register(&vidisp, baresip_vidispl(),
+ "vidbridge", vidbridge_disp_alloc,
+ NULL, vidbridge_disp_display, 0);
+ if (err)
+ return err;
+
+ err = vidsrc_register(&vidsrc, baresip_vidsrcl(),
+ "vidbridge", vidbridge_src_alloc, NULL);
+ if (err)
+ return err;
+
+ return err;
+}
+
+
+static int module_close(void)
+{
+ vidsrc = mem_deref(vidsrc);
+ vidisp = mem_deref(vidisp);
+
+ ht_src = mem_deref(ht_src);
+ ht_disp = mem_deref(ht_disp);
+
+ return 0;
+}
+
+
+EXPORT_SYM const struct mod_export DECL_EXPORTS(vidbridge) = {
+ "vidbridge",
+ "video",
+ module_init,
+ module_close,
+};
diff --git a/modules/vidbridge/vidbridge.h b/modules/vidbridge/vidbridge.h
new file mode 100644
index 0000000..0fbf68e
--- /dev/null
+++ b/modules/vidbridge/vidbridge.h
@@ -0,0 +1,47 @@
+/**
+ * @file vidbridge.h Video bridge -- internal interface
+ *
+ * Copyright (C) 2010 Creytiv.com
+ */
+
+
+struct vidsrc_st {
+ const struct vidsrc *vs; /* inheritance (1st) */
+
+ struct le le;
+ struct vidisp_st *vidisp;
+ char *device;
+ vidsrc_frame_h *frameh;
+ void *arg;
+};
+
+
+struct vidisp_st {
+ const struct vidisp *vd; /* inheritance (1st) */
+
+ struct le le;
+ struct vidsrc_st *vidsrc;
+ char *device;
+};
+
+
+extern struct hash *ht_src;
+extern struct hash *ht_disp;
+
+
+int vidbridge_disp_alloc(struct vidisp_st **stp, const struct vidisp *vd,
+ struct vidisp_prm *prm, const char *dev,
+ vidisp_resize_h *resizeh, void *arg);
+int vidbridge_disp_display(struct vidisp_st *st, const char *title,
+ const struct vidframe *frame);
+struct vidisp_st *vidbridge_disp_find(const char *device);
+
+
+int vidbridge_src_alloc(struct vidsrc_st **stp, const struct vidsrc *vs,
+ struct media_ctx **ctx, struct vidsrc_prm *prm,
+ const struct vidsz *size, const char *fmt,
+ const char *dev, vidsrc_frame_h *frameh,
+ vidsrc_error_h *errorh, void *arg);
+struct vidsrc_st *vidbridge_src_find(const char *device);
+void vidbridge_src_input(const struct vidsrc_st *st,
+ const struct vidframe *frame);