fab3445af7fcfbd05cadf4b39485dddc86a0108f
[openwrt/staging/neocturne.git] /
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
6
7 Signed-off-by: Maxim Devaev <mdevaev@gmail.com>
8 ---
9 .../bcm2835-codec/bcm2835-v4l2-codec.c | 246 ++++++++++++------
10 .../vchiq-mmal/mmal-parameters.h | 2 +
11 2 files changed, 165 insertions(+), 83 deletions(-)
12
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");
18
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");
22 +
23 /*
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 {
27 ENCODE,
28 ISP,
29 DEINTERLACE,
30 + ENCODE_IMAGE,
31 NUM_ROLES
32 };
33
34 @@ -96,6 +101,7 @@ static const char * const roles[] = {
35 "encode",
36 "isp",
37 "image_fx",
38 + "encode_image",
39 };
40
41 static const char * const components[] = {
42 @@ -103,6 +109,7 @@ static const char * const components[] =
43 "ril.video_encode",
44 "ril.isp",
45 "ril.image_fx",
46 + "ril.image_encode",
47 };
48
49 /* Timeout for stop_streaming to allow all buffers to return */
50 @@ -136,6 +143,8 @@ static const char * const components[] =
51 */
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)
56
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
60 /* YUV formats */
61 .fourcc = V4L2_PIX_FMT_YUV420,
62 .depth = 8,
63 - .bytesperline_align = { 32, 64, 64, 32 },
64 + .bytesperline_align = { 32, 64, 64, 32, 32 },
65 .flags = 0,
66 .mmal_fmt = MMAL_ENCODING_I420,
67 .size_multiplier_x2 = 3,
68 }, {
69 .fourcc = V4L2_PIX_FMT_YVU420,
70 .depth = 8,
71 - .bytesperline_align = { 32, 64, 64, 32 },
72 + .bytesperline_align = { 32, 64, 64, 32, 32 },
73 .flags = 0,
74 .mmal_fmt = MMAL_ENCODING_YV12,
75 .size_multiplier_x2 = 3,
76 }, {
77 .fourcc = V4L2_PIX_FMT_NV12,
78 .depth = 8,
79 - .bytesperline_align = { 32, 32, 32, 32 },
80 + .bytesperline_align = { 32, 32, 32, 32, 32 },
81 .flags = 0,
82 .mmal_fmt = MMAL_ENCODING_NV12,
83 .size_multiplier_x2 = 3,
84 }, {
85 .fourcc = V4L2_PIX_FMT_NV21,
86 .depth = 8,
87 - .bytesperline_align = { 32, 32, 32, 32 },
88 + .bytesperline_align = { 32, 32, 32, 32, 32 },
89 .flags = 0,
90 .mmal_fmt = MMAL_ENCODING_NV21,
91 .size_multiplier_x2 = 3,
92 }, {
93 .fourcc = V4L2_PIX_FMT_RGB565,
94 .depth = 16,
95 - .bytesperline_align = { 32, 32, 32, 32 },
96 + .bytesperline_align = { 32, 32, 32, 32, 32 },
97 .flags = 0,
98 .mmal_fmt = MMAL_ENCODING_RGB16,
99 .size_multiplier_x2 = 2,
100 }, {
101 .fourcc = V4L2_PIX_FMT_YUYV,
102 .depth = 16,
103 - .bytesperline_align = { 32, 32, 32, 32 },
104 + .bytesperline_align = { 32, 32, 32, 32, 32 },
105 .flags = 0,
106 .mmal_fmt = MMAL_ENCODING_YUYV,
107 .size_multiplier_x2 = 2,
108 }, {
109 .fourcc = V4L2_PIX_FMT_UYVY,
110 .depth = 16,
111 - .bytesperline_align = { 32, 32, 32, 32 },
112 + .bytesperline_align = { 32, 32, 32, 32, 32 },
113 .flags = 0,
114 .mmal_fmt = MMAL_ENCODING_UYVY,
115 .size_multiplier_x2 = 2,
116 }, {
117 .fourcc = V4L2_PIX_FMT_YVYU,
118 .depth = 16,
119 - .bytesperline_align = { 32, 32, 32, 32 },
120 + .bytesperline_align = { 32, 32, 32, 32, 32 },
121 .flags = 0,
122 .mmal_fmt = MMAL_ENCODING_YVYU,
123 .size_multiplier_x2 = 2,
124 }, {
125 .fourcc = V4L2_PIX_FMT_VYUY,
126 .depth = 16,
127 - .bytesperline_align = { 32, 32, 32, 32 },
128 + .bytesperline_align = { 32, 32, 32, 32, 32 },
129 .flags = 0,
130 .mmal_fmt = MMAL_ENCODING_VYUY,
131 .size_multiplier_x2 = 2,
132 @@ -222,21 +231,21 @@ static const struct bcm2835_codec_fmt su
133 /* RGB formats */
134 .fourcc = V4L2_PIX_FMT_RGB24,
135 .depth = 24,
136 - .bytesperline_align = { 32, 32, 32, 32 },
137 + .bytesperline_align = { 32, 32, 32, 32, 32 },
138 .flags = 0,
139 .mmal_fmt = MMAL_ENCODING_RGB24,
140 .size_multiplier_x2 = 2,
141 }, {
142 .fourcc = V4L2_PIX_FMT_BGR24,
143 .depth = 24,
144 - .bytesperline_align = { 32, 32, 32, 32 },
145 + .bytesperline_align = { 32, 32, 32, 32, 32 },
146 .flags = 0,
147 .mmal_fmt = MMAL_ENCODING_BGR24,
148 .size_multiplier_x2 = 2,
149 }, {
150 .fourcc = V4L2_PIX_FMT_BGR32,
151 .depth = 32,
152 - .bytesperline_align = { 32, 32, 32, 32 },
153 + .bytesperline_align = { 32, 32, 32, 32, 32 },
154 .flags = 0,
155 .mmal_fmt = MMAL_ENCODING_BGRA,
156 .size_multiplier_x2 = 2,
157 @@ -252,7 +261,7 @@ static const struct bcm2835_codec_fmt su
158 /* 8 bit */
159 .fourcc = V4L2_PIX_FMT_SRGGB8,
160 .depth = 8,
161 - .bytesperline_align = { 32, 32, 32, 32 },
162 + .bytesperline_align = { 32, 32, 32, 32, 32 },
163 .flags = 0,
164 .mmal_fmt = MMAL_ENCODING_BAYER_SRGGB8,
165 .size_multiplier_x2 = 2,
166 @@ -260,7 +269,7 @@ static const struct bcm2835_codec_fmt su
167 }, {
168 .fourcc = V4L2_PIX_FMT_SBGGR8,
169 .depth = 8,
170 - .bytesperline_align = { 32, 32, 32, 32 },
171 + .bytesperline_align = { 32, 32, 32, 32, 32 },
172 .flags = 0,
173 .mmal_fmt = MMAL_ENCODING_BAYER_SBGGR8,
174 .size_multiplier_x2 = 2,
175 @@ -268,7 +277,7 @@ static const struct bcm2835_codec_fmt su
176 }, {
177 .fourcc = V4L2_PIX_FMT_SGRBG8,
178 .depth = 8,
179 - .bytesperline_align = { 32, 32, 32, 32 },
180 + .bytesperline_align = { 32, 32, 32, 32, 32 },
181 .flags = 0,
182 .mmal_fmt = MMAL_ENCODING_BAYER_SGRBG8,
183 .size_multiplier_x2 = 2,
184 @@ -276,7 +285,7 @@ static const struct bcm2835_codec_fmt su
185 }, {
186 .fourcc = V4L2_PIX_FMT_SGBRG8,
187 .depth = 8,
188 - .bytesperline_align = { 32, 32, 32, 32 },
189 + .bytesperline_align = { 32, 32, 32, 32, 32 },
190 .flags = 0,
191 .mmal_fmt = MMAL_ENCODING_BAYER_SGBRG8,
192 .size_multiplier_x2 = 2,
193 @@ -285,7 +294,7 @@ static const struct bcm2835_codec_fmt su
194 /* 10 bit */
195 .fourcc = V4L2_PIX_FMT_SRGGB10P,
196 .depth = 10,
197 - .bytesperline_align = { 32, 32, 32, 32 },
198 + .bytesperline_align = { 32, 32, 32, 32, 32 },
199 .flags = 0,
200 .mmal_fmt = MMAL_ENCODING_BAYER_SRGGB10P,
201 .size_multiplier_x2 = 2,
202 @@ -293,7 +302,7 @@ static const struct bcm2835_codec_fmt su
203 }, {
204 .fourcc = V4L2_PIX_FMT_SBGGR10P,
205 .depth = 10,
206 - .bytesperline_align = { 32, 32, 32, 32 },
207 + .bytesperline_align = { 32, 32, 32, 32, 32 },
208 .flags = 0,
209 .mmal_fmt = MMAL_ENCODING_BAYER_SBGGR10P,
210 .size_multiplier_x2 = 2,
211 @@ -301,7 +310,7 @@ static const struct bcm2835_codec_fmt su
212 }, {
213 .fourcc = V4L2_PIX_FMT_SGRBG10P,
214 .depth = 10,
215 - .bytesperline_align = { 32, 32, 32, 32 },
216 + .bytesperline_align = { 32, 32, 32, 32, 32 },
217 .flags = 0,
218 .mmal_fmt = MMAL_ENCODING_BAYER_SGRBG10P,
219 .size_multiplier_x2 = 2,
220 @@ -309,7 +318,7 @@ static const struct bcm2835_codec_fmt su
221 }, {
222 .fourcc = V4L2_PIX_FMT_SGBRG10P,
223 .depth = 10,
224 - .bytesperline_align = { 32, 32, 32, 32 },
225 + .bytesperline_align = { 32, 32, 32, 32, 32 },
226 .flags = 0,
227 .mmal_fmt = MMAL_ENCODING_BAYER_SGBRG10P,
228 .size_multiplier_x2 = 2,
229 @@ -318,7 +327,7 @@ static const struct bcm2835_codec_fmt su
230 /* 12 bit */
231 .fourcc = V4L2_PIX_FMT_SRGGB12P,
232 .depth = 12,
233 - .bytesperline_align = { 32, 32, 32, 32 },
234 + .bytesperline_align = { 32, 32, 32, 32, 32 },
235 .flags = 0,
236 .mmal_fmt = MMAL_ENCODING_BAYER_SRGGB12P,
237 .size_multiplier_x2 = 2,
238 @@ -326,7 +335,7 @@ static const struct bcm2835_codec_fmt su
239 }, {
240 .fourcc = V4L2_PIX_FMT_SBGGR12P,
241 .depth = 12,
242 - .bytesperline_align = { 32, 32, 32, 32 },
243 + .bytesperline_align = { 32, 32, 32, 32, 32 },
244 .flags = 0,
245 .mmal_fmt = MMAL_ENCODING_BAYER_SBGGR12P,
246 .size_multiplier_x2 = 2,
247 @@ -334,7 +343,7 @@ static const struct bcm2835_codec_fmt su
248 }, {
249 .fourcc = V4L2_PIX_FMT_SGRBG12P,
250 .depth = 12,
251 - .bytesperline_align = { 32, 32, 32, 32 },
252 + .bytesperline_align = { 32, 32, 32, 32, 32 },
253 .flags = 0,
254 .mmal_fmt = MMAL_ENCODING_BAYER_SGRBG12P,
255 .size_multiplier_x2 = 2,
256 @@ -342,7 +351,7 @@ static const struct bcm2835_codec_fmt su
257 }, {
258 .fourcc = V4L2_PIX_FMT_SGBRG12P,
259 .depth = 12,
260 - .bytesperline_align = { 32, 32, 32, 32 },
261 + .bytesperline_align = { 32, 32, 32, 32, 32 },
262 .flags = 0,
263 .mmal_fmt = MMAL_ENCODING_BAYER_SGBRG12P,
264 .size_multiplier_x2 = 2,
265 @@ -351,7 +360,7 @@ static const struct bcm2835_codec_fmt su
266 /* 14 bit */
267 .fourcc = V4L2_PIX_FMT_SRGGB14P,
268 .depth = 14,
269 - .bytesperline_align = { 32, 32, 32, 32 },
270 + .bytesperline_align = { 32, 32, 32, 32, 32 },
271 .flags = 0,
272 .mmal_fmt = MMAL_ENCODING_BAYER_SRGGB14P,
273 .size_multiplier_x2 = 2,
274 @@ -359,7 +368,7 @@ static const struct bcm2835_codec_fmt su
275 }, {
276 .fourcc = V4L2_PIX_FMT_SBGGR14P,
277 .depth = 14,
278 - .bytesperline_align = { 32, 32, 32, 32 },
279 + .bytesperline_align = { 32, 32, 32, 32, 32 },
280 .flags = 0,
281 .mmal_fmt = MMAL_ENCODING_BAYER_SBGGR14P,
282 .size_multiplier_x2 = 2,
283 @@ -368,7 +377,7 @@ static const struct bcm2835_codec_fmt su
284 }, {
285 .fourcc = V4L2_PIX_FMT_SGRBG14P,
286 .depth = 14,
287 - .bytesperline_align = { 32, 32, 32, 32 },
288 + .bytesperline_align = { 32, 32, 32, 32, 32 },
289 .flags = 0,
290 .mmal_fmt = MMAL_ENCODING_BAYER_SGRBG14P,
291 .size_multiplier_x2 = 2,
292 @@ -376,7 +385,7 @@ static const struct bcm2835_codec_fmt su
293 }, {
294 .fourcc = V4L2_PIX_FMT_SGBRG14P,
295 .depth = 14,
296 - .bytesperline_align = { 32, 32, 32, 32 },
297 + .bytesperline_align = { 32, 32, 32, 32, 32 },
298 .flags = 0,
299 .mmal_fmt = MMAL_ENCODING_BAYER_SGBRG14P,
300 .size_multiplier_x2 = 2,
301 @@ -385,7 +394,7 @@ static const struct bcm2835_codec_fmt su
302 /* 16 bit */
303 .fourcc = V4L2_PIX_FMT_SRGGB16,
304 .depth = 16,
305 - .bytesperline_align = { 32, 32, 32, 32 },
306 + .bytesperline_align = { 32, 32, 32, 32, 32 },
307 .flags = 0,
308 .mmal_fmt = MMAL_ENCODING_BAYER_SRGGB16,
309 .size_multiplier_x2 = 2,
310 @@ -393,7 +402,7 @@ static const struct bcm2835_codec_fmt su
311 }, {
312 .fourcc = V4L2_PIX_FMT_SBGGR16,
313 .depth = 16,
314 - .bytesperline_align = { 32, 32, 32, 32 },
315 + .bytesperline_align = { 32, 32, 32, 32, 32 },
316 .flags = 0,
317 .mmal_fmt = MMAL_ENCODING_BAYER_SBGGR16,
318 .size_multiplier_x2 = 2,
319 @@ -401,7 +410,7 @@ static const struct bcm2835_codec_fmt su
320 }, {
321 .fourcc = V4L2_PIX_FMT_SGRBG16,
322 .depth = 16,
323 - .bytesperline_align = { 32, 32, 32, 32 },
324 + .bytesperline_align = { 32, 32, 32, 32, 32 },
325 .flags = 0,
326 .mmal_fmt = MMAL_ENCODING_BAYER_SGRBG16,
327 .size_multiplier_x2 = 2,
328 @@ -409,7 +418,7 @@ static const struct bcm2835_codec_fmt su
329 }, {
330 .fourcc = V4L2_PIX_FMT_SGBRG16,
331 .depth = 16,
332 - .bytesperline_align = { 32, 32, 32, 32 },
333 + .bytesperline_align = { 32, 32, 32, 32, 32 },
334 .flags = 0,
335 .mmal_fmt = MMAL_ENCODING_BAYER_SGBRG16,
336 .size_multiplier_x2 = 2,
337 @@ -419,7 +428,7 @@ static const struct bcm2835_codec_fmt su
338 /* 10 bit */
339 .fourcc = V4L2_PIX_FMT_SRGGB10,
340 .depth = 16,
341 - .bytesperline_align = { 32, 32, 32, 32 },
342 + .bytesperline_align = { 32, 32, 32, 32, 32 },
343 .flags = 0,
344 .mmal_fmt = MMAL_ENCODING_BAYER_SRGGB10,
345 .size_multiplier_x2 = 2,
346 @@ -427,7 +436,7 @@ static const struct bcm2835_codec_fmt su
347 }, {
348 .fourcc = V4L2_PIX_FMT_SBGGR10,
349 .depth = 16,
350 - .bytesperline_align = { 32, 32, 32, 32 },
351 + .bytesperline_align = { 32, 32, 32, 32, 32 },
352 .flags = 0,
353 .mmal_fmt = MMAL_ENCODING_BAYER_SBGGR10,
354 .size_multiplier_x2 = 2,
355 @@ -435,7 +444,7 @@ static const struct bcm2835_codec_fmt su
356 }, {
357 .fourcc = V4L2_PIX_FMT_SGRBG10,
358 .depth = 16,
359 - .bytesperline_align = { 32, 32, 32, 32 },
360 + .bytesperline_align = { 32, 32, 32, 32, 32 },
361 .flags = 0,
362 .mmal_fmt = MMAL_ENCODING_BAYER_SGRBG10,
363 .size_multiplier_x2 = 2,
364 @@ -443,7 +452,7 @@ static const struct bcm2835_codec_fmt su
365 }, {
366 .fourcc = V4L2_PIX_FMT_SGBRG10,
367 .depth = 16,
368 - .bytesperline_align = { 32, 32, 32, 32 },
369 + .bytesperline_align = { 32, 32, 32, 32, 32 },
370 .flags = 0,
371 .mmal_fmt = MMAL_ENCODING_BAYER_SGBRG10,
372 .size_multiplier_x2 = 2,
373 @@ -452,7 +461,7 @@ static const struct bcm2835_codec_fmt su
374 /* 12 bit */
375 .fourcc = V4L2_PIX_FMT_SRGGB12,
376 .depth = 16,
377 - .bytesperline_align = { 32, 32, 32, 32 },
378 + .bytesperline_align = { 32, 32, 32, 32, 32 },
379 .flags = 0,
380 .mmal_fmt = MMAL_ENCODING_BAYER_SRGGB12,
381 .size_multiplier_x2 = 2,
382 @@ -460,7 +469,7 @@ static const struct bcm2835_codec_fmt su
383 }, {
384 .fourcc = V4L2_PIX_FMT_SBGGR12,
385 .depth = 16,
386 - .bytesperline_align = { 32, 32, 32, 32 },
387 + .bytesperline_align = { 32, 32, 32, 32, 32 },
388 .flags = 0,
389 .mmal_fmt = MMAL_ENCODING_BAYER_SBGGR12,
390 .size_multiplier_x2 = 2,
391 @@ -468,7 +477,7 @@ static const struct bcm2835_codec_fmt su
392 }, {
393 .fourcc = V4L2_PIX_FMT_SGRBG12,
394 .depth = 16,
395 - .bytesperline_align = { 32, 32, 32, 32 },
396 + .bytesperline_align = { 32, 32, 32, 32, 32 },
397 .flags = 0,
398 .mmal_fmt = MMAL_ENCODING_BAYER_SGRBG12,
399 .size_multiplier_x2 = 2,
400 @@ -476,7 +485,7 @@ static const struct bcm2835_codec_fmt su
401 }, {
402 .fourcc = V4L2_PIX_FMT_SGBRG12,
403 .depth = 16,
404 - .bytesperline_align = { 32, 32, 32, 32 },
405 + .bytesperline_align = { 32, 32, 32, 32, 32 },
406 .flags = 0,
407 .mmal_fmt = MMAL_ENCODING_BAYER_SGBRG12,
408 .size_multiplier_x2 = 2,
409 @@ -485,7 +494,7 @@ static const struct bcm2835_codec_fmt su
410 /* 14 bit */
411 .fourcc = V4L2_PIX_FMT_SRGGB14,
412 .depth = 16,
413 - .bytesperline_align = { 32, 32, 32, 32 },
414 + .bytesperline_align = { 32, 32, 32, 32, 32 },
415 .flags = 0,
416 .mmal_fmt = MMAL_ENCODING_BAYER_SRGGB14,
417 .size_multiplier_x2 = 2,
418 @@ -493,7 +502,7 @@ static const struct bcm2835_codec_fmt su
419 }, {
420 .fourcc = V4L2_PIX_FMT_SBGGR14,
421 .depth = 16,
422 - .bytesperline_align = { 32, 32, 32, 32 },
423 + .bytesperline_align = { 32, 32, 32, 32, 32 },
424 .flags = 0,
425 .mmal_fmt = MMAL_ENCODING_BAYER_SBGGR14,
426 .size_multiplier_x2 = 2,
427 @@ -501,7 +510,7 @@ static const struct bcm2835_codec_fmt su
428 }, {
429 .fourcc = V4L2_PIX_FMT_SGRBG14,
430 .depth = 16,
431 - .bytesperline_align = { 32, 32, 32, 32 },
432 + .bytesperline_align = { 32, 32, 32, 32, 32 },
433 .flags = 0,
434 .mmal_fmt = MMAL_ENCODING_BAYER_SGRBG14,
435 .size_multiplier_x2 = 2,
436 @@ -509,7 +518,7 @@ static const struct bcm2835_codec_fmt su
437 }, {
438 .fourcc = V4L2_PIX_FMT_SGBRG14,
439 .depth = 16,
440 - .bytesperline_align = { 32, 32, 32, 32 },
441 + .bytesperline_align = { 32, 32, 32, 32, 32 },
442 .flags = 0,
443 .mmal_fmt = MMAL_ENCODING_BAYER_SGBRG14,
444 .size_multiplier_x2 = 2,
445 @@ -519,7 +528,7 @@ static const struct bcm2835_codec_fmt su
446 /* 8 bit */
447 .fourcc = V4L2_PIX_FMT_GREY,
448 .depth = 8,
449 - .bytesperline_align = { 32, 32, 32, 32 },
450 + .bytesperline_align = { 32, 32, 32, 32, 32 },
451 .flags = 0,
452 .mmal_fmt = MMAL_ENCODING_GREY,
453 .size_multiplier_x2 = 2,
454 @@ -527,7 +536,7 @@ static const struct bcm2835_codec_fmt su
455 /* 10 bit */
456 .fourcc = V4L2_PIX_FMT_Y10P,
457 .depth = 10,
458 - .bytesperline_align = { 32, 32, 32, 32 },
459 + .bytesperline_align = { 32, 32, 32, 32, 32 },
460 .flags = 0,
461 .mmal_fmt = MMAL_ENCODING_Y10P,
462 .size_multiplier_x2 = 2,
463 @@ -535,7 +544,7 @@ static const struct bcm2835_codec_fmt su
464 /* 12 bit */
465 .fourcc = V4L2_PIX_FMT_Y12P,
466 .depth = 12,
467 - .bytesperline_align = { 32, 32, 32, 32 },
468 + .bytesperline_align = { 32, 32, 32, 32, 32 },
469 .flags = 0,
470 .mmal_fmt = MMAL_ENCODING_Y12P,
471 .size_multiplier_x2 = 2,
472 @@ -543,7 +552,7 @@ static const struct bcm2835_codec_fmt su
473 /* 14 bit */
474 .fourcc = V4L2_PIX_FMT_Y14P,
475 .depth = 14,
476 - .bytesperline_align = { 32, 32, 32, 32 },
477 + .bytesperline_align = { 32, 32, 32, 32, 32 },
478 .flags = 0,
479 .mmal_fmt = MMAL_ENCODING_Y14P,
480 .size_multiplier_x2 = 2,
481 @@ -551,7 +560,7 @@ static const struct bcm2835_codec_fmt su
482 /* 16 bit */
483 .fourcc = V4L2_PIX_FMT_Y16,
484 .depth = 16,
485 - .bytesperline_align = { 32, 32, 32, 32 },
486 + .bytesperline_align = { 32, 32, 32, 32, 32 },
487 .flags = 0,
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,
493 .depth = 16,
494 - .bytesperline_align = { 32, 32, 32, 32 },
495 + .bytesperline_align = { 32, 32, 32, 32, 32 },
496 .flags = 0,
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,
502 .depth = 16,
503 - .bytesperline_align = { 32, 32, 32, 32 },
504 + .bytesperline_align = { 32, 32, 32, 32, 32 },
505 .flags = 0,
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,
511 .depth = 16,
512 - .bytesperline_align = { 32, 32, 32, 32 },
513 + .bytesperline_align = { 32, 32, 32, 32, 32 },
514 .flags = 0,
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,
520 }, {
521 + .fourcc = V4L2_PIX_FMT_JPEG,
522 + .depth = 0,
523 + .flags = V4L2_FMT_FLAG_COMPRESSED,
524 + .mmal_fmt = MMAL_ENCODING_JPEG,
525 + }, {
526 .fourcc = V4L2_PIX_FMT_MJPEG,
527 .depth = 0,
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;
534 };
535
536 enum {
537 @@ -838,6 +853,9 @@ static inline unsigned int get_sizeimage
538 struct bcm2835_codec_fmt *fmt)
539 {
540 if (fmt->flags & V4L2_FMT_FLAG_COMPRESSED) {
541 + if (fmt->fourcc == V4L2_PIX_FMT_JPEG)
542 + return DEF_COMP_BUF_SIZE_JPEG;
543 +
544 if (width * height > 1280 * 720)
545 return DEF_COMP_BUF_SIZE_GREATER_720P;
546 else
547 @@ -1422,12 +1440,12 @@ static int vidioc_try_fmt(struct bcm2835
548 f->fmt.pix_mp.height = MIN_H;
549
550 /*
551 - * For decoders the buffer must have a vertical alignment of 16
552 - * lines.
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.
557 */
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);
561 }
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);
566
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) {
571 /*
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
581 switch (s->type) {
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)
586 return -EINVAL;
587 q_data = &ctx->q_data[V4L2_M2M_DST];
588 break;
589 @@ -1762,6 +1781,7 @@ static int vidioc_g_selection(struct fil
590 }
591 break;
592 case ENCODE:
593 + case ENCODE_IMAGE:
594 switch (s->target) {
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
598 switch (s->type) {
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)
603 return -EINVAL;
604 q_data = &ctx->q_data[V4L2_M2M_DST];
605 break;
606 @@ -1882,6 +1902,7 @@ static int vidioc_s_selection(struct fil
607 }
608 break;
609 case ENCODE:
610 + case ENCODE_IMAGE:
611 switch (s->target) {
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
615 sizeof(u32_value));
616 break;
617 }
618 + case V4L2_CID_JPEG_COMPRESSION_QUALITY:
619 + if (!ctx->component)
620 + break;
621 +
622 + ret = vchiq_mmal_port_parameter_set(ctx->dev->instance,
623 + &ctx->component->output[0],
624 + MMAL_PARAMETER_JPEG_Q_FACTOR,
625 + &ctrl->val,
626 + sizeof(ctrl->val));
627 + break;
628
629 default:
630 v4l2_err(&ctx->dev->v4l2_dev, "Invalid control\n");
631 @@ -2364,7 +2395,7 @@ static int vidioc_try_encoder_cmd(struct
632 {
633 struct bcm2835_codec_ctx *ctx = file2ctx(file);
634
635 - if (ctx->dev->role != ENCODE)
636 + if (ctx->dev->role != ENCODE && ctx->dev->role != ENCODE_IMAGE)
637 return -EINVAL;
638
639 switch (cmd->cmd) {
640 @@ -2567,6 +2598,20 @@ static int bcm2835_codec_create_componen
641 MMAL_PARAMETER_IMAGE_EFFECT_PARAMETERS,
642 &params,
643 sizeof(params));
644 +
645 + } else if (dev->role == ENCODE_IMAGE) {
646 + enable = 0;
647 + vchiq_mmal_port_parameter_set(dev->instance,
648 + &ctx->component->control,
649 + MMAL_PARAMETER_EXIF_DISABLE,
650 + &enable,
651 + sizeof(enable));
652 + enable = 1;
653 + vchiq_mmal_port_parameter_set(dev->instance,
654 + &ctx->component->output[0],
655 + MMAL_PARAMETER_JPEG_IJG_SCALING,
656 + &enable,
657 + sizeof(enable));
658 }
659
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;
663 }
664
665 - if (dev->role == ENCODE) {
666 + if (dev->role == ENCODE || dev->role == ENCODE_IMAGE) {
667 u32 param = 1;
668
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);
673
674 - /* Enable SPS Timing header so framerate information is encoded
675 - * in the H264 header.
676 - */
677 - vchiq_mmal_port_parameter_set(ctx->dev->instance,
678 - &ctx->component->output[0],
679 - MMAL_PARAMETER_VIDEO_ENCODE_SPS_TIMING,
680 - &param, sizeof(param));
681 -
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 - &param, sizeof(param));
687 - /*
688 - * Avoid fragmenting the buffers over multiple frames (unless
689 - * the frame is bigger than the whole buffer)
690 - */
691 - vchiq_mmal_port_parameter_set(ctx->dev->instance,
692 - &ctx->component->control,
693 - MMAL_PARAMETER_MINIMISE_FRAGMENTATION,
694 - &param, sizeof(param));
695 + if (dev->role == ENCODE) {
696 + /* Enable SPS Timing header so framerate information is encoded
697 + * in the H264 header.
698 + */
699 + vchiq_mmal_port_parameter_set(ctx->dev->instance,
700 + &ctx->component->output[0],
701 + MMAL_PARAMETER_VIDEO_ENCODE_SPS_TIMING,
702 + &param, sizeof(param));
703 +
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 + &param, sizeof(param));
709 + /*
710 + * Avoid fragmenting the buffers over multiple frames (unless
711 + * the frame is bigger than the whole buffer)
712 + */
713 + vchiq_mmal_port_parameter_set(ctx->dev->instance,
714 + &ctx->component->control,
715 + MMAL_PARAMETER_MINIMISE_FRAGMENTATION,
716 + &param, sizeof(param));
717 + }
718 } else {
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);
723 }
724 break;
725 + case ENCODE_IMAGE:
726 + {
727 + /* Encode image controls */
728 + v4l2_ctrl_handler_init(hdl, 1);
729 +
730 + v4l2_ctrl_new_std(hdl, &bcm2835_codec_ctrl_ops,
731 + V4L2_CID_JPEG_COMPRESSION_QUALITY,
732 + 1, 100,
733 + 1, 80);
734 + if (hdl->error) {
735 + rc = hdl->error;
736 + goto free_ctrl_handler;
737 + }
738 + ctx->fh.ctrl_handler = hdl;
739 + v4l2_ctrl_handler_setup(hdl);
740 + }
741 + break;
742 case NUM_ROLES:
743 break;
744 }
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;
748 break;
749 + case ENCODE_IMAGE:
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;
754 + break;
755 default:
756 ret = -EINVAL;
757 goto unreg_dev;
758 @@ -3626,6 +3696,10 @@ static int bcm2835_codec_probe(struct pl
759 if (ret)
760 goto out;
761
762 + ret = bcm2835_codec_create(drv, &drv->encode_image, ENCODE_IMAGE);
763 + if (ret)
764 + goto out;
765 +
766 /* Register the media device node */
767 if (media_device_register(mdev) < 0)
768 goto out;
769 @@ -3635,6 +3709,10 @@ static int bcm2835_codec_probe(struct pl
770 return 0;
771
772 out:
773 + if (drv->encode_image) {
774 + bcm2835_codec_destroy(drv->encode_image);
775 + drv->encode_image = NULL;
776 + }
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
781
782 media_device_unregister(&drv->mdev);
783
784 + bcm2835_codec_destroy(drv->encode_image);
785 +
786 bcm2835_codec_destroy(drv->deinterlace);
787
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 */
794 MMAL_PARAMETER_CDN,
795 + /**< Takes a @ref MMAL_PARAMETER_BOOLEAN_T */
796 + MMAL_PARAMETER_JPEG_IJG_SCALING,
797 };
798
799 struct mmal_parameter_rational {