You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
7519 lines
219 KiB
Diff
7519 lines
219 KiB
Diff
From 85961f2d8f646488acb86f996c78a1f9ad57cb0a Mon Sep 17 00:00:00 2001
|
|
From: Dave Stevenson <dave.stevenson@raspberrypi.org>
|
|
Date: Mon, 24 Sep 2018 16:30:37 +0100
|
|
Subject: [PATCH] staging: vc04_services: Split vchiq-mmal into a
|
|
module
|
|
|
|
In preparation for adding a video codec V4L2 module which also
|
|
wants to use vchiq-mmal functions, split it out into an
|
|
independent module.
|
|
The minimum number of changes have been made to achieve this
|
|
(eg straight moves where possible) so existing checkpatch
|
|
errors will still be present.
|
|
|
|
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org>
|
|
---
|
|
drivers/staging/vc04_services/Kconfig | 1 +
|
|
drivers/staging/vc04_services/Makefile | 1 +
|
|
.../vc04_services/bcm2835-camera/Kconfig | 2 +-
|
|
.../vc04_services/bcm2835-camera/Makefile | 5 +++--
|
|
.../staging/vc04_services/vchiq-mmal/Kconfig | 7 ++++++
|
|
.../staging/vc04_services/vchiq-mmal/Makefile | 8 +++++++
|
|
.../mmal-common.h | 0
|
|
.../mmal-encodings.h | 0
|
|
.../mmal-msg-common.h | 0
|
|
.../mmal-msg-format.h | 0
|
|
.../mmal-msg-port.h | 0
|
|
.../{bcm2835-camera => vchiq-mmal}/mmal-msg.h | 0
|
|
.../mmal-parameters.h | 0
|
|
.../mmal-vchiq.c | 22 +++++++++++++++++++
|
|
.../mmal-vchiq.h | 0
|
|
15 files changed, 43 insertions(+), 3 deletions(-)
|
|
create mode 100644 drivers/staging/vc04_services/vchiq-mmal/Kconfig
|
|
create mode 100644 drivers/staging/vc04_services/vchiq-mmal/Makefile
|
|
rename drivers/staging/vc04_services/{bcm2835-camera => vchiq-mmal}/mmal-common.h (100%)
|
|
rename drivers/staging/vc04_services/{bcm2835-camera => vchiq-mmal}/mmal-encodings.h (100%)
|
|
rename drivers/staging/vc04_services/{bcm2835-camera => vchiq-mmal}/mmal-msg-common.h (100%)
|
|
rename drivers/staging/vc04_services/{bcm2835-camera => vchiq-mmal}/mmal-msg-format.h (100%)
|
|
rename drivers/staging/vc04_services/{bcm2835-camera => vchiq-mmal}/mmal-msg-port.h (100%)
|
|
rename drivers/staging/vc04_services/{bcm2835-camera => vchiq-mmal}/mmal-msg.h (100%)
|
|
rename drivers/staging/vc04_services/{bcm2835-camera => vchiq-mmal}/mmal-parameters.h (100%)
|
|
rename drivers/staging/vc04_services/{bcm2835-camera => vchiq-mmal}/mmal-vchiq.c (98%)
|
|
rename drivers/staging/vc04_services/{bcm2835-camera => vchiq-mmal}/mmal-vchiq.h (100%)
|
|
|
|
--- a/drivers/staging/vc04_services/Kconfig
|
|
+++ b/drivers/staging/vc04_services/Kconfig
|
|
@@ -22,6 +22,7 @@ config BCM2835_VCHIQ
|
|
source "drivers/staging/vc04_services/bcm2835-audio/Kconfig"
|
|
|
|
source "drivers/staging/vc04_services/bcm2835-camera/Kconfig"
|
|
+source "drivers/staging/vc04_services/vchiq-mmal/Kconfig"
|
|
|
|
endif
|
|
|
|
--- a/drivers/staging/vc04_services/Makefile
|
|
+++ b/drivers/staging/vc04_services/Makefile
|
|
@@ -12,6 +12,7 @@ vchiq-objs := \
|
|
|
|
obj-$(CONFIG_SND_BCM2835) += bcm2835-audio/
|
|
obj-$(CONFIG_VIDEO_BCM2835) += bcm2835-camera/
|
|
+obj-$(CONFIG_BCM2835_VCHIQ_MMAL) += vchiq-mmal/
|
|
|
|
ccflags-y += -Idrivers/staging/vc04_services -D__VCCOREVER__=0x04000000
|
|
|
|
--- a/drivers/staging/vc04_services/bcm2835-camera/Kconfig
|
|
+++ b/drivers/staging/vc04_services/bcm2835-camera/Kconfig
|
|
@@ -3,7 +3,7 @@ config VIDEO_BCM2835
|
|
tristate "BCM2835 Camera"
|
|
depends on MEDIA_SUPPORT
|
|
depends on VIDEO_V4L2 && (ARCH_BCM2835 || COMPILE_TEST)
|
|
- select BCM2835_VCHIQ
|
|
+ select BCM2835_VCHIQ_MMAL
|
|
select VIDEOBUF2_VMALLOC
|
|
select BTREE
|
|
help
|
|
--- a/drivers/staging/vc04_services/bcm2835-camera/Makefile
|
|
+++ b/drivers/staging/vc04_services/bcm2835-camera/Makefile
|
|
@@ -1,11 +1,12 @@
|
|
# SPDX-License-Identifier: GPL-2.0
|
|
bcm2835-v4l2-$(CONFIG_VIDEO_BCM2835) := \
|
|
bcm2835-camera.o \
|
|
- controls.o \
|
|
- mmal-vchiq.o
|
|
+ controls.o
|
|
|
|
obj-$(CONFIG_VIDEO_BCM2835) += bcm2835-v4l2.o
|
|
|
|
ccflags-y += \
|
|
-I $(srctree)/$(src)/.. \
|
|
+ -Idrivers/staging/vc04_services \
|
|
+ -Idrivers/staging/vc04_services/vchiq-mmal \
|
|
-D__VCCOREVER__=0x04000000
|
|
--- /dev/null
|
|
+++ b/drivers/staging/vc04_services/vchiq-mmal/Kconfig
|
|
@@ -0,0 +1,7 @@
|
|
+config BCM2835_VCHIQ_MMAL
|
|
+ tristate "BCM2835 MMAL VCHIQ service"
|
|
+ depends on (ARCH_BCM2835 || COMPILE_TEST)
|
|
+ select BCM2835_VCHIQ
|
|
+ help
|
|
+ Enables the MMAL API over VCHIQ as used for the
|
|
+ majority of the multimedia services on VideoCore.
|
|
--- /dev/null
|
|
+++ b/drivers/staging/vc04_services/vchiq-mmal/Makefile
|
|
@@ -0,0 +1,8 @@
|
|
+# SPDX-License-Identifier: GPL-2.0
|
|
+bcm2835-mmal-vchiq-objs := mmal-vchiq.o
|
|
+
|
|
+obj-$(CONFIG_BCM2835_VCHIQ_MMAL) += bcm2835-mmal-vchiq.o
|
|
+
|
|
+ccflags-y += \
|
|
+ -Idrivers/staging/vc04_services \
|
|
+ -D__VCCOREVER__=0x04000000
|
|
--- a/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.c
|
|
+++ /dev/null
|
|
@@ -1,1891 +0,0 @@
|
|
-// SPDX-License-Identifier: GPL-2.0
|
|
-/*
|
|
- * Broadcom BM2835 V4L2 driver
|
|
- *
|
|
- * Copyright © 2013 Raspberry Pi (Trading) Ltd.
|
|
- *
|
|
- * Authors: Vincent Sanders @ Collabora
|
|
- * Dave Stevenson @ Broadcom
|
|
- * (now dave.stevenson@raspberrypi.org)
|
|
- * Simon Mellor @ Broadcom
|
|
- * Luke Diamand @ Broadcom
|
|
- *
|
|
- * V4L2 driver MMAL vchiq interface code
|
|
- */
|
|
-
|
|
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
|
-
|
|
-#include <linux/errno.h>
|
|
-#include <linux/kernel.h>
|
|
-#include <linux/mutex.h>
|
|
-#include <linux/mm.h>
|
|
-#include <linux/slab.h>
|
|
-#include <linux/completion.h>
|
|
-#include <linux/vmalloc.h>
|
|
-#include <media/videobuf2-vmalloc.h>
|
|
-
|
|
-#include "mmal-common.h"
|
|
-#include "mmal-vchiq.h"
|
|
-#include "mmal-msg.h"
|
|
-
|
|
-#define USE_VCHIQ_ARM
|
|
-#include "interface/vchi/vchi.h"
|
|
-
|
|
-/* maximum number of components supported */
|
|
-#define VCHIQ_MMAL_MAX_COMPONENTS 4
|
|
-
|
|
-/*#define FULL_MSG_DUMP 1*/
|
|
-
|
|
-#ifdef DEBUG
|
|
-static const char *const msg_type_names[] = {
|
|
- "UNKNOWN",
|
|
- "QUIT",
|
|
- "SERVICE_CLOSED",
|
|
- "GET_VERSION",
|
|
- "COMPONENT_CREATE",
|
|
- "COMPONENT_DESTROY",
|
|
- "COMPONENT_ENABLE",
|
|
- "COMPONENT_DISABLE",
|
|
- "PORT_INFO_GET",
|
|
- "PORT_INFO_SET",
|
|
- "PORT_ACTION",
|
|
- "BUFFER_FROM_HOST",
|
|
- "BUFFER_TO_HOST",
|
|
- "GET_STATS",
|
|
- "PORT_PARAMETER_SET",
|
|
- "PORT_PARAMETER_GET",
|
|
- "EVENT_TO_HOST",
|
|
- "GET_CORE_STATS_FOR_PORT",
|
|
- "OPAQUE_ALLOCATOR",
|
|
- "CONSUME_MEM",
|
|
- "LMK",
|
|
- "OPAQUE_ALLOCATOR_DESC",
|
|
- "DRM_GET_LHS32",
|
|
- "DRM_GET_TIME",
|
|
- "BUFFER_FROM_HOST_ZEROLEN",
|
|
- "PORT_FLUSH",
|
|
- "HOST_LOG",
|
|
-};
|
|
-#endif
|
|
-
|
|
-static const char *const port_action_type_names[] = {
|
|
- "UNKNOWN",
|
|
- "ENABLE",
|
|
- "DISABLE",
|
|
- "FLUSH",
|
|
- "CONNECT",
|
|
- "DISCONNECT",
|
|
- "SET_REQUIREMENTS",
|
|
-};
|
|
-
|
|
-#if defined(DEBUG)
|
|
-#if defined(FULL_MSG_DUMP)
|
|
-#define DBG_DUMP_MSG(MSG, MSG_LEN, TITLE) \
|
|
- do { \
|
|
- pr_debug(TITLE" type:%s(%d) length:%d\n", \
|
|
- msg_type_names[(MSG)->h.type], \
|
|
- (MSG)->h.type, (MSG_LEN)); \
|
|
- print_hex_dump(KERN_DEBUG, "<<h: ", DUMP_PREFIX_OFFSET, \
|
|
- 16, 4, (MSG), \
|
|
- sizeof(struct mmal_msg_header), 1); \
|
|
- print_hex_dump(KERN_DEBUG, "<<p: ", DUMP_PREFIX_OFFSET, \
|
|
- 16, 4, \
|
|
- ((u8 *)(MSG)) + sizeof(struct mmal_msg_header),\
|
|
- (MSG_LEN) - sizeof(struct mmal_msg_header), 1); \
|
|
- } while (0)
|
|
-#else
|
|
-#define DBG_DUMP_MSG(MSG, MSG_LEN, TITLE) \
|
|
- { \
|
|
- pr_debug(TITLE" type:%s(%d) length:%d\n", \
|
|
- msg_type_names[(MSG)->h.type], \
|
|
- (MSG)->h.type, (MSG_LEN)); \
|
|
- }
|
|
-#endif
|
|
-#else
|
|
-#define DBG_DUMP_MSG(MSG, MSG_LEN, TITLE)
|
|
-#endif
|
|
-
|
|
-struct vchiq_mmal_instance;
|
|
-
|
|
-/* normal message context */
|
|
-struct mmal_msg_context {
|
|
- struct vchiq_mmal_instance *instance;
|
|
-
|
|
- /* Index in the context_map idr so that we can find the
|
|
- * mmal_msg_context again when servicing the VCHI reply.
|
|
- */
|
|
- int handle;
|
|
-
|
|
- union {
|
|
- struct {
|
|
- /* work struct for buffer_cb callback */
|
|
- struct work_struct work;
|
|
- /* work struct for deferred callback */
|
|
- struct work_struct buffer_to_host_work;
|
|
- /* mmal instance */
|
|
- struct vchiq_mmal_instance *instance;
|
|
- /* mmal port */
|
|
- struct vchiq_mmal_port *port;
|
|
- /* actual buffer used to store bulk reply */
|
|
- struct mmal_buffer *buffer;
|
|
- /* amount of buffer used */
|
|
- unsigned long buffer_used;
|
|
- /* MMAL buffer flags */
|
|
- u32 mmal_flags;
|
|
- /* Presentation and Decode timestamps */
|
|
- s64 pts;
|
|
- s64 dts;
|
|
-
|
|
- int status; /* context status */
|
|
-
|
|
- } bulk; /* bulk data */
|
|
-
|
|
- struct {
|
|
- /* message handle to release */
|
|
- struct vchi_held_msg msg_handle;
|
|
- /* pointer to received message */
|
|
- struct mmal_msg *msg;
|
|
- /* received message length */
|
|
- u32 msg_len;
|
|
- /* completion upon reply */
|
|
- struct completion cmplt;
|
|
- } sync; /* synchronous response */
|
|
- } u;
|
|
-
|
|
-};
|
|
-
|
|
-struct vchiq_mmal_instance {
|
|
- VCHI_SERVICE_HANDLE_T handle;
|
|
-
|
|
- /* ensure serialised access to service */
|
|
- struct mutex vchiq_mutex;
|
|
-
|
|
- /* vmalloc page to receive scratch bulk xfers into */
|
|
- void *bulk_scratch;
|
|
-
|
|
- struct idr context_map;
|
|
- /* protect accesses to context_map */
|
|
- struct mutex context_map_lock;
|
|
-
|
|
- /* component to use next */
|
|
- int component_idx;
|
|
- struct vchiq_mmal_component component[VCHIQ_MMAL_MAX_COMPONENTS];
|
|
-
|
|
- /* ordered workqueue to process all bulk operations */
|
|
- struct workqueue_struct *bulk_wq;
|
|
-};
|
|
-
|
|
-static struct mmal_msg_context *
|
|
-get_msg_context(struct vchiq_mmal_instance *instance)
|
|
-{
|
|
- struct mmal_msg_context *msg_context;
|
|
- int handle;
|
|
-
|
|
- /* todo: should this be allocated from a pool to avoid kzalloc */
|
|
- msg_context = kzalloc(sizeof(*msg_context), GFP_KERNEL);
|
|
-
|
|
- if (!msg_context)
|
|
- return ERR_PTR(-ENOMEM);
|
|
-
|
|
- /* Create an ID that will be passed along with our message so
|
|
- * that when we service the VCHI reply, we can look up what
|
|
- * message is being replied to.
|
|
- */
|
|
- mutex_lock(&instance->context_map_lock);
|
|
- handle = idr_alloc(&instance->context_map, msg_context,
|
|
- 0, 0, GFP_KERNEL);
|
|
- mutex_unlock(&instance->context_map_lock);
|
|
-
|
|
- if (handle < 0) {
|
|
- kfree(msg_context);
|
|
- return ERR_PTR(handle);
|
|
- }
|
|
-
|
|
- msg_context->instance = instance;
|
|
- msg_context->handle = handle;
|
|
-
|
|
- return msg_context;
|
|
-}
|
|
-
|
|
-static struct mmal_msg_context *
|
|
-lookup_msg_context(struct vchiq_mmal_instance *instance, int handle)
|
|
-{
|
|
- return idr_find(&instance->context_map, handle);
|
|
-}
|
|
-
|
|
-static void
|
|
-release_msg_context(struct mmal_msg_context *msg_context)
|
|
-{
|
|
- struct vchiq_mmal_instance *instance = msg_context->instance;
|
|
-
|
|
- mutex_lock(&instance->context_map_lock);
|
|
- idr_remove(&instance->context_map, msg_context->handle);
|
|
- mutex_unlock(&instance->context_map_lock);
|
|
- kfree(msg_context);
|
|
-}
|
|
-
|
|
-/* deals with receipt of event to host message */
|
|
-static void event_to_host_cb(struct vchiq_mmal_instance *instance,
|
|
- struct mmal_msg *msg, u32 msg_len)
|
|
-{
|
|
- pr_debug("unhandled event\n");
|
|
- pr_debug("component:%u port type:%d num:%d cmd:0x%x length:%d\n",
|
|
- msg->u.event_to_host.client_component,
|
|
- msg->u.event_to_host.port_type,
|
|
- msg->u.event_to_host.port_num,
|
|
- msg->u.event_to_host.cmd, msg->u.event_to_host.length);
|
|
-}
|
|
-
|
|
-/* workqueue scheduled callback
|
|
- *
|
|
- * we do this because it is important we do not call any other vchiq
|
|
- * sync calls from witin the message delivery thread
|
|
- */
|
|
-static void buffer_work_cb(struct work_struct *work)
|
|
-{
|
|
- struct mmal_msg_context *msg_context =
|
|
- container_of(work, struct mmal_msg_context, u.bulk.work);
|
|
-
|
|
- atomic_dec(&msg_context->u.bulk.port->buffers_with_vpu);
|
|
-
|
|
- msg_context->u.bulk.port->buffer_cb(msg_context->u.bulk.instance,
|
|
- msg_context->u.bulk.port,
|
|
- msg_context->u.bulk.status,
|
|
- msg_context->u.bulk.buffer,
|
|
- msg_context->u.bulk.buffer_used,
|
|
- msg_context->u.bulk.mmal_flags,
|
|
- msg_context->u.bulk.dts,
|
|
- msg_context->u.bulk.pts);
|
|
-}
|
|
-
|
|
-/* workqueue scheduled callback to handle receiving buffers
|
|
- *
|
|
- * VCHI will allow up to 4 bulk receives to be scheduled before blocking.
|
|
- * If we block in the service_callback context then we can't process the
|
|
- * VCHI_CALLBACK_BULK_RECEIVED message that would otherwise allow the blocked
|
|
- * vchi_bulk_queue_receive() call to complete.
|
|
- */
|
|
-static void buffer_to_host_work_cb(struct work_struct *work)
|
|
-{
|
|
- struct mmal_msg_context *msg_context =
|
|
- container_of(work, struct mmal_msg_context,
|
|
- u.bulk.buffer_to_host_work);
|
|
- struct vchiq_mmal_instance *instance = msg_context->instance;
|
|
- unsigned long len = msg_context->u.bulk.buffer_used;
|
|
- int ret;
|
|
-
|
|
- if (!len)
|
|
- /* Dummy receive to ensure the buffers remain in order */
|
|
- len = 8;
|
|
- /* queue the bulk submission */
|
|
- vchi_service_use(instance->handle);
|
|
- ret = vchi_bulk_queue_receive(instance->handle,
|
|
- msg_context->u.bulk.buffer->buffer,
|
|
- /* Actual receive needs to be a multiple
|
|
- * of 4 bytes
|
|
- */
|
|
- (len + 3) & ~3,
|
|
- VCHI_FLAGS_CALLBACK_WHEN_OP_COMPLETE |
|
|
- VCHI_FLAGS_BLOCK_UNTIL_QUEUED,
|
|
- msg_context);
|
|
-
|
|
- vchi_service_release(instance->handle);
|
|
-
|
|
- if (ret != 0)
|
|
- pr_err("%s: ctx: %p, vchi_bulk_queue_receive failed %d\n",
|
|
- __func__, msg_context, ret);
|
|
-}
|
|
-
|
|
-/* enqueue a bulk receive for a given message context */
|
|
-static int bulk_receive(struct vchiq_mmal_instance *instance,
|
|
- struct mmal_msg *msg,
|
|
- struct mmal_msg_context *msg_context)
|
|
-{
|
|
- unsigned long rd_len;
|
|
-
|
|
- rd_len = msg->u.buffer_from_host.buffer_header.length;
|
|
-
|
|
- if (!msg_context->u.bulk.buffer) {
|
|
- pr_err("bulk.buffer not configured - error in buffer_from_host\n");
|
|
-
|
|
- /* todo: this is a serious error, we should never have
|
|
- * committed a buffer_to_host operation to the mmal
|
|
- * port without the buffer to back it up (underflow
|
|
- * handling) and there is no obvious way to deal with
|
|
- * this - how is the mmal servie going to react when
|
|
- * we fail to do the xfer and reschedule a buffer when
|
|
- * it arrives? perhaps a starved flag to indicate a
|
|
- * waiting bulk receive?
|
|
- */
|
|
-
|
|
- return -EINVAL;
|
|
- }
|
|
-
|
|
- /* ensure we do not overrun the available buffer */
|
|
- if (rd_len > msg_context->u.bulk.buffer->buffer_size) {
|
|
- rd_len = msg_context->u.bulk.buffer->buffer_size;
|
|
- pr_warn("short read as not enough receive buffer space\n");
|
|
- /* todo: is this the correct response, what happens to
|
|
- * the rest of the message data?
|
|
- */
|
|
- }
|
|
-
|
|
- /* store length */
|
|
- msg_context->u.bulk.buffer_used = rd_len;
|
|
- msg_context->u.bulk.dts = msg->u.buffer_from_host.buffer_header.dts;
|
|
- msg_context->u.bulk.pts = msg->u.buffer_from_host.buffer_header.pts;
|
|
-
|
|
- queue_work(msg_context->instance->bulk_wq,
|
|
- &msg_context->u.bulk.buffer_to_host_work);
|
|
-
|
|
- return 0;
|
|
-}
|
|
-
|
|
-/* data in message, memcpy from packet into output buffer */
|
|
-static int inline_receive(struct vchiq_mmal_instance *instance,
|
|
- struct mmal_msg *msg,
|
|
- struct mmal_msg_context *msg_context)
|
|
-{
|
|
- memcpy(msg_context->u.bulk.buffer->buffer,
|
|
- msg->u.buffer_from_host.short_data,
|
|
- msg->u.buffer_from_host.payload_in_message);
|
|
-
|
|
- msg_context->u.bulk.buffer_used =
|
|
- msg->u.buffer_from_host.payload_in_message;
|
|
-
|
|
- return 0;
|
|
-}
|
|
-
|
|
-/* queue the buffer availability with MMAL_MSG_TYPE_BUFFER_FROM_HOST */
|
|
-static int
|
|
-buffer_from_host(struct vchiq_mmal_instance *instance,
|
|
- struct vchiq_mmal_port *port, struct mmal_buffer *buf)
|
|
-{
|
|
- struct mmal_msg_context *msg_context;
|
|
- struct mmal_msg m;
|
|
- int ret;
|
|
-
|
|
- if (!port->enabled)
|
|
- return -EINVAL;
|
|
-
|
|
- pr_debug("instance:%p buffer:%p\n", instance->handle, buf);
|
|
-
|
|
- /* get context */
|
|
- if (!buf->msg_context) {
|
|
- pr_err("%s: msg_context not allocated, buf %p\n", __func__,
|
|
- buf);
|
|
- return -EINVAL;
|
|
- }
|
|
- msg_context = buf->msg_context;
|
|
-
|
|
- /* store bulk message context for when data arrives */
|
|
- msg_context->u.bulk.instance = instance;
|
|
- msg_context->u.bulk.port = port;
|
|
- msg_context->u.bulk.buffer = buf;
|
|
- msg_context->u.bulk.buffer_used = 0;
|
|
-
|
|
- /* initialise work structure ready to schedule callback */
|
|
- INIT_WORK(&msg_context->u.bulk.work, buffer_work_cb);
|
|
- INIT_WORK(&msg_context->u.bulk.buffer_to_host_work,
|
|
- buffer_to_host_work_cb);
|
|
-
|
|
- atomic_inc(&port->buffers_with_vpu);
|
|
-
|
|
- /* prep the buffer from host message */
|
|
- memset(&m, 0xbc, sizeof(m)); /* just to make debug clearer */
|
|
-
|
|
- m.h.type = MMAL_MSG_TYPE_BUFFER_FROM_HOST;
|
|
- m.h.magic = MMAL_MAGIC;
|
|
- m.h.context = msg_context->handle;
|
|
- m.h.status = 0;
|
|
-
|
|
- /* drvbuf is our private data passed back */
|
|
- m.u.buffer_from_host.drvbuf.magic = MMAL_MAGIC;
|
|
- m.u.buffer_from_host.drvbuf.component_handle = port->component->handle;
|
|
- m.u.buffer_from_host.drvbuf.port_handle = port->handle;
|
|
- m.u.buffer_from_host.drvbuf.client_context = msg_context->handle;
|
|
-
|
|
- /* buffer header */
|
|
- m.u.buffer_from_host.buffer_header.cmd = 0;
|
|
- m.u.buffer_from_host.buffer_header.data =
|
|
- (u32)(unsigned long)buf->buffer;
|
|
- m.u.buffer_from_host.buffer_header.alloc_size = buf->buffer_size;
|
|
- m.u.buffer_from_host.buffer_header.length = 0; /* nothing used yet */
|
|
- m.u.buffer_from_host.buffer_header.offset = 0; /* no offset */
|
|
- m.u.buffer_from_host.buffer_header.flags = 0; /* no flags */
|
|
- m.u.buffer_from_host.buffer_header.pts = MMAL_TIME_UNKNOWN;
|
|
- m.u.buffer_from_host.buffer_header.dts = MMAL_TIME_UNKNOWN;
|
|
-
|
|
- /* clear buffer type sepecific data */
|
|
- memset(&m.u.buffer_from_host.buffer_header_type_specific, 0,
|
|
- sizeof(m.u.buffer_from_host.buffer_header_type_specific));
|
|
-
|
|
- /* no payload in message */
|
|
- m.u.buffer_from_host.payload_in_message = 0;
|
|
-
|
|
- vchi_service_use(instance->handle);
|
|
-
|
|
- ret = vchi_queue_kernel_message(instance->handle,
|
|
- &m,
|
|
- sizeof(struct mmal_msg_header) +
|
|
- sizeof(m.u.buffer_from_host));
|
|
-
|
|
- vchi_service_release(instance->handle);
|
|
-
|
|
- return ret;
|
|
-}
|
|
-
|
|
-/* deals with receipt of buffer to host message */
|
|
-static void buffer_to_host_cb(struct vchiq_mmal_instance *instance,
|
|
- struct mmal_msg *msg, u32 msg_len)
|
|
-{
|
|
- struct mmal_msg_context *msg_context;
|
|
- u32 handle;
|
|
-
|
|
- pr_debug("%s: instance:%p msg:%p msg_len:%d\n",
|
|
- __func__, instance, msg, msg_len);
|
|
-
|
|
- if (msg->u.buffer_from_host.drvbuf.magic == MMAL_MAGIC) {
|
|
- handle = msg->u.buffer_from_host.drvbuf.client_context;
|
|
- msg_context = lookup_msg_context(instance, handle);
|
|
-
|
|
- if (!msg_context) {
|
|
- pr_err("drvbuf.client_context(%u) is invalid\n",
|
|
- handle);
|
|
- return;
|
|
- }
|
|
- } else {
|
|
- pr_err("MMAL_MSG_TYPE_BUFFER_TO_HOST with bad magic\n");
|
|
- return;
|
|
- }
|
|
-
|
|
- msg_context->u.bulk.mmal_flags =
|
|
- msg->u.buffer_from_host.buffer_header.flags;
|
|
-
|
|
- if (msg->h.status != MMAL_MSG_STATUS_SUCCESS) {
|
|
- /* message reception had an error */
|
|
- pr_warn("error %d in reply\n", msg->h.status);
|
|
-
|
|
- msg_context->u.bulk.status = msg->h.status;
|
|
-
|
|
- } else if (msg->u.buffer_from_host.buffer_header.length == 0) {
|
|
- /* empty buffer */
|
|
- if (msg->u.buffer_from_host.buffer_header.flags &
|
|
- MMAL_BUFFER_HEADER_FLAG_EOS) {
|
|
- msg_context->u.bulk.status =
|
|
- bulk_receive(instance, msg, msg_context);
|
|
- if (msg_context->u.bulk.status == 0)
|
|
- return; /* successful bulk submission, bulk
|
|
- * completion will trigger callback
|
|
- */
|
|
- } else {
|
|
- /* do callback with empty buffer - not EOS though */
|
|
- msg_context->u.bulk.status = 0;
|
|
- msg_context->u.bulk.buffer_used = 0;
|
|
- }
|
|
- } else if (msg->u.buffer_from_host.payload_in_message == 0) {
|
|
- /* data is not in message, queue a bulk receive */
|
|
- msg_context->u.bulk.status =
|
|
- bulk_receive(instance, msg, msg_context);
|
|
- if (msg_context->u.bulk.status == 0)
|
|
- return; /* successful bulk submission, bulk
|
|
- * completion will trigger callback
|
|
- */
|
|
-
|
|
- /* failed to submit buffer, this will end badly */
|
|
- pr_err("error %d on bulk submission\n",
|
|
- msg_context->u.bulk.status);
|
|
-
|
|
- } else if (msg->u.buffer_from_host.payload_in_message <=
|
|
- MMAL_VC_SHORT_DATA) {
|
|
- /* data payload within message */
|
|
- msg_context->u.bulk.status = inline_receive(instance, msg,
|
|
- msg_context);
|
|
- } else {
|
|
- pr_err("message with invalid short payload\n");
|
|
-
|
|
- /* signal error */
|
|
- msg_context->u.bulk.status = -EINVAL;
|
|
- msg_context->u.bulk.buffer_used =
|
|
- msg->u.buffer_from_host.payload_in_message;
|
|
- }
|
|
-
|
|
- /* schedule the port callback */
|
|
- schedule_work(&msg_context->u.bulk.work);
|
|
-}
|
|
-
|
|
-static void bulk_receive_cb(struct vchiq_mmal_instance *instance,
|
|
- struct mmal_msg_context *msg_context)
|
|
-{
|
|
- msg_context->u.bulk.status = 0;
|
|
-
|
|
- /* schedule the port callback */
|
|
- schedule_work(&msg_context->u.bulk.work);
|
|
-}
|
|
-
|
|
-static void bulk_abort_cb(struct vchiq_mmal_instance *instance,
|
|
- struct mmal_msg_context *msg_context)
|
|
-{
|
|
- pr_err("%s: bulk ABORTED msg_context:%p\n", __func__, msg_context);
|
|
-
|
|
- msg_context->u.bulk.status = -EINTR;
|
|
-
|
|
- schedule_work(&msg_context->u.bulk.work);
|
|
-}
|
|
-
|
|
-/* incoming event service callback */
|
|
-static void service_callback(void *param,
|
|
- const VCHI_CALLBACK_REASON_T reason,
|
|
- void *bulk_ctx)
|
|
-{
|
|
- struct vchiq_mmal_instance *instance = param;
|
|
- int status;
|
|
- u32 msg_len;
|
|
- struct mmal_msg *msg;
|
|
- struct vchi_held_msg msg_handle;
|
|
- struct mmal_msg_context *msg_context;
|
|
-
|
|
- if (!instance) {
|
|
- pr_err("Message callback passed NULL instance\n");
|
|
- return;
|
|
- }
|
|
-
|
|
- switch (reason) {
|
|
- case VCHI_CALLBACK_MSG_AVAILABLE:
|
|
- status = vchi_msg_hold(instance->handle, (void **)&msg,
|
|
- &msg_len, VCHI_FLAGS_NONE, &msg_handle);
|
|
- if (status) {
|
|
- pr_err("Unable to dequeue a message (%d)\n", status);
|
|
- break;
|
|
- }
|
|
-
|
|
- DBG_DUMP_MSG(msg, msg_len, "<<< reply message");
|
|
-
|
|
- /* handling is different for buffer messages */
|
|
- switch (msg->h.type) {
|
|
- case MMAL_MSG_TYPE_BUFFER_FROM_HOST:
|
|
- vchi_held_msg_release(&msg_handle);
|
|
- break;
|
|
-
|
|
- case MMAL_MSG_TYPE_EVENT_TO_HOST:
|
|
- event_to_host_cb(instance, msg, msg_len);
|
|
- vchi_held_msg_release(&msg_handle);
|
|
-
|
|
- break;
|
|
-
|
|
- case MMAL_MSG_TYPE_BUFFER_TO_HOST:
|
|
- buffer_to_host_cb(instance, msg, msg_len);
|
|
- vchi_held_msg_release(&msg_handle);
|
|
- break;
|
|
-
|
|
- default:
|
|
- /* messages dependent on header context to complete */
|
|
- if (!msg->h.context) {
|
|
- pr_err("received message context was null!\n");
|
|
- vchi_held_msg_release(&msg_handle);
|
|
- break;
|
|
- }
|
|
-
|
|
- msg_context = lookup_msg_context(instance,
|
|
- msg->h.context);
|
|
- if (!msg_context) {
|
|
- pr_err("received invalid message context %u!\n",
|
|
- msg->h.context);
|
|
- vchi_held_msg_release(&msg_handle);
|
|
- break;
|
|
- }
|
|
-
|
|
- /* fill in context values */
|
|
- msg_context->u.sync.msg_handle = msg_handle;
|
|
- msg_context->u.sync.msg = msg;
|
|
- msg_context->u.sync.msg_len = msg_len;
|
|
-
|
|
- /* todo: should this check (completion_done()
|
|
- * == 1) for no one waiting? or do we need a
|
|
- * flag to tell us the completion has been
|
|
- * interrupted so we can free the message and
|
|
- * its context. This probably also solves the
|
|
- * message arriving after interruption todo
|
|
- * below
|
|
- */
|
|
-
|
|
- /* complete message so caller knows it happened */
|
|
- complete(&msg_context->u.sync.cmplt);
|
|
- break;
|
|
- }
|
|
-
|
|
- break;
|
|
-
|
|
- case VCHI_CALLBACK_BULK_RECEIVED:
|
|
- bulk_receive_cb(instance, bulk_ctx);
|
|
- break;
|
|
-
|
|
- case VCHI_CALLBACK_BULK_RECEIVE_ABORTED:
|
|
- bulk_abort_cb(instance, bulk_ctx);
|
|
- break;
|
|
-
|
|
- case VCHI_CALLBACK_SERVICE_CLOSED:
|
|
- /* TODO: consider if this requires action if received when
|
|
- * driver is not explicitly closing the service
|
|
- */
|
|
- break;
|
|
-
|
|
- default:
|
|
- pr_err("Received unhandled message reason %d\n", reason);
|
|
- break;
|
|
- }
|
|
-}
|
|
-
|
|
-static int send_synchronous_mmal_msg(struct vchiq_mmal_instance *instance,
|
|
- struct mmal_msg *msg,
|
|
- unsigned int payload_len,
|
|
- struct mmal_msg **msg_out,
|
|
- struct vchi_held_msg *msg_handle_out)
|
|
-{
|
|
- struct mmal_msg_context *msg_context;
|
|
- int ret;
|
|
- unsigned long timeout;
|
|
-
|
|
- /* payload size must not cause message to exceed max size */
|
|
- if (payload_len >
|
|
- (MMAL_MSG_MAX_SIZE - sizeof(struct mmal_msg_header))) {
|
|
- pr_err("payload length %d exceeds max:%d\n", payload_len,
|
|
- (int)(MMAL_MSG_MAX_SIZE -
|
|
- sizeof(struct mmal_msg_header)));
|
|
- return -EINVAL;
|
|
- }
|
|
-
|
|
- msg_context = get_msg_context(instance);
|
|
- if (IS_ERR(msg_context))
|
|
- return PTR_ERR(msg_context);
|
|
-
|
|
- init_completion(&msg_context->u.sync.cmplt);
|
|
-
|
|
- msg->h.magic = MMAL_MAGIC;
|
|
- msg->h.context = msg_context->handle;
|
|
- msg->h.status = 0;
|
|
-
|
|
- DBG_DUMP_MSG(msg, (sizeof(struct mmal_msg_header) + payload_len),
|
|
- ">>> sync message");
|
|
-
|
|
- vchi_service_use(instance->handle);
|
|
-
|
|
- ret = vchi_queue_kernel_message(instance->handle,
|
|
- msg,
|
|
- sizeof(struct mmal_msg_header) +
|
|
- payload_len);
|
|
-
|
|
- vchi_service_release(instance->handle);
|
|
-
|
|
- if (ret) {
|
|
- pr_err("error %d queuing message\n", ret);
|
|
- release_msg_context(msg_context);
|
|
- return ret;
|
|
- }
|
|
-
|
|
- timeout = wait_for_completion_timeout(&msg_context->u.sync.cmplt,
|
|
- 3 * HZ);
|
|
- if (timeout == 0) {
|
|
- pr_err("timed out waiting for sync completion\n");
|
|
- ret = -ETIME;
|
|
- /* todo: what happens if the message arrives after aborting */
|
|
- release_msg_context(msg_context);
|
|
- return ret;
|
|
- }
|
|
-
|
|
- *msg_out = msg_context->u.sync.msg;
|
|
- *msg_handle_out = msg_context->u.sync.msg_handle;
|
|
- release_msg_context(msg_context);
|
|
-
|
|
- return 0;
|
|
-}
|
|
-
|
|
-static void dump_port_info(struct vchiq_mmal_port *port)
|
|
-{
|
|
- pr_debug("port handle:0x%x enabled:%d\n", port->handle, port->enabled);
|
|
-
|
|
- pr_debug("buffer minimum num:%d size:%d align:%d\n",
|
|
- port->minimum_buffer.num,
|
|
- port->minimum_buffer.size, port->minimum_buffer.alignment);
|
|
-
|
|
- pr_debug("buffer recommended num:%d size:%d align:%d\n",
|
|
- port->recommended_buffer.num,
|
|
- port->recommended_buffer.size,
|
|
- port->recommended_buffer.alignment);
|
|
-
|
|
- pr_debug("buffer current values num:%d size:%d align:%d\n",
|
|
- port->current_buffer.num,
|
|
- port->current_buffer.size, port->current_buffer.alignment);
|
|
-
|
|
- pr_debug("elementary stream: type:%d encoding:0x%x variant:0x%x\n",
|
|
- port->format.type,
|
|
- port->format.encoding, port->format.encoding_variant);
|
|
-
|
|
- pr_debug(" bitrate:%d flags:0x%x\n",
|
|
- port->format.bitrate, port->format.flags);
|
|
-
|
|
- if (port->format.type == MMAL_ES_TYPE_VIDEO) {
|
|
- pr_debug
|
|
- ("es video format: width:%d height:%d colourspace:0x%x\n",
|
|
- port->es.video.width, port->es.video.height,
|
|
- port->es.video.color_space);
|
|
-
|
|
- pr_debug(" : crop xywh %d,%d,%d,%d\n",
|
|
- port->es.video.crop.x,
|
|
- port->es.video.crop.y,
|
|
- port->es.video.crop.width, port->es.video.crop.height);
|
|
- pr_debug(" : framerate %d/%d aspect %d/%d\n",
|
|
- port->es.video.frame_rate.num,
|
|
- port->es.video.frame_rate.den,
|
|
- port->es.video.par.num, port->es.video.par.den);
|
|
- }
|
|
-}
|
|
-
|
|
-static void port_to_mmal_msg(struct vchiq_mmal_port *port, struct mmal_port *p)
|
|
-{
|
|
- /* todo do readonly fields need setting at all? */
|
|
- p->type = port->type;
|
|
- p->index = port->index;
|
|
- p->index_all = 0;
|
|
- p->is_enabled = port->enabled;
|
|
- p->buffer_num_min = port->minimum_buffer.num;
|
|
- p->buffer_size_min = port->minimum_buffer.size;
|
|
- p->buffer_alignment_min = port->minimum_buffer.alignment;
|
|
- p->buffer_num_recommended = port->recommended_buffer.num;
|
|
- p->buffer_size_recommended = port->recommended_buffer.size;
|
|
-
|
|
- /* only three writable fields in a port */
|
|
- p->buffer_num = port->current_buffer.num;
|
|
- p->buffer_size = port->current_buffer.size;
|
|
- p->userdata = (u32)(unsigned long)port;
|
|
-}
|
|
-
|
|
-static int port_info_set(struct vchiq_mmal_instance *instance,
|
|
- struct vchiq_mmal_port *port)
|
|
-{
|
|
- int ret;
|
|
- struct mmal_msg m;
|
|
- struct mmal_msg *rmsg;
|
|
- struct vchi_held_msg rmsg_handle;
|
|
-
|
|
- pr_debug("setting port info port %p\n", port);
|
|
- if (!port)
|
|
- return -1;
|
|
- dump_port_info(port);
|
|
-
|
|
- m.h.type = MMAL_MSG_TYPE_PORT_INFO_SET;
|
|
-
|
|
- m.u.port_info_set.component_handle = port->component->handle;
|
|
- m.u.port_info_set.port_type = port->type;
|
|
- m.u.port_info_set.port_index = port->index;
|
|
-
|
|
- port_to_mmal_msg(port, &m.u.port_info_set.port);
|
|
-
|
|
- /* elementary stream format setup */
|
|
- m.u.port_info_set.format.type = port->format.type;
|
|
- m.u.port_info_set.format.encoding = port->format.encoding;
|
|
- m.u.port_info_set.format.encoding_variant =
|
|
- port->format.encoding_variant;
|
|
- m.u.port_info_set.format.bitrate = port->format.bitrate;
|
|
- m.u.port_info_set.format.flags = port->format.flags;
|
|
-
|
|
- memcpy(&m.u.port_info_set.es, &port->es,
|
|
- sizeof(union mmal_es_specific_format));
|
|
-
|
|
- m.u.port_info_set.format.extradata_size = port->format.extradata_size;
|
|
- memcpy(&m.u.port_info_set.extradata, port->format.extradata,
|
|
- port->format.extradata_size);
|
|
-
|
|
- ret = send_synchronous_mmal_msg(instance, &m,
|
|
- sizeof(m.u.port_info_set),
|
|
- &rmsg, &rmsg_handle);
|
|
- if (ret)
|
|
- return ret;
|
|
-
|
|
- if (rmsg->h.type != MMAL_MSG_TYPE_PORT_INFO_SET) {
|
|
- /* got an unexpected message type in reply */
|
|
- ret = -EINVAL;
|
|
- goto release_msg;
|
|
- }
|
|
-
|
|
- /* return operation status */
|
|
- ret = -rmsg->u.port_info_get_reply.status;
|
|
-
|
|
- pr_debug("%s:result:%d component:0x%x port:%d\n", __func__, ret,
|
|
- port->component->handle, port->handle);
|
|
-
|
|
-release_msg:
|
|
- vchi_held_msg_release(&rmsg_handle);
|
|
-
|
|
- return ret;
|
|
-}
|
|
-
|
|
-/* use port info get message to retrieve port information */
|
|
-static int port_info_get(struct vchiq_mmal_instance *instance,
|
|
- struct vchiq_mmal_port *port)
|
|
-{
|
|
- int ret;
|
|
- struct mmal_msg m;
|
|
- struct mmal_msg *rmsg;
|
|
- struct vchi_held_msg rmsg_handle;
|
|
-
|
|
- /* port info time */
|
|
- m.h.type = MMAL_MSG_TYPE_PORT_INFO_GET;
|
|
- m.u.port_info_get.component_handle = port->component->handle;
|
|
- m.u.port_info_get.port_type = port->type;
|
|
- m.u.port_info_get.index = port->index;
|
|
-
|
|
- ret = send_synchronous_mmal_msg(instance, &m,
|
|
- sizeof(m.u.port_info_get),
|
|
- &rmsg, &rmsg_handle);
|
|
- if (ret)
|
|
- return ret;
|
|
-
|
|
- if (rmsg->h.type != MMAL_MSG_TYPE_PORT_INFO_GET) {
|
|
- /* got an unexpected message type in reply */
|
|
- ret = -EINVAL;
|
|
- goto release_msg;
|
|
- }
|
|
-
|
|
- /* return operation status */
|
|
- ret = -rmsg->u.port_info_get_reply.status;
|
|
- if (ret != MMAL_MSG_STATUS_SUCCESS)
|
|
- goto release_msg;
|
|
-
|
|
- if (rmsg->u.port_info_get_reply.port.is_enabled == 0)
|
|
- port->enabled = 0;
|
|
- else
|
|
- port->enabled = 1;
|
|
-
|
|
- /* copy the values out of the message */
|
|
- port->handle = rmsg->u.port_info_get_reply.port_handle;
|
|
-
|
|
- /* port type and index cached to use on port info set because
|
|
- * it does not use a port handle
|
|
- */
|
|
- port->type = rmsg->u.port_info_get_reply.port_type;
|
|
- port->index = rmsg->u.port_info_get_reply.port_index;
|
|
-
|
|
- port->minimum_buffer.num =
|
|
- rmsg->u.port_info_get_reply.port.buffer_num_min;
|
|
- port->minimum_buffer.size =
|
|
- rmsg->u.port_info_get_reply.port.buffer_size_min;
|
|
- port->minimum_buffer.alignment =
|
|
- rmsg->u.port_info_get_reply.port.buffer_alignment_min;
|
|
-
|
|
- port->recommended_buffer.alignment =
|
|
- rmsg->u.port_info_get_reply.port.buffer_alignment_min;
|
|
- port->recommended_buffer.num =
|
|
- rmsg->u.port_info_get_reply.port.buffer_num_recommended;
|
|
-
|
|
- port->current_buffer.num = rmsg->u.port_info_get_reply.port.buffer_num;
|
|
- port->current_buffer.size =
|
|
- rmsg->u.port_info_get_reply.port.buffer_size;
|
|
-
|
|
- /* stream format */
|
|
- port->format.type = rmsg->u.port_info_get_reply.format.type;
|
|
- port->format.encoding = rmsg->u.port_info_get_reply.format.encoding;
|
|
- port->format.encoding_variant =
|
|
- rmsg->u.port_info_get_reply.format.encoding_variant;
|
|
- port->format.bitrate = rmsg->u.port_info_get_reply.format.bitrate;
|
|
- port->format.flags = rmsg->u.port_info_get_reply.format.flags;
|
|
-
|
|
- /* elementary stream format */
|
|
- memcpy(&port->es,
|
|
- &rmsg->u.port_info_get_reply.es,
|
|
- sizeof(union mmal_es_specific_format));
|
|
- port->format.es = &port->es;
|
|
-
|
|
- port->format.extradata_size =
|
|
- rmsg->u.port_info_get_reply.format.extradata_size;
|
|
- memcpy(port->format.extradata,
|
|
- rmsg->u.port_info_get_reply.extradata,
|
|
- port->format.extradata_size);
|
|
-
|
|
- pr_debug("received port info\n");
|
|
- dump_port_info(port);
|
|
-
|
|
-release_msg:
|
|
-
|
|
- pr_debug("%s:result:%d component:0x%x port:%d\n",
|
|
- __func__, ret, port->component->handle, port->handle);
|
|
-
|
|
- vchi_held_msg_release(&rmsg_handle);
|
|
-
|
|
- return ret;
|
|
-}
|
|
-
|
|
-/* create comonent on vc */
|
|
-static int create_component(struct vchiq_mmal_instance *instance,
|
|
- struct vchiq_mmal_component *component,
|
|
- const char *name)
|
|
-{
|
|
- int ret;
|
|
- struct mmal_msg m;
|
|
- struct mmal_msg *rmsg;
|
|
- struct vchi_held_msg rmsg_handle;
|
|
-
|
|
- /* build component create message */
|
|
- m.h.type = MMAL_MSG_TYPE_COMPONENT_CREATE;
|
|
- m.u.component_create.client_component = (u32)(unsigned long)component;
|
|
- strncpy(m.u.component_create.name, name,
|
|
- sizeof(m.u.component_create.name));
|
|
-
|
|
- ret = send_synchronous_mmal_msg(instance, &m,
|
|
- sizeof(m.u.component_create),
|
|
- &rmsg, &rmsg_handle);
|
|
- if (ret)
|
|
- return ret;
|
|
-
|
|
- if (rmsg->h.type != m.h.type) {
|
|
- /* got an unexpected message type in reply */
|
|
- ret = -EINVAL;
|
|
- goto release_msg;
|
|
- }
|
|
-
|
|
- ret = -rmsg->u.component_create_reply.status;
|
|
- if (ret != MMAL_MSG_STATUS_SUCCESS)
|
|
- goto release_msg;
|
|
-
|
|
- /* a valid component response received */
|
|
- component->handle = rmsg->u.component_create_reply.component_handle;
|
|
- component->inputs = rmsg->u.component_create_reply.input_num;
|
|
- component->outputs = rmsg->u.component_create_reply.output_num;
|
|
- component->clocks = rmsg->u.component_create_reply.clock_num;
|
|
-
|
|
- pr_debug("Component handle:0x%x in:%d out:%d clock:%d\n",
|
|
- component->handle,
|
|
- component->inputs, component->outputs, component->clocks);
|
|
-
|
|
-release_msg:
|
|
- vchi_held_msg_release(&rmsg_handle);
|
|
-
|
|
- return ret;
|
|
-}
|
|
-
|
|
-/* destroys a component on vc */
|
|
-static int destroy_component(struct vchiq_mmal_instance *instance,
|
|
- struct vchiq_mmal_component *component)
|
|
-{
|
|
- int ret;
|
|
- struct mmal_msg m;
|
|
- struct mmal_msg *rmsg;
|
|
- struct vchi_held_msg rmsg_handle;
|
|
-
|
|
- m.h.type = MMAL_MSG_TYPE_COMPONENT_DESTROY;
|
|
- m.u.component_destroy.component_handle = component->handle;
|
|
-
|
|
- ret = send_synchronous_mmal_msg(instance, &m,
|
|
- sizeof(m.u.component_destroy),
|
|
- &rmsg, &rmsg_handle);
|
|
- if (ret)
|
|
- return ret;
|
|
-
|
|
- if (rmsg->h.type != m.h.type) {
|
|
- /* got an unexpected message type in reply */
|
|
- ret = -EINVAL;
|
|
- goto release_msg;
|
|
- }
|
|
-
|
|
- ret = -rmsg->u.component_destroy_reply.status;
|
|
-
|
|
-release_msg:
|
|
-
|
|
- vchi_held_msg_release(&rmsg_handle);
|
|
-
|
|
- return ret;
|
|
-}
|
|
-
|
|
-/* enable a component on vc */
|
|
-static int enable_component(struct vchiq_mmal_instance *instance,
|
|
- struct vchiq_mmal_component *component)
|
|
-{
|
|
- int ret;
|
|
- struct mmal_msg m;
|
|
- struct mmal_msg *rmsg;
|
|
- struct vchi_held_msg rmsg_handle;
|
|
-
|
|
- m.h.type = MMAL_MSG_TYPE_COMPONENT_ENABLE;
|
|
- m.u.component_enable.component_handle = component->handle;
|
|
-
|
|
- ret = send_synchronous_mmal_msg(instance, &m,
|
|
- sizeof(m.u.component_enable),
|
|
- &rmsg, &rmsg_handle);
|
|
- if (ret)
|
|
- return ret;
|
|
-
|
|
- if (rmsg->h.type != m.h.type) {
|
|
- /* got an unexpected message type in reply */
|
|
- ret = -EINVAL;
|
|
- goto release_msg;
|
|
- }
|
|
-
|
|
- ret = -rmsg->u.component_enable_reply.status;
|
|
-
|
|
-release_msg:
|
|
- vchi_held_msg_release(&rmsg_handle);
|
|
-
|
|
- return ret;
|
|
-}
|
|
-
|
|
-/* disable a component on vc */
|
|
-static int disable_component(struct vchiq_mmal_instance *instance,
|
|
- struct vchiq_mmal_component *component)
|
|
-{
|
|
- int ret;
|
|
- struct mmal_msg m;
|
|
- struct mmal_msg *rmsg;
|
|
- struct vchi_held_msg rmsg_handle;
|
|
-
|
|
- m.h.type = MMAL_MSG_TYPE_COMPONENT_DISABLE;
|
|
- m.u.component_disable.component_handle = component->handle;
|
|
-
|
|
- ret = send_synchronous_mmal_msg(instance, &m,
|
|
- sizeof(m.u.component_disable),
|
|
- &rmsg, &rmsg_handle);
|
|
- if (ret)
|
|
- return ret;
|
|
-
|
|
- if (rmsg->h.type != m.h.type) {
|
|
- /* got an unexpected message type in reply */
|
|
- ret = -EINVAL;
|
|
- goto release_msg;
|
|
- }
|
|
-
|
|
- ret = -rmsg->u.component_disable_reply.status;
|
|
-
|
|
-release_msg:
|
|
-
|
|
- vchi_held_msg_release(&rmsg_handle);
|
|
-
|
|
- return ret;
|
|
-}
|
|
-
|
|
-/* get version of mmal implementation */
|
|
-static int get_version(struct vchiq_mmal_instance *instance,
|
|
- u32 *major_out, u32 *minor_out)
|
|
-{
|
|
- int ret;
|
|
- struct mmal_msg m;
|
|
- struct mmal_msg *rmsg;
|
|
- struct vchi_held_msg rmsg_handle;
|
|
-
|
|
- m.h.type = MMAL_MSG_TYPE_GET_VERSION;
|
|
-
|
|
- ret = send_synchronous_mmal_msg(instance, &m,
|
|
- sizeof(m.u.version),
|
|
- &rmsg, &rmsg_handle);
|
|
- if (ret)
|
|
- return ret;
|
|
-
|
|
- if (rmsg->h.type != m.h.type) {
|
|
- /* got an unexpected message type in reply */
|
|
- ret = -EINVAL;
|
|
- goto release_msg;
|
|
- }
|
|
-
|
|
- *major_out = rmsg->u.version.major;
|
|
- *minor_out = rmsg->u.version.minor;
|
|
-
|
|
-release_msg:
|
|
- vchi_held_msg_release(&rmsg_handle);
|
|
-
|
|
- return ret;
|
|
-}
|
|
-
|
|
-/* do a port action with a port as a parameter */
|
|
-static int port_action_port(struct vchiq_mmal_instance *instance,
|
|
- struct vchiq_mmal_port *port,
|
|
- enum mmal_msg_port_action_type action_type)
|
|
-{
|
|
- int ret;
|
|
- struct mmal_msg m;
|
|
- struct mmal_msg *rmsg;
|
|
- struct vchi_held_msg rmsg_handle;
|
|
-
|
|
- m.h.type = MMAL_MSG_TYPE_PORT_ACTION;
|
|
- m.u.port_action_port.component_handle = port->component->handle;
|
|
- m.u.port_action_port.port_handle = port->handle;
|
|
- m.u.port_action_port.action = action_type;
|
|
-
|
|
- port_to_mmal_msg(port, &m.u.port_action_port.port);
|
|
-
|
|
- ret = send_synchronous_mmal_msg(instance, &m,
|
|
- sizeof(m.u.port_action_port),
|
|
- &rmsg, &rmsg_handle);
|
|
- if (ret)
|
|
- return ret;
|
|
-
|
|
- if (rmsg->h.type != MMAL_MSG_TYPE_PORT_ACTION) {
|
|
- /* got an unexpected message type in reply */
|
|
- ret = -EINVAL;
|
|
- goto release_msg;
|
|
- }
|
|
-
|
|
- ret = -rmsg->u.port_action_reply.status;
|
|
-
|
|
- pr_debug("%s:result:%d component:0x%x port:%d action:%s(%d)\n",
|
|
- __func__,
|
|
- ret, port->component->handle, port->handle,
|
|
- port_action_type_names[action_type], action_type);
|
|
-
|
|
-release_msg:
|
|
- vchi_held_msg_release(&rmsg_handle);
|
|
-
|
|
- return ret;
|
|
-}
|
|
-
|
|
-/* do a port action with handles as parameters */
|
|
-static int port_action_handle(struct vchiq_mmal_instance *instance,
|
|
- struct vchiq_mmal_port *port,
|
|
- enum mmal_msg_port_action_type action_type,
|
|
- u32 connect_component_handle,
|
|
- u32 connect_port_handle)
|
|
-{
|
|
- int ret;
|
|
- struct mmal_msg m;
|
|
- struct mmal_msg *rmsg;
|
|
- struct vchi_held_msg rmsg_handle;
|
|
-
|
|
- m.h.type = MMAL_MSG_TYPE_PORT_ACTION;
|
|
-
|
|
- m.u.port_action_handle.component_handle = port->component->handle;
|
|
- m.u.port_action_handle.port_handle = port->handle;
|
|
- m.u.port_action_handle.action = action_type;
|
|
-
|
|
- m.u.port_action_handle.connect_component_handle =
|
|
- connect_component_handle;
|
|
- m.u.port_action_handle.connect_port_handle = connect_port_handle;
|
|
-
|
|
- ret = send_synchronous_mmal_msg(instance, &m,
|
|
- sizeof(m.u.port_action_handle),
|
|
- &rmsg, &rmsg_handle);
|
|
- if (ret)
|
|
- return ret;
|
|
-
|
|
- if (rmsg->h.type != MMAL_MSG_TYPE_PORT_ACTION) {
|
|
- /* got an unexpected message type in reply */
|
|
- ret = -EINVAL;
|
|
- goto release_msg;
|
|
- }
|
|
-
|
|
- ret = -rmsg->u.port_action_reply.status;
|
|
-
|
|
- pr_debug("%s:result:%d component:0x%x port:%d action:%s(%d) connect component:0x%x connect port:%d\n",
|
|
- __func__,
|
|
- ret, port->component->handle, port->handle,
|
|
- port_action_type_names[action_type],
|
|
- action_type, connect_component_handle, connect_port_handle);
|
|
-
|
|
-release_msg:
|
|
- vchi_held_msg_release(&rmsg_handle);
|
|
-
|
|
- return ret;
|
|
-}
|
|
-
|
|
-static int port_parameter_set(struct vchiq_mmal_instance *instance,
|
|
- struct vchiq_mmal_port *port,
|
|
- u32 parameter_id, void *value, u32 value_size)
|
|
-{
|
|
- int ret;
|
|
- struct mmal_msg m;
|
|
- struct mmal_msg *rmsg;
|
|
- struct vchi_held_msg rmsg_handle;
|
|
-
|
|
- m.h.type = MMAL_MSG_TYPE_PORT_PARAMETER_SET;
|
|
-
|
|
- m.u.port_parameter_set.component_handle = port->component->handle;
|
|
- m.u.port_parameter_set.port_handle = port->handle;
|
|
- m.u.port_parameter_set.id = parameter_id;
|
|
- m.u.port_parameter_set.size = (2 * sizeof(u32)) + value_size;
|
|
- memcpy(&m.u.port_parameter_set.value, value, value_size);
|
|
-
|
|
- ret = send_synchronous_mmal_msg(instance, &m,
|
|
- (4 * sizeof(u32)) + value_size,
|
|
- &rmsg, &rmsg_handle);
|
|
- if (ret)
|
|
- return ret;
|
|
-
|
|
- if (rmsg->h.type != MMAL_MSG_TYPE_PORT_PARAMETER_SET) {
|
|
- /* got an unexpected message type in reply */
|
|
- ret = -EINVAL;
|
|
- goto release_msg;
|
|
- }
|
|
-
|
|
- ret = -rmsg->u.port_parameter_set_reply.status;
|
|
-
|
|
- pr_debug("%s:result:%d component:0x%x port:%d parameter:%d\n",
|
|
- __func__,
|
|
- ret, port->component->handle, port->handle, parameter_id);
|
|
-
|
|
-release_msg:
|
|
- vchi_held_msg_release(&rmsg_handle);
|
|
-
|
|
- return ret;
|
|
-}
|
|
-
|
|
-static int port_parameter_get(struct vchiq_mmal_instance *instance,
|
|
- struct vchiq_mmal_port *port,
|
|
- u32 parameter_id, void *value, u32 *value_size)
|
|
-{
|
|
- int ret;
|
|
- struct mmal_msg m;
|
|
- struct mmal_msg *rmsg;
|
|
- struct vchi_held_msg rmsg_handle;
|
|
-
|
|
- m.h.type = MMAL_MSG_TYPE_PORT_PARAMETER_GET;
|
|
-
|
|
- m.u.port_parameter_get.component_handle = port->component->handle;
|
|
- m.u.port_parameter_get.port_handle = port->handle;
|
|
- m.u.port_parameter_get.id = parameter_id;
|
|
- m.u.port_parameter_get.size = (2 * sizeof(u32)) + *value_size;
|
|
-
|
|
- ret = send_synchronous_mmal_msg(instance, &m,
|
|
- sizeof(struct
|
|
- mmal_msg_port_parameter_get),
|
|
- &rmsg, &rmsg_handle);
|
|
- if (ret)
|
|
- return ret;
|
|
-
|
|
- if (rmsg->h.type != MMAL_MSG_TYPE_PORT_PARAMETER_GET) {
|
|
- /* got an unexpected message type in reply */
|
|
- pr_err("Incorrect reply type %d\n", rmsg->h.type);
|
|
- ret = -EINVAL;
|
|
- goto release_msg;
|
|
- }
|
|
-
|
|
- ret = -rmsg->u.port_parameter_get_reply.status;
|
|
- /* port_parameter_get_reply.size includes the header,
|
|
- * whilst *value_size doesn't.
|
|
- */
|
|
- rmsg->u.port_parameter_get_reply.size -= (2 * sizeof(u32));
|
|
-
|
|
- if (ret || rmsg->u.port_parameter_get_reply.size > *value_size) {
|
|
- /* Copy only as much as we have space for
|
|
- * but report true size of parameter
|
|
- */
|
|
- memcpy(value, &rmsg->u.port_parameter_get_reply.value,
|
|
- *value_size);
|
|
- *value_size = rmsg->u.port_parameter_get_reply.size;
|
|
- } else {
|
|
- memcpy(value, &rmsg->u.port_parameter_get_reply.value,
|
|
- rmsg->u.port_parameter_get_reply.size);
|
|
- }
|
|
-
|
|
- pr_debug("%s:result:%d component:0x%x port:%d parameter:%d\n", __func__,
|
|
- ret, port->component->handle, port->handle, parameter_id);
|
|
-
|
|
-release_msg:
|
|
- vchi_held_msg_release(&rmsg_handle);
|
|
-
|
|
- return ret;
|
|
-}
|
|
-
|
|
-/* disables a port and drains buffers from it */
|
|
-static int port_disable(struct vchiq_mmal_instance *instance,
|
|
- struct vchiq_mmal_port *port)
|
|
-{
|
|
- int ret;
|
|
- struct list_head *q, *buf_head;
|
|
- unsigned long flags = 0;
|
|
-
|
|
- if (!port->enabled)
|
|
- return 0;
|
|
-
|
|
- port->enabled = 0;
|
|
-
|
|
- ret = port_action_port(instance, port,
|
|
- MMAL_MSG_PORT_ACTION_TYPE_DISABLE);
|
|
- if (ret == 0) {
|
|
- /*
|
|
- * Drain all queued buffers on port. This should only
|
|
- * apply to buffers that have been queued before the port
|
|
- * has been enabled. If the port has been enabled and buffers
|
|
- * passed, then the buffers should have been removed from this
|
|
- * list, and we should get the relevant callbacks via VCHIQ
|
|
- * to release the buffers.
|
|
- */
|
|
- spin_lock_irqsave(&port->slock, flags);
|
|
-
|
|
- list_for_each_safe(buf_head, q, &port->buffers) {
|
|
- struct mmal_buffer *mmalbuf;
|
|
-
|
|
- mmalbuf = list_entry(buf_head, struct mmal_buffer,
|
|
- list);
|
|
- list_del(buf_head);
|
|
- if (port->buffer_cb)
|
|
- port->buffer_cb(instance,
|
|
- port, 0, mmalbuf, 0, 0,
|
|
- MMAL_TIME_UNKNOWN,
|
|
- MMAL_TIME_UNKNOWN);
|
|
- }
|
|
-
|
|
- spin_unlock_irqrestore(&port->slock, flags);
|
|
-
|
|
- ret = port_info_get(instance, port);
|
|
- }
|
|
-
|
|
- return ret;
|
|
-}
|
|
-
|
|
-/* enable a port */
|
|
-static int port_enable(struct vchiq_mmal_instance *instance,
|
|
- struct vchiq_mmal_port *port)
|
|
-{
|
|
- unsigned int hdr_count;
|
|
- struct list_head *q, *buf_head;
|
|
- int ret;
|
|
-
|
|
- if (port->enabled)
|
|
- return 0;
|
|
-
|
|
- ret = port_action_port(instance, port,
|
|
- MMAL_MSG_PORT_ACTION_TYPE_ENABLE);
|
|
- if (ret)
|
|
- goto done;
|
|
-
|
|
- port->enabled = 1;
|
|
-
|
|
- if (port->buffer_cb) {
|
|
- /* send buffer headers to videocore */
|
|
- hdr_count = 1;
|
|
- list_for_each_safe(buf_head, q, &port->buffers) {
|
|
- struct mmal_buffer *mmalbuf;
|
|
-
|
|
- mmalbuf = list_entry(buf_head, struct mmal_buffer,
|
|
- list);
|
|
- ret = buffer_from_host(instance, port, mmalbuf);
|
|
- if (ret)
|
|
- goto done;
|
|
-
|
|
- list_del(buf_head);
|
|
- hdr_count++;
|
|
- if (hdr_count > port->current_buffer.num)
|
|
- break;
|
|
- }
|
|
- }
|
|
-
|
|
- ret = port_info_get(instance, port);
|
|
-
|
|
-done:
|
|
- return ret;
|
|
-}
|
|
-
|
|
-/* ------------------------------------------------------------------
|
|
- * Exported API
|
|
- *------------------------------------------------------------------
|
|
- */
|
|
-
|
|
-int vchiq_mmal_port_set_format(struct vchiq_mmal_instance *instance,
|
|
- struct vchiq_mmal_port *port)
|
|
-{
|
|
- int ret;
|
|
-
|
|
- if (mutex_lock_interruptible(&instance->vchiq_mutex))
|
|
- return -EINTR;
|
|
-
|
|
- ret = port_info_set(instance, port);
|
|
- if (ret)
|
|
- goto release_unlock;
|
|
-
|
|
- /* read what has actually been set */
|
|
- ret = port_info_get(instance, port);
|
|
-
|
|
-release_unlock:
|
|
- mutex_unlock(&instance->vchiq_mutex);
|
|
-
|
|
- return ret;
|
|
-}
|
|
-
|
|
-int vchiq_mmal_port_parameter_set(struct vchiq_mmal_instance *instance,
|
|
- struct vchiq_mmal_port *port,
|
|
- u32 parameter, void *value, u32 value_size)
|
|
-{
|
|
- int ret;
|
|
-
|
|
- if (mutex_lock_interruptible(&instance->vchiq_mutex))
|
|
- return -EINTR;
|
|
-
|
|
- ret = port_parameter_set(instance, port, parameter, value, value_size);
|
|
-
|
|
- mutex_unlock(&instance->vchiq_mutex);
|
|
-
|
|
- return ret;
|
|
-}
|
|
-
|
|
-int vchiq_mmal_port_parameter_get(struct vchiq_mmal_instance *instance,
|
|
- struct vchiq_mmal_port *port,
|
|
- u32 parameter, void *value, u32 *value_size)
|
|
-{
|
|
- int ret;
|
|
-
|
|
- if (mutex_lock_interruptible(&instance->vchiq_mutex))
|
|
- return -EINTR;
|
|
-
|
|
- ret = port_parameter_get(instance, port, parameter, value, value_size);
|
|
-
|
|
- mutex_unlock(&instance->vchiq_mutex);
|
|
-
|
|
- return ret;
|
|
-}
|
|
-
|
|
-/* enable a port
|
|
- *
|
|
- * enables a port and queues buffers for satisfying callbacks if we
|
|
- * provide a callback handler
|
|
- */
|
|
-int vchiq_mmal_port_enable(struct vchiq_mmal_instance *instance,
|
|
- struct vchiq_mmal_port *port,
|
|
- vchiq_mmal_buffer_cb buffer_cb)
|
|
-{
|
|
- int ret;
|
|
-
|
|
- if (mutex_lock_interruptible(&instance->vchiq_mutex))
|
|
- return -EINTR;
|
|
-
|
|
- /* already enabled - noop */
|
|
- if (port->enabled) {
|
|
- ret = 0;
|
|
- goto unlock;
|
|
- }
|
|
-
|
|
- port->buffer_cb = buffer_cb;
|
|
-
|
|
- ret = port_enable(instance, port);
|
|
-
|
|
-unlock:
|
|
- mutex_unlock(&instance->vchiq_mutex);
|
|
-
|
|
- return ret;
|
|
-}
|
|
-
|
|
-int vchiq_mmal_port_disable(struct vchiq_mmal_instance *instance,
|
|
- struct vchiq_mmal_port *port)
|
|
-{
|
|
- int ret;
|
|
-
|
|
- if (mutex_lock_interruptible(&instance->vchiq_mutex))
|
|
- return -EINTR;
|
|
-
|
|
- if (!port->enabled) {
|
|
- mutex_unlock(&instance->vchiq_mutex);
|
|
- return 0;
|
|
- }
|
|
-
|
|
- ret = port_disable(instance, port);
|
|
-
|
|
- mutex_unlock(&instance->vchiq_mutex);
|
|
-
|
|
- return ret;
|
|
-}
|
|
-
|
|
-/* ports will be connected in a tunneled manner so data buffers
|
|
- * are not handled by client.
|
|
- */
|
|
-int vchiq_mmal_port_connect_tunnel(struct vchiq_mmal_instance *instance,
|
|
- struct vchiq_mmal_port *src,
|
|
- struct vchiq_mmal_port *dst)
|
|
-{
|
|
- int ret;
|
|
-
|
|
- if (mutex_lock_interruptible(&instance->vchiq_mutex))
|
|
- return -EINTR;
|
|
-
|
|
- /* disconnect ports if connected */
|
|
- if (src->connected) {
|
|
- ret = port_disable(instance, src);
|
|
- if (ret) {
|
|
- pr_err("failed disabling src port(%d)\n", ret);
|
|
- goto release_unlock;
|
|
- }
|
|
-
|
|
- /* do not need to disable the destination port as they
|
|
- * are connected and it is done automatically
|
|
- */
|
|
-
|
|
- ret = port_action_handle(instance, src,
|
|
- MMAL_MSG_PORT_ACTION_TYPE_DISCONNECT,
|
|
- src->connected->component->handle,
|
|
- src->connected->handle);
|
|
- if (ret < 0) {
|
|
- pr_err("failed disconnecting src port\n");
|
|
- goto release_unlock;
|
|
- }
|
|
- src->connected->enabled = 0;
|
|
- src->connected = NULL;
|
|
- }
|
|
-
|
|
- if (!dst) {
|
|
- /* do not make new connection */
|
|
- ret = 0;
|
|
- pr_debug("not making new connection\n");
|
|
- goto release_unlock;
|
|
- }
|
|
-
|
|
- /* copy src port format to dst */
|
|
- dst->format.encoding = src->format.encoding;
|
|
- dst->es.video.width = src->es.video.width;
|
|
- dst->es.video.height = src->es.video.height;
|
|
- dst->es.video.crop.x = src->es.video.crop.x;
|
|
- dst->es.video.crop.y = src->es.video.crop.y;
|
|
- dst->es.video.crop.width = src->es.video.crop.width;
|
|
- dst->es.video.crop.height = src->es.video.crop.height;
|
|
- dst->es.video.frame_rate.num = src->es.video.frame_rate.num;
|
|
- dst->es.video.frame_rate.den = src->es.video.frame_rate.den;
|
|
-
|
|
- /* set new format */
|
|
- ret = port_info_set(instance, dst);
|
|
- if (ret) {
|
|
- pr_debug("setting port info failed\n");
|
|
- goto release_unlock;
|
|
- }
|
|
-
|
|
- /* read what has actually been set */
|
|
- ret = port_info_get(instance, dst);
|
|
- if (ret) {
|
|
- pr_debug("read back port info failed\n");
|
|
- goto release_unlock;
|
|
- }
|
|
-
|
|
- /* connect two ports together */
|
|
- ret = port_action_handle(instance, src,
|
|
- MMAL_MSG_PORT_ACTION_TYPE_CONNECT,
|
|
- dst->component->handle, dst->handle);
|
|
- if (ret < 0) {
|
|
- pr_debug("connecting port %d:%d to %d:%d failed\n",
|
|
- src->component->handle, src->handle,
|
|
- dst->component->handle, dst->handle);
|
|
- goto release_unlock;
|
|
- }
|
|
- src->connected = dst;
|
|
-
|
|
-release_unlock:
|
|
-
|
|
- mutex_unlock(&instance->vchiq_mutex);
|
|
-
|
|
- return ret;
|
|
-}
|
|
-
|
|
-int vchiq_mmal_submit_buffer(struct vchiq_mmal_instance *instance,
|
|
- struct vchiq_mmal_port *port,
|
|
- struct mmal_buffer *buffer)
|
|
-{
|
|
- unsigned long flags = 0;
|
|
- int ret;
|
|
-
|
|
- ret = buffer_from_host(instance, port, buffer);
|
|
- if (ret == -EINVAL) {
|
|
- /* Port is disabled. Queue for when it is enabled. */
|
|
- spin_lock_irqsave(&port->slock, flags);
|
|
- list_add_tail(&buffer->list, &port->buffers);
|
|
- spin_unlock_irqrestore(&port->slock, flags);
|
|
- }
|
|
-
|
|
- return 0;
|
|
-}
|
|
-
|
|
-int mmal_vchi_buffer_init(struct vchiq_mmal_instance *instance,
|
|
- struct mmal_buffer *buf)
|
|
-{
|
|
- struct mmal_msg_context *msg_context = get_msg_context(instance);
|
|
-
|
|
- if (IS_ERR(msg_context))
|
|
- return (PTR_ERR(msg_context));
|
|
-
|
|
- buf->msg_context = msg_context;
|
|
- return 0;
|
|
-}
|
|
-
|
|
-int mmal_vchi_buffer_cleanup(struct mmal_buffer *buf)
|
|
-{
|
|
- struct mmal_msg_context *msg_context = buf->msg_context;
|
|
-
|
|
- if (msg_context)
|
|
- release_msg_context(msg_context);
|
|
- buf->msg_context = NULL;
|
|
-
|
|
- return 0;
|
|
-}
|
|
-
|
|
-/* Initialise a mmal component and its ports
|
|
- *
|
|
- */
|
|
-int vchiq_mmal_component_init(struct vchiq_mmal_instance *instance,
|
|
- const char *name,
|
|
- struct vchiq_mmal_component **component_out)
|
|
-{
|
|
- int ret;
|
|
- int idx; /* port index */
|
|
- struct vchiq_mmal_component *component;
|
|
-
|
|
- if (mutex_lock_interruptible(&instance->vchiq_mutex))
|
|
- return -EINTR;
|
|
-
|
|
- if (instance->component_idx == VCHIQ_MMAL_MAX_COMPONENTS) {
|
|
- ret = -EINVAL; /* todo is this correct error? */
|
|
- goto unlock;
|
|
- }
|
|
-
|
|
- component = &instance->component[instance->component_idx];
|
|
-
|
|
- ret = create_component(instance, component, name);
|
|
- if (ret < 0) {
|
|
- pr_err("%s: failed to create component %d (Not enough GPU mem?)\n",
|
|
- __func__, ret);
|
|
- goto unlock;
|
|
- }
|
|
-
|
|
- /* ports info needs gathering */
|
|
- component->control.type = MMAL_PORT_TYPE_CONTROL;
|
|
- component->control.index = 0;
|
|
- component->control.component = component;
|
|
- spin_lock_init(&component->control.slock);
|
|
- INIT_LIST_HEAD(&component->control.buffers);
|
|
- ret = port_info_get(instance, &component->control);
|
|
- if (ret < 0)
|
|
- goto release_component;
|
|
-
|
|
- for (idx = 0; idx < component->inputs; idx++) {
|
|
- component->input[idx].type = MMAL_PORT_TYPE_INPUT;
|
|
- component->input[idx].index = idx;
|
|
- component->input[idx].component = component;
|
|
- spin_lock_init(&component->input[idx].slock);
|
|
- INIT_LIST_HEAD(&component->input[idx].buffers);
|
|
- ret = port_info_get(instance, &component->input[idx]);
|
|
- if (ret < 0)
|
|
- goto release_component;
|
|
- }
|
|
-
|
|
- for (idx = 0; idx < component->outputs; idx++) {
|
|
- component->output[idx].type = MMAL_PORT_TYPE_OUTPUT;
|
|
- component->output[idx].index = idx;
|
|
- component->output[idx].component = component;
|
|
- spin_lock_init(&component->output[idx].slock);
|
|
- INIT_LIST_HEAD(&component->output[idx].buffers);
|
|
- ret = port_info_get(instance, &component->output[idx]);
|
|
- if (ret < 0)
|
|
- goto release_component;
|
|
- }
|
|
-
|
|
- for (idx = 0; idx < component->clocks; idx++) {
|
|
- component->clock[idx].type = MMAL_PORT_TYPE_CLOCK;
|
|
- component->clock[idx].index = idx;
|
|
- component->clock[idx].component = component;
|
|
- spin_lock_init(&component->clock[idx].slock);
|
|
- INIT_LIST_HEAD(&component->clock[idx].buffers);
|
|
- ret = port_info_get(instance, &component->clock[idx]);
|
|
- if (ret < 0)
|
|
- goto release_component;
|
|
- }
|
|
-
|
|
- instance->component_idx++;
|
|
-
|
|
- *component_out = component;
|
|
-
|
|
- mutex_unlock(&instance->vchiq_mutex);
|
|
-
|
|
- return 0;
|
|
-
|
|
-release_component:
|
|
- destroy_component(instance, component);
|
|
-unlock:
|
|
- mutex_unlock(&instance->vchiq_mutex);
|
|
-
|
|
- return ret;
|
|
-}
|
|
-
|
|
-/*
|
|
- * cause a mmal component to be destroyed
|
|
- */
|
|
-int vchiq_mmal_component_finalise(struct vchiq_mmal_instance *instance,
|
|
- struct vchiq_mmal_component *component)
|
|
-{
|
|
- int ret;
|
|
-
|
|
- if (mutex_lock_interruptible(&instance->vchiq_mutex))
|
|
- return -EINTR;
|
|
-
|
|
- if (component->enabled)
|
|
- ret = disable_component(instance, component);
|
|
-
|
|
- ret = destroy_component(instance, component);
|
|
-
|
|
- mutex_unlock(&instance->vchiq_mutex);
|
|
-
|
|
- return ret;
|
|
-}
|
|
-
|
|
-/*
|
|
- * cause a mmal component to be enabled
|
|
- */
|
|
-int vchiq_mmal_component_enable(struct vchiq_mmal_instance *instance,
|
|
- struct vchiq_mmal_component *component)
|
|
-{
|
|
- int ret;
|
|
-
|
|
- if (mutex_lock_interruptible(&instance->vchiq_mutex))
|
|
- return -EINTR;
|
|
-
|
|
- if (component->enabled) {
|
|
- mutex_unlock(&instance->vchiq_mutex);
|
|
- return 0;
|
|
- }
|
|
-
|
|
- ret = enable_component(instance, component);
|
|
- if (ret == 0)
|
|
- component->enabled = true;
|
|
-
|
|
- mutex_unlock(&instance->vchiq_mutex);
|
|
-
|
|
- return ret;
|
|
-}
|
|
-
|
|
-/*
|
|
- * cause a mmal component to be enabled
|
|
- */
|
|
-int vchiq_mmal_component_disable(struct vchiq_mmal_instance *instance,
|
|
- struct vchiq_mmal_component *component)
|
|
-{
|
|
- int ret;
|
|
-
|
|
- if (mutex_lock_interruptible(&instance->vchiq_mutex))
|
|
- return -EINTR;
|
|
-
|
|
- if (!component->enabled) {
|
|
- mutex_unlock(&instance->vchiq_mutex);
|
|
- return 0;
|
|
- }
|
|
-
|
|
- ret = disable_component(instance, component);
|
|
- if (ret == 0)
|
|
- component->enabled = 0;
|
|
-
|
|
- mutex_unlock(&instance->vchiq_mutex);
|
|
-
|
|
- return ret;
|
|
-}
|
|
-
|
|
-int vchiq_mmal_version(struct vchiq_mmal_instance *instance,
|
|
- u32 *major_out, u32 *minor_out)
|
|
-{
|
|
- int ret;
|
|
-
|
|
- if (mutex_lock_interruptible(&instance->vchiq_mutex))
|
|
- return -EINTR;
|
|
-
|
|
- ret = get_version(instance, major_out, minor_out);
|
|
-
|
|
- mutex_unlock(&instance->vchiq_mutex);
|
|
-
|
|
- return ret;
|
|
-}
|
|
-
|
|
-int vchiq_mmal_finalise(struct vchiq_mmal_instance *instance)
|
|
-{
|
|
- int status = 0;
|
|
-
|
|
- if (!instance)
|
|
- return -EINVAL;
|
|
-
|
|
- if (mutex_lock_interruptible(&instance->vchiq_mutex))
|
|
- return -EINTR;
|
|
-
|
|
- vchi_service_use(instance->handle);
|
|
-
|
|
- status = vchi_service_close(instance->handle);
|
|
- if (status != 0)
|
|
- pr_err("mmal-vchiq: VCHIQ close failed\n");
|
|
-
|
|
- mutex_unlock(&instance->vchiq_mutex);
|
|
-
|
|
- flush_workqueue(instance->bulk_wq);
|
|
- destroy_workqueue(instance->bulk_wq);
|
|
-
|
|
- vfree(instance->bulk_scratch);
|
|
-
|
|
- idr_destroy(&instance->context_map);
|
|
-
|
|
- kfree(instance);
|
|
-
|
|
- return status;
|
|
-}
|
|
-
|
|
-int vchiq_mmal_init(struct vchiq_mmal_instance **out_instance)
|
|
-{
|
|
- int status;
|
|
- struct vchiq_mmal_instance *instance;
|
|
- static VCHI_INSTANCE_T vchi_instance;
|
|
- struct service_creation params = {
|
|
- .version = VCHI_VERSION_EX(VC_MMAL_VER, VC_MMAL_MIN_VER),
|
|
- .service_id = VC_MMAL_SERVER_NAME,
|
|
- .callback = service_callback,
|
|
- .callback_param = NULL,
|
|
- };
|
|
-
|
|
- /* compile time checks to ensure structure size as they are
|
|
- * directly (de)serialised from memory.
|
|
- */
|
|
-
|
|
- /* ensure the header structure has packed to the correct size */
|
|
- BUILD_BUG_ON(sizeof(struct mmal_msg_header) != 24);
|
|
-
|
|
- /* ensure message structure does not exceed maximum length */
|
|
- BUILD_BUG_ON(sizeof(struct mmal_msg) > MMAL_MSG_MAX_SIZE);
|
|
-
|
|
- /* mmal port struct is correct size */
|
|
- BUILD_BUG_ON(sizeof(struct mmal_port) != 64);
|
|
-
|
|
- /* create a vchi instance */
|
|
- status = vchi_initialise(&vchi_instance);
|
|
- if (status) {
|
|
- pr_err("Failed to initialise VCHI instance (status=%d)\n",
|
|
- status);
|
|
- return -EIO;
|
|
- }
|
|
-
|
|
- status = vchi_connect(vchi_instance);
|
|
- if (status) {
|
|
- pr_err("Failed to connect VCHI instance (status=%d)\n", status);
|
|
- return -EIO;
|
|
- }
|
|
-
|
|
- instance = kzalloc(sizeof(*instance), GFP_KERNEL);
|
|
-
|
|
- if (!instance)
|
|
- return -ENOMEM;
|
|
-
|
|
- mutex_init(&instance->vchiq_mutex);
|
|
-
|
|
- instance->bulk_scratch = vmalloc(PAGE_SIZE);
|
|
-
|
|
- mutex_init(&instance->context_map_lock);
|
|
- idr_init_base(&instance->context_map, 1);
|
|
-
|
|
- params.callback_param = instance;
|
|
-
|
|
- instance->bulk_wq = alloc_ordered_workqueue("mmal-vchiq",
|
|
- WQ_MEM_RECLAIM);
|
|
- if (!instance->bulk_wq)
|
|
- goto err_free;
|
|
-
|
|
- status = vchi_service_open(vchi_instance, ¶ms, &instance->handle);
|
|
- if (status) {
|
|
- pr_err("Failed to open VCHI service connection (status=%d)\n",
|
|
- status);
|
|
- goto err_close_services;
|
|
- }
|
|
-
|
|
- vchi_service_release(instance->handle);
|
|
-
|
|
- *out_instance = instance;
|
|
-
|
|
- return 0;
|
|
-
|
|
-err_close_services:
|
|
- vchi_service_close(instance->handle);
|
|
- destroy_workqueue(instance->bulk_wq);
|
|
-err_free:
|
|
- vfree(instance->bulk_scratch);
|
|
- kfree(instance);
|
|
- return -ENODEV;
|
|
-}
|
|
--- /dev/null
|
|
+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c
|
|
@@ -0,0 +1,1913 @@
|
|
+// SPDX-License-Identifier: GPL-2.0
|
|
+/*
|
|
+ * Broadcom BM2835 V4L2 driver
|
|
+ *
|
|
+ * Copyright © 2013 Raspberry Pi (Trading) Ltd.
|
|
+ *
|
|
+ * Authors: Vincent Sanders @ Collabora
|
|
+ * Dave Stevenson @ Broadcom
|
|
+ * (now dave.stevenson@raspberrypi.org)
|
|
+ * Simon Mellor @ Broadcom
|
|
+ * Luke Diamand @ Broadcom
|
|
+ *
|
|
+ * V4L2 driver MMAL vchiq interface code
|
|
+ */
|
|
+
|
|
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
|
+
|
|
+#include <linux/errno.h>
|
|
+#include <linux/kernel.h>
|
|
+#include <linux/module.h>
|
|
+#include <linux/mutex.h>
|
|
+#include <linux/mm.h>
|
|
+#include <linux/slab.h>
|
|
+#include <linux/completion.h>
|
|
+#include <linux/vmalloc.h>
|
|
+#include <media/videobuf2-vmalloc.h>
|
|
+
|
|
+#include "mmal-common.h"
|
|
+#include "mmal-vchiq.h"
|
|
+#include "mmal-msg.h"
|
|
+
|
|
+#define USE_VCHIQ_ARM
|
|
+#include "interface/vchi/vchi.h"
|
|
+
|
|
+MODULE_DESCRIPTION("BCM2835 MMAL VCHIQ interface");
|
|
+MODULE_AUTHOR("Dave Stevenson, <dave.stevenson@raspberrypi.org>");
|
|
+MODULE_LICENSE("GPL");
|
|
+MODULE_VERSION("0.0.1");
|
|
+
|
|
+/* maximum number of components supported */
|
|
+#define VCHIQ_MMAL_MAX_COMPONENTS 4
|
|
+
|
|
+/*#define FULL_MSG_DUMP 1*/
|
|
+
|
|
+#ifdef DEBUG
|
|
+static const char *const msg_type_names[] = {
|
|
+ "UNKNOWN",
|
|
+ "QUIT",
|
|
+ "SERVICE_CLOSED",
|
|
+ "GET_VERSION",
|
|
+ "COMPONENT_CREATE",
|
|
+ "COMPONENT_DESTROY",
|
|
+ "COMPONENT_ENABLE",
|
|
+ "COMPONENT_DISABLE",
|
|
+ "PORT_INFO_GET",
|
|
+ "PORT_INFO_SET",
|
|
+ "PORT_ACTION",
|
|
+ "BUFFER_FROM_HOST",
|
|
+ "BUFFER_TO_HOST",
|
|
+ "GET_STATS",
|
|
+ "PORT_PARAMETER_SET",
|
|
+ "PORT_PARAMETER_GET",
|
|
+ "EVENT_TO_HOST",
|
|
+ "GET_CORE_STATS_FOR_PORT",
|
|
+ "OPAQUE_ALLOCATOR",
|
|
+ "CONSUME_MEM",
|
|
+ "LMK",
|
|
+ "OPAQUE_ALLOCATOR_DESC",
|
|
+ "DRM_GET_LHS32",
|
|
+ "DRM_GET_TIME",
|
|
+ "BUFFER_FROM_HOST_ZEROLEN",
|
|
+ "PORT_FLUSH",
|
|
+ "HOST_LOG",
|
|
+};
|
|
+#endif
|
|
+
|
|
+static const char *const port_action_type_names[] = {
|
|
+ "UNKNOWN",
|
|
+ "ENABLE",
|
|
+ "DISABLE",
|
|
+ "FLUSH",
|
|
+ "CONNECT",
|
|
+ "DISCONNECT",
|
|
+ "SET_REQUIREMENTS",
|
|
+};
|
|
+
|
|
+#if defined(DEBUG)
|
|
+#if defined(FULL_MSG_DUMP)
|
|
+#define DBG_DUMP_MSG(MSG, MSG_LEN, TITLE) \
|
|
+ do { \
|
|
+ pr_debug(TITLE" type:%s(%d) length:%d\n", \
|
|
+ msg_type_names[(MSG)->h.type], \
|
|
+ (MSG)->h.type, (MSG_LEN)); \
|
|
+ print_hex_dump(KERN_DEBUG, "<<h: ", DUMP_PREFIX_OFFSET, \
|
|
+ 16, 4, (MSG), \
|
|
+ sizeof(struct mmal_msg_header), 1); \
|
|
+ print_hex_dump(KERN_DEBUG, "<<p: ", DUMP_PREFIX_OFFSET, \
|
|
+ 16, 4, \
|
|
+ ((u8 *)(MSG)) + sizeof(struct mmal_msg_header),\
|
|
+ (MSG_LEN) - sizeof(struct mmal_msg_header), 1); \
|
|
+ } while (0)
|
|
+#else
|
|
+#define DBG_DUMP_MSG(MSG, MSG_LEN, TITLE) \
|
|
+ { \
|
|
+ pr_debug(TITLE" type:%s(%d) length:%d\n", \
|
|
+ msg_type_names[(MSG)->h.type], \
|
|
+ (MSG)->h.type, (MSG_LEN)); \
|
|
+ }
|
|
+#endif
|
|
+#else
|
|
+#define DBG_DUMP_MSG(MSG, MSG_LEN, TITLE)
|
|
+#endif
|
|
+
|
|
+struct vchiq_mmal_instance;
|
|
+
|
|
+/* normal message context */
|
|
+struct mmal_msg_context {
|
|
+ struct vchiq_mmal_instance *instance;
|
|
+
|
|
+ /* Index in the context_map idr so that we can find the
|
|
+ * mmal_msg_context again when servicing the VCHI reply.
|
|
+ */
|
|
+ int handle;
|
|
+
|
|
+ union {
|
|
+ struct {
|
|
+ /* work struct for buffer_cb callback */
|
|
+ struct work_struct work;
|
|
+ /* work struct for deferred callback */
|
|
+ struct work_struct buffer_to_host_work;
|
|
+ /* mmal instance */
|
|
+ struct vchiq_mmal_instance *instance;
|
|
+ /* mmal port */
|
|
+ struct vchiq_mmal_port *port;
|
|
+ /* actual buffer used to store bulk reply */
|
|
+ struct mmal_buffer *buffer;
|
|
+ /* amount of buffer used */
|
|
+ unsigned long buffer_used;
|
|
+ /* MMAL buffer flags */
|
|
+ u32 mmal_flags;
|
|
+ /* Presentation and Decode timestamps */
|
|
+ s64 pts;
|
|
+ s64 dts;
|
|
+
|
|
+ int status; /* context status */
|
|
+
|
|
+ } bulk; /* bulk data */
|
|
+
|
|
+ struct {
|
|
+ /* message handle to release */
|
|
+ struct vchi_held_msg msg_handle;
|
|
+ /* pointer to received message */
|
|
+ struct mmal_msg *msg;
|
|
+ /* received message length */
|
|
+ u32 msg_len;
|
|
+ /* completion upon reply */
|
|
+ struct completion cmplt;
|
|
+ } sync; /* synchronous response */
|
|
+ } u;
|
|
+
|
|
+};
|
|
+
|
|
+struct vchiq_mmal_instance {
|
|
+ VCHI_SERVICE_HANDLE_T handle;
|
|
+
|
|
+ /* ensure serialised access to service */
|
|
+ struct mutex vchiq_mutex;
|
|
+
|
|
+ /* vmalloc page to receive scratch bulk xfers into */
|
|
+ void *bulk_scratch;
|
|
+
|
|
+ struct idr context_map;
|
|
+ /* protect accesses to context_map */
|
|
+ struct mutex context_map_lock;
|
|
+
|
|
+ /* component to use next */
|
|
+ int component_idx;
|
|
+ struct vchiq_mmal_component component[VCHIQ_MMAL_MAX_COMPONENTS];
|
|
+
|
|
+ /* ordered workqueue to process all bulk operations */
|
|
+ struct workqueue_struct *bulk_wq;
|
|
+};
|
|
+
|
|
+static struct mmal_msg_context *
|
|
+get_msg_context(struct vchiq_mmal_instance *instance)
|
|
+{
|
|
+ struct mmal_msg_context *msg_context;
|
|
+ int handle;
|
|
+
|
|
+ /* todo: should this be allocated from a pool to avoid kzalloc */
|
|
+ msg_context = kzalloc(sizeof(*msg_context), GFP_KERNEL);
|
|
+
|
|
+ if (!msg_context)
|
|
+ return ERR_PTR(-ENOMEM);
|
|
+
|
|
+ /* Create an ID that will be passed along with our message so
|
|
+ * that when we service the VCHI reply, we can look up what
|
|
+ * message is being replied to.
|
|
+ */
|
|
+ mutex_lock(&instance->context_map_lock);
|
|
+ handle = idr_alloc(&instance->context_map, msg_context,
|
|
+ 0, 0, GFP_KERNEL);
|
|
+ mutex_unlock(&instance->context_map_lock);
|
|
+
|
|
+ if (handle < 0) {
|
|
+ kfree(msg_context);
|
|
+ return ERR_PTR(handle);
|
|
+ }
|
|
+
|
|
+ msg_context->instance = instance;
|
|
+ msg_context->handle = handle;
|
|
+
|
|
+ return msg_context;
|
|
+}
|
|
+
|
|
+static struct mmal_msg_context *
|
|
+lookup_msg_context(struct vchiq_mmal_instance *instance, int handle)
|
|
+{
|
|
+ return idr_find(&instance->context_map, handle);
|
|
+}
|
|
+
|
|
+static void
|
|
+release_msg_context(struct mmal_msg_context *msg_context)
|
|
+{
|
|
+ struct vchiq_mmal_instance *instance = msg_context->instance;
|
|
+
|
|
+ mutex_lock(&instance->context_map_lock);
|
|
+ idr_remove(&instance->context_map, msg_context->handle);
|
|
+ mutex_unlock(&instance->context_map_lock);
|
|
+ kfree(msg_context);
|
|
+}
|
|
+
|
|
+/* deals with receipt of event to host message */
|
|
+static void event_to_host_cb(struct vchiq_mmal_instance *instance,
|
|
+ struct mmal_msg *msg, u32 msg_len)
|
|
+{
|
|
+ pr_debug("unhandled event\n");
|
|
+ pr_debug("component:%u port type:%d num:%d cmd:0x%x length:%d\n",
|
|
+ msg->u.event_to_host.client_component,
|
|
+ msg->u.event_to_host.port_type,
|
|
+ msg->u.event_to_host.port_num,
|
|
+ msg->u.event_to_host.cmd, msg->u.event_to_host.length);
|
|
+}
|
|
+
|
|
+/* workqueue scheduled callback
|
|
+ *
|
|
+ * we do this because it is important we do not call any other vchiq
|
|
+ * sync calls from witin the message delivery thread
|
|
+ */
|
|
+static void buffer_work_cb(struct work_struct *work)
|
|
+{
|
|
+ struct mmal_msg_context *msg_context =
|
|
+ container_of(work, struct mmal_msg_context, u.bulk.work);
|
|
+
|
|
+ atomic_dec(&msg_context->u.bulk.port->buffers_with_vpu);
|
|
+
|
|
+ msg_context->u.bulk.port->buffer_cb(msg_context->u.bulk.instance,
|
|
+ msg_context->u.bulk.port,
|
|
+ msg_context->u.bulk.status,
|
|
+ msg_context->u.bulk.buffer,
|
|
+ msg_context->u.bulk.buffer_used,
|
|
+ msg_context->u.bulk.mmal_flags,
|
|
+ msg_context->u.bulk.dts,
|
|
+ msg_context->u.bulk.pts);
|
|
+}
|
|
+
|
|
+/* workqueue scheduled callback to handle receiving buffers
|
|
+ *
|
|
+ * VCHI will allow up to 4 bulk receives to be scheduled before blocking.
|
|
+ * If we block in the service_callback context then we can't process the
|
|
+ * VCHI_CALLBACK_BULK_RECEIVED message that would otherwise allow the blocked
|
|
+ * vchi_bulk_queue_receive() call to complete.
|
|
+ */
|
|
+static void buffer_to_host_work_cb(struct work_struct *work)
|
|
+{
|
|
+ struct mmal_msg_context *msg_context =
|
|
+ container_of(work, struct mmal_msg_context,
|
|
+ u.bulk.buffer_to_host_work);
|
|
+ struct vchiq_mmal_instance *instance = msg_context->instance;
|
|
+ unsigned long len = msg_context->u.bulk.buffer_used;
|
|
+ int ret;
|
|
+
|
|
+ if (!len)
|
|
+ /* Dummy receive to ensure the buffers remain in order */
|
|
+ len = 8;
|
|
+ /* queue the bulk submission */
|
|
+ vchi_service_use(instance->handle);
|
|
+ ret = vchi_bulk_queue_receive(instance->handle,
|
|
+ msg_context->u.bulk.buffer->buffer,
|
|
+ /* Actual receive needs to be a multiple
|
|
+ * of 4 bytes
|
|
+ */
|
|
+ (len + 3) & ~3,
|
|
+ VCHI_FLAGS_CALLBACK_WHEN_OP_COMPLETE |
|
|
+ VCHI_FLAGS_BLOCK_UNTIL_QUEUED,
|
|
+ msg_context);
|
|
+
|
|
+ vchi_service_release(instance->handle);
|
|
+
|
|
+ if (ret != 0)
|
|
+ pr_err("%s: ctx: %p, vchi_bulk_queue_receive failed %d\n",
|
|
+ __func__, msg_context, ret);
|
|
+}
|
|
+
|
|
+/* enqueue a bulk receive for a given message context */
|
|
+static int bulk_receive(struct vchiq_mmal_instance *instance,
|
|
+ struct mmal_msg *msg,
|
|
+ struct mmal_msg_context *msg_context)
|
|
+{
|
|
+ unsigned long rd_len;
|
|
+
|
|
+ rd_len = msg->u.buffer_from_host.buffer_header.length;
|
|
+
|
|
+ if (!msg_context->u.bulk.buffer) {
|
|
+ pr_err("bulk.buffer not configured - error in buffer_from_host\n");
|
|
+
|
|
+ /* todo: this is a serious error, we should never have
|
|
+ * committed a buffer_to_host operation to the mmal
|
|
+ * port without the buffer to back it up (underflow
|
|
+ * handling) and there is no obvious way to deal with
|
|
+ * this - how is the mmal servie going to react when
|
|
+ * we fail to do the xfer and reschedule a buffer when
|
|
+ * it arrives? perhaps a starved flag to indicate a
|
|
+ * waiting bulk receive?
|
|
+ */
|
|
+
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
+ /* ensure we do not overrun the available buffer */
|
|
+ if (rd_len > msg_context->u.bulk.buffer->buffer_size) {
|
|
+ rd_len = msg_context->u.bulk.buffer->buffer_size;
|
|
+ pr_warn("short read as not enough receive buffer space\n");
|
|
+ /* todo: is this the correct response, what happens to
|
|
+ * the rest of the message data?
|
|
+ */
|
|
+ }
|
|
+
|
|
+ /* store length */
|
|
+ msg_context->u.bulk.buffer_used = rd_len;
|
|
+ msg_context->u.bulk.dts = msg->u.buffer_from_host.buffer_header.dts;
|
|
+ msg_context->u.bulk.pts = msg->u.buffer_from_host.buffer_header.pts;
|
|
+
|
|
+ queue_work(msg_context->instance->bulk_wq,
|
|
+ &msg_context->u.bulk.buffer_to_host_work);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+/* data in message, memcpy from packet into output buffer */
|
|
+static int inline_receive(struct vchiq_mmal_instance *instance,
|
|
+ struct mmal_msg *msg,
|
|
+ struct mmal_msg_context *msg_context)
|
|
+{
|
|
+ memcpy(msg_context->u.bulk.buffer->buffer,
|
|
+ msg->u.buffer_from_host.short_data,
|
|
+ msg->u.buffer_from_host.payload_in_message);
|
|
+
|
|
+ msg_context->u.bulk.buffer_used =
|
|
+ msg->u.buffer_from_host.payload_in_message;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+/* queue the buffer availability with MMAL_MSG_TYPE_BUFFER_FROM_HOST */
|
|
+static int
|
|
+buffer_from_host(struct vchiq_mmal_instance *instance,
|
|
+ struct vchiq_mmal_port *port, struct mmal_buffer *buf)
|
|
+{
|
|
+ struct mmal_msg_context *msg_context;
|
|
+ struct mmal_msg m;
|
|
+ int ret;
|
|
+
|
|
+ if (!port->enabled)
|
|
+ return -EINVAL;
|
|
+
|
|
+ pr_debug("instance:%p buffer:%p\n", instance->handle, buf);
|
|
+
|
|
+ /* get context */
|
|
+ if (!buf->msg_context) {
|
|
+ pr_err("%s: msg_context not allocated, buf %p\n", __func__,
|
|
+ buf);
|
|
+ return -EINVAL;
|
|
+ }
|
|
+ msg_context = buf->msg_context;
|
|
+
|
|
+ /* store bulk message context for when data arrives */
|
|
+ msg_context->u.bulk.instance = instance;
|
|
+ msg_context->u.bulk.port = port;
|
|
+ msg_context->u.bulk.buffer = buf;
|
|
+ msg_context->u.bulk.buffer_used = 0;
|
|
+
|
|
+ /* initialise work structure ready to schedule callback */
|
|
+ INIT_WORK(&msg_context->u.bulk.work, buffer_work_cb);
|
|
+ INIT_WORK(&msg_context->u.bulk.buffer_to_host_work,
|
|
+ buffer_to_host_work_cb);
|
|
+
|
|
+ atomic_inc(&port->buffers_with_vpu);
|
|
+
|
|
+ /* prep the buffer from host message */
|
|
+ memset(&m, 0xbc, sizeof(m)); /* just to make debug clearer */
|
|
+
|
|
+ m.h.type = MMAL_MSG_TYPE_BUFFER_FROM_HOST;
|
|
+ m.h.magic = MMAL_MAGIC;
|
|
+ m.h.context = msg_context->handle;
|
|
+ m.h.status = 0;
|
|
+
|
|
+ /* drvbuf is our private data passed back */
|
|
+ m.u.buffer_from_host.drvbuf.magic = MMAL_MAGIC;
|
|
+ m.u.buffer_from_host.drvbuf.component_handle = port->component->handle;
|
|
+ m.u.buffer_from_host.drvbuf.port_handle = port->handle;
|
|
+ m.u.buffer_from_host.drvbuf.client_context = msg_context->handle;
|
|
+
|
|
+ /* buffer header */
|
|
+ m.u.buffer_from_host.buffer_header.cmd = 0;
|
|
+ m.u.buffer_from_host.buffer_header.data =
|
|
+ (u32)(unsigned long)buf->buffer;
|
|
+ m.u.buffer_from_host.buffer_header.alloc_size = buf->buffer_size;
|
|
+ m.u.buffer_from_host.buffer_header.length = 0; /* nothing used yet */
|
|
+ m.u.buffer_from_host.buffer_header.offset = 0; /* no offset */
|
|
+ m.u.buffer_from_host.buffer_header.flags = 0; /* no flags */
|
|
+ m.u.buffer_from_host.buffer_header.pts = MMAL_TIME_UNKNOWN;
|
|
+ m.u.buffer_from_host.buffer_header.dts = MMAL_TIME_UNKNOWN;
|
|
+
|
|
+ /* clear buffer type sepecific data */
|
|
+ memset(&m.u.buffer_from_host.buffer_header_type_specific, 0,
|
|
+ sizeof(m.u.buffer_from_host.buffer_header_type_specific));
|
|
+
|
|
+ /* no payload in message */
|
|
+ m.u.buffer_from_host.payload_in_message = 0;
|
|
+
|
|
+ vchi_service_use(instance->handle);
|
|
+
|
|
+ ret = vchi_queue_kernel_message(instance->handle,
|
|
+ &m,
|
|
+ sizeof(struct mmal_msg_header) +
|
|
+ sizeof(m.u.buffer_from_host));
|
|
+
|
|
+ vchi_service_release(instance->handle);
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+/* deals with receipt of buffer to host message */
|
|
+static void buffer_to_host_cb(struct vchiq_mmal_instance *instance,
|
|
+ struct mmal_msg *msg, u32 msg_len)
|
|
+{
|
|
+ struct mmal_msg_context *msg_context;
|
|
+ u32 handle;
|
|
+
|
|
+ pr_debug("%s: instance:%p msg:%p msg_len:%d\n",
|
|
+ __func__, instance, msg, msg_len);
|
|
+
|
|
+ if (msg->u.buffer_from_host.drvbuf.magic == MMAL_MAGIC) {
|
|
+ handle = msg->u.buffer_from_host.drvbuf.client_context;
|
|
+ msg_context = lookup_msg_context(instance, handle);
|
|
+
|
|
+ if (!msg_context) {
|
|
+ pr_err("drvbuf.client_context(%u) is invalid\n",
|
|
+ handle);
|
|
+ return;
|
|
+ }
|
|
+ } else {
|
|
+ pr_err("MMAL_MSG_TYPE_BUFFER_TO_HOST with bad magic\n");
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ msg_context->u.bulk.mmal_flags =
|
|
+ msg->u.buffer_from_host.buffer_header.flags;
|
|
+
|
|
+ if (msg->h.status != MMAL_MSG_STATUS_SUCCESS) {
|
|
+ /* message reception had an error */
|
|
+ pr_warn("error %d in reply\n", msg->h.status);
|
|
+
|
|
+ msg_context->u.bulk.status = msg->h.status;
|
|
+
|
|
+ } else if (msg->u.buffer_from_host.buffer_header.length == 0) {
|
|
+ /* empty buffer */
|
|
+ if (msg->u.buffer_from_host.buffer_header.flags &
|
|
+ MMAL_BUFFER_HEADER_FLAG_EOS) {
|
|
+ msg_context->u.bulk.status =
|
|
+ bulk_receive(instance, msg, msg_context);
|
|
+ if (msg_context->u.bulk.status == 0)
|
|
+ return; /* successful bulk submission, bulk
|
|
+ * completion will trigger callback
|
|
+ */
|
|
+ } else {
|
|
+ /* do callback with empty buffer - not EOS though */
|
|
+ msg_context->u.bulk.status = 0;
|
|
+ msg_context->u.bulk.buffer_used = 0;
|
|
+ }
|
|
+ } else if (msg->u.buffer_from_host.payload_in_message == 0) {
|
|
+ /* data is not in message, queue a bulk receive */
|
|
+ msg_context->u.bulk.status =
|
|
+ bulk_receive(instance, msg, msg_context);
|
|
+ if (msg_context->u.bulk.status == 0)
|
|
+ return; /* successful bulk submission, bulk
|
|
+ * completion will trigger callback
|
|
+ */
|
|
+
|
|
+ /* failed to submit buffer, this will end badly */
|
|
+ pr_err("error %d on bulk submission\n",
|
|
+ msg_context->u.bulk.status);
|
|
+
|
|
+ } else if (msg->u.buffer_from_host.payload_in_message <=
|
|
+ MMAL_VC_SHORT_DATA) {
|
|
+ /* data payload within message */
|
|
+ msg_context->u.bulk.status = inline_receive(instance, msg,
|
|
+ msg_context);
|
|
+ } else {
|
|
+ pr_err("message with invalid short payload\n");
|
|
+
|
|
+ /* signal error */
|
|
+ msg_context->u.bulk.status = -EINVAL;
|
|
+ msg_context->u.bulk.buffer_used =
|
|
+ msg->u.buffer_from_host.payload_in_message;
|
|
+ }
|
|
+
|
|
+ /* schedule the port callback */
|
|
+ schedule_work(&msg_context->u.bulk.work);
|
|
+}
|
|
+
|
|
+static void bulk_receive_cb(struct vchiq_mmal_instance *instance,
|
|
+ struct mmal_msg_context *msg_context)
|
|
+{
|
|
+ msg_context->u.bulk.status = 0;
|
|
+
|
|
+ /* schedule the port callback */
|
|
+ schedule_work(&msg_context->u.bulk.work);
|
|
+}
|
|
+
|
|
+static void bulk_abort_cb(struct vchiq_mmal_instance *instance,
|
|
+ struct mmal_msg_context *msg_context)
|
|
+{
|
|
+ pr_err("%s: bulk ABORTED msg_context:%p\n", __func__, msg_context);
|
|
+
|
|
+ msg_context->u.bulk.status = -EINTR;
|
|
+
|
|
+ schedule_work(&msg_context->u.bulk.work);
|
|
+}
|
|
+
|
|
+/* incoming event service callback */
|
|
+static void service_callback(void *param,
|
|
+ const VCHI_CALLBACK_REASON_T reason,
|
|
+ void *bulk_ctx)
|
|
+{
|
|
+ struct vchiq_mmal_instance *instance = param;
|
|
+ int status;
|
|
+ u32 msg_len;
|
|
+ struct mmal_msg *msg;
|
|
+ struct vchi_held_msg msg_handle;
|
|
+ struct mmal_msg_context *msg_context;
|
|
+
|
|
+ if (!instance) {
|
|
+ pr_err("Message callback passed NULL instance\n");
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ switch (reason) {
|
|
+ case VCHI_CALLBACK_MSG_AVAILABLE:
|
|
+ status = vchi_msg_hold(instance->handle, (void **)&msg,
|
|
+ &msg_len, VCHI_FLAGS_NONE, &msg_handle);
|
|
+ if (status) {
|
|
+ pr_err("Unable to dequeue a message (%d)\n", status);
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ DBG_DUMP_MSG(msg, msg_len, "<<< reply message");
|
|
+
|
|
+ /* handling is different for buffer messages */
|
|
+ switch (msg->h.type) {
|
|
+ case MMAL_MSG_TYPE_BUFFER_FROM_HOST:
|
|
+ vchi_held_msg_release(&msg_handle);
|
|
+ break;
|
|
+
|
|
+ case MMAL_MSG_TYPE_EVENT_TO_HOST:
|
|
+ event_to_host_cb(instance, msg, msg_len);
|
|
+ vchi_held_msg_release(&msg_handle);
|
|
+
|
|
+ break;
|
|
+
|
|
+ case MMAL_MSG_TYPE_BUFFER_TO_HOST:
|
|
+ buffer_to_host_cb(instance, msg, msg_len);
|
|
+ vchi_held_msg_release(&msg_handle);
|
|
+ break;
|
|
+
|
|
+ default:
|
|
+ /* messages dependent on header context to complete */
|
|
+ if (!msg->h.context) {
|
|
+ pr_err("received message context was null!\n");
|
|
+ vchi_held_msg_release(&msg_handle);
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ msg_context = lookup_msg_context(instance,
|
|
+ msg->h.context);
|
|
+ if (!msg_context) {
|
|
+ pr_err("received invalid message context %u!\n",
|
|
+ msg->h.context);
|
|
+ vchi_held_msg_release(&msg_handle);
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ /* fill in context values */
|
|
+ msg_context->u.sync.msg_handle = msg_handle;
|
|
+ msg_context->u.sync.msg = msg;
|
|
+ msg_context->u.sync.msg_len = msg_len;
|
|
+
|
|
+ /* todo: should this check (completion_done()
|
|
+ * == 1) for no one waiting? or do we need a
|
|
+ * flag to tell us the completion has been
|
|
+ * interrupted so we can free the message and
|
|
+ * its context. This probably also solves the
|
|
+ * message arriving after interruption todo
|
|
+ * below
|
|
+ */
|
|
+
|
|
+ /* complete message so caller knows it happened */
|
|
+ complete(&msg_context->u.sync.cmplt);
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ break;
|
|
+
|
|
+ case VCHI_CALLBACK_BULK_RECEIVED:
|
|
+ bulk_receive_cb(instance, bulk_ctx);
|
|
+ break;
|
|
+
|
|
+ case VCHI_CALLBACK_BULK_RECEIVE_ABORTED:
|
|
+ bulk_abort_cb(instance, bulk_ctx);
|
|
+ break;
|
|
+
|
|
+ case VCHI_CALLBACK_SERVICE_CLOSED:
|
|
+ /* TODO: consider if this requires action if received when
|
|
+ * driver is not explicitly closing the service
|
|
+ */
|
|
+ break;
|
|
+
|
|
+ default:
|
|
+ pr_err("Received unhandled message reason %d\n", reason);
|
|
+ break;
|
|
+ }
|
|
+}
|
|
+
|
|
+static int send_synchronous_mmal_msg(struct vchiq_mmal_instance *instance,
|
|
+ struct mmal_msg *msg,
|
|
+ unsigned int payload_len,
|
|
+ struct mmal_msg **msg_out,
|
|
+ struct vchi_held_msg *msg_handle_out)
|
|
+{
|
|
+ struct mmal_msg_context *msg_context;
|
|
+ int ret;
|
|
+ unsigned long timeout;
|
|
+
|
|
+ /* payload size must not cause message to exceed max size */
|
|
+ if (payload_len >
|
|
+ (MMAL_MSG_MAX_SIZE - sizeof(struct mmal_msg_header))) {
|
|
+ pr_err("payload length %d exceeds max:%d\n", payload_len,
|
|
+ (int)(MMAL_MSG_MAX_SIZE -
|
|
+ sizeof(struct mmal_msg_header)));
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
+ msg_context = get_msg_context(instance);
|
|
+ if (IS_ERR(msg_context))
|
|
+ return PTR_ERR(msg_context);
|
|
+
|
|
+ init_completion(&msg_context->u.sync.cmplt);
|
|
+
|
|
+ msg->h.magic = MMAL_MAGIC;
|
|
+ msg->h.context = msg_context->handle;
|
|
+ msg->h.status = 0;
|
|
+
|
|
+ DBG_DUMP_MSG(msg, (sizeof(struct mmal_msg_header) + payload_len),
|
|
+ ">>> sync message");
|
|
+
|
|
+ vchi_service_use(instance->handle);
|
|
+
|
|
+ ret = vchi_queue_kernel_message(instance->handle,
|
|
+ msg,
|
|
+ sizeof(struct mmal_msg_header) +
|
|
+ payload_len);
|
|
+
|
|
+ vchi_service_release(instance->handle);
|
|
+
|
|
+ if (ret) {
|
|
+ pr_err("error %d queuing message\n", ret);
|
|
+ release_msg_context(msg_context);
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ timeout = wait_for_completion_timeout(&msg_context->u.sync.cmplt,
|
|
+ 3 * HZ);
|
|
+ if (timeout == 0) {
|
|
+ pr_err("timed out waiting for sync completion\n");
|
|
+ ret = -ETIME;
|
|
+ /* todo: what happens if the message arrives after aborting */
|
|
+ release_msg_context(msg_context);
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ *msg_out = msg_context->u.sync.msg;
|
|
+ *msg_handle_out = msg_context->u.sync.msg_handle;
|
|
+ release_msg_context(msg_context);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static void dump_port_info(struct vchiq_mmal_port *port)
|
|
+{
|
|
+ pr_debug("port handle:0x%x enabled:%d\n", port->handle, port->enabled);
|
|
+
|
|
+ pr_debug("buffer minimum num:%d size:%d align:%d\n",
|
|
+ port->minimum_buffer.num,
|
|
+ port->minimum_buffer.size, port->minimum_buffer.alignment);
|
|
+
|
|
+ pr_debug("buffer recommended num:%d size:%d align:%d\n",
|
|
+ port->recommended_buffer.num,
|
|
+ port->recommended_buffer.size,
|
|
+ port->recommended_buffer.alignment);
|
|
+
|
|
+ pr_debug("buffer current values num:%d size:%d align:%d\n",
|
|
+ port->current_buffer.num,
|
|
+ port->current_buffer.size, port->current_buffer.alignment);
|
|
+
|
|
+ pr_debug("elementary stream: type:%d encoding:0x%x variant:0x%x\n",
|
|
+ port->format.type,
|
|
+ port->format.encoding, port->format.encoding_variant);
|
|
+
|
|
+ pr_debug(" bitrate:%d flags:0x%x\n",
|
|
+ port->format.bitrate, port->format.flags);
|
|
+
|
|
+ if (port->format.type == MMAL_ES_TYPE_VIDEO) {
|
|
+ pr_debug
|
|
+ ("es video format: width:%d height:%d colourspace:0x%x\n",
|
|
+ port->es.video.width, port->es.video.height,
|
|
+ port->es.video.color_space);
|
|
+
|
|
+ pr_debug(" : crop xywh %d,%d,%d,%d\n",
|
|
+ port->es.video.crop.x,
|
|
+ port->es.video.crop.y,
|
|
+ port->es.video.crop.width, port->es.video.crop.height);
|
|
+ pr_debug(" : framerate %d/%d aspect %d/%d\n",
|
|
+ port->es.video.frame_rate.num,
|
|
+ port->es.video.frame_rate.den,
|
|
+ port->es.video.par.num, port->es.video.par.den);
|
|
+ }
|
|
+}
|
|
+
|
|
+static void port_to_mmal_msg(struct vchiq_mmal_port *port, struct mmal_port *p)
|
|
+{
|
|
+ /* todo do readonly fields need setting at all? */
|
|
+ p->type = port->type;
|
|
+ p->index = port->index;
|
|
+ p->index_all = 0;
|
|
+ p->is_enabled = port->enabled;
|
|
+ p->buffer_num_min = port->minimum_buffer.num;
|
|
+ p->buffer_size_min = port->minimum_buffer.size;
|
|
+ p->buffer_alignment_min = port->minimum_buffer.alignment;
|
|
+ p->buffer_num_recommended = port->recommended_buffer.num;
|
|
+ p->buffer_size_recommended = port->recommended_buffer.size;
|
|
+
|
|
+ /* only three writable fields in a port */
|
|
+ p->buffer_num = port->current_buffer.num;
|
|
+ p->buffer_size = port->current_buffer.size;
|
|
+ p->userdata = (u32)(unsigned long)port;
|
|
+}
|
|
+
|
|
+static int port_info_set(struct vchiq_mmal_instance *instance,
|
|
+ struct vchiq_mmal_port *port)
|
|
+{
|
|
+ int ret;
|
|
+ struct mmal_msg m;
|
|
+ struct mmal_msg *rmsg;
|
|
+ struct vchi_held_msg rmsg_handle;
|
|
+
|
|
+ pr_debug("setting port info port %p\n", port);
|
|
+ if (!port)
|
|
+ return -1;
|
|
+ dump_port_info(port);
|
|
+
|
|
+ m.h.type = MMAL_MSG_TYPE_PORT_INFO_SET;
|
|
+
|
|
+ m.u.port_info_set.component_handle = port->component->handle;
|
|
+ m.u.port_info_set.port_type = port->type;
|
|
+ m.u.port_info_set.port_index = port->index;
|
|
+
|
|
+ port_to_mmal_msg(port, &m.u.port_info_set.port);
|
|
+
|
|
+ /* elementary stream format setup */
|
|
+ m.u.port_info_set.format.type = port->format.type;
|
|
+ m.u.port_info_set.format.encoding = port->format.encoding;
|
|
+ m.u.port_info_set.format.encoding_variant =
|
|
+ port->format.encoding_variant;
|
|
+ m.u.port_info_set.format.bitrate = port->format.bitrate;
|
|
+ m.u.port_info_set.format.flags = port->format.flags;
|
|
+
|
|
+ memcpy(&m.u.port_info_set.es, &port->es,
|
|
+ sizeof(union mmal_es_specific_format));
|
|
+
|
|
+ m.u.port_info_set.format.extradata_size = port->format.extradata_size;
|
|
+ memcpy(&m.u.port_info_set.extradata, port->format.extradata,
|
|
+ port->format.extradata_size);
|
|
+
|
|
+ ret = send_synchronous_mmal_msg(instance, &m,
|
|
+ sizeof(m.u.port_info_set),
|
|
+ &rmsg, &rmsg_handle);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
+ if (rmsg->h.type != MMAL_MSG_TYPE_PORT_INFO_SET) {
|
|
+ /* got an unexpected message type in reply */
|
|
+ ret = -EINVAL;
|
|
+ goto release_msg;
|
|
+ }
|
|
+
|
|
+ /* return operation status */
|
|
+ ret = -rmsg->u.port_info_get_reply.status;
|
|
+
|
|
+ pr_debug("%s:result:%d component:0x%x port:%d\n", __func__, ret,
|
|
+ port->component->handle, port->handle);
|
|
+
|
|
+release_msg:
|
|
+ vchi_held_msg_release(&rmsg_handle);
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+/* use port info get message to retrieve port information */
|
|
+static int port_info_get(struct vchiq_mmal_instance *instance,
|
|
+ struct vchiq_mmal_port *port)
|
|
+{
|
|
+ int ret;
|
|
+ struct mmal_msg m;
|
|
+ struct mmal_msg *rmsg;
|
|
+ struct vchi_held_msg rmsg_handle;
|
|
+
|
|
+ /* port info time */
|
|
+ m.h.type = MMAL_MSG_TYPE_PORT_INFO_GET;
|
|
+ m.u.port_info_get.component_handle = port->component->handle;
|
|
+ m.u.port_info_get.port_type = port->type;
|
|
+ m.u.port_info_get.index = port->index;
|
|
+
|
|
+ ret = send_synchronous_mmal_msg(instance, &m,
|
|
+ sizeof(m.u.port_info_get),
|
|
+ &rmsg, &rmsg_handle);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
+ if (rmsg->h.type != MMAL_MSG_TYPE_PORT_INFO_GET) {
|
|
+ /* got an unexpected message type in reply */
|
|
+ ret = -EINVAL;
|
|
+ goto release_msg;
|
|
+ }
|
|
+
|
|
+ /* return operation status */
|
|
+ ret = -rmsg->u.port_info_get_reply.status;
|
|
+ if (ret != MMAL_MSG_STATUS_SUCCESS)
|
|
+ goto release_msg;
|
|
+
|
|
+ if (rmsg->u.port_info_get_reply.port.is_enabled == 0)
|
|
+ port->enabled = 0;
|
|
+ else
|
|
+ port->enabled = 1;
|
|
+
|
|
+ /* copy the values out of the message */
|
|
+ port->handle = rmsg->u.port_info_get_reply.port_handle;
|
|
+
|
|
+ /* port type and index cached to use on port info set because
|
|
+ * it does not use a port handle
|
|
+ */
|
|
+ port->type = rmsg->u.port_info_get_reply.port_type;
|
|
+ port->index = rmsg->u.port_info_get_reply.port_index;
|
|
+
|
|
+ port->minimum_buffer.num =
|
|
+ rmsg->u.port_info_get_reply.port.buffer_num_min;
|
|
+ port->minimum_buffer.size =
|
|
+ rmsg->u.port_info_get_reply.port.buffer_size_min;
|
|
+ port->minimum_buffer.alignment =
|
|
+ rmsg->u.port_info_get_reply.port.buffer_alignment_min;
|
|
+
|
|
+ port->recommended_buffer.alignment =
|
|
+ rmsg->u.port_info_get_reply.port.buffer_alignment_min;
|
|
+ port->recommended_buffer.num =
|
|
+ rmsg->u.port_info_get_reply.port.buffer_num_recommended;
|
|
+
|
|
+ port->current_buffer.num = rmsg->u.port_info_get_reply.port.buffer_num;
|
|
+ port->current_buffer.size =
|
|
+ rmsg->u.port_info_get_reply.port.buffer_size;
|
|
+
|
|
+ /* stream format */
|
|
+ port->format.type = rmsg->u.port_info_get_reply.format.type;
|
|
+ port->format.encoding = rmsg->u.port_info_get_reply.format.encoding;
|
|
+ port->format.encoding_variant =
|
|
+ rmsg->u.port_info_get_reply.format.encoding_variant;
|
|
+ port->format.bitrate = rmsg->u.port_info_get_reply.format.bitrate;
|
|
+ port->format.flags = rmsg->u.port_info_get_reply.format.flags;
|
|
+
|
|
+ /* elementary stream format */
|
|
+ memcpy(&port->es,
|
|
+ &rmsg->u.port_info_get_reply.es,
|
|
+ sizeof(union mmal_es_specific_format));
|
|
+ port->format.es = &port->es;
|
|
+
|
|
+ port->format.extradata_size =
|
|
+ rmsg->u.port_info_get_reply.format.extradata_size;
|
|
+ memcpy(port->format.extradata,
|
|
+ rmsg->u.port_info_get_reply.extradata,
|
|
+ port->format.extradata_size);
|
|
+
|
|
+ pr_debug("received port info\n");
|
|
+ dump_port_info(port);
|
|
+
|
|
+release_msg:
|
|
+
|
|
+ pr_debug("%s:result:%d component:0x%x port:%d\n",
|
|
+ __func__, ret, port->component->handle, port->handle);
|
|
+
|
|
+ vchi_held_msg_release(&rmsg_handle);
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+/* create comonent on vc */
|
|
+static int create_component(struct vchiq_mmal_instance *instance,
|
|
+ struct vchiq_mmal_component *component,
|
|
+ const char *name)
|
|
+{
|
|
+ int ret;
|
|
+ struct mmal_msg m;
|
|
+ struct mmal_msg *rmsg;
|
|
+ struct vchi_held_msg rmsg_handle;
|
|
+
|
|
+ /* build component create message */
|
|
+ m.h.type = MMAL_MSG_TYPE_COMPONENT_CREATE;
|
|
+ m.u.component_create.client_component = (u32)(unsigned long)component;
|
|
+ strncpy(m.u.component_create.name, name,
|
|
+ sizeof(m.u.component_create.name));
|
|
+
|
|
+ ret = send_synchronous_mmal_msg(instance, &m,
|
|
+ sizeof(m.u.component_create),
|
|
+ &rmsg, &rmsg_handle);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
+ if (rmsg->h.type != m.h.type) {
|
|
+ /* got an unexpected message type in reply */
|
|
+ ret = -EINVAL;
|
|
+ goto release_msg;
|
|
+ }
|
|
+
|
|
+ ret = -rmsg->u.component_create_reply.status;
|
|
+ if (ret != MMAL_MSG_STATUS_SUCCESS)
|
|
+ goto release_msg;
|
|
+
|
|
+ /* a valid component response received */
|
|
+ component->handle = rmsg->u.component_create_reply.component_handle;
|
|
+ component->inputs = rmsg->u.component_create_reply.input_num;
|
|
+ component->outputs = rmsg->u.component_create_reply.output_num;
|
|
+ component->clocks = rmsg->u.component_create_reply.clock_num;
|
|
+
|
|
+ pr_debug("Component handle:0x%x in:%d out:%d clock:%d\n",
|
|
+ component->handle,
|
|
+ component->inputs, component->outputs, component->clocks);
|
|
+
|
|
+release_msg:
|
|
+ vchi_held_msg_release(&rmsg_handle);
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+/* destroys a component on vc */
|
|
+static int destroy_component(struct vchiq_mmal_instance *instance,
|
|
+ struct vchiq_mmal_component *component)
|
|
+{
|
|
+ int ret;
|
|
+ struct mmal_msg m;
|
|
+ struct mmal_msg *rmsg;
|
|
+ struct vchi_held_msg rmsg_handle;
|
|
+
|
|
+ m.h.type = MMAL_MSG_TYPE_COMPONENT_DESTROY;
|
|
+ m.u.component_destroy.component_handle = component->handle;
|
|
+
|
|
+ ret = send_synchronous_mmal_msg(instance, &m,
|
|
+ sizeof(m.u.component_destroy),
|
|
+ &rmsg, &rmsg_handle);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
+ if (rmsg->h.type != m.h.type) {
|
|
+ /* got an unexpected message type in reply */
|
|
+ ret = -EINVAL;
|
|
+ goto release_msg;
|
|
+ }
|
|
+
|
|
+ ret = -rmsg->u.component_destroy_reply.status;
|
|
+
|
|
+release_msg:
|
|
+
|
|
+ vchi_held_msg_release(&rmsg_handle);
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+/* enable a component on vc */
|
|
+static int enable_component(struct vchiq_mmal_instance *instance,
|
|
+ struct vchiq_mmal_component *component)
|
|
+{
|
|
+ int ret;
|
|
+ struct mmal_msg m;
|
|
+ struct mmal_msg *rmsg;
|
|
+ struct vchi_held_msg rmsg_handle;
|
|
+
|
|
+ m.h.type = MMAL_MSG_TYPE_COMPONENT_ENABLE;
|
|
+ m.u.component_enable.component_handle = component->handle;
|
|
+
|
|
+ ret = send_synchronous_mmal_msg(instance, &m,
|
|
+ sizeof(m.u.component_enable),
|
|
+ &rmsg, &rmsg_handle);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
+ if (rmsg->h.type != m.h.type) {
|
|
+ /* got an unexpected message type in reply */
|
|
+ ret = -EINVAL;
|
|
+ goto release_msg;
|
|
+ }
|
|
+
|
|
+ ret = -rmsg->u.component_enable_reply.status;
|
|
+
|
|
+release_msg:
|
|
+ vchi_held_msg_release(&rmsg_handle);
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+/* disable a component on vc */
|
|
+static int disable_component(struct vchiq_mmal_instance *instance,
|
|
+ struct vchiq_mmal_component *component)
|
|
+{
|
|
+ int ret;
|
|
+ struct mmal_msg m;
|
|
+ struct mmal_msg *rmsg;
|
|
+ struct vchi_held_msg rmsg_handle;
|
|
+
|
|
+ m.h.type = MMAL_MSG_TYPE_COMPONENT_DISABLE;
|
|
+ m.u.component_disable.component_handle = component->handle;
|
|
+
|
|
+ ret = send_synchronous_mmal_msg(instance, &m,
|
|
+ sizeof(m.u.component_disable),
|
|
+ &rmsg, &rmsg_handle);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
+ if (rmsg->h.type != m.h.type) {
|
|
+ /* got an unexpected message type in reply */
|
|
+ ret = -EINVAL;
|
|
+ goto release_msg;
|
|
+ }
|
|
+
|
|
+ ret = -rmsg->u.component_disable_reply.status;
|
|
+
|
|
+release_msg:
|
|
+
|
|
+ vchi_held_msg_release(&rmsg_handle);
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+/* get version of mmal implementation */
|
|
+static int get_version(struct vchiq_mmal_instance *instance,
|
|
+ u32 *major_out, u32 *minor_out)
|
|
+{
|
|
+ int ret;
|
|
+ struct mmal_msg m;
|
|
+ struct mmal_msg *rmsg;
|
|
+ struct vchi_held_msg rmsg_handle;
|
|
+
|
|
+ m.h.type = MMAL_MSG_TYPE_GET_VERSION;
|
|
+
|
|
+ ret = send_synchronous_mmal_msg(instance, &m,
|
|
+ sizeof(m.u.version),
|
|
+ &rmsg, &rmsg_handle);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
+ if (rmsg->h.type != m.h.type) {
|
|
+ /* got an unexpected message type in reply */
|
|
+ ret = -EINVAL;
|
|
+ goto release_msg;
|
|
+ }
|
|
+
|
|
+ *major_out = rmsg->u.version.major;
|
|
+ *minor_out = rmsg->u.version.minor;
|
|
+
|
|
+release_msg:
|
|
+ vchi_held_msg_release(&rmsg_handle);
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+/* do a port action with a port as a parameter */
|
|
+static int port_action_port(struct vchiq_mmal_instance *instance,
|
|
+ struct vchiq_mmal_port *port,
|
|
+ enum mmal_msg_port_action_type action_type)
|
|
+{
|
|
+ int ret;
|
|
+ struct mmal_msg m;
|
|
+ struct mmal_msg *rmsg;
|
|
+ struct vchi_held_msg rmsg_handle;
|
|
+
|
|
+ m.h.type = MMAL_MSG_TYPE_PORT_ACTION;
|
|
+ m.u.port_action_port.component_handle = port->component->handle;
|
|
+ m.u.port_action_port.port_handle = port->handle;
|
|
+ m.u.port_action_port.action = action_type;
|
|
+
|
|
+ port_to_mmal_msg(port, &m.u.port_action_port.port);
|
|
+
|
|
+ ret = send_synchronous_mmal_msg(instance, &m,
|
|
+ sizeof(m.u.port_action_port),
|
|
+ &rmsg, &rmsg_handle);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
+ if (rmsg->h.type != MMAL_MSG_TYPE_PORT_ACTION) {
|
|
+ /* got an unexpected message type in reply */
|
|
+ ret = -EINVAL;
|
|
+ goto release_msg;
|
|
+ }
|
|
+
|
|
+ ret = -rmsg->u.port_action_reply.status;
|
|
+
|
|
+ pr_debug("%s:result:%d component:0x%x port:%d action:%s(%d)\n",
|
|
+ __func__,
|
|
+ ret, port->component->handle, port->handle,
|
|
+ port_action_type_names[action_type], action_type);
|
|
+
|
|
+release_msg:
|
|
+ vchi_held_msg_release(&rmsg_handle);
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+/* do a port action with handles as parameters */
|
|
+static int port_action_handle(struct vchiq_mmal_instance *instance,
|
|
+ struct vchiq_mmal_port *port,
|
|
+ enum mmal_msg_port_action_type action_type,
|
|
+ u32 connect_component_handle,
|
|
+ u32 connect_port_handle)
|
|
+{
|
|
+ int ret;
|
|
+ struct mmal_msg m;
|
|
+ struct mmal_msg *rmsg;
|
|
+ struct vchi_held_msg rmsg_handle;
|
|
+
|
|
+ m.h.type = MMAL_MSG_TYPE_PORT_ACTION;
|
|
+
|
|
+ m.u.port_action_handle.component_handle = port->component->handle;
|
|
+ m.u.port_action_handle.port_handle = port->handle;
|
|
+ m.u.port_action_handle.action = action_type;
|
|
+
|
|
+ m.u.port_action_handle.connect_component_handle =
|
|
+ connect_component_handle;
|
|
+ m.u.port_action_handle.connect_port_handle = connect_port_handle;
|
|
+
|
|
+ ret = send_synchronous_mmal_msg(instance, &m,
|
|
+ sizeof(m.u.port_action_handle),
|
|
+ &rmsg, &rmsg_handle);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
+ if (rmsg->h.type != MMAL_MSG_TYPE_PORT_ACTION) {
|
|
+ /* got an unexpected message type in reply */
|
|
+ ret = -EINVAL;
|
|
+ goto release_msg;
|
|
+ }
|
|
+
|
|
+ ret = -rmsg->u.port_action_reply.status;
|
|
+
|
|
+ pr_debug("%s:result:%d component:0x%x port:%d action:%s(%d) connect component:0x%x connect port:%d\n",
|
|
+ __func__,
|
|
+ ret, port->component->handle, port->handle,
|
|
+ port_action_type_names[action_type],
|
|
+ action_type, connect_component_handle, connect_port_handle);
|
|
+
|
|
+release_msg:
|
|
+ vchi_held_msg_release(&rmsg_handle);
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+static int port_parameter_set(struct vchiq_mmal_instance *instance,
|
|
+ struct vchiq_mmal_port *port,
|
|
+ u32 parameter_id, void *value, u32 value_size)
|
|
+{
|
|
+ int ret;
|
|
+ struct mmal_msg m;
|
|
+ struct mmal_msg *rmsg;
|
|
+ struct vchi_held_msg rmsg_handle;
|
|
+
|
|
+ m.h.type = MMAL_MSG_TYPE_PORT_PARAMETER_SET;
|
|
+
|
|
+ m.u.port_parameter_set.component_handle = port->component->handle;
|
|
+ m.u.port_parameter_set.port_handle = port->handle;
|
|
+ m.u.port_parameter_set.id = parameter_id;
|
|
+ m.u.port_parameter_set.size = (2 * sizeof(u32)) + value_size;
|
|
+ memcpy(&m.u.port_parameter_set.value, value, value_size);
|
|
+
|
|
+ ret = send_synchronous_mmal_msg(instance, &m,
|
|
+ (4 * sizeof(u32)) + value_size,
|
|
+ &rmsg, &rmsg_handle);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
+ if (rmsg->h.type != MMAL_MSG_TYPE_PORT_PARAMETER_SET) {
|
|
+ /* got an unexpected message type in reply */
|
|
+ ret = -EINVAL;
|
|
+ goto release_msg;
|
|
+ }
|
|
+
|
|
+ ret = -rmsg->u.port_parameter_set_reply.status;
|
|
+
|
|
+ pr_debug("%s:result:%d component:0x%x port:%d parameter:%d\n",
|
|
+ __func__,
|
|
+ ret, port->component->handle, port->handle, parameter_id);
|
|
+
|
|
+release_msg:
|
|
+ vchi_held_msg_release(&rmsg_handle);
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+static int port_parameter_get(struct vchiq_mmal_instance *instance,
|
|
+ struct vchiq_mmal_port *port,
|
|
+ u32 parameter_id, void *value, u32 *value_size)
|
|
+{
|
|
+ int ret;
|
|
+ struct mmal_msg m;
|
|
+ struct mmal_msg *rmsg;
|
|
+ struct vchi_held_msg rmsg_handle;
|
|
+
|
|
+ m.h.type = MMAL_MSG_TYPE_PORT_PARAMETER_GET;
|
|
+
|
|
+ m.u.port_parameter_get.component_handle = port->component->handle;
|
|
+ m.u.port_parameter_get.port_handle = port->handle;
|
|
+ m.u.port_parameter_get.id = parameter_id;
|
|
+ m.u.port_parameter_get.size = (2 * sizeof(u32)) + *value_size;
|
|
+
|
|
+ ret = send_synchronous_mmal_msg(instance, &m,
|
|
+ sizeof(struct
|
|
+ mmal_msg_port_parameter_get),
|
|
+ &rmsg, &rmsg_handle);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
+ if (rmsg->h.type != MMAL_MSG_TYPE_PORT_PARAMETER_GET) {
|
|
+ /* got an unexpected message type in reply */
|
|
+ pr_err("Incorrect reply type %d\n", rmsg->h.type);
|
|
+ ret = -EINVAL;
|
|
+ goto release_msg;
|
|
+ }
|
|
+
|
|
+ ret = -rmsg->u.port_parameter_get_reply.status;
|
|
+ /* port_parameter_get_reply.size includes the header,
|
|
+ * whilst *value_size doesn't.
|
|
+ */
|
|
+ rmsg->u.port_parameter_get_reply.size -= (2 * sizeof(u32));
|
|
+
|
|
+ if (ret || rmsg->u.port_parameter_get_reply.size > *value_size) {
|
|
+ /* Copy only as much as we have space for
|
|
+ * but report true size of parameter
|
|
+ */
|
|
+ memcpy(value, &rmsg->u.port_parameter_get_reply.value,
|
|
+ *value_size);
|
|
+ *value_size = rmsg->u.port_parameter_get_reply.size;
|
|
+ } else {
|
|
+ memcpy(value, &rmsg->u.port_parameter_get_reply.value,
|
|
+ rmsg->u.port_parameter_get_reply.size);
|
|
+ }
|
|
+
|
|
+ pr_debug("%s:result:%d component:0x%x port:%d parameter:%d\n", __func__,
|
|
+ ret, port->component->handle, port->handle, parameter_id);
|
|
+
|
|
+release_msg:
|
|
+ vchi_held_msg_release(&rmsg_handle);
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+/* disables a port and drains buffers from it */
|
|
+static int port_disable(struct vchiq_mmal_instance *instance,
|
|
+ struct vchiq_mmal_port *port)
|
|
+{
|
|
+ int ret;
|
|
+ struct list_head *q, *buf_head;
|
|
+ unsigned long flags = 0;
|
|
+
|
|
+ if (!port->enabled)
|
|
+ return 0;
|
|
+
|
|
+ port->enabled = 0;
|
|
+
|
|
+ ret = port_action_port(instance, port,
|
|
+ MMAL_MSG_PORT_ACTION_TYPE_DISABLE);
|
|
+ if (ret == 0) {
|
|
+ /*
|
|
+ * Drain all queued buffers on port. This should only
|
|
+ * apply to buffers that have been queued before the port
|
|
+ * has been enabled. If the port has been enabled and buffers
|
|
+ * passed, then the buffers should have been removed from this
|
|
+ * list, and we should get the relevant callbacks via VCHIQ
|
|
+ * to release the buffers.
|
|
+ */
|
|
+ spin_lock_irqsave(&port->slock, flags);
|
|
+
|
|
+ list_for_each_safe(buf_head, q, &port->buffers) {
|
|
+ struct mmal_buffer *mmalbuf;
|
|
+
|
|
+ mmalbuf = list_entry(buf_head, struct mmal_buffer,
|
|
+ list);
|
|
+ list_del(buf_head);
|
|
+ if (port->buffer_cb)
|
|
+ port->buffer_cb(instance,
|
|
+ port, 0, mmalbuf, 0, 0,
|
|
+ MMAL_TIME_UNKNOWN,
|
|
+ MMAL_TIME_UNKNOWN);
|
|
+ }
|
|
+
|
|
+ spin_unlock_irqrestore(&port->slock, flags);
|
|
+
|
|
+ ret = port_info_get(instance, port);
|
|
+ }
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+/* enable a port */
|
|
+static int port_enable(struct vchiq_mmal_instance *instance,
|
|
+ struct vchiq_mmal_port *port)
|
|
+{
|
|
+ unsigned int hdr_count;
|
|
+ struct list_head *q, *buf_head;
|
|
+ int ret;
|
|
+
|
|
+ if (port->enabled)
|
|
+ return 0;
|
|
+
|
|
+ ret = port_action_port(instance, port,
|
|
+ MMAL_MSG_PORT_ACTION_TYPE_ENABLE);
|
|
+ if (ret)
|
|
+ goto done;
|
|
+
|
|
+ port->enabled = 1;
|
|
+
|
|
+ if (port->buffer_cb) {
|
|
+ /* send buffer headers to videocore */
|
|
+ hdr_count = 1;
|
|
+ list_for_each_safe(buf_head, q, &port->buffers) {
|
|
+ struct mmal_buffer *mmalbuf;
|
|
+
|
|
+ mmalbuf = list_entry(buf_head, struct mmal_buffer,
|
|
+ list);
|
|
+ ret = buffer_from_host(instance, port, mmalbuf);
|
|
+ if (ret)
|
|
+ goto done;
|
|
+
|
|
+ list_del(buf_head);
|
|
+ hdr_count++;
|
|
+ if (hdr_count > port->current_buffer.num)
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ ret = port_info_get(instance, port);
|
|
+
|
|
+done:
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+/* ------------------------------------------------------------------
|
|
+ * Exported API
|
|
+ *------------------------------------------------------------------
|
|
+ */
|
|
+
|
|
+int vchiq_mmal_port_set_format(struct vchiq_mmal_instance *instance,
|
|
+ struct vchiq_mmal_port *port)
|
|
+{
|
|
+ int ret;
|
|
+
|
|
+ if (mutex_lock_interruptible(&instance->vchiq_mutex))
|
|
+ return -EINTR;
|
|
+
|
|
+ ret = port_info_set(instance, port);
|
|
+ if (ret)
|
|
+ goto release_unlock;
|
|
+
|
|
+ /* read what has actually been set */
|
|
+ ret = port_info_get(instance, port);
|
|
+
|
|
+release_unlock:
|
|
+ mutex_unlock(&instance->vchiq_mutex);
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+EXPORT_SYMBOL_GPL(vchiq_mmal_port_set_format);
|
|
+
|
|
+int vchiq_mmal_port_parameter_set(struct vchiq_mmal_instance *instance,
|
|
+ struct vchiq_mmal_port *port,
|
|
+ u32 parameter, void *value, u32 value_size)
|
|
+{
|
|
+ int ret;
|
|
+
|
|
+ if (mutex_lock_interruptible(&instance->vchiq_mutex))
|
|
+ return -EINTR;
|
|
+
|
|
+ ret = port_parameter_set(instance, port, parameter, value, value_size);
|
|
+
|
|
+ mutex_unlock(&instance->vchiq_mutex);
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+EXPORT_SYMBOL_GPL(vchiq_mmal_port_parameter_set);
|
|
+
|
|
+int vchiq_mmal_port_parameter_get(struct vchiq_mmal_instance *instance,
|
|
+ struct vchiq_mmal_port *port,
|
|
+ u32 parameter, void *value, u32 *value_size)
|
|
+{
|
|
+ int ret;
|
|
+
|
|
+ if (mutex_lock_interruptible(&instance->vchiq_mutex))
|
|
+ return -EINTR;
|
|
+
|
|
+ ret = port_parameter_get(instance, port, parameter, value, value_size);
|
|
+
|
|
+ mutex_unlock(&instance->vchiq_mutex);
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+EXPORT_SYMBOL_GPL(vchiq_mmal_port_parameter_get);
|
|
+
|
|
+/* enable a port
|
|
+ *
|
|
+ * enables a port and queues buffers for satisfying callbacks if we
|
|
+ * provide a callback handler
|
|
+ */
|
|
+int vchiq_mmal_port_enable(struct vchiq_mmal_instance *instance,
|
|
+ struct vchiq_mmal_port *port,
|
|
+ vchiq_mmal_buffer_cb buffer_cb)
|
|
+{
|
|
+ int ret;
|
|
+
|
|
+ if (mutex_lock_interruptible(&instance->vchiq_mutex))
|
|
+ return -EINTR;
|
|
+
|
|
+ /* already enabled - noop */
|
|
+ if (port->enabled) {
|
|
+ ret = 0;
|
|
+ goto unlock;
|
|
+ }
|
|
+
|
|
+ port->buffer_cb = buffer_cb;
|
|
+
|
|
+ ret = port_enable(instance, port);
|
|
+
|
|
+unlock:
|
|
+ mutex_unlock(&instance->vchiq_mutex);
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+EXPORT_SYMBOL_GPL(vchiq_mmal_port_enable);
|
|
+
|
|
+int vchiq_mmal_port_disable(struct vchiq_mmal_instance *instance,
|
|
+ struct vchiq_mmal_port *port)
|
|
+{
|
|
+ int ret;
|
|
+
|
|
+ if (mutex_lock_interruptible(&instance->vchiq_mutex))
|
|
+ return -EINTR;
|
|
+
|
|
+ if (!port->enabled) {
|
|
+ mutex_unlock(&instance->vchiq_mutex);
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ ret = port_disable(instance, port);
|
|
+
|
|
+ mutex_unlock(&instance->vchiq_mutex);
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+EXPORT_SYMBOL_GPL(vchiq_mmal_port_disable);
|
|
+
|
|
+/* ports will be connected in a tunneled manner so data buffers
|
|
+ * are not handled by client.
|
|
+ */
|
|
+int vchiq_mmal_port_connect_tunnel(struct vchiq_mmal_instance *instance,
|
|
+ struct vchiq_mmal_port *src,
|
|
+ struct vchiq_mmal_port *dst)
|
|
+{
|
|
+ int ret;
|
|
+
|
|
+ if (mutex_lock_interruptible(&instance->vchiq_mutex))
|
|
+ return -EINTR;
|
|
+
|
|
+ /* disconnect ports if connected */
|
|
+ if (src->connected) {
|
|
+ ret = port_disable(instance, src);
|
|
+ if (ret) {
|
|
+ pr_err("failed disabling src port(%d)\n", ret);
|
|
+ goto release_unlock;
|
|
+ }
|
|
+
|
|
+ /* do not need to disable the destination port as they
|
|
+ * are connected and it is done automatically
|
|
+ */
|
|
+
|
|
+ ret = port_action_handle(instance, src,
|
|
+ MMAL_MSG_PORT_ACTION_TYPE_DISCONNECT,
|
|
+ src->connected->component->handle,
|
|
+ src->connected->handle);
|
|
+ if (ret < 0) {
|
|
+ pr_err("failed disconnecting src port\n");
|
|
+ goto release_unlock;
|
|
+ }
|
|
+ src->connected->enabled = 0;
|
|
+ src->connected = NULL;
|
|
+ }
|
|
+
|
|
+ if (!dst) {
|
|
+ /* do not make new connection */
|
|
+ ret = 0;
|
|
+ pr_debug("not making new connection\n");
|
|
+ goto release_unlock;
|
|
+ }
|
|
+
|
|
+ /* copy src port format to dst */
|
|
+ dst->format.encoding = src->format.encoding;
|
|
+ dst->es.video.width = src->es.video.width;
|
|
+ dst->es.video.height = src->es.video.height;
|
|
+ dst->es.video.crop.x = src->es.video.crop.x;
|
|
+ dst->es.video.crop.y = src->es.video.crop.y;
|
|
+ dst->es.video.crop.width = src->es.video.crop.width;
|
|
+ dst->es.video.crop.height = src->es.video.crop.height;
|
|
+ dst->es.video.frame_rate.num = src->es.video.frame_rate.num;
|
|
+ dst->es.video.frame_rate.den = src->es.video.frame_rate.den;
|
|
+
|
|
+ /* set new format */
|
|
+ ret = port_info_set(instance, dst);
|
|
+ if (ret) {
|
|
+ pr_debug("setting port info failed\n");
|
|
+ goto release_unlock;
|
|
+ }
|
|
+
|
|
+ /* read what has actually been set */
|
|
+ ret = port_info_get(instance, dst);
|
|
+ if (ret) {
|
|
+ pr_debug("read back port info failed\n");
|
|
+ goto release_unlock;
|
|
+ }
|
|
+
|
|
+ /* connect two ports together */
|
|
+ ret = port_action_handle(instance, src,
|
|
+ MMAL_MSG_PORT_ACTION_TYPE_CONNECT,
|
|
+ dst->component->handle, dst->handle);
|
|
+ if (ret < 0) {
|
|
+ pr_debug("connecting port %d:%d to %d:%d failed\n",
|
|
+ src->component->handle, src->handle,
|
|
+ dst->component->handle, dst->handle);
|
|
+ goto release_unlock;
|
|
+ }
|
|
+ src->connected = dst;
|
|
+
|
|
+release_unlock:
|
|
+
|
|
+ mutex_unlock(&instance->vchiq_mutex);
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+EXPORT_SYMBOL_GPL(vchiq_mmal_port_connect_tunnel);
|
|
+
|
|
+int vchiq_mmal_submit_buffer(struct vchiq_mmal_instance *instance,
|
|
+ struct vchiq_mmal_port *port,
|
|
+ struct mmal_buffer *buffer)
|
|
+{
|
|
+ unsigned long flags = 0;
|
|
+ int ret;
|
|
+
|
|
+ ret = buffer_from_host(instance, port, buffer);
|
|
+ if (ret == -EINVAL) {
|
|
+ /* Port is disabled. Queue for when it is enabled. */
|
|
+ spin_lock_irqsave(&port->slock, flags);
|
|
+ list_add_tail(&buffer->list, &port->buffers);
|
|
+ spin_unlock_irqrestore(&port->slock, flags);
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+EXPORT_SYMBOL_GPL(vchiq_mmal_submit_buffer);
|
|
+
|
|
+int mmal_vchi_buffer_init(struct vchiq_mmal_instance *instance,
|
|
+ struct mmal_buffer *buf)
|
|
+{
|
|
+ struct mmal_msg_context *msg_context = get_msg_context(instance);
|
|
+
|
|
+ if (IS_ERR(msg_context))
|
|
+ return (PTR_ERR(msg_context));
|
|
+
|
|
+ buf->msg_context = msg_context;
|
|
+ return 0;
|
|
+}
|
|
+EXPORT_SYMBOL_GPL(mmal_vchi_buffer_init);
|
|
+
|
|
+int mmal_vchi_buffer_cleanup(struct mmal_buffer *buf)
|
|
+{
|
|
+ struct mmal_msg_context *msg_context = buf->msg_context;
|
|
+
|
|
+ if (msg_context)
|
|
+ release_msg_context(msg_context);
|
|
+ buf->msg_context = NULL;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+EXPORT_SYMBOL_GPL(mmal_vchi_buffer_cleanup);
|
|
+
|
|
+/* Initialise a mmal component and its ports
|
|
+ *
|
|
+ */
|
|
+int vchiq_mmal_component_init(struct vchiq_mmal_instance *instance,
|
|
+ const char *name,
|
|
+ struct vchiq_mmal_component **component_out)
|
|
+{
|
|
+ int ret;
|
|
+ int idx; /* port index */
|
|
+ struct vchiq_mmal_component *component;
|
|
+
|
|
+ if (mutex_lock_interruptible(&instance->vchiq_mutex))
|
|
+ return -EINTR;
|
|
+
|
|
+ if (instance->component_idx == VCHIQ_MMAL_MAX_COMPONENTS) {
|
|
+ ret = -EINVAL; /* todo is this correct error? */
|
|
+ goto unlock;
|
|
+ }
|
|
+
|
|
+ component = &instance->component[instance->component_idx];
|
|
+
|
|
+ ret = create_component(instance, component, name);
|
|
+ if (ret < 0) {
|
|
+ pr_err("%s: failed to create component %d (Not enough GPU mem?)\n",
|
|
+ __func__, ret);
|
|
+ goto unlock;
|
|
+ }
|
|
+
|
|
+ /* ports info needs gathering */
|
|
+ component->control.type = MMAL_PORT_TYPE_CONTROL;
|
|
+ component->control.index = 0;
|
|
+ component->control.component = component;
|
|
+ spin_lock_init(&component->control.slock);
|
|
+ INIT_LIST_HEAD(&component->control.buffers);
|
|
+ ret = port_info_get(instance, &component->control);
|
|
+ if (ret < 0)
|
|
+ goto release_component;
|
|
+
|
|
+ for (idx = 0; idx < component->inputs; idx++) {
|
|
+ component->input[idx].type = MMAL_PORT_TYPE_INPUT;
|
|
+ component->input[idx].index = idx;
|
|
+ component->input[idx].component = component;
|
|
+ spin_lock_init(&component->input[idx].slock);
|
|
+ INIT_LIST_HEAD(&component->input[idx].buffers);
|
|
+ ret = port_info_get(instance, &component->input[idx]);
|
|
+ if (ret < 0)
|
|
+ goto release_component;
|
|
+ }
|
|
+
|
|
+ for (idx = 0; idx < component->outputs; idx++) {
|
|
+ component->output[idx].type = MMAL_PORT_TYPE_OUTPUT;
|
|
+ component->output[idx].index = idx;
|
|
+ component->output[idx].component = component;
|
|
+ spin_lock_init(&component->output[idx].slock);
|
|
+ INIT_LIST_HEAD(&component->output[idx].buffers);
|
|
+ ret = port_info_get(instance, &component->output[idx]);
|
|
+ if (ret < 0)
|
|
+ goto release_component;
|
|
+ }
|
|
+
|
|
+ for (idx = 0; idx < component->clocks; idx++) {
|
|
+ component->clock[idx].type = MMAL_PORT_TYPE_CLOCK;
|
|
+ component->clock[idx].index = idx;
|
|
+ component->clock[idx].component = component;
|
|
+ spin_lock_init(&component->clock[idx].slock);
|
|
+ INIT_LIST_HEAD(&component->clock[idx].buffers);
|
|
+ ret = port_info_get(instance, &component->clock[idx]);
|
|
+ if (ret < 0)
|
|
+ goto release_component;
|
|
+ }
|
|
+
|
|
+ instance->component_idx++;
|
|
+
|
|
+ *component_out = component;
|
|
+
|
|
+ mutex_unlock(&instance->vchiq_mutex);
|
|
+
|
|
+ return 0;
|
|
+
|
|
+release_component:
|
|
+ destroy_component(instance, component);
|
|
+unlock:
|
|
+ mutex_unlock(&instance->vchiq_mutex);
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+EXPORT_SYMBOL_GPL(vchiq_mmal_component_init);
|
|
+
|
|
+/*
|
|
+ * cause a mmal component to be destroyed
|
|
+ */
|
|
+int vchiq_mmal_component_finalise(struct vchiq_mmal_instance *instance,
|
|
+ struct vchiq_mmal_component *component)
|
|
+{
|
|
+ int ret;
|
|
+
|
|
+ if (mutex_lock_interruptible(&instance->vchiq_mutex))
|
|
+ return -EINTR;
|
|
+
|
|
+ if (component->enabled)
|
|
+ ret = disable_component(instance, component);
|
|
+
|
|
+ ret = destroy_component(instance, component);
|
|
+
|
|
+ mutex_unlock(&instance->vchiq_mutex);
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+EXPORT_SYMBOL_GPL(vchiq_mmal_component_finalise);
|
|
+
|
|
+/*
|
|
+ * cause a mmal component to be enabled
|
|
+ */
|
|
+int vchiq_mmal_component_enable(struct vchiq_mmal_instance *instance,
|
|
+ struct vchiq_mmal_component *component)
|
|
+{
|
|
+ int ret;
|
|
+
|
|
+ if (mutex_lock_interruptible(&instance->vchiq_mutex))
|
|
+ return -EINTR;
|
|
+
|
|
+ if (component->enabled) {
|
|
+ mutex_unlock(&instance->vchiq_mutex);
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ ret = enable_component(instance, component);
|
|
+ if (ret == 0)
|
|
+ component->enabled = true;
|
|
+
|
|
+ mutex_unlock(&instance->vchiq_mutex);
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+EXPORT_SYMBOL_GPL(vchiq_mmal_component_enable);
|
|
+
|
|
+/*
|
|
+ * cause a mmal component to be enabled
|
|
+ */
|
|
+int vchiq_mmal_component_disable(struct vchiq_mmal_instance *instance,
|
|
+ struct vchiq_mmal_component *component)
|
|
+{
|
|
+ int ret;
|
|
+
|
|
+ if (mutex_lock_interruptible(&instance->vchiq_mutex))
|
|
+ return -EINTR;
|
|
+
|
|
+ if (!component->enabled) {
|
|
+ mutex_unlock(&instance->vchiq_mutex);
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ ret = disable_component(instance, component);
|
|
+ if (ret == 0)
|
|
+ component->enabled = 0;
|
|
+
|
|
+ mutex_unlock(&instance->vchiq_mutex);
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+EXPORT_SYMBOL_GPL(vchiq_mmal_component_disable);
|
|
+
|
|
+int vchiq_mmal_version(struct vchiq_mmal_instance *instance,
|
|
+ u32 *major_out, u32 *minor_out)
|
|
+{
|
|
+ int ret;
|
|
+
|
|
+ if (mutex_lock_interruptible(&instance->vchiq_mutex))
|
|
+ return -EINTR;
|
|
+
|
|
+ ret = get_version(instance, major_out, minor_out);
|
|
+
|
|
+ mutex_unlock(&instance->vchiq_mutex);
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+EXPORT_SYMBOL_GPL(vchiq_mmal_version);
|
|
+
|
|
+int vchiq_mmal_finalise(struct vchiq_mmal_instance *instance)
|
|
+{
|
|
+ int status = 0;
|
|
+
|
|
+ if (!instance)
|
|
+ return -EINVAL;
|
|
+
|
|
+ if (mutex_lock_interruptible(&instance->vchiq_mutex))
|
|
+ return -EINTR;
|
|
+
|
|
+ vchi_service_use(instance->handle);
|
|
+
|
|
+ status = vchi_service_close(instance->handle);
|
|
+ if (status != 0)
|
|
+ pr_err("mmal-vchiq: VCHIQ close failed\n");
|
|
+
|
|
+ mutex_unlock(&instance->vchiq_mutex);
|
|
+
|
|
+ flush_workqueue(instance->bulk_wq);
|
|
+ destroy_workqueue(instance->bulk_wq);
|
|
+
|
|
+ vfree(instance->bulk_scratch);
|
|
+
|
|
+ idr_destroy(&instance->context_map);
|
|
+
|
|
+ kfree(instance);
|
|
+
|
|
+ return status;
|
|
+}
|
|
+EXPORT_SYMBOL_GPL(vchiq_mmal_finalise);
|
|
+
|
|
+int vchiq_mmal_init(struct vchiq_mmal_instance **out_instance)
|
|
+{
|
|
+ int status;
|
|
+ struct vchiq_mmal_instance *instance;
|
|
+ static VCHI_INSTANCE_T vchi_instance;
|
|
+ struct service_creation params = {
|
|
+ .version = VCHI_VERSION_EX(VC_MMAL_VER, VC_MMAL_MIN_VER),
|
|
+ .service_id = VC_MMAL_SERVER_NAME,
|
|
+ .callback = service_callback,
|
|
+ .callback_param = NULL,
|
|
+ };
|
|
+
|
|
+ /* compile time checks to ensure structure size as they are
|
|
+ * directly (de)serialised from memory.
|
|
+ */
|
|
+
|
|
+ /* ensure the header structure has packed to the correct size */
|
|
+ BUILD_BUG_ON(sizeof(struct mmal_msg_header) != 24);
|
|
+
|
|
+ /* ensure message structure does not exceed maximum length */
|
|
+ BUILD_BUG_ON(sizeof(struct mmal_msg) > MMAL_MSG_MAX_SIZE);
|
|
+
|
|
+ /* mmal port struct is correct size */
|
|
+ BUILD_BUG_ON(sizeof(struct mmal_port) != 64);
|
|
+
|
|
+ /* create a vchi instance */
|
|
+ status = vchi_initialise(&vchi_instance);
|
|
+ if (status) {
|
|
+ pr_err("Failed to initialise VCHI instance (status=%d)\n",
|
|
+ status);
|
|
+ return -EIO;
|
|
+ }
|
|
+
|
|
+ status = vchi_connect(vchi_instance);
|
|
+ if (status) {
|
|
+ pr_err("Failed to connect VCHI instance (status=%d)\n", status);
|
|
+ return -EIO;
|
|
+ }
|
|
+
|
|
+ instance = kzalloc(sizeof(*instance), GFP_KERNEL);
|
|
+
|
|
+ if (!instance)
|
|
+ return -ENOMEM;
|
|
+
|
|
+ mutex_init(&instance->vchiq_mutex);
|
|
+
|
|
+ instance->bulk_scratch = vmalloc(PAGE_SIZE);
|
|
+
|
|
+ mutex_init(&instance->context_map_lock);
|
|
+ idr_init_base(&instance->context_map, 1);
|
|
+
|
|
+ params.callback_param = instance;
|
|
+
|
|
+ instance->bulk_wq = alloc_ordered_workqueue("mmal-vchiq",
|
|
+ WQ_MEM_RECLAIM);
|
|
+ if (!instance->bulk_wq)
|
|
+ goto err_free;
|
|
+
|
|
+ status = vchi_service_open(vchi_instance, ¶ms, &instance->handle);
|
|
+ if (status) {
|
|
+ pr_err("Failed to open VCHI service connection (status=%d)\n",
|
|
+ status);
|
|
+ goto err_close_services;
|
|
+ }
|
|
+
|
|
+ vchi_service_release(instance->handle);
|
|
+
|
|
+ *out_instance = instance;
|
|
+
|
|
+ return 0;
|
|
+
|
|
+err_close_services:
|
|
+ vchi_service_close(instance->handle);
|
|
+ destroy_workqueue(instance->bulk_wq);
|
|
+err_free:
|
|
+ vfree(instance->bulk_scratch);
|
|
+ kfree(instance);
|
|
+ return -ENODEV;
|
|
+}
|
|
+EXPORT_SYMBOL_GPL(vchiq_mmal_init);
|
|
--- a/drivers/staging/vc04_services/bcm2835-camera/mmal-common.h
|
|
+++ /dev/null
|
|
@@ -1,60 +0,0 @@
|
|
-/* SPDX-License-Identifier: GPL-2.0 */
|
|
-/*
|
|
- * Broadcom BM2835 V4L2 driver
|
|
- *
|
|
- * Copyright © 2013 Raspberry Pi (Trading) Ltd.
|
|
- *
|
|
- * Authors: Vincent Sanders @ Collabora
|
|
- * Dave Stevenson @ Broadcom
|
|
- * (now dave.stevenson@raspberrypi.org)
|
|
- * Simon Mellor @ Broadcom
|
|
- * Luke Diamand @ Broadcom
|
|
- *
|
|
- * MMAL structures
|
|
- *
|
|
- */
|
|
-#ifndef MMAL_COMMON_H
|
|
-#define MMAL_COMMON_H
|
|
-
|
|
-#define MMAL_FOURCC(a, b, c, d) ((a) | (b << 8) | (c << 16) | (d << 24))
|
|
-#define MMAL_MAGIC MMAL_FOURCC('m', 'm', 'a', 'l')
|
|
-
|
|
-/** Special value signalling that time is not known */
|
|
-#define MMAL_TIME_UNKNOWN BIT_ULL(63)
|
|
-
|
|
-struct mmal_msg_context;
|
|
-
|
|
-/* mapping between v4l and mmal video modes */
|
|
-struct mmal_fmt {
|
|
- u32 fourcc; /* v4l2 format id */
|
|
- int flags; /* v4l2 flags field */
|
|
- u32 mmal;
|
|
- int depth;
|
|
- u32 mmal_component; /* MMAL component index to be used to encode */
|
|
- u32 ybbp; /* depth of first Y plane for planar formats */
|
|
- bool remove_padding; /* Does the GPU have to remove padding,
|
|
- * or can we do hide padding via bytesperline.
|
|
- */
|
|
-};
|
|
-
|
|
-/* buffer for one video frame */
|
|
-struct mmal_buffer {
|
|
- /* v4l buffer data -- must be first */
|
|
- struct vb2_v4l2_buffer vb;
|
|
-
|
|
- /* list of buffers available */
|
|
- struct list_head list;
|
|
-
|
|
- void *buffer; /* buffer pointer */
|
|
- unsigned long buffer_size; /* size of allocated buffer */
|
|
-
|
|
- struct mmal_msg_context *msg_context;
|
|
-};
|
|
-
|
|
-/* */
|
|
-struct mmal_colourfx {
|
|
- s32 enable;
|
|
- u32 u;
|
|
- u32 v;
|
|
-};
|
|
-#endif
|
|
--- a/drivers/staging/vc04_services/bcm2835-camera/mmal-encodings.h
|
|
+++ /dev/null
|
|
@@ -1,124 +0,0 @@
|
|
-/* SPDX-License-Identifier: GPL-2.0 */
|
|
-/*
|
|
- * Broadcom BM2835 V4L2 driver
|
|
- *
|
|
- * Copyright © 2013 Raspberry Pi (Trading) Ltd.
|
|
- *
|
|
- * Authors: Vincent Sanders @ Collabora
|
|
- * Dave Stevenson @ Broadcom
|
|
- * (now dave.stevenson@raspberrypi.org)
|
|
- * Simon Mellor @ Broadcom
|
|
- * Luke Diamand @ Broadcom
|
|
- */
|
|
-#ifndef MMAL_ENCODINGS_H
|
|
-#define MMAL_ENCODINGS_H
|
|
-
|
|
-#define MMAL_ENCODING_H264 MMAL_FOURCC('H', '2', '6', '4')
|
|
-#define MMAL_ENCODING_H263 MMAL_FOURCC('H', '2', '6', '3')
|
|
-#define MMAL_ENCODING_MP4V MMAL_FOURCC('M', 'P', '4', 'V')
|
|
-#define MMAL_ENCODING_MP2V MMAL_FOURCC('M', 'P', '2', 'V')
|
|
-#define MMAL_ENCODING_MP1V MMAL_FOURCC('M', 'P', '1', 'V')
|
|
-#define MMAL_ENCODING_WMV3 MMAL_FOURCC('W', 'M', 'V', '3')
|
|
-#define MMAL_ENCODING_WMV2 MMAL_FOURCC('W', 'M', 'V', '2')
|
|
-#define MMAL_ENCODING_WMV1 MMAL_FOURCC('W', 'M', 'V', '1')
|
|
-#define MMAL_ENCODING_WVC1 MMAL_FOURCC('W', 'V', 'C', '1')
|
|
-#define MMAL_ENCODING_VP8 MMAL_FOURCC('V', 'P', '8', ' ')
|
|
-#define MMAL_ENCODING_VP7 MMAL_FOURCC('V', 'P', '7', ' ')
|
|
-#define MMAL_ENCODING_VP6 MMAL_FOURCC('V', 'P', '6', ' ')
|
|
-#define MMAL_ENCODING_THEORA MMAL_FOURCC('T', 'H', 'E', 'O')
|
|
-#define MMAL_ENCODING_SPARK MMAL_FOURCC('S', 'P', 'R', 'K')
|
|
-#define MMAL_ENCODING_MJPEG MMAL_FOURCC('M', 'J', 'P', 'G')
|
|
-
|
|
-#define MMAL_ENCODING_JPEG MMAL_FOURCC('J', 'P', 'E', 'G')
|
|
-#define MMAL_ENCODING_GIF MMAL_FOURCC('G', 'I', 'F', ' ')
|
|
-#define MMAL_ENCODING_PNG MMAL_FOURCC('P', 'N', 'G', ' ')
|
|
-#define MMAL_ENCODING_PPM MMAL_FOURCC('P', 'P', 'M', ' ')
|
|
-#define MMAL_ENCODING_TGA MMAL_FOURCC('T', 'G', 'A', ' ')
|
|
-#define MMAL_ENCODING_BMP MMAL_FOURCC('B', 'M', 'P', ' ')
|
|
-
|
|
-#define MMAL_ENCODING_I420 MMAL_FOURCC('I', '4', '2', '0')
|
|
-#define MMAL_ENCODING_I420_SLICE MMAL_FOURCC('S', '4', '2', '0')
|
|
-#define MMAL_ENCODING_YV12 MMAL_FOURCC('Y', 'V', '1', '2')
|
|
-#define MMAL_ENCODING_I422 MMAL_FOURCC('I', '4', '2', '2')
|
|
-#define MMAL_ENCODING_I422_SLICE MMAL_FOURCC('S', '4', '2', '2')
|
|
-#define MMAL_ENCODING_YUYV MMAL_FOURCC('Y', 'U', 'Y', 'V')
|
|
-#define MMAL_ENCODING_YVYU MMAL_FOURCC('Y', 'V', 'Y', 'U')
|
|
-#define MMAL_ENCODING_UYVY MMAL_FOURCC('U', 'Y', 'V', 'Y')
|
|
-#define MMAL_ENCODING_VYUY MMAL_FOURCC('V', 'Y', 'U', 'Y')
|
|
-#define MMAL_ENCODING_NV12 MMAL_FOURCC('N', 'V', '1', '2')
|
|
-#define MMAL_ENCODING_NV21 MMAL_FOURCC('N', 'V', '2', '1')
|
|
-#define MMAL_ENCODING_ARGB MMAL_FOURCC('A', 'R', 'G', 'B')
|
|
-#define MMAL_ENCODING_RGBA MMAL_FOURCC('R', 'G', 'B', 'A')
|
|
-#define MMAL_ENCODING_ABGR MMAL_FOURCC('A', 'B', 'G', 'R')
|
|
-#define MMAL_ENCODING_BGRA MMAL_FOURCC('B', 'G', 'R', 'A')
|
|
-#define MMAL_ENCODING_RGB16 MMAL_FOURCC('R', 'G', 'B', '2')
|
|
-#define MMAL_ENCODING_RGB24 MMAL_FOURCC('R', 'G', 'B', '3')
|
|
-#define MMAL_ENCODING_RGB32 MMAL_FOURCC('R', 'G', 'B', '4')
|
|
-#define MMAL_ENCODING_BGR16 MMAL_FOURCC('B', 'G', 'R', '2')
|
|
-#define MMAL_ENCODING_BGR24 MMAL_FOURCC('B', 'G', 'R', '3')
|
|
-#define MMAL_ENCODING_BGR32 MMAL_FOURCC('B', 'G', 'R', '4')
|
|
-
|
|
-/** SAND Video (YUVUV128) format, native format understood by VideoCore.
|
|
- * This format is *not* opaque - if requested you will receive full frames
|
|
- * of YUV_UV video.
|
|
- */
|
|
-#define MMAL_ENCODING_YUVUV128 MMAL_FOURCC('S', 'A', 'N', 'D')
|
|
-
|
|
-/** VideoCore opaque image format, image handles are returned to
|
|
- * the host but not the actual image data.
|
|
- */
|
|
-#define MMAL_ENCODING_OPAQUE MMAL_FOURCC('O', 'P', 'Q', 'V')
|
|
-
|
|
-/** An EGL image handle
|
|
- */
|
|
-#define MMAL_ENCODING_EGL_IMAGE MMAL_FOURCC('E', 'G', 'L', 'I')
|
|
-
|
|
-/* }@ */
|
|
-
|
|
-/** \name Pre-defined audio encodings */
|
|
-/* @{ */
|
|
-#define MMAL_ENCODING_PCM_UNSIGNED_BE MMAL_FOURCC('P', 'C', 'M', 'U')
|
|
-#define MMAL_ENCODING_PCM_UNSIGNED_LE MMAL_FOURCC('p', 'c', 'm', 'u')
|
|
-#define MMAL_ENCODING_PCM_SIGNED_BE MMAL_FOURCC('P', 'C', 'M', 'S')
|
|
-#define MMAL_ENCODING_PCM_SIGNED_LE MMAL_FOURCC('p', 'c', 'm', 's')
|
|
-#define MMAL_ENCODING_PCM_FLOAT_BE MMAL_FOURCC('P', 'C', 'M', 'F')
|
|
-#define MMAL_ENCODING_PCM_FLOAT_LE MMAL_FOURCC('p', 'c', 'm', 'f')
|
|
-
|
|
-/* Pre-defined H264 encoding variants */
|
|
-
|
|
-/** ISO 14496-10 Annex B byte stream format */
|
|
-#define MMAL_ENCODING_VARIANT_H264_DEFAULT 0
|
|
-/** ISO 14496-15 AVC stream format */
|
|
-#define MMAL_ENCODING_VARIANT_H264_AVC1 MMAL_FOURCC('A', 'V', 'C', '1')
|
|
-/** Implicitly delineated NAL units without emulation prevention */
|
|
-#define MMAL_ENCODING_VARIANT_H264_RAW MMAL_FOURCC('R', 'A', 'W', ' ')
|
|
-
|
|
-/** \defgroup MmalColorSpace List of pre-defined video color spaces
|
|
- * This defines a list of common color spaces. This list isn't exhaustive and
|
|
- * is only provided as a convenience to avoid clients having to use FourCC
|
|
- * codes directly. However components are allowed to define and use their own
|
|
- * FourCC codes.
|
|
- */
|
|
-/* @{ */
|
|
-
|
|
-/** Unknown color space */
|
|
-#define MMAL_COLOR_SPACE_UNKNOWN 0
|
|
-/** ITU-R BT.601-5 [SDTV] */
|
|
-#define MMAL_COLOR_SPACE_ITUR_BT601 MMAL_FOURCC('Y', '6', '0', '1')
|
|
-/** ITU-R BT.709-3 [HDTV] */
|
|
-#define MMAL_COLOR_SPACE_ITUR_BT709 MMAL_FOURCC('Y', '7', '0', '9')
|
|
-/** JPEG JFIF */
|
|
-#define MMAL_COLOR_SPACE_JPEG_JFIF MMAL_FOURCC('Y', 'J', 'F', 'I')
|
|
-/** Title 47 Code of Federal Regulations (2003) 73.682 (a) (20) */
|
|
-#define MMAL_COLOR_SPACE_FCC MMAL_FOURCC('Y', 'F', 'C', 'C')
|
|
-/** Society of Motion Picture and Television Engineers 240M (1999) */
|
|
-#define MMAL_COLOR_SPACE_SMPTE240M MMAL_FOURCC('Y', '2', '4', '0')
|
|
-/** ITU-R BT.470-2 System M */
|
|
-#define MMAL_COLOR_SPACE_BT470_2_M MMAL_FOURCC('Y', '_', '_', 'M')
|
|
-/** ITU-R BT.470-2 System BG */
|
|
-#define MMAL_COLOR_SPACE_BT470_2_BG MMAL_FOURCC('Y', '_', 'B', 'G')
|
|
-/** JPEG JFIF, but with 16..255 luma */
|
|
-#define MMAL_COLOR_SPACE_JFIF_Y16_255 MMAL_FOURCC('Y', 'Y', '1', '6')
|
|
-/* @} MmalColorSpace List */
|
|
-
|
|
-#endif /* MMAL_ENCODINGS_H */
|
|
--- a/drivers/staging/vc04_services/bcm2835-camera/mmal-msg-common.h
|
|
+++ /dev/null
|
|
@@ -1,48 +0,0 @@
|
|
-/* SPDX-License-Identifier: GPL-2.0 */
|
|
-/*
|
|
- * Broadcom BM2835 V4L2 driver
|
|
- *
|
|
- * Copyright © 2013 Raspberry Pi (Trading) Ltd.
|
|
- *
|
|
- * Authors: Vincent Sanders @ Collabora
|
|
- * Dave Stevenson @ Broadcom
|
|
- * (now dave.stevenson@raspberrypi.org)
|
|
- * Simon Mellor @ Broadcom
|
|
- * Luke Diamand @ Broadcom
|
|
- */
|
|
-
|
|
-#ifndef MMAL_MSG_COMMON_H
|
|
-#define MMAL_MSG_COMMON_H
|
|
-
|
|
-enum mmal_msg_status {
|
|
- MMAL_MSG_STATUS_SUCCESS = 0, /**< Success */
|
|
- MMAL_MSG_STATUS_ENOMEM, /**< Out of memory */
|
|
- MMAL_MSG_STATUS_ENOSPC, /**< Out of resources other than memory */
|
|
- MMAL_MSG_STATUS_EINVAL, /**< Argument is invalid */
|
|
- MMAL_MSG_STATUS_ENOSYS, /**< Function not implemented */
|
|
- MMAL_MSG_STATUS_ENOENT, /**< No such file or directory */
|
|
- MMAL_MSG_STATUS_ENXIO, /**< No such device or address */
|
|
- MMAL_MSG_STATUS_EIO, /**< I/O error */
|
|
- MMAL_MSG_STATUS_ESPIPE, /**< Illegal seek */
|
|
- MMAL_MSG_STATUS_ECORRUPT, /**< Data is corrupt \attention */
|
|
- MMAL_MSG_STATUS_ENOTREADY, /**< Component is not ready */
|
|
- MMAL_MSG_STATUS_ECONFIG, /**< Component is not configured */
|
|
- MMAL_MSG_STATUS_EISCONN, /**< Port is already connected */
|
|
- MMAL_MSG_STATUS_ENOTCONN, /**< Port is disconnected */
|
|
- MMAL_MSG_STATUS_EAGAIN, /**< Resource temporarily unavailable. */
|
|
- MMAL_MSG_STATUS_EFAULT, /**< Bad address */
|
|
-};
|
|
-
|
|
-struct mmal_rect {
|
|
- s32 x; /**< x coordinate (from left) */
|
|
- s32 y; /**< y coordinate (from top) */
|
|
- s32 width; /**< width */
|
|
- s32 height; /**< height */
|
|
-};
|
|
-
|
|
-struct mmal_rational {
|
|
- s32 num; /**< Numerator */
|
|
- s32 den; /**< Denominator */
|
|
-};
|
|
-
|
|
-#endif /* MMAL_MSG_COMMON_H */
|
|
--- a/drivers/staging/vc04_services/bcm2835-camera/mmal-msg-format.h
|
|
+++ /dev/null
|
|
@@ -1,106 +0,0 @@
|
|
-/* SPDX-License-Identifier: GPL-2.0 */
|
|
-/*
|
|
- * Broadcom BM2835 V4L2 driver
|
|
- *
|
|
- * Copyright © 2013 Raspberry Pi (Trading) Ltd.
|
|
- *
|
|
- * Authors: Vincent Sanders @ Collabora
|
|
- * Dave Stevenson @ Broadcom
|
|
- * (now dave.stevenson@raspberrypi.org)
|
|
- * Simon Mellor @ Broadcom
|
|
- * Luke Diamand @ Broadcom
|
|
- */
|
|
-
|
|
-#ifndef MMAL_MSG_FORMAT_H
|
|
-#define MMAL_MSG_FORMAT_H
|
|
-
|
|
-#include "mmal-msg-common.h"
|
|
-
|
|
-/* MMAL_ES_FORMAT_T */
|
|
-
|
|
-struct mmal_audio_format {
|
|
- u32 channels; /* Number of audio channels */
|
|
- u32 sample_rate; /* Sample rate */
|
|
-
|
|
- u32 bits_per_sample; /* Bits per sample */
|
|
- u32 block_align; /* Size of a block of data */
|
|
-};
|
|
-
|
|
-struct mmal_video_format {
|
|
- u32 width; /* Width of frame in pixels */
|
|
- u32 height; /* Height of frame in rows of pixels */
|
|
- struct mmal_rect crop; /* Visible region of the frame */
|
|
- struct mmal_rational frame_rate; /* Frame rate */
|
|
- struct mmal_rational par; /* Pixel aspect ratio */
|
|
-
|
|
- /*
|
|
- * FourCC specifying the color space of the video stream. See the
|
|
- * MmalColorSpace "pre-defined color spaces" for some examples.
|
|
- */
|
|
- u32 color_space;
|
|
-};
|
|
-
|
|
-struct mmal_subpicture_format {
|
|
- u32 x_offset;
|
|
- u32 y_offset;
|
|
-};
|
|
-
|
|
-union mmal_es_specific_format {
|
|
- struct mmal_audio_format audio;
|
|
- struct mmal_video_format video;
|
|
- struct mmal_subpicture_format subpicture;
|
|
-};
|
|
-
|
|
-/* Definition of an elementary stream format (MMAL_ES_FORMAT_T) */
|
|
-struct mmal_es_format_local {
|
|
- u32 type; /* enum mmal_es_type */
|
|
-
|
|
- u32 encoding; /* FourCC specifying encoding of the elementary
|
|
- * stream.
|
|
- */
|
|
- u32 encoding_variant; /* FourCC specifying the specific
|
|
- * encoding variant of the elementary
|
|
- * stream.
|
|
- */
|
|
-
|
|
- union mmal_es_specific_format *es; /* Type specific
|
|
- * information for the
|
|
- * elementary stream
|
|
- */
|
|
-
|
|
- u32 bitrate; /* Bitrate in bits per second */
|
|
- u32 flags; /* Flags describing properties of the elementary
|
|
- * stream.
|
|
- */
|
|
-
|
|
- u32 extradata_size; /* Size of the codec specific data */
|
|
- u8 *extradata; /* Codec specific data */
|
|
-};
|
|
-
|
|
-/* Remote definition of an elementary stream format (MMAL_ES_FORMAT_T) */
|
|
-struct mmal_es_format {
|
|
- u32 type; /* enum mmal_es_type */
|
|
-
|
|
- u32 encoding; /* FourCC specifying encoding of the elementary
|
|
- * stream.
|
|
- */
|
|
- u32 encoding_variant; /* FourCC specifying the specific
|
|
- * encoding variant of the elementary
|
|
- * stream.
|
|
- */
|
|
-
|
|
- u32 es; /* Type specific
|
|
- * information for the
|
|
- * elementary stream
|
|
- */
|
|
-
|
|
- u32 bitrate; /* Bitrate in bits per second */
|
|
- u32 flags; /* Flags describing properties of the elementary
|
|
- * stream.
|
|
- */
|
|
-
|
|
- u32 extradata_size; /* Size of the codec specific data */
|
|
- u32 extradata; /* Codec specific data */
|
|
-};
|
|
-
|
|
-#endif /* MMAL_MSG_FORMAT_H */
|
|
--- a/drivers/staging/vc04_services/bcm2835-camera/mmal-msg-port.h
|
|
+++ /dev/null
|
|
@@ -1,109 +0,0 @@
|
|
-/* SPDX-License-Identifier: GPL-2.0 */
|
|
-/*
|
|
- * Broadcom BM2835 V4L2 driver
|
|
- *
|
|
- * Copyright © 2013 Raspberry Pi (Trading) Ltd.
|
|
- *
|
|
- * Authors: Vincent Sanders @ Collabora
|
|
- * Dave Stevenson @ Broadcom
|
|
- * (now dave.stevenson@raspberrypi.org)
|
|
- * Simon Mellor @ Broadcom
|
|
- * Luke Diamand @ Broadcom
|
|
- */
|
|
-
|
|
-/* MMAL_PORT_TYPE_T */
|
|
-enum mmal_port_type {
|
|
- MMAL_PORT_TYPE_UNKNOWN = 0, /* Unknown port type */
|
|
- MMAL_PORT_TYPE_CONTROL, /* Control port */
|
|
- MMAL_PORT_TYPE_INPUT, /* Input port */
|
|
- MMAL_PORT_TYPE_OUTPUT, /* Output port */
|
|
- MMAL_PORT_TYPE_CLOCK, /* Clock port */
|
|
-};
|
|
-
|
|
-/* The port is pass-through and doesn't need buffer headers allocated */
|
|
-#define MMAL_PORT_CAPABILITY_PASSTHROUGH 0x01
|
|
-/*
|
|
- *The port wants to allocate the buffer payloads.
|
|
- * This signals a preference that payload allocation should be done
|
|
- * on this port for efficiency reasons.
|
|
- */
|
|
-#define MMAL_PORT_CAPABILITY_ALLOCATION 0x02
|
|
-/*
|
|
- * The port supports format change events.
|
|
- * This applies to input ports and is used to let the client know
|
|
- * whether the port supports being reconfigured via a format
|
|
- * change event (i.e. without having to disable the port).
|
|
- */
|
|
-#define MMAL_PORT_CAPABILITY_SUPPORTS_EVENT_FORMAT_CHANGE 0x04
|
|
-
|
|
-/*
|
|
- * mmal port structure (MMAL_PORT_T)
|
|
- *
|
|
- * most elements are informational only, the pointer values for
|
|
- * interogation messages are generally provided as additional
|
|
- * structures within the message. When used to set values only the
|
|
- * buffer_num, buffer_size and userdata parameters are writable.
|
|
- */
|
|
-struct mmal_port {
|
|
- u32 priv; /* Private member used by the framework */
|
|
- u32 name; /* Port name. Used for debugging purposes (RO) */
|
|
-
|
|
- u32 type; /* Type of the port (RO) enum mmal_port_type */
|
|
- u16 index; /* Index of the port in its type list (RO) */
|
|
- u16 index_all; /* Index of the port in the list of all ports (RO) */
|
|
-
|
|
- u32 is_enabled; /* Indicates whether the port is enabled or not (RO) */
|
|
- u32 format; /* Format of the elementary stream */
|
|
-
|
|
- u32 buffer_num_min; /* Minimum number of buffers the port
|
|
- * requires (RO). This is set by the
|
|
- * component.
|
|
- */
|
|
-
|
|
- u32 buffer_size_min; /* Minimum size of buffers the port
|
|
- * requires (RO). This is set by the
|
|
- * component.
|
|
- */
|
|
-
|
|
- u32 buffer_alignment_min;/* Minimum alignment requirement for
|
|
- * the buffers (RO). A value of
|
|
- * zero means no special alignment
|
|
- * requirements. This is set by the
|
|
- * component.
|
|
- */
|
|
-
|
|
- u32 buffer_num_recommended; /* Number of buffers the port
|
|
- * recommends for optimal
|
|
- * performance (RO). A value of
|
|
- * zero means no special
|
|
- * recommendation. This is set
|
|
- * by the component.
|
|
- */
|
|
-
|
|
- u32 buffer_size_recommended; /* Size of buffers the port
|
|
- * recommends for optimal
|
|
- * performance (RO). A value of
|
|
- * zero means no special
|
|
- * recommendation. This is set
|
|
- * by the component.
|
|
- */
|
|
-
|
|
- u32 buffer_num; /* Actual number of buffers the port will use.
|
|
- * This is set by the client.
|
|
- */
|
|
-
|
|
- u32 buffer_size; /* Actual maximum size of the buffers that
|
|
- * will be sent to the port. This is set by
|
|
- * the client.
|
|
- */
|
|
-
|
|
- u32 component; /* Component this port belongs to (Read Only) */
|
|
-
|
|
- u32 userdata; /* Field reserved for use by the client */
|
|
-
|
|
- u32 capabilities; /* Flags describing the capabilities of a
|
|
- * port (RO). Bitwise combination of \ref
|
|
- * portcapabilities "Port capabilities"
|
|
- * values.
|
|
- */
|
|
-};
|
|
--- a/drivers/staging/vc04_services/bcm2835-camera/mmal-msg.h
|
|
+++ /dev/null
|
|
@@ -1,406 +0,0 @@
|
|
-/* SPDX-License-Identifier: GPL-2.0 */
|
|
-/*
|
|
- * Broadcom BM2835 V4L2 driver
|
|
- *
|
|
- * Copyright © 2013 Raspberry Pi (Trading) Ltd.
|
|
- *
|
|
- * Authors: Vincent Sanders @ Collabora
|
|
- * Dave Stevenson @ Broadcom
|
|
- * (now dave.stevenson@raspberrypi.org)
|
|
- * Simon Mellor @ Broadcom
|
|
- * Luke Diamand @ Broadcom
|
|
- */
|
|
-
|
|
-/*
|
|
- * all the data structures which serialise the MMAL protocol. note
|
|
- * these are directly mapped onto the recived message data.
|
|
- *
|
|
- * BEWARE: They seem to *assume* pointers are u32 and that there is no
|
|
- * structure padding!
|
|
- *
|
|
- * NOTE: this implementation uses kernel types to ensure sizes. Rather
|
|
- * than assigning values to enums to force their size the
|
|
- * implementation uses fixed size types and not the enums (though the
|
|
- * comments have the actual enum type
|
|
- */
|
|
-#ifndef MMAL_MSG_H
|
|
-#define MMAL_MSG_H
|
|
-
|
|
-#define VC_MMAL_VER 15
|
|
-#define VC_MMAL_MIN_VER 10
|
|
-#define VC_MMAL_SERVER_NAME MAKE_FOURCC("mmal")
|
|
-
|
|
-/* max total message size is 512 bytes */
|
|
-#define MMAL_MSG_MAX_SIZE 512
|
|
-/* with six 32bit header elements max payload is therefore 488 bytes */
|
|
-#define MMAL_MSG_MAX_PAYLOAD 488
|
|
-
|
|
-#include "mmal-msg-common.h"
|
|
-#include "mmal-msg-format.h"
|
|
-#include "mmal-msg-port.h"
|
|
-
|
|
-enum mmal_msg_type {
|
|
- MMAL_MSG_TYPE_QUIT = 1,
|
|
- MMAL_MSG_TYPE_SERVICE_CLOSED,
|
|
- MMAL_MSG_TYPE_GET_VERSION,
|
|
- MMAL_MSG_TYPE_COMPONENT_CREATE,
|
|
- MMAL_MSG_TYPE_COMPONENT_DESTROY, /* 5 */
|
|
- MMAL_MSG_TYPE_COMPONENT_ENABLE,
|
|
- MMAL_MSG_TYPE_COMPONENT_DISABLE,
|
|
- MMAL_MSG_TYPE_PORT_INFO_GET,
|
|
- MMAL_MSG_TYPE_PORT_INFO_SET,
|
|
- MMAL_MSG_TYPE_PORT_ACTION, /* 10 */
|
|
- MMAL_MSG_TYPE_BUFFER_FROM_HOST,
|
|
- MMAL_MSG_TYPE_BUFFER_TO_HOST,
|
|
- MMAL_MSG_TYPE_GET_STATS,
|
|
- MMAL_MSG_TYPE_PORT_PARAMETER_SET,
|
|
- MMAL_MSG_TYPE_PORT_PARAMETER_GET, /* 15 */
|
|
- MMAL_MSG_TYPE_EVENT_TO_HOST,
|
|
- MMAL_MSG_TYPE_GET_CORE_STATS_FOR_PORT,
|
|
- MMAL_MSG_TYPE_OPAQUE_ALLOCATOR,
|
|
- MMAL_MSG_TYPE_CONSUME_MEM,
|
|
- MMAL_MSG_TYPE_LMK, /* 20 */
|
|
- MMAL_MSG_TYPE_OPAQUE_ALLOCATOR_DESC,
|
|
- MMAL_MSG_TYPE_DRM_GET_LHS32,
|
|
- MMAL_MSG_TYPE_DRM_GET_TIME,
|
|
- MMAL_MSG_TYPE_BUFFER_FROM_HOST_ZEROLEN,
|
|
- MMAL_MSG_TYPE_PORT_FLUSH, /* 25 */
|
|
- MMAL_MSG_TYPE_HOST_LOG,
|
|
- MMAL_MSG_TYPE_MSG_LAST
|
|
-};
|
|
-
|
|
-/* port action request messages differ depending on the action type */
|
|
-enum mmal_msg_port_action_type {
|
|
- MMAL_MSG_PORT_ACTION_TYPE_UNKNOWN = 0, /* Unknown action */
|
|
- MMAL_MSG_PORT_ACTION_TYPE_ENABLE, /* Enable a port */
|
|
- MMAL_MSG_PORT_ACTION_TYPE_DISABLE, /* Disable a port */
|
|
- MMAL_MSG_PORT_ACTION_TYPE_FLUSH, /* Flush a port */
|
|
- MMAL_MSG_PORT_ACTION_TYPE_CONNECT, /* Connect ports */
|
|
- MMAL_MSG_PORT_ACTION_TYPE_DISCONNECT, /* Disconnect ports */
|
|
- MMAL_MSG_PORT_ACTION_TYPE_SET_REQUIREMENTS, /* Set buffer requirements*/
|
|
-};
|
|
-
|
|
-struct mmal_msg_header {
|
|
- u32 magic;
|
|
- u32 type; /* enum mmal_msg_type */
|
|
-
|
|
- /* Opaque handle to the control service */
|
|
- u32 control_service;
|
|
-
|
|
- u32 context; /* a u32 per message context */
|
|
- u32 status; /* The status of the vchiq operation */
|
|
- u32 padding;
|
|
-};
|
|
-
|
|
-/* Send from VC to host to report version */
|
|
-struct mmal_msg_version {
|
|
- u32 flags;
|
|
- u32 major;
|
|
- u32 minor;
|
|
- u32 minimum;
|
|
-};
|
|
-
|
|
-/* request to VC to create component */
|
|
-struct mmal_msg_component_create {
|
|
- u32 client_component; /* component context */
|
|
- char name[128];
|
|
- u32 pid; /* For debug */
|
|
-};
|
|
-
|
|
-/* reply from VC to component creation request */
|
|
-struct mmal_msg_component_create_reply {
|
|
- u32 status; /* enum mmal_msg_status - how does this differ to
|
|
- * the one in the header?
|
|
- */
|
|
- u32 component_handle; /* VideoCore handle for component */
|
|
- u32 input_num; /* Number of input ports */
|
|
- u32 output_num; /* Number of output ports */
|
|
- u32 clock_num; /* Number of clock ports */
|
|
-};
|
|
-
|
|
-/* request to VC to destroy a component */
|
|
-struct mmal_msg_component_destroy {
|
|
- u32 component_handle;
|
|
-};
|
|
-
|
|
-struct mmal_msg_component_destroy_reply {
|
|
- u32 status; /* The component destruction status */
|
|
-};
|
|
-
|
|
-/* request and reply to VC to enable a component */
|
|
-struct mmal_msg_component_enable {
|
|
- u32 component_handle;
|
|
-};
|
|
-
|
|
-struct mmal_msg_component_enable_reply {
|
|
- u32 status; /* The component enable status */
|
|
-};
|
|
-
|
|
-/* request and reply to VC to disable a component */
|
|
-struct mmal_msg_component_disable {
|
|
- u32 component_handle;
|
|
-};
|
|
-
|
|
-struct mmal_msg_component_disable_reply {
|
|
- u32 status; /* The component disable status */
|
|
-};
|
|
-
|
|
-/* request to VC to get port information */
|
|
-struct mmal_msg_port_info_get {
|
|
- u32 component_handle; /* component handle port is associated with */
|
|
- u32 port_type; /* enum mmal_msg_port_type */
|
|
- u32 index; /* port index to query */
|
|
-};
|
|
-
|
|
-/* reply from VC to get port info request */
|
|
-struct mmal_msg_port_info_get_reply {
|
|
- u32 status; /* enum mmal_msg_status */
|
|
- u32 component_handle; /* component handle port is associated with */
|
|
- u32 port_type; /* enum mmal_msg_port_type */
|
|
- u32 port_index; /* port indexed in query */
|
|
- s32 found; /* unused */
|
|
- u32 port_handle; /* Handle to use for this port */
|
|
- struct mmal_port port;
|
|
- struct mmal_es_format format; /* elementary stream format */
|
|
- union mmal_es_specific_format es; /* es type specific data */
|
|
- u8 extradata[MMAL_FORMAT_EXTRADATA_MAX_SIZE]; /* es extra data */
|
|
-};
|
|
-
|
|
-/* request to VC to set port information */
|
|
-struct mmal_msg_port_info_set {
|
|
- u32 component_handle;
|
|
- u32 port_type; /* enum mmal_msg_port_type */
|
|
- u32 port_index; /* port indexed in query */
|
|
- struct mmal_port port;
|
|
- struct mmal_es_format format;
|
|
- union mmal_es_specific_format es;
|
|
- u8 extradata[MMAL_FORMAT_EXTRADATA_MAX_SIZE];
|
|
-};
|
|
-
|
|
-/* reply from VC to port info set request */
|
|
-struct mmal_msg_port_info_set_reply {
|
|
- u32 status;
|
|
- u32 component_handle; /* component handle port is associated with */
|
|
- u32 port_type; /* enum mmal_msg_port_type */
|
|
- u32 index; /* port indexed in query */
|
|
- s32 found; /* unused */
|
|
- u32 port_handle; /* Handle to use for this port */
|
|
- struct mmal_port port;
|
|
- struct mmal_es_format format;
|
|
- union mmal_es_specific_format es;
|
|
- u8 extradata[MMAL_FORMAT_EXTRADATA_MAX_SIZE];
|
|
-};
|
|
-
|
|
-/* port action requests that take a mmal_port as a parameter */
|
|
-struct mmal_msg_port_action_port {
|
|
- u32 component_handle;
|
|
- u32 port_handle;
|
|
- u32 action; /* enum mmal_msg_port_action_type */
|
|
- struct mmal_port port;
|
|
-};
|
|
-
|
|
-/* port action requests that take handles as a parameter */
|
|
-struct mmal_msg_port_action_handle {
|
|
- u32 component_handle;
|
|
- u32 port_handle;
|
|
- u32 action; /* enum mmal_msg_port_action_type */
|
|
- u32 connect_component_handle;
|
|
- u32 connect_port_handle;
|
|
-};
|
|
-
|
|
-struct mmal_msg_port_action_reply {
|
|
- u32 status; /* The port action operation status */
|
|
-};
|
|
-
|
|
-/* MMAL buffer transfer */
|
|
-
|
|
-/* Size of space reserved in a buffer message for short messages. */
|
|
-#define MMAL_VC_SHORT_DATA 128
|
|
-
|
|
-/* Signals that the current payload is the end of the stream of data */
|
|
-#define MMAL_BUFFER_HEADER_FLAG_EOS BIT(0)
|
|
-/* Signals that the start of the current payload starts a frame */
|
|
-#define MMAL_BUFFER_HEADER_FLAG_FRAME_START BIT(1)
|
|
-/* Signals that the end of the current payload ends a frame */
|
|
-#define MMAL_BUFFER_HEADER_FLAG_FRAME_END BIT(2)
|
|
-/* Signals that the current payload contains only complete frames (>1) */
|
|
-#define MMAL_BUFFER_HEADER_FLAG_FRAME \
|
|
- (MMAL_BUFFER_HEADER_FLAG_FRAME_START | \
|
|
- MMAL_BUFFER_HEADER_FLAG_FRAME_END)
|
|
-/* Signals that the current payload is a keyframe (i.e. self decodable) */
|
|
-#define MMAL_BUFFER_HEADER_FLAG_KEYFRAME BIT(3)
|
|
-/*
|
|
- * Signals a discontinuity in the stream of data (e.g. after a seek).
|
|
- * Can be used for instance by a decoder to reset its state
|
|
- */
|
|
-#define MMAL_BUFFER_HEADER_FLAG_DISCONTINUITY BIT(4)
|
|
-/*
|
|
- * Signals a buffer containing some kind of config data for the component
|
|
- * (e.g. codec config data)
|
|
- */
|
|
-#define MMAL_BUFFER_HEADER_FLAG_CONFIG BIT(5)
|
|
-/* Signals an encrypted payload */
|
|
-#define MMAL_BUFFER_HEADER_FLAG_ENCRYPTED BIT(6)
|
|
-/* Signals a buffer containing side information */
|
|
-#define MMAL_BUFFER_HEADER_FLAG_CODECSIDEINFO BIT(7)
|
|
-/*
|
|
- * Signals a buffer which is the snapshot/postview image from a stills
|
|
- * capture
|
|
- */
|
|
-#define MMAL_BUFFER_HEADER_FLAGS_SNAPSHOT BIT(8)
|
|
-/* Signals a buffer which contains data known to be corrupted */
|
|
-#define MMAL_BUFFER_HEADER_FLAG_CORRUPTED BIT(9)
|
|
-/* Signals that a buffer failed to be transmitted */
|
|
-#define MMAL_BUFFER_HEADER_FLAG_TRANSMISSION_FAILED BIT(10)
|
|
-
|
|
-struct mmal_driver_buffer {
|
|
- u32 magic;
|
|
- u32 component_handle;
|
|
- u32 port_handle;
|
|
- u32 client_context;
|
|
-};
|
|
-
|
|
-/* buffer header */
|
|
-struct mmal_buffer_header {
|
|
- u32 next; /* next header */
|
|
- u32 priv; /* framework private data */
|
|
- u32 cmd;
|
|
- u32 data;
|
|
- u32 alloc_size;
|
|
- u32 length;
|
|
- u32 offset;
|
|
- u32 flags;
|
|
- s64 pts;
|
|
- s64 dts;
|
|
- u32 type;
|
|
- u32 user_data;
|
|
-};
|
|
-
|
|
-struct mmal_buffer_header_type_specific {
|
|
- union {
|
|
- struct {
|
|
- u32 planes;
|
|
- u32 offset[4];
|
|
- u32 pitch[4];
|
|
- u32 flags;
|
|
- } video;
|
|
- } u;
|
|
-};
|
|
-
|
|
-struct mmal_msg_buffer_from_host {
|
|
- /*
|
|
- *The front 32 bytes of the buffer header are copied
|
|
- * back to us in the reply to allow for context. This
|
|
- * area is used to store two mmal_driver_buffer structures to
|
|
- * allow for multiple concurrent service users.
|
|
- */
|
|
- /* control data */
|
|
- struct mmal_driver_buffer drvbuf;
|
|
-
|
|
- /* referenced control data for passthrough buffer management */
|
|
- struct mmal_driver_buffer drvbuf_ref;
|
|
- struct mmal_buffer_header buffer_header; /* buffer header itself */
|
|
- struct mmal_buffer_header_type_specific buffer_header_type_specific;
|
|
- s32 is_zero_copy;
|
|
- s32 has_reference;
|
|
-
|
|
- /* allows short data to be xfered in control message */
|
|
- u32 payload_in_message;
|
|
- u8 short_data[MMAL_VC_SHORT_DATA];
|
|
-};
|
|
-
|
|
-/* port parameter setting */
|
|
-
|
|
-#define MMAL_WORKER_PORT_PARAMETER_SPACE 96
|
|
-
|
|
-struct mmal_msg_port_parameter_set {
|
|
- u32 component_handle; /* component */
|
|
- u32 port_handle; /* port */
|
|
- u32 id; /* Parameter ID */
|
|
- u32 size; /* Parameter size */
|
|
- u32 value[MMAL_WORKER_PORT_PARAMETER_SPACE];
|
|
-};
|
|
-
|
|
-struct mmal_msg_port_parameter_set_reply {
|
|
- u32 status; /* enum mmal_msg_status todo: how does this
|
|
- * differ to the one in the header?
|
|
- */
|
|
-};
|
|
-
|
|
-/* port parameter getting */
|
|
-
|
|
-struct mmal_msg_port_parameter_get {
|
|
- u32 component_handle; /* component */
|
|
- u32 port_handle; /* port */
|
|
- u32 id; /* Parameter ID */
|
|
- u32 size; /* Parameter size */
|
|
-};
|
|
-
|
|
-struct mmal_msg_port_parameter_get_reply {
|
|
- u32 status; /* Status of mmal_port_parameter_get call */
|
|
- u32 id; /* Parameter ID */
|
|
- u32 size; /* Parameter size */
|
|
- u32 value[MMAL_WORKER_PORT_PARAMETER_SPACE];
|
|
-};
|
|
-
|
|
-/* event messages */
|
|
-#define MMAL_WORKER_EVENT_SPACE 256
|
|
-
|
|
-struct mmal_msg_event_to_host {
|
|
- u32 client_component; /* component context */
|
|
-
|
|
- u32 port_type;
|
|
- u32 port_num;
|
|
-
|
|
- u32 cmd;
|
|
- u32 length;
|
|
- u8 data[MMAL_WORKER_EVENT_SPACE];
|
|
- u32 delayed_buffer;
|
|
-};
|
|
-
|
|
-/* all mmal messages are serialised through this structure */
|
|
-struct mmal_msg {
|
|
- /* header */
|
|
- struct mmal_msg_header h;
|
|
- /* payload */
|
|
- union {
|
|
- struct mmal_msg_version version;
|
|
-
|
|
- struct mmal_msg_component_create component_create;
|
|
- struct mmal_msg_component_create_reply component_create_reply;
|
|
-
|
|
- struct mmal_msg_component_destroy component_destroy;
|
|
- struct mmal_msg_component_destroy_reply component_destroy_reply;
|
|
-
|
|
- struct mmal_msg_component_enable component_enable;
|
|
- struct mmal_msg_component_enable_reply component_enable_reply;
|
|
-
|
|
- struct mmal_msg_component_disable component_disable;
|
|
- struct mmal_msg_component_disable_reply component_disable_reply;
|
|
-
|
|
- struct mmal_msg_port_info_get port_info_get;
|
|
- struct mmal_msg_port_info_get_reply port_info_get_reply;
|
|
-
|
|
- struct mmal_msg_port_info_set port_info_set;
|
|
- struct mmal_msg_port_info_set_reply port_info_set_reply;
|
|
-
|
|
- struct mmal_msg_port_action_port port_action_port;
|
|
- struct mmal_msg_port_action_handle port_action_handle;
|
|
- struct mmal_msg_port_action_reply port_action_reply;
|
|
-
|
|
- struct mmal_msg_buffer_from_host buffer_from_host;
|
|
-
|
|
- struct mmal_msg_port_parameter_set port_parameter_set;
|
|
- struct mmal_msg_port_parameter_set_reply
|
|
- port_parameter_set_reply;
|
|
- struct mmal_msg_port_parameter_get
|
|
- port_parameter_get;
|
|
- struct mmal_msg_port_parameter_get_reply
|
|
- port_parameter_get_reply;
|
|
-
|
|
- struct mmal_msg_event_to_host event_to_host;
|
|
-
|
|
- u8 payload[MMAL_MSG_MAX_PAYLOAD];
|
|
- } u;
|
|
-};
|
|
-#endif
|
|
--- a/drivers/staging/vc04_services/bcm2835-camera/mmal-parameters.h
|
|
+++ /dev/null
|
|
@@ -1,755 +0,0 @@
|
|
-/* SPDX-License-Identifier: GPL-2.0 */
|
|
-/*
|
|
- * Broadcom BM2835 V4L2 driver
|
|
- *
|
|
- * Copyright © 2013 Raspberry Pi (Trading) Ltd.
|
|
- *
|
|
- * Authors: Vincent Sanders @ Collabora
|
|
- * Dave Stevenson @ Broadcom
|
|
- * (now dave.stevenson@raspberrypi.org)
|
|
- * Simon Mellor @ Broadcom
|
|
- * Luke Diamand @ Broadcom
|
|
- */
|
|
-
|
|
-/* common parameters */
|
|
-
|
|
-/** @name Parameter groups
|
|
- * Parameters are divided into groups, and then allocated sequentially within
|
|
- * a group using an enum.
|
|
- * @{
|
|
- */
|
|
-
|
|
-#ifndef MMAL_PARAMETERS_H
|
|
-#define MMAL_PARAMETERS_H
|
|
-
|
|
-/** Common parameter ID group, used with many types of component. */
|
|
-#define MMAL_PARAMETER_GROUP_COMMON (0 << 16)
|
|
-/** Camera-specific parameter ID group. */
|
|
-#define MMAL_PARAMETER_GROUP_CAMERA (1 << 16)
|
|
-/** Video-specific parameter ID group. */
|
|
-#define MMAL_PARAMETER_GROUP_VIDEO (2 << 16)
|
|
-/** Audio-specific parameter ID group. */
|
|
-#define MMAL_PARAMETER_GROUP_AUDIO (3 << 16)
|
|
-/** Clock-specific parameter ID group. */
|
|
-#define MMAL_PARAMETER_GROUP_CLOCK (4 << 16)
|
|
-/** Miracast-specific parameter ID group. */
|
|
-#define MMAL_PARAMETER_GROUP_MIRACAST (5 << 16)
|
|
-
|
|
-/* Common parameters */
|
|
-enum mmal_parameter_common_type {
|
|
- /**< Never a valid parameter ID */
|
|
- MMAL_PARAMETER_UNUSED = MMAL_PARAMETER_GROUP_COMMON,
|
|
-
|
|
- /**< MMAL_PARAMETER_ENCODING_T */
|
|
- MMAL_PARAMETER_SUPPORTED_ENCODINGS,
|
|
- /**< MMAL_PARAMETER_URI_T */
|
|
- MMAL_PARAMETER_URI,
|
|
- /** MMAL_PARAMETER_CHANGE_EVENT_REQUEST_T */
|
|
- MMAL_PARAMETER_CHANGE_EVENT_REQUEST,
|
|
- /** MMAL_PARAMETER_BOOLEAN_T */
|
|
- MMAL_PARAMETER_ZERO_COPY,
|
|
- /**< MMAL_PARAMETER_BUFFER_REQUIREMENTS_T */
|
|
- MMAL_PARAMETER_BUFFER_REQUIREMENTS,
|
|
- /**< MMAL_PARAMETER_STATISTICS_T */
|
|
- MMAL_PARAMETER_STATISTICS,
|
|
- /**< MMAL_PARAMETER_CORE_STATISTICS_T */
|
|
- MMAL_PARAMETER_CORE_STATISTICS,
|
|
- /**< MMAL_PARAMETER_MEM_USAGE_T */
|
|
- MMAL_PARAMETER_MEM_USAGE,
|
|
- /**< MMAL_PARAMETER_UINT32_T */
|
|
- MMAL_PARAMETER_BUFFER_FLAG_FILTER,
|
|
- /**< MMAL_PARAMETER_SEEK_T */
|
|
- MMAL_PARAMETER_SEEK,
|
|
- /**< MMAL_PARAMETER_BOOLEAN_T */
|
|
- MMAL_PARAMETER_POWERMON_ENABLE,
|
|
- /**< MMAL_PARAMETER_LOGGING_T */
|
|
- MMAL_PARAMETER_LOGGING,
|
|
- /**< MMAL_PARAMETER_UINT64_T */
|
|
- MMAL_PARAMETER_SYSTEM_TIME,
|
|
- /**< MMAL_PARAMETER_BOOLEAN_T */
|
|
- MMAL_PARAMETER_NO_IMAGE_PADDING,
|
|
-};
|
|
-
|
|
-/* camera parameters */
|
|
-
|
|
-enum mmal_parameter_camera_type {
|
|
- /* 0 */
|
|
- /** @ref MMAL_PARAMETER_THUMBNAIL_CONFIG_T */
|
|
- MMAL_PARAMETER_THUMBNAIL_CONFIGURATION =
|
|
- MMAL_PARAMETER_GROUP_CAMERA,
|
|
- /**< Unused? */
|
|
- MMAL_PARAMETER_CAPTURE_QUALITY,
|
|
- /**< @ref MMAL_PARAMETER_INT32_T */
|
|
- MMAL_PARAMETER_ROTATION,
|
|
- /**< @ref MMAL_PARAMETER_BOOLEAN_T */
|
|
- MMAL_PARAMETER_EXIF_DISABLE,
|
|
- /**< @ref MMAL_PARAMETER_EXIF_T */
|
|
- MMAL_PARAMETER_EXIF,
|
|
- /**< @ref MMAL_PARAM_AWBMODE_T */
|
|
- MMAL_PARAMETER_AWB_MODE,
|
|
- /**< @ref MMAL_PARAMETER_IMAGEFX_T */
|
|
- MMAL_PARAMETER_IMAGE_EFFECT,
|
|
- /**< @ref MMAL_PARAMETER_COLOURFX_T */
|
|
- MMAL_PARAMETER_COLOUR_EFFECT,
|
|
- /**< @ref MMAL_PARAMETER_FLICKERAVOID_T */
|
|
- MMAL_PARAMETER_FLICKER_AVOID,
|
|
- /**< @ref MMAL_PARAMETER_FLASH_T */
|
|
- MMAL_PARAMETER_FLASH,
|
|
- /**< @ref MMAL_PARAMETER_REDEYE_T */
|
|
- MMAL_PARAMETER_REDEYE,
|
|
- /**< @ref MMAL_PARAMETER_FOCUS_T */
|
|
- MMAL_PARAMETER_FOCUS,
|
|
- /**< Unused? */
|
|
- MMAL_PARAMETER_FOCAL_LENGTHS,
|
|
- /**< @ref MMAL_PARAMETER_INT32_T */
|
|
- MMAL_PARAMETER_EXPOSURE_COMP,
|
|
- /**< @ref MMAL_PARAMETER_SCALEFACTOR_T */
|
|
- MMAL_PARAMETER_ZOOM,
|
|
- /**< @ref MMAL_PARAMETER_MIRROR_T */
|
|
- MMAL_PARAMETER_MIRROR,
|
|
-
|
|
- /* 0x10 */
|
|
- /**< @ref MMAL_PARAMETER_UINT32_T */
|
|
- MMAL_PARAMETER_CAMERA_NUM,
|
|
- /**< @ref MMAL_PARAMETER_BOOLEAN_T */
|
|
- MMAL_PARAMETER_CAPTURE,
|
|
- /**< @ref MMAL_PARAMETER_EXPOSUREMODE_T */
|
|
- MMAL_PARAMETER_EXPOSURE_MODE,
|
|
- /**< @ref MMAL_PARAMETER_EXPOSUREMETERINGMODE_T */
|
|
- MMAL_PARAMETER_EXP_METERING_MODE,
|
|
- /**< @ref MMAL_PARAMETER_FOCUS_STATUS_T */
|
|
- MMAL_PARAMETER_FOCUS_STATUS,
|
|
- /**< @ref MMAL_PARAMETER_CAMERA_CONFIG_T */
|
|
- MMAL_PARAMETER_CAMERA_CONFIG,
|
|
- /**< @ref MMAL_PARAMETER_CAPTURE_STATUS_T */
|
|
- MMAL_PARAMETER_CAPTURE_STATUS,
|
|
- /**< @ref MMAL_PARAMETER_FACE_TRACK_T */
|
|
- MMAL_PARAMETER_FACE_TRACK,
|
|
- /**< @ref MMAL_PARAMETER_BOOLEAN_T */
|
|
- MMAL_PARAMETER_DRAW_BOX_FACES_AND_FOCUS,
|
|
- /**< @ref MMAL_PARAMETER_UINT32_T */
|
|
- MMAL_PARAMETER_JPEG_Q_FACTOR,
|
|
- /**< @ref MMAL_PARAMETER_FRAME_RATE_T */
|
|
- MMAL_PARAMETER_FRAME_RATE,
|
|
- /**< @ref MMAL_PARAMETER_CAMERA_STC_MODE_T */
|
|
- MMAL_PARAMETER_USE_STC,
|
|
- /**< @ref MMAL_PARAMETER_CAMERA_INFO_T */
|
|
- MMAL_PARAMETER_CAMERA_INFO,
|
|
- /**< @ref MMAL_PARAMETER_BOOLEAN_T */
|
|
- MMAL_PARAMETER_VIDEO_STABILISATION,
|
|
- /**< @ref MMAL_PARAMETER_FACE_TRACK_RESULTS_T */
|
|
- MMAL_PARAMETER_FACE_TRACK_RESULTS,
|
|
- /**< @ref MMAL_PARAMETER_BOOLEAN_T */
|
|
- MMAL_PARAMETER_ENABLE_RAW_CAPTURE,
|
|
-
|
|
- /* 0x20 */
|
|
- /**< @ref MMAL_PARAMETER_URI_T */
|
|
- MMAL_PARAMETER_DPF_FILE,
|
|
- /**< @ref MMAL_PARAMETER_BOOLEAN_T */
|
|
- MMAL_PARAMETER_ENABLE_DPF_FILE,
|
|
- /**< @ref MMAL_PARAMETER_BOOLEAN_T */
|
|
- MMAL_PARAMETER_DPF_FAIL_IS_FATAL,
|
|
- /**< @ref MMAL_PARAMETER_CAPTUREMODE_T */
|
|
- MMAL_PARAMETER_CAPTURE_MODE,
|
|
- /**< @ref MMAL_PARAMETER_FOCUS_REGIONS_T */
|
|
- MMAL_PARAMETER_FOCUS_REGIONS,
|
|
- /**< @ref MMAL_PARAMETER_INPUT_CROP_T */
|
|
- MMAL_PARAMETER_INPUT_CROP,
|
|
- /**< @ref MMAL_PARAMETER_SENSOR_INFORMATION_T */
|
|
- MMAL_PARAMETER_SENSOR_INFORMATION,
|
|
- /**< @ref MMAL_PARAMETER_FLASH_SELECT_T */
|
|
- MMAL_PARAMETER_FLASH_SELECT,
|
|
- /**< @ref MMAL_PARAMETER_FIELD_OF_VIEW_T */
|
|
- MMAL_PARAMETER_FIELD_OF_VIEW,
|
|
- /**< @ref MMAL_PARAMETER_BOOLEAN_T */
|
|
- MMAL_PARAMETER_HIGH_DYNAMIC_RANGE,
|
|
- /**< @ref MMAL_PARAMETER_DRC_T */
|
|
- MMAL_PARAMETER_DYNAMIC_RANGE_COMPRESSION,
|
|
- /**< @ref MMAL_PARAMETER_ALGORITHM_CONTROL_T */
|
|
- MMAL_PARAMETER_ALGORITHM_CONTROL,
|
|
- /**< @ref MMAL_PARAMETER_RATIONAL_T */
|
|
- MMAL_PARAMETER_SHARPNESS,
|
|
- /**< @ref MMAL_PARAMETER_RATIONAL_T */
|
|
- MMAL_PARAMETER_CONTRAST,
|
|
- /**< @ref MMAL_PARAMETER_RATIONAL_T */
|
|
- MMAL_PARAMETER_BRIGHTNESS,
|
|
- /**< @ref MMAL_PARAMETER_RATIONAL_T */
|
|
- MMAL_PARAMETER_SATURATION,
|
|
-
|
|
- /* 0x30 */
|
|
- /**< @ref MMAL_PARAMETER_UINT32_T */
|
|
- MMAL_PARAMETER_ISO,
|
|
- /**< @ref MMAL_PARAMETER_BOOLEAN_T */
|
|
- MMAL_PARAMETER_ANTISHAKE,
|
|
- /** @ref MMAL_PARAMETER_IMAGEFX_PARAMETERS_T */
|
|
- MMAL_PARAMETER_IMAGE_EFFECT_PARAMETERS,
|
|
- /** @ref MMAL_PARAMETER_BOOLEAN_T */
|
|
- MMAL_PARAMETER_CAMERA_BURST_CAPTURE,
|
|
- /** @ref MMAL_PARAMETER_UINT32_T */
|
|
- MMAL_PARAMETER_CAMERA_MIN_ISO,
|
|
- /** @ref MMAL_PARAMETER_CAMERA_USE_CASE_T */
|
|
- MMAL_PARAMETER_CAMERA_USE_CASE,
|
|
- /**< @ref MMAL_PARAMETER_BOOLEAN_T */
|
|
- MMAL_PARAMETER_CAPTURE_STATS_PASS,
|
|
- /** @ref MMAL_PARAMETER_UINT32_T */
|
|
- MMAL_PARAMETER_CAMERA_CUSTOM_SENSOR_CONFIG,
|
|
- /** @ref MMAL_PARAMETER_BOOLEAN_T */
|
|
- MMAL_PARAMETER_ENABLE_REGISTER_FILE,
|
|
- /** @ref MMAL_PARAMETER_BOOLEAN_T */
|
|
- MMAL_PARAMETER_REGISTER_FAIL_IS_FATAL,
|
|
- /** @ref MMAL_PARAMETER_CONFIGFILE_T */
|
|
- MMAL_PARAMETER_CONFIGFILE_REGISTERS,
|
|
- /** @ref MMAL_PARAMETER_CONFIGFILE_CHUNK_T */
|
|
- MMAL_PARAMETER_CONFIGFILE_CHUNK_REGISTERS,
|
|
- /**< @ref MMAL_PARAMETER_BOOLEAN_T */
|
|
- MMAL_PARAMETER_JPEG_ATTACH_LOG,
|
|
- /**< @ref MMAL_PARAMETER_ZEROSHUTTERLAG_T */
|
|
- MMAL_PARAMETER_ZERO_SHUTTER_LAG,
|
|
- /**< @ref MMAL_PARAMETER_FPS_RANGE_T */
|
|
- MMAL_PARAMETER_FPS_RANGE,
|
|
- /**< @ref MMAL_PARAMETER_INT32_T */
|
|
- MMAL_PARAMETER_CAPTURE_EXPOSURE_COMP,
|
|
-
|
|
- /* 0x40 */
|
|
- /**< @ref MMAL_PARAMETER_BOOLEAN_T */
|
|
- MMAL_PARAMETER_SW_SHARPEN_DISABLE,
|
|
- /**< @ref MMAL_PARAMETER_BOOLEAN_T */
|
|
- MMAL_PARAMETER_FLASH_REQUIRED,
|
|
- /**< @ref MMAL_PARAMETER_BOOLEAN_T */
|
|
- MMAL_PARAMETER_SW_SATURATION_DISABLE,
|
|
- /**< Takes a @ref MMAL_PARAMETER_UINT32_T */
|
|
- MMAL_PARAMETER_SHUTTER_SPEED,
|
|
- /**< Takes a @ref MMAL_PARAMETER_AWB_GAINS_T */
|
|
- MMAL_PARAMETER_CUSTOM_AWB_GAINS,
|
|
-};
|
|
-
|
|
-struct mmal_parameter_rational {
|
|
- s32 num; /**< Numerator */
|
|
- s32 den; /**< Denominator */
|
|
-};
|
|
-
|
|
-enum mmal_parameter_camera_config_timestamp_mode {
|
|
- MMAL_PARAM_TIMESTAMP_MODE_ZERO = 0, /* Always timestamp frames as 0 */
|
|
- MMAL_PARAM_TIMESTAMP_MODE_RAW_STC, /* Use the raw STC value
|
|
- * for the frame timestamp
|
|
- */
|
|
- MMAL_PARAM_TIMESTAMP_MODE_RESET_STC, /* Use the STC timestamp
|
|
- * but subtract the
|
|
- * timestamp of the first
|
|
- * frame sent to give a
|
|
- * zero based timestamp.
|
|
- */
|
|
-};
|
|
-
|
|
-struct mmal_parameter_fps_range {
|
|
- /**< Low end of the permitted framerate range */
|
|
- struct mmal_parameter_rational fps_low;
|
|
- /**< High end of the permitted framerate range */
|
|
- struct mmal_parameter_rational fps_high;
|
|
-};
|
|
-
|
|
-/* camera configuration parameter */
|
|
-struct mmal_parameter_camera_config {
|
|
- /* Parameters for setting up the image pools */
|
|
- u32 max_stills_w; /* Max size of stills capture */
|
|
- u32 max_stills_h;
|
|
- u32 stills_yuv422; /* Allow YUV422 stills capture */
|
|
- u32 one_shot_stills; /* Continuous or one shot stills captures. */
|
|
-
|
|
- u32 max_preview_video_w; /* Max size of the preview or video
|
|
- * capture frames
|
|
- */
|
|
- u32 max_preview_video_h;
|
|
- u32 num_preview_video_frames;
|
|
-
|
|
- /** Sets the height of the circular buffer for stills capture. */
|
|
- u32 stills_capture_circular_buffer_height;
|
|
-
|
|
- /** Allows preview/encode to resume as fast as possible after the stills
|
|
- * input frame has been received, and then processes the still frame in
|
|
- * the background whilst preview/encode has resumed.
|
|
- * Actual mode is controlled by MMAL_PARAMETER_CAPTURE_MODE.
|
|
- */
|
|
- u32 fast_preview_resume;
|
|
-
|
|
- /** Selects algorithm for timestamping frames if
|
|
- * there is no clock component connected.
|
|
- * enum mmal_parameter_camera_config_timestamp_mode
|
|
- */
|
|
- s32 use_stc_timestamp;
|
|
-};
|
|
-
|
|
-enum mmal_parameter_exposuremode {
|
|
- MMAL_PARAM_EXPOSUREMODE_OFF,
|
|
- MMAL_PARAM_EXPOSUREMODE_AUTO,
|
|
- MMAL_PARAM_EXPOSUREMODE_NIGHT,
|
|
- MMAL_PARAM_EXPOSUREMODE_NIGHTPREVIEW,
|
|
- MMAL_PARAM_EXPOSUREMODE_BACKLIGHT,
|
|
- MMAL_PARAM_EXPOSUREMODE_SPOTLIGHT,
|
|
- MMAL_PARAM_EXPOSUREMODE_SPORTS,
|
|
- MMAL_PARAM_EXPOSUREMODE_SNOW,
|
|
- MMAL_PARAM_EXPOSUREMODE_BEACH,
|
|
- MMAL_PARAM_EXPOSUREMODE_VERYLONG,
|
|
- MMAL_PARAM_EXPOSUREMODE_FIXEDFPS,
|
|
- MMAL_PARAM_EXPOSUREMODE_ANTISHAKE,
|
|
- MMAL_PARAM_EXPOSUREMODE_FIREWORKS,
|
|
-};
|
|
-
|
|
-enum mmal_parameter_exposuremeteringmode {
|
|
- MMAL_PARAM_EXPOSUREMETERINGMODE_AVERAGE,
|
|
- MMAL_PARAM_EXPOSUREMETERINGMODE_SPOT,
|
|
- MMAL_PARAM_EXPOSUREMETERINGMODE_BACKLIT,
|
|
- MMAL_PARAM_EXPOSUREMETERINGMODE_MATRIX,
|
|
-};
|
|
-
|
|
-enum mmal_parameter_awbmode {
|
|
- MMAL_PARAM_AWBMODE_OFF,
|
|
- MMAL_PARAM_AWBMODE_AUTO,
|
|
- MMAL_PARAM_AWBMODE_SUNLIGHT,
|
|
- MMAL_PARAM_AWBMODE_CLOUDY,
|
|
- MMAL_PARAM_AWBMODE_SHADE,
|
|
- MMAL_PARAM_AWBMODE_TUNGSTEN,
|
|
- MMAL_PARAM_AWBMODE_FLUORESCENT,
|
|
- MMAL_PARAM_AWBMODE_INCANDESCENT,
|
|
- MMAL_PARAM_AWBMODE_FLASH,
|
|
- MMAL_PARAM_AWBMODE_HORIZON,
|
|
-};
|
|
-
|
|
-enum mmal_parameter_imagefx {
|
|
- MMAL_PARAM_IMAGEFX_NONE,
|
|
- MMAL_PARAM_IMAGEFX_NEGATIVE,
|
|
- MMAL_PARAM_IMAGEFX_SOLARIZE,
|
|
- MMAL_PARAM_IMAGEFX_POSTERIZE,
|
|
- MMAL_PARAM_IMAGEFX_WHITEBOARD,
|
|
- MMAL_PARAM_IMAGEFX_BLACKBOARD,
|
|
- MMAL_PARAM_IMAGEFX_SKETCH,
|
|
- MMAL_PARAM_IMAGEFX_DENOISE,
|
|
- MMAL_PARAM_IMAGEFX_EMBOSS,
|
|
- MMAL_PARAM_IMAGEFX_OILPAINT,
|
|
- MMAL_PARAM_IMAGEFX_HATCH,
|
|
- MMAL_PARAM_IMAGEFX_GPEN,
|
|
- MMAL_PARAM_IMAGEFX_PASTEL,
|
|
- MMAL_PARAM_IMAGEFX_WATERCOLOUR,
|
|
- MMAL_PARAM_IMAGEFX_FILM,
|
|
- MMAL_PARAM_IMAGEFX_BLUR,
|
|
- MMAL_PARAM_IMAGEFX_SATURATION,
|
|
- MMAL_PARAM_IMAGEFX_COLOURSWAP,
|
|
- MMAL_PARAM_IMAGEFX_WASHEDOUT,
|
|
- MMAL_PARAM_IMAGEFX_POSTERISE,
|
|
- MMAL_PARAM_IMAGEFX_COLOURPOINT,
|
|
- MMAL_PARAM_IMAGEFX_COLOURBALANCE,
|
|
- MMAL_PARAM_IMAGEFX_CARTOON,
|
|
-};
|
|
-
|
|
-enum MMAL_PARAM_FLICKERAVOID_T {
|
|
- MMAL_PARAM_FLICKERAVOID_OFF,
|
|
- MMAL_PARAM_FLICKERAVOID_AUTO,
|
|
- MMAL_PARAM_FLICKERAVOID_50HZ,
|
|
- MMAL_PARAM_FLICKERAVOID_60HZ,
|
|
- MMAL_PARAM_FLICKERAVOID_MAX = 0x7FFFFFFF
|
|
-};
|
|
-
|
|
-struct mmal_parameter_awbgains {
|
|
- struct mmal_parameter_rational r_gain; /**< Red gain */
|
|
- struct mmal_parameter_rational b_gain; /**< Blue gain */
|
|
-};
|
|
-
|
|
-/** Manner of video rate control */
|
|
-enum mmal_parameter_rate_control_mode {
|
|
- MMAL_VIDEO_RATECONTROL_DEFAULT,
|
|
- MMAL_VIDEO_RATECONTROL_VARIABLE,
|
|
- MMAL_VIDEO_RATECONTROL_CONSTANT,
|
|
- MMAL_VIDEO_RATECONTROL_VARIABLE_SKIP_FRAMES,
|
|
- MMAL_VIDEO_RATECONTROL_CONSTANT_SKIP_FRAMES
|
|
-};
|
|
-
|
|
-enum mmal_video_profile {
|
|
- MMAL_VIDEO_PROFILE_H263_BASELINE,
|
|
- MMAL_VIDEO_PROFILE_H263_H320CODING,
|
|
- MMAL_VIDEO_PROFILE_H263_BACKWARDCOMPATIBLE,
|
|
- MMAL_VIDEO_PROFILE_H263_ISWV2,
|
|
- MMAL_VIDEO_PROFILE_H263_ISWV3,
|
|
- MMAL_VIDEO_PROFILE_H263_HIGHCOMPRESSION,
|
|
- MMAL_VIDEO_PROFILE_H263_INTERNET,
|
|
- MMAL_VIDEO_PROFILE_H263_INTERLACE,
|
|
- MMAL_VIDEO_PROFILE_H263_HIGHLATENCY,
|
|
- MMAL_VIDEO_PROFILE_MP4V_SIMPLE,
|
|
- MMAL_VIDEO_PROFILE_MP4V_SIMPLESCALABLE,
|
|
- MMAL_VIDEO_PROFILE_MP4V_CORE,
|
|
- MMAL_VIDEO_PROFILE_MP4V_MAIN,
|
|
- MMAL_VIDEO_PROFILE_MP4V_NBIT,
|
|
- MMAL_VIDEO_PROFILE_MP4V_SCALABLETEXTURE,
|
|
- MMAL_VIDEO_PROFILE_MP4V_SIMPLEFACE,
|
|
- MMAL_VIDEO_PROFILE_MP4V_SIMPLEFBA,
|
|
- MMAL_VIDEO_PROFILE_MP4V_BASICANIMATED,
|
|
- MMAL_VIDEO_PROFILE_MP4V_HYBRID,
|
|
- MMAL_VIDEO_PROFILE_MP4V_ADVANCEDREALTIME,
|
|
- MMAL_VIDEO_PROFILE_MP4V_CORESCALABLE,
|
|
- MMAL_VIDEO_PROFILE_MP4V_ADVANCEDCODING,
|
|
- MMAL_VIDEO_PROFILE_MP4V_ADVANCEDCORE,
|
|
- MMAL_VIDEO_PROFILE_MP4V_ADVANCEDSCALABLE,
|
|
- MMAL_VIDEO_PROFILE_MP4V_ADVANCEDSIMPLE,
|
|
- MMAL_VIDEO_PROFILE_H264_BASELINE,
|
|
- MMAL_VIDEO_PROFILE_H264_MAIN,
|
|
- MMAL_VIDEO_PROFILE_H264_EXTENDED,
|
|
- MMAL_VIDEO_PROFILE_H264_HIGH,
|
|
- MMAL_VIDEO_PROFILE_H264_HIGH10,
|
|
- MMAL_VIDEO_PROFILE_H264_HIGH422,
|
|
- MMAL_VIDEO_PROFILE_H264_HIGH444,
|
|
- MMAL_VIDEO_PROFILE_H264_CONSTRAINED_BASELINE,
|
|
- MMAL_VIDEO_PROFILE_DUMMY = 0x7FFFFFFF
|
|
-};
|
|
-
|
|
-enum mmal_video_level {
|
|
- MMAL_VIDEO_LEVEL_H263_10,
|
|
- MMAL_VIDEO_LEVEL_H263_20,
|
|
- MMAL_VIDEO_LEVEL_H263_30,
|
|
- MMAL_VIDEO_LEVEL_H263_40,
|
|
- MMAL_VIDEO_LEVEL_H263_45,
|
|
- MMAL_VIDEO_LEVEL_H263_50,
|
|
- MMAL_VIDEO_LEVEL_H263_60,
|
|
- MMAL_VIDEO_LEVEL_H263_70,
|
|
- MMAL_VIDEO_LEVEL_MP4V_0,
|
|
- MMAL_VIDEO_LEVEL_MP4V_0b,
|
|
- MMAL_VIDEO_LEVEL_MP4V_1,
|
|
- MMAL_VIDEO_LEVEL_MP4V_2,
|
|
- MMAL_VIDEO_LEVEL_MP4V_3,
|
|
- MMAL_VIDEO_LEVEL_MP4V_4,
|
|
- MMAL_VIDEO_LEVEL_MP4V_4a,
|
|
- MMAL_VIDEO_LEVEL_MP4V_5,
|
|
- MMAL_VIDEO_LEVEL_MP4V_6,
|
|
- MMAL_VIDEO_LEVEL_H264_1,
|
|
- MMAL_VIDEO_LEVEL_H264_1b,
|
|
- MMAL_VIDEO_LEVEL_H264_11,
|
|
- MMAL_VIDEO_LEVEL_H264_12,
|
|
- MMAL_VIDEO_LEVEL_H264_13,
|
|
- MMAL_VIDEO_LEVEL_H264_2,
|
|
- MMAL_VIDEO_LEVEL_H264_21,
|
|
- MMAL_VIDEO_LEVEL_H264_22,
|
|
- MMAL_VIDEO_LEVEL_H264_3,
|
|
- MMAL_VIDEO_LEVEL_H264_31,
|
|
- MMAL_VIDEO_LEVEL_H264_32,
|
|
- MMAL_VIDEO_LEVEL_H264_4,
|
|
- MMAL_VIDEO_LEVEL_H264_41,
|
|
- MMAL_VIDEO_LEVEL_H264_42,
|
|
- MMAL_VIDEO_LEVEL_H264_5,
|
|
- MMAL_VIDEO_LEVEL_H264_51,
|
|
- MMAL_VIDEO_LEVEL_DUMMY = 0x7FFFFFFF
|
|
-};
|
|
-
|
|
-struct mmal_parameter_video_profile {
|
|
- enum mmal_video_profile profile;
|
|
- enum mmal_video_level level;
|
|
-};
|
|
-
|
|
-/* video parameters */
|
|
-
|
|
-enum mmal_parameter_video_type {
|
|
- /** @ref MMAL_DISPLAYREGION_T */
|
|
- MMAL_PARAMETER_DISPLAYREGION = MMAL_PARAMETER_GROUP_VIDEO,
|
|
-
|
|
- /** @ref MMAL_PARAMETER_VIDEO_PROFILE_T */
|
|
- MMAL_PARAMETER_SUPPORTED_PROFILES,
|
|
-
|
|
- /** @ref MMAL_PARAMETER_VIDEO_PROFILE_T */
|
|
- MMAL_PARAMETER_PROFILE,
|
|
-
|
|
- /** @ref MMAL_PARAMETER_UINT32_T */
|
|
- MMAL_PARAMETER_INTRAPERIOD,
|
|
-
|
|
- /** @ref MMAL_PARAMETER_VIDEO_RATECONTROL_T */
|
|
- MMAL_PARAMETER_RATECONTROL,
|
|
-
|
|
- /** @ref MMAL_PARAMETER_VIDEO_NALUNITFORMAT_T */
|
|
- MMAL_PARAMETER_NALUNITFORMAT,
|
|
-
|
|
- /** @ref MMAL_PARAMETER_BOOLEAN_T */
|
|
- MMAL_PARAMETER_MINIMISE_FRAGMENTATION,
|
|
-
|
|
- /** @ref MMAL_PARAMETER_UINT32_T.
|
|
- * Setting the value to zero resets to the default (one slice per
|
|
- * frame).
|
|
- */
|
|
- MMAL_PARAMETER_MB_ROWS_PER_SLICE,
|
|
-
|
|
- /** @ref MMAL_PARAMETER_VIDEO_LEVEL_EXTENSION_T */
|
|
- MMAL_PARAMETER_VIDEO_LEVEL_EXTENSION,
|
|
-
|
|
- /** @ref MMAL_PARAMETER_VIDEO_EEDE_ENABLE_T */
|
|
- MMAL_PARAMETER_VIDEO_EEDE_ENABLE,
|
|
-
|
|
- /** @ref MMAL_PARAMETER_VIDEO_EEDE_LOSSRATE_T */
|
|
- MMAL_PARAMETER_VIDEO_EEDE_LOSSRATE,
|
|
-
|
|
- /** @ref MMAL_PARAMETER_BOOLEAN_T. Request an I-frame. */
|
|
- MMAL_PARAMETER_VIDEO_REQUEST_I_FRAME,
|
|
- /** @ref MMAL_PARAMETER_VIDEO_INTRA_REFRESH_T */
|
|
- MMAL_PARAMETER_VIDEO_INTRA_REFRESH,
|
|
-
|
|
- /** @ref MMAL_PARAMETER_BOOLEAN_T. */
|
|
- MMAL_PARAMETER_VIDEO_IMMUTABLE_INPUT,
|
|
-
|
|
- /** @ref MMAL_PARAMETER_UINT32_T. Run-time bit rate control */
|
|
- MMAL_PARAMETER_VIDEO_BIT_RATE,
|
|
-
|
|
- /** @ref MMAL_PARAMETER_FRAME_RATE_T */
|
|
- MMAL_PARAMETER_VIDEO_FRAME_RATE,
|
|
-
|
|
- /** @ref MMAL_PARAMETER_UINT32_T. */
|
|
- MMAL_PARAMETER_VIDEO_ENCODE_MIN_QUANT,
|
|
-
|
|
- /** @ref MMAL_PARAMETER_UINT32_T. */
|
|
- MMAL_PARAMETER_VIDEO_ENCODE_MAX_QUANT,
|
|
-
|
|
- /** @ref MMAL_PARAMETER_VIDEO_ENCODE_RC_MODEL_T. */
|
|
- MMAL_PARAMETER_VIDEO_ENCODE_RC_MODEL,
|
|
-
|
|
- MMAL_PARAMETER_EXTRA_BUFFERS, /**< @ref MMAL_PARAMETER_UINT32_T. */
|
|
- /** @ref MMAL_PARAMETER_UINT32_T.
|
|
- * Changing this parameter from the default can reduce frame rate
|
|
- * because image buffers need to be re-pitched.
|
|
- */
|
|
- MMAL_PARAMETER_VIDEO_ALIGN_HORIZ,
|
|
-
|
|
- /** @ref MMAL_PARAMETER_UINT32_T.
|
|
- * Changing this parameter from the default can reduce frame rate
|
|
- * because image buffers need to be re-pitched.
|
|
- */
|
|
- MMAL_PARAMETER_VIDEO_ALIGN_VERT,
|
|
-
|
|
- /** @ref MMAL_PARAMETER_BOOLEAN_T. */
|
|
- MMAL_PARAMETER_VIDEO_DROPPABLE_PFRAMES,
|
|
-
|
|
- /** @ref MMAL_PARAMETER_UINT32_T. */
|
|
- MMAL_PARAMETER_VIDEO_ENCODE_INITIAL_QUANT,
|
|
-
|
|
- /**< @ref MMAL_PARAMETER_UINT32_T. */
|
|
- MMAL_PARAMETER_VIDEO_ENCODE_QP_P,
|
|
-
|
|
- /**< @ref MMAL_PARAMETER_UINT32_T. */
|
|
- MMAL_PARAMETER_VIDEO_ENCODE_RC_SLICE_DQUANT,
|
|
-
|
|
- /** @ref MMAL_PARAMETER_UINT32_T */
|
|
- MMAL_PARAMETER_VIDEO_ENCODE_FRAME_LIMIT_BITS,
|
|
-
|
|
- /** @ref MMAL_PARAMETER_UINT32_T. */
|
|
- MMAL_PARAMETER_VIDEO_ENCODE_PEAK_RATE,
|
|
-
|
|
- /* H264 specific parameters */
|
|
-
|
|
- /** @ref MMAL_PARAMETER_BOOLEAN_T. */
|
|
- MMAL_PARAMETER_VIDEO_ENCODE_H264_DISABLE_CABAC,
|
|
-
|
|
- /** @ref MMAL_PARAMETER_BOOLEAN_T. */
|
|
- MMAL_PARAMETER_VIDEO_ENCODE_H264_LOW_LATENCY,
|
|
-
|
|
- /** @ref MMAL_PARAMETER_BOOLEAN_T. */
|
|
- MMAL_PARAMETER_VIDEO_ENCODE_H264_AU_DELIMITERS,
|
|
-
|
|
- /** @ref MMAL_PARAMETER_UINT32_T. */
|
|
- MMAL_PARAMETER_VIDEO_ENCODE_H264_DEBLOCK_IDC,
|
|
-
|
|
- /** @ref MMAL_PARAMETER_VIDEO_ENCODER_H264_MB_INTRA_MODES_T. */
|
|
- MMAL_PARAMETER_VIDEO_ENCODE_H264_MB_INTRA_MODE,
|
|
-
|
|
- /** @ref MMAL_PARAMETER_BOOLEAN_T */
|
|
- MMAL_PARAMETER_VIDEO_ENCODE_HEADER_ON_OPEN,
|
|
-
|
|
- /** @ref MMAL_PARAMETER_BOOLEAN_T */
|
|
- MMAL_PARAMETER_VIDEO_ENCODE_PRECODE_FOR_QP,
|
|
-
|
|
- /** @ref MMAL_PARAMETER_VIDEO_DRM_INIT_INFO_T. */
|
|
- MMAL_PARAMETER_VIDEO_DRM_INIT_INFO,
|
|
-
|
|
- /** @ref MMAL_PARAMETER_BOOLEAN_T */
|
|
- MMAL_PARAMETER_VIDEO_TIMESTAMP_FIFO,
|
|
-
|
|
- /** @ref MMAL_PARAMETER_BOOLEAN_T */
|
|
- MMAL_PARAMETER_VIDEO_DECODE_ERROR_CONCEALMENT,
|
|
-
|
|
- /** @ref MMAL_PARAMETER_VIDEO_DRM_PROTECT_BUFFER_T. */
|
|
- MMAL_PARAMETER_VIDEO_DRM_PROTECT_BUFFER,
|
|
-
|
|
- /** @ref MMAL_PARAMETER_BYTES_T */
|
|
- MMAL_PARAMETER_VIDEO_DECODE_CONFIG_VD3,
|
|
-
|
|
- /**< @ref MMAL_PARAMETER_BOOLEAN_T */
|
|
- MMAL_PARAMETER_VIDEO_ENCODE_H264_VCL_HRD_PARAMETERS,
|
|
-
|
|
- /**< @ref MMAL_PARAMETER_BOOLEAN_T */
|
|
- MMAL_PARAMETER_VIDEO_ENCODE_H264_LOW_DELAY_HRD_FLAG,
|
|
-
|
|
- /**< @ref MMAL_PARAMETER_BOOLEAN_T */
|
|
- MMAL_PARAMETER_VIDEO_ENCODE_INLINE_HEADER
|
|
-};
|
|
-
|
|
-/** Valid mirror modes */
|
|
-enum mmal_parameter_mirror {
|
|
- MMAL_PARAM_MIRROR_NONE,
|
|
- MMAL_PARAM_MIRROR_VERTICAL,
|
|
- MMAL_PARAM_MIRROR_HORIZONTAL,
|
|
- MMAL_PARAM_MIRROR_BOTH,
|
|
-};
|
|
-
|
|
-enum mmal_parameter_displaytransform {
|
|
- MMAL_DISPLAY_ROT0 = 0,
|
|
- MMAL_DISPLAY_MIRROR_ROT0 = 1,
|
|
- MMAL_DISPLAY_MIRROR_ROT180 = 2,
|
|
- MMAL_DISPLAY_ROT180 = 3,
|
|
- MMAL_DISPLAY_MIRROR_ROT90 = 4,
|
|
- MMAL_DISPLAY_ROT270 = 5,
|
|
- MMAL_DISPLAY_ROT90 = 6,
|
|
- MMAL_DISPLAY_MIRROR_ROT270 = 7,
|
|
-};
|
|
-
|
|
-enum mmal_parameter_displaymode {
|
|
- MMAL_DISPLAY_MODE_FILL = 0,
|
|
- MMAL_DISPLAY_MODE_LETTERBOX = 1,
|
|
-};
|
|
-
|
|
-enum mmal_parameter_displayset {
|
|
- MMAL_DISPLAY_SET_NONE = 0,
|
|
- MMAL_DISPLAY_SET_NUM = 1,
|
|
- MMAL_DISPLAY_SET_FULLSCREEN = 2,
|
|
- MMAL_DISPLAY_SET_TRANSFORM = 4,
|
|
- MMAL_DISPLAY_SET_DEST_RECT = 8,
|
|
- MMAL_DISPLAY_SET_SRC_RECT = 0x10,
|
|
- MMAL_DISPLAY_SET_MODE = 0x20,
|
|
- MMAL_DISPLAY_SET_PIXEL = 0x40,
|
|
- MMAL_DISPLAY_SET_NOASPECT = 0x80,
|
|
- MMAL_DISPLAY_SET_LAYER = 0x100,
|
|
- MMAL_DISPLAY_SET_COPYPROTECT = 0x200,
|
|
- MMAL_DISPLAY_SET_ALPHA = 0x400,
|
|
-};
|
|
-
|
|
-/* rectangle, used lots so it gets its own struct */
|
|
-struct vchiq_mmal_rect {
|
|
- s32 x;
|
|
- s32 y;
|
|
- s32 width;
|
|
- s32 height;
|
|
-};
|
|
-
|
|
-struct mmal_parameter_displayregion {
|
|
- /** Bitfield that indicates which fields are set and should be
|
|
- * used. All other fields will maintain their current value.
|
|
- * \ref MMAL_DISPLAYSET_T defines the bits that can be
|
|
- * combined.
|
|
- */
|
|
- u32 set;
|
|
-
|
|
- /** Describes the display output device, with 0 typically
|
|
- * being a directly connected LCD display. The actual values
|
|
- * will depend on the hardware. Code using hard-wired numbers
|
|
- * (e.g. 2) is certain to fail.
|
|
- */
|
|
-
|
|
- u32 display_num;
|
|
- /** Indicates that we are using the full device screen area,
|
|
- * rather than a window of the display. If zero, then
|
|
- * dest_rect is used to specify a region of the display to
|
|
- * use.
|
|
- */
|
|
-
|
|
- s32 fullscreen;
|
|
- /** Indicates any rotation or flipping used to map frames onto
|
|
- * the natural display orientation.
|
|
- */
|
|
- u32 transform; /* enum mmal_parameter_displaytransform */
|
|
-
|
|
- /** Where to display the frame within the screen, if
|
|
- * fullscreen is zero.
|
|
- */
|
|
- struct vchiq_mmal_rect dest_rect;
|
|
-
|
|
- /** Indicates which area of the frame to display. If all
|
|
- * values are zero, the whole frame will be used.
|
|
- */
|
|
- struct vchiq_mmal_rect src_rect;
|
|
-
|
|
- /** If set to non-zero, indicates that any display scaling
|
|
- * should disregard the aspect ratio of the frame region being
|
|
- * displayed.
|
|
- */
|
|
- s32 noaspect;
|
|
-
|
|
- /** Indicates how the image should be scaled to fit the
|
|
- * display. \code MMAL_DISPLAY_MODE_FILL \endcode indicates
|
|
- * that the image should fill the screen by potentially
|
|
- * cropping the frames. Setting \code mode \endcode to \code
|
|
- * MMAL_DISPLAY_MODE_LETTERBOX \endcode indicates that all the
|
|
- * source region should be displayed and black bars added if
|
|
- * necessary.
|
|
- */
|
|
- u32 mode; /* enum mmal_parameter_displaymode */
|
|
-
|
|
- /** If non-zero, defines the width of a source pixel relative
|
|
- * to \code pixel_y \endcode. If zero, then pixels default to
|
|
- * being square.
|
|
- */
|
|
- u32 pixel_x;
|
|
-
|
|
- /** If non-zero, defines the height of a source pixel relative
|
|
- * to \code pixel_x \endcode. If zero, then pixels default to
|
|
- * being square.
|
|
- */
|
|
- u32 pixel_y;
|
|
-
|
|
- /** Sets the relative depth of the images, with greater values
|
|
- * being in front of smaller values.
|
|
- */
|
|
- u32 layer;
|
|
-
|
|
- /** Set to non-zero to ensure copy protection is used on
|
|
- * output.
|
|
- */
|
|
- s32 copyprotect_required;
|
|
-
|
|
- /** Level of opacity of the layer, where zero is fully
|
|
- * transparent and 255 is fully opaque.
|
|
- */
|
|
- u32 alpha;
|
|
-};
|
|
-
|
|
-#define MMAL_MAX_IMAGEFX_PARAMETERS 5
|
|
-
|
|
-struct mmal_parameter_imagefx_parameters {
|
|
- enum mmal_parameter_imagefx effect;
|
|
- u32 num_effect_params;
|
|
- u32 effect_parameter[MMAL_MAX_IMAGEFX_PARAMETERS];
|
|
-};
|
|
-
|
|
-#define MMAL_PARAMETER_CAMERA_INFO_MAX_CAMERAS 4
|
|
-#define MMAL_PARAMETER_CAMERA_INFO_MAX_FLASHES 2
|
|
-#define MMAL_PARAMETER_CAMERA_INFO_MAX_STR_LEN 16
|
|
-
|
|
-struct mmal_parameter_camera_info_camera_t {
|
|
- u32 port_id;
|
|
- u32 max_width;
|
|
- u32 max_height;
|
|
- u32 lens_present;
|
|
- u8 camera_name[MMAL_PARAMETER_CAMERA_INFO_MAX_STR_LEN];
|
|
-};
|
|
-
|
|
-enum mmal_parameter_camera_info_flash_type_t {
|
|
- /* Make values explicit to ensure they match values in config ini */
|
|
- MMAL_PARAMETER_CAMERA_INFO_FLASH_TYPE_XENON = 0,
|
|
- MMAL_PARAMETER_CAMERA_INFO_FLASH_TYPE_LED = 1,
|
|
- MMAL_PARAMETER_CAMERA_INFO_FLASH_TYPE_OTHER = 2,
|
|
- MMAL_PARAMETER_CAMERA_INFO_FLASH_TYPE_MAX = 0x7FFFFFFF
|
|
-};
|
|
-
|
|
-struct mmal_parameter_camera_info_flash_t {
|
|
- enum mmal_parameter_camera_info_flash_type_t flash_type;
|
|
-};
|
|
-
|
|
-struct mmal_parameter_camera_info_t {
|
|
- u32 num_cameras;
|
|
- u32 num_flashes;
|
|
- struct mmal_parameter_camera_info_camera_t
|
|
- cameras[MMAL_PARAMETER_CAMERA_INFO_MAX_CAMERAS];
|
|
- struct mmal_parameter_camera_info_flash_t
|
|
- flashes[MMAL_PARAMETER_CAMERA_INFO_MAX_FLASHES];
|
|
-};
|
|
-
|
|
-#endif
|
|
--- a/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.h
|
|
+++ /dev/null
|
|
@@ -1,166 +0,0 @@
|
|
-/* SPDX-License-Identifier: GPL-2.0 */
|
|
-/*
|
|
- * Broadcom BM2835 V4L2 driver
|
|
- *
|
|
- * Copyright © 2013 Raspberry Pi (Trading) Ltd.
|
|
- *
|
|
- * Authors: Vincent Sanders @ Collabora
|
|
- * Dave Stevenson @ Broadcom
|
|
- * (now dave.stevenson@raspberrypi.org)
|
|
- * Simon Mellor @ Broadcom
|
|
- * Luke Diamand @ Broadcom
|
|
- *
|
|
- * MMAL interface to VCHIQ message passing
|
|
- */
|
|
-
|
|
-#ifndef MMAL_VCHIQ_H
|
|
-#define MMAL_VCHIQ_H
|
|
-
|
|
-#include "mmal-msg-format.h"
|
|
-
|
|
-#define MAX_PORT_COUNT 4
|
|
-
|
|
-/* Maximum size of the format extradata. */
|
|
-#define MMAL_FORMAT_EXTRADATA_MAX_SIZE 128
|
|
-
|
|
-struct vchiq_mmal_instance;
|
|
-
|
|
-enum vchiq_mmal_es_type {
|
|
- MMAL_ES_TYPE_UNKNOWN, /**< Unknown elementary stream type */
|
|
- MMAL_ES_TYPE_CONTROL, /**< Elementary stream of control commands */
|
|
- MMAL_ES_TYPE_AUDIO, /**< Audio elementary stream */
|
|
- MMAL_ES_TYPE_VIDEO, /**< Video elementary stream */
|
|
- MMAL_ES_TYPE_SUBPICTURE /**< Sub-picture elementary stream */
|
|
-};
|
|
-
|
|
-struct vchiq_mmal_port_buffer {
|
|
- unsigned int num; /* number of buffers */
|
|
- u32 size; /* size of buffers */
|
|
- u32 alignment; /* alignment of buffers */
|
|
-};
|
|
-
|
|
-struct vchiq_mmal_port;
|
|
-
|
|
-typedef void (*vchiq_mmal_buffer_cb)(
|
|
- struct vchiq_mmal_instance *instance,
|
|
- struct vchiq_mmal_port *port,
|
|
- int status, struct mmal_buffer *buffer,
|
|
- unsigned long length, u32 mmal_flags, s64 dts, s64 pts);
|
|
-
|
|
-struct vchiq_mmal_port {
|
|
- u32 enabled:1;
|
|
- u32 handle;
|
|
- u32 type; /* port type, cached to use on port info set */
|
|
- u32 index; /* port index, cached to use on port info set */
|
|
-
|
|
- /* component port belongs to, allows simple deref */
|
|
- struct vchiq_mmal_component *component;
|
|
-
|
|
- struct vchiq_mmal_port *connected; /* port connected to */
|
|
-
|
|
- /* buffer info */
|
|
- struct vchiq_mmal_port_buffer minimum_buffer;
|
|
- struct vchiq_mmal_port_buffer recommended_buffer;
|
|
- struct vchiq_mmal_port_buffer current_buffer;
|
|
-
|
|
- /* stream format */
|
|
- struct mmal_es_format_local format;
|
|
- /* elementary stream format */
|
|
- union mmal_es_specific_format es;
|
|
-
|
|
- /* data buffers to fill */
|
|
- struct list_head buffers;
|
|
- /* lock to serialise adding and removing buffers from list */
|
|
- spinlock_t slock;
|
|
-
|
|
- /* Count of buffers the VPU has yet to return */
|
|
- atomic_t buffers_with_vpu;
|
|
- /* callback on buffer completion */
|
|
- vchiq_mmal_buffer_cb buffer_cb;
|
|
- /* callback context */
|
|
- void *cb_ctx;
|
|
-};
|
|
-
|
|
-struct vchiq_mmal_component {
|
|
- u32 enabled:1;
|
|
- u32 handle; /* VideoCore handle for component */
|
|
- u32 inputs; /* Number of input ports */
|
|
- u32 outputs; /* Number of output ports */
|
|
- u32 clocks; /* Number of clock ports */
|
|
- struct vchiq_mmal_port control; /* control port */
|
|
- struct vchiq_mmal_port input[MAX_PORT_COUNT]; /* input ports */
|
|
- struct vchiq_mmal_port output[MAX_PORT_COUNT]; /* output ports */
|
|
- struct vchiq_mmal_port clock[MAX_PORT_COUNT]; /* clock ports */
|
|
-};
|
|
-
|
|
-int vchiq_mmal_init(struct vchiq_mmal_instance **out_instance);
|
|
-int vchiq_mmal_finalise(struct vchiq_mmal_instance *instance);
|
|
-
|
|
-/* Initialise a mmal component and its ports
|
|
- *
|
|
- */
|
|
-int vchiq_mmal_component_init(
|
|
- struct vchiq_mmal_instance *instance,
|
|
- const char *name,
|
|
- struct vchiq_mmal_component **component_out);
|
|
-
|
|
-int vchiq_mmal_component_finalise(
|
|
- struct vchiq_mmal_instance *instance,
|
|
- struct vchiq_mmal_component *component);
|
|
-
|
|
-int vchiq_mmal_component_enable(
|
|
- struct vchiq_mmal_instance *instance,
|
|
- struct vchiq_mmal_component *component);
|
|
-
|
|
-int vchiq_mmal_component_disable(
|
|
- struct vchiq_mmal_instance *instance,
|
|
- struct vchiq_mmal_component *component);
|
|
-
|
|
-/* enable a mmal port
|
|
- *
|
|
- * enables a port and if a buffer callback provided enque buffer
|
|
- * headers as appropriate for the port.
|
|
- */
|
|
-int vchiq_mmal_port_enable(
|
|
- struct vchiq_mmal_instance *instance,
|
|
- struct vchiq_mmal_port *port,
|
|
- vchiq_mmal_buffer_cb buffer_cb);
|
|
-
|
|
-/* disable a port
|
|
- *
|
|
- * disable a port will dequeue any pending buffers
|
|
- */
|
|
-int vchiq_mmal_port_disable(struct vchiq_mmal_instance *instance,
|
|
- struct vchiq_mmal_port *port);
|
|
-
|
|
-int vchiq_mmal_port_parameter_set(struct vchiq_mmal_instance *instance,
|
|
- struct vchiq_mmal_port *port,
|
|
- u32 parameter,
|
|
- void *value,
|
|
- u32 value_size);
|
|
-
|
|
-int vchiq_mmal_port_parameter_get(struct vchiq_mmal_instance *instance,
|
|
- struct vchiq_mmal_port *port,
|
|
- u32 parameter,
|
|
- void *value,
|
|
- u32 *value_size);
|
|
-
|
|
-int vchiq_mmal_port_set_format(struct vchiq_mmal_instance *instance,
|
|
- struct vchiq_mmal_port *port);
|
|
-
|
|
-int vchiq_mmal_port_connect_tunnel(struct vchiq_mmal_instance *instance,
|
|
- struct vchiq_mmal_port *src,
|
|
- struct vchiq_mmal_port *dst);
|
|
-
|
|
-int vchiq_mmal_version(struct vchiq_mmal_instance *instance,
|
|
- u32 *major_out,
|
|
- u32 *minor_out);
|
|
-
|
|
-int vchiq_mmal_submit_buffer(struct vchiq_mmal_instance *instance,
|
|
- struct vchiq_mmal_port *port,
|
|
- struct mmal_buffer *buf);
|
|
-
|
|
-int mmal_vchi_buffer_init(struct vchiq_mmal_instance *instance,
|
|
- struct mmal_buffer *buf);
|
|
-int mmal_vchi_buffer_cleanup(struct mmal_buffer *buf);
|
|
-#endif /* MMAL_VCHIQ_H */
|
|
--- /dev/null
|
|
+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-common.h
|
|
@@ -0,0 +1,60 @@
|
|
+/* SPDX-License-Identifier: GPL-2.0 */
|
|
+/*
|
|
+ * Broadcom BM2835 V4L2 driver
|
|
+ *
|
|
+ * Copyright © 2013 Raspberry Pi (Trading) Ltd.
|
|
+ *
|
|
+ * Authors: Vincent Sanders @ Collabora
|
|
+ * Dave Stevenson @ Broadcom
|
|
+ * (now dave.stevenson@raspberrypi.org)
|
|
+ * Simon Mellor @ Broadcom
|
|
+ * Luke Diamand @ Broadcom
|
|
+ *
|
|
+ * MMAL structures
|
|
+ *
|
|
+ */
|
|
+#ifndef MMAL_COMMON_H
|
|
+#define MMAL_COMMON_H
|
|
+
|
|
+#define MMAL_FOURCC(a, b, c, d) ((a) | (b << 8) | (c << 16) | (d << 24))
|
|
+#define MMAL_MAGIC MMAL_FOURCC('m', 'm', 'a', 'l')
|
|
+
|
|
+/** Special value signalling that time is not known */
|
|
+#define MMAL_TIME_UNKNOWN BIT_ULL(63)
|
|
+
|
|
+struct mmal_msg_context;
|
|
+
|
|
+/* mapping between v4l and mmal video modes */
|
|
+struct mmal_fmt {
|
|
+ u32 fourcc; /* v4l2 format id */
|
|
+ int flags; /* v4l2 flags field */
|
|
+ u32 mmal;
|
|
+ int depth;
|
|
+ u32 mmal_component; /* MMAL component index to be used to encode */
|
|
+ u32 ybbp; /* depth of first Y plane for planar formats */
|
|
+ bool remove_padding; /* Does the GPU have to remove padding,
|
|
+ * or can we do hide padding via bytesperline.
|
|
+ */
|
|
+};
|
|
+
|
|
+/* buffer for one video frame */
|
|
+struct mmal_buffer {
|
|
+ /* v4l buffer data -- must be first */
|
|
+ struct vb2_v4l2_buffer vb;
|
|
+
|
|
+ /* list of buffers available */
|
|
+ struct list_head list;
|
|
+
|
|
+ void *buffer; /* buffer pointer */
|
|
+ unsigned long buffer_size; /* size of allocated buffer */
|
|
+
|
|
+ struct mmal_msg_context *msg_context;
|
|
+};
|
|
+
|
|
+/* */
|
|
+struct mmal_colourfx {
|
|
+ s32 enable;
|
|
+ u32 u;
|
|
+ u32 v;
|
|
+};
|
|
+#endif
|
|
--- /dev/null
|
|
+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-encodings.h
|
|
@@ -0,0 +1,124 @@
|
|
+/* SPDX-License-Identifier: GPL-2.0 */
|
|
+/*
|
|
+ * Broadcom BM2835 V4L2 driver
|
|
+ *
|
|
+ * Copyright © 2013 Raspberry Pi (Trading) Ltd.
|
|
+ *
|
|
+ * Authors: Vincent Sanders @ Collabora
|
|
+ * Dave Stevenson @ Broadcom
|
|
+ * (now dave.stevenson@raspberrypi.org)
|
|
+ * Simon Mellor @ Broadcom
|
|
+ * Luke Diamand @ Broadcom
|
|
+ */
|
|
+#ifndef MMAL_ENCODINGS_H
|
|
+#define MMAL_ENCODINGS_H
|
|
+
|
|
+#define MMAL_ENCODING_H264 MMAL_FOURCC('H', '2', '6', '4')
|
|
+#define MMAL_ENCODING_H263 MMAL_FOURCC('H', '2', '6', '3')
|
|
+#define MMAL_ENCODING_MP4V MMAL_FOURCC('M', 'P', '4', 'V')
|
|
+#define MMAL_ENCODING_MP2V MMAL_FOURCC('M', 'P', '2', 'V')
|
|
+#define MMAL_ENCODING_MP1V MMAL_FOURCC('M', 'P', '1', 'V')
|
|
+#define MMAL_ENCODING_WMV3 MMAL_FOURCC('W', 'M', 'V', '3')
|
|
+#define MMAL_ENCODING_WMV2 MMAL_FOURCC('W', 'M', 'V', '2')
|
|
+#define MMAL_ENCODING_WMV1 MMAL_FOURCC('W', 'M', 'V', '1')
|
|
+#define MMAL_ENCODING_WVC1 MMAL_FOURCC('W', 'V', 'C', '1')
|
|
+#define MMAL_ENCODING_VP8 MMAL_FOURCC('V', 'P', '8', ' ')
|
|
+#define MMAL_ENCODING_VP7 MMAL_FOURCC('V', 'P', '7', ' ')
|
|
+#define MMAL_ENCODING_VP6 MMAL_FOURCC('V', 'P', '6', ' ')
|
|
+#define MMAL_ENCODING_THEORA MMAL_FOURCC('T', 'H', 'E', 'O')
|
|
+#define MMAL_ENCODING_SPARK MMAL_FOURCC('S', 'P', 'R', 'K')
|
|
+#define MMAL_ENCODING_MJPEG MMAL_FOURCC('M', 'J', 'P', 'G')
|
|
+
|
|
+#define MMAL_ENCODING_JPEG MMAL_FOURCC('J', 'P', 'E', 'G')
|
|
+#define MMAL_ENCODING_GIF MMAL_FOURCC('G', 'I', 'F', ' ')
|
|
+#define MMAL_ENCODING_PNG MMAL_FOURCC('P', 'N', 'G', ' ')
|
|
+#define MMAL_ENCODING_PPM MMAL_FOURCC('P', 'P', 'M', ' ')
|
|
+#define MMAL_ENCODING_TGA MMAL_FOURCC('T', 'G', 'A', ' ')
|
|
+#define MMAL_ENCODING_BMP MMAL_FOURCC('B', 'M', 'P', ' ')
|
|
+
|
|
+#define MMAL_ENCODING_I420 MMAL_FOURCC('I', '4', '2', '0')
|
|
+#define MMAL_ENCODING_I420_SLICE MMAL_FOURCC('S', '4', '2', '0')
|
|
+#define MMAL_ENCODING_YV12 MMAL_FOURCC('Y', 'V', '1', '2')
|
|
+#define MMAL_ENCODING_I422 MMAL_FOURCC('I', '4', '2', '2')
|
|
+#define MMAL_ENCODING_I422_SLICE MMAL_FOURCC('S', '4', '2', '2')
|
|
+#define MMAL_ENCODING_YUYV MMAL_FOURCC('Y', 'U', 'Y', 'V')
|
|
+#define MMAL_ENCODING_YVYU MMAL_FOURCC('Y', 'V', 'Y', 'U')
|
|
+#define MMAL_ENCODING_UYVY MMAL_FOURCC('U', 'Y', 'V', 'Y')
|
|
+#define MMAL_ENCODING_VYUY MMAL_FOURCC('V', 'Y', 'U', 'Y')
|
|
+#define MMAL_ENCODING_NV12 MMAL_FOURCC('N', 'V', '1', '2')
|
|
+#define MMAL_ENCODING_NV21 MMAL_FOURCC('N', 'V', '2', '1')
|
|
+#define MMAL_ENCODING_ARGB MMAL_FOURCC('A', 'R', 'G', 'B')
|
|
+#define MMAL_ENCODING_RGBA MMAL_FOURCC('R', 'G', 'B', 'A')
|
|
+#define MMAL_ENCODING_ABGR MMAL_FOURCC('A', 'B', 'G', 'R')
|
|
+#define MMAL_ENCODING_BGRA MMAL_FOURCC('B', 'G', 'R', 'A')
|
|
+#define MMAL_ENCODING_RGB16 MMAL_FOURCC('R', 'G', 'B', '2')
|
|
+#define MMAL_ENCODING_RGB24 MMAL_FOURCC('R', 'G', 'B', '3')
|
|
+#define MMAL_ENCODING_RGB32 MMAL_FOURCC('R', 'G', 'B', '4')
|
|
+#define MMAL_ENCODING_BGR16 MMAL_FOURCC('B', 'G', 'R', '2')
|
|
+#define MMAL_ENCODING_BGR24 MMAL_FOURCC('B', 'G', 'R', '3')
|
|
+#define MMAL_ENCODING_BGR32 MMAL_FOURCC('B', 'G', 'R', '4')
|
|
+
|
|
+/** SAND Video (YUVUV128) format, native format understood by VideoCore.
|
|
+ * This format is *not* opaque - if requested you will receive full frames
|
|
+ * of YUV_UV video.
|
|
+ */
|
|
+#define MMAL_ENCODING_YUVUV128 MMAL_FOURCC('S', 'A', 'N', 'D')
|
|
+
|
|
+/** VideoCore opaque image format, image handles are returned to
|
|
+ * the host but not the actual image data.
|
|
+ */
|
|
+#define MMAL_ENCODING_OPAQUE MMAL_FOURCC('O', 'P', 'Q', 'V')
|
|
+
|
|
+/** An EGL image handle
|
|
+ */
|
|
+#define MMAL_ENCODING_EGL_IMAGE MMAL_FOURCC('E', 'G', 'L', 'I')
|
|
+
|
|
+/* }@ */
|
|
+
|
|
+/** \name Pre-defined audio encodings */
|
|
+/* @{ */
|
|
+#define MMAL_ENCODING_PCM_UNSIGNED_BE MMAL_FOURCC('P', 'C', 'M', 'U')
|
|
+#define MMAL_ENCODING_PCM_UNSIGNED_LE MMAL_FOURCC('p', 'c', 'm', 'u')
|
|
+#define MMAL_ENCODING_PCM_SIGNED_BE MMAL_FOURCC('P', 'C', 'M', 'S')
|
|
+#define MMAL_ENCODING_PCM_SIGNED_LE MMAL_FOURCC('p', 'c', 'm', 's')
|
|
+#define MMAL_ENCODING_PCM_FLOAT_BE MMAL_FOURCC('P', 'C', 'M', 'F')
|
|
+#define MMAL_ENCODING_PCM_FLOAT_LE MMAL_FOURCC('p', 'c', 'm', 'f')
|
|
+
|
|
+/* Pre-defined H264 encoding variants */
|
|
+
|
|
+/** ISO 14496-10 Annex B byte stream format */
|
|
+#define MMAL_ENCODING_VARIANT_H264_DEFAULT 0
|
|
+/** ISO 14496-15 AVC stream format */
|
|
+#define MMAL_ENCODING_VARIANT_H264_AVC1 MMAL_FOURCC('A', 'V', 'C', '1')
|
|
+/** Implicitly delineated NAL units without emulation prevention */
|
|
+#define MMAL_ENCODING_VARIANT_H264_RAW MMAL_FOURCC('R', 'A', 'W', ' ')
|
|
+
|
|
+/** \defgroup MmalColorSpace List of pre-defined video color spaces
|
|
+ * This defines a list of common color spaces. This list isn't exhaustive and
|
|
+ * is only provided as a convenience to avoid clients having to use FourCC
|
|
+ * codes directly. However components are allowed to define and use their own
|
|
+ * FourCC codes.
|
|
+ */
|
|
+/* @{ */
|
|
+
|
|
+/** Unknown color space */
|
|
+#define MMAL_COLOR_SPACE_UNKNOWN 0
|
|
+/** ITU-R BT.601-5 [SDTV] */
|
|
+#define MMAL_COLOR_SPACE_ITUR_BT601 MMAL_FOURCC('Y', '6', '0', '1')
|
|
+/** ITU-R BT.709-3 [HDTV] */
|
|
+#define MMAL_COLOR_SPACE_ITUR_BT709 MMAL_FOURCC('Y', '7', '0', '9')
|
|
+/** JPEG JFIF */
|
|
+#define MMAL_COLOR_SPACE_JPEG_JFIF MMAL_FOURCC('Y', 'J', 'F', 'I')
|
|
+/** Title 47 Code of Federal Regulations (2003) 73.682 (a) (20) */
|
|
+#define MMAL_COLOR_SPACE_FCC MMAL_FOURCC('Y', 'F', 'C', 'C')
|
|
+/** Society of Motion Picture and Television Engineers 240M (1999) */
|
|
+#define MMAL_COLOR_SPACE_SMPTE240M MMAL_FOURCC('Y', '2', '4', '0')
|
|
+/** ITU-R BT.470-2 System M */
|
|
+#define MMAL_COLOR_SPACE_BT470_2_M MMAL_FOURCC('Y', '_', '_', 'M')
|
|
+/** ITU-R BT.470-2 System BG */
|
|
+#define MMAL_COLOR_SPACE_BT470_2_BG MMAL_FOURCC('Y', '_', 'B', 'G')
|
|
+/** JPEG JFIF, but with 16..255 luma */
|
|
+#define MMAL_COLOR_SPACE_JFIF_Y16_255 MMAL_FOURCC('Y', 'Y', '1', '6')
|
|
+/* @} MmalColorSpace List */
|
|
+
|
|
+#endif /* MMAL_ENCODINGS_H */
|
|
--- /dev/null
|
|
+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-msg-common.h
|
|
@@ -0,0 +1,48 @@
|
|
+/* SPDX-License-Identifier: GPL-2.0 */
|
|
+/*
|
|
+ * Broadcom BM2835 V4L2 driver
|
|
+ *
|
|
+ * Copyright © 2013 Raspberry Pi (Trading) Ltd.
|
|
+ *
|
|
+ * Authors: Vincent Sanders @ Collabora
|
|
+ * Dave Stevenson @ Broadcom
|
|
+ * (now dave.stevenson@raspberrypi.org)
|
|
+ * Simon Mellor @ Broadcom
|
|
+ * Luke Diamand @ Broadcom
|
|
+ */
|
|
+
|
|
+#ifndef MMAL_MSG_COMMON_H
|
|
+#define MMAL_MSG_COMMON_H
|
|
+
|
|
+enum mmal_msg_status {
|
|
+ MMAL_MSG_STATUS_SUCCESS = 0, /**< Success */
|
|
+ MMAL_MSG_STATUS_ENOMEM, /**< Out of memory */
|
|
+ MMAL_MSG_STATUS_ENOSPC, /**< Out of resources other than memory */
|
|
+ MMAL_MSG_STATUS_EINVAL, /**< Argument is invalid */
|
|
+ MMAL_MSG_STATUS_ENOSYS, /**< Function not implemented */
|
|
+ MMAL_MSG_STATUS_ENOENT, /**< No such file or directory */
|
|
+ MMAL_MSG_STATUS_ENXIO, /**< No such device or address */
|
|
+ MMAL_MSG_STATUS_EIO, /**< I/O error */
|
|
+ MMAL_MSG_STATUS_ESPIPE, /**< Illegal seek */
|
|
+ MMAL_MSG_STATUS_ECORRUPT, /**< Data is corrupt \attention */
|
|
+ MMAL_MSG_STATUS_ENOTREADY, /**< Component is not ready */
|
|
+ MMAL_MSG_STATUS_ECONFIG, /**< Component is not configured */
|
|
+ MMAL_MSG_STATUS_EISCONN, /**< Port is already connected */
|
|
+ MMAL_MSG_STATUS_ENOTCONN, /**< Port is disconnected */
|
|
+ MMAL_MSG_STATUS_EAGAIN, /**< Resource temporarily unavailable. */
|
|
+ MMAL_MSG_STATUS_EFAULT, /**< Bad address */
|
|
+};
|
|
+
|
|
+struct mmal_rect {
|
|
+ s32 x; /**< x coordinate (from left) */
|
|
+ s32 y; /**< y coordinate (from top) */
|
|
+ s32 width; /**< width */
|
|
+ s32 height; /**< height */
|
|
+};
|
|
+
|
|
+struct mmal_rational {
|
|
+ s32 num; /**< Numerator */
|
|
+ s32 den; /**< Denominator */
|
|
+};
|
|
+
|
|
+#endif /* MMAL_MSG_COMMON_H */
|
|
--- /dev/null
|
|
+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-msg-format.h
|
|
@@ -0,0 +1,106 @@
|
|
+/* SPDX-License-Identifier: GPL-2.0 */
|
|
+/*
|
|
+ * Broadcom BM2835 V4L2 driver
|
|
+ *
|
|
+ * Copyright © 2013 Raspberry Pi (Trading) Ltd.
|
|
+ *
|
|
+ * Authors: Vincent Sanders @ Collabora
|
|
+ * Dave Stevenson @ Broadcom
|
|
+ * (now dave.stevenson@raspberrypi.org)
|
|
+ * Simon Mellor @ Broadcom
|
|
+ * Luke Diamand @ Broadcom
|
|
+ */
|
|
+
|
|
+#ifndef MMAL_MSG_FORMAT_H
|
|
+#define MMAL_MSG_FORMAT_H
|
|
+
|
|
+#include "mmal-msg-common.h"
|
|
+
|
|
+/* MMAL_ES_FORMAT_T */
|
|
+
|
|
+struct mmal_audio_format {
|
|
+ u32 channels; /* Number of audio channels */
|
|
+ u32 sample_rate; /* Sample rate */
|
|
+
|
|
+ u32 bits_per_sample; /* Bits per sample */
|
|
+ u32 block_align; /* Size of a block of data */
|
|
+};
|
|
+
|
|
+struct mmal_video_format {
|
|
+ u32 width; /* Width of frame in pixels */
|
|
+ u32 height; /* Height of frame in rows of pixels */
|
|
+ struct mmal_rect crop; /* Visible region of the frame */
|
|
+ struct mmal_rational frame_rate; /* Frame rate */
|
|
+ struct mmal_rational par; /* Pixel aspect ratio */
|
|
+
|
|
+ /*
|
|
+ * FourCC specifying the color space of the video stream. See the
|
|
+ * MmalColorSpace "pre-defined color spaces" for some examples.
|
|
+ */
|
|
+ u32 color_space;
|
|
+};
|
|
+
|
|
+struct mmal_subpicture_format {
|
|
+ u32 x_offset;
|
|
+ u32 y_offset;
|
|
+};
|
|
+
|
|
+union mmal_es_specific_format {
|
|
+ struct mmal_audio_format audio;
|
|
+ struct mmal_video_format video;
|
|
+ struct mmal_subpicture_format subpicture;
|
|
+};
|
|
+
|
|
+/* Definition of an elementary stream format (MMAL_ES_FORMAT_T) */
|
|
+struct mmal_es_format_local {
|
|
+ u32 type; /* enum mmal_es_type */
|
|
+
|
|
+ u32 encoding; /* FourCC specifying encoding of the elementary
|
|
+ * stream.
|
|
+ */
|
|
+ u32 encoding_variant; /* FourCC specifying the specific
|
|
+ * encoding variant of the elementary
|
|
+ * stream.
|
|
+ */
|
|
+
|
|
+ union mmal_es_specific_format *es; /* Type specific
|
|
+ * information for the
|
|
+ * elementary stream
|
|
+ */
|
|
+
|
|
+ u32 bitrate; /* Bitrate in bits per second */
|
|
+ u32 flags; /* Flags describing properties of the elementary
|
|
+ * stream.
|
|
+ */
|
|
+
|
|
+ u32 extradata_size; /* Size of the codec specific data */
|
|
+ u8 *extradata; /* Codec specific data */
|
|
+};
|
|
+
|
|
+/* Remote definition of an elementary stream format (MMAL_ES_FORMAT_T) */
|
|
+struct mmal_es_format {
|
|
+ u32 type; /* enum mmal_es_type */
|
|
+
|
|
+ u32 encoding; /* FourCC specifying encoding of the elementary
|
|
+ * stream.
|
|
+ */
|
|
+ u32 encoding_variant; /* FourCC specifying the specific
|
|
+ * encoding variant of the elementary
|
|
+ * stream.
|
|
+ */
|
|
+
|
|
+ u32 es; /* Type specific
|
|
+ * information for the
|
|
+ * elementary stream
|
|
+ */
|
|
+
|
|
+ u32 bitrate; /* Bitrate in bits per second */
|
|
+ u32 flags; /* Flags describing properties of the elementary
|
|
+ * stream.
|
|
+ */
|
|
+
|
|
+ u32 extradata_size; /* Size of the codec specific data */
|
|
+ u32 extradata; /* Codec specific data */
|
|
+};
|
|
+
|
|
+#endif /* MMAL_MSG_FORMAT_H */
|
|
--- /dev/null
|
|
+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-msg-port.h
|
|
@@ -0,0 +1,109 @@
|
|
+/* SPDX-License-Identifier: GPL-2.0 */
|
|
+/*
|
|
+ * Broadcom BM2835 V4L2 driver
|
|
+ *
|
|
+ * Copyright © 2013 Raspberry Pi (Trading) Ltd.
|
|
+ *
|
|
+ * Authors: Vincent Sanders @ Collabora
|
|
+ * Dave Stevenson @ Broadcom
|
|
+ * (now dave.stevenson@raspberrypi.org)
|
|
+ * Simon Mellor @ Broadcom
|
|
+ * Luke Diamand @ Broadcom
|
|
+ */
|
|
+
|
|
+/* MMAL_PORT_TYPE_T */
|
|
+enum mmal_port_type {
|
|
+ MMAL_PORT_TYPE_UNKNOWN = 0, /* Unknown port type */
|
|
+ MMAL_PORT_TYPE_CONTROL, /* Control port */
|
|
+ MMAL_PORT_TYPE_INPUT, /* Input port */
|
|
+ MMAL_PORT_TYPE_OUTPUT, /* Output port */
|
|
+ MMAL_PORT_TYPE_CLOCK, /* Clock port */
|
|
+};
|
|
+
|
|
+/* The port is pass-through and doesn't need buffer headers allocated */
|
|
+#define MMAL_PORT_CAPABILITY_PASSTHROUGH 0x01
|
|
+/*
|
|
+ *The port wants to allocate the buffer payloads.
|
|
+ * This signals a preference that payload allocation should be done
|
|
+ * on this port for efficiency reasons.
|
|
+ */
|
|
+#define MMAL_PORT_CAPABILITY_ALLOCATION 0x02
|
|
+/*
|
|
+ * The port supports format change events.
|
|
+ * This applies to input ports and is used to let the client know
|
|
+ * whether the port supports being reconfigured via a format
|
|
+ * change event (i.e. without having to disable the port).
|
|
+ */
|
|
+#define MMAL_PORT_CAPABILITY_SUPPORTS_EVENT_FORMAT_CHANGE 0x04
|
|
+
|
|
+/*
|
|
+ * mmal port structure (MMAL_PORT_T)
|
|
+ *
|
|
+ * most elements are informational only, the pointer values for
|
|
+ * interogation messages are generally provided as additional
|
|
+ * structures within the message. When used to set values only the
|
|
+ * buffer_num, buffer_size and userdata parameters are writable.
|
|
+ */
|
|
+struct mmal_port {
|
|
+ u32 priv; /* Private member used by the framework */
|
|
+ u32 name; /* Port name. Used for debugging purposes (RO) */
|
|
+
|
|
+ u32 type; /* Type of the port (RO) enum mmal_port_type */
|
|
+ u16 index; /* Index of the port in its type list (RO) */
|
|
+ u16 index_all; /* Index of the port in the list of all ports (RO) */
|
|
+
|
|
+ u32 is_enabled; /* Indicates whether the port is enabled or not (RO) */
|
|
+ u32 format; /* Format of the elementary stream */
|
|
+
|
|
+ u32 buffer_num_min; /* Minimum number of buffers the port
|
|
+ * requires (RO). This is set by the
|
|
+ * component.
|
|
+ */
|
|
+
|
|
+ u32 buffer_size_min; /* Minimum size of buffers the port
|
|
+ * requires (RO). This is set by the
|
|
+ * component.
|
|
+ */
|
|
+
|
|
+ u32 buffer_alignment_min;/* Minimum alignment requirement for
|
|
+ * the buffers (RO). A value of
|
|
+ * zero means no special alignment
|
|
+ * requirements. This is set by the
|
|
+ * component.
|
|
+ */
|
|
+
|
|
+ u32 buffer_num_recommended; /* Number of buffers the port
|
|
+ * recommends for optimal
|
|
+ * performance (RO). A value of
|
|
+ * zero means no special
|
|
+ * recommendation. This is set
|
|
+ * by the component.
|
|
+ */
|
|
+
|
|
+ u32 buffer_size_recommended; /* Size of buffers the port
|
|
+ * recommends for optimal
|
|
+ * performance (RO). A value of
|
|
+ * zero means no special
|
|
+ * recommendation. This is set
|
|
+ * by the component.
|
|
+ */
|
|
+
|
|
+ u32 buffer_num; /* Actual number of buffers the port will use.
|
|
+ * This is set by the client.
|
|
+ */
|
|
+
|
|
+ u32 buffer_size; /* Actual maximum size of the buffers that
|
|
+ * will be sent to the port. This is set by
|
|
+ * the client.
|
|
+ */
|
|
+
|
|
+ u32 component; /* Component this port belongs to (Read Only) */
|
|
+
|
|
+ u32 userdata; /* Field reserved for use by the client */
|
|
+
|
|
+ u32 capabilities; /* Flags describing the capabilities of a
|
|
+ * port (RO). Bitwise combination of \ref
|
|
+ * portcapabilities "Port capabilities"
|
|
+ * values.
|
|
+ */
|
|
+};
|
|
--- /dev/null
|
|
+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-msg.h
|
|
@@ -0,0 +1,406 @@
|
|
+/* SPDX-License-Identifier: GPL-2.0 */
|
|
+/*
|
|
+ * Broadcom BM2835 V4L2 driver
|
|
+ *
|
|
+ * Copyright © 2013 Raspberry Pi (Trading) Ltd.
|
|
+ *
|
|
+ * Authors: Vincent Sanders @ Collabora
|
|
+ * Dave Stevenson @ Broadcom
|
|
+ * (now dave.stevenson@raspberrypi.org)
|
|
+ * Simon Mellor @ Broadcom
|
|
+ * Luke Diamand @ Broadcom
|
|
+ */
|
|
+
|
|
+/*
|
|
+ * all the data structures which serialise the MMAL protocol. note
|
|
+ * these are directly mapped onto the recived message data.
|
|
+ *
|
|
+ * BEWARE: They seem to *assume* pointers are u32 and that there is no
|
|
+ * structure padding!
|
|
+ *
|
|
+ * NOTE: this implementation uses kernel types to ensure sizes. Rather
|
|
+ * than assigning values to enums to force their size the
|
|
+ * implementation uses fixed size types and not the enums (though the
|
|
+ * comments have the actual enum type
|
|
+ */
|
|
+#ifndef MMAL_MSG_H
|
|
+#define MMAL_MSG_H
|
|
+
|
|
+#define VC_MMAL_VER 15
|
|
+#define VC_MMAL_MIN_VER 10
|
|
+#define VC_MMAL_SERVER_NAME MAKE_FOURCC("mmal")
|
|
+
|
|
+/* max total message size is 512 bytes */
|
|
+#define MMAL_MSG_MAX_SIZE 512
|
|
+/* with six 32bit header elements max payload is therefore 488 bytes */
|
|
+#define MMAL_MSG_MAX_PAYLOAD 488
|
|
+
|
|
+#include "mmal-msg-common.h"
|
|
+#include "mmal-msg-format.h"
|
|
+#include "mmal-msg-port.h"
|
|
+
|
|
+enum mmal_msg_type {
|
|
+ MMAL_MSG_TYPE_QUIT = 1,
|
|
+ MMAL_MSG_TYPE_SERVICE_CLOSED,
|
|
+ MMAL_MSG_TYPE_GET_VERSION,
|
|
+ MMAL_MSG_TYPE_COMPONENT_CREATE,
|
|
+ MMAL_MSG_TYPE_COMPONENT_DESTROY, /* 5 */
|
|
+ MMAL_MSG_TYPE_COMPONENT_ENABLE,
|
|
+ MMAL_MSG_TYPE_COMPONENT_DISABLE,
|
|
+ MMAL_MSG_TYPE_PORT_INFO_GET,
|
|
+ MMAL_MSG_TYPE_PORT_INFO_SET,
|
|
+ MMAL_MSG_TYPE_PORT_ACTION, /* 10 */
|
|
+ MMAL_MSG_TYPE_BUFFER_FROM_HOST,
|
|
+ MMAL_MSG_TYPE_BUFFER_TO_HOST,
|
|
+ MMAL_MSG_TYPE_GET_STATS,
|
|
+ MMAL_MSG_TYPE_PORT_PARAMETER_SET,
|
|
+ MMAL_MSG_TYPE_PORT_PARAMETER_GET, /* 15 */
|
|
+ MMAL_MSG_TYPE_EVENT_TO_HOST,
|
|
+ MMAL_MSG_TYPE_GET_CORE_STATS_FOR_PORT,
|
|
+ MMAL_MSG_TYPE_OPAQUE_ALLOCATOR,
|
|
+ MMAL_MSG_TYPE_CONSUME_MEM,
|
|
+ MMAL_MSG_TYPE_LMK, /* 20 */
|
|
+ MMAL_MSG_TYPE_OPAQUE_ALLOCATOR_DESC,
|
|
+ MMAL_MSG_TYPE_DRM_GET_LHS32,
|
|
+ MMAL_MSG_TYPE_DRM_GET_TIME,
|
|
+ MMAL_MSG_TYPE_BUFFER_FROM_HOST_ZEROLEN,
|
|
+ MMAL_MSG_TYPE_PORT_FLUSH, /* 25 */
|
|
+ MMAL_MSG_TYPE_HOST_LOG,
|
|
+ MMAL_MSG_TYPE_MSG_LAST
|
|
+};
|
|
+
|
|
+/* port action request messages differ depending on the action type */
|
|
+enum mmal_msg_port_action_type {
|
|
+ MMAL_MSG_PORT_ACTION_TYPE_UNKNOWN = 0, /* Unknown action */
|
|
+ MMAL_MSG_PORT_ACTION_TYPE_ENABLE, /* Enable a port */
|
|
+ MMAL_MSG_PORT_ACTION_TYPE_DISABLE, /* Disable a port */
|
|
+ MMAL_MSG_PORT_ACTION_TYPE_FLUSH, /* Flush a port */
|
|
+ MMAL_MSG_PORT_ACTION_TYPE_CONNECT, /* Connect ports */
|
|
+ MMAL_MSG_PORT_ACTION_TYPE_DISCONNECT, /* Disconnect ports */
|
|
+ MMAL_MSG_PORT_ACTION_TYPE_SET_REQUIREMENTS, /* Set buffer requirements*/
|
|
+};
|
|
+
|
|
+struct mmal_msg_header {
|
|
+ u32 magic;
|
|
+ u32 type; /* enum mmal_msg_type */
|
|
+
|
|
+ /* Opaque handle to the control service */
|
|
+ u32 control_service;
|
|
+
|
|
+ u32 context; /* a u32 per message context */
|
|
+ u32 status; /* The status of the vchiq operation */
|
|
+ u32 padding;
|
|
+};
|
|
+
|
|
+/* Send from VC to host to report version */
|
|
+struct mmal_msg_version {
|
|
+ u32 flags;
|
|
+ u32 major;
|
|
+ u32 minor;
|
|
+ u32 minimum;
|
|
+};
|
|
+
|
|
+/* request to VC to create component */
|
|
+struct mmal_msg_component_create {
|
|
+ u32 client_component; /* component context */
|
|
+ char name[128];
|
|
+ u32 pid; /* For debug */
|
|
+};
|
|
+
|
|
+/* reply from VC to component creation request */
|
|
+struct mmal_msg_component_create_reply {
|
|
+ u32 status; /* enum mmal_msg_status - how does this differ to
|
|
+ * the one in the header?
|
|
+ */
|
|
+ u32 component_handle; /* VideoCore handle for component */
|
|
+ u32 input_num; /* Number of input ports */
|
|
+ u32 output_num; /* Number of output ports */
|
|
+ u32 clock_num; /* Number of clock ports */
|
|
+};
|
|
+
|
|
+/* request to VC to destroy a component */
|
|
+struct mmal_msg_component_destroy {
|
|
+ u32 component_handle;
|
|
+};
|
|
+
|
|
+struct mmal_msg_component_destroy_reply {
|
|
+ u32 status; /* The component destruction status */
|
|
+};
|
|
+
|
|
+/* request and reply to VC to enable a component */
|
|
+struct mmal_msg_component_enable {
|
|
+ u32 component_handle;
|
|
+};
|
|
+
|
|
+struct mmal_msg_component_enable_reply {
|
|
+ u32 status; /* The component enable status */
|
|
+};
|
|
+
|
|
+/* request and reply to VC to disable a component */
|
|
+struct mmal_msg_component_disable {
|
|
+ u32 component_handle;
|
|
+};
|
|
+
|
|
+struct mmal_msg_component_disable_reply {
|
|
+ u32 status; /* The component disable status */
|
|
+};
|
|
+
|
|
+/* request to VC to get port information */
|
|
+struct mmal_msg_port_info_get {
|
|
+ u32 component_handle; /* component handle port is associated with */
|
|
+ u32 port_type; /* enum mmal_msg_port_type */
|
|
+ u32 index; /* port index to query */
|
|
+};
|
|
+
|
|
+/* reply from VC to get port info request */
|
|
+struct mmal_msg_port_info_get_reply {
|
|
+ u32 status; /* enum mmal_msg_status */
|
|
+ u32 component_handle; /* component handle port is associated with */
|
|
+ u32 port_type; /* enum mmal_msg_port_type */
|
|
+ u32 port_index; /* port indexed in query */
|
|
+ s32 found; /* unused */
|
|
+ u32 port_handle; /* Handle to use for this port */
|
|
+ struct mmal_port port;
|
|
+ struct mmal_es_format format; /* elementary stream format */
|
|
+ union mmal_es_specific_format es; /* es type specific data */
|
|
+ u8 extradata[MMAL_FORMAT_EXTRADATA_MAX_SIZE]; /* es extra data */
|
|
+};
|
|
+
|
|
+/* request to VC to set port information */
|
|
+struct mmal_msg_port_info_set {
|
|
+ u32 component_handle;
|
|
+ u32 port_type; /* enum mmal_msg_port_type */
|
|
+ u32 port_index; /* port indexed in query */
|
|
+ struct mmal_port port;
|
|
+ struct mmal_es_format format;
|
|
+ union mmal_es_specific_format es;
|
|
+ u8 extradata[MMAL_FORMAT_EXTRADATA_MAX_SIZE];
|
|
+};
|
|
+
|
|
+/* reply from VC to port info set request */
|
|
+struct mmal_msg_port_info_set_reply {
|
|
+ u32 status;
|
|
+ u32 component_handle; /* component handle port is associated with */
|
|
+ u32 port_type; /* enum mmal_msg_port_type */
|
|
+ u32 index; /* port indexed in query */
|
|
+ s32 found; /* unused */
|
|
+ u32 port_handle; /* Handle to use for this port */
|
|
+ struct mmal_port port;
|
|
+ struct mmal_es_format format;
|
|
+ union mmal_es_specific_format es;
|
|
+ u8 extradata[MMAL_FORMAT_EXTRADATA_MAX_SIZE];
|
|
+};
|
|
+
|
|
+/* port action requests that take a mmal_port as a parameter */
|
|
+struct mmal_msg_port_action_port {
|
|
+ u32 component_handle;
|
|
+ u32 port_handle;
|
|
+ u32 action; /* enum mmal_msg_port_action_type */
|
|
+ struct mmal_port port;
|
|
+};
|
|
+
|
|
+/* port action requests that take handles as a parameter */
|
|
+struct mmal_msg_port_action_handle {
|
|
+ u32 component_handle;
|
|
+ u32 port_handle;
|
|
+ u32 action; /* enum mmal_msg_port_action_type */
|
|
+ u32 connect_component_handle;
|
|
+ u32 connect_port_handle;
|
|
+};
|
|
+
|
|
+struct mmal_msg_port_action_reply {
|
|
+ u32 status; /* The port action operation status */
|
|
+};
|
|
+
|
|
+/* MMAL buffer transfer */
|
|
+
|
|
+/* Size of space reserved in a buffer message for short messages. */
|
|
+#define MMAL_VC_SHORT_DATA 128
|
|
+
|
|
+/* Signals that the current payload is the end of the stream of data */
|
|
+#define MMAL_BUFFER_HEADER_FLAG_EOS BIT(0)
|
|
+/* Signals that the start of the current payload starts a frame */
|
|
+#define MMAL_BUFFER_HEADER_FLAG_FRAME_START BIT(1)
|
|
+/* Signals that the end of the current payload ends a frame */
|
|
+#define MMAL_BUFFER_HEADER_FLAG_FRAME_END BIT(2)
|
|
+/* Signals that the current payload contains only complete frames (>1) */
|
|
+#define MMAL_BUFFER_HEADER_FLAG_FRAME \
|
|
+ (MMAL_BUFFER_HEADER_FLAG_FRAME_START | \
|
|
+ MMAL_BUFFER_HEADER_FLAG_FRAME_END)
|
|
+/* Signals that the current payload is a keyframe (i.e. self decodable) */
|
|
+#define MMAL_BUFFER_HEADER_FLAG_KEYFRAME BIT(3)
|
|
+/*
|
|
+ * Signals a discontinuity in the stream of data (e.g. after a seek).
|
|
+ * Can be used for instance by a decoder to reset its state
|
|
+ */
|
|
+#define MMAL_BUFFER_HEADER_FLAG_DISCONTINUITY BIT(4)
|
|
+/*
|
|
+ * Signals a buffer containing some kind of config data for the component
|
|
+ * (e.g. codec config data)
|
|
+ */
|
|
+#define MMAL_BUFFER_HEADER_FLAG_CONFIG BIT(5)
|
|
+/* Signals an encrypted payload */
|
|
+#define MMAL_BUFFER_HEADER_FLAG_ENCRYPTED BIT(6)
|
|
+/* Signals a buffer containing side information */
|
|
+#define MMAL_BUFFER_HEADER_FLAG_CODECSIDEINFO BIT(7)
|
|
+/*
|
|
+ * Signals a buffer which is the snapshot/postview image from a stills
|
|
+ * capture
|
|
+ */
|
|
+#define MMAL_BUFFER_HEADER_FLAGS_SNAPSHOT BIT(8)
|
|
+/* Signals a buffer which contains data known to be corrupted */
|
|
+#define MMAL_BUFFER_HEADER_FLAG_CORRUPTED BIT(9)
|
|
+/* Signals that a buffer failed to be transmitted */
|
|
+#define MMAL_BUFFER_HEADER_FLAG_TRANSMISSION_FAILED BIT(10)
|
|
+
|
|
+struct mmal_driver_buffer {
|
|
+ u32 magic;
|
|
+ u32 component_handle;
|
|
+ u32 port_handle;
|
|
+ u32 client_context;
|
|
+};
|
|
+
|
|
+/* buffer header */
|
|
+struct mmal_buffer_header {
|
|
+ u32 next; /* next header */
|
|
+ u32 priv; /* framework private data */
|
|
+ u32 cmd;
|
|
+ u32 data;
|
|
+ u32 alloc_size;
|
|
+ u32 length;
|
|
+ u32 offset;
|
|
+ u32 flags;
|
|
+ s64 pts;
|
|
+ s64 dts;
|
|
+ u32 type;
|
|
+ u32 user_data;
|
|
+};
|
|
+
|
|
+struct mmal_buffer_header_type_specific {
|
|
+ union {
|
|
+ struct {
|
|
+ u32 planes;
|
|
+ u32 offset[4];
|
|
+ u32 pitch[4];
|
|
+ u32 flags;
|
|
+ } video;
|
|
+ } u;
|
|
+};
|
|
+
|
|
+struct mmal_msg_buffer_from_host {
|
|
+ /*
|
|
+ *The front 32 bytes of the buffer header are copied
|
|
+ * back to us in the reply to allow for context. This
|
|
+ * area is used to store two mmal_driver_buffer structures to
|
|
+ * allow for multiple concurrent service users.
|
|
+ */
|
|
+ /* control data */
|
|
+ struct mmal_driver_buffer drvbuf;
|
|
+
|
|
+ /* referenced control data for passthrough buffer management */
|
|
+ struct mmal_driver_buffer drvbuf_ref;
|
|
+ struct mmal_buffer_header buffer_header; /* buffer header itself */
|
|
+ struct mmal_buffer_header_type_specific buffer_header_type_specific;
|
|
+ s32 is_zero_copy;
|
|
+ s32 has_reference;
|
|
+
|
|
+ /* allows short data to be xfered in control message */
|
|
+ u32 payload_in_message;
|
|
+ u8 short_data[MMAL_VC_SHORT_DATA];
|
|
+};
|
|
+
|
|
+/* port parameter setting */
|
|
+
|
|
+#define MMAL_WORKER_PORT_PARAMETER_SPACE 96
|
|
+
|
|
+struct mmal_msg_port_parameter_set {
|
|
+ u32 component_handle; /* component */
|
|
+ u32 port_handle; /* port */
|
|
+ u32 id; /* Parameter ID */
|
|
+ u32 size; /* Parameter size */
|
|
+ u32 value[MMAL_WORKER_PORT_PARAMETER_SPACE];
|
|
+};
|
|
+
|
|
+struct mmal_msg_port_parameter_set_reply {
|
|
+ u32 status; /* enum mmal_msg_status todo: how does this
|
|
+ * differ to the one in the header?
|
|
+ */
|
|
+};
|
|
+
|
|
+/* port parameter getting */
|
|
+
|
|
+struct mmal_msg_port_parameter_get {
|
|
+ u32 component_handle; /* component */
|
|
+ u32 port_handle; /* port */
|
|
+ u32 id; /* Parameter ID */
|
|
+ u32 size; /* Parameter size */
|
|
+};
|
|
+
|
|
+struct mmal_msg_port_parameter_get_reply {
|
|
+ u32 status; /* Status of mmal_port_parameter_get call */
|
|
+ u32 id; /* Parameter ID */
|
|
+ u32 size; /* Parameter size */
|
|
+ u32 value[MMAL_WORKER_PORT_PARAMETER_SPACE];
|
|
+};
|
|
+
|
|
+/* event messages */
|
|
+#define MMAL_WORKER_EVENT_SPACE 256
|
|
+
|
|
+struct mmal_msg_event_to_host {
|
|
+ u32 client_component; /* component context */
|
|
+
|
|
+ u32 port_type;
|
|
+ u32 port_num;
|
|
+
|
|
+ u32 cmd;
|
|
+ u32 length;
|
|
+ u8 data[MMAL_WORKER_EVENT_SPACE];
|
|
+ u32 delayed_buffer;
|
|
+};
|
|
+
|
|
+/* all mmal messages are serialised through this structure */
|
|
+struct mmal_msg {
|
|
+ /* header */
|
|
+ struct mmal_msg_header h;
|
|
+ /* payload */
|
|
+ union {
|
|
+ struct mmal_msg_version version;
|
|
+
|
|
+ struct mmal_msg_component_create component_create;
|
|
+ struct mmal_msg_component_create_reply component_create_reply;
|
|
+
|
|
+ struct mmal_msg_component_destroy component_destroy;
|
|
+ struct mmal_msg_component_destroy_reply component_destroy_reply;
|
|
+
|
|
+ struct mmal_msg_component_enable component_enable;
|
|
+ struct mmal_msg_component_enable_reply component_enable_reply;
|
|
+
|
|
+ struct mmal_msg_component_disable component_disable;
|
|
+ struct mmal_msg_component_disable_reply component_disable_reply;
|
|
+
|
|
+ struct mmal_msg_port_info_get port_info_get;
|
|
+ struct mmal_msg_port_info_get_reply port_info_get_reply;
|
|
+
|
|
+ struct mmal_msg_port_info_set port_info_set;
|
|
+ struct mmal_msg_port_info_set_reply port_info_set_reply;
|
|
+
|
|
+ struct mmal_msg_port_action_port port_action_port;
|
|
+ struct mmal_msg_port_action_handle port_action_handle;
|
|
+ struct mmal_msg_port_action_reply port_action_reply;
|
|
+
|
|
+ struct mmal_msg_buffer_from_host buffer_from_host;
|
|
+
|
|
+ struct mmal_msg_port_parameter_set port_parameter_set;
|
|
+ struct mmal_msg_port_parameter_set_reply
|
|
+ port_parameter_set_reply;
|
|
+ struct mmal_msg_port_parameter_get
|
|
+ port_parameter_get;
|
|
+ struct mmal_msg_port_parameter_get_reply
|
|
+ port_parameter_get_reply;
|
|
+
|
|
+ struct mmal_msg_event_to_host event_to_host;
|
|
+
|
|
+ u8 payload[MMAL_MSG_MAX_PAYLOAD];
|
|
+ } u;
|
|
+};
|
|
+#endif
|
|
--- /dev/null
|
|
+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-parameters.h
|
|
@@ -0,0 +1,755 @@
|
|
+/* SPDX-License-Identifier: GPL-2.0 */
|
|
+/*
|
|
+ * Broadcom BM2835 V4L2 driver
|
|
+ *
|
|
+ * Copyright © 2013 Raspberry Pi (Trading) Ltd.
|
|
+ *
|
|
+ * Authors: Vincent Sanders @ Collabora
|
|
+ * Dave Stevenson @ Broadcom
|
|
+ * (now dave.stevenson@raspberrypi.org)
|
|
+ * Simon Mellor @ Broadcom
|
|
+ * Luke Diamand @ Broadcom
|
|
+ */
|
|
+
|
|
+/* common parameters */
|
|
+
|
|
+/** @name Parameter groups
|
|
+ * Parameters are divided into groups, and then allocated sequentially within
|
|
+ * a group using an enum.
|
|
+ * @{
|
|
+ */
|
|
+
|
|
+#ifndef MMAL_PARAMETERS_H
|
|
+#define MMAL_PARAMETERS_H
|
|
+
|
|
+/** Common parameter ID group, used with many types of component. */
|
|
+#define MMAL_PARAMETER_GROUP_COMMON (0 << 16)
|
|
+/** Camera-specific parameter ID group. */
|
|
+#define MMAL_PARAMETER_GROUP_CAMERA (1 << 16)
|
|
+/** Video-specific parameter ID group. */
|
|
+#define MMAL_PARAMETER_GROUP_VIDEO (2 << 16)
|
|
+/** Audio-specific parameter ID group. */
|
|
+#define MMAL_PARAMETER_GROUP_AUDIO (3 << 16)
|
|
+/** Clock-specific parameter ID group. */
|
|
+#define MMAL_PARAMETER_GROUP_CLOCK (4 << 16)
|
|
+/** Miracast-specific parameter ID group. */
|
|
+#define MMAL_PARAMETER_GROUP_MIRACAST (5 << 16)
|
|
+
|
|
+/* Common parameters */
|
|
+enum mmal_parameter_common_type {
|
|
+ /**< Never a valid parameter ID */
|
|
+ MMAL_PARAMETER_UNUSED = MMAL_PARAMETER_GROUP_COMMON,
|
|
+
|
|
+ /**< MMAL_PARAMETER_ENCODING_T */
|
|
+ MMAL_PARAMETER_SUPPORTED_ENCODINGS,
|
|
+ /**< MMAL_PARAMETER_URI_T */
|
|
+ MMAL_PARAMETER_URI,
|
|
+ /** MMAL_PARAMETER_CHANGE_EVENT_REQUEST_T */
|
|
+ MMAL_PARAMETER_CHANGE_EVENT_REQUEST,
|
|
+ /** MMAL_PARAMETER_BOOLEAN_T */
|
|
+ MMAL_PARAMETER_ZERO_COPY,
|
|
+ /**< MMAL_PARAMETER_BUFFER_REQUIREMENTS_T */
|
|
+ MMAL_PARAMETER_BUFFER_REQUIREMENTS,
|
|
+ /**< MMAL_PARAMETER_STATISTICS_T */
|
|
+ MMAL_PARAMETER_STATISTICS,
|
|
+ /**< MMAL_PARAMETER_CORE_STATISTICS_T */
|
|
+ MMAL_PARAMETER_CORE_STATISTICS,
|
|
+ /**< MMAL_PARAMETER_MEM_USAGE_T */
|
|
+ MMAL_PARAMETER_MEM_USAGE,
|
|
+ /**< MMAL_PARAMETER_UINT32_T */
|
|
+ MMAL_PARAMETER_BUFFER_FLAG_FILTER,
|
|
+ /**< MMAL_PARAMETER_SEEK_T */
|
|
+ MMAL_PARAMETER_SEEK,
|
|
+ /**< MMAL_PARAMETER_BOOLEAN_T */
|
|
+ MMAL_PARAMETER_POWERMON_ENABLE,
|
|
+ /**< MMAL_PARAMETER_LOGGING_T */
|
|
+ MMAL_PARAMETER_LOGGING,
|
|
+ /**< MMAL_PARAMETER_UINT64_T */
|
|
+ MMAL_PARAMETER_SYSTEM_TIME,
|
|
+ /**< MMAL_PARAMETER_BOOLEAN_T */
|
|
+ MMAL_PARAMETER_NO_IMAGE_PADDING,
|
|
+};
|
|
+
|
|
+/* camera parameters */
|
|
+
|
|
+enum mmal_parameter_camera_type {
|
|
+ /* 0 */
|
|
+ /** @ref MMAL_PARAMETER_THUMBNAIL_CONFIG_T */
|
|
+ MMAL_PARAMETER_THUMBNAIL_CONFIGURATION =
|
|
+ MMAL_PARAMETER_GROUP_CAMERA,
|
|
+ /**< Unused? */
|
|
+ MMAL_PARAMETER_CAPTURE_QUALITY,
|
|
+ /**< @ref MMAL_PARAMETER_INT32_T */
|
|
+ MMAL_PARAMETER_ROTATION,
|
|
+ /**< @ref MMAL_PARAMETER_BOOLEAN_T */
|
|
+ MMAL_PARAMETER_EXIF_DISABLE,
|
|
+ /**< @ref MMAL_PARAMETER_EXIF_T */
|
|
+ MMAL_PARAMETER_EXIF,
|
|
+ /**< @ref MMAL_PARAM_AWBMODE_T */
|
|
+ MMAL_PARAMETER_AWB_MODE,
|
|
+ /**< @ref MMAL_PARAMETER_IMAGEFX_T */
|
|
+ MMAL_PARAMETER_IMAGE_EFFECT,
|
|
+ /**< @ref MMAL_PARAMETER_COLOURFX_T */
|
|
+ MMAL_PARAMETER_COLOUR_EFFECT,
|
|
+ /**< @ref MMAL_PARAMETER_FLICKERAVOID_T */
|
|
+ MMAL_PARAMETER_FLICKER_AVOID,
|
|
+ /**< @ref MMAL_PARAMETER_FLASH_T */
|
|
+ MMAL_PARAMETER_FLASH,
|
|
+ /**< @ref MMAL_PARAMETER_REDEYE_T */
|
|
+ MMAL_PARAMETER_REDEYE,
|
|
+ /**< @ref MMAL_PARAMETER_FOCUS_T */
|
|
+ MMAL_PARAMETER_FOCUS,
|
|
+ /**< Unused? */
|
|
+ MMAL_PARAMETER_FOCAL_LENGTHS,
|
|
+ /**< @ref MMAL_PARAMETER_INT32_T */
|
|
+ MMAL_PARAMETER_EXPOSURE_COMP,
|
|
+ /**< @ref MMAL_PARAMETER_SCALEFACTOR_T */
|
|
+ MMAL_PARAMETER_ZOOM,
|
|
+ /**< @ref MMAL_PARAMETER_MIRROR_T */
|
|
+ MMAL_PARAMETER_MIRROR,
|
|
+
|
|
+ /* 0x10 */
|
|
+ /**< @ref MMAL_PARAMETER_UINT32_T */
|
|
+ MMAL_PARAMETER_CAMERA_NUM,
|
|
+ /**< @ref MMAL_PARAMETER_BOOLEAN_T */
|
|
+ MMAL_PARAMETER_CAPTURE,
|
|
+ /**< @ref MMAL_PARAMETER_EXPOSUREMODE_T */
|
|
+ MMAL_PARAMETER_EXPOSURE_MODE,
|
|
+ /**< @ref MMAL_PARAMETER_EXPOSUREMETERINGMODE_T */
|
|
+ MMAL_PARAMETER_EXP_METERING_MODE,
|
|
+ /**< @ref MMAL_PARAMETER_FOCUS_STATUS_T */
|
|
+ MMAL_PARAMETER_FOCUS_STATUS,
|
|
+ /**< @ref MMAL_PARAMETER_CAMERA_CONFIG_T */
|
|
+ MMAL_PARAMETER_CAMERA_CONFIG,
|
|
+ /**< @ref MMAL_PARAMETER_CAPTURE_STATUS_T */
|
|
+ MMAL_PARAMETER_CAPTURE_STATUS,
|
|
+ /**< @ref MMAL_PARAMETER_FACE_TRACK_T */
|
|
+ MMAL_PARAMETER_FACE_TRACK,
|
|
+ /**< @ref MMAL_PARAMETER_BOOLEAN_T */
|
|
+ MMAL_PARAMETER_DRAW_BOX_FACES_AND_FOCUS,
|
|
+ /**< @ref MMAL_PARAMETER_UINT32_T */
|
|
+ MMAL_PARAMETER_JPEG_Q_FACTOR,
|
|
+ /**< @ref MMAL_PARAMETER_FRAME_RATE_T */
|
|
+ MMAL_PARAMETER_FRAME_RATE,
|
|
+ /**< @ref MMAL_PARAMETER_CAMERA_STC_MODE_T */
|
|
+ MMAL_PARAMETER_USE_STC,
|
|
+ /**< @ref MMAL_PARAMETER_CAMERA_INFO_T */
|
|
+ MMAL_PARAMETER_CAMERA_INFO,
|
|
+ /**< @ref MMAL_PARAMETER_BOOLEAN_T */
|
|
+ MMAL_PARAMETER_VIDEO_STABILISATION,
|
|
+ /**< @ref MMAL_PARAMETER_FACE_TRACK_RESULTS_T */
|
|
+ MMAL_PARAMETER_FACE_TRACK_RESULTS,
|
|
+ /**< @ref MMAL_PARAMETER_BOOLEAN_T */
|
|
+ MMAL_PARAMETER_ENABLE_RAW_CAPTURE,
|
|
+
|
|
+ /* 0x20 */
|
|
+ /**< @ref MMAL_PARAMETER_URI_T */
|
|
+ MMAL_PARAMETER_DPF_FILE,
|
|
+ /**< @ref MMAL_PARAMETER_BOOLEAN_T */
|
|
+ MMAL_PARAMETER_ENABLE_DPF_FILE,
|
|
+ /**< @ref MMAL_PARAMETER_BOOLEAN_T */
|
|
+ MMAL_PARAMETER_DPF_FAIL_IS_FATAL,
|
|
+ /**< @ref MMAL_PARAMETER_CAPTUREMODE_T */
|
|
+ MMAL_PARAMETER_CAPTURE_MODE,
|
|
+ /**< @ref MMAL_PARAMETER_FOCUS_REGIONS_T */
|
|
+ MMAL_PARAMETER_FOCUS_REGIONS,
|
|
+ /**< @ref MMAL_PARAMETER_INPUT_CROP_T */
|
|
+ MMAL_PARAMETER_INPUT_CROP,
|
|
+ /**< @ref MMAL_PARAMETER_SENSOR_INFORMATION_T */
|
|
+ MMAL_PARAMETER_SENSOR_INFORMATION,
|
|
+ /**< @ref MMAL_PARAMETER_FLASH_SELECT_T */
|
|
+ MMAL_PARAMETER_FLASH_SELECT,
|
|
+ /**< @ref MMAL_PARAMETER_FIELD_OF_VIEW_T */
|
|
+ MMAL_PARAMETER_FIELD_OF_VIEW,
|
|
+ /**< @ref MMAL_PARAMETER_BOOLEAN_T */
|
|
+ MMAL_PARAMETER_HIGH_DYNAMIC_RANGE,
|
|
+ /**< @ref MMAL_PARAMETER_DRC_T */
|
|
+ MMAL_PARAMETER_DYNAMIC_RANGE_COMPRESSION,
|
|
+ /**< @ref MMAL_PARAMETER_ALGORITHM_CONTROL_T */
|
|
+ MMAL_PARAMETER_ALGORITHM_CONTROL,
|
|
+ /**< @ref MMAL_PARAMETER_RATIONAL_T */
|
|
+ MMAL_PARAMETER_SHARPNESS,
|
|
+ /**< @ref MMAL_PARAMETER_RATIONAL_T */
|
|
+ MMAL_PARAMETER_CONTRAST,
|
|
+ /**< @ref MMAL_PARAMETER_RATIONAL_T */
|
|
+ MMAL_PARAMETER_BRIGHTNESS,
|
|
+ /**< @ref MMAL_PARAMETER_RATIONAL_T */
|
|
+ MMAL_PARAMETER_SATURATION,
|
|
+
|
|
+ /* 0x30 */
|
|
+ /**< @ref MMAL_PARAMETER_UINT32_T */
|
|
+ MMAL_PARAMETER_ISO,
|
|
+ /**< @ref MMAL_PARAMETER_BOOLEAN_T */
|
|
+ MMAL_PARAMETER_ANTISHAKE,
|
|
+ /** @ref MMAL_PARAMETER_IMAGEFX_PARAMETERS_T */
|
|
+ MMAL_PARAMETER_IMAGE_EFFECT_PARAMETERS,
|
|
+ /** @ref MMAL_PARAMETER_BOOLEAN_T */
|
|
+ MMAL_PARAMETER_CAMERA_BURST_CAPTURE,
|
|
+ /** @ref MMAL_PARAMETER_UINT32_T */
|
|
+ MMAL_PARAMETER_CAMERA_MIN_ISO,
|
|
+ /** @ref MMAL_PARAMETER_CAMERA_USE_CASE_T */
|
|
+ MMAL_PARAMETER_CAMERA_USE_CASE,
|
|
+ /**< @ref MMAL_PARAMETER_BOOLEAN_T */
|
|
+ MMAL_PARAMETER_CAPTURE_STATS_PASS,
|
|
+ /** @ref MMAL_PARAMETER_UINT32_T */
|
|
+ MMAL_PARAMETER_CAMERA_CUSTOM_SENSOR_CONFIG,
|
|
+ /** @ref MMAL_PARAMETER_BOOLEAN_T */
|
|
+ MMAL_PARAMETER_ENABLE_REGISTER_FILE,
|
|
+ /** @ref MMAL_PARAMETER_BOOLEAN_T */
|
|
+ MMAL_PARAMETER_REGISTER_FAIL_IS_FATAL,
|
|
+ /** @ref MMAL_PARAMETER_CONFIGFILE_T */
|
|
+ MMAL_PARAMETER_CONFIGFILE_REGISTERS,
|
|
+ /** @ref MMAL_PARAMETER_CONFIGFILE_CHUNK_T */
|
|
+ MMAL_PARAMETER_CONFIGFILE_CHUNK_REGISTERS,
|
|
+ /**< @ref MMAL_PARAMETER_BOOLEAN_T */
|
|
+ MMAL_PARAMETER_JPEG_ATTACH_LOG,
|
|
+ /**< @ref MMAL_PARAMETER_ZEROSHUTTERLAG_T */
|
|
+ MMAL_PARAMETER_ZERO_SHUTTER_LAG,
|
|
+ /**< @ref MMAL_PARAMETER_FPS_RANGE_T */
|
|
+ MMAL_PARAMETER_FPS_RANGE,
|
|
+ /**< @ref MMAL_PARAMETER_INT32_T */
|
|
+ MMAL_PARAMETER_CAPTURE_EXPOSURE_COMP,
|
|
+
|
|
+ /* 0x40 */
|
|
+ /**< @ref MMAL_PARAMETER_BOOLEAN_T */
|
|
+ MMAL_PARAMETER_SW_SHARPEN_DISABLE,
|
|
+ /**< @ref MMAL_PARAMETER_BOOLEAN_T */
|
|
+ MMAL_PARAMETER_FLASH_REQUIRED,
|
|
+ /**< @ref MMAL_PARAMETER_BOOLEAN_T */
|
|
+ MMAL_PARAMETER_SW_SATURATION_DISABLE,
|
|
+ /**< Takes a @ref MMAL_PARAMETER_UINT32_T */
|
|
+ MMAL_PARAMETER_SHUTTER_SPEED,
|
|
+ /**< Takes a @ref MMAL_PARAMETER_AWB_GAINS_T */
|
|
+ MMAL_PARAMETER_CUSTOM_AWB_GAINS,
|
|
+};
|
|
+
|
|
+struct mmal_parameter_rational {
|
|
+ s32 num; /**< Numerator */
|
|
+ s32 den; /**< Denominator */
|
|
+};
|
|
+
|
|
+enum mmal_parameter_camera_config_timestamp_mode {
|
|
+ MMAL_PARAM_TIMESTAMP_MODE_ZERO = 0, /* Always timestamp frames as 0 */
|
|
+ MMAL_PARAM_TIMESTAMP_MODE_RAW_STC, /* Use the raw STC value
|
|
+ * for the frame timestamp
|
|
+ */
|
|
+ MMAL_PARAM_TIMESTAMP_MODE_RESET_STC, /* Use the STC timestamp
|
|
+ * but subtract the
|
|
+ * timestamp of the first
|
|
+ * frame sent to give a
|
|
+ * zero based timestamp.
|
|
+ */
|
|
+};
|
|
+
|
|
+struct mmal_parameter_fps_range {
|
|
+ /**< Low end of the permitted framerate range */
|
|
+ struct mmal_parameter_rational fps_low;
|
|
+ /**< High end of the permitted framerate range */
|
|
+ struct mmal_parameter_rational fps_high;
|
|
+};
|
|
+
|
|
+/* camera configuration parameter */
|
|
+struct mmal_parameter_camera_config {
|
|
+ /* Parameters for setting up the image pools */
|
|
+ u32 max_stills_w; /* Max size of stills capture */
|
|
+ u32 max_stills_h;
|
|
+ u32 stills_yuv422; /* Allow YUV422 stills capture */
|
|
+ u32 one_shot_stills; /* Continuous or one shot stills captures. */
|
|
+
|
|
+ u32 max_preview_video_w; /* Max size of the preview or video
|
|
+ * capture frames
|
|
+ */
|
|
+ u32 max_preview_video_h;
|
|
+ u32 num_preview_video_frames;
|
|
+
|
|
+ /** Sets the height of the circular buffer for stills capture. */
|
|
+ u32 stills_capture_circular_buffer_height;
|
|
+
|
|
+ /** Allows preview/encode to resume as fast as possible after the stills
|
|
+ * input frame has been received, and then processes the still frame in
|
|
+ * the background whilst preview/encode has resumed.
|
|
+ * Actual mode is controlled by MMAL_PARAMETER_CAPTURE_MODE.
|
|
+ */
|
|
+ u32 fast_preview_resume;
|
|
+
|
|
+ /** Selects algorithm for timestamping frames if
|
|
+ * there is no clock component connected.
|
|
+ * enum mmal_parameter_camera_config_timestamp_mode
|
|
+ */
|
|
+ s32 use_stc_timestamp;
|
|
+};
|
|
+
|
|
+enum mmal_parameter_exposuremode {
|
|
+ MMAL_PARAM_EXPOSUREMODE_OFF,
|
|
+ MMAL_PARAM_EXPOSUREMODE_AUTO,
|
|
+ MMAL_PARAM_EXPOSUREMODE_NIGHT,
|
|
+ MMAL_PARAM_EXPOSUREMODE_NIGHTPREVIEW,
|
|
+ MMAL_PARAM_EXPOSUREMODE_BACKLIGHT,
|
|
+ MMAL_PARAM_EXPOSUREMODE_SPOTLIGHT,
|
|
+ MMAL_PARAM_EXPOSUREMODE_SPORTS,
|
|
+ MMAL_PARAM_EXPOSUREMODE_SNOW,
|
|
+ MMAL_PARAM_EXPOSUREMODE_BEACH,
|
|
+ MMAL_PARAM_EXPOSUREMODE_VERYLONG,
|
|
+ MMAL_PARAM_EXPOSUREMODE_FIXEDFPS,
|
|
+ MMAL_PARAM_EXPOSUREMODE_ANTISHAKE,
|
|
+ MMAL_PARAM_EXPOSUREMODE_FIREWORKS,
|
|
+};
|
|
+
|
|
+enum mmal_parameter_exposuremeteringmode {
|
|
+ MMAL_PARAM_EXPOSUREMETERINGMODE_AVERAGE,
|
|
+ MMAL_PARAM_EXPOSUREMETERINGMODE_SPOT,
|
|
+ MMAL_PARAM_EXPOSUREMETERINGMODE_BACKLIT,
|
|
+ MMAL_PARAM_EXPOSUREMETERINGMODE_MATRIX,
|
|
+};
|
|
+
|
|
+enum mmal_parameter_awbmode {
|
|
+ MMAL_PARAM_AWBMODE_OFF,
|
|
+ MMAL_PARAM_AWBMODE_AUTO,
|
|
+ MMAL_PARAM_AWBMODE_SUNLIGHT,
|
|
+ MMAL_PARAM_AWBMODE_CLOUDY,
|
|
+ MMAL_PARAM_AWBMODE_SHADE,
|
|
+ MMAL_PARAM_AWBMODE_TUNGSTEN,
|
|
+ MMAL_PARAM_AWBMODE_FLUORESCENT,
|
|
+ MMAL_PARAM_AWBMODE_INCANDESCENT,
|
|
+ MMAL_PARAM_AWBMODE_FLASH,
|
|
+ MMAL_PARAM_AWBMODE_HORIZON,
|
|
+};
|
|
+
|
|
+enum mmal_parameter_imagefx {
|
|
+ MMAL_PARAM_IMAGEFX_NONE,
|
|
+ MMAL_PARAM_IMAGEFX_NEGATIVE,
|
|
+ MMAL_PARAM_IMAGEFX_SOLARIZE,
|
|
+ MMAL_PARAM_IMAGEFX_POSTERIZE,
|
|
+ MMAL_PARAM_IMAGEFX_WHITEBOARD,
|
|
+ MMAL_PARAM_IMAGEFX_BLACKBOARD,
|
|
+ MMAL_PARAM_IMAGEFX_SKETCH,
|
|
+ MMAL_PARAM_IMAGEFX_DENOISE,
|
|
+ MMAL_PARAM_IMAGEFX_EMBOSS,
|
|
+ MMAL_PARAM_IMAGEFX_OILPAINT,
|
|
+ MMAL_PARAM_IMAGEFX_HATCH,
|
|
+ MMAL_PARAM_IMAGEFX_GPEN,
|
|
+ MMAL_PARAM_IMAGEFX_PASTEL,
|
|
+ MMAL_PARAM_IMAGEFX_WATERCOLOUR,
|
|
+ MMAL_PARAM_IMAGEFX_FILM,
|
|
+ MMAL_PARAM_IMAGEFX_BLUR,
|
|
+ MMAL_PARAM_IMAGEFX_SATURATION,
|
|
+ MMAL_PARAM_IMAGEFX_COLOURSWAP,
|
|
+ MMAL_PARAM_IMAGEFX_WASHEDOUT,
|
|
+ MMAL_PARAM_IMAGEFX_POSTERISE,
|
|
+ MMAL_PARAM_IMAGEFX_COLOURPOINT,
|
|
+ MMAL_PARAM_IMAGEFX_COLOURBALANCE,
|
|
+ MMAL_PARAM_IMAGEFX_CARTOON,
|
|
+};
|
|
+
|
|
+enum MMAL_PARAM_FLICKERAVOID_T {
|
|
+ MMAL_PARAM_FLICKERAVOID_OFF,
|
|
+ MMAL_PARAM_FLICKERAVOID_AUTO,
|
|
+ MMAL_PARAM_FLICKERAVOID_50HZ,
|
|
+ MMAL_PARAM_FLICKERAVOID_60HZ,
|
|
+ MMAL_PARAM_FLICKERAVOID_MAX = 0x7FFFFFFF
|
|
+};
|
|
+
|
|
+struct mmal_parameter_awbgains {
|
|
+ struct mmal_parameter_rational r_gain; /**< Red gain */
|
|
+ struct mmal_parameter_rational b_gain; /**< Blue gain */
|
|
+};
|
|
+
|
|
+/** Manner of video rate control */
|
|
+enum mmal_parameter_rate_control_mode {
|
|
+ MMAL_VIDEO_RATECONTROL_DEFAULT,
|
|
+ MMAL_VIDEO_RATECONTROL_VARIABLE,
|
|
+ MMAL_VIDEO_RATECONTROL_CONSTANT,
|
|
+ MMAL_VIDEO_RATECONTROL_VARIABLE_SKIP_FRAMES,
|
|
+ MMAL_VIDEO_RATECONTROL_CONSTANT_SKIP_FRAMES
|
|
+};
|
|
+
|
|
+enum mmal_video_profile {
|
|
+ MMAL_VIDEO_PROFILE_H263_BASELINE,
|
|
+ MMAL_VIDEO_PROFILE_H263_H320CODING,
|
|
+ MMAL_VIDEO_PROFILE_H263_BACKWARDCOMPATIBLE,
|
|
+ MMAL_VIDEO_PROFILE_H263_ISWV2,
|
|
+ MMAL_VIDEO_PROFILE_H263_ISWV3,
|
|
+ MMAL_VIDEO_PROFILE_H263_HIGHCOMPRESSION,
|
|
+ MMAL_VIDEO_PROFILE_H263_INTERNET,
|
|
+ MMAL_VIDEO_PROFILE_H263_INTERLACE,
|
|
+ MMAL_VIDEO_PROFILE_H263_HIGHLATENCY,
|
|
+ MMAL_VIDEO_PROFILE_MP4V_SIMPLE,
|
|
+ MMAL_VIDEO_PROFILE_MP4V_SIMPLESCALABLE,
|
|
+ MMAL_VIDEO_PROFILE_MP4V_CORE,
|
|
+ MMAL_VIDEO_PROFILE_MP4V_MAIN,
|
|
+ MMAL_VIDEO_PROFILE_MP4V_NBIT,
|
|
+ MMAL_VIDEO_PROFILE_MP4V_SCALABLETEXTURE,
|
|
+ MMAL_VIDEO_PROFILE_MP4V_SIMPLEFACE,
|
|
+ MMAL_VIDEO_PROFILE_MP4V_SIMPLEFBA,
|
|
+ MMAL_VIDEO_PROFILE_MP4V_BASICANIMATED,
|
|
+ MMAL_VIDEO_PROFILE_MP4V_HYBRID,
|
|
+ MMAL_VIDEO_PROFILE_MP4V_ADVANCEDREALTIME,
|
|
+ MMAL_VIDEO_PROFILE_MP4V_CORESCALABLE,
|
|
+ MMAL_VIDEO_PROFILE_MP4V_ADVANCEDCODING,
|
|
+ MMAL_VIDEO_PROFILE_MP4V_ADVANCEDCORE,
|
|
+ MMAL_VIDEO_PROFILE_MP4V_ADVANCEDSCALABLE,
|
|
+ MMAL_VIDEO_PROFILE_MP4V_ADVANCEDSIMPLE,
|
|
+ MMAL_VIDEO_PROFILE_H264_BASELINE,
|
|
+ MMAL_VIDEO_PROFILE_H264_MAIN,
|
|
+ MMAL_VIDEO_PROFILE_H264_EXTENDED,
|
|
+ MMAL_VIDEO_PROFILE_H264_HIGH,
|
|
+ MMAL_VIDEO_PROFILE_H264_HIGH10,
|
|
+ MMAL_VIDEO_PROFILE_H264_HIGH422,
|
|
+ MMAL_VIDEO_PROFILE_H264_HIGH444,
|
|
+ MMAL_VIDEO_PROFILE_H264_CONSTRAINED_BASELINE,
|
|
+ MMAL_VIDEO_PROFILE_DUMMY = 0x7FFFFFFF
|
|
+};
|
|
+
|
|
+enum mmal_video_level {
|
|
+ MMAL_VIDEO_LEVEL_H263_10,
|
|
+ MMAL_VIDEO_LEVEL_H263_20,
|
|
+ MMAL_VIDEO_LEVEL_H263_30,
|
|
+ MMAL_VIDEO_LEVEL_H263_40,
|
|
+ MMAL_VIDEO_LEVEL_H263_45,
|
|
+ MMAL_VIDEO_LEVEL_H263_50,
|
|
+ MMAL_VIDEO_LEVEL_H263_60,
|
|
+ MMAL_VIDEO_LEVEL_H263_70,
|
|
+ MMAL_VIDEO_LEVEL_MP4V_0,
|
|
+ MMAL_VIDEO_LEVEL_MP4V_0b,
|
|
+ MMAL_VIDEO_LEVEL_MP4V_1,
|
|
+ MMAL_VIDEO_LEVEL_MP4V_2,
|
|
+ MMAL_VIDEO_LEVEL_MP4V_3,
|
|
+ MMAL_VIDEO_LEVEL_MP4V_4,
|
|
+ MMAL_VIDEO_LEVEL_MP4V_4a,
|
|
+ MMAL_VIDEO_LEVEL_MP4V_5,
|
|
+ MMAL_VIDEO_LEVEL_MP4V_6,
|
|
+ MMAL_VIDEO_LEVEL_H264_1,
|
|
+ MMAL_VIDEO_LEVEL_H264_1b,
|
|
+ MMAL_VIDEO_LEVEL_H264_11,
|
|
+ MMAL_VIDEO_LEVEL_H264_12,
|
|
+ MMAL_VIDEO_LEVEL_H264_13,
|
|
+ MMAL_VIDEO_LEVEL_H264_2,
|
|
+ MMAL_VIDEO_LEVEL_H264_21,
|
|
+ MMAL_VIDEO_LEVEL_H264_22,
|
|
+ MMAL_VIDEO_LEVEL_H264_3,
|
|
+ MMAL_VIDEO_LEVEL_H264_31,
|
|
+ MMAL_VIDEO_LEVEL_H264_32,
|
|
+ MMAL_VIDEO_LEVEL_H264_4,
|
|
+ MMAL_VIDEO_LEVEL_H264_41,
|
|
+ MMAL_VIDEO_LEVEL_H264_42,
|
|
+ MMAL_VIDEO_LEVEL_H264_5,
|
|
+ MMAL_VIDEO_LEVEL_H264_51,
|
|
+ MMAL_VIDEO_LEVEL_DUMMY = 0x7FFFFFFF
|
|
+};
|
|
+
|
|
+struct mmal_parameter_video_profile {
|
|
+ enum mmal_video_profile profile;
|
|
+ enum mmal_video_level level;
|
|
+};
|
|
+
|
|
+/* video parameters */
|
|
+
|
|
+enum mmal_parameter_video_type {
|
|
+ /** @ref MMAL_DISPLAYREGION_T */
|
|
+ MMAL_PARAMETER_DISPLAYREGION = MMAL_PARAMETER_GROUP_VIDEO,
|
|
+
|
|
+ /** @ref MMAL_PARAMETER_VIDEO_PROFILE_T */
|
|
+ MMAL_PARAMETER_SUPPORTED_PROFILES,
|
|
+
|
|
+ /** @ref MMAL_PARAMETER_VIDEO_PROFILE_T */
|
|
+ MMAL_PARAMETER_PROFILE,
|
|
+
|
|
+ /** @ref MMAL_PARAMETER_UINT32_T */
|
|
+ MMAL_PARAMETER_INTRAPERIOD,
|
|
+
|
|
+ /** @ref MMAL_PARAMETER_VIDEO_RATECONTROL_T */
|
|
+ MMAL_PARAMETER_RATECONTROL,
|
|
+
|
|
+ /** @ref MMAL_PARAMETER_VIDEO_NALUNITFORMAT_T */
|
|
+ MMAL_PARAMETER_NALUNITFORMAT,
|
|
+
|
|
+ /** @ref MMAL_PARAMETER_BOOLEAN_T */
|
|
+ MMAL_PARAMETER_MINIMISE_FRAGMENTATION,
|
|
+
|
|
+ /** @ref MMAL_PARAMETER_UINT32_T.
|
|
+ * Setting the value to zero resets to the default (one slice per
|
|
+ * frame).
|
|
+ */
|
|
+ MMAL_PARAMETER_MB_ROWS_PER_SLICE,
|
|
+
|
|
+ /** @ref MMAL_PARAMETER_VIDEO_LEVEL_EXTENSION_T */
|
|
+ MMAL_PARAMETER_VIDEO_LEVEL_EXTENSION,
|
|
+
|
|
+ /** @ref MMAL_PARAMETER_VIDEO_EEDE_ENABLE_T */
|
|
+ MMAL_PARAMETER_VIDEO_EEDE_ENABLE,
|
|
+
|
|
+ /** @ref MMAL_PARAMETER_VIDEO_EEDE_LOSSRATE_T */
|
|
+ MMAL_PARAMETER_VIDEO_EEDE_LOSSRATE,
|
|
+
|
|
+ /** @ref MMAL_PARAMETER_BOOLEAN_T. Request an I-frame. */
|
|
+ MMAL_PARAMETER_VIDEO_REQUEST_I_FRAME,
|
|
+ /** @ref MMAL_PARAMETER_VIDEO_INTRA_REFRESH_T */
|
|
+ MMAL_PARAMETER_VIDEO_INTRA_REFRESH,
|
|
+
|
|
+ /** @ref MMAL_PARAMETER_BOOLEAN_T. */
|
|
+ MMAL_PARAMETER_VIDEO_IMMUTABLE_INPUT,
|
|
+
|
|
+ /** @ref MMAL_PARAMETER_UINT32_T. Run-time bit rate control */
|
|
+ MMAL_PARAMETER_VIDEO_BIT_RATE,
|
|
+
|
|
+ /** @ref MMAL_PARAMETER_FRAME_RATE_T */
|
|
+ MMAL_PARAMETER_VIDEO_FRAME_RATE,
|
|
+
|
|
+ /** @ref MMAL_PARAMETER_UINT32_T. */
|
|
+ MMAL_PARAMETER_VIDEO_ENCODE_MIN_QUANT,
|
|
+
|
|
+ /** @ref MMAL_PARAMETER_UINT32_T. */
|
|
+ MMAL_PARAMETER_VIDEO_ENCODE_MAX_QUANT,
|
|
+
|
|
+ /** @ref MMAL_PARAMETER_VIDEO_ENCODE_RC_MODEL_T. */
|
|
+ MMAL_PARAMETER_VIDEO_ENCODE_RC_MODEL,
|
|
+
|
|
+ MMAL_PARAMETER_EXTRA_BUFFERS, /**< @ref MMAL_PARAMETER_UINT32_T. */
|
|
+ /** @ref MMAL_PARAMETER_UINT32_T.
|
|
+ * Changing this parameter from the default can reduce frame rate
|
|
+ * because image buffers need to be re-pitched.
|
|
+ */
|
|
+ MMAL_PARAMETER_VIDEO_ALIGN_HORIZ,
|
|
+
|
|
+ /** @ref MMAL_PARAMETER_UINT32_T.
|
|
+ * Changing this parameter from the default can reduce frame rate
|
|
+ * because image buffers need to be re-pitched.
|
|
+ */
|
|
+ MMAL_PARAMETER_VIDEO_ALIGN_VERT,
|
|
+
|
|
+ /** @ref MMAL_PARAMETER_BOOLEAN_T. */
|
|
+ MMAL_PARAMETER_VIDEO_DROPPABLE_PFRAMES,
|
|
+
|
|
+ /** @ref MMAL_PARAMETER_UINT32_T. */
|
|
+ MMAL_PARAMETER_VIDEO_ENCODE_INITIAL_QUANT,
|
|
+
|
|
+ /**< @ref MMAL_PARAMETER_UINT32_T. */
|
|
+ MMAL_PARAMETER_VIDEO_ENCODE_QP_P,
|
|
+
|
|
+ /**< @ref MMAL_PARAMETER_UINT32_T. */
|
|
+ MMAL_PARAMETER_VIDEO_ENCODE_RC_SLICE_DQUANT,
|
|
+
|
|
+ /** @ref MMAL_PARAMETER_UINT32_T */
|
|
+ MMAL_PARAMETER_VIDEO_ENCODE_FRAME_LIMIT_BITS,
|
|
+
|
|
+ /** @ref MMAL_PARAMETER_UINT32_T. */
|
|
+ MMAL_PARAMETER_VIDEO_ENCODE_PEAK_RATE,
|
|
+
|
|
+ /* H264 specific parameters */
|
|
+
|
|
+ /** @ref MMAL_PARAMETER_BOOLEAN_T. */
|
|
+ MMAL_PARAMETER_VIDEO_ENCODE_H264_DISABLE_CABAC,
|
|
+
|
|
+ /** @ref MMAL_PARAMETER_BOOLEAN_T. */
|
|
+ MMAL_PARAMETER_VIDEO_ENCODE_H264_LOW_LATENCY,
|
|
+
|
|
+ /** @ref MMAL_PARAMETER_BOOLEAN_T. */
|
|
+ MMAL_PARAMETER_VIDEO_ENCODE_H264_AU_DELIMITERS,
|
|
+
|
|
+ /** @ref MMAL_PARAMETER_UINT32_T. */
|
|
+ MMAL_PARAMETER_VIDEO_ENCODE_H264_DEBLOCK_IDC,
|
|
+
|
|
+ /** @ref MMAL_PARAMETER_VIDEO_ENCODER_H264_MB_INTRA_MODES_T. */
|
|
+ MMAL_PARAMETER_VIDEO_ENCODE_H264_MB_INTRA_MODE,
|
|
+
|
|
+ /** @ref MMAL_PARAMETER_BOOLEAN_T */
|
|
+ MMAL_PARAMETER_VIDEO_ENCODE_HEADER_ON_OPEN,
|
|
+
|
|
+ /** @ref MMAL_PARAMETER_BOOLEAN_T */
|
|
+ MMAL_PARAMETER_VIDEO_ENCODE_PRECODE_FOR_QP,
|
|
+
|
|
+ /** @ref MMAL_PARAMETER_VIDEO_DRM_INIT_INFO_T. */
|
|
+ MMAL_PARAMETER_VIDEO_DRM_INIT_INFO,
|
|
+
|
|
+ /** @ref MMAL_PARAMETER_BOOLEAN_T */
|
|
+ MMAL_PARAMETER_VIDEO_TIMESTAMP_FIFO,
|
|
+
|
|
+ /** @ref MMAL_PARAMETER_BOOLEAN_T */
|
|
+ MMAL_PARAMETER_VIDEO_DECODE_ERROR_CONCEALMENT,
|
|
+
|
|
+ /** @ref MMAL_PARAMETER_VIDEO_DRM_PROTECT_BUFFER_T. */
|
|
+ MMAL_PARAMETER_VIDEO_DRM_PROTECT_BUFFER,
|
|
+
|
|
+ /** @ref MMAL_PARAMETER_BYTES_T */
|
|
+ MMAL_PARAMETER_VIDEO_DECODE_CONFIG_VD3,
|
|
+
|
|
+ /**< @ref MMAL_PARAMETER_BOOLEAN_T */
|
|
+ MMAL_PARAMETER_VIDEO_ENCODE_H264_VCL_HRD_PARAMETERS,
|
|
+
|
|
+ /**< @ref MMAL_PARAMETER_BOOLEAN_T */
|
|
+ MMAL_PARAMETER_VIDEO_ENCODE_H264_LOW_DELAY_HRD_FLAG,
|
|
+
|
|
+ /**< @ref MMAL_PARAMETER_BOOLEAN_T */
|
|
+ MMAL_PARAMETER_VIDEO_ENCODE_INLINE_HEADER
|
|
+};
|
|
+
|
|
+/** Valid mirror modes */
|
|
+enum mmal_parameter_mirror {
|
|
+ MMAL_PARAM_MIRROR_NONE,
|
|
+ MMAL_PARAM_MIRROR_VERTICAL,
|
|
+ MMAL_PARAM_MIRROR_HORIZONTAL,
|
|
+ MMAL_PARAM_MIRROR_BOTH,
|
|
+};
|
|
+
|
|
+enum mmal_parameter_displaytransform {
|
|
+ MMAL_DISPLAY_ROT0 = 0,
|
|
+ MMAL_DISPLAY_MIRROR_ROT0 = 1,
|
|
+ MMAL_DISPLAY_MIRROR_ROT180 = 2,
|
|
+ MMAL_DISPLAY_ROT180 = 3,
|
|
+ MMAL_DISPLAY_MIRROR_ROT90 = 4,
|
|
+ MMAL_DISPLAY_ROT270 = 5,
|
|
+ MMAL_DISPLAY_ROT90 = 6,
|
|
+ MMAL_DISPLAY_MIRROR_ROT270 = 7,
|
|
+};
|
|
+
|
|
+enum mmal_parameter_displaymode {
|
|
+ MMAL_DISPLAY_MODE_FILL = 0,
|
|
+ MMAL_DISPLAY_MODE_LETTERBOX = 1,
|
|
+};
|
|
+
|
|
+enum mmal_parameter_displayset {
|
|
+ MMAL_DISPLAY_SET_NONE = 0,
|
|
+ MMAL_DISPLAY_SET_NUM = 1,
|
|
+ MMAL_DISPLAY_SET_FULLSCREEN = 2,
|
|
+ MMAL_DISPLAY_SET_TRANSFORM = 4,
|
|
+ MMAL_DISPLAY_SET_DEST_RECT = 8,
|
|
+ MMAL_DISPLAY_SET_SRC_RECT = 0x10,
|
|
+ MMAL_DISPLAY_SET_MODE = 0x20,
|
|
+ MMAL_DISPLAY_SET_PIXEL = 0x40,
|
|
+ MMAL_DISPLAY_SET_NOASPECT = 0x80,
|
|
+ MMAL_DISPLAY_SET_LAYER = 0x100,
|
|
+ MMAL_DISPLAY_SET_COPYPROTECT = 0x200,
|
|
+ MMAL_DISPLAY_SET_ALPHA = 0x400,
|
|
+};
|
|
+
|
|
+/* rectangle, used lots so it gets its own struct */
|
|
+struct vchiq_mmal_rect {
|
|
+ s32 x;
|
|
+ s32 y;
|
|
+ s32 width;
|
|
+ s32 height;
|
|
+};
|
|
+
|
|
+struct mmal_parameter_displayregion {
|
|
+ /** Bitfield that indicates which fields are set and should be
|
|
+ * used. All other fields will maintain their current value.
|
|
+ * \ref MMAL_DISPLAYSET_T defines the bits that can be
|
|
+ * combined.
|
|
+ */
|
|
+ u32 set;
|
|
+
|
|
+ /** Describes the display output device, with 0 typically
|
|
+ * being a directly connected LCD display. The actual values
|
|
+ * will depend on the hardware. Code using hard-wired numbers
|
|
+ * (e.g. 2) is certain to fail.
|
|
+ */
|
|
+
|
|
+ u32 display_num;
|
|
+ /** Indicates that we are using the full device screen area,
|
|
+ * rather than a window of the display. If zero, then
|
|
+ * dest_rect is used to specify a region of the display to
|
|
+ * use.
|
|
+ */
|
|
+
|
|
+ s32 fullscreen;
|
|
+ /** Indicates any rotation or flipping used to map frames onto
|
|
+ * the natural display orientation.
|
|
+ */
|
|
+ u32 transform; /* enum mmal_parameter_displaytransform */
|
|
+
|
|
+ /** Where to display the frame within the screen, if
|
|
+ * fullscreen is zero.
|
|
+ */
|
|
+ struct vchiq_mmal_rect dest_rect;
|
|
+
|
|
+ /** Indicates which area of the frame to display. If all
|
|
+ * values are zero, the whole frame will be used.
|
|
+ */
|
|
+ struct vchiq_mmal_rect src_rect;
|
|
+
|
|
+ /** If set to non-zero, indicates that any display scaling
|
|
+ * should disregard the aspect ratio of the frame region being
|
|
+ * displayed.
|
|
+ */
|
|
+ s32 noaspect;
|
|
+
|
|
+ /** Indicates how the image should be scaled to fit the
|
|
+ * display. \code MMAL_DISPLAY_MODE_FILL \endcode indicates
|
|
+ * that the image should fill the screen by potentially
|
|
+ * cropping the frames. Setting \code mode \endcode to \code
|
|
+ * MMAL_DISPLAY_MODE_LETTERBOX \endcode indicates that all the
|
|
+ * source region should be displayed and black bars added if
|
|
+ * necessary.
|
|
+ */
|
|
+ u32 mode; /* enum mmal_parameter_displaymode */
|
|
+
|
|
+ /** If non-zero, defines the width of a source pixel relative
|
|
+ * to \code pixel_y \endcode. If zero, then pixels default to
|
|
+ * being square.
|
|
+ */
|
|
+ u32 pixel_x;
|
|
+
|
|
+ /** If non-zero, defines the height of a source pixel relative
|
|
+ * to \code pixel_x \endcode. If zero, then pixels default to
|
|
+ * being square.
|
|
+ */
|
|
+ u32 pixel_y;
|
|
+
|
|
+ /** Sets the relative depth of the images, with greater values
|
|
+ * being in front of smaller values.
|
|
+ */
|
|
+ u32 layer;
|
|
+
|
|
+ /** Set to non-zero to ensure copy protection is used on
|
|
+ * output.
|
|
+ */
|
|
+ s32 copyprotect_required;
|
|
+
|
|
+ /** Level of opacity of the layer, where zero is fully
|
|
+ * transparent and 255 is fully opaque.
|
|
+ */
|
|
+ u32 alpha;
|
|
+};
|
|
+
|
|
+#define MMAL_MAX_IMAGEFX_PARAMETERS 5
|
|
+
|
|
+struct mmal_parameter_imagefx_parameters {
|
|
+ enum mmal_parameter_imagefx effect;
|
|
+ u32 num_effect_params;
|
|
+ u32 effect_parameter[MMAL_MAX_IMAGEFX_PARAMETERS];
|
|
+};
|
|
+
|
|
+#define MMAL_PARAMETER_CAMERA_INFO_MAX_CAMERAS 4
|
|
+#define MMAL_PARAMETER_CAMERA_INFO_MAX_FLASHES 2
|
|
+#define MMAL_PARAMETER_CAMERA_INFO_MAX_STR_LEN 16
|
|
+
|
|
+struct mmal_parameter_camera_info_camera_t {
|
|
+ u32 port_id;
|
|
+ u32 max_width;
|
|
+ u32 max_height;
|
|
+ u32 lens_present;
|
|
+ u8 camera_name[MMAL_PARAMETER_CAMERA_INFO_MAX_STR_LEN];
|
|
+};
|
|
+
|
|
+enum mmal_parameter_camera_info_flash_type_t {
|
|
+ /* Make values explicit to ensure they match values in config ini */
|
|
+ MMAL_PARAMETER_CAMERA_INFO_FLASH_TYPE_XENON = 0,
|
|
+ MMAL_PARAMETER_CAMERA_INFO_FLASH_TYPE_LED = 1,
|
|
+ MMAL_PARAMETER_CAMERA_INFO_FLASH_TYPE_OTHER = 2,
|
|
+ MMAL_PARAMETER_CAMERA_INFO_FLASH_TYPE_MAX = 0x7FFFFFFF
|
|
+};
|
|
+
|
|
+struct mmal_parameter_camera_info_flash_t {
|
|
+ enum mmal_parameter_camera_info_flash_type_t flash_type;
|
|
+};
|
|
+
|
|
+struct mmal_parameter_camera_info_t {
|
|
+ u32 num_cameras;
|
|
+ u32 num_flashes;
|
|
+ struct mmal_parameter_camera_info_camera_t
|
|
+ cameras[MMAL_PARAMETER_CAMERA_INFO_MAX_CAMERAS];
|
|
+ struct mmal_parameter_camera_info_flash_t
|
|
+ flashes[MMAL_PARAMETER_CAMERA_INFO_MAX_FLASHES];
|
|
+};
|
|
+
|
|
+#endif
|
|
--- /dev/null
|
|
+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h
|
|
@@ -0,0 +1,166 @@
|
|
+/* SPDX-License-Identifier: GPL-2.0 */
|
|
+/*
|
|
+ * Broadcom BM2835 V4L2 driver
|
|
+ *
|
|
+ * Copyright © 2013 Raspberry Pi (Trading) Ltd.
|
|
+ *
|
|
+ * Authors: Vincent Sanders @ Collabora
|
|
+ * Dave Stevenson @ Broadcom
|
|
+ * (now dave.stevenson@raspberrypi.org)
|
|
+ * Simon Mellor @ Broadcom
|
|
+ * Luke Diamand @ Broadcom
|
|
+ *
|
|
+ * MMAL interface to VCHIQ message passing
|
|
+ */
|
|
+
|
|
+#ifndef MMAL_VCHIQ_H
|
|
+#define MMAL_VCHIQ_H
|
|
+
|
|
+#include "mmal-msg-format.h"
|
|
+
|
|
+#define MAX_PORT_COUNT 4
|
|
+
|
|
+/* Maximum size of the format extradata. */
|
|
+#define MMAL_FORMAT_EXTRADATA_MAX_SIZE 128
|
|
+
|
|
+struct vchiq_mmal_instance;
|
|
+
|
|
+enum vchiq_mmal_es_type {
|
|
+ MMAL_ES_TYPE_UNKNOWN, /**< Unknown elementary stream type */
|
|
+ MMAL_ES_TYPE_CONTROL, /**< Elementary stream of control commands */
|
|
+ MMAL_ES_TYPE_AUDIO, /**< Audio elementary stream */
|
|
+ MMAL_ES_TYPE_VIDEO, /**< Video elementary stream */
|
|
+ MMAL_ES_TYPE_SUBPICTURE /**< Sub-picture elementary stream */
|
|
+};
|
|
+
|
|
+struct vchiq_mmal_port_buffer {
|
|
+ unsigned int num; /* number of buffers */
|
|
+ u32 size; /* size of buffers */
|
|
+ u32 alignment; /* alignment of buffers */
|
|
+};
|
|
+
|
|
+struct vchiq_mmal_port;
|
|
+
|
|
+typedef void (*vchiq_mmal_buffer_cb)(
|
|
+ struct vchiq_mmal_instance *instance,
|
|
+ struct vchiq_mmal_port *port,
|
|
+ int status, struct mmal_buffer *buffer,
|
|
+ unsigned long length, u32 mmal_flags, s64 dts, s64 pts);
|
|
+
|
|
+struct vchiq_mmal_port {
|
|
+ u32 enabled:1;
|
|
+ u32 handle;
|
|
+ u32 type; /* port type, cached to use on port info set */
|
|
+ u32 index; /* port index, cached to use on port info set */
|
|
+
|
|
+ /* component port belongs to, allows simple deref */
|
|
+ struct vchiq_mmal_component *component;
|
|
+
|
|
+ struct vchiq_mmal_port *connected; /* port connected to */
|
|
+
|
|
+ /* buffer info */
|
|
+ struct vchiq_mmal_port_buffer minimum_buffer;
|
|
+ struct vchiq_mmal_port_buffer recommended_buffer;
|
|
+ struct vchiq_mmal_port_buffer current_buffer;
|
|
+
|
|
+ /* stream format */
|
|
+ struct mmal_es_format_local format;
|
|
+ /* elementary stream format */
|
|
+ union mmal_es_specific_format es;
|
|
+
|
|
+ /* data buffers to fill */
|
|
+ struct list_head buffers;
|
|
+ /* lock to serialise adding and removing buffers from list */
|
|
+ spinlock_t slock;
|
|
+
|
|
+ /* Count of buffers the VPU has yet to return */
|
|
+ atomic_t buffers_with_vpu;
|
|
+ /* callback on buffer completion */
|
|
+ vchiq_mmal_buffer_cb buffer_cb;
|
|
+ /* callback context */
|
|
+ void *cb_ctx;
|
|
+};
|
|
+
|
|
+struct vchiq_mmal_component {
|
|
+ u32 enabled:1;
|
|
+ u32 handle; /* VideoCore handle for component */
|
|
+ u32 inputs; /* Number of input ports */
|
|
+ u32 outputs; /* Number of output ports */
|
|
+ u32 clocks; /* Number of clock ports */
|
|
+ struct vchiq_mmal_port control; /* control port */
|
|
+ struct vchiq_mmal_port input[MAX_PORT_COUNT]; /* input ports */
|
|
+ struct vchiq_mmal_port output[MAX_PORT_COUNT]; /* output ports */
|
|
+ struct vchiq_mmal_port clock[MAX_PORT_COUNT]; /* clock ports */
|
|
+};
|
|
+
|
|
+int vchiq_mmal_init(struct vchiq_mmal_instance **out_instance);
|
|
+int vchiq_mmal_finalise(struct vchiq_mmal_instance *instance);
|
|
+
|
|
+/* Initialise a mmal component and its ports
|
|
+ *
|
|
+ */
|
|
+int vchiq_mmal_component_init(
|
|
+ struct vchiq_mmal_instance *instance,
|
|
+ const char *name,
|
|
+ struct vchiq_mmal_component **component_out);
|
|
+
|
|
+int vchiq_mmal_component_finalise(
|
|
+ struct vchiq_mmal_instance *instance,
|
|
+ struct vchiq_mmal_component *component);
|
|
+
|
|
+int vchiq_mmal_component_enable(
|
|
+ struct vchiq_mmal_instance *instance,
|
|
+ struct vchiq_mmal_component *component);
|
|
+
|
|
+int vchiq_mmal_component_disable(
|
|
+ struct vchiq_mmal_instance *instance,
|
|
+ struct vchiq_mmal_component *component);
|
|
+
|
|
+/* enable a mmal port
|
|
+ *
|
|
+ * enables a port and if a buffer callback provided enque buffer
|
|
+ * headers as appropriate for the port.
|
|
+ */
|
|
+int vchiq_mmal_port_enable(
|
|
+ struct vchiq_mmal_instance *instance,
|
|
+ struct vchiq_mmal_port *port,
|
|
+ vchiq_mmal_buffer_cb buffer_cb);
|
|
+
|
|
+/* disable a port
|
|
+ *
|
|
+ * disable a port will dequeue any pending buffers
|
|
+ */
|
|
+int vchiq_mmal_port_disable(struct vchiq_mmal_instance *instance,
|
|
+ struct vchiq_mmal_port *port);
|
|
+
|
|
+int vchiq_mmal_port_parameter_set(struct vchiq_mmal_instance *instance,
|
|
+ struct vchiq_mmal_port *port,
|
|
+ u32 parameter,
|
|
+ void *value,
|
|
+ u32 value_size);
|
|
+
|
|
+int vchiq_mmal_port_parameter_get(struct vchiq_mmal_instance *instance,
|
|
+ struct vchiq_mmal_port *port,
|
|
+ u32 parameter,
|
|
+ void *value,
|
|
+ u32 *value_size);
|
|
+
|
|
+int vchiq_mmal_port_set_format(struct vchiq_mmal_instance *instance,
|
|
+ struct vchiq_mmal_port *port);
|
|
+
|
|
+int vchiq_mmal_port_connect_tunnel(struct vchiq_mmal_instance *instance,
|
|
+ struct vchiq_mmal_port *src,
|
|
+ struct vchiq_mmal_port *dst);
|
|
+
|
|
+int vchiq_mmal_version(struct vchiq_mmal_instance *instance,
|
|
+ u32 *major_out,
|
|
+ u32 *minor_out);
|
|
+
|
|
+int vchiq_mmal_submit_buffer(struct vchiq_mmal_instance *instance,
|
|
+ struct vchiq_mmal_port *port,
|
|
+ struct mmal_buffer *buf);
|
|
+
|
|
+int mmal_vchi_buffer_init(struct vchiq_mmal_instance *instance,
|
|
+ struct mmal_buffer *buf);
|
|
+int mmal_vchi_buffer_cleanup(struct mmal_buffer *buf);
|
|
+#endif /* MMAL_VCHIQ_H */
|