1 From edd6ba8103e315dea54c1f1bdbf0562590e0acd8 Mon Sep 17 00:00:00 2001
2 From: Maxim Devaev <mdevaev@gmail.com>
3 Date: Thu, 3 Mar 2022 23:06:15 +0300
4 Subject: [PATCH] bcm2835-codec: /dev/video31 as interface to
5 image_encode JPEG encoder
7 Signed-off-by: Maxim Devaev <mdevaev@gmail.com>
9 .../bcm2835-codec/bcm2835-v4l2-codec.c | 246 ++++++++++++------
10 .../vchiq-mmal/mmal-parameters.h | 2 +
11 2 files changed, 165 insertions(+), 83 deletions(-)
13 --- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c
14 +++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c
15 @@ -62,6 +62,10 @@ static int deinterlace_video_nr = 18;
16 module_param(deinterlace_video_nr, int, 0644);
17 MODULE_PARM_DESC(deinterlace_video_nr, "deinterlace video device number");
19 +static int encode_image_nr = 31;
20 +module_param(encode_image_nr, int, 0644);
21 +MODULE_PARM_DESC(encode_image_nr, "encoder image device number");
24 * Workaround for GStreamer v4l2convert component not considering Bayer formats
25 * as raw, and therefore not considering a V4L2 device that supports them as
26 @@ -88,6 +92,7 @@ enum bcm2835_codec_role {
34 @@ -96,6 +101,7 @@ static const char * const roles[] = {
41 static const char * const components[] = {
42 @@ -103,6 +109,7 @@ static const char * const components[] =
49 /* Timeout for stop_streaming to allow all buffers to return */
50 @@ -136,6 +143,8 @@ static const char * const components[] =
52 #define DEF_COMP_BUF_SIZE_GREATER_720P (768 << 10)
53 #define DEF_COMP_BUF_SIZE_720P_OR_LESS (512 << 10)
54 +/* JPEG image can be very large. For paranoid reasons 4MB is used */
55 +#define DEF_COMP_BUF_SIZE_JPEG (4096 << 10)
57 /* Flags that indicate a format can be used for capture/output */
58 #define MEM2MEM_CAPTURE BIT(0)
59 @@ -158,63 +167,63 @@ static const struct bcm2835_codec_fmt su
61 .fourcc = V4L2_PIX_FMT_YUV420,
63 - .bytesperline_align = { 32, 64, 64, 32 },
64 + .bytesperline_align = { 32, 64, 64, 32, 32 },
66 .mmal_fmt = MMAL_ENCODING_I420,
67 .size_multiplier_x2 = 3,
69 .fourcc = V4L2_PIX_FMT_YVU420,
71 - .bytesperline_align = { 32, 64, 64, 32 },
72 + .bytesperline_align = { 32, 64, 64, 32, 32 },
74 .mmal_fmt = MMAL_ENCODING_YV12,
75 .size_multiplier_x2 = 3,
77 .fourcc = V4L2_PIX_FMT_NV12,
79 - .bytesperline_align = { 32, 32, 32, 32 },
80 + .bytesperline_align = { 32, 32, 32, 32, 32 },
82 .mmal_fmt = MMAL_ENCODING_NV12,
83 .size_multiplier_x2 = 3,
85 .fourcc = V4L2_PIX_FMT_NV21,
87 - .bytesperline_align = { 32, 32, 32, 32 },
88 + .bytesperline_align = { 32, 32, 32, 32, 32 },
90 .mmal_fmt = MMAL_ENCODING_NV21,
91 .size_multiplier_x2 = 3,
93 .fourcc = V4L2_PIX_FMT_RGB565,
95 - .bytesperline_align = { 32, 32, 32, 32 },
96 + .bytesperline_align = { 32, 32, 32, 32, 32 },
98 .mmal_fmt = MMAL_ENCODING_RGB16,
99 .size_multiplier_x2 = 2,
101 .fourcc = V4L2_PIX_FMT_YUYV,
103 - .bytesperline_align = { 32, 32, 32, 32 },
104 + .bytesperline_align = { 32, 32, 32, 32, 32 },
106 .mmal_fmt = MMAL_ENCODING_YUYV,
107 .size_multiplier_x2 = 2,
109 .fourcc = V4L2_PIX_FMT_UYVY,
111 - .bytesperline_align = { 32, 32, 32, 32 },
112 + .bytesperline_align = { 32, 32, 32, 32, 32 },
114 .mmal_fmt = MMAL_ENCODING_UYVY,
115 .size_multiplier_x2 = 2,
117 .fourcc = V4L2_PIX_FMT_YVYU,
119 - .bytesperline_align = { 32, 32, 32, 32 },
120 + .bytesperline_align = { 32, 32, 32, 32, 32 },
122 .mmal_fmt = MMAL_ENCODING_YVYU,
123 .size_multiplier_x2 = 2,
125 .fourcc = V4L2_PIX_FMT_VYUY,
127 - .bytesperline_align = { 32, 32, 32, 32 },
128 + .bytesperline_align = { 32, 32, 32, 32, 32 },
130 .mmal_fmt = MMAL_ENCODING_VYUY,
131 .size_multiplier_x2 = 2,
132 @@ -222,21 +231,21 @@ static const struct bcm2835_codec_fmt su
134 .fourcc = V4L2_PIX_FMT_RGB24,
136 - .bytesperline_align = { 32, 32, 32, 32 },
137 + .bytesperline_align = { 32, 32, 32, 32, 32 },
139 .mmal_fmt = MMAL_ENCODING_RGB24,
140 .size_multiplier_x2 = 2,
142 .fourcc = V4L2_PIX_FMT_BGR24,
144 - .bytesperline_align = { 32, 32, 32, 32 },
145 + .bytesperline_align = { 32, 32, 32, 32, 32 },
147 .mmal_fmt = MMAL_ENCODING_BGR24,
148 .size_multiplier_x2 = 2,
150 .fourcc = V4L2_PIX_FMT_BGR32,
152 - .bytesperline_align = { 32, 32, 32, 32 },
153 + .bytesperline_align = { 32, 32, 32, 32, 32 },
155 .mmal_fmt = MMAL_ENCODING_BGRA,
156 .size_multiplier_x2 = 2,
157 @@ -252,7 +261,7 @@ static const struct bcm2835_codec_fmt su
159 .fourcc = V4L2_PIX_FMT_SRGGB8,
161 - .bytesperline_align = { 32, 32, 32, 32 },
162 + .bytesperline_align = { 32, 32, 32, 32, 32 },
164 .mmal_fmt = MMAL_ENCODING_BAYER_SRGGB8,
165 .size_multiplier_x2 = 2,
166 @@ -260,7 +269,7 @@ static const struct bcm2835_codec_fmt su
168 .fourcc = V4L2_PIX_FMT_SBGGR8,
170 - .bytesperline_align = { 32, 32, 32, 32 },
171 + .bytesperline_align = { 32, 32, 32, 32, 32 },
173 .mmal_fmt = MMAL_ENCODING_BAYER_SBGGR8,
174 .size_multiplier_x2 = 2,
175 @@ -268,7 +277,7 @@ static const struct bcm2835_codec_fmt su
177 .fourcc = V4L2_PIX_FMT_SGRBG8,
179 - .bytesperline_align = { 32, 32, 32, 32 },
180 + .bytesperline_align = { 32, 32, 32, 32, 32 },
182 .mmal_fmt = MMAL_ENCODING_BAYER_SGRBG8,
183 .size_multiplier_x2 = 2,
184 @@ -276,7 +285,7 @@ static const struct bcm2835_codec_fmt su
186 .fourcc = V4L2_PIX_FMT_SGBRG8,
188 - .bytesperline_align = { 32, 32, 32, 32 },
189 + .bytesperline_align = { 32, 32, 32, 32, 32 },
191 .mmal_fmt = MMAL_ENCODING_BAYER_SGBRG8,
192 .size_multiplier_x2 = 2,
193 @@ -285,7 +294,7 @@ static const struct bcm2835_codec_fmt su
195 .fourcc = V4L2_PIX_FMT_SRGGB10P,
197 - .bytesperline_align = { 32, 32, 32, 32 },
198 + .bytesperline_align = { 32, 32, 32, 32, 32 },
200 .mmal_fmt = MMAL_ENCODING_BAYER_SRGGB10P,
201 .size_multiplier_x2 = 2,
202 @@ -293,7 +302,7 @@ static const struct bcm2835_codec_fmt su
204 .fourcc = V4L2_PIX_FMT_SBGGR10P,
206 - .bytesperline_align = { 32, 32, 32, 32 },
207 + .bytesperline_align = { 32, 32, 32, 32, 32 },
209 .mmal_fmt = MMAL_ENCODING_BAYER_SBGGR10P,
210 .size_multiplier_x2 = 2,
211 @@ -301,7 +310,7 @@ static const struct bcm2835_codec_fmt su
213 .fourcc = V4L2_PIX_FMT_SGRBG10P,
215 - .bytesperline_align = { 32, 32, 32, 32 },
216 + .bytesperline_align = { 32, 32, 32, 32, 32 },
218 .mmal_fmt = MMAL_ENCODING_BAYER_SGRBG10P,
219 .size_multiplier_x2 = 2,
220 @@ -309,7 +318,7 @@ static const struct bcm2835_codec_fmt su
222 .fourcc = V4L2_PIX_FMT_SGBRG10P,
224 - .bytesperline_align = { 32, 32, 32, 32 },
225 + .bytesperline_align = { 32, 32, 32, 32, 32 },
227 .mmal_fmt = MMAL_ENCODING_BAYER_SGBRG10P,
228 .size_multiplier_x2 = 2,
229 @@ -318,7 +327,7 @@ static const struct bcm2835_codec_fmt su
231 .fourcc = V4L2_PIX_FMT_SRGGB12P,
233 - .bytesperline_align = { 32, 32, 32, 32 },
234 + .bytesperline_align = { 32, 32, 32, 32, 32 },
236 .mmal_fmt = MMAL_ENCODING_BAYER_SRGGB12P,
237 .size_multiplier_x2 = 2,
238 @@ -326,7 +335,7 @@ static const struct bcm2835_codec_fmt su
240 .fourcc = V4L2_PIX_FMT_SBGGR12P,
242 - .bytesperline_align = { 32, 32, 32, 32 },
243 + .bytesperline_align = { 32, 32, 32, 32, 32 },
245 .mmal_fmt = MMAL_ENCODING_BAYER_SBGGR12P,
246 .size_multiplier_x2 = 2,
247 @@ -334,7 +343,7 @@ static const struct bcm2835_codec_fmt su
249 .fourcc = V4L2_PIX_FMT_SGRBG12P,
251 - .bytesperline_align = { 32, 32, 32, 32 },
252 + .bytesperline_align = { 32, 32, 32, 32, 32 },
254 .mmal_fmt = MMAL_ENCODING_BAYER_SGRBG12P,
255 .size_multiplier_x2 = 2,
256 @@ -342,7 +351,7 @@ static const struct bcm2835_codec_fmt su
258 .fourcc = V4L2_PIX_FMT_SGBRG12P,
260 - .bytesperline_align = { 32, 32, 32, 32 },
261 + .bytesperline_align = { 32, 32, 32, 32, 32 },
263 .mmal_fmt = MMAL_ENCODING_BAYER_SGBRG12P,
264 .size_multiplier_x2 = 2,
265 @@ -351,7 +360,7 @@ static const struct bcm2835_codec_fmt su
267 .fourcc = V4L2_PIX_FMT_SRGGB14P,
269 - .bytesperline_align = { 32, 32, 32, 32 },
270 + .bytesperline_align = { 32, 32, 32, 32, 32 },
272 .mmal_fmt = MMAL_ENCODING_BAYER_SRGGB14P,
273 .size_multiplier_x2 = 2,
274 @@ -359,7 +368,7 @@ static const struct bcm2835_codec_fmt su
276 .fourcc = V4L2_PIX_FMT_SBGGR14P,
278 - .bytesperline_align = { 32, 32, 32, 32 },
279 + .bytesperline_align = { 32, 32, 32, 32, 32 },
281 .mmal_fmt = MMAL_ENCODING_BAYER_SBGGR14P,
282 .size_multiplier_x2 = 2,
283 @@ -368,7 +377,7 @@ static const struct bcm2835_codec_fmt su
285 .fourcc = V4L2_PIX_FMT_SGRBG14P,
287 - .bytesperline_align = { 32, 32, 32, 32 },
288 + .bytesperline_align = { 32, 32, 32, 32, 32 },
290 .mmal_fmt = MMAL_ENCODING_BAYER_SGRBG14P,
291 .size_multiplier_x2 = 2,
292 @@ -376,7 +385,7 @@ static const struct bcm2835_codec_fmt su
294 .fourcc = V4L2_PIX_FMT_SGBRG14P,
296 - .bytesperline_align = { 32, 32, 32, 32 },
297 + .bytesperline_align = { 32, 32, 32, 32, 32 },
299 .mmal_fmt = MMAL_ENCODING_BAYER_SGBRG14P,
300 .size_multiplier_x2 = 2,
301 @@ -385,7 +394,7 @@ static const struct bcm2835_codec_fmt su
303 .fourcc = V4L2_PIX_FMT_SRGGB16,
305 - .bytesperline_align = { 32, 32, 32, 32 },
306 + .bytesperline_align = { 32, 32, 32, 32, 32 },
308 .mmal_fmt = MMAL_ENCODING_BAYER_SRGGB16,
309 .size_multiplier_x2 = 2,
310 @@ -393,7 +402,7 @@ static const struct bcm2835_codec_fmt su
312 .fourcc = V4L2_PIX_FMT_SBGGR16,
314 - .bytesperline_align = { 32, 32, 32, 32 },
315 + .bytesperline_align = { 32, 32, 32, 32, 32 },
317 .mmal_fmt = MMAL_ENCODING_BAYER_SBGGR16,
318 .size_multiplier_x2 = 2,
319 @@ -401,7 +410,7 @@ static const struct bcm2835_codec_fmt su
321 .fourcc = V4L2_PIX_FMT_SGRBG16,
323 - .bytesperline_align = { 32, 32, 32, 32 },
324 + .bytesperline_align = { 32, 32, 32, 32, 32 },
326 .mmal_fmt = MMAL_ENCODING_BAYER_SGRBG16,
327 .size_multiplier_x2 = 2,
328 @@ -409,7 +418,7 @@ static const struct bcm2835_codec_fmt su
330 .fourcc = V4L2_PIX_FMT_SGBRG16,
332 - .bytesperline_align = { 32, 32, 32, 32 },
333 + .bytesperline_align = { 32, 32, 32, 32, 32 },
335 .mmal_fmt = MMAL_ENCODING_BAYER_SGBRG16,
336 .size_multiplier_x2 = 2,
337 @@ -419,7 +428,7 @@ static const struct bcm2835_codec_fmt su
339 .fourcc = V4L2_PIX_FMT_SRGGB10,
341 - .bytesperline_align = { 32, 32, 32, 32 },
342 + .bytesperline_align = { 32, 32, 32, 32, 32 },
344 .mmal_fmt = MMAL_ENCODING_BAYER_SRGGB10,
345 .size_multiplier_x2 = 2,
346 @@ -427,7 +436,7 @@ static const struct bcm2835_codec_fmt su
348 .fourcc = V4L2_PIX_FMT_SBGGR10,
350 - .bytesperline_align = { 32, 32, 32, 32 },
351 + .bytesperline_align = { 32, 32, 32, 32, 32 },
353 .mmal_fmt = MMAL_ENCODING_BAYER_SBGGR10,
354 .size_multiplier_x2 = 2,
355 @@ -435,7 +444,7 @@ static const struct bcm2835_codec_fmt su
357 .fourcc = V4L2_PIX_FMT_SGRBG10,
359 - .bytesperline_align = { 32, 32, 32, 32 },
360 + .bytesperline_align = { 32, 32, 32, 32, 32 },
362 .mmal_fmt = MMAL_ENCODING_BAYER_SGRBG10,
363 .size_multiplier_x2 = 2,
364 @@ -443,7 +452,7 @@ static const struct bcm2835_codec_fmt su
366 .fourcc = V4L2_PIX_FMT_SGBRG10,
368 - .bytesperline_align = { 32, 32, 32, 32 },
369 + .bytesperline_align = { 32, 32, 32, 32, 32 },
371 .mmal_fmt = MMAL_ENCODING_BAYER_SGBRG10,
372 .size_multiplier_x2 = 2,
373 @@ -452,7 +461,7 @@ static const struct bcm2835_codec_fmt su
375 .fourcc = V4L2_PIX_FMT_SRGGB12,
377 - .bytesperline_align = { 32, 32, 32, 32 },
378 + .bytesperline_align = { 32, 32, 32, 32, 32 },
380 .mmal_fmt = MMAL_ENCODING_BAYER_SRGGB12,
381 .size_multiplier_x2 = 2,
382 @@ -460,7 +469,7 @@ static const struct bcm2835_codec_fmt su
384 .fourcc = V4L2_PIX_FMT_SBGGR12,
386 - .bytesperline_align = { 32, 32, 32, 32 },
387 + .bytesperline_align = { 32, 32, 32, 32, 32 },
389 .mmal_fmt = MMAL_ENCODING_BAYER_SBGGR12,
390 .size_multiplier_x2 = 2,
391 @@ -468,7 +477,7 @@ static const struct bcm2835_codec_fmt su
393 .fourcc = V4L2_PIX_FMT_SGRBG12,
395 - .bytesperline_align = { 32, 32, 32, 32 },
396 + .bytesperline_align = { 32, 32, 32, 32, 32 },
398 .mmal_fmt = MMAL_ENCODING_BAYER_SGRBG12,
399 .size_multiplier_x2 = 2,
400 @@ -476,7 +485,7 @@ static const struct bcm2835_codec_fmt su
402 .fourcc = V4L2_PIX_FMT_SGBRG12,
404 - .bytesperline_align = { 32, 32, 32, 32 },
405 + .bytesperline_align = { 32, 32, 32, 32, 32 },
407 .mmal_fmt = MMAL_ENCODING_BAYER_SGBRG12,
408 .size_multiplier_x2 = 2,
409 @@ -485,7 +494,7 @@ static const struct bcm2835_codec_fmt su
411 .fourcc = V4L2_PIX_FMT_SRGGB14,
413 - .bytesperline_align = { 32, 32, 32, 32 },
414 + .bytesperline_align = { 32, 32, 32, 32, 32 },
416 .mmal_fmt = MMAL_ENCODING_BAYER_SRGGB14,
417 .size_multiplier_x2 = 2,
418 @@ -493,7 +502,7 @@ static const struct bcm2835_codec_fmt su
420 .fourcc = V4L2_PIX_FMT_SBGGR14,
422 - .bytesperline_align = { 32, 32, 32, 32 },
423 + .bytesperline_align = { 32, 32, 32, 32, 32 },
425 .mmal_fmt = MMAL_ENCODING_BAYER_SBGGR14,
426 .size_multiplier_x2 = 2,
427 @@ -501,7 +510,7 @@ static const struct bcm2835_codec_fmt su
429 .fourcc = V4L2_PIX_FMT_SGRBG14,
431 - .bytesperline_align = { 32, 32, 32, 32 },
432 + .bytesperline_align = { 32, 32, 32, 32, 32 },
434 .mmal_fmt = MMAL_ENCODING_BAYER_SGRBG14,
435 .size_multiplier_x2 = 2,
436 @@ -509,7 +518,7 @@ static const struct bcm2835_codec_fmt su
438 .fourcc = V4L2_PIX_FMT_SGBRG14,
440 - .bytesperline_align = { 32, 32, 32, 32 },
441 + .bytesperline_align = { 32, 32, 32, 32, 32 },
443 .mmal_fmt = MMAL_ENCODING_BAYER_SGBRG14,
444 .size_multiplier_x2 = 2,
445 @@ -519,7 +528,7 @@ static const struct bcm2835_codec_fmt su
447 .fourcc = V4L2_PIX_FMT_GREY,
449 - .bytesperline_align = { 32, 32, 32, 32 },
450 + .bytesperline_align = { 32, 32, 32, 32, 32 },
452 .mmal_fmt = MMAL_ENCODING_GREY,
453 .size_multiplier_x2 = 2,
454 @@ -527,7 +536,7 @@ static const struct bcm2835_codec_fmt su
456 .fourcc = V4L2_PIX_FMT_Y10P,
458 - .bytesperline_align = { 32, 32, 32, 32 },
459 + .bytesperline_align = { 32, 32, 32, 32, 32 },
461 .mmal_fmt = MMAL_ENCODING_Y10P,
462 .size_multiplier_x2 = 2,
463 @@ -535,7 +544,7 @@ static const struct bcm2835_codec_fmt su
465 .fourcc = V4L2_PIX_FMT_Y12P,
467 - .bytesperline_align = { 32, 32, 32, 32 },
468 + .bytesperline_align = { 32, 32, 32, 32, 32 },
470 .mmal_fmt = MMAL_ENCODING_Y12P,
471 .size_multiplier_x2 = 2,
472 @@ -543,7 +552,7 @@ static const struct bcm2835_codec_fmt su
474 .fourcc = V4L2_PIX_FMT_Y14P,
476 - .bytesperline_align = { 32, 32, 32, 32 },
477 + .bytesperline_align = { 32, 32, 32, 32, 32 },
479 .mmal_fmt = MMAL_ENCODING_Y14P,
480 .size_multiplier_x2 = 2,
481 @@ -551,7 +560,7 @@ static const struct bcm2835_codec_fmt su
483 .fourcc = V4L2_PIX_FMT_Y16,
485 - .bytesperline_align = { 32, 32, 32, 32 },
486 + .bytesperline_align = { 32, 32, 32, 32, 32 },
488 .mmal_fmt = MMAL_ENCODING_Y16,
489 .size_multiplier_x2 = 2,
490 @@ -559,7 +568,7 @@ static const struct bcm2835_codec_fmt su
491 /* 10 bit as 16bpp */
492 .fourcc = V4L2_PIX_FMT_Y10,
494 - .bytesperline_align = { 32, 32, 32, 32 },
495 + .bytesperline_align = { 32, 32, 32, 32, 32 },
497 .mmal_fmt = MMAL_ENCODING_Y10,
498 .size_multiplier_x2 = 2,
499 @@ -567,7 +576,7 @@ static const struct bcm2835_codec_fmt su
500 /* 12 bit as 16bpp */
501 .fourcc = V4L2_PIX_FMT_Y12,
503 - .bytesperline_align = { 32, 32, 32, 32 },
504 + .bytesperline_align = { 32, 32, 32, 32, 32 },
506 .mmal_fmt = MMAL_ENCODING_Y12,
507 .size_multiplier_x2 = 2,
508 @@ -575,7 +584,7 @@ static const struct bcm2835_codec_fmt su
509 /* 14 bit as 16bpp */
510 .fourcc = V4L2_PIX_FMT_Y14,
512 - .bytesperline_align = { 32, 32, 32, 32 },
513 + .bytesperline_align = { 32, 32, 32, 32, 32 },
515 .mmal_fmt = MMAL_ENCODING_Y14,
516 .size_multiplier_x2 = 2,
517 @@ -586,6 +595,11 @@ static const struct bcm2835_codec_fmt su
518 .flags = V4L2_FMT_FLAG_COMPRESSED,
519 .mmal_fmt = MMAL_ENCODING_H264,
521 + .fourcc = V4L2_PIX_FMT_JPEG,
523 + .flags = V4L2_FMT_FLAG_COMPRESSED,
524 + .mmal_fmt = MMAL_ENCODING_JPEG,
526 .fourcc = V4L2_PIX_FMT_MJPEG,
528 .flags = V4L2_FMT_FLAG_COMPRESSED,
529 @@ -705,6 +719,7 @@ struct bcm2835_codec_driver {
530 struct bcm2835_codec_dev *decode;
531 struct bcm2835_codec_dev *isp;
532 struct bcm2835_codec_dev *deinterlace;
533 + struct bcm2835_codec_dev *encode_image;
537 @@ -838,6 +853,9 @@ static inline unsigned int get_sizeimage
538 struct bcm2835_codec_fmt *fmt)
540 if (fmt->flags & V4L2_FMT_FLAG_COMPRESSED) {
541 + if (fmt->fourcc == V4L2_PIX_FMT_JPEG)
542 + return DEF_COMP_BUF_SIZE_JPEG;
544 if (width * height > 1280 * 720)
545 return DEF_COMP_BUF_SIZE_GREATER_720P;
547 @@ -1422,12 +1440,12 @@ static int vidioc_try_fmt(struct bcm2835
548 f->fmt.pix_mp.height = MIN_H;
551 - * For decoders the buffer must have a vertical alignment of 16
553 + * For decoders and image encoders the buffer must have
554 + * a vertical alignment of 16 lines.
555 * The selection will reflect any cropping rectangle when only
556 * some of the pixels are active.
558 - if (ctx->dev->role == DECODE)
559 + if (ctx->dev->role == DECODE || ctx->dev->role == ENCODE_IMAGE)
560 f->fmt.pix_mp.height = ALIGN(f->fmt.pix_mp.height, 16);
562 f->fmt.pix_mp.num_planes = 1;
563 @@ -1573,12 +1591,13 @@ static int vidioc_s_fmt(struct bcm2835_c
564 v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "Calculated bpl as %u, size %u\n",
565 q_data->bytesperline, q_data->sizeimage);
567 - if (ctx->dev->role == DECODE &&
568 + if ((ctx->dev->role == DECODE || ctx->dev->role == ENCODE_IMAGE) &&
569 q_data->fmt->flags & V4L2_FMT_FLAG_COMPRESSED &&
570 q_data->crop_width && q_data->height) {
572 - * On the decoder, if provided with a resolution on the input
573 - * side, then replicate that to the output side.
574 + * On the decoder or image encoder, if provided with
575 + * a resolution on the input side, then replicate that
576 + * to the output side.
577 * GStreamer appears not to support V4L2_EVENT_SOURCE_CHANGE,
578 * nor set up a resolution on the output side, therefore
579 * we can't decode anything at a resolution other than the
580 @@ -1719,7 +1738,7 @@ static int vidioc_g_selection(struct fil
582 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
583 /* CAPTURE on encoder is not valid. */
584 - if (ctx->dev->role == ENCODE)
585 + if (ctx->dev->role == ENCODE || ctx->dev->role == ENCODE_IMAGE)
587 q_data = &ctx->q_data[V4L2_M2M_DST];
589 @@ -1762,6 +1781,7 @@ static int vidioc_g_selection(struct fil
595 case V4L2_SEL_TGT_CROP_DEFAULT:
596 case V4L2_SEL_TGT_CROP_BOUNDS:
597 @@ -1846,7 +1866,7 @@ static int vidioc_s_selection(struct fil
599 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
600 /* CAPTURE on encoder is not valid. */
601 - if (ctx->dev->role == ENCODE)
602 + if (ctx->dev->role == ENCODE || ctx->dev->role == ENCODE_IMAGE)
604 q_data = &ctx->q_data[V4L2_M2M_DST];
606 @@ -1882,6 +1902,7 @@ static int vidioc_s_selection(struct fil
612 case V4L2_SEL_TGT_CROP:
613 /* Only support crop from (0,0) */
614 @@ -2266,6 +2287,16 @@ static int bcm2835_codec_s_ctrl(struct v
618 + case V4L2_CID_JPEG_COMPRESSION_QUALITY:
619 + if (!ctx->component)
622 + ret = vchiq_mmal_port_parameter_set(ctx->dev->instance,
623 + &ctx->component->output[0],
624 + MMAL_PARAMETER_JPEG_Q_FACTOR,
626 + sizeof(ctrl->val));
630 v4l2_err(&ctx->dev->v4l2_dev, "Invalid control\n");
631 @@ -2364,7 +2395,7 @@ static int vidioc_try_encoder_cmd(struct
633 struct bcm2835_codec_ctx *ctx = file2ctx(file);
635 - if (ctx->dev->role != ENCODE)
636 + if (ctx->dev->role != ENCODE && ctx->dev->role != ENCODE_IMAGE)
640 @@ -2567,6 +2598,20 @@ static int bcm2835_codec_create_componen
641 MMAL_PARAMETER_IMAGE_EFFECT_PARAMETERS,
645 + } else if (dev->role == ENCODE_IMAGE) {
647 + vchiq_mmal_port_parameter_set(dev->instance,
648 + &ctx->component->control,
649 + MMAL_PARAMETER_EXIF_DISABLE,
653 + vchiq_mmal_port_parameter_set(dev->instance,
654 + &ctx->component->output[0],
655 + MMAL_PARAMETER_JPEG_IJG_SCALING,
660 setup_mmal_port_format(ctx, &ctx->q_data[V4L2_M2M_SRC],
661 @@ -2595,7 +2640,7 @@ static int bcm2835_codec_create_componen
662 goto destroy_component;
665 - if (dev->role == ENCODE) {
666 + if (dev->role == ENCODE || dev->role == ENCODE_IMAGE) {
669 if (ctx->q_data[V4L2_M2M_SRC].sizeimage <
670 @@ -2604,27 +2649,29 @@ static int bcm2835_codec_create_componen
671 ctx->q_data[V4L2_M2M_SRC].sizeimage,
672 ctx->component->output[0].minimum_buffer.size);
674 - /* Enable SPS Timing header so framerate information is encoded
675 - * in the H264 header.
677 - vchiq_mmal_port_parameter_set(ctx->dev->instance,
678 - &ctx->component->output[0],
679 - MMAL_PARAMETER_VIDEO_ENCODE_SPS_TIMING,
680 - ¶m, sizeof(param));
682 - /* Enable inserting headers into the first frame */
683 - vchiq_mmal_port_parameter_set(ctx->dev->instance,
684 - &ctx->component->control,
685 - MMAL_PARAMETER_VIDEO_ENCODE_HEADERS_WITH_FRAME,
686 - ¶m, sizeof(param));
688 - * Avoid fragmenting the buffers over multiple frames (unless
689 - * the frame is bigger than the whole buffer)
691 - vchiq_mmal_port_parameter_set(ctx->dev->instance,
692 - &ctx->component->control,
693 - MMAL_PARAMETER_MINIMISE_FRAGMENTATION,
694 - ¶m, sizeof(param));
695 + if (dev->role == ENCODE) {
696 + /* Enable SPS Timing header so framerate information is encoded
697 + * in the H264 header.
699 + vchiq_mmal_port_parameter_set(ctx->dev->instance,
700 + &ctx->component->output[0],
701 + MMAL_PARAMETER_VIDEO_ENCODE_SPS_TIMING,
702 + ¶m, sizeof(param));
704 + /* Enable inserting headers into the first frame */
705 + vchiq_mmal_port_parameter_set(ctx->dev->instance,
706 + &ctx->component->control,
707 + MMAL_PARAMETER_VIDEO_ENCODE_HEADERS_WITH_FRAME,
708 + ¶m, sizeof(param));
710 + * Avoid fragmenting the buffers over multiple frames (unless
711 + * the frame is bigger than the whole buffer)
713 + vchiq_mmal_port_parameter_set(ctx->dev->instance,
714 + &ctx->component->control,
715 + MMAL_PARAMETER_MINIMISE_FRAGMENTATION,
716 + ¶m, sizeof(param));
719 if (ctx->q_data[V4L2_M2M_DST].sizeimage <
720 ctx->component->output[0].minimum_buffer.size)
721 @@ -3248,6 +3295,23 @@ static int bcm2835_codec_open(struct fil
722 v4l2_ctrl_handler_init(hdl, 0);
727 + /* Encode image controls */
728 + v4l2_ctrl_handler_init(hdl, 1);
730 + v4l2_ctrl_new_std(hdl, &bcm2835_codec_ctrl_ops,
731 + V4L2_CID_JPEG_COMPRESSION_QUALITY,
736 + goto free_ctrl_handler;
738 + ctx->fh.ctrl_handler = hdl;
739 + v4l2_ctrl_handler_setup(hdl);
745 @@ -3527,6 +3591,12 @@ static int bcm2835_codec_create(struct b
746 function = MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER;
747 video_nr = deinterlace_video_nr;
750 + v4l2_disable_ioctl(vfd, VIDIOC_DECODER_CMD);
751 + v4l2_disable_ioctl(vfd, VIDIOC_TRY_DECODER_CMD);
752 + function = MEDIA_ENT_F_PROC_VIDEO_ENCODER;
753 + video_nr = encode_image_nr;
758 @@ -3626,6 +3696,10 @@ static int bcm2835_codec_probe(struct pl
762 + ret = bcm2835_codec_create(drv, &drv->encode_image, ENCODE_IMAGE);
766 /* Register the media device node */
767 if (media_device_register(mdev) < 0)
769 @@ -3635,6 +3709,10 @@ static int bcm2835_codec_probe(struct pl
773 + if (drv->encode_image) {
774 + bcm2835_codec_destroy(drv->encode_image);
775 + drv->encode_image = NULL;
777 if (drv->deinterlace) {
778 bcm2835_codec_destroy(drv->deinterlace);
779 drv->deinterlace = NULL;
780 @@ -3660,6 +3738,8 @@ static int bcm2835_codec_remove(struct p
782 media_device_unregister(&drv->mdev);
784 + bcm2835_codec_destroy(drv->encode_image);
786 bcm2835_codec_destroy(drv->deinterlace);
788 bcm2835_codec_destroy(drv->isp);
789 --- a/drivers/staging/vc04_services/vchiq-mmal/mmal-parameters.h
790 +++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-parameters.h
791 @@ -279,6 +279,8 @@ enum mmal_parameter_camera_type {
792 MMAL_PARAMETER_GAMMA,
793 /**< Takes a @ref MMAL_PARAMETER_CDN_T */
795 + /**< Takes a @ref MMAL_PARAMETER_BOOLEAN_T */
796 + MMAL_PARAMETER_JPEG_IJG_SCALING,
799 struct mmal_parameter_rational {