kernel: bump 5.4 to 5.4.48
[oweals/openwrt.git] / target / linux / bcm27xx / patches-5.4 / 950-0286-staging-bcm2835-codec-switch-to-multi-planar-API.patch
1 From 9495e07dac5cb6230838763572f73b863cd72019 Mon Sep 17 00:00:00 2001
2 From: Chen-Yu Tsai <wens@csie.org>
3 Date: Thu, 18 Jul 2019 17:07:05 +0800
4 Subject: [PATCH] staging: bcm2835-codec: switch to multi-planar API
5
6 There are two APIs for mem2mem devices, the older single-planar API and
7 the newer multi-planar one. Without making things overly complex, the
8 driver can only support one or the other. However the userspace libv4l2
9 library has a plugin that allows multi-planar API devices to service
10 single-planar consumers.
11
12 Chromium supports the multi-planar API exclusively, though this is
13 currently limited to ChromiumOS. It would be possible to add support
14 for generic Linux.
15
16 Switching to the multi-planar API would allow usage of both APIs from
17 userspace.
18
19 Signed-off-by: Chen-Yu Tsai <wens@csie.org>
20 ---
21  .../bcm2835-codec/bcm2835-v4l2-codec.c        | 141 +++++++++---------
22  1 file changed, 74 insertions(+), 67 deletions(-)
23
24 --- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c
25 +++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c
26 @@ -504,7 +504,7 @@ static struct bcm2835_codec_fmt *find_fo
27  
28         for (k = 0; k < fmts->num_entries; k++) {
29                 fmt = &fmts->list[k];
30 -               if (fmt->fourcc == f->fmt.pix.pixelformat)
31 +               if (fmt->fourcc == f->fmt.pix_mp.pixelformat)
32                         break;
33         }
34         if (k == fmts->num_entries)
35 @@ -522,9 +522,9 @@ static struct bcm2835_codec_q_data *get_
36                                                enum v4l2_buf_type type)
37  {
38         switch (type) {
39 -       case V4L2_BUF_TYPE_VIDEO_OUTPUT:
40 +       case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
41                 return &ctx->q_data[V4L2_M2M_SRC];
42 -       case V4L2_BUF_TYPE_VIDEO_CAPTURE:
43 +       case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
44                 return &ctx->q_data[V4L2_M2M_DST];
45         default:
46                 v4l2_err(&ctx->dev->v4l2_dev, "%s: Invalid queue type %u\n",
47 @@ -541,9 +541,9 @@ static struct vchiq_mmal_port *get_port_
48                 return NULL;
49  
50         switch (type) {
51 -       case V4L2_BUF_TYPE_VIDEO_OUTPUT:
52 +       case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
53                 return &ctx->component->input[0];
54 -       case V4L2_BUF_TYPE_VIDEO_CAPTURE:
55 +       case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
56                 return &ctx->component->output[0];
57         default:
58                 v4l2_err(&ctx->dev->v4l2_dev, "%s: Invalid queue type %u\n",
59 @@ -752,7 +752,7 @@ static void handle_fmt_changed(struct bc
60                  format->es.video.crop.width, format->es.video.crop.height,
61                  format->es.video.color_space);
62  
63 -       q_data = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
64 +       q_data = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
65         q_data->crop_width = format->es.video.crop.width;
66         q_data->crop_height = format->es.video.crop.height;
67         q_data->bytesperline = format->es.video.crop.width;
68 @@ -945,7 +945,7 @@ static int vidioc_querycap(struct file *
69         strncpy(cap->card, MEM2MEM_NAME, sizeof(cap->card) - 1);
70         snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
71                  MEM2MEM_NAME);
72 -       cap->device_caps = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING;
73 +       cap->device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING;
74         cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
75         return 0;
76  }
77 @@ -996,16 +996,20 @@ static int vidioc_g_fmt(struct bcm2835_c
78  
79         q_data = get_q_data(ctx, f->type);
80  
81 -       f->fmt.pix.width        = q_data->crop_width;
82 -       f->fmt.pix.height       = q_data->height;
83 -       f->fmt.pix.field        = V4L2_FIELD_NONE;
84 -       f->fmt.pix.pixelformat  = q_data->fmt->fourcc;
85 -       f->fmt.pix.bytesperline = q_data->bytesperline;
86 -       f->fmt.pix.sizeimage    = q_data->sizeimage;
87 -       f->fmt.pix.colorspace   = ctx->colorspace;
88 -       f->fmt.pix.xfer_func    = ctx->xfer_func;
89 -       f->fmt.pix.ycbcr_enc    = ctx->ycbcr_enc;
90 -       f->fmt.pix.quantization = ctx->quant;
91 +       f->fmt.pix_mp.width                     = q_data->crop_width;
92 +       f->fmt.pix_mp.height                    = q_data->height;
93 +       f->fmt.pix_mp.pixelformat               = q_data->fmt->fourcc;
94 +       f->fmt.pix_mp.field                     = V4L2_FIELD_NONE;
95 +       f->fmt.pix_mp.colorspace                = ctx->colorspace;
96 +       f->fmt.pix_mp.plane_fmt[0].sizeimage    = q_data->sizeimage;
97 +       f->fmt.pix_mp.plane_fmt[0].bytesperline = q_data->bytesperline;
98 +       f->fmt.pix_mp.num_planes                = 1;
99 +       f->fmt.pix_mp.ycbcr_enc                 = ctx->ycbcr_enc;
100 +       f->fmt.pix_mp.quantization              = ctx->quant;
101 +       f->fmt.pix_mp.xfer_func                 = ctx->xfer_func;
102 +
103 +       memset(f->fmt.pix_mp.plane_fmt[0].reserved, 0,
104 +              sizeof(f->fmt.pix_mp.plane_fmt[0].reserved));
105  
106         return 0;
107  }
108 @@ -1029,17 +1033,17 @@ static int vidioc_try_fmt(struct bcm2835
109          * The V4L2 specification requires the driver to correct the format
110          * struct if any of the dimensions is unsupported
111          */
112 -       if (f->fmt.pix.width > MAX_W)
113 -               f->fmt.pix.width = MAX_W;
114 -       if (f->fmt.pix.height > MAX_H)
115 -               f->fmt.pix.height = MAX_H;
116 +       if (f->fmt.pix_mp.width > MAX_W)
117 +               f->fmt.pix_mp.width = MAX_W;
118 +       if (f->fmt.pix_mp.height > MAX_H)
119 +               f->fmt.pix_mp.height = MAX_H;
120  
121         if (!fmt->flags & V4L2_FMT_FLAG_COMPRESSED) {
122                 /* Only clip min w/h on capture. Treat 0x0 as unknown. */
123 -               if (f->fmt.pix.width < MIN_W)
124 -                       f->fmt.pix.width = MIN_W;
125 -               if (f->fmt.pix.height < MIN_H)
126 -                       f->fmt.pix.height = MIN_H;
127 +               if (f->fmt.pix_mp.width < MIN_W)
128 +                       f->fmt.pix_mp.width = MIN_W;
129 +               if (f->fmt.pix_mp.height < MIN_H)
130 +                       f->fmt.pix_mp.height = MIN_H;
131  
132                 /*
133                  * For codecs the buffer must have a vertical alignment of 16
134 @@ -1048,16 +1052,18 @@ static int vidioc_try_fmt(struct bcm2835
135                  * some of the pixels are active.
136                  */
137                 if (ctx->dev->role != ISP)
138 -                       f->fmt.pix.height = ALIGN(f->fmt.pix.height, 16);
139 +                       f->fmt.pix_mp.height = ALIGN(f->fmt.pix_mp.height, 16);
140         }
141 -       f->fmt.pix.bytesperline = get_bytesperline(f->fmt.pix.width,
142 -                                                  fmt);
143 -       f->fmt.pix.sizeimage = get_sizeimage(f->fmt.pix.bytesperline,
144 -                                            f->fmt.pix.width,
145 -                                            f->fmt.pix.height,
146 -                                            fmt);
147 +       f->fmt.pix_mp.num_planes = 1;
148 +       f->fmt.pix_mp.plane_fmt[0].bytesperline =
149 +               get_bytesperline(f->fmt.pix_mp.width, fmt);
150 +       f->fmt.pix_mp.plane_fmt[0].sizeimage =
151 +               get_sizeimage(f->fmt.pix_mp.plane_fmt[0].bytesperline,
152 +                             f->fmt.pix_mp.width, f->fmt.pix_mp.height, fmt);
153 +       memset(f->fmt.pix_mp.plane_fmt[0].reserved, 0,
154 +              sizeof(f->fmt.pix_mp.plane_fmt[0].reserved));
155  
156 -       f->fmt.pix.field = V4L2_FIELD_NONE;
157 +       f->fmt.pix_mp.field = V4L2_FIELD_NONE;
158  
159         return 0;
160  }
161 @@ -1070,8 +1076,8 @@ static int vidioc_try_fmt_vid_cap(struct
162  
163         fmt = find_format(f, ctx->dev, true);
164         if (!fmt) {
165 -               f->fmt.pix.pixelformat = get_default_format(ctx->dev,
166 -                                                           true)->fourcc;
167 +               f->fmt.pix_mp.pixelformat = get_default_format(ctx->dev,
168 +                                                              true)->fourcc;
169                 fmt = find_format(f, ctx->dev, true);
170         }
171  
172 @@ -1086,13 +1092,13 @@ static int vidioc_try_fmt_vid_out(struct
173  
174         fmt = find_format(f, ctx->dev, false);
175         if (!fmt) {
176 -               f->fmt.pix.pixelformat = get_default_format(ctx->dev,
177 -                                                           false)->fourcc;
178 +               f->fmt.pix_mp.pixelformat = get_default_format(ctx->dev,
179 +                                                              false)->fourcc;
180                 fmt = find_format(f, ctx->dev, false);
181         }
182  
183 -       if (!f->fmt.pix.colorspace)
184 -               f->fmt.pix.colorspace = ctx->colorspace;
185 +       if (!f->fmt.pix_mp.colorspace)
186 +               f->fmt.pix_mp.colorspace = ctx->colorspace;
187  
188         return vidioc_try_fmt(ctx, f, fmt);
189  }
190 @@ -1106,9 +1112,10 @@ static int vidioc_s_fmt(struct bcm2835_c
191         bool update_capture_port = false;
192         int ret;
193  
194 -       v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "Setting format for type %d, wxh: %dx%d, fmt: %08x, size %u\n",
195 -                f->type, f->fmt.pix.width, f->fmt.pix.height,
196 -                f->fmt.pix.pixelformat, f->fmt.pix.sizeimage);
197 +       v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "Setting format for type %d, wxh: %dx%d, fmt: %08x, size %u\n",
198 +                f->type, f->fmt.pix_mp.width, f->fmt.pix_mp.height,
199 +                f->fmt.pix_mp.pixelformat, f->fmt.pix_mp.plane_fmt[0].sizeimage);
200 +
201  
202         vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
203         if (!vq)
204 @@ -1124,9 +1131,9 @@ static int vidioc_s_fmt(struct bcm2835_c
205         }
206  
207         q_data->fmt = find_format(f, ctx->dev,
208 -                                 f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE);
209 -       q_data->crop_width = f->fmt.pix.width;
210 -       q_data->height = f->fmt.pix.height;
211 +                                 f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
212 +       q_data->crop_width = f->fmt.pix_mp.width;
213 +       q_data->height = f->fmt.pix_mp.height;
214         if (!q_data->selection_set)
215                 q_data->crop_height = requested_height;
216  
217 @@ -1134,21 +1141,21 @@ static int vidioc_s_fmt(struct bcm2835_c
218          * Copying the behaviour of vicodec which retains a single set of
219          * colorspace parameters for both input and output.
220          */
221 -       ctx->colorspace = f->fmt.pix.colorspace;
222 -       ctx->xfer_func = f->fmt.pix.xfer_func;
223 -       ctx->ycbcr_enc = f->fmt.pix.ycbcr_enc;
224 -       ctx->quant = f->fmt.pix.quantization;
225 +       ctx->colorspace = f->fmt.pix_mp.colorspace;
226 +       ctx->xfer_func = f->fmt.pix_mp.xfer_func;
227 +       ctx->ycbcr_enc = f->fmt.pix_mp.ycbcr_enc;
228 +       ctx->quant = f->fmt.pix_mp.quantization;
229  
230         /* All parameters should have been set correctly by try_fmt */
231 -       q_data->bytesperline = f->fmt.pix.bytesperline;
232 -       q_data->sizeimage = f->fmt.pix.sizeimage;
233 +       q_data->bytesperline = f->fmt.pix_mp.plane_fmt[0].bytesperline;
234 +       q_data->sizeimage = f->fmt.pix_mp.plane_fmt[0].sizeimage;
235  
236         v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "Calulated bpl as %u, size %u\n",
237                  q_data->bytesperline, q_data->sizeimage);
238  
239         if (ctx->dev->role == DECODE &&
240             q_data->fmt->flags & V4L2_FMT_FLAG_COMPRESSED &&
241 -           f->fmt.pix.width && f->fmt.pix.height) {
242 +           q_data->crop_width && q_data->height) {
243                 /*
244                  * On the decoder, if provided with a resolution on the input
245                  * side, then replicate that to the output side.
246 @@ -1165,7 +1172,7 @@ static int vidioc_s_fmt(struct bcm2835_c
247                 q_data_dst->height = ALIGN(q_data->crop_height, 16);
248  
249                 q_data_dst->bytesperline =
250 -                       get_bytesperline(f->fmt.pix.width, q_data_dst->fmt);
251 +                       get_bytesperline(f->fmt.pix_mp.width, q_data_dst->fmt);
252                 q_data_dst->sizeimage = get_sizeimage(q_data_dst->bytesperline,
253                                                       q_data_dst->crop_width,
254                                                       q_data_dst->height,
255 @@ -1215,7 +1222,7 @@ static int vidioc_s_fmt(struct bcm2835_c
256  static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
257                                 struct v4l2_format *f)
258  {
259 -       unsigned int height = f->fmt.pix.height;
260 +       unsigned int height = f->fmt.pix_mp.height;
261         int ret;
262  
263         ret = vidioc_try_fmt_vid_cap(file, priv, f);
264 @@ -1228,7 +1235,7 @@ static int vidioc_s_fmt_vid_cap(struct f
265  static int vidioc_s_fmt_vid_out(struct file *file, void *priv,
266                                 struct v4l2_format *f)
267  {
268 -       unsigned int height = f->fmt.pix.height;
269 +       unsigned int height = f->fmt.pix_mp.height;
270         int ret;
271  
272         ret = vidioc_try_fmt_vid_out(file, priv, f);
273 @@ -1244,7 +1251,7 @@ static int vidioc_g_selection(struct fil
274  {
275         struct bcm2835_codec_ctx *ctx = file2ctx(file);
276         struct bcm2835_codec_q_data *q_data;
277 -       bool capture_queue = s->type == V4L2_BUF_TYPE_VIDEO_CAPTURE ?
278 +       bool capture_queue = s->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ?
279                                                                 true : false;
280  
281         if ((ctx->dev->role == DECODE && !capture_queue) ||
282 @@ -1307,7 +1314,7 @@ static int vidioc_s_selection(struct fil
283  {
284         struct bcm2835_codec_ctx *ctx = file2ctx(file);
285         struct bcm2835_codec_q_data *q_data = NULL;
286 -       bool capture_queue = s->type == V4L2_BUF_TYPE_VIDEO_CAPTURE ?
287 +       bool capture_queue = s->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ?
288                                                                 true : false;
289  
290         v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "%s: ctx %p, type %d, q_data %p, target %d, rect x/y %d/%d, w/h %ux%u\n",
291 @@ -1368,7 +1375,7 @@ static int vidioc_s_parm(struct file *fi
292  {
293         struct bcm2835_codec_ctx *ctx = file2ctx(file);
294  
295 -       if (parm->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
296 +       if (parm->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
297                 return -EINVAL;
298  
299         ctx->framerate_num =
300 @@ -1739,14 +1746,14 @@ static const struct v4l2_ioctl_ops bcm28
301         .vidioc_querycap        = vidioc_querycap,
302  
303         .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
304 -       .vidioc_g_fmt_vid_cap   = vidioc_g_fmt_vid_cap,
305 -       .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
306 -       .vidioc_s_fmt_vid_cap   = vidioc_s_fmt_vid_cap,
307 +       .vidioc_g_fmt_vid_cap_mplane    = vidioc_g_fmt_vid_cap,
308 +       .vidioc_try_fmt_vid_cap_mplane  = vidioc_try_fmt_vid_cap,
309 +       .vidioc_s_fmt_vid_cap_mplane    = vidioc_s_fmt_vid_cap,
310  
311         .vidioc_enum_fmt_vid_out = vidioc_enum_fmt_vid_out,
312 -       .vidioc_g_fmt_vid_out   = vidioc_g_fmt_vid_out,
313 -       .vidioc_try_fmt_vid_out = vidioc_try_fmt_vid_out,
314 -       .vidioc_s_fmt_vid_out   = vidioc_s_fmt_vid_out,
315 +       .vidioc_g_fmt_vid_out_mplane    = vidioc_g_fmt_vid_out,
316 +       .vidioc_try_fmt_vid_out_mplane  = vidioc_try_fmt_vid_out,
317 +       .vidioc_s_fmt_vid_out_mplane    = vidioc_s_fmt_vid_out,
318  
319         .vidioc_reqbufs         = v4l2_m2m_ioctl_reqbufs,
320         .vidioc_querybuf        = v4l2_m2m_ioctl_querybuf,
321 @@ -2089,7 +2096,7 @@ static int bcm2835_codec_start_streaming
322                 ctx->component_enabled = true;
323         }
324  
325 -       if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
326 +       if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
327                 /*
328                  * Create the EOS buffer.
329                  * We only need the MMAL part, and want to NOT attach a memory
330 @@ -2216,7 +2223,7 @@ static int queue_init(void *priv, struct
331         struct bcm2835_codec_ctx *ctx = priv;
332         int ret;
333  
334 -       src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
335 +       src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
336         src_vq->io_modes = VB2_MMAP | VB2_DMABUF;
337         src_vq->drv_priv = ctx;
338         src_vq->buf_struct_size = sizeof(struct m2m_mmal_buffer);
339 @@ -2230,7 +2237,7 @@ static int queue_init(void *priv, struct
340         if (ret)
341                 return ret;
342  
343 -       dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
344 +       dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
345         dst_vq->io_modes = VB2_MMAP | VB2_DMABUF;
346         dst_vq->drv_priv = ctx;
347         dst_vq->buf_struct_size = sizeof(struct m2m_mmal_buffer);