Lines Matching refs:tpg

3  * v4l2-tpg-core.c - Test Pattern Generator
11 #include "v4l2-tpg-colors.h"
85 void tpg_init(struct tpg_data *tpg, unsigned w, unsigned h)
87 memset(tpg, 0, sizeof(*tpg));
88 tpg->scaled_width = tpg->src_width = w;
89 tpg->src_height = tpg->buf_height = h;
90 tpg->crop.width = tpg->compose.width = w;
91 tpg->crop.height = tpg->compose.height = h;
92 tpg->recalc_colors = true;
93 tpg->recalc_square_border = true;
94 tpg->brightness = 128;
95 tpg->contrast = 128;
96 tpg->saturation = 128;
97 tpg->hue = 0;
98 tpg->mv_hor_mode = TPG_MOVE_NONE;
99 tpg->mv_vert_mode = TPG_MOVE_NONE;
100 tpg->field = V4L2_FIELD_NONE;
101 tpg_s_fourcc(tpg, V4L2_PIX_FMT_RGB24);
102 tpg->colorspace = V4L2_COLORSPACE_SRGB;
103 tpg->perc_fill = 100;
104 tpg->hsv_enc = V4L2_HSV_ENC_180;
107 int tpg_alloc(struct tpg_data *tpg, unsigned max_w)
112 tpg->max_line_width = max_w;
117 tpg->lines[pat][plane] =
119 if (!tpg->lines[pat][plane])
123 tpg->downsampled_lines[pat][plane] =
125 if (!tpg->downsampled_lines[pat][plane])
132 tpg->contrast_line[plane] =
134 if (!tpg->contrast_line[plane])
136 tpg->black_line[plane] =
138 if (!tpg->black_line[plane])
140 tpg->random_line[plane] =
142 if (!tpg->random_line[plane])
148 void tpg_free(struct tpg_data *tpg)
155 vfree(tpg->lines[pat][plane]);
156 tpg->lines[pat][plane] = NULL;
159 vfree(tpg->downsampled_lines[pat][plane]);
160 tpg->downsampled_lines[pat][plane] = NULL;
163 vfree(tpg->contrast_line[plane]);
164 vfree(tpg->black_line[plane]);
165 vfree(tpg->random_line[plane]);
166 tpg->contrast_line[plane] = NULL;
167 tpg->black_line[plane] = NULL;
168 tpg->random_line[plane] = NULL;
172 bool tpg_s_fourcc(struct tpg_data *tpg, u32 fourcc)
174 tpg->fourcc = fourcc;
175 tpg->planes = 1;
176 tpg->buffers = 1;
177 tpg->recalc_colors = true;
178 tpg->interleaved = false;
179 tpg->vdownsampling[0] = 1;
180 tpg->hdownsampling[0] = 1;
181 tpg->hmask[0] = ~0;
182 tpg->hmask[1] = ~0;
183 tpg->hmask[2] = ~0;
202 tpg->interleaved = true;
203 tpg->vdownsampling[1] = 1;
204 tpg->hdownsampling[1] = 1;
205 tpg->planes = 2;
244 tpg->color_enc = TGP_COLOR_ENC_RGB;
252 tpg->color_enc = TGP_COLOR_ENC_LUMA;
262 tpg->color_enc = TGP_COLOR_ENC_YCBCR;
266 tpg->buffers = 3;
270 tpg->vdownsampling[1] = 2;
271 tpg->vdownsampling[2] = 2;
272 tpg->hdownsampling[1] = 2;
273 tpg->hdownsampling[2] = 2;
274 tpg->planes = 3;
275 tpg->color_enc = TGP_COLOR_ENC_YCBCR;
279 tpg->buffers = 3;
282 tpg->vdownsampling[1] = 1;
283 tpg->vdownsampling[2] = 1;
284 tpg->hdownsampling[1] = 2;
285 tpg->hdownsampling[2] = 2;
286 tpg->planes = 3;
287 tpg->color_enc = TGP_COLOR_ENC_YCBCR;
291 tpg->buffers = 2;
295 tpg->vdownsampling[1] = 1;
296 tpg->hdownsampling[1] = 1;
297 tpg->hmask[1] = ~1;
298 tpg->planes = 2;
299 tpg->color_enc = TGP_COLOR_ENC_YCBCR;
303 tpg->buffers = 2;
307 tpg->vdownsampling[1] = 2;
308 tpg->hdownsampling[1] = 1;
309 tpg->hmask[1] = ~1;
310 tpg->planes = 2;
311 tpg->color_enc = TGP_COLOR_ENC_YCBCR;
315 tpg->buffers = 3;
316 tpg->planes = 3;
317 tpg->vdownsampling[1] = 1;
318 tpg->vdownsampling[2] = 1;
319 tpg->hdownsampling[1] = 1;
320 tpg->hdownsampling[2] = 1;
321 tpg->color_enc = TGP_COLOR_ENC_YCBCR;
325 tpg->vdownsampling[1] = 1;
326 tpg->hdownsampling[1] = 1;
327 tpg->planes = 2;
328 tpg->color_enc = TGP_COLOR_ENC_YCBCR;
334 tpg->hmask[0] = ~1;
335 tpg->color_enc = TGP_COLOR_ENC_YCBCR;
339 tpg->color_enc = TGP_COLOR_ENC_HSV;
348 tpg->twopixelsize[0] = 2;
385 tpg->twopixelsize[0] = 2 * 2;
390 tpg->twopixelsize[0] = 2 * 3;
409 tpg->twopixelsize[0] = 2 * 4;
423 tpg->twopixelsize[0] = 2;
424 tpg->twopixelsize[1] = 2;
438 tpg->twopixelsize[0] = 4;
439 tpg->twopixelsize[1] = 4;
450 tpg->twopixelsize[0] = 2;
451 tpg->twopixelsize[1] = 2;
452 tpg->twopixelsize[2] = 2;
456 tpg->twopixelsize[0] = 2;
457 tpg->twopixelsize[1] = 4;
463 void tpg_s_crop_compose(struct tpg_data *tpg, const struct v4l2_rect *crop,
466 tpg->crop = *crop;
467 tpg->compose = *compose;
468 tpg->scaled_width = (tpg->src_width * tpg->compose.width +
469 tpg->crop.width - 1) / tpg->crop.width;
470 tpg->scaled_width &= ~1;
471 if (tpg->scaled_width > tpg->max_line_width)
472 tpg->scaled_width = tpg->max_line_width;
473 if (tpg->scaled_width < 2)
474 tpg->scaled_width = 2;
475 tpg->recalc_lines = true;
478 void tpg_reset_source(struct tpg_data *tpg, unsigned width, unsigned height,
483 tpg->src_width = width;
484 tpg->src_height = height;
485 tpg->field = field;
486 tpg->buf_height = height;
488 tpg->buf_height /= 2;
489 tpg->scaled_width = width;
490 tpg->crop.top = tpg->crop.left = 0;
491 tpg->crop.width = width;
492 tpg->crop.height = height;
493 tpg->compose.top = tpg->compose.left = 0;
494 tpg->compose.width = width;
495 tpg->compose.height = tpg->buf_height;
496 for (p = 0; p < tpg->planes; p++)
497 tpg->bytesperline[p] = (width * tpg->twopixelsize[p]) /
498 (2 * tpg->hdownsampling[p]);
499 tpg->recalc_square_border = true;
502 static enum tpg_color tpg_get_textbg_color(struct tpg_data *tpg)
504 switch (tpg->pattern) {
514 static enum tpg_color tpg_get_textfg_color(struct tpg_data *tpg)
516 switch (tpg->pattern) {
539 static void color_to_hsv(struct tpg_data *tpg, int r, int g, int b,
572 third_size = (tpg->real_hsv_enc == V4L2_HSV_ENC_180) ? 60 : 85;
592 if (tpg->real_hsv_enc == V4L2_HSV_ENC_180) {
612 static void color_to_ycbcr(struct tpg_data *tpg, int r, int g, int b,
666 bool full = tpg->real_quantization == V4L2_QUANTIZATION_FULL_RANGE;
670 switch (tpg->real_ycbcr_enc) {
726 static void ycbcr_to_color(struct tpg_data *tpg, int y, int cb, int cr,
780 bool full = tpg->real_quantization == V4L2_QUANTIZATION_FULL_RANGE;
785 switch (tpg->real_ycbcr_enc) {
837 static void precalculate_color(struct tpg_data *tpg, int k)
847 col = tpg_get_textbg_color(tpg);
853 col = tpg_get_textfg_color(tpg);
858 } else if (tpg->pattern == TPG_PAT_NOISE) {
861 r = g = b = tpg->qual_offset + prandom_u32_max(196);
866 if (tpg->pattern == TPG_PAT_CSC_COLORBAR && col <= TPG_COLOR_CSC_BLACK) {
867 r = tpg_csc_colors[tpg->colorspace][tpg->real_xfer_func][col].r;
868 g = tpg_csc_colors[tpg->colorspace][tpg->real_xfer_func][col].g;
869 b = tpg_csc_colors[tpg->colorspace][tpg->real_xfer_func][col].b;
876 if (tpg->qual == TPG_QUAL_GRAY ||
877 tpg->color_enc == TGP_COLOR_ENC_LUMA) {
890 if (tpg->real_rgb_range == V4L2_DV_RGB_RANGE_LIMITED &&
891 tpg->rgb_range == V4L2_DV_RGB_RANGE_FULL &&
892 tpg->color_enc == TGP_COLOR_ENC_RGB) {
901 } else if (tpg->real_rgb_range != V4L2_DV_RGB_RANGE_LIMITED &&
902 tpg->rgb_range == V4L2_DV_RGB_RANGE_LIMITED &&
903 tpg->color_enc == TGP_COLOR_ENC_RGB) {
917 if ((tpg->brightness != 128 || tpg->contrast != 128 ||
918 tpg->saturation != 128 || tpg->hue) &&
919 tpg->color_enc != TGP_COLOR_ENC_LUMA) {
925 color_to_ycbcr(tpg, r, g, b, &y, &cb, &cr);
927 y = (16 << 4) + ((y - (16 << 4)) * tpg->contrast) / 128;
928 y += (tpg->brightness << 4) - (128 << 4);
932 tmp_cb = (cb * cos(128 + tpg->hue)) / 127 + (cr * sin[128 + tpg->hue]) / 127;
933 tmp_cr = (cr * cos(128 + tpg->hue)) / 127 - (cb * sin[128 + tpg->hue]) / 127;
935 cb = (128 << 4) + (tmp_cb * tpg->contrast * tpg->saturation) / (128 * 128);
936 cr = (128 << 4) + (tmp_cr * tpg->contrast * tpg->saturation) / (128 * 128);
937 if (tpg->color_enc == TGP_COLOR_ENC_YCBCR)
940 ycbcr_to_color(tpg, y, cb, cr, &r, &g, &b);
941 } else if ((tpg->brightness != 128 || tpg->contrast != 128) &&
942 tpg->color_enc == TGP_COLOR_ENC_LUMA) {
943 r = (16 << 4) + ((r - (16 << 4)) * tpg->contrast) / 128;
944 r += (tpg->brightness << 4) - (128 << 4);
947 switch (tpg->color_enc) {
952 color_to_hsv(tpg, r, g, b, &h, &s, &v);
953 tpg->colors[k][0] = h;
954 tpg->colors[k][1] = s;
955 tpg->colors[k][2] = v;
962 color_to_ycbcr(tpg, r, g, b, &y, &cb, &cr);
972 if (tpg->real_quantization == V4L2_QUANTIZATION_LIM_RANGE &&
973 tpg->real_ycbcr_enc != V4L2_YCBCR_ENC_XV601 &&
974 tpg->real_ycbcr_enc != V4L2_YCBCR_ENC_XV709) {
983 switch (tpg->fourcc) {
1000 tpg->colors[k][0] = y;
1001 tpg->colors[k][1] = cb;
1002 tpg->colors[k][2] = cr;
1007 tpg->colors[k][0] = r >> 4;
1012 if (tpg->real_quantization == V4L2_QUANTIZATION_LIM_RANGE) {
1017 switch (tpg->fourcc) {
1070 tpg->colors[k][0] = r;
1071 tpg->colors[k][1] = g;
1072 tpg->colors[k][2] = b;
1078 static void tpg_precalculate_colors(struct tpg_data *tpg)
1083 precalculate_color(tpg, k);
1087 static void gen_twopix(struct tpg_data *tpg,
1090 unsigned offset = odd * tpg->twopixelsize[0] / 2;
1091 u8 alpha = tpg->alpha_component;
1094 if (tpg->alpha_red_only && color != TPG_COLOR_CSC_RED &&
1099 precalculate_color(tpg, color);
1100 r_y_h = tpg->colors[color][0]; /* R or precalculated Y, H */
1101 g_u_s = tpg->colors[color][1]; /* G or precalculated U, V */
1102 b_v = tpg->colors[color][2]; /* B or precalculated V */
1104 switch (tpg->fourcc) {
1497 unsigned tpg_g_interleaved_plane(const struct tpg_data *tpg, unsigned buf_line)
1499 switch (tpg->fourcc) {
1523 static unsigned tpg_get_pat_lines(const struct tpg_data *tpg)
1525 switch (tpg->pattern) {
1545 static unsigned tpg_get_pat_line(const struct tpg_data *tpg, unsigned line)
1547 switch (tpg->pattern) {
1559 return (line * 8) / tpg->src_height;
1561 return line == tpg->src_height / 2;
1563 return (line + 1) / 2 == tpg->src_height / 4;
1565 return (line + 10) / 20 == tpg->src_height / 40;
1573 * Note: x is in the range 0 to 2 * tpg->src_width.
1575 static enum tpg_color tpg_get_color(const struct tpg_data *tpg,
1598 switch (tpg->pattern) {
1602 return bars[tpg->pattern][((x * 8) / tpg->src_width) % 8];
1604 return bars[1][(pat_line + (x * 8) / tpg->src_width) % 8];
1637 if (pat_line || (x % tpg->src_width) == tpg->src_width / 2)
1641 if (pat_line || ((x % tpg->src_width) + 1) / 2 == tpg->src_width / 4)
1645 if (pat_line || ((x % tpg->src_width) + 10) / 20 == tpg->src_width / 40)
1649 return TPG_COLOR_RAMP + ((x % tpg->src_width) * 256) / tpg->src_width;
1661 static void tpg_calculate_square_border(struct tpg_data *tpg)
1663 unsigned w = tpg->src_width;
1664 unsigned h = tpg->src_height;
1671 tpg->square.width = sq_w;
1672 if (tpg->vid_aspect == TPG_VIDEO_ASPECT_16X9_ANAMORPHIC) {
1677 tpg->square.width = ana_sq_w;
1679 tpg->square.left = (w - tpg->square.width) / 2;
1680 if (tpg->pix_aspect == TPG_PIXEL_ASPECT_NTSC)
1682 else if (tpg->pix_aspect == TPG_PIXEL_ASPECT_PAL)
1684 tpg->square.height = sq_h;
1685 tpg->square.top = (h - sq_h) / 2;
1686 tpg->border.left = 0;
1687 tpg->border.width = w;
1688 tpg->border.top = 0;
1689 tpg->border.height = h;
1690 switch (tpg->vid_aspect) {
1692 if (tpg->pix_aspect)
1695 tpg->border.width = ((4 * h) / 3) & ~1;
1696 if (((w - tpg->border.width) / 2) & ~1)
1697 tpg->border.width -= 2;
1698 tpg->border.left = (w - tpg->border.width) / 2;
1701 tpg->border.height = ((3 * w) / 4) & ~1;
1702 tpg->border.top = (h - tpg->border.height) / 2;
1705 if (tpg->pix_aspect) {
1706 tpg->border.height = tpg->pix_aspect == TPG_PIXEL_ASPECT_NTSC ? 420 : 506;
1707 tpg->border.top = (h - tpg->border.height) / 2;
1711 tpg->border.width = ((14 * h) / 9) & ~1;
1712 if (((w - tpg->border.width) / 2) & ~1)
1713 tpg->border.width -= 2;
1714 tpg->border.left = (w - tpg->border.width) / 2;
1717 tpg->border.height = ((9 * w) / 14) & ~1;
1718 tpg->border.top = (h - tpg->border.height) / 2;
1721 if (tpg->pix_aspect) {
1722 tpg->border.height = tpg->pix_aspect == TPG_PIXEL_ASPECT_NTSC ? 368 : 442;
1723 tpg->border.top = (h - tpg->border.height) / 2;
1727 tpg->border.width = ((16 * h) / 9) & ~1;
1728 if (((w - tpg->border.width) / 2) & ~1)
1729 tpg->border.width -= 2;
1730 tpg->border.left = (w - tpg->border.width) / 2;
1733 tpg->border.height = ((9 * w) / 16) & ~1;
1734 tpg->border.top = (h - tpg->border.height) / 2;
1741 static void tpg_precalculate_line(struct tpg_data *tpg)
1749 switch (tpg->pattern) {
1761 for (pat = 0; pat < tpg_get_pat_lines(tpg); pat++) {
1763 unsigned int_part = tpg->src_width / tpg->scaled_width;
1764 unsigned fract_part = tpg->src_width % tpg->scaled_width;
1768 for (x = 0; x < tpg->scaled_width * 2; x += 2) {
1772 real_x = tpg->hflip ? tpg->src_width * 2 - real_x - 2 : real_x;
1773 color1 = tpg_get_color(tpg, pat, real_x);
1777 if (error >= tpg->scaled_width) {
1778 error -= tpg->scaled_width;
1783 real_x = tpg->hflip ? tpg->src_width * 2 - real_x - 2 : real_x;
1784 color2 = tpg_get_color(tpg, pat, real_x);
1788 if (error >= tpg->scaled_width) {
1789 error -= tpg->scaled_width;
1793 gen_twopix(tpg, pix, tpg->hflip ? color2 : color1, 0);
1794 gen_twopix(tpg, pix, tpg->hflip ? color1 : color2, 1);
1795 for (p = 0; p < tpg->planes; p++) {
1796 unsigned twopixsize = tpg->twopixelsize[p];
1797 unsigned hdiv = tpg->hdownsampling[p];
1798 u8 *pos = tpg->lines[pat][p] + tpg_hdiv(tpg, p, x);
1805 if (tpg->vdownsampling[tpg->planes - 1] > 1) {
1806 unsigned pat_lines = tpg_get_pat_lines(tpg);
1811 for (p = 1; p < tpg->planes; p++) {
1812 unsigned w = tpg_hdiv(tpg, p, tpg->scaled_width * 2);
1813 u8 *pos1 = tpg->lines[pat][p];
1814 u8 *pos2 = tpg->lines[next_pat][p];
1815 u8 *dest = tpg->downsampled_lines[pat][p];
1823 gen_twopix(tpg, pix, contrast, 0);
1824 gen_twopix(tpg, pix, contrast, 1);
1825 for (p = 0; p < tpg->planes; p++) {
1826 unsigned twopixsize = tpg->twopixelsize[p];
1827 u8 *pos = tpg->contrast_line[p];
1829 for (x = 0; x < tpg->scaled_width; x += 2, pos += twopixsize)
1833 gen_twopix(tpg, pix, TPG_COLOR_100_BLACK, 0);
1834 gen_twopix(tpg, pix, TPG_COLOR_100_BLACK, 1);
1835 for (p = 0; p < tpg->planes; p++) {
1836 unsigned twopixsize = tpg->twopixelsize[p];
1837 u8 *pos = tpg->black_line[p];
1839 for (x = 0; x < tpg->scaled_width; x += 2, pos += twopixsize)
1843 for (x = 0; x < tpg->scaled_width * 2; x += 2) {
1844 gen_twopix(tpg, pix, TPG_COLOR_RANDOM, 0);
1845 gen_twopix(tpg, pix, TPG_COLOR_RANDOM, 1);
1846 for (p = 0; p < tpg->planes; p++) {
1847 unsigned twopixsize = tpg->twopixelsize[p];
1848 u8 *pos = tpg->random_line[p] + x * twopixsize / 2;
1854 gen_twopix(tpg, tpg->textbg, TPG_COLOR_TEXTBG, 0);
1855 gen_twopix(tpg, tpg->textbg, TPG_COLOR_TEXTBG, 1);
1856 gen_twopix(tpg, tpg->textfg, TPG_COLOR_TEXTFG, 0);
1857 gen_twopix(tpg, tpg->textfg, TPG_COLOR_TEXTFG, 1);
1864 unsigned vdiv = tpg->vdownsampling[p]; \
1865 unsigned hdiv = tpg->hdownsampling[p]; \
1869 memcpy(&fg, tpg->textfg[p], sizeof(PIXTYPE)); \
1870 memcpy(&bg, tpg->textbg[p], sizeof(PIXTYPE)); \
1873 int l = tpg->vflip ? 15 - line : line; \
1875 ((y * step + l) / (vdiv * div)) * tpg->bytesperline[p] + \
1882 if (hdiv == 2 && tpg->hflip) { \
1892 } else if (tpg->hflip) { \
1912 pos += (tpg->hflip ? -8 : 8) / (int)hdiv; \
1917 static noinline void tpg_print_str_2(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2],
1924 static noinline void tpg_print_str_4(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2],
1931 static noinline void tpg_print_str_6(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2],
1938 static noinline void tpg_print_str_8(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2],
1945 void tpg_gen_text(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2],
1948 unsigned step = V4L2_FIELD_HAS_T_OR_B(tpg->field) ? 2 : 1;
1958 if (y + 16 >= tpg->compose.height || x + 8 >= tpg->compose.width)
1961 if (len > (tpg->compose.width - x) / 8)
1962 len = (tpg->compose.width - x) / 8;
1963 if (tpg->vflip)
1964 y = tpg->compose.height - y - 16;
1965 if (tpg->hflip)
1966 x = tpg->compose.width - x - 8;
1967 y += tpg->compose.top;
1968 x += tpg->compose.left;
1969 if (tpg->field == V4L2_FIELD_BOTTOM)
1971 else if (tpg->field == V4L2_FIELD_SEQ_TB || tpg->field == V4L2_FIELD_SEQ_BT)
1974 for (p = 0; p < tpg->planes; p++) {
1976 switch (tpg->twopixelsize[p]) {
1978 tpg_print_str_2(tpg, basep, p, first, div, step, y, x,
1982 tpg_print_str_4(tpg, basep, p, first, div, step, y, x,
1986 tpg_print_str_6(tpg, basep, p, first, div, step, y, x,
1990 tpg_print_str_8(tpg, basep, p, first, div, step, y, x,
1997 void tpg_update_mv_step(struct tpg_data *tpg)
1999 int factor = tpg->mv_hor_mode > TPG_MOVE_NONE ? -1 : 1;
2001 if (tpg->hflip)
2003 switch (tpg->mv_hor_mode) {
2006 tpg->mv_hor_step = ((tpg->src_width + 319) / 320) * 4;
2010 tpg->mv_hor_step = ((tpg->src_width + 639) / 640) * 4;
2014 tpg->mv_hor_step = 2;
2017 tpg->mv_hor_step = 0;
2021 tpg->mv_hor_step = tpg->src_width - tpg->mv_hor_step;
2023 factor = tpg->mv_vert_mode > TPG_MOVE_NONE ? -1 : 1;
2024 switch (tpg->mv_vert_mode) {
2027 tpg->mv_vert_step = ((tpg->src_width + 319) / 320) * 4;
2031 tpg->mv_vert_step = ((tpg->src_width + 639) / 640) * 4;
2035 tpg->mv_vert_step = 1;
2038 tpg->mv_vert_step = 0;
2042 tpg->mv_vert_step = tpg->src_height - tpg->mv_vert_step;
2046 static unsigned tpg_calc_frameline(const struct tpg_data *tpg, unsigned src_y,
2051 return tpg->crop.top + src_y * 2;
2053 return tpg->crop.top + src_y * 2 + 1;
2055 return src_y + tpg->crop.top;
2063 static unsigned tpg_calc_buffer_line(const struct tpg_data *tpg, unsigned y,
2066 y += tpg->compose.top;
2070 return tpg->buf_height / 2 + y / 2;
2075 return tpg->buf_height / 2 + y / 2;
2081 static void tpg_recalc(struct tpg_data *tpg)
2083 if (tpg->recalc_colors) {
2084 tpg->recalc_colors = false;
2085 tpg->recalc_lines = true;
2086 tpg->real_xfer_func = tpg->xfer_func;
2087 tpg->real_ycbcr_enc = tpg->ycbcr_enc;
2088 tpg->real_hsv_enc = tpg->hsv_enc;
2089 tpg->real_quantization = tpg->quantization;
2091 if (tpg->xfer_func == V4L2_XFER_FUNC_DEFAULT)
2092 tpg->real_xfer_func =
2093 V4L2_MAP_XFER_FUNC_DEFAULT(tpg->colorspace);
2095 if (tpg->ycbcr_enc == V4L2_YCBCR_ENC_DEFAULT)
2096 tpg->real_ycbcr_enc =
2097 V4L2_MAP_YCBCR_ENC_DEFAULT(tpg->colorspace);
2099 if (tpg->quantization == V4L2_QUANTIZATION_DEFAULT)
2100 tpg->real_quantization =
2102 tpg->color_enc != TGP_COLOR_ENC_YCBCR,
2103 tpg->colorspace, tpg->real_ycbcr_enc);
2105 tpg_precalculate_colors(tpg);
2107 if (tpg->recalc_square_border) {
2108 tpg->recalc_square_border = false;
2109 tpg_calculate_square_border(tpg);
2111 if (tpg->recalc_lines) {
2112 tpg->recalc_lines = false;
2113 tpg_precalculate_line(tpg);
2117 void tpg_calc_text_basep(struct tpg_data *tpg,
2120 unsigned stride = tpg->bytesperline[p];
2121 unsigned h = tpg->buf_height;
2123 tpg_recalc(tpg);
2127 h /= tpg->vdownsampling[p];
2128 if (tpg->field == V4L2_FIELD_SEQ_TB)
2130 else if (tpg->field == V4L2_FIELD_SEQ_BT)
2132 if (p == 0 && tpg->interleaved)
2133 tpg_calc_text_basep(tpg, basep, 1, vbuf);
2136 static int tpg_pattern_avg(const struct tpg_data *tpg,
2139 unsigned pat_lines = tpg_get_pat_lines(tpg);
2165 void tpg_log_status(struct tpg_data *tpg)
2167 pr_info("tpg source WxH: %ux%u (%s)\n",
2168 tpg->src_width, tpg->src_height,
2169 tpg_color_enc_str(tpg->color_enc));
2170 pr_info("tpg field: %u\n", tpg->field);
2171 pr_info("tpg crop: %ux%u@%dx%d\n", tpg->crop.width, tpg->crop.height,
2172 tpg->crop.left, tpg->crop.top);
2173 pr_info("tpg compose: %ux%u@%dx%d\n", tpg->compose.width, tpg->compose.height,
2174 tpg->compose.left, tpg->compose.top);
2175 pr_info("tpg colorspace: %d\n", tpg->colorspace);
2176 pr_info("tpg transfer function: %d/%d\n", tpg->xfer_func, tpg->real_xfer_func);
2177 if (tpg->color_enc == TGP_COLOR_ENC_HSV)
2178 pr_info("tpg HSV encoding: %d/%d\n",
2179 tpg->hsv_enc, tpg->real_hsv_enc);
2180 else if (tpg->color_enc == TGP_COLOR_ENC_YCBCR)
2181 pr_info("tpg Y'CbCr encoding: %d/%d\n",
2182 tpg->ycbcr_enc, tpg->real_ycbcr_enc);
2183 pr_info("tpg quantization: %d/%d\n", tpg->quantization, tpg->real_quantization);
2184 pr_info("tpg RGB range: %d/%d\n", tpg->rgb_range, tpg->real_rgb_range);
2216 static void tpg_fill_params_pattern(const struct tpg_data *tpg, unsigned p,
2220 tpg_hscale_div(tpg, p, tpg->mv_hor_count % tpg->src_width);
2222 tpg_hscale_div(tpg, p, (tpg->mv_hor_count + tpg->mv_hor_step) %
2223 tpg->src_width);
2224 params->mv_vert_old = tpg->mv_vert_count % tpg->src_height;
2226 (tpg->mv_vert_count + tpg->mv_vert_step) % tpg->src_height;
2229 static void tpg_fill_params_extras(const struct tpg_data *tpg,
2236 params->wss_width = tpg->crop.left < tpg->src_width / 2 ?
2237 tpg->src_width / 2 - tpg->crop.left : 0;
2238 if (params->wss_width > tpg->crop.width)
2239 params->wss_width = tpg->crop.width;
2240 params->wss_width = tpg_hscale_div(tpg, p, params->wss_width);
2242 params->twopixsize * prandom_u32_max(tpg->src_width / 2);
2244 if (tpg->crop.left < tpg->border.left) {
2245 left_pillar_width = tpg->border.left - tpg->crop.left;
2246 if (left_pillar_width > tpg->crop.width)
2247 left_pillar_width = tpg->crop.width;
2248 left_pillar_width = tpg_hscale_div(tpg, p, left_pillar_width);
2252 if (tpg->crop.left + tpg->crop.width >
2253 tpg->border.left + tpg->border.width) {
2255 tpg->border.left + tpg->border.width - tpg->crop.left;
2257 tpg_hscale_div(tpg, p, right_pillar_start);
2263 params->sav_eav_f = tpg->field ==
2267 static void tpg_fill_plane_extras(const struct tpg_data *tpg,
2274 const struct v4l2_rect *sq = &tpg->square;
2275 const struct v4l2_rect *b = &tpg->border;
2276 const struct v4l2_rect *c = &tpg->crop;
2284 u8 *wss = tpg->random_line[p] + params->wss_random_offset;
2289 if (tpg->show_border && frame_line >= b->top &&
2297 memcpy(vbuf + left, tpg->contrast_line[p],
2303 tpg->contrast_line[p], twopixsize);
2307 tpg->contrast_line[p], twopixsize);
2310 if (tpg->qual != TPG_QUAL_NOISE && frame_line >= b->top &&
2312 memcpy(vbuf, tpg->black_line[p], params->left_pillar_width);
2313 memcpy(vbuf + params->right_pillar_start, tpg->black_line[p],
2316 if (tpg->show_square && frame_line >= sq->top &&
2330 left = tpg_hscale_div(tpg, p, left);
2331 width = tpg_hscale_div(tpg, p, width);
2332 memcpy(vbuf + left, tpg->contrast_line[p], width);
2334 if (tpg->insert_sav) {
2335 unsigned offset = tpg_hdiv(tpg, p, tpg->compose.width / 3);
2349 if (tpg->insert_eav) {
2350 unsigned offset = tpg_hdiv(tpg, p, tpg->compose.width * 2 / 3);
2366 static void tpg_fill_plane_pattern(const struct tpg_data *tpg,
2378 unsigned line_offset = tpg_hscale_div(tpg, p, tpg->crop.left);
2391 if (params->hmax == tpg->compose.height)
2393 if (!tpg->perc_fill_blank)
2398 if (tpg->vflip) {
2399 frame_line = tpg->src_height - frame_line - 1;
2400 frame_line_next = tpg->src_height - frame_line_next - 1;
2404 linestart_older = tpg->contrast_line[p];
2405 linestart_newer = tpg->contrast_line[p];
2406 } else if (tpg->qual != TPG_QUAL_NOISE &&
2407 (frame_line < tpg->border.top ||
2408 frame_line >= tpg->border.top + tpg->border.height)) {
2409 linestart_older = tpg->black_line[p];
2410 linestart_newer = tpg->black_line[p];
2411 } else if (tpg->pattern == TPG_PAT_NOISE || tpg->qual == TPG_QUAL_NOISE) {
2412 linestart_older = tpg->random_line[p] +
2413 twopixsize * prandom_u32_max(tpg->src_width / 2);
2414 linestart_newer = tpg->random_line[p] +
2415 twopixsize * prandom_u32_max(tpg->src_width / 2);
2418 (frame_line + mv_vert_old) % tpg->src_height;
2420 (frame_line + mv_vert_new) % tpg->src_height;
2424 pat_line_old = tpg_get_pat_line(tpg, frame_line_old);
2425 pat_line_new = tpg_get_pat_line(tpg, frame_line_new);
2426 linestart_older = tpg->lines[pat_line_old][p] + mv_hor_old;
2427 linestart_newer = tpg->lines[pat_line_new][p] + mv_hor_new;
2429 if (tpg->vdownsampling[p] > 1 && frame_line != frame_line_next) {
2436 pat_line_next_old = tpg_get_pat_line(tpg,
2437 (frame_line_next + mv_vert_old) % tpg->src_height);
2438 pat_line_next_new = tpg_get_pat_line(tpg,
2439 (frame_line_next + mv_vert_new) % tpg->src_height);
2441 switch (tpg->field) {
2445 avg_pat = tpg_pattern_avg(tpg, pat_line_old, pat_line_new);
2448 linestart_older = tpg->downsampled_lines[avg_pat][p] + mv_hor_old;
2456 avg_pat = tpg_pattern_avg(tpg, pat_line_old, pat_line_next_old);
2458 linestart_older = tpg->downsampled_lines[avg_pat][p] +
2460 avg_pat = tpg_pattern_avg(tpg, pat_line_new, pat_line_next_new);
2462 linestart_newer = tpg->downsampled_lines[avg_pat][p] +
2470 if (tpg->field_alternate) {
2480 switch (tpg->field) {
2509 void tpg_fill_plane_buffer(struct tpg_data *tpg, v4l2_std_id std,
2513 unsigned factor = V4L2_FIELD_HAS_T_OR_B(tpg->field) ? 2 : 1;
2516 unsigned int_part = (tpg->crop.height / factor) / tpg->compose.height;
2517 unsigned fract_part = (tpg->crop.height / factor) % tpg->compose.height;
2522 tpg_recalc(tpg);
2526 params.twopixsize = tpg->twopixelsize[p];
2527 params.img_width = tpg_hdiv(tpg, p, tpg->compose.width);
2528 params.stride = tpg->bytesperline[p];
2529 params.hmax = (tpg->compose.height * tpg->perc_fill) / 100;
2531 tpg_fill_params_pattern(tpg, p, &params);
2532 tpg_fill_params_extras(tpg, p, &params);
2534 vbuf += tpg_hdiv(tpg, p, tpg->compose.left);
2536 for (h = 0; h < tpg->compose.height; h++) {
2539 params.frame_line = tpg_calc_frameline(tpg, src_y, tpg->field);
2541 buf_line = tpg_calc_buffer_line(tpg, h, tpg->field);
2544 if (error >= tpg->compose.height) {
2545 error -= tpg->compose.height;
2553 if (tpg_g_interleaved(tpg))
2554 p = tpg_g_interleaved_plane(tpg, buf_line);
2556 if (tpg->vdownsampling[p] > 1) {
2565 if (tpg->field == V4L2_FIELD_SEQ_BT ||
2566 tpg->field == V4L2_FIELD_SEQ_TB) {
2572 if (error + fract_part >= tpg->compose.height)
2575 tpg_calc_frameline(tpg, next_src_y, tpg->field);
2580 tpg_calc_frameline(tpg, src_y, tpg->field);
2583 buf_line /= tpg->vdownsampling[p];
2585 tpg_fill_plane_pattern(tpg, &params, p, h,
2587 tpg_fill_plane_extras(tpg, &params, p, h,
2592 void tpg_fillbuffer(struct tpg_data *tpg, v4l2_std_id std, unsigned p, u8 *vbuf)
2597 if (tpg->buffers > 1) {
2598 tpg_fill_plane_buffer(tpg, std, p, vbuf);
2602 for (i = 0; i < tpg_g_planes(tpg); i++) {
2603 tpg_fill_plane_buffer(tpg, std, i, vbuf + offset);
2604 offset += tpg_calc_plane_size(tpg, i);