Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  * v4l2-tpg.h - Test Pattern Generator
0004  *
0005  * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
0006  */
0007 
0008 #ifndef _V4L2_TPG_H_
0009 #define _V4L2_TPG_H_
0010 
0011 #include <linux/types.h>
0012 #include <linux/errno.h>
0013 #include <linux/random.h>
0014 #include <linux/slab.h>
0015 #include <linux/vmalloc.h>
0016 #include <linux/videodev2.h>
0017 
0018 struct tpg_rbg_color8 {
0019     unsigned char r, g, b;
0020 };
0021 
0022 struct tpg_rbg_color16 {
0023     __u16 r, g, b;
0024 };
0025 
0026 enum tpg_color {
0027     TPG_COLOR_CSC_WHITE,
0028     TPG_COLOR_CSC_YELLOW,
0029     TPG_COLOR_CSC_CYAN,
0030     TPG_COLOR_CSC_GREEN,
0031     TPG_COLOR_CSC_MAGENTA,
0032     TPG_COLOR_CSC_RED,
0033     TPG_COLOR_CSC_BLUE,
0034     TPG_COLOR_CSC_BLACK,
0035     TPG_COLOR_75_YELLOW,
0036     TPG_COLOR_75_CYAN,
0037     TPG_COLOR_75_GREEN,
0038     TPG_COLOR_75_MAGENTA,
0039     TPG_COLOR_75_RED,
0040     TPG_COLOR_75_BLUE,
0041     TPG_COLOR_100_WHITE,
0042     TPG_COLOR_100_YELLOW,
0043     TPG_COLOR_100_CYAN,
0044     TPG_COLOR_100_GREEN,
0045     TPG_COLOR_100_MAGENTA,
0046     TPG_COLOR_100_RED,
0047     TPG_COLOR_100_BLUE,
0048     TPG_COLOR_100_BLACK,
0049     TPG_COLOR_TEXTFG,
0050     TPG_COLOR_TEXTBG,
0051     TPG_COLOR_RANDOM,
0052     TPG_COLOR_RAMP,
0053     TPG_COLOR_MAX = TPG_COLOR_RAMP + 256
0054 };
0055 
0056 extern const struct tpg_rbg_color8 tpg_colors[TPG_COLOR_MAX];
0057 extern const unsigned short tpg_rec709_to_linear[255 * 16 + 1];
0058 extern const unsigned short tpg_linear_to_rec709[255 * 16 + 1];
0059 extern const struct tpg_rbg_color16 tpg_csc_colors[V4L2_COLORSPACE_DCI_P3 + 1]
0060                       [V4L2_XFER_FUNC_SMPTE2084 + 1]
0061                       [TPG_COLOR_CSC_BLACK + 1];
0062 enum tpg_pattern {
0063     TPG_PAT_75_COLORBAR,
0064     TPG_PAT_100_COLORBAR,
0065     TPG_PAT_CSC_COLORBAR,
0066     TPG_PAT_100_HCOLORBAR,
0067     TPG_PAT_100_COLORSQUARES,
0068     TPG_PAT_BLACK,
0069     TPG_PAT_WHITE,
0070     TPG_PAT_RED,
0071     TPG_PAT_GREEN,
0072     TPG_PAT_BLUE,
0073     TPG_PAT_CHECKERS_16X16,
0074     TPG_PAT_CHECKERS_2X2,
0075     TPG_PAT_CHECKERS_1X1,
0076     TPG_PAT_COLOR_CHECKERS_2X2,
0077     TPG_PAT_COLOR_CHECKERS_1X1,
0078     TPG_PAT_ALTERNATING_HLINES,
0079     TPG_PAT_ALTERNATING_VLINES,
0080     TPG_PAT_CROSS_1_PIXEL,
0081     TPG_PAT_CROSS_2_PIXELS,
0082     TPG_PAT_CROSS_10_PIXELS,
0083     TPG_PAT_GRAY_RAMP,
0084 
0085     /* Must be the last pattern */
0086     TPG_PAT_NOISE,
0087 };
0088 
0089 extern const char * const tpg_pattern_strings[];
0090 
0091 enum tpg_quality {
0092     TPG_QUAL_COLOR,
0093     TPG_QUAL_GRAY,
0094     TPG_QUAL_NOISE
0095 };
0096 
0097 enum tpg_video_aspect {
0098     TPG_VIDEO_ASPECT_IMAGE,
0099     TPG_VIDEO_ASPECT_4X3,
0100     TPG_VIDEO_ASPECT_14X9_CENTRE,
0101     TPG_VIDEO_ASPECT_16X9_CENTRE,
0102     TPG_VIDEO_ASPECT_16X9_ANAMORPHIC,
0103 };
0104 
0105 enum tpg_pixel_aspect {
0106     TPG_PIXEL_ASPECT_SQUARE,
0107     TPG_PIXEL_ASPECT_NTSC,
0108     TPG_PIXEL_ASPECT_PAL,
0109 };
0110 
0111 enum tpg_move_mode {
0112     TPG_MOVE_NEG_FAST,
0113     TPG_MOVE_NEG,
0114     TPG_MOVE_NEG_SLOW,
0115     TPG_MOVE_NONE,
0116     TPG_MOVE_POS_SLOW,
0117     TPG_MOVE_POS,
0118     TPG_MOVE_POS_FAST,
0119 };
0120 
0121 enum tgp_color_enc {
0122     TGP_COLOR_ENC_RGB,
0123     TGP_COLOR_ENC_YCBCR,
0124     TGP_COLOR_ENC_HSV,
0125     TGP_COLOR_ENC_LUMA,
0126 };
0127 
0128 extern const char * const tpg_aspect_strings[];
0129 
0130 #define TPG_MAX_PLANES 3
0131 #define TPG_MAX_PAT_LINES 8
0132 
0133 struct tpg_data {
0134     /* Source frame size */
0135     unsigned            src_width, src_height;
0136     /* Buffer height */
0137     unsigned            buf_height;
0138     /* Scaled output frame size */
0139     unsigned            scaled_width;
0140     u32             field;
0141     bool                field_alternate;
0142     /* crop coordinates are frame-based */
0143     struct v4l2_rect        crop;
0144     /* compose coordinates are format-based */
0145     struct v4l2_rect        compose;
0146     /* border and square coordinates are frame-based */
0147     struct v4l2_rect        border;
0148     struct v4l2_rect        square;
0149 
0150     /* Color-related fields */
0151     enum tpg_quality        qual;
0152     unsigned            qual_offset;
0153     u8              alpha_component;
0154     bool                alpha_red_only;
0155     u8              brightness;
0156     u8              contrast;
0157     u8              saturation;
0158     s16             hue;
0159     u32             fourcc;
0160     enum tgp_color_enc      color_enc;
0161     u32             colorspace;
0162     u32             xfer_func;
0163     u32             ycbcr_enc;
0164     u32             hsv_enc;
0165     /*
0166      * Stores the actual transfer function, i.e. will never be
0167      * V4L2_XFER_FUNC_DEFAULT.
0168      */
0169     u32             real_xfer_func;
0170     /*
0171      * Stores the actual Y'CbCr encoding, i.e. will never be
0172      * V4L2_YCBCR_ENC_DEFAULT.
0173      */
0174     u32             real_hsv_enc;
0175     u32             real_ycbcr_enc;
0176     u32             quantization;
0177     /*
0178      * Stores the actual quantization, i.e. will never be
0179      * V4L2_QUANTIZATION_DEFAULT.
0180      */
0181     u32             real_quantization;
0182     enum tpg_video_aspect       vid_aspect;
0183     enum tpg_pixel_aspect       pix_aspect;
0184     unsigned            rgb_range;
0185     unsigned            real_rgb_range;
0186     unsigned            buffers;
0187     unsigned            planes;
0188     bool                interleaved;
0189     u8              vdownsampling[TPG_MAX_PLANES];
0190     u8              hdownsampling[TPG_MAX_PLANES];
0191     /*
0192      * horizontal positions must be ANDed with this value to enforce
0193      * correct boundaries for packed YUYV values.
0194      */
0195     unsigned            hmask[TPG_MAX_PLANES];
0196     /* Used to store the colors in native format, either RGB or YUV */
0197     u8              colors[TPG_COLOR_MAX][3];
0198     u8              textfg[TPG_MAX_PLANES][8], textbg[TPG_MAX_PLANES][8];
0199     /* size in bytes for two pixels in each plane */
0200     unsigned            twopixelsize[TPG_MAX_PLANES];
0201     unsigned            bytesperline[TPG_MAX_PLANES];
0202 
0203     /* Configuration */
0204     enum tpg_pattern        pattern;
0205     bool                hflip;
0206     bool                vflip;
0207     unsigned            perc_fill;
0208     bool                perc_fill_blank;
0209     bool                show_border;
0210     bool                show_square;
0211     bool                insert_sav;
0212     bool                insert_eav;
0213     bool                insert_hdmi_video_guard_band;
0214 
0215     /* Test pattern movement */
0216     enum tpg_move_mode      mv_hor_mode;
0217     int             mv_hor_count;
0218     int             mv_hor_step;
0219     enum tpg_move_mode      mv_vert_mode;
0220     int             mv_vert_count;
0221     int             mv_vert_step;
0222 
0223     bool                recalc_colors;
0224     bool                recalc_lines;
0225     bool                recalc_square_border;
0226 
0227     /* Used to store TPG_MAX_PAT_LINES lines, each with up to two planes */
0228     unsigned            max_line_width;
0229     u8              *lines[TPG_MAX_PAT_LINES][TPG_MAX_PLANES];
0230     u8              *downsampled_lines[TPG_MAX_PAT_LINES][TPG_MAX_PLANES];
0231     u8              *random_line[TPG_MAX_PLANES];
0232     u8              *contrast_line[TPG_MAX_PLANES];
0233     u8              *black_line[TPG_MAX_PLANES];
0234 };
0235 
0236 void tpg_init(struct tpg_data *tpg, unsigned w, unsigned h);
0237 int tpg_alloc(struct tpg_data *tpg, unsigned max_w);
0238 void tpg_free(struct tpg_data *tpg);
0239 void tpg_reset_source(struct tpg_data *tpg, unsigned width, unsigned height,
0240                u32 field);
0241 void tpg_log_status(struct tpg_data *tpg);
0242 
0243 void tpg_set_font(const u8 *f);
0244 void tpg_gen_text(const struct tpg_data *tpg,
0245         u8 *basep[TPG_MAX_PLANES][2], int y, int x, const char *text);
0246 void tpg_calc_text_basep(struct tpg_data *tpg,
0247         u8 *basep[TPG_MAX_PLANES][2], unsigned p, u8 *vbuf);
0248 unsigned tpg_g_interleaved_plane(const struct tpg_data *tpg, unsigned buf_line);
0249 void tpg_fill_plane_buffer(struct tpg_data *tpg, v4l2_std_id std,
0250                unsigned p, u8 *vbuf);
0251 void tpg_fillbuffer(struct tpg_data *tpg, v4l2_std_id std,
0252             unsigned p, u8 *vbuf);
0253 bool tpg_s_fourcc(struct tpg_data *tpg, u32 fourcc);
0254 void tpg_s_crop_compose(struct tpg_data *tpg, const struct v4l2_rect *crop,
0255         const struct v4l2_rect *compose);
0256 const char *tpg_g_color_order(const struct tpg_data *tpg);
0257 
0258 static inline void tpg_s_pattern(struct tpg_data *tpg, enum tpg_pattern pattern)
0259 {
0260     if (tpg->pattern == pattern)
0261         return;
0262     tpg->pattern = pattern;
0263     tpg->recalc_colors = true;
0264 }
0265 
0266 static inline void tpg_s_quality(struct tpg_data *tpg,
0267                     enum tpg_quality qual, unsigned qual_offset)
0268 {
0269     if (tpg->qual == qual && tpg->qual_offset == qual_offset)
0270         return;
0271     tpg->qual = qual;
0272     tpg->qual_offset = qual_offset;
0273     tpg->recalc_colors = true;
0274 }
0275 
0276 static inline enum tpg_quality tpg_g_quality(const struct tpg_data *tpg)
0277 {
0278     return tpg->qual;
0279 }
0280 
0281 static inline void tpg_s_alpha_component(struct tpg_data *tpg,
0282                         u8 alpha_component)
0283 {
0284     if (tpg->alpha_component == alpha_component)
0285         return;
0286     tpg->alpha_component = alpha_component;
0287     tpg->recalc_colors = true;
0288 }
0289 
0290 static inline void tpg_s_alpha_mode(struct tpg_data *tpg,
0291                         bool red_only)
0292 {
0293     if (tpg->alpha_red_only == red_only)
0294         return;
0295     tpg->alpha_red_only = red_only;
0296     tpg->recalc_colors = true;
0297 }
0298 
0299 static inline void tpg_s_brightness(struct tpg_data *tpg,
0300                     u8 brightness)
0301 {
0302     if (tpg->brightness == brightness)
0303         return;
0304     tpg->brightness = brightness;
0305     tpg->recalc_colors = true;
0306 }
0307 
0308 static inline void tpg_s_contrast(struct tpg_data *tpg,
0309                     u8 contrast)
0310 {
0311     if (tpg->contrast == contrast)
0312         return;
0313     tpg->contrast = contrast;
0314     tpg->recalc_colors = true;
0315 }
0316 
0317 static inline void tpg_s_saturation(struct tpg_data *tpg,
0318                     u8 saturation)
0319 {
0320     if (tpg->saturation == saturation)
0321         return;
0322     tpg->saturation = saturation;
0323     tpg->recalc_colors = true;
0324 }
0325 
0326 static inline void tpg_s_hue(struct tpg_data *tpg,
0327                     s16 hue)
0328 {
0329     hue = clamp_t(s16, hue, -128, 128);
0330     if (tpg->hue == hue)
0331         return;
0332     tpg->hue = hue;
0333     tpg->recalc_colors = true;
0334 }
0335 
0336 static inline void tpg_s_rgb_range(struct tpg_data *tpg,
0337                     unsigned rgb_range)
0338 {
0339     if (tpg->rgb_range == rgb_range)
0340         return;
0341     tpg->rgb_range = rgb_range;
0342     tpg->recalc_colors = true;
0343 }
0344 
0345 static inline void tpg_s_real_rgb_range(struct tpg_data *tpg,
0346                     unsigned rgb_range)
0347 {
0348     if (tpg->real_rgb_range == rgb_range)
0349         return;
0350     tpg->real_rgb_range = rgb_range;
0351     tpg->recalc_colors = true;
0352 }
0353 
0354 static inline void tpg_s_colorspace(struct tpg_data *tpg, u32 colorspace)
0355 {
0356     if (tpg->colorspace == colorspace)
0357         return;
0358     tpg->colorspace = colorspace;
0359     tpg->recalc_colors = true;
0360 }
0361 
0362 static inline u32 tpg_g_colorspace(const struct tpg_data *tpg)
0363 {
0364     return tpg->colorspace;
0365 }
0366 
0367 static inline void tpg_s_ycbcr_enc(struct tpg_data *tpg, u32 ycbcr_enc)
0368 {
0369     if (tpg->ycbcr_enc == ycbcr_enc)
0370         return;
0371     tpg->ycbcr_enc = ycbcr_enc;
0372     tpg->recalc_colors = true;
0373 }
0374 
0375 static inline u32 tpg_g_ycbcr_enc(const struct tpg_data *tpg)
0376 {
0377     return tpg->ycbcr_enc;
0378 }
0379 
0380 static inline void tpg_s_hsv_enc(struct tpg_data *tpg, u32 hsv_enc)
0381 {
0382     if (tpg->hsv_enc == hsv_enc)
0383         return;
0384     tpg->hsv_enc = hsv_enc;
0385     tpg->recalc_colors = true;
0386 }
0387 
0388 static inline u32 tpg_g_hsv_enc(const struct tpg_data *tpg)
0389 {
0390     return tpg->hsv_enc;
0391 }
0392 
0393 static inline void tpg_s_xfer_func(struct tpg_data *tpg, u32 xfer_func)
0394 {
0395     if (tpg->xfer_func == xfer_func)
0396         return;
0397     tpg->xfer_func = xfer_func;
0398     tpg->recalc_colors = true;
0399 }
0400 
0401 static inline u32 tpg_g_xfer_func(const struct tpg_data *tpg)
0402 {
0403     return tpg->xfer_func;
0404 }
0405 
0406 static inline void tpg_s_quantization(struct tpg_data *tpg, u32 quantization)
0407 {
0408     if (tpg->quantization == quantization)
0409         return;
0410     tpg->quantization = quantization;
0411     tpg->recalc_colors = true;
0412 }
0413 
0414 static inline u32 tpg_g_quantization(const struct tpg_data *tpg)
0415 {
0416     return tpg->quantization;
0417 }
0418 
0419 static inline unsigned tpg_g_buffers(const struct tpg_data *tpg)
0420 {
0421     return tpg->buffers;
0422 }
0423 
0424 static inline unsigned tpg_g_planes(const struct tpg_data *tpg)
0425 {
0426     return tpg->interleaved ? 1 : tpg->planes;
0427 }
0428 
0429 static inline bool tpg_g_interleaved(const struct tpg_data *tpg)
0430 {
0431     return tpg->interleaved;
0432 }
0433 
0434 static inline unsigned tpg_g_twopixelsize(const struct tpg_data *tpg, unsigned plane)
0435 {
0436     return tpg->twopixelsize[plane];
0437 }
0438 
0439 static inline unsigned tpg_hdiv(const struct tpg_data *tpg,
0440                   unsigned plane, unsigned x)
0441 {
0442     return ((x / tpg->hdownsampling[plane]) & tpg->hmask[plane]) *
0443         tpg->twopixelsize[plane] / 2;
0444 }
0445 
0446 static inline unsigned tpg_hscale(const struct tpg_data *tpg, unsigned x)
0447 {
0448     return (x * tpg->scaled_width) / tpg->src_width;
0449 }
0450 
0451 static inline unsigned tpg_hscale_div(const struct tpg_data *tpg,
0452                       unsigned plane, unsigned x)
0453 {
0454     return tpg_hdiv(tpg, plane, tpg_hscale(tpg, x));
0455 }
0456 
0457 static inline unsigned tpg_g_bytesperline(const struct tpg_data *tpg, unsigned plane)
0458 {
0459     return tpg->bytesperline[plane];
0460 }
0461 
0462 static inline void tpg_s_bytesperline(struct tpg_data *tpg, unsigned plane, unsigned bpl)
0463 {
0464     unsigned p;
0465 
0466     if (tpg->buffers > 1) {
0467         tpg->bytesperline[plane] = bpl;
0468         return;
0469     }
0470 
0471     for (p = 0; p < tpg_g_planes(tpg); p++) {
0472         unsigned plane_w = bpl * tpg->twopixelsize[p] / tpg->twopixelsize[0];
0473 
0474         tpg->bytesperline[p] = plane_w / tpg->hdownsampling[p];
0475     }
0476     if (tpg_g_interleaved(tpg))
0477         tpg->bytesperline[1] = tpg->bytesperline[0];
0478 }
0479 
0480 
0481 static inline unsigned tpg_g_line_width(const struct tpg_data *tpg, unsigned plane)
0482 {
0483     unsigned w = 0;
0484     unsigned p;
0485 
0486     if (tpg->buffers > 1)
0487         return tpg_g_bytesperline(tpg, plane);
0488     for (p = 0; p < tpg_g_planes(tpg); p++) {
0489         unsigned plane_w = tpg_g_bytesperline(tpg, p);
0490 
0491         w += plane_w / tpg->vdownsampling[p];
0492     }
0493     return w;
0494 }
0495 
0496 static inline unsigned tpg_calc_line_width(const struct tpg_data *tpg,
0497                        unsigned plane, unsigned bpl)
0498 {
0499     unsigned w = 0;
0500     unsigned p;
0501 
0502     if (tpg->buffers > 1)
0503         return bpl;
0504     for (p = 0; p < tpg_g_planes(tpg); p++) {
0505         unsigned plane_w = bpl * tpg->twopixelsize[p] / tpg->twopixelsize[0];
0506 
0507         plane_w /= tpg->hdownsampling[p];
0508         w += plane_w / tpg->vdownsampling[p];
0509     }
0510     return w;
0511 }
0512 
0513 static inline unsigned tpg_calc_plane_size(const struct tpg_data *tpg, unsigned plane)
0514 {
0515     if (plane >= tpg_g_planes(tpg))
0516         return 0;
0517 
0518     return tpg_g_bytesperline(tpg, plane) * tpg->buf_height /
0519            tpg->vdownsampling[plane];
0520 }
0521 
0522 static inline void tpg_s_buf_height(struct tpg_data *tpg, unsigned h)
0523 {
0524     tpg->buf_height = h;
0525 }
0526 
0527 static inline void tpg_s_field(struct tpg_data *tpg, unsigned field, bool alternate)
0528 {
0529     tpg->field = field;
0530     tpg->field_alternate = alternate;
0531 }
0532 
0533 static inline void tpg_s_perc_fill(struct tpg_data *tpg,
0534                       unsigned perc_fill)
0535 {
0536     tpg->perc_fill = perc_fill;
0537 }
0538 
0539 static inline unsigned tpg_g_perc_fill(const struct tpg_data *tpg)
0540 {
0541     return tpg->perc_fill;
0542 }
0543 
0544 static inline void tpg_s_perc_fill_blank(struct tpg_data *tpg,
0545                      bool perc_fill_blank)
0546 {
0547     tpg->perc_fill_blank = perc_fill_blank;
0548 }
0549 
0550 static inline void tpg_s_video_aspect(struct tpg_data *tpg,
0551                     enum tpg_video_aspect vid_aspect)
0552 {
0553     if (tpg->vid_aspect == vid_aspect)
0554         return;
0555     tpg->vid_aspect = vid_aspect;
0556     tpg->recalc_square_border = true;
0557 }
0558 
0559 static inline enum tpg_video_aspect tpg_g_video_aspect(const struct tpg_data *tpg)
0560 {
0561     return tpg->vid_aspect;
0562 }
0563 
0564 static inline void tpg_s_pixel_aspect(struct tpg_data *tpg,
0565                     enum tpg_pixel_aspect pix_aspect)
0566 {
0567     if (tpg->pix_aspect == pix_aspect)
0568         return;
0569     tpg->pix_aspect = pix_aspect;
0570     tpg->recalc_square_border = true;
0571 }
0572 
0573 static inline void tpg_s_show_border(struct tpg_data *tpg,
0574                     bool show_border)
0575 {
0576     tpg->show_border = show_border;
0577 }
0578 
0579 static inline void tpg_s_show_square(struct tpg_data *tpg,
0580                     bool show_square)
0581 {
0582     tpg->show_square = show_square;
0583 }
0584 
0585 static inline void tpg_s_insert_sav(struct tpg_data *tpg, bool insert_sav)
0586 {
0587     tpg->insert_sav = insert_sav;
0588 }
0589 
0590 static inline void tpg_s_insert_eav(struct tpg_data *tpg, bool insert_eav)
0591 {
0592     tpg->insert_eav = insert_eav;
0593 }
0594 
0595 /*
0596  * This inserts 4 pixels of the RGB color 0xab55ab at the left hand side of the
0597  * image. This is only done for 3 or 4 byte RGB pixel formats. This pixel value
0598  * equals the Video Guard Band value as defined by HDMI (see section 5.2.2.1
0599  * in the HDMI 1.3 Specification) that preceeds the first actual pixel. If the
0600  * HDMI receiver doesn't handle this correctly, then it might keep skipping
0601  * these Video Guard Band patterns and end up with a shorter video line. So this
0602  * is a nice pattern to test with.
0603  */
0604 static inline void tpg_s_insert_hdmi_video_guard_band(struct tpg_data *tpg,
0605                               bool insert_hdmi_video_guard_band)
0606 {
0607     tpg->insert_hdmi_video_guard_band = insert_hdmi_video_guard_band;
0608 }
0609 
0610 void tpg_update_mv_step(struct tpg_data *tpg);
0611 
0612 static inline void tpg_s_mv_hor_mode(struct tpg_data *tpg,
0613                 enum tpg_move_mode mv_hor_mode)
0614 {
0615     tpg->mv_hor_mode = mv_hor_mode;
0616     tpg_update_mv_step(tpg);
0617 }
0618 
0619 static inline void tpg_s_mv_vert_mode(struct tpg_data *tpg,
0620                 enum tpg_move_mode mv_vert_mode)
0621 {
0622     tpg->mv_vert_mode = mv_vert_mode;
0623     tpg_update_mv_step(tpg);
0624 }
0625 
0626 static inline void tpg_init_mv_count(struct tpg_data *tpg)
0627 {
0628     tpg->mv_hor_count = tpg->mv_vert_count = 0;
0629 }
0630 
0631 static inline void tpg_update_mv_count(struct tpg_data *tpg, bool frame_is_field)
0632 {
0633     tpg->mv_hor_count += tpg->mv_hor_step * (frame_is_field ? 1 : 2);
0634     tpg->mv_vert_count += tpg->mv_vert_step * (frame_is_field ? 1 : 2);
0635 }
0636 
0637 static inline void tpg_s_hflip(struct tpg_data *tpg, bool hflip)
0638 {
0639     if (tpg->hflip == hflip)
0640         return;
0641     tpg->hflip = hflip;
0642     tpg_update_mv_step(tpg);
0643     tpg->recalc_lines = true;
0644 }
0645 
0646 static inline bool tpg_g_hflip(const struct tpg_data *tpg)
0647 {
0648     return tpg->hflip;
0649 }
0650 
0651 static inline void tpg_s_vflip(struct tpg_data *tpg, bool vflip)
0652 {
0653     tpg->vflip = vflip;
0654 }
0655 
0656 static inline bool tpg_g_vflip(const struct tpg_data *tpg)
0657 {
0658     return tpg->vflip;
0659 }
0660 
0661 static inline bool tpg_pattern_is_static(const struct tpg_data *tpg)
0662 {
0663     return tpg->pattern != TPG_PAT_NOISE &&
0664            tpg->mv_hor_mode == TPG_MOVE_NONE &&
0665            tpg->mv_vert_mode == TPG_MOVE_NONE;
0666 }
0667 
0668 #endif