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