Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c6ff1c1b authored by Hans Verkuil's avatar Hans Verkuil Committed by Mauro Carvalho Chehab
Browse files

[media] vivid-tpg: move the 'extras' drawing to a separate function



This moves the drawing code for the extras (border, square, etc) to
a function of its own instead of having this in the main for loop.

Signed-off-by: default avatarHans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@osg.samsung.com>
parent 07386b9a
Loading
Loading
Loading
Loading
+104 −112
Original line number Diff line number Diff line
@@ -1594,6 +1594,105 @@ static void tpg_fill_params_extras(const struct tpg_data *tpg,
			(params->is_60hz ? V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM);
}

static void tpg_fill_plane_extras(const struct tpg_data *tpg,
				  const struct tpg_draw_params *params,
				  unsigned p, unsigned h, u8 *vbuf)
{
	unsigned twopixsize = params->twopixsize;
	unsigned img_width = params->img_width;
	unsigned frame_line = params->frame_line;
	const struct v4l2_rect *sq = &tpg->square;
	const struct v4l2_rect *b = &tpg->border;
	const struct v4l2_rect *c = &tpg->crop;

	if (params->is_tv && !params->is_60hz &&
	    frame_line == 0 && params->wss_width) {
		/*
		 * Replace the first half of the top line of a 50 Hz frame
		 * with random data to simulate a WSS signal.
		 */
		u8 *wss = tpg->random_line[p] + params->wss_random_offset;

		memcpy(vbuf, wss, params->wss_width);
	}

	if (tpg->show_border && frame_line >= b->top &&
	    frame_line < b->top + b->height) {
		unsigned bottom = b->top + b->height - 1;
		unsigned left = params->left_pillar_width;
		unsigned right = params->right_pillar_start;

		if (frame_line == b->top || frame_line == b->top + 1 ||
		    frame_line == bottom || frame_line == bottom - 1) {
			memcpy(vbuf + left, tpg->contrast_line[p],
					right - left);
		} else {
			if (b->left >= c->left &&
			    b->left < c->left + c->width)
				memcpy(vbuf + left,
					tpg->contrast_line[p], twopixsize);
			if (b->left + b->width > c->left &&
			    b->left + b->width <= c->left + c->width)
				memcpy(vbuf + right - twopixsize,
					tpg->contrast_line[p], twopixsize);
		}
	}
	if (tpg->qual != TPG_QUAL_NOISE && frame_line >= b->top &&
	    frame_line < b->top + b->height) {
		memcpy(vbuf, tpg->black_line[p], params->left_pillar_width);
		memcpy(vbuf + params->right_pillar_start, tpg->black_line[p],
		       img_width - params->right_pillar_start);
	}
	if (tpg->show_square && frame_line >= sq->top &&
	    frame_line < sq->top + sq->height &&
	    sq->left < c->left + c->width &&
	    sq->left + sq->width >= c->left) {
		unsigned left = sq->left;
		unsigned width = sq->width;

		if (c->left > left) {
			width -= c->left - left;
			left = c->left;
		}
		if (c->left + c->width < left + width)
			width -= left + width - c->left - c->width;
		left -= c->left;
		left = tpg_hscale_div(tpg, p, left);
		width = tpg_hscale_div(tpg, p, width);
		memcpy(vbuf + left, tpg->contrast_line[p], width);
	}
	if (tpg->insert_sav) {
		unsigned offset = tpg_hdiv(tpg, p, tpg->compose.width / 3);
		u8 *p = vbuf + offset;
		unsigned vact = 0, hact = 0;

		p[0] = 0xff;
		p[1] = 0;
		p[2] = 0;
		p[3] = 0x80 | (params->sav_eav_f << 6) |
			(vact << 5) | (hact << 4) |
			((hact ^ vact) << 3) |
			((hact ^ params->sav_eav_f) << 2) |
			((params->sav_eav_f ^ vact) << 1) |
			(hact ^ vact ^ params->sav_eav_f);
	}
	if (tpg->insert_eav) {
		unsigned offset = tpg_hdiv(tpg, p, tpg->compose.width * 2 / 3);
		u8 *p = vbuf + offset;
		unsigned vact = 0, hact = 1;

		p[0] = 0xff;
		p[1] = 0;
		p[2] = 0;
		p[3] = 0x80 | (params->sav_eav_f << 6) |
			(vact << 5) | (hact << 4) |
			((hact ^ vact) << 3) |
			((hact ^ params->sav_eav_f) << 2) |
			((params->sav_eav_f ^ vact) << 1) |
			(hact ^ vact ^ params->sav_eav_f);
	}
}

void tpg_fill_plane_buffer(struct tpg_data *tpg, v4l2_std_id std, unsigned p, u8 *vbuf)
{
	struct tpg_draw_params params;
@@ -1608,7 +1707,6 @@ void tpg_fill_plane_buffer(struct tpg_data *tpg, v4l2_std_id std, unsigned p, u8
	unsigned line_offset;
	unsigned stride;
	unsigned factor = V4L2_FIELD_HAS_T_OR_B(tpg->field) ? 2 : 1;
	u8 *orig_vbuf = vbuf;

	/* Coarse scaling with Bresenham */
	unsigned int_part = (tpg->crop.height / factor) / tpg->compose.height;
@@ -1653,7 +1751,9 @@ void tpg_fill_plane_buffer(struct tpg_data *tpg, v4l2_std_id std, unsigned p, u8
		u8 *linestart_top;
		u8 *linestart_bottom;

		frame_line = tpg_calc_frameline(tpg, src_y, tpg->field);
		params.frame_line = tpg_calc_frameline(tpg, src_y, tpg->field);
		params.frame_line_next = params.frame_line;
		frame_line = params.frame_line;
		even = !(frame_line & 1);
		buf_line = tpg_calc_buffer_line(tpg, h, tpg->field);
		src_y += int_part;
@@ -1802,117 +1902,9 @@ void tpg_fill_plane_buffer(struct tpg_data *tpg, v4l2_std_id std, unsigned p, u8
			memcpy(vbuf + buf_line * stride, linestart_older, img_width);
			break;
		}
	}

	vbuf = orig_vbuf;
	vbuf += tpg_hdiv(tpg, p, tpg->compose.left);
	src_y = 0;
	error = 0;
	for (h = 0; h < tpg->compose.height; h++) {
		unsigned frame_line = tpg_calc_frameline(tpg, src_y, tpg->field);
		unsigned buf_line = tpg_calc_buffer_line(tpg, h, tpg->field);
		const struct v4l2_rect *sq = &tpg->square;
		const struct v4l2_rect *b = &tpg->border;
		const struct v4l2_rect *c = &tpg->crop;

		src_y += int_part;
		error += fract_part;
		if (error >= tpg->compose.height) {
			error -= tpg->compose.height;
			src_y++;
		}

		if (vdiv > 1) {
			if (h & 1)
				continue;
			buf_line /= vdiv;
		}

		if (params.is_tv && !params.is_60hz && frame_line == 0 && params.wss_width) {
			/*
			 * Replace the first half of the top line of a 50 Hz frame
			 * with random data to simulate a WSS signal.
			 */
			u8 *wss = tpg->random_line[p] + params.wss_random_offset;

			memcpy(vbuf + buf_line * stride, wss, params.wss_width);
		}

		if (tpg->show_border && frame_line >= b->top &&
		    frame_line < b->top + b->height) {
			unsigned bottom = b->top + b->height - 1;
			unsigned left = params.left_pillar_width;
			unsigned right = params.right_pillar_start;

			if (frame_line == b->top || frame_line == b->top + 1 ||
			    frame_line == bottom || frame_line == bottom - 1) {
				memcpy(vbuf + buf_line * stride + left, tpg->contrast_line[p],
						right - left);
			} else {
				if (b->left >= c->left &&
				    b->left < c->left + c->width)
					memcpy(vbuf + buf_line * stride + left,
						tpg->contrast_line[p], twopixsize);
				if (b->left + b->width > c->left &&
				    b->left + b->width <= c->left + c->width)
					memcpy(vbuf + buf_line * stride + right - twopixsize,
						tpg->contrast_line[p], twopixsize);
			}
		}
		if (tpg->qual != TPG_QUAL_NOISE && frame_line >= b->top &&
		    frame_line < b->top + b->height) {
			memcpy(vbuf + buf_line * stride, tpg->black_line[p], params.left_pillar_width);
			memcpy(vbuf + buf_line * stride + params.right_pillar_start, tpg->black_line[p],
			       img_width - params.right_pillar_start);
		}
		if (tpg->show_square && frame_line >= sq->top &&
		    frame_line < sq->top + sq->height &&
		    sq->left < c->left + c->width &&
		    sq->left + sq->width >= c->left) {
			unsigned left = sq->left;
			unsigned width = sq->width;

			if (c->left > left) {
				width -= c->left - left;
				left = c->left;
			}
			if (c->left + c->width < left + width)
				width -= left + width - c->left - c->width;
			left -= c->left;
			left = tpg_hscale_div(tpg, p, left);
			width = tpg_hscale_div(tpg, p, width);
			memcpy(vbuf + buf_line * stride + left, tpg->contrast_line[p], width);
		}
		if (tpg->insert_sav) {
			unsigned offset = tpg_hdiv(tpg, p, tpg->compose.width / 3);
			u8 *p = vbuf + buf_line * stride + offset;
			unsigned vact = 0, hact = 0;

			p[0] = 0xff;
			p[1] = 0;
			p[2] = 0;
			p[3] = 0x80 | (params.sav_eav_f << 6) |
				(vact << 5) | (hact << 4) |
				((hact ^ vact) << 3) |
				((hact ^ params.sav_eav_f) << 2) |
				((params.sav_eav_f ^ vact) << 1) |
				(hact ^ vact ^ params.sav_eav_f);
		}
		if (tpg->insert_eav) {
			unsigned offset = tpg_hdiv(tpg, p, tpg->compose.width * 2 / 3);
			u8 *p = vbuf + buf_line * stride + offset;
			unsigned vact = 0, hact = 1;

			p[0] = 0xff;
			p[1] = 0;
			p[2] = 0;
			p[3] = 0x80 | (params.sav_eav_f << 6) |
				(vact << 5) | (hact << 4) |
				((hact ^ vact) << 3) |
				((hact ^ params.sav_eav_f) << 2) |
				((params.sav_eav_f ^ vact) << 1) |
				(hact ^ vact ^ params.sav_eav_f);
		}
		tpg_fill_plane_extras(tpg, &params, p, h,
				vbuf + buf_line * params.stride);
	}
}