Merge tag 'for-linus-4.14b-rc2-tag' of git://git.kernel.org/pub/scm/linux/kernel...
[platform/kernel/linux-rpi.git] / include / media / v4l2-tpg.h
1 /*
2  * v4l2-tpg.h - Test Pattern Generator
3  *
4  * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
5  *
6  * This program is free software; you may redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; version 2 of the License.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
11  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
12  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
13  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
14  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
15  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
16  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
17  * SOFTWARE.
18  */
19
20 #ifndef _V4L2_TPG_H_
21 #define _V4L2_TPG_H_
22
23 #include <linux/types.h>
24 #include <linux/errno.h>
25 #include <linux/random.h>
26 #include <linux/slab.h>
27 #include <linux/vmalloc.h>
28 #include <linux/videodev2.h>
29 #include <media/v4l2-tpg-colors.h>
30
31 enum tpg_pattern {
32         TPG_PAT_75_COLORBAR,
33         TPG_PAT_100_COLORBAR,
34         TPG_PAT_CSC_COLORBAR,
35         TPG_PAT_100_HCOLORBAR,
36         TPG_PAT_100_COLORSQUARES,
37         TPG_PAT_BLACK,
38         TPG_PAT_WHITE,
39         TPG_PAT_RED,
40         TPG_PAT_GREEN,
41         TPG_PAT_BLUE,
42         TPG_PAT_CHECKERS_16X16,
43         TPG_PAT_CHECKERS_2X2,
44         TPG_PAT_CHECKERS_1X1,
45         TPG_PAT_COLOR_CHECKERS_2X2,
46         TPG_PAT_COLOR_CHECKERS_1X1,
47         TPG_PAT_ALTERNATING_HLINES,
48         TPG_PAT_ALTERNATING_VLINES,
49         TPG_PAT_CROSS_1_PIXEL,
50         TPG_PAT_CROSS_2_PIXELS,
51         TPG_PAT_CROSS_10_PIXELS,
52         TPG_PAT_GRAY_RAMP,
53
54         /* Must be the last pattern */
55         TPG_PAT_NOISE,
56 };
57
58 extern const char * const tpg_pattern_strings[];
59
60 enum tpg_quality {
61         TPG_QUAL_COLOR,
62         TPG_QUAL_GRAY,
63         TPG_QUAL_NOISE
64 };
65
66 enum tpg_video_aspect {
67         TPG_VIDEO_ASPECT_IMAGE,
68         TPG_VIDEO_ASPECT_4X3,
69         TPG_VIDEO_ASPECT_14X9_CENTRE,
70         TPG_VIDEO_ASPECT_16X9_CENTRE,
71         TPG_VIDEO_ASPECT_16X9_ANAMORPHIC,
72 };
73
74 enum tpg_pixel_aspect {
75         TPG_PIXEL_ASPECT_SQUARE,
76         TPG_PIXEL_ASPECT_NTSC,
77         TPG_PIXEL_ASPECT_PAL,
78 };
79
80 enum tpg_move_mode {
81         TPG_MOVE_NEG_FAST,
82         TPG_MOVE_NEG,
83         TPG_MOVE_NEG_SLOW,
84         TPG_MOVE_NONE,
85         TPG_MOVE_POS_SLOW,
86         TPG_MOVE_POS,
87         TPG_MOVE_POS_FAST,
88 };
89
90 enum tgp_color_enc {
91         TGP_COLOR_ENC_RGB,
92         TGP_COLOR_ENC_YCBCR,
93         TGP_COLOR_ENC_HSV,
94         TGP_COLOR_ENC_LUMA,
95 };
96
97 extern const char * const tpg_aspect_strings[];
98
99 #define TPG_MAX_PLANES 3
100 #define TPG_MAX_PAT_LINES 8
101
102 struct tpg_data {
103         /* Source frame size */
104         unsigned                        src_width, src_height;
105         /* Buffer height */
106         unsigned                        buf_height;
107         /* Scaled output frame size */
108         unsigned                        scaled_width;
109         u32                             field;
110         bool                            field_alternate;
111         /* crop coordinates are frame-based */
112         struct v4l2_rect                crop;
113         /* compose coordinates are format-based */
114         struct v4l2_rect                compose;
115         /* border and square coordinates are frame-based */
116         struct v4l2_rect                border;
117         struct v4l2_rect                square;
118
119         /* Color-related fields */
120         enum tpg_quality                qual;
121         unsigned                        qual_offset;
122         u8                              alpha_component;
123         bool                            alpha_red_only;
124         u8                              brightness;
125         u8                              contrast;
126         u8                              saturation;
127         s16                             hue;
128         u32                             fourcc;
129         enum tgp_color_enc              color_enc;
130         u32                             colorspace;
131         u32                             xfer_func;
132         u32                             ycbcr_enc;
133         u32                             hsv_enc;
134         /*
135          * Stores the actual transfer function, i.e. will never be
136          * V4L2_XFER_FUNC_DEFAULT.
137          */
138         u32                             real_xfer_func;
139         /*
140          * Stores the actual Y'CbCr encoding, i.e. will never be
141          * V4L2_YCBCR_ENC_DEFAULT.
142          */
143         u32                             real_hsv_enc;
144         u32                             real_ycbcr_enc;
145         u32                             quantization;
146         /*
147          * Stores the actual quantization, i.e. will never be
148          * V4L2_QUANTIZATION_DEFAULT.
149          */
150         u32                             real_quantization;
151         enum tpg_video_aspect           vid_aspect;
152         enum tpg_pixel_aspect           pix_aspect;
153         unsigned                        rgb_range;
154         unsigned                        real_rgb_range;
155         unsigned                        buffers;
156         unsigned                        planes;
157         bool                            interleaved;
158         u8                              vdownsampling[TPG_MAX_PLANES];
159         u8                              hdownsampling[TPG_MAX_PLANES];
160         /*
161          * horizontal positions must be ANDed with this value to enforce
162          * correct boundaries for packed YUYV values.
163          */
164         unsigned                        hmask[TPG_MAX_PLANES];
165         /* Used to store the colors in native format, either RGB or YUV */
166         u8                              colors[TPG_COLOR_MAX][3];
167         u8                              textfg[TPG_MAX_PLANES][8], textbg[TPG_MAX_PLANES][8];
168         /* size in bytes for two pixels in each plane */
169         unsigned                        twopixelsize[TPG_MAX_PLANES];
170         unsigned                        bytesperline[TPG_MAX_PLANES];
171
172         /* Configuration */
173         enum tpg_pattern                pattern;
174         bool                            hflip;
175         bool                            vflip;
176         unsigned                        perc_fill;
177         bool                            perc_fill_blank;
178         bool                            show_border;
179         bool                            show_square;
180         bool                            insert_sav;
181         bool                            insert_eav;
182
183         /* Test pattern movement */
184         enum tpg_move_mode              mv_hor_mode;
185         int                             mv_hor_count;
186         int                             mv_hor_step;
187         enum tpg_move_mode              mv_vert_mode;
188         int                             mv_vert_count;
189         int                             mv_vert_step;
190
191         bool                            recalc_colors;
192         bool                            recalc_lines;
193         bool                            recalc_square_border;
194
195         /* Used to store TPG_MAX_PAT_LINES lines, each with up to two planes */
196         unsigned                        max_line_width;
197         u8                              *lines[TPG_MAX_PAT_LINES][TPG_MAX_PLANES];
198         u8                              *downsampled_lines[TPG_MAX_PAT_LINES][TPG_MAX_PLANES];
199         u8                              *random_line[TPG_MAX_PLANES];
200         u8                              *contrast_line[TPG_MAX_PLANES];
201         u8                              *black_line[TPG_MAX_PLANES];
202 };
203
204 void tpg_init(struct tpg_data *tpg, unsigned w, unsigned h);
205 int tpg_alloc(struct tpg_data *tpg, unsigned max_w);
206 void tpg_free(struct tpg_data *tpg);
207 void tpg_reset_source(struct tpg_data *tpg, unsigned width, unsigned height,
208                        u32 field);
209 void tpg_log_status(struct tpg_data *tpg);
210
211 void tpg_set_font(const u8 *f);
212 void tpg_gen_text(const struct tpg_data *tpg,
213                 u8 *basep[TPG_MAX_PLANES][2], int y, int x, char *text);
214 void tpg_calc_text_basep(struct tpg_data *tpg,
215                 u8 *basep[TPG_MAX_PLANES][2], unsigned p, u8 *vbuf);
216 unsigned tpg_g_interleaved_plane(const struct tpg_data *tpg, unsigned buf_line);
217 void tpg_fill_plane_buffer(struct tpg_data *tpg, v4l2_std_id std,
218                            unsigned p, u8 *vbuf);
219 void tpg_fillbuffer(struct tpg_data *tpg, v4l2_std_id std,
220                     unsigned p, u8 *vbuf);
221 bool tpg_s_fourcc(struct tpg_data *tpg, u32 fourcc);
222 void tpg_s_crop_compose(struct tpg_data *tpg, const struct v4l2_rect *crop,
223                 const struct v4l2_rect *compose);
224
225 static inline void tpg_s_pattern(struct tpg_data *tpg, enum tpg_pattern pattern)
226 {
227         if (tpg->pattern == pattern)
228                 return;
229         tpg->pattern = pattern;
230         tpg->recalc_colors = true;
231 }
232
233 static inline void tpg_s_quality(struct tpg_data *tpg,
234                                     enum tpg_quality qual, unsigned qual_offset)
235 {
236         if (tpg->qual == qual && tpg->qual_offset == qual_offset)
237                 return;
238         tpg->qual = qual;
239         tpg->qual_offset = qual_offset;
240         tpg->recalc_colors = true;
241 }
242
243 static inline enum tpg_quality tpg_g_quality(const struct tpg_data *tpg)
244 {
245         return tpg->qual;
246 }
247
248 static inline void tpg_s_alpha_component(struct tpg_data *tpg,
249                                             u8 alpha_component)
250 {
251         if (tpg->alpha_component == alpha_component)
252                 return;
253         tpg->alpha_component = alpha_component;
254         tpg->recalc_colors = true;
255 }
256
257 static inline void tpg_s_alpha_mode(struct tpg_data *tpg,
258                                             bool red_only)
259 {
260         if (tpg->alpha_red_only == red_only)
261                 return;
262         tpg->alpha_red_only = red_only;
263         tpg->recalc_colors = true;
264 }
265
266 static inline void tpg_s_brightness(struct tpg_data *tpg,
267                                         u8 brightness)
268 {
269         if (tpg->brightness == brightness)
270                 return;
271         tpg->brightness = brightness;
272         tpg->recalc_colors = true;
273 }
274
275 static inline void tpg_s_contrast(struct tpg_data *tpg,
276                                         u8 contrast)
277 {
278         if (tpg->contrast == contrast)
279                 return;
280         tpg->contrast = contrast;
281         tpg->recalc_colors = true;
282 }
283
284 static inline void tpg_s_saturation(struct tpg_data *tpg,
285                                         u8 saturation)
286 {
287         if (tpg->saturation == saturation)
288                 return;
289         tpg->saturation = saturation;
290         tpg->recalc_colors = true;
291 }
292
293 static inline void tpg_s_hue(struct tpg_data *tpg,
294                                         s16 hue)
295 {
296         if (tpg->hue == hue)
297                 return;
298         tpg->hue = hue;
299         tpg->recalc_colors = true;
300 }
301
302 static inline void tpg_s_rgb_range(struct tpg_data *tpg,
303                                         unsigned rgb_range)
304 {
305         if (tpg->rgb_range == rgb_range)
306                 return;
307         tpg->rgb_range = rgb_range;
308         tpg->recalc_colors = true;
309 }
310
311 static inline void tpg_s_real_rgb_range(struct tpg_data *tpg,
312                                         unsigned rgb_range)
313 {
314         if (tpg->real_rgb_range == rgb_range)
315                 return;
316         tpg->real_rgb_range = rgb_range;
317         tpg->recalc_colors = true;
318 }
319
320 static inline void tpg_s_colorspace(struct tpg_data *tpg, u32 colorspace)
321 {
322         if (tpg->colorspace == colorspace)
323                 return;
324         tpg->colorspace = colorspace;
325         tpg->recalc_colors = true;
326 }
327
328 static inline u32 tpg_g_colorspace(const struct tpg_data *tpg)
329 {
330         return tpg->colorspace;
331 }
332
333 static inline void tpg_s_ycbcr_enc(struct tpg_data *tpg, u32 ycbcr_enc)
334 {
335         if (tpg->ycbcr_enc == ycbcr_enc)
336                 return;
337         tpg->ycbcr_enc = ycbcr_enc;
338         tpg->recalc_colors = true;
339 }
340
341 static inline u32 tpg_g_ycbcr_enc(const struct tpg_data *tpg)
342 {
343         return tpg->ycbcr_enc;
344 }
345
346 static inline void tpg_s_hsv_enc(struct tpg_data *tpg, u32 hsv_enc)
347 {
348         if (tpg->hsv_enc == hsv_enc)
349                 return;
350         tpg->hsv_enc = hsv_enc;
351         tpg->recalc_colors = true;
352 }
353
354 static inline u32 tpg_g_hsv_enc(const struct tpg_data *tpg)
355 {
356         return tpg->hsv_enc;
357 }
358
359 static inline void tpg_s_xfer_func(struct tpg_data *tpg, u32 xfer_func)
360 {
361         if (tpg->xfer_func == xfer_func)
362                 return;
363         tpg->xfer_func = xfer_func;
364         tpg->recalc_colors = true;
365 }
366
367 static inline u32 tpg_g_xfer_func(const struct tpg_data *tpg)
368 {
369         return tpg->xfer_func;
370 }
371
372 static inline void tpg_s_quantization(struct tpg_data *tpg, u32 quantization)
373 {
374         if (tpg->quantization == quantization)
375                 return;
376         tpg->quantization = quantization;
377         tpg->recalc_colors = true;
378 }
379
380 static inline u32 tpg_g_quantization(const struct tpg_data *tpg)
381 {
382         return tpg->quantization;
383 }
384
385 static inline unsigned tpg_g_buffers(const struct tpg_data *tpg)
386 {
387         return tpg->buffers;
388 }
389
390 static inline unsigned tpg_g_planes(const struct tpg_data *tpg)
391 {
392         return tpg->interleaved ? 1 : tpg->planes;
393 }
394
395 static inline bool tpg_g_interleaved(const struct tpg_data *tpg)
396 {
397         return tpg->interleaved;
398 }
399
400 static inline unsigned tpg_g_twopixelsize(const struct tpg_data *tpg, unsigned plane)
401 {
402         return tpg->twopixelsize[plane];
403 }
404
405 static inline unsigned tpg_hdiv(const struct tpg_data *tpg,
406                                   unsigned plane, unsigned x)
407 {
408         return ((x / tpg->hdownsampling[plane]) & tpg->hmask[plane]) *
409                 tpg->twopixelsize[plane] / 2;
410 }
411
412 static inline unsigned tpg_hscale(const struct tpg_data *tpg, unsigned x)
413 {
414         return (x * tpg->scaled_width) / tpg->src_width;
415 }
416
417 static inline unsigned tpg_hscale_div(const struct tpg_data *tpg,
418                                       unsigned plane, unsigned x)
419 {
420         return tpg_hdiv(tpg, plane, tpg_hscale(tpg, x));
421 }
422
423 static inline unsigned tpg_g_bytesperline(const struct tpg_data *tpg, unsigned plane)
424 {
425         return tpg->bytesperline[plane];
426 }
427
428 static inline void tpg_s_bytesperline(struct tpg_data *tpg, unsigned plane, unsigned bpl)
429 {
430         unsigned p;
431
432         if (tpg->buffers > 1) {
433                 tpg->bytesperline[plane] = bpl;
434                 return;
435         }
436
437         for (p = 0; p < tpg_g_planes(tpg); p++) {
438                 unsigned plane_w = bpl * tpg->twopixelsize[p] / tpg->twopixelsize[0];
439
440                 tpg->bytesperline[p] = plane_w / tpg->hdownsampling[p];
441         }
442         if (tpg_g_interleaved(tpg))
443                 tpg->bytesperline[1] = tpg->bytesperline[0];
444 }
445
446
447 static inline unsigned tpg_g_line_width(const struct tpg_data *tpg, unsigned plane)
448 {
449         unsigned w = 0;
450         unsigned p;
451
452         if (tpg->buffers > 1)
453                 return tpg_g_bytesperline(tpg, plane);
454         for (p = 0; p < tpg_g_planes(tpg); p++) {
455                 unsigned plane_w = tpg_g_bytesperline(tpg, p);
456
457                 w += plane_w / tpg->vdownsampling[p];
458         }
459         return w;
460 }
461
462 static inline unsigned tpg_calc_line_width(const struct tpg_data *tpg,
463                                            unsigned plane, unsigned bpl)
464 {
465         unsigned w = 0;
466         unsigned p;
467
468         if (tpg->buffers > 1)
469                 return bpl;
470         for (p = 0; p < tpg_g_planes(tpg); p++) {
471                 unsigned plane_w = bpl * tpg->twopixelsize[p] / tpg->twopixelsize[0];
472
473                 plane_w /= tpg->hdownsampling[p];
474                 w += plane_w / tpg->vdownsampling[p];
475         }
476         return w;
477 }
478
479 static inline unsigned tpg_calc_plane_size(const struct tpg_data *tpg, unsigned plane)
480 {
481         if (plane >= tpg_g_planes(tpg))
482                 return 0;
483
484         return tpg_g_bytesperline(tpg, plane) * tpg->buf_height /
485                tpg->vdownsampling[plane];
486 }
487
488 static inline void tpg_s_buf_height(struct tpg_data *tpg, unsigned h)
489 {
490         tpg->buf_height = h;
491 }
492
493 static inline void tpg_s_field(struct tpg_data *tpg, unsigned field, bool alternate)
494 {
495         tpg->field = field;
496         tpg->field_alternate = alternate;
497 }
498
499 static inline void tpg_s_perc_fill(struct tpg_data *tpg,
500                                       unsigned perc_fill)
501 {
502         tpg->perc_fill = perc_fill;
503 }
504
505 static inline unsigned tpg_g_perc_fill(const struct tpg_data *tpg)
506 {
507         return tpg->perc_fill;
508 }
509
510 static inline void tpg_s_perc_fill_blank(struct tpg_data *tpg,
511                                          bool perc_fill_blank)
512 {
513         tpg->perc_fill_blank = perc_fill_blank;
514 }
515
516 static inline void tpg_s_video_aspect(struct tpg_data *tpg,
517                                         enum tpg_video_aspect vid_aspect)
518 {
519         if (tpg->vid_aspect == vid_aspect)
520                 return;
521         tpg->vid_aspect = vid_aspect;
522         tpg->recalc_square_border = true;
523 }
524
525 static inline enum tpg_video_aspect tpg_g_video_aspect(const struct tpg_data *tpg)
526 {
527         return tpg->vid_aspect;
528 }
529
530 static inline void tpg_s_pixel_aspect(struct tpg_data *tpg,
531                                         enum tpg_pixel_aspect pix_aspect)
532 {
533         if (tpg->pix_aspect == pix_aspect)
534                 return;
535         tpg->pix_aspect = pix_aspect;
536         tpg->recalc_square_border = true;
537 }
538
539 static inline void tpg_s_show_border(struct tpg_data *tpg,
540                                         bool show_border)
541 {
542         tpg->show_border = show_border;
543 }
544
545 static inline void tpg_s_show_square(struct tpg_data *tpg,
546                                         bool show_square)
547 {
548         tpg->show_square = show_square;
549 }
550
551 static inline void tpg_s_insert_sav(struct tpg_data *tpg, bool insert_sav)
552 {
553         tpg->insert_sav = insert_sav;
554 }
555
556 static inline void tpg_s_insert_eav(struct tpg_data *tpg, bool insert_eav)
557 {
558         tpg->insert_eav = insert_eav;
559 }
560
561 void tpg_update_mv_step(struct tpg_data *tpg);
562
563 static inline void tpg_s_mv_hor_mode(struct tpg_data *tpg,
564                                 enum tpg_move_mode mv_hor_mode)
565 {
566         tpg->mv_hor_mode = mv_hor_mode;
567         tpg_update_mv_step(tpg);
568 }
569
570 static inline void tpg_s_mv_vert_mode(struct tpg_data *tpg,
571                                 enum tpg_move_mode mv_vert_mode)
572 {
573         tpg->mv_vert_mode = mv_vert_mode;
574         tpg_update_mv_step(tpg);
575 }
576
577 static inline void tpg_init_mv_count(struct tpg_data *tpg)
578 {
579         tpg->mv_hor_count = tpg->mv_vert_count = 0;
580 }
581
582 static inline void tpg_update_mv_count(struct tpg_data *tpg, bool frame_is_field)
583 {
584         tpg->mv_hor_count += tpg->mv_hor_step * (frame_is_field ? 1 : 2);
585         tpg->mv_vert_count += tpg->mv_vert_step * (frame_is_field ? 1 : 2);
586 }
587
588 static inline void tpg_s_hflip(struct tpg_data *tpg, bool hflip)
589 {
590         if (tpg->hflip == hflip)
591                 return;
592         tpg->hflip = hflip;
593         tpg_update_mv_step(tpg);
594         tpg->recalc_lines = true;
595 }
596
597 static inline bool tpg_g_hflip(const struct tpg_data *tpg)
598 {
599         return tpg->hflip;
600 }
601
602 static inline void tpg_s_vflip(struct tpg_data *tpg, bool vflip)
603 {
604         tpg->vflip = vflip;
605 }
606
607 static inline bool tpg_g_vflip(const struct tpg_data *tpg)
608 {
609         return tpg->vflip;
610 }
611
612 static inline bool tpg_pattern_is_static(const struct tpg_data *tpg)
613 {
614         return tpg->pattern != TPG_PAT_NOISE &&
615                tpg->mv_hor_mode == TPG_MOVE_NONE &&
616                tpg->mv_vert_mode == TPG_MOVE_NONE;
617 }
618
619 #endif