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

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

[media] vivid-tpg: split off the pattern drawing code



The last part of the vivid-tpg refactoring: split off the pattern
drawing code into a function of its own. This greatly improves the
readability and maintainability of this code.

Signed-off-by: default avatarHans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@osg.samsung.com>
parent c6ff1c1b
Loading
Loading
Loading
Loading
+162 −158
Original line number Diff line number Diff line
@@ -1693,57 +1693,21 @@ static void tpg_fill_plane_extras(const struct tpg_data *tpg,
	}
}

void tpg_fill_plane_buffer(struct tpg_data *tpg, v4l2_std_id std, unsigned p, u8 *vbuf)
static void tpg_fill_plane_pattern(const struct tpg_data *tpg,
				   const struct tpg_draw_params *params,
				   unsigned p, unsigned h, u8 *vbuf)
{
	struct tpg_draw_params params;
	unsigned mv_hor_old;
	unsigned mv_hor_new;
	unsigned mv_vert_old;
	unsigned mv_vert_new;
	int h;
	unsigned twopixsize;
	unsigned vdiv = tpg->vdownsampling[p];
	unsigned img_width;
	unsigned line_offset;
	unsigned stride;
	unsigned factor = V4L2_FIELD_HAS_T_OR_B(tpg->field) ? 2 : 1;

	/* Coarse scaling with Bresenham */
	unsigned int_part = (tpg->crop.height / factor) / tpg->compose.height;
	unsigned fract_part = (tpg->crop.height / factor) % tpg->compose.height;
	unsigned src_y = 0;
	unsigned error = 0;

	tpg_recalc(tpg);

	params.is_tv = std;
	params.is_60hz = std & V4L2_STD_525_60;
	params.twopixsize = tpg->twopixelsize[p];
	params.img_width = tpg_hdiv(tpg, p, tpg->compose.width);
	params.stride = tpg->bytesperline[p];
	params.hmax = (tpg->compose.height * tpg->perc_fill) / 100;

	tpg_fill_params_pattern(tpg, p, &params);

	mv_hor_old = params.mv_hor_old;
	mv_hor_new = params.mv_hor_new;
	mv_vert_old = params.mv_vert_old;
	mv_vert_new = params.mv_vert_new;

	tpg_fill_params_extras(tpg, p, &params);

	twopixsize = params.twopixsize;
	img_width = params.img_width;
	stride = params.stride;

	vbuf += tpg_hdiv(tpg, p, tpg->compose.left);
	line_offset = tpg_hscale_div(tpg, p, tpg->crop.left);

	for (h = 0; h < tpg->compose.height; h++) {
	unsigned twopixsize = params->twopixsize;
	unsigned img_width = params->img_width;
	unsigned mv_hor_old = params->mv_hor_old;
	unsigned mv_hor_new = params->mv_hor_new;
	unsigned mv_vert_old = params->mv_vert_old;
	unsigned mv_vert_new = params->mv_vert_new;
	unsigned frame_line = params->frame_line;
	unsigned frame_line_next = params->frame_line_next;
	unsigned line_offset = tpg_hscale_div(tpg, p, tpg->crop.left);
	bool even;
	bool fill_blank = false;
		unsigned frame_line;
		unsigned buf_line;
	unsigned pat_line_old;
	unsigned pat_line_new;
	u8 *linestart_older;
@@ -1751,48 +1715,20 @@ void tpg_fill_plane_buffer(struct tpg_data *tpg, v4l2_std_id std, unsigned p, u8
	u8 *linestart_top;
	u8 *linestart_bottom;

		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;
		error += fract_part;
		if (error >= tpg->compose.height) {
			error -= tpg->compose.height;
			src_y++;
		}

		if (vdiv > 1) {
			/*
			 * When doing vertical downsampling the field setting
			 * matters: for SEQ_BT/TB we downsample each field
			 * separately (i.e. lines 0+2 are combined, as are
			 * lines 1+3), for the other field settings we combine
			 * odd and even lines. Doing that for SEQ_BT/TB would
			 * be really weird.
			 */
			if (tpg->field == V4L2_FIELD_SEQ_BT ||
			    tpg->field == V4L2_FIELD_SEQ_TB) {
				if ((h & 3) >= 2)
					continue;
			} else if (h & 1) {
				continue;
			}

			buf_line /= vdiv;
		}

		if (h >= params.hmax) {
			if (params.hmax == tpg->compose.height)
				continue;
	if (h >= params->hmax) {
		if (params->hmax == tpg->compose.height)
			return;
		if (!tpg->perc_fill_blank)
				continue;
			return;
		fill_blank = true;
	}

		if (tpg->vflip)
	if (tpg->vflip) {
		frame_line = tpg->src_height - frame_line - 1;
		frame_line_next = tpg->src_height - frame_line_next - 1;
	}

	if (fill_blank) {
		linestart_older = tpg->contrast_line[p];
@@ -1820,17 +1756,13 @@ void tpg_fill_plane_buffer(struct tpg_data *tpg, v4l2_std_id std, unsigned p, u8
		linestart_older = tpg->lines[pat_line_old][p] + mv_hor_old;
		linestart_newer = tpg->lines[pat_line_new][p] + mv_hor_new;

			if (vdiv > 1) {
				unsigned frame_line_next;
		if (tpg->vdownsampling[p] > 1 && frame_line != frame_line_next) {
			int avg_pat;

			/*
			 * Now decide whether we need to use downsampled_lines[].
			 * That's necessary if the two lines use different patterns.
			 */
				frame_line_next = tpg_calc_frameline(tpg, src_y, tpg->field);
				if (tpg->vflip)
					frame_line_next = tpg->src_height - frame_line_next - 1;
			pat_line_next_old = tpg_get_pat_line(tpg,
					(frame_line_next + mv_vert_old) % tpg->src_height);
			pat_line_next_new = tpg_get_pat_line(tpg,
@@ -1867,7 +1799,7 @@ void tpg_fill_plane_buffer(struct tpg_data *tpg, v4l2_std_id std, unsigned p, u8
	}
	if (tpg->field_alternate) {
		linestart_top = linestart_bottom = linestart_older;
		} else if (params.is_60hz) {
	} else if (params->is_60hz) {
		linestart_top = linestart_newer;
		linestart_bottom = linestart_older;
	} else {
@@ -1881,28 +1813,100 @@ void tpg_fill_plane_buffer(struct tpg_data *tpg, v4l2_std_id std, unsigned p, u8
	case V4L2_FIELD_SEQ_TB:
	case V4L2_FIELD_SEQ_BT:
		if (even)
				memcpy(vbuf + buf_line * stride, linestart_top, img_width);
			memcpy(vbuf, linestart_top, img_width);
		else
				memcpy(vbuf + buf_line * stride, linestart_bottom, img_width);
			memcpy(vbuf, linestart_bottom, img_width);
		break;
	case V4L2_FIELD_INTERLACED_BT:
		if (even)
				memcpy(vbuf + buf_line * stride, linestart_bottom, img_width);
			memcpy(vbuf, linestart_bottom, img_width);
		else
				memcpy(vbuf + buf_line * stride, linestart_top, img_width);
			memcpy(vbuf, linestart_top, img_width);
		break;
	case V4L2_FIELD_TOP:
			memcpy(vbuf + buf_line * stride, linestart_top, img_width);
		memcpy(vbuf, linestart_top, img_width);
		break;
	case V4L2_FIELD_BOTTOM:
			memcpy(vbuf + buf_line * stride, linestart_bottom, img_width);
		memcpy(vbuf, linestart_bottom, img_width);
		break;
	case V4L2_FIELD_NONE:
	default:
			memcpy(vbuf + buf_line * stride, linestart_older, img_width);
		memcpy(vbuf, linestart_older, img_width);
		break;
	}
}

void tpg_fill_plane_buffer(struct tpg_data *tpg, v4l2_std_id std,
			   unsigned p, u8 *vbuf)
{
	struct tpg_draw_params params;
	unsigned factor = V4L2_FIELD_HAS_T_OR_B(tpg->field) ? 2 : 1;

	/* Coarse scaling with Bresenham */
	unsigned int_part = (tpg->crop.height / factor) / tpg->compose.height;
	unsigned fract_part = (tpg->crop.height / factor) % tpg->compose.height;
	unsigned src_y = 0;
	unsigned error = 0;
	unsigned h;

	tpg_recalc(tpg);

	params.is_tv = std;
	params.is_60hz = std & V4L2_STD_525_60;
	params.twopixsize = tpg->twopixelsize[p];
	params.img_width = tpg_hdiv(tpg, p, tpg->compose.width);
	params.stride = tpg->bytesperline[p];
	params.hmax = (tpg->compose.height * tpg->perc_fill) / 100;

	tpg_fill_params_pattern(tpg, p, &params);
	tpg_fill_params_extras(tpg, p, &params);

	vbuf += tpg_hdiv(tpg, p, tpg->compose.left);

	for (h = 0; h < tpg->compose.height; h++) {
		unsigned buf_line;

		params.frame_line = tpg_calc_frameline(tpg, src_y, tpg->field);
		params.frame_line_next = params.frame_line;
		buf_line = tpg_calc_buffer_line(tpg, h, tpg->field);
		src_y += int_part;
		error += fract_part;
		if (error >= tpg->compose.height) {
			error -= tpg->compose.height;
			src_y++;
		}

		if (tpg->vdownsampling[p] > 1) {
			/*
			 * When doing vertical downsampling the field setting
			 * matters: for SEQ_BT/TB we downsample each field
			 * separately (i.e. lines 0+2 are combined, as are
			 * lines 1+3), for the other field settings we combine
			 * odd and even lines. Doing that for SEQ_BT/TB would
			 * be really weird.
			 */
			if (tpg->field == V4L2_FIELD_SEQ_BT ||
			    tpg->field == V4L2_FIELD_SEQ_TB) {
				unsigned next_src_y = src_y;

				if ((h & 3) >= 2)
					continue;
				next_src_y += int_part;
				if (error + fract_part >= tpg->compose.height)
					next_src_y++;
				params.frame_line_next =
					tpg_calc_frameline(tpg, next_src_y, tpg->field);
			} else {
				if (h & 1)
					continue;
				params.frame_line_next =
					tpg_calc_frameline(tpg, src_y, tpg->field);
			}

			buf_line /= tpg->vdownsampling[p];
		}
		tpg_fill_plane_pattern(tpg, &params, p, h,
				vbuf + buf_line * params.stride);
		tpg_fill_plane_extras(tpg, &params, p, h,
				vbuf + buf_line * params.stride);
	}