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.
281 lines
10 KiB
Diff
281 lines
10 KiB
Diff
5 years ago
|
From 862ee4fbd8c6b984f920b88908e33951e51134ca Mon Sep 17 00:00:00 2001
|
||
5 years ago
|
From: Dave Stevenson <dave.stevenson@raspberrypi.org>
|
||
|
Date: Mon, 24 Sep 2018 17:33:37 +0100
|
||
5 years ago
|
Subject: [PATCH] staging: mmal-vchiq: Make a mmal_buf struct for
|
||
5 years ago
|
passing parameters
|
||
|
|
||
|
The callback from vchi_mmal to the client was growing lots of extra
|
||
|
parameters. Consolidate them into a single struct instead of
|
||
|
growing the list further.
|
||
|
The struct is associated with the client buffer, therefore there
|
||
|
are various changes to setup various containers for the struct,
|
||
|
and pass the appropriate members.
|
||
|
|
||
|
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org>
|
||
|
---
|
||
|
.../bcm2835-camera/bcm2835-camera.c | 62 ++++++++++++-------
|
||
|
.../vc04_services/vchiq-mmal/mmal-common.h | 5 ++
|
||
|
.../vc04_services/vchiq-mmal/mmal-vchiq.c | 29 ++++++---
|
||
|
.../vc04_services/vchiq-mmal/mmal-vchiq.h | 3 +-
|
||
|
4 files changed, 64 insertions(+), 35 deletions(-)
|
||
|
|
||
|
--- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
|
||
|
+++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
|
||
|
@@ -72,6 +72,12 @@ static const struct v4l2_fract
|
||
|
tpf_max = {.numerator = 1, .denominator = FPS_MIN},
|
||
|
tpf_default = {.numerator = 1000, .denominator = 30000};
|
||
|
|
||
|
+/* Container for MMAL and VB2 buffers*/
|
||
|
+struct vb2_mmal_buffer {
|
||
|
+ struct vb2_v4l2_buffer vb;
|
||
|
+ struct mmal_buffer mmal;
|
||
|
+};
|
||
|
+
|
||
|
/* video formats */
|
||
|
static struct mmal_fmt formats[] = {
|
||
|
{
|
||
|
@@ -267,14 +273,15 @@ static int buffer_init(struct vb2_buffer
|
||
|
{
|
||
|
struct bm2835_mmal_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
|
||
|
struct vb2_v4l2_buffer *vb2 = to_vb2_v4l2_buffer(vb);
|
||
|
- struct mmal_buffer *buf = container_of(vb2, struct mmal_buffer, vb);
|
||
|
+ struct vb2_mmal_buffer *buf =
|
||
|
+ container_of(vb2, struct vb2_mmal_buffer, vb);
|
||
|
|
||
|
v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, "%s: dev:%p, vb %p\n",
|
||
|
__func__, dev, vb);
|
||
|
- buf->buffer = vb2_plane_vaddr(&buf->vb.vb2_buf, 0);
|
||
|
- buf->buffer_size = vb2_plane_size(&buf->vb.vb2_buf, 0);
|
||
|
+ buf->mmal.buffer = vb2_plane_vaddr(&buf->vb.vb2_buf, 0);
|
||
|
+ buf->mmal.buffer_size = vb2_plane_size(&buf->vb.vb2_buf, 0);
|
||
|
|
||
|
- return mmal_vchi_buffer_init(dev->instance, buf);
|
||
|
+ return mmal_vchi_buffer_init(dev->instance, &buf->mmal);
|
||
|
}
|
||
|
|
||
|
static int buffer_prepare(struct vb2_buffer *vb)
|
||
|
@@ -303,11 +310,13 @@ static void buffer_cleanup(struct vb2_bu
|
||
|
{
|
||
|
struct bm2835_mmal_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
|
||
|
struct vb2_v4l2_buffer *vb2 = to_vb2_v4l2_buffer(vb);
|
||
|
- struct mmal_buffer *buf = container_of(vb2, struct mmal_buffer, vb);
|
||
|
+ struct vb2_mmal_buffer *buf =
|
||
|
+ container_of(vb2, struct vb2_mmal_buffer, vb);
|
||
|
|
||
|
v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, "%s: dev:%p, vb %p\n",
|
||
|
__func__, dev, vb);
|
||
|
- mmal_vchi_buffer_cleanup(buf);
|
||
|
+
|
||
|
+ mmal_vchi_buffer_cleanup(&buf->mmal);
|
||
|
}
|
||
|
|
||
|
static inline bool is_capturing(struct bm2835_mmal_dev *dev)
|
||
|
@@ -319,14 +328,16 @@ static inline bool is_capturing(struct b
|
||
|
static void buffer_cb(struct vchiq_mmal_instance *instance,
|
||
|
struct vchiq_mmal_port *port,
|
||
|
int status,
|
||
|
- struct mmal_buffer *buf,
|
||
|
- unsigned long length, u32 mmal_flags, s64 dts, s64 pts)
|
||
|
+ struct mmal_buffer *mmal_buf)
|
||
|
{
|
||
|
struct bm2835_mmal_dev *dev = port->cb_ctx;
|
||
|
+ struct vb2_mmal_buffer *buf =
|
||
|
+ container_of(mmal_buf, struct vb2_mmal_buffer, mmal);
|
||
|
|
||
|
v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
|
||
|
"%s: status:%d, buf:%p, length:%lu, flags %u, pts %lld\n",
|
||
|
- __func__, status, buf, length, mmal_flags, pts);
|
||
|
+ __func__, status, buf, mmal_buf->length, mmal_buf->mmal_flags,
|
||
|
+ mmal_buf->pts);
|
||
|
|
||
|
if (status != 0) {
|
||
|
/* error in transfer */
|
||
|
@@ -337,7 +348,7 @@ static void buffer_cb(struct vchiq_mmal_
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
- if (length == 0) {
|
||
|
+ if (mmal_buf->length == 0) {
|
||
|
/* stream ended */
|
||
|
if (dev->capture.frame_count) {
|
||
|
/* empty buffer whilst capturing - expected to be an
|
||
|
@@ -353,7 +364,8 @@ static void buffer_cb(struct vchiq_mmal_
|
||
|
&dev->capture.frame_count,
|
||
|
sizeof(dev->capture.frame_count));
|
||
|
}
|
||
|
- if (vchiq_mmal_submit_buffer(instance, port, buf))
|
||
|
+ if (vchiq_mmal_submit_buffer(instance, port,
|
||
|
+ &buf->mmal))
|
||
|
v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
|
||
|
"Failed to return EOS buffer");
|
||
|
} else {
|
||
|
@@ -382,16 +394,16 @@ static void buffer_cb(struct vchiq_mmal_
|
||
|
v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
|
||
|
"Buffer time set as current time - %lld",
|
||
|
buf->vb.vb2_buf.timestamp);
|
||
|
- } else if (pts != 0) {
|
||
|
+ } else if (mmal_buf->pts != 0) {
|
||
|
ktime_t timestamp;
|
||
|
- s64 runtime_us = pts -
|
||
|
+ s64 runtime_us = mmal_buf->pts -
|
||
|
dev->capture.vc_start_timestamp;
|
||
|
timestamp = ktime_add_us(dev->capture.kernel_start_ts,
|
||
|
runtime_us);
|
||
|
v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
|
||
|
"Convert start time %llu and %llu with offset %llu to %llu\n",
|
||
|
ktime_to_ns(dev->capture.kernel_start_ts),
|
||
|
- dev->capture.vc_start_timestamp, pts,
|
||
|
+ dev->capture.vc_start_timestamp, mmal_buf->pts,
|
||
|
ktime_to_ns(timestamp));
|
||
|
if (timestamp < dev->capture.last_timestamp) {
|
||
|
v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
|
||
|
@@ -416,15 +428,15 @@ static void buffer_cb(struct vchiq_mmal_
|
||
|
dev->capture.last_timestamp = buf->vb.vb2_buf.timestamp;
|
||
|
buf->vb.sequence = dev->capture.sequence++;
|
||
|
|
||
|
- vb2_set_plane_payload(&buf->vb.vb2_buf, 0, length);
|
||
|
- if (mmal_flags & MMAL_BUFFER_HEADER_FLAG_KEYFRAME)
|
||
|
+ vb2_set_plane_payload(&buf->vb.vb2_buf, 0, mmal_buf->length);
|
||
|
+ if (mmal_buf->mmal_flags & MMAL_BUFFER_HEADER_FLAG_KEYFRAME)
|
||
|
buf->vb.flags |= V4L2_BUF_FLAG_KEYFRAME;
|
||
|
|
||
|
v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
|
||
|
"Buffer has ts %llu", dev->capture.last_timestamp);
|
||
|
vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
|
||
|
|
||
|
- if (mmal_flags & MMAL_BUFFER_HEADER_FLAG_EOS &&
|
||
|
+ if (mmal_buf->mmal_flags & MMAL_BUFFER_HEADER_FLAG_EOS &&
|
||
|
is_capturing(dev)) {
|
||
|
v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
|
||
|
"Grab another frame as buffer has EOS");
|
||
|
@@ -507,14 +519,16 @@ static void buffer_queue(struct vb2_buff
|
||
|
{
|
||
|
struct bm2835_mmal_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
|
||
|
struct vb2_v4l2_buffer *vb2 = to_vb2_v4l2_buffer(vb);
|
||
|
- struct mmal_buffer *buf = container_of(vb2, struct mmal_buffer, vb);
|
||
|
+ struct vb2_mmal_buffer *buf =
|
||
|
+ container_of(vb2, struct vb2_mmal_buffer, vb);
|
||
|
int ret;
|
||
|
|
||
|
v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
|
||
|
"%s: dev:%p buf:%p, idx %u\n",
|
||
|
__func__, dev, buf, vb2->vb2_buf.index);
|
||
|
|
||
|
- ret = vchiq_mmal_submit_buffer(dev->instance, dev->capture.port, buf);
|
||
|
+ ret = vchiq_mmal_submit_buffer(dev->instance, dev->capture.port,
|
||
|
+ &buf->mmal);
|
||
|
if (ret < 0)
|
||
|
v4l2_err(&dev->v4l2_dev, "%s: error submitting buffer\n",
|
||
|
__func__);
|
||
|
@@ -628,7 +642,7 @@ static void stop_streaming(struct vb2_qu
|
||
|
dev->capture.frame_count = 0;
|
||
|
|
||
|
/* ensure a format has actually been set */
|
||
|
- if (!dev->capture.port) {
|
||
|
+ if (!port) {
|
||
|
v4l2_err(&dev->v4l2_dev,
|
||
|
"no capture port - stream not started?\n");
|
||
|
return;
|
||
|
@@ -648,11 +662,11 @@ static void stop_streaming(struct vb2_qu
|
||
|
|
||
|
/* disable the connection from camera to encoder */
|
||
|
ret = vchiq_mmal_port_disable(dev->instance, dev->capture.camera_port);
|
||
|
- if (!ret && dev->capture.camera_port != dev->capture.port) {
|
||
|
+ if (!ret && dev->capture.camera_port != port) {
|
||
|
v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
|
||
|
"disabling port\n");
|
||
|
- ret = vchiq_mmal_port_disable(dev->instance, dev->capture.port);
|
||
|
- } else if (dev->capture.camera_port != dev->capture.port) {
|
||
|
+ ret = vchiq_mmal_port_disable(dev->instance, port);
|
||
|
+ } else if (dev->capture.camera_port != port) {
|
||
|
v4l2_err(&dev->v4l2_dev, "port_disable failed, error %d\n",
|
||
|
ret);
|
||
|
}
|
||
|
@@ -1954,7 +1968,7 @@ static int bcm2835_mmal_probe(struct pla
|
||
|
q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||
|
q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ;
|
||
|
q->drv_priv = dev;
|
||
|
- q->buf_struct_size = sizeof(struct mmal_buffer);
|
||
|
+ q->buf_struct_size = sizeof(struct vb2_mmal_buffer);
|
||
|
q->ops = &bm2835_mmal_video_qops;
|
||
|
q->mem_ops = &vb2_vmalloc_memops;
|
||
|
q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
|
||
|
--- a/drivers/staging/vc04_services/vchiq-mmal/mmal-common.h
|
||
|
+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-common.h
|
||
|
@@ -50,6 +50,11 @@ struct mmal_buffer {
|
||
|
unsigned long buffer_size; /* size of allocated buffer */
|
||
|
|
||
|
struct mmal_msg_context *msg_context;
|
||
|
+
|
||
|
+ unsigned long length;
|
||
|
+ u32 mmal_flags;
|
||
|
+ s64 dts;
|
||
|
+ s64 pts;
|
||
|
};
|
||
|
|
||
|
/* */
|
||
|
--- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c
|
||
|
+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c
|
||
5 years ago
|
@@ -259,17 +259,25 @@ static void buffer_work_cb(struct work_s
|
||
5 years ago
|
{
|
||
|
struct mmal_msg_context *msg_context =
|
||
|
container_of(work, struct mmal_msg_context, u.bulk.work);
|
||
|
+ struct mmal_buffer *buffer = msg_context->u.bulk.buffer;
|
||
|
+
|
||
|
+ if (!buffer) {
|
||
|
+ pr_err("%s: ctx: %p, No mmal buffer to pass details\n",
|
||
|
+ __func__, msg_context);
|
||
|
+ return;
|
||
|
+ }
|
||
|
+
|
||
|
+ buffer->length = msg_context->u.bulk.buffer_used;
|
||
|
+ buffer->mmal_flags = msg_context->u.bulk.mmal_flags;
|
||
|
+ buffer->dts = msg_context->u.bulk.dts;
|
||
|
+ buffer->pts = msg_context->u.bulk.pts;
|
||
|
|
||
|
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);
|
||
|
+ msg_context->u.bulk.buffer);
|
||
|
}
|
||
|
|
||
|
/* workqueue scheduled callback to handle receiving buffers
|
||
5 years ago
|
@@ -1327,11 +1335,14 @@ static int port_disable(struct vchiq_mma
|
||
5 years ago
|
mmalbuf = list_entry(buf_head, struct mmal_buffer,
|
||
|
list);
|
||
|
list_del(buf_head);
|
||
|
- if (port->buffer_cb)
|
||
|
+ if (port->buffer_cb) {
|
||
|
+ mmalbuf->length = 0;
|
||
|
+ mmalbuf->mmal_flags = 0;
|
||
|
+ mmalbuf->dts = MMAL_TIME_UNKNOWN;
|
||
|
+ mmalbuf->pts = MMAL_TIME_UNKNOWN;
|
||
|
port->buffer_cb(instance,
|
||
|
- port, 0, mmalbuf, 0, 0,
|
||
|
- MMAL_TIME_UNKNOWN,
|
||
|
- MMAL_TIME_UNKNOWN);
|
||
|
+ port, 0, mmalbuf);
|
||
|
+ }
|
||
|
}
|
||
|
|
||
|
spin_unlock_irqrestore(&port->slock, flags);
|
||
|
--- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h
|
||
|
+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h
|
||
|
@@ -44,8 +44,7 @@ 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);
|
||
|
+ int status, struct mmal_buffer *buffer);
|
||
|
|
||
|
struct vchiq_mmal_port {
|
||
|
u32 enabled:1;
|