summaryrefslogtreecommitdiff
path: root/modules/vidbridge
diff options
context:
space:
mode:
authorAlfred E. Heggestad <aeh@db.org>2014-02-09 11:50:07 +0100
committerAlfred E. Heggestad <aeh@db.org>2014-02-09 11:50:07 +0100
commit98bf08bdcf2edd9d397f32650a8bfe62186fbecf (patch)
treeebc6ec71f44bff8c42e4eefced61948623df02fc /modules/vidbridge
parente6ad5cf4401b860ba402d4b7b3c7c254bc87a019 (diff)
baresip 0.4.10
Diffstat (limited to 'modules/vidbridge')
-rw-r--r--modules/vidbridge/disp.c95
-rw-r--r--modules/vidbridge/module.mk11
-rw-r--r--modules/vidbridge/src.c94
-rw-r--r--modules/vidbridge/vidbridge.c58
-rw-r--r--modules/vidbridge/vidbridge.h47
5 files changed, 305 insertions, 0 deletions
diff --git a/modules/vidbridge/disp.c b/modules/vidbridge/disp.c
new file mode 100644
index 0000000..bce9cff
--- /dev/null
+++ b/modules/vidbridge/disp.c
@@ -0,0 +1,95 @@
+/**
+ * @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);
+ mem_deref(st->vd);
+}
+
+
+int vidbridge_disp_alloc(struct vidisp_st **stp, 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 = mem_ref(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..ff9bf70
--- /dev/null
+++ b/modules/vidbridge/src.c
@@ -0,0 +1,94 @@
+/**
+ * @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);
+ mem_deref(st->vs);
+}
+
+
+int vidbridge_src_alloc(struct vidsrc_st **stp, 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 = mem_ref(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..69aa41f
--- /dev/null
+++ b/modules/vidbridge/vidbridge.c
@@ -0,0 +1,58 @@
+/**
+ * @file vidbridge.c Video bridge
+ *
+ * Copyright (C) 2010 Creytiv.com
+ */
+#include <re.h>
+#include <rem.h>
+#include <baresip.h>
+#include "vidbridge.h"
+
+
+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, "vidbridge", vidbridge_disp_alloc,
+ NULL, vidbridge_disp_display, 0);
+ if (err)
+ return err;
+
+ err = vidsrc_register(&vidsrc, "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..15fcdfc
--- /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 {
+ struct vidsrc *vs; /* inheritance (1st) */
+
+ struct le le;
+ struct vidisp_st *vidisp;
+ char *device;
+ vidsrc_frame_h *frameh;
+ void *arg;
+};
+
+
+struct vidisp_st {
+ 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, 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, 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);