1 From 6fe43df9941cbd4810c4fcd02e49156a85180c16 Mon Sep 17 00:00:00 2001
2 From: Dave Stevenson <dave.stevenson@raspberrypi.org>
3 Date: Wed, 13 Feb 2019 14:07:52 +0000
4 Subject: [PATCH] staging: bcm2835_codec: Add support for the ISP as an
7 The MMAL ISP component can also use this same V4L2 wrapper to
8 provide a M2M format conversion and resizer.
9 Instantiate 3 V4L2 devices now, one for each of decode, encode,
11 The ISP currently doesn't expose any controls via V4L2, but this
12 can be extended in the future.
14 Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org>
16 .../bcm2835-codec/bcm2835-v4l2-codec.c | 132 ++++++++++++------
17 1 file changed, 92 insertions(+), 40 deletions(-)
19 --- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c
20 +++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c
21 @@ -54,10 +54,26 @@ static int encode_video_nr = 11;
22 module_param(encode_video_nr, int, 0644);
23 MODULE_PARM_DESC(encode_video_nr, "encoder video device number");
25 +static int isp_video_nr = 12;
26 +module_param(isp_video_nr, int, 0644);
27 +MODULE_PARM_DESC(isp_video_nr, "isp video device number");
29 static unsigned int debug;
30 module_param(debug, uint, 0644);
31 MODULE_PARM_DESC(debug, "activates debug info (0-3)");
33 +enum bcm2835_codec_role {
39 +static const char * const components[] = {
48 @@ -373,7 +389,7 @@ struct bcm2835_codec_dev {
51 /* allocated mmal instance and components */
52 - bool decode; /* Is this instance a decoder? */
53 + enum bcm2835_codec_role role;
54 /* The list of formats supported on input and output queues. */
55 struct bcm2835_codec_fmt_list supported_fmts[2];
57 @@ -558,7 +574,7 @@ static void setup_mmal_port_format(struc
58 port->es.video.frame_rate.den = 1;
60 /* Compressed format - leave resolution as 0 for decode */
61 - if (ctx->dev->decode) {
62 + if (ctx->dev->role == DECODE) {
63 port->es.video.width = 0;
64 port->es.video.height = 0;
65 port->es.video.crop.width = 0;
66 @@ -1089,7 +1105,8 @@ static int vidioc_s_fmt(struct bcm2835_c
67 v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "Calulated bpl as %u, size %u\n",
68 q_data->bytesperline, q_data->sizeimage);
70 - if (ctx->dev->decode && q_data->fmt->flags & V4L2_FMT_FLAG_COMPRESSED &&
71 + if (ctx->dev->role == DECODE &&
72 + q_data->fmt->flags & V4L2_FMT_FLAG_COMPRESSED &&
73 f->fmt.pix.width && f->fmt.pix.height) {
75 * On the decoder, if provided with a resolution on the input
76 @@ -1188,7 +1205,8 @@ static int vidioc_g_selection(struct fil
77 bool capture_queue = s->type == V4L2_BUF_TYPE_VIDEO_CAPTURE ?
80 - if (capture_queue ^ ctx->dev->decode)
81 + if ((ctx->dev->role == DECODE && !capture_queue) ||
82 + (ctx->dev->role == ENCODE && capture_queue))
83 /* OUTPUT on decoder and CAPTURE on encoder are not valid. */
86 @@ -1196,7 +1214,8 @@ static int vidioc_g_selection(struct fil
90 - if (ctx->dev->decode) {
91 + switch (ctx->dev->role) {
94 case V4L2_SEL_TGT_COMPOSE_DEFAULT:
95 case V4L2_SEL_TGT_COMPOSE:
96 @@ -1214,7 +1233,8 @@ static int vidioc_g_selection(struct fil
104 case V4L2_SEL_TGT_CROP_DEFAULT:
105 case V4L2_SEL_TGT_CROP_BOUNDS:
106 @@ -1232,6 +1252,9 @@ static int vidioc_g_selection(struct fil
116 @@ -1249,7 +1272,8 @@ static int vidioc_s_selection(struct fil
117 __func__, ctx, s->type, q_data, s->target, s->r.left, s->r.top,
118 s->r.width, s->r.height);
120 - if (capture_queue ^ ctx->dev->decode)
121 + if ((ctx->dev->role == DECODE && !capture_queue) ||
122 + (ctx->dev->role == ENCODE && capture_queue))
123 /* OUTPUT on decoder and CAPTURE on encoder are not valid. */
126 @@ -1257,7 +1281,8 @@ static int vidioc_s_selection(struct fil
130 - if (ctx->dev->decode) {
131 + switch (ctx->dev->role) {
134 case V4L2_SEL_TGT_COMPOSE:
135 /* Accept cropped image */
136 @@ -1272,7 +1297,8 @@ static int vidioc_s_selection(struct fil
144 case V4L2_SEL_TGT_CROP:
145 /* Only support crop from (0,0) */
146 @@ -1287,6 +1313,9 @@ static int vidioc_s_selection(struct fil
156 @@ -1490,7 +1519,7 @@ static int vidioc_try_decoder_cmd(struct
158 struct bcm2835_codec_ctx *ctx = file2ctx(file);
160 - if (!ctx->dev->decode)
161 + if (ctx->dev->role != DECODE)
165 @@ -1564,7 +1593,7 @@ static int vidioc_try_encoder_cmd(struct
167 struct bcm2835_codec_ctx *ctx = file2ctx(file);
169 - if (ctx->dev->decode)
170 + if (ctx->dev->role != ENCODE)
174 @@ -1697,12 +1726,11 @@ static int bcm2835_codec_create_componen
175 unsigned int enable = 1;
178 - ret = vchiq_mmal_component_init(dev->instance, dev->decode ?
179 - "ril.video_decode" : "ril.video_encode",
180 + ret = vchiq_mmal_component_init(dev->instance, components[dev->role],
183 - v4l2_err(&dev->v4l2_dev, "%s: failed to create component for %s\n",
184 - __func__, dev->decode ? "decode" : "encode");
185 + v4l2_err(&dev->v4l2_dev, "%s: failed to create component %s\n",
186 + __func__, components[dev->role]);
190 @@ -1729,13 +1757,7 @@ static int bcm2835_codec_create_componen
192 goto destroy_component;
195 - if (ctx->q_data[V4L2_M2M_DST].sizeimage <
196 - ctx->component->output[0].minimum_buffer.size)
197 - v4l2_err(&dev->v4l2_dev, "buffer size mismatch sizeimage %u < min size %u\n",
198 - ctx->q_data[V4L2_M2M_DST].sizeimage,
199 - ctx->component->output[0].minimum_buffer.size);
201 + if (dev->role == ENCODE) {
202 if (ctx->q_data[V4L2_M2M_SRC].sizeimage <
203 ctx->component->output[0].minimum_buffer.size)
204 v4l2_err(&dev->v4l2_dev, "buffer size mismatch sizeimage %u < min size %u\n",
205 @@ -1744,6 +1766,12 @@ static int bcm2835_codec_create_componen
207 /* Now we have a component we can set all the ctrls */
208 bcm2835_codec_set_ctrls(ctx);
210 + if (ctx->q_data[V4L2_M2M_DST].sizeimage <
211 + ctx->component->output[0].minimum_buffer.size)
212 + v4l2_err(&dev->v4l2_dev, "buffer size mismatch sizeimage %u < min size %u\n",
213 + ctx->q_data[V4L2_M2M_DST].sizeimage,
214 + ctx->component->output[0].minimum_buffer.size);
218 @@ -2090,8 +2118,6 @@ static int bcm2835_codec_open(struct fil
219 struct v4l2_ctrl_handler *hdl;
222 - v4l2_dbg(1, debug, &dev->v4l2_dev, "Creating instance for %s\n",
223 - dev->decode ? "decode" : "encode");
224 if (mutex_lock_interruptible(&dev->dev_mutex)) {
225 v4l2_err(&dev->v4l2_dev, "Mutex fail\n");
227 @@ -2104,7 +2130,8 @@ static int bcm2835_codec_open(struct fil
229 ctx->q_data[V4L2_M2M_SRC].fmt = get_default_format(dev, false);
230 ctx->q_data[V4L2_M2M_DST].fmt = get_default_format(dev, true);
232 + switch (dev->role) {
235 * Input width and height are irrelevant as they will be defined
236 * by the bitstream not the format. Required by V4L2 though.
237 @@ -2126,7 +2153,8 @@ static int bcm2835_codec_open(struct fil
238 get_sizeimage(ctx->q_data[V4L2_M2M_DST].bytesperline,
239 ctx->q_data[V4L2_M2M_DST].height,
240 ctx->q_data[V4L2_M2M_DST].fmt);
244 ctx->q_data[V4L2_M2M_SRC].crop_width = DEFAULT_WIDTH;
245 ctx->q_data[V4L2_M2M_SRC].crop_height = DEFAULT_HEIGHT;
246 ctx->q_data[V4L2_M2M_SRC].height = DEFAULT_HEIGHT;
247 @@ -2144,6 +2172,9 @@ static int bcm2835_codec_open(struct fil
248 ctx->q_data[V4L2_M2M_DST].height = DEFAULT_HEIGHT;
249 ctx->q_data[V4L2_M2M_DST].sizeimage =
250 DEF_COMP_BUF_SIZE_720P_OR_LESS;
256 ctx->colorspace = V4L2_COLORSPACE_REC709;
257 @@ -2154,7 +2185,7 @@ static int bcm2835_codec_open(struct fil
258 file->private_data = &ctx->fh;
261 - if (!dev->decode) {
262 + if (dev->role == ENCODE) {
263 /* Encode controls */
264 v4l2_ctrl_handler_init(hdl, 6);
266 @@ -2303,14 +2334,11 @@ static int bcm2835_codec_get_supported_f
267 unsigned int i, j, num_encodings;
270 - ret = vchiq_mmal_component_init(dev->instance,
272 - "ril.video_decode" :
273 - "ril.video_encode",
274 + ret = vchiq_mmal_component_init(dev->instance, components[dev->role],
277 - v4l2_err(&dev->v4l2_dev, "%s: failed to create component\n",
279 + v4l2_err(&dev->v4l2_dev, "%s: failed to create component %s\n",
280 + __func__, components[dev->role]);
284 @@ -2406,12 +2434,13 @@ destroy_component:
286 static int bcm2835_codec_create(struct platform_device *pdev,
287 struct bcm2835_codec_dev **new_dev,
289 + enum bcm2835_codec_role role)
291 struct bcm2835_codec_dev *dev;
292 struct video_device *vfd;
295 + const static char *roles[] = {"decode", "encode", "isp"};
297 dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
299 @@ -2419,7 +2448,7 @@ static int bcm2835_codec_create(struct p
303 - dev->decode = decode;
306 ret = vchiq_mmal_init(&dev->instance);
308 @@ -2441,14 +2470,27 @@ static int bcm2835_codec_create(struct p
309 vfd->lock = &dev->dev_mutex;
310 vfd->v4l2_dev = &dev->v4l2_dev;
315 v4l2_disable_ioctl(vfd, VIDIOC_ENCODER_CMD);
316 v4l2_disable_ioctl(vfd, VIDIOC_TRY_ENCODER_CMD);
317 video_nr = decode_video_nr;
321 v4l2_disable_ioctl(vfd, VIDIOC_DECODER_CMD);
322 v4l2_disable_ioctl(vfd, VIDIOC_TRY_DECODER_CMD);
323 video_nr = encode_video_nr;
326 + v4l2_disable_ioctl(vfd, VIDIOC_ENCODER_CMD);
327 + v4l2_disable_ioctl(vfd, VIDIOC_TRY_ENCODER_CMD);
328 + v4l2_disable_ioctl(vfd, VIDIOC_DECODER_CMD);
329 + v4l2_disable_ioctl(vfd, VIDIOC_TRY_DECODER_CMD);
330 + video_nr = isp_video_nr;
337 ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr);
338 @@ -2473,7 +2515,7 @@ static int bcm2835_codec_create(struct p
341 v4l2_info(&dev->v4l2_dev, "Loaded V4L2 %s\n",
342 - dev->decode ? "decode" : "encode");
347 @@ -2509,11 +2551,15 @@ static int bcm2835_codec_probe(struct pl
351 - ret = bcm2835_codec_create(pdev, &drv->encode, false);
352 + ret = bcm2835_codec_create(pdev, &drv->decode, DECODE);
356 - ret = bcm2835_codec_create(pdev, &drv->decode, true);
357 + ret = bcm2835_codec_create(pdev, &drv->encode, ENCODE);
361 + ret = bcm2835_codec_create(pdev, &drv->isp, ISP);
365 @@ -2526,6 +2572,10 @@ out:
366 bcm2835_codec_destroy(drv->encode);
370 + bcm2835_codec_destroy(drv->decode);
371 + drv->decode = NULL;
376 @@ -2533,6 +2583,8 @@ static int bcm2835_codec_remove(struct p
378 struct bcm2835_codec_driver *drv = platform_get_drvdata(pdev);
380 + bcm2835_codec_destroy(drv->isp);
382 bcm2835_codec_destroy(drv->encode);
384 bcm2835_codec_destroy(drv->decode);