Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v4.7-rc3 597 lines 14 kB view raw
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 31enum 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 58extern const char * const tpg_pattern_strings[]; 59 60enum tpg_quality { 61 TPG_QUAL_COLOR, 62 TPG_QUAL_GRAY, 63 TPG_QUAL_NOISE 64}; 65 66enum 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 74enum tpg_pixel_aspect { 75 TPG_PIXEL_ASPECT_SQUARE, 76 TPG_PIXEL_ASPECT_NTSC, 77 TPG_PIXEL_ASPECT_PAL, 78}; 79 80enum 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 90extern const char * const tpg_aspect_strings[]; 91 92#define TPG_MAX_PLANES 3 93#define TPG_MAX_PAT_LINES 8 94 95struct tpg_data { 96 /* Source frame size */ 97 unsigned src_width, src_height; 98 /* Buffer height */ 99 unsigned buf_height; 100 /* Scaled output frame size */ 101 unsigned scaled_width; 102 u32 field; 103 bool field_alternate; 104 /* crop coordinates are frame-based */ 105 struct v4l2_rect crop; 106 /* compose coordinates are format-based */ 107 struct v4l2_rect compose; 108 /* border and square coordinates are frame-based */ 109 struct v4l2_rect border; 110 struct v4l2_rect square; 111 112 /* Color-related fields */ 113 enum tpg_quality qual; 114 unsigned qual_offset; 115 u8 alpha_component; 116 bool alpha_red_only; 117 u8 brightness; 118 u8 contrast; 119 u8 saturation; 120 s16 hue; 121 u32 fourcc; 122 bool is_yuv; 123 u32 colorspace; 124 u32 xfer_func; 125 u32 ycbcr_enc; 126 /* 127 * Stores the actual transfer function, i.e. will never be 128 * V4L2_XFER_FUNC_DEFAULT. 129 */ 130 u32 real_xfer_func; 131 /* 132 * Stores the actual Y'CbCr encoding, i.e. will never be 133 * V4L2_YCBCR_ENC_DEFAULT. 134 */ 135 u32 real_ycbcr_enc; 136 u32 quantization; 137 /* 138 * Stores the actual quantization, i.e. will never be 139 * V4L2_QUANTIZATION_DEFAULT. 140 */ 141 u32 real_quantization; 142 enum tpg_video_aspect vid_aspect; 143 enum tpg_pixel_aspect pix_aspect; 144 unsigned rgb_range; 145 unsigned real_rgb_range; 146 unsigned buffers; 147 unsigned planes; 148 bool interleaved; 149 u8 vdownsampling[TPG_MAX_PLANES]; 150 u8 hdownsampling[TPG_MAX_PLANES]; 151 /* 152 * horizontal positions must be ANDed with this value to enforce 153 * correct boundaries for packed YUYV values. 154 */ 155 unsigned hmask[TPG_MAX_PLANES]; 156 /* Used to store the colors in native format, either RGB or YUV */ 157 u8 colors[TPG_COLOR_MAX][3]; 158 u8 textfg[TPG_MAX_PLANES][8], textbg[TPG_MAX_PLANES][8]; 159 /* size in bytes for two pixels in each plane */ 160 unsigned twopixelsize[TPG_MAX_PLANES]; 161 unsigned bytesperline[TPG_MAX_PLANES]; 162 163 /* Configuration */ 164 enum tpg_pattern pattern; 165 bool hflip; 166 bool vflip; 167 unsigned perc_fill; 168 bool perc_fill_blank; 169 bool show_border; 170 bool show_square; 171 bool insert_sav; 172 bool insert_eav; 173 174 /* Test pattern movement */ 175 enum tpg_move_mode mv_hor_mode; 176 int mv_hor_count; 177 int mv_hor_step; 178 enum tpg_move_mode mv_vert_mode; 179 int mv_vert_count; 180 int mv_vert_step; 181 182 bool recalc_colors; 183 bool recalc_lines; 184 bool recalc_square_border; 185 186 /* Used to store TPG_MAX_PAT_LINES lines, each with up to two planes */ 187 unsigned max_line_width; 188 u8 *lines[TPG_MAX_PAT_LINES][TPG_MAX_PLANES]; 189 u8 *downsampled_lines[TPG_MAX_PAT_LINES][TPG_MAX_PLANES]; 190 u8 *random_line[TPG_MAX_PLANES]; 191 u8 *contrast_line[TPG_MAX_PLANES]; 192 u8 *black_line[TPG_MAX_PLANES]; 193}; 194 195void tpg_init(struct tpg_data *tpg, unsigned w, unsigned h); 196int tpg_alloc(struct tpg_data *tpg, unsigned max_w); 197void tpg_free(struct tpg_data *tpg); 198void tpg_reset_source(struct tpg_data *tpg, unsigned width, unsigned height, 199 u32 field); 200void tpg_log_status(struct tpg_data *tpg); 201 202void tpg_set_font(const u8 *f); 203void tpg_gen_text(const struct tpg_data *tpg, 204 u8 *basep[TPG_MAX_PLANES][2], int y, int x, char *text); 205void tpg_calc_text_basep(struct tpg_data *tpg, 206 u8 *basep[TPG_MAX_PLANES][2], unsigned p, u8 *vbuf); 207unsigned tpg_g_interleaved_plane(const struct tpg_data *tpg, unsigned buf_line); 208void tpg_fill_plane_buffer(struct tpg_data *tpg, v4l2_std_id std, 209 unsigned p, u8 *vbuf); 210void tpg_fillbuffer(struct tpg_data *tpg, v4l2_std_id std, 211 unsigned p, u8 *vbuf); 212bool tpg_s_fourcc(struct tpg_data *tpg, u32 fourcc); 213void tpg_s_crop_compose(struct tpg_data *tpg, const struct v4l2_rect *crop, 214 const struct v4l2_rect *compose); 215 216static inline void tpg_s_pattern(struct tpg_data *tpg, enum tpg_pattern pattern) 217{ 218 if (tpg->pattern == pattern) 219 return; 220 tpg->pattern = pattern; 221 tpg->recalc_colors = true; 222} 223 224static inline void tpg_s_quality(struct tpg_data *tpg, 225 enum tpg_quality qual, unsigned qual_offset) 226{ 227 if (tpg->qual == qual && tpg->qual_offset == qual_offset) 228 return; 229 tpg->qual = qual; 230 tpg->qual_offset = qual_offset; 231 tpg->recalc_colors = true; 232} 233 234static inline enum tpg_quality tpg_g_quality(const struct tpg_data *tpg) 235{ 236 return tpg->qual; 237} 238 239static inline void tpg_s_alpha_component(struct tpg_data *tpg, 240 u8 alpha_component) 241{ 242 if (tpg->alpha_component == alpha_component) 243 return; 244 tpg->alpha_component = alpha_component; 245 tpg->recalc_colors = true; 246} 247 248static inline void tpg_s_alpha_mode(struct tpg_data *tpg, 249 bool red_only) 250{ 251 if (tpg->alpha_red_only == red_only) 252 return; 253 tpg->alpha_red_only = red_only; 254 tpg->recalc_colors = true; 255} 256 257static inline void tpg_s_brightness(struct tpg_data *tpg, 258 u8 brightness) 259{ 260 if (tpg->brightness == brightness) 261 return; 262 tpg->brightness = brightness; 263 tpg->recalc_colors = true; 264} 265 266static inline void tpg_s_contrast(struct tpg_data *tpg, 267 u8 contrast) 268{ 269 if (tpg->contrast == contrast) 270 return; 271 tpg->contrast = contrast; 272 tpg->recalc_colors = true; 273} 274 275static inline void tpg_s_saturation(struct tpg_data *tpg, 276 u8 saturation) 277{ 278 if (tpg->saturation == saturation) 279 return; 280 tpg->saturation = saturation; 281 tpg->recalc_colors = true; 282} 283 284static inline void tpg_s_hue(struct tpg_data *tpg, 285 s16 hue) 286{ 287 if (tpg->hue == hue) 288 return; 289 tpg->hue = hue; 290 tpg->recalc_colors = true; 291} 292 293static inline void tpg_s_rgb_range(struct tpg_data *tpg, 294 unsigned rgb_range) 295{ 296 if (tpg->rgb_range == rgb_range) 297 return; 298 tpg->rgb_range = rgb_range; 299 tpg->recalc_colors = true; 300} 301 302static inline void tpg_s_real_rgb_range(struct tpg_data *tpg, 303 unsigned rgb_range) 304{ 305 if (tpg->real_rgb_range == rgb_range) 306 return; 307 tpg->real_rgb_range = rgb_range; 308 tpg->recalc_colors = true; 309} 310 311static inline void tpg_s_colorspace(struct tpg_data *tpg, u32 colorspace) 312{ 313 if (tpg->colorspace == colorspace) 314 return; 315 tpg->colorspace = colorspace; 316 tpg->recalc_colors = true; 317} 318 319static inline u32 tpg_g_colorspace(const struct tpg_data *tpg) 320{ 321 return tpg->colorspace; 322} 323 324static inline void tpg_s_ycbcr_enc(struct tpg_data *tpg, u32 ycbcr_enc) 325{ 326 if (tpg->ycbcr_enc == ycbcr_enc) 327 return; 328 tpg->ycbcr_enc = ycbcr_enc; 329 tpg->recalc_colors = true; 330} 331 332static inline u32 tpg_g_ycbcr_enc(const struct tpg_data *tpg) 333{ 334 return tpg->ycbcr_enc; 335} 336 337static inline void tpg_s_xfer_func(struct tpg_data *tpg, u32 xfer_func) 338{ 339 if (tpg->xfer_func == xfer_func) 340 return; 341 tpg->xfer_func = xfer_func; 342 tpg->recalc_colors = true; 343} 344 345static inline u32 tpg_g_xfer_func(const struct tpg_data *tpg) 346{ 347 return tpg->xfer_func; 348} 349 350static inline void tpg_s_quantization(struct tpg_data *tpg, u32 quantization) 351{ 352 if (tpg->quantization == quantization) 353 return; 354 tpg->quantization = quantization; 355 tpg->recalc_colors = true; 356} 357 358static inline u32 tpg_g_quantization(const struct tpg_data *tpg) 359{ 360 return tpg->quantization; 361} 362 363static inline unsigned tpg_g_buffers(const struct tpg_data *tpg) 364{ 365 return tpg->buffers; 366} 367 368static inline unsigned tpg_g_planes(const struct tpg_data *tpg) 369{ 370 return tpg->interleaved ? 1 : tpg->planes; 371} 372 373static inline bool tpg_g_interleaved(const struct tpg_data *tpg) 374{ 375 return tpg->interleaved; 376} 377 378static inline unsigned tpg_g_twopixelsize(const struct tpg_data *tpg, unsigned plane) 379{ 380 return tpg->twopixelsize[plane]; 381} 382 383static inline unsigned tpg_hdiv(const struct tpg_data *tpg, 384 unsigned plane, unsigned x) 385{ 386 return ((x / tpg->hdownsampling[plane]) & tpg->hmask[plane]) * 387 tpg->twopixelsize[plane] / 2; 388} 389 390static inline unsigned tpg_hscale(const struct tpg_data *tpg, unsigned x) 391{ 392 return (x * tpg->scaled_width) / tpg->src_width; 393} 394 395static inline unsigned tpg_hscale_div(const struct tpg_data *tpg, 396 unsigned plane, unsigned x) 397{ 398 return tpg_hdiv(tpg, plane, tpg_hscale(tpg, x)); 399} 400 401static inline unsigned tpg_g_bytesperline(const struct tpg_data *tpg, unsigned plane) 402{ 403 return tpg->bytesperline[plane]; 404} 405 406static inline void tpg_s_bytesperline(struct tpg_data *tpg, unsigned plane, unsigned bpl) 407{ 408 unsigned p; 409 410 if (tpg->buffers > 1) { 411 tpg->bytesperline[plane] = bpl; 412 return; 413 } 414 415 for (p = 0; p < tpg_g_planes(tpg); p++) { 416 unsigned plane_w = bpl * tpg->twopixelsize[p] / tpg->twopixelsize[0]; 417 418 tpg->bytesperline[p] = plane_w / tpg->hdownsampling[p]; 419 } 420 if (tpg_g_interleaved(tpg)) 421 tpg->bytesperline[1] = tpg->bytesperline[0]; 422} 423 424 425static inline unsigned tpg_g_line_width(const struct tpg_data *tpg, unsigned plane) 426{ 427 unsigned w = 0; 428 unsigned p; 429 430 if (tpg->buffers > 1) 431 return tpg_g_bytesperline(tpg, plane); 432 for (p = 0; p < tpg_g_planes(tpg); p++) { 433 unsigned plane_w = tpg_g_bytesperline(tpg, p); 434 435 w += plane_w / tpg->vdownsampling[p]; 436 } 437 return w; 438} 439 440static inline unsigned tpg_calc_line_width(const struct tpg_data *tpg, 441 unsigned plane, unsigned bpl) 442{ 443 unsigned w = 0; 444 unsigned p; 445 446 if (tpg->buffers > 1) 447 return bpl; 448 for (p = 0; p < tpg_g_planes(tpg); p++) { 449 unsigned plane_w = bpl * tpg->twopixelsize[p] / tpg->twopixelsize[0]; 450 451 plane_w /= tpg->hdownsampling[p]; 452 w += plane_w / tpg->vdownsampling[p]; 453 } 454 return w; 455} 456 457static inline unsigned tpg_calc_plane_size(const struct tpg_data *tpg, unsigned plane) 458{ 459 if (plane >= tpg_g_planes(tpg)) 460 return 0; 461 462 return tpg_g_bytesperline(tpg, plane) * tpg->buf_height / 463 tpg->vdownsampling[plane]; 464} 465 466static inline void tpg_s_buf_height(struct tpg_data *tpg, unsigned h) 467{ 468 tpg->buf_height = h; 469} 470 471static inline void tpg_s_field(struct tpg_data *tpg, unsigned field, bool alternate) 472{ 473 tpg->field = field; 474 tpg->field_alternate = alternate; 475} 476 477static inline void tpg_s_perc_fill(struct tpg_data *tpg, 478 unsigned perc_fill) 479{ 480 tpg->perc_fill = perc_fill; 481} 482 483static inline unsigned tpg_g_perc_fill(const struct tpg_data *tpg) 484{ 485 return tpg->perc_fill; 486} 487 488static inline void tpg_s_perc_fill_blank(struct tpg_data *tpg, 489 bool perc_fill_blank) 490{ 491 tpg->perc_fill_blank = perc_fill_blank; 492} 493 494static inline void tpg_s_video_aspect(struct tpg_data *tpg, 495 enum tpg_video_aspect vid_aspect) 496{ 497 if (tpg->vid_aspect == vid_aspect) 498 return; 499 tpg->vid_aspect = vid_aspect; 500 tpg->recalc_square_border = true; 501} 502 503static inline enum tpg_video_aspect tpg_g_video_aspect(const struct tpg_data *tpg) 504{ 505 return tpg->vid_aspect; 506} 507 508static inline void tpg_s_pixel_aspect(struct tpg_data *tpg, 509 enum tpg_pixel_aspect pix_aspect) 510{ 511 if (tpg->pix_aspect == pix_aspect) 512 return; 513 tpg->pix_aspect = pix_aspect; 514 tpg->recalc_square_border = true; 515} 516 517static inline void tpg_s_show_border(struct tpg_data *tpg, 518 bool show_border) 519{ 520 tpg->show_border = show_border; 521} 522 523static inline void tpg_s_show_square(struct tpg_data *tpg, 524 bool show_square) 525{ 526 tpg->show_square = show_square; 527} 528 529static inline void tpg_s_insert_sav(struct tpg_data *tpg, bool insert_sav) 530{ 531 tpg->insert_sav = insert_sav; 532} 533 534static inline void tpg_s_insert_eav(struct tpg_data *tpg, bool insert_eav) 535{ 536 tpg->insert_eav = insert_eav; 537} 538 539void tpg_update_mv_step(struct tpg_data *tpg); 540 541static inline void tpg_s_mv_hor_mode(struct tpg_data *tpg, 542 enum tpg_move_mode mv_hor_mode) 543{ 544 tpg->mv_hor_mode = mv_hor_mode; 545 tpg_update_mv_step(tpg); 546} 547 548static inline void tpg_s_mv_vert_mode(struct tpg_data *tpg, 549 enum tpg_move_mode mv_vert_mode) 550{ 551 tpg->mv_vert_mode = mv_vert_mode; 552 tpg_update_mv_step(tpg); 553} 554 555static inline void tpg_init_mv_count(struct tpg_data *tpg) 556{ 557 tpg->mv_hor_count = tpg->mv_vert_count = 0; 558} 559 560static inline void tpg_update_mv_count(struct tpg_data *tpg, bool frame_is_field) 561{ 562 tpg->mv_hor_count += tpg->mv_hor_step * (frame_is_field ? 1 : 2); 563 tpg->mv_vert_count += tpg->mv_vert_step * (frame_is_field ? 1 : 2); 564} 565 566static inline void tpg_s_hflip(struct tpg_data *tpg, bool hflip) 567{ 568 if (tpg->hflip == hflip) 569 return; 570 tpg->hflip = hflip; 571 tpg_update_mv_step(tpg); 572 tpg->recalc_lines = true; 573} 574 575static inline bool tpg_g_hflip(const struct tpg_data *tpg) 576{ 577 return tpg->hflip; 578} 579 580static inline void tpg_s_vflip(struct tpg_data *tpg, bool vflip) 581{ 582 tpg->vflip = vflip; 583} 584 585static inline bool tpg_g_vflip(const struct tpg_data *tpg) 586{ 587 return tpg->vflip; 588} 589 590static inline bool tpg_pattern_is_static(const struct tpg_data *tpg) 591{ 592 return tpg->pattern != TPG_PAT_NOISE && 593 tpg->mv_hor_mode == TPG_MOVE_NONE && 594 tpg->mv_vert_mode == TPG_MOVE_NONE; 595} 596 597#endif