From 98bf08bdcf2edd9d397f32650a8bfe62186fbecf Mon Sep 17 00:00:00 2001 From: "Alfred E. Heggestad" Date: Sun, 9 Feb 2014 11:50:07 +0100 Subject: baresip 0.4.10 --- modules/selfview/module.mk | 11 ++ modules/selfview/selfview.c | 267 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 278 insertions(+) create mode 100644 modules/selfview/module.mk create mode 100644 modules/selfview/selfview.c (limited to 'modules/selfview') diff --git a/modules/selfview/module.mk b/modules/selfview/module.mk new file mode 100644 index 0000000..2719433 --- /dev/null +++ b/modules/selfview/module.mk @@ -0,0 +1,11 @@ +# +# module.mk +# +# Copyright (C) 2010 Creytiv.com +# + +MOD := selfview +$(MOD)_SRCS += selfview.c +$(MOD)_LFLAGS += + +include mk/mod.mk diff --git a/modules/selfview/selfview.c b/modules/selfview/selfview.c new file mode 100644 index 0000000..cf5cdc3 --- /dev/null +++ b/modules/selfview/selfview.c @@ -0,0 +1,267 @@ +/** + * @file selfview.c Selfview Video-Filter + * + * Copyright (C) 2010 Creytiv.com + */ +#include +#include +#include +#include + + +/* shared state */ +struct selfview { + struct lock *lock; /**< Protect frame */ + struct vidframe *frame; /**< Copy of encoded frame */ +}; + +struct selfview_enc { + struct vidfilt_enc_st vf; /**< Inheritance */ + struct selfview *selfview; /**< Ref. to shared state */ + struct vidisp_st *disp; /**< Selfview display */ +}; + +struct selfview_dec { + struct vidfilt_dec_st vf; /**< Inheritance */ + struct selfview *selfview; /**< Ref. to shared state */ +}; + + +static struct vidsz selfview_size = {0, 0}; + + +static void destructor(void *arg) +{ + struct selfview *st = arg; + + lock_write_get(st->lock); + mem_deref(st->frame); + lock_rel(st->lock); + mem_deref(st->lock); +} + + +static void encode_destructor(void *arg) +{ + struct selfview_enc *st = arg; + + list_unlink(&st->vf.le); + mem_deref(st->selfview); + mem_deref(st->disp); +} + + +static void decode_destructor(void *arg) +{ + struct selfview_dec *st = arg; + + list_unlink(&st->vf.le); + mem_deref(st->selfview); +} + + +static int selfview_alloc(struct selfview **selfviewp, void **ctx) +{ + struct selfview *selfview; + int err; + + if (!selfviewp || !ctx) + return EINVAL; + + if (*ctx) { + *selfviewp = mem_ref(*ctx); + } + else { + selfview = mem_zalloc(sizeof(*selfview), destructor); + if (!selfview) + return ENOMEM; + + err = lock_alloc(&selfview->lock); + if (err) + return err; + + *ctx = selfview; + *selfviewp = selfview; + } + + return 0; +} + + +static int encode_update(struct vidfilt_enc_st **stp, void **ctx, + const struct vidfilt *vf) +{ + struct selfview_enc *st; + int err; + + if (!stp || !ctx || !vf) + return EINVAL; + + if (*stp) + return 0; + + st = mem_zalloc(sizeof(*st), encode_destructor); + if (!st) + return ENOMEM; + + err = selfview_alloc(&st->selfview, ctx); + + if (err) + mem_deref(st); + else + *stp = (struct vidfilt_enc_st *)st; + + return err; +} + + +static int decode_update(struct vidfilt_dec_st **stp, void **ctx, + const struct vidfilt *vf) +{ + struct selfview_dec *st; + int err; + + if (!stp || !ctx || !vf) + return EINVAL; + + st = mem_zalloc(sizeof(*st), decode_destructor); + if (!st) + return ENOMEM; + + err = selfview_alloc(&st->selfview, ctx); + + if (err) + mem_deref(st); + else + *stp = (struct vidfilt_dec_st *)st; + + return err; +} + + +static int encode_win(struct vidfilt_enc_st *st, struct vidframe *frame) +{ + struct selfview_enc *enc = (struct selfview_enc *)st; + int err; + + if (!frame) + return 0; + + if (!enc->disp) { + + err = vidisp_alloc(&enc->disp, NULL, NULL, NULL, NULL, NULL); + if (err) + return err; + } + + return vidisp_display(enc->disp, "Selfview", frame); +} + + +static int encode_pip(struct vidfilt_enc_st *st, struct vidframe *frame) +{ + struct selfview_enc *enc = (struct selfview_enc *)st; + struct selfview *selfview = enc->selfview; + int err = 0; + + if (!frame) + return 0; + + lock_write_get(selfview->lock); + if (!selfview->frame) { + struct vidsz sz; + + /* Use size if configured, or else 20% of main window */ + if (selfview_size.w && selfview_size.h) { + sz = selfview_size; + } + else { + sz.w = frame->size.w / 5; + sz.h = frame->size.h / 5; + } + + err = vidframe_alloc(&selfview->frame, VID_FMT_YUV420P, &sz); + } + if (!err) + vidconv(selfview->frame, frame, NULL); + lock_rel(selfview->lock); + + return err; +} + + +static int decode_pip(struct vidfilt_dec_st *st, struct vidframe *frame) +{ + struct selfview_dec *dec = (struct selfview_dec *)st; + struct selfview *sv = dec->selfview; + + if (!frame) + return 0; + + lock_read_get(sv->lock); + if (sv->frame) { + struct vidrect rect; + + rect.w = min(sv->frame->size.w, frame->size.w/2); + rect.h = min(sv->frame->size.h, frame->size.h/2); + if (rect.w <= (frame->size.w - 10)) + rect.x = frame->size.w - rect.w - 10; + else + rect.x = frame->size.w/2; + if (rect.h <= (frame->size.h - 10)) + rect.y = frame->size.h - rect.h - 10; + else + rect.y = frame->size.h/2; + + vidconv(frame, sv->frame, &rect); + + vidframe_draw_rect(frame, rect.x, rect.y, rect.w, rect.h, + 127, 127, 127); + } + lock_rel(sv->lock); + + return 0; +} + + +static struct vidfilt selfview_win = { + LE_INIT, "selfview_window", encode_update, encode_win, NULL, NULL +}; +static struct vidfilt selfview_pip = { + LE_INIT, "selfview_pip", + encode_update, encode_pip, decode_update, decode_pip +}; + + +static int module_init(void) +{ + struct pl pl; + + if (conf_get(conf_cur(), "video_selfview", &pl)) + return 0; + + if (0 == pl_strcasecmp(&pl, "window")) + vidfilt_register(&selfview_win); + else if (0 == pl_strcasecmp(&pl, "pip")) + vidfilt_register(&selfview_pip); + + (void)conf_get_vidsz(conf_cur(), "selfview_size", &selfview_size); + + return 0; +} + + +static int module_close(void) +{ + vidfilt_unregister(&selfview_win); + vidfilt_unregister(&selfview_pip); + return 0; +} + + +EXPORT_SYM const struct mod_export DECL_EXPORTS(selfview) = { + "selfview", + "vidfilt", + module_init, + module_close +}; -- cgit v1.2.3