mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-22 06:57:57 +00:00
330 lines
11 KiB
Diff
330 lines
11 KiB
Diff
|
From 84e8138ee002f3d0e643db45b8e27cb792c0c864 Mon Sep 17 00:00:00 2001
|
||
|
From: John Cox <jc@kynesim.co.uk>
|
||
|
Date: Thu, 11 Mar 2021 12:51:00 +0000
|
||
|
Subject: [PATCH] media: rpivid: Convert to MPLANE
|
||
|
|
||
|
Use multi-planar interface rather than single plane interface. This
|
||
|
allows dmabufs holding compressed data to be resized.
|
||
|
|
||
|
Signed-off-by: John Cox <jc@kynesim.co.uk>
|
||
|
---
|
||
|
drivers/staging/media/rpivid/rpivid.c | 2 +-
|
||
|
drivers/staging/media/rpivid/rpivid.h | 4 +-
|
||
|
drivers/staging/media/rpivid/rpivid_h265.c | 9 ++-
|
||
|
drivers/staging/media/rpivid/rpivid_video.c | 88 ++++++++++-----------
|
||
|
drivers/staging/media/rpivid/rpivid_video.h | 4 +-
|
||
|
5 files changed, 52 insertions(+), 55 deletions(-)
|
||
|
|
||
|
--- a/drivers/staging/media/rpivid/rpivid.c
|
||
|
+++ b/drivers/staging/media/rpivid/rpivid.c
|
||
|
@@ -283,7 +283,7 @@ static const struct video_device rpivid_
|
||
|
.ioctl_ops = &rpivid_ioctl_ops,
|
||
|
.minor = -1,
|
||
|
.release = video_device_release_empty,
|
||
|
- .device_caps = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING,
|
||
|
+ .device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING,
|
||
|
};
|
||
|
|
||
|
static const struct v4l2_m2m_ops rpivid_m2m_ops = {
|
||
|
--- a/drivers/staging/media/rpivid/rpivid.h
|
||
|
+++ b/drivers/staging/media/rpivid/rpivid.h
|
||
|
@@ -85,8 +85,8 @@ struct rpivid_ctx {
|
||
|
struct v4l2_fh fh;
|
||
|
struct rpivid_dev *dev;
|
||
|
|
||
|
- struct v4l2_pix_format src_fmt;
|
||
|
- struct v4l2_pix_format dst_fmt;
|
||
|
+ struct v4l2_pix_format_mplane src_fmt;
|
||
|
+ struct v4l2_pix_format_mplane dst_fmt;
|
||
|
int dst_fmt_set;
|
||
|
// fatal_err is set if an error has occurred s.t. decode cannot
|
||
|
// continue (such as running out of CMA)
|
||
|
--- a/drivers/staging/media/rpivid/rpivid_h265.c
|
||
|
+++ b/drivers/staging/media/rpivid/rpivid_h265.c
|
||
|
@@ -1613,7 +1613,7 @@ static void rpivid_h265_setup(struct rpi
|
||
|
de->cmd_copy_gptr = ctx->cmdbufs + 0;
|
||
|
|
||
|
de->frame_c_offset = ctx->dst_fmt.height * 128;
|
||
|
- de->frame_stride = ctx->dst_fmt.bytesperline * 128;
|
||
|
+ de->frame_stride = ctx->dst_fmt.plane_fmt[0].bytesperline * 128;
|
||
|
de->frame_addr =
|
||
|
vb2_dma_contig_plane_dma_addr(&run->dst->vb2_buf, 0);
|
||
|
de->frame_aux = NULL;
|
||
|
@@ -1654,11 +1654,11 @@ static void rpivid_h265_setup(struct rpi
|
||
|
goto fail;
|
||
|
}
|
||
|
if (run->dst->planes[0].length <
|
||
|
- ctx->dst_fmt.sizeimage) {
|
||
|
+ ctx->dst_fmt.plane_fmt[0].sizeimage) {
|
||
|
v4l2_warn(&dev->v4l2_dev,
|
||
|
"Capture plane[0] length (%d) < sizeimage (%d)\n",
|
||
|
run->dst->planes[0].length,
|
||
|
- ctx->dst_fmt.sizeimage);
|
||
|
+ ctx->dst_fmt.plane_fmt[0].sizeimage);
|
||
|
goto fail;
|
||
|
}
|
||
|
|
||
|
@@ -1812,7 +1812,8 @@ static void rpivid_h265_setup(struct rpi
|
||
|
// slices. If this changes we will need idx mapping code.
|
||
|
// Uses sh so here rather than trigger
|
||
|
|
||
|
- vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
|
||
|
+ vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx,
|
||
|
+ V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
|
||
|
|
||
|
if (!vq) {
|
||
|
v4l2_err(&dev->v4l2_dev, "VQ gone!\n");
|
||
|
--- a/drivers/staging/media/rpivid/rpivid_video.c
|
||
|
+++ b/drivers/staging/media/rpivid/rpivid_video.c
|
||
|
@@ -42,25 +42,27 @@ static inline unsigned int constrain2x(u
|
||
|
(x > y * 2) ? y : x;
|
||
|
}
|
||
|
|
||
|
-int rpivid_prepare_src_format(struct v4l2_pix_format *pix_fmt)
|
||
|
+int rpivid_prepare_src_format(struct v4l2_pix_format_mplane *pix_fmt)
|
||
|
{
|
||
|
if (pix_fmt->pixelformat != V4L2_PIX_FMT_HEVC_SLICE)
|
||
|
return -EINVAL;
|
||
|
|
||
|
/* Zero bytes per line for encoded source. */
|
||
|
- pix_fmt->bytesperline = 0;
|
||
|
+ pix_fmt->plane_fmt[0].bytesperline = 0;
|
||
|
/* Choose some minimum size since this can't be 0 */
|
||
|
- pix_fmt->sizeimage = max_t(u32, SZ_1K, pix_fmt->sizeimage);
|
||
|
+ pix_fmt->plane_fmt[0].sizeimage = max_t(u32, SZ_1K,
|
||
|
+ pix_fmt->plane_fmt[0].sizeimage);
|
||
|
+ pix_fmt->num_planes = 1;
|
||
|
pix_fmt->field = V4L2_FIELD_NONE;
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
-int rpivid_prepare_dst_format(struct v4l2_pix_format *pix_fmt)
|
||
|
+int rpivid_prepare_dst_format(struct v4l2_pix_format_mplane *pix_fmt)
|
||
|
{
|
||
|
unsigned int width = pix_fmt->width;
|
||
|
unsigned int height = pix_fmt->height;
|
||
|
- unsigned int sizeimage = pix_fmt->sizeimage;
|
||
|
- unsigned int bytesperline = pix_fmt->bytesperline;
|
||
|
+ unsigned int sizeimage = pix_fmt->plane_fmt[0].sizeimage;
|
||
|
+ unsigned int bytesperline = pix_fmt->plane_fmt[0].bytesperline;
|
||
|
|
||
|
switch (pix_fmt->pixelformat) {
|
||
|
/* For column formats set bytesperline to column height (stride2) */
|
||
|
@@ -112,8 +114,9 @@ int rpivid_prepare_dst_format(struct v4l
|
||
|
pix_fmt->height = height;
|
||
|
|
||
|
pix_fmt->field = V4L2_FIELD_NONE;
|
||
|
- pix_fmt->bytesperline = bytesperline;
|
||
|
- pix_fmt->sizeimage = sizeimage;
|
||
|
+ pix_fmt->plane_fmt[0].bytesperline = bytesperline;
|
||
|
+ pix_fmt->plane_fmt[0].sizeimage = sizeimage;
|
||
|
+ pix_fmt->num_planes = 1;
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
@@ -222,12 +225,12 @@ static u32 pixelformat_from_sps(const st
|
||
|
return pf;
|
||
|
}
|
||
|
|
||
|
-static struct v4l2_pix_format
|
||
|
+static struct v4l2_pix_format_mplane
|
||
|
rpivid_hevc_default_dst_fmt(struct rpivid_ctx * const ctx)
|
||
|
{
|
||
|
const struct v4l2_ctrl_hevc_sps * const sps =
|
||
|
rpivid_find_control_data(ctx, V4L2_CID_MPEG_VIDEO_HEVC_SPS);
|
||
|
- struct v4l2_pix_format pix_fmt = {
|
||
|
+ struct v4l2_pix_format_mplane pix_fmt = {
|
||
|
.width = sps->pic_width_in_luma_samples,
|
||
|
.height = sps->pic_height_in_luma_samples,
|
||
|
.pixelformat = pixelformat_from_sps(sps, 0)
|
||
|
@@ -267,7 +270,7 @@ static int rpivid_g_fmt_vid_cap(struct f
|
||
|
|
||
|
if (!ctx->dst_fmt_set)
|
||
|
ctx->dst_fmt = rpivid_hevc_default_dst_fmt(ctx);
|
||
|
- f->fmt.pix = ctx->dst_fmt;
|
||
|
+ f->fmt.pix_mp = ctx->dst_fmt;
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
@@ -276,12 +279,12 @@ static int rpivid_g_fmt_vid_out(struct f
|
||
|
{
|
||
|
struct rpivid_ctx *ctx = rpivid_file2ctx(file);
|
||
|
|
||
|
- f->fmt.pix = ctx->src_fmt;
|
||
|
+ f->fmt.pix_mp = ctx->src_fmt;
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
-static inline void copy_color(struct v4l2_pix_format *d,
|
||
|
- const struct v4l2_pix_format *s)
|
||
|
+static inline void copy_color(struct v4l2_pix_format_mplane *d,
|
||
|
+ const struct v4l2_pix_format_mplane *s)
|
||
|
{
|
||
|
d->colorspace = s->colorspace;
|
||
|
d->xfer_func = s->xfer_func;
|
||
|
@@ -298,12 +301,8 @@ static int rpivid_try_fmt_vid_cap(struct
|
||
|
u32 pixelformat;
|
||
|
int i;
|
||
|
|
||
|
- /* Reject format types we don't support */
|
||
|
- if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
|
||
|
- return -EINVAL;
|
||
|
-
|
||
|
for (i = 0; (pixelformat = pixelformat_from_sps(sps, i)) != 0; i++) {
|
||
|
- if (f->fmt.pix.pixelformat == pixelformat)
|
||
|
+ if (f->fmt.pix_mp.pixelformat == pixelformat)
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
@@ -317,23 +316,20 @@ static int rpivid_try_fmt_vid_cap(struct
|
||
|
|
||
|
// We don't have any way of finding out colourspace so believe
|
||
|
// anything we are told - take anything set in src as a default
|
||
|
- if (f->fmt.pix.colorspace == V4L2_COLORSPACE_DEFAULT)
|
||
|
- copy_color(&f->fmt.pix, &ctx->src_fmt);
|
||
|
+ if (f->fmt.pix_mp.colorspace == V4L2_COLORSPACE_DEFAULT)
|
||
|
+ copy_color(&f->fmt.pix_mp, &ctx->src_fmt);
|
||
|
|
||
|
- f->fmt.pix.pixelformat = pixelformat;
|
||
|
- return rpivid_prepare_dst_format(&f->fmt.pix);
|
||
|
+ f->fmt.pix_mp.pixelformat = pixelformat;
|
||
|
+ return rpivid_prepare_dst_format(&f->fmt.pix_mp);
|
||
|
}
|
||
|
|
||
|
static int rpivid_try_fmt_vid_out(struct file *file, void *priv,
|
||
|
struct v4l2_format *f)
|
||
|
{
|
||
|
- if (f->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
|
||
|
- return -EINVAL;
|
||
|
-
|
||
|
- if (rpivid_prepare_src_format(&f->fmt.pix)) {
|
||
|
+ if (rpivid_prepare_src_format(&f->fmt.pix_mp)) {
|
||
|
// Set default src format
|
||
|
- f->fmt.pix.pixelformat = RPIVID_SRC_PIXELFORMAT_DEFAULT;
|
||
|
- rpivid_prepare_src_format(&f->fmt.pix);
|
||
|
+ f->fmt.pix_mp.pixelformat = RPIVID_SRC_PIXELFORMAT_DEFAULT;
|
||
|
+ rpivid_prepare_src_format(&f->fmt.pix_mp);
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
@@ -353,7 +349,7 @@ static int rpivid_s_fmt_vid_cap(struct f
|
||
|
if (ret)
|
||
|
return ret;
|
||
|
|
||
|
- ctx->dst_fmt = f->fmt.pix;
|
||
|
+ ctx->dst_fmt = f->fmt.pix_mp;
|
||
|
ctx->dst_fmt_set = 1;
|
||
|
|
||
|
return 0;
|
||
|
@@ -374,14 +370,14 @@ static int rpivid_s_fmt_vid_out(struct f
|
||
|
if (ret)
|
||
|
return ret;
|
||
|
|
||
|
- ctx->src_fmt = f->fmt.pix;
|
||
|
+ ctx->src_fmt = f->fmt.pix_mp;
|
||
|
ctx->dst_fmt_set = 0; // Setting src invalidates dst
|
||
|
|
||
|
vq->subsystem_flags |=
|
||
|
VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF;
|
||
|
|
||
|
/* Propagate colorspace information to capture. */
|
||
|
- copy_color(&ctx->dst_fmt, &f->fmt.pix);
|
||
|
+ copy_color(&ctx->dst_fmt, &f->fmt.pix_mp);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
@@ -389,14 +385,14 @@ const struct v4l2_ioctl_ops rpivid_ioctl
|
||
|
.vidioc_querycap = rpivid_querycap,
|
||
|
|
||
|
.vidioc_enum_fmt_vid_cap = rpivid_enum_fmt_vid_cap,
|
||
|
- .vidioc_g_fmt_vid_cap = rpivid_g_fmt_vid_cap,
|
||
|
- .vidioc_try_fmt_vid_cap = rpivid_try_fmt_vid_cap,
|
||
|
- .vidioc_s_fmt_vid_cap = rpivid_s_fmt_vid_cap,
|
||
|
+ .vidioc_g_fmt_vid_cap_mplane = rpivid_g_fmt_vid_cap,
|
||
|
+ .vidioc_try_fmt_vid_cap_mplane = rpivid_try_fmt_vid_cap,
|
||
|
+ .vidioc_s_fmt_vid_cap_mplane = rpivid_s_fmt_vid_cap,
|
||
|
|
||
|
.vidioc_enum_fmt_vid_out = rpivid_enum_fmt_vid_out,
|
||
|
- .vidioc_g_fmt_vid_out = rpivid_g_fmt_vid_out,
|
||
|
- .vidioc_try_fmt_vid_out = rpivid_try_fmt_vid_out,
|
||
|
- .vidioc_s_fmt_vid_out = rpivid_s_fmt_vid_out,
|
||
|
+ .vidioc_g_fmt_vid_out_mplane = rpivid_g_fmt_vid_out,
|
||
|
+ .vidioc_try_fmt_vid_out_mplane = rpivid_try_fmt_vid_out,
|
||
|
+ .vidioc_s_fmt_vid_out_mplane = rpivid_s_fmt_vid_out,
|
||
|
|
||
|
.vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs,
|
||
|
.vidioc_querybuf = v4l2_m2m_ioctl_querybuf,
|
||
|
@@ -421,7 +417,7 @@ static int rpivid_queue_setup(struct vb2
|
||
|
struct device *alloc_devs[])
|
||
|
{
|
||
|
struct rpivid_ctx *ctx = vb2_get_drv_priv(vq);
|
||
|
- struct v4l2_pix_format *pix_fmt;
|
||
|
+ struct v4l2_pix_format_mplane *pix_fmt;
|
||
|
|
||
|
if (V4L2_TYPE_IS_OUTPUT(vq->type))
|
||
|
pix_fmt = &ctx->src_fmt;
|
||
|
@@ -429,10 +425,10 @@ static int rpivid_queue_setup(struct vb2
|
||
|
pix_fmt = &ctx->dst_fmt;
|
||
|
|
||
|
if (*nplanes) {
|
||
|
- if (sizes[0] < pix_fmt->sizeimage)
|
||
|
+ if (sizes[0] < pix_fmt->plane_fmt[0].sizeimage)
|
||
|
return -EINVAL;
|
||
|
} else {
|
||
|
- sizes[0] = pix_fmt->sizeimage;
|
||
|
+ sizes[0] = pix_fmt->plane_fmt[0].sizeimage;
|
||
|
*nplanes = 1;
|
||
|
}
|
||
|
|
||
|
@@ -471,17 +467,17 @@ static int rpivid_buf_prepare(struct vb2
|
||
|
{
|
||
|
struct vb2_queue *vq = vb->vb2_queue;
|
||
|
struct rpivid_ctx *ctx = vb2_get_drv_priv(vq);
|
||
|
- struct v4l2_pix_format *pix_fmt;
|
||
|
+ struct v4l2_pix_format_mplane *pix_fmt;
|
||
|
|
||
|
if (V4L2_TYPE_IS_OUTPUT(vq->type))
|
||
|
pix_fmt = &ctx->src_fmt;
|
||
|
else
|
||
|
pix_fmt = &ctx->dst_fmt;
|
||
|
|
||
|
- if (vb2_plane_size(vb, 0) < pix_fmt->sizeimage)
|
||
|
+ if (vb2_plane_size(vb, 0) < pix_fmt->plane_fmt[0].sizeimage)
|
||
|
return -EINVAL;
|
||
|
|
||
|
- vb2_set_plane_payload(vb, 0, pix_fmt->sizeimage);
|
||
|
+ vb2_set_plane_payload(vb, 0, pix_fmt->plane_fmt[0].sizeimage);
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
@@ -567,7 +563,7 @@ int rpivid_queue_init(void *priv, struct
|
||
|
struct rpivid_ctx *ctx = priv;
|
||
|
int ret;
|
||
|
|
||
|
- src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
|
||
|
+ src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
|
||
|
src_vq->io_modes = VB2_MMAP | VB2_DMABUF;
|
||
|
src_vq->drv_priv = ctx;
|
||
|
src_vq->buf_struct_size = sizeof(struct rpivid_buffer);
|
||
|
@@ -584,7 +580,7 @@ int rpivid_queue_init(void *priv, struct
|
||
|
if (ret)
|
||
|
return ret;
|
||
|
|
||
|
- dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||
|
+ dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
|
||
|
dst_vq->io_modes = VB2_MMAP | VB2_DMABUF;
|
||
|
dst_vq->drv_priv = ctx;
|
||
|
dst_vq->buf_struct_size = sizeof(struct rpivid_buffer);
|
||
|
--- a/drivers/staging/media/rpivid/rpivid_video.h
|
||
|
+++ b/drivers/staging/media/rpivid/rpivid_video.h
|
||
|
@@ -24,7 +24,7 @@ extern const struct v4l2_ioctl_ops rpivi
|
||
|
|
||
|
int rpivid_queue_init(void *priv, struct vb2_queue *src_vq,
|
||
|
struct vb2_queue *dst_vq);
|
||
|
-int rpivid_prepare_src_format(struct v4l2_pix_format *pix_fmt);
|
||
|
-int rpivid_prepare_dst_format(struct v4l2_pix_format *pix_fmt);
|
||
|
+int rpivid_prepare_src_format(struct v4l2_pix_format_mplane *pix_fmt);
|
||
|
+int rpivid_prepare_dst_format(struct v4l2_pix_format_mplane *pix_fmt);
|
||
|
|
||
|
#endif
|