summaryrefslogtreecommitdiff
path: root/modules/omx/module.c
diff options
context:
space:
mode:
Diffstat (limited to 'modules/omx/module.c')
-rw-r--r--modules/omx/module.c133
1 files changed, 133 insertions, 0 deletions
diff --git a/modules/omx/module.c b/modules/omx/module.c
new file mode 100644
index 0000000..b9d04cf
--- /dev/null
+++ b/modules/omx/module.c
@@ -0,0 +1,133 @@
+/**
+ * @file omx/module.c Raspberry Pi VideoCoreIV OpenMAX interface
+ *
+ * Copyright (C) 2016 - 2017 Creytiv.com
+ * Copyright (C) 2016 - 2017 Jonathan Sieber
+ */
+
+
+#include "omx.h"
+
+#include <stdlib.h>
+
+#include <re/re.h>
+#include <rem/rem.h>
+#include <baresip.h>
+
+int omx_vidisp_alloc(struct vidisp_st **vp, const struct vidisp* vd,
+ struct vidisp_prm *prm, const char *dev, vidisp_resize_h *resizeh,
+ void *arg);
+int omx_vidisp_display(struct vidisp_st *st, const char *title,
+ const struct vidframe *frame);
+
+struct vidisp_st {
+ const struct vidisp *vd; /* inheritance */
+ struct vidsz size;
+ struct omx_state* omx;
+};
+
+static struct vidisp* vid;
+
+static struct omx_state omx;
+
+static void destructor(void *arg)
+{
+ struct vidisp_st *st = arg;
+ omx_display_disable(st->omx);
+}
+
+int omx_vidisp_alloc(struct vidisp_st **vp, const struct vidisp* vd,
+ struct vidisp_prm *prm, const char *dev, vidisp_resize_h *resizeh,
+ void *arg)
+{
+ struct vidisp_st *st;
+
+ /* Not used by OMX */
+ (void) prm;
+ (void) dev;
+ (void) resizeh;
+ (void) arg;
+
+ info("omx: vidisp_alloc\n");
+
+ st = mem_zalloc(sizeof(*st), destructor);
+ if (!st)
+ return ENOMEM;
+
+ st->vd = vd;
+ *vp = st;
+
+ st->omx = &omx;
+
+ return 0;
+}
+
+
+int omx_vidisp_display(struct vidisp_st *st, const char *title,
+ const struct vidframe *frame)
+{
+ int err = 0;
+ void* buf;
+ uint32_t len;
+
+ struct vidframe omx_frame;
+
+ (void)title;
+
+ if (frame->fmt != VID_FMT_YUV420P) {
+ return EINVAL;
+ }
+
+ if (!vidsz_cmp(&st->size, &frame->size)) {
+ info("omx: new frame size: w=%d h=%d\n",
+ frame->size.w, frame->size.h);
+ info("omx: linesize[0]=%d\tlinesize[1]=%d\tlinesize[2]=%d\n",
+ frame->linesize[0], frame->linesize[1],
+ frame->linesize[2]);
+ err = omx_display_enable(st->omx,
+ frame->size.w, frame->size.h, frame->linesize[0]);
+ if (err) {
+ error("omx_display_enable failed");
+ return err;
+ }
+ st->size = frame->size;
+ }
+
+ /* Get Buffer Pointer */
+ omx_display_input_buffer(st->omx, &buf, &len);
+
+ vidframe_init_buf(&omx_frame, VID_FMT_YUV420P, &frame->size,
+ buf);
+
+ vidconv(&omx_frame, frame, 0);
+
+ omx_display_flush_buffer(st->omx);
+ return 0;
+}
+
+static int module_init(void)
+{
+ if (omx_init(&omx) != 0) {
+ error("Could not initialize OpenMAX");
+ return ENODEV;
+ }
+
+ return vidisp_register(&vid, "omx",
+ omx_vidisp_alloc, NULL, omx_vidisp_display, NULL);
+}
+
+static int module_close(void)
+{
+ /* HACK: not deinitializing OMX because of a hangup */
+ /* omx_deinit(&omx) */
+ vid = mem_deref(vid);
+ return 0;
+}
+
+
+EXPORT_SYM const struct mod_export DECL_EXPORTS(omx) = {
+ "omx",
+ "vidisp",
+ module_init,
+ module_close
+};