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

[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
...@@ -1693,57 +1693,21 @@ static void tpg_fill_plane_extras(const struct tpg_data *tpg, ...@@ -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 twopixsize = params->twopixsize;
unsigned mv_hor_old; unsigned img_width = params->img_width;
unsigned mv_hor_new; unsigned mv_hor_old = params->mv_hor_old;
unsigned mv_vert_old; unsigned mv_hor_new = params->mv_hor_new;
unsigned mv_vert_new; unsigned mv_vert_old = params->mv_vert_old;
int h; unsigned mv_vert_new = params->mv_vert_new;
unsigned twopixsize; unsigned frame_line = params->frame_line;
unsigned vdiv = tpg->vdownsampling[p]; unsigned frame_line_next = params->frame_line_next;
unsigned img_width; unsigned line_offset = tpg_hscale_div(tpg, p, tpg->crop.left);
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++) {
bool even; bool even;
bool fill_blank = false; bool fill_blank = false;
unsigned frame_line;
unsigned buf_line;
unsigned pat_line_old; unsigned pat_line_old;
unsigned pat_line_new; unsigned pat_line_new;
u8 *linestart_older; u8 *linestart_older;
...@@ -1751,48 +1715,20 @@ void tpg_fill_plane_buffer(struct tpg_data *tpg, v4l2_std_id std, unsigned p, u8 ...@@ -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_top;
u8 *linestart_bottom; 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); 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 (h >= params->hmax) {
if (params.hmax == tpg->compose.height) if (params->hmax == tpg->compose.height)
continue; return;
if (!tpg->perc_fill_blank) if (!tpg->perc_fill_blank)
continue; return;
fill_blank = true; fill_blank = true;
} }
if (tpg->vflip) if (tpg->vflip) {
frame_line = tpg->src_height - frame_line - 1; frame_line = tpg->src_height - frame_line - 1;
frame_line_next = tpg->src_height - frame_line_next - 1;
}
if (fill_blank) { if (fill_blank) {
linestart_older = tpg->contrast_line[p]; 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 ...@@ -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_older = tpg->lines[pat_line_old][p] + mv_hor_old;
linestart_newer = tpg->lines[pat_line_new][p] + mv_hor_new; linestart_newer = tpg->lines[pat_line_new][p] + mv_hor_new;
if (vdiv > 1) { if (tpg->vdownsampling[p] > 1 && frame_line != frame_line_next) {
unsigned frame_line_next;
int avg_pat; int avg_pat;
/* /*
* Now decide whether we need to use downsampled_lines[]. * Now decide whether we need to use downsampled_lines[].
* That's necessary if the two lines use different patterns. * 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, pat_line_next_old = tpg_get_pat_line(tpg,
(frame_line_next + mv_vert_old) % tpg->src_height); (frame_line_next + mv_vert_old) % tpg->src_height);
pat_line_next_new = tpg_get_pat_line(tpg, 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 ...@@ -1867,7 +1799,7 @@ void tpg_fill_plane_buffer(struct tpg_data *tpg, v4l2_std_id std, unsigned p, u8
} }
if (tpg->field_alternate) { if (tpg->field_alternate) {
linestart_top = linestart_bottom = linestart_older; linestart_top = linestart_bottom = linestart_older;
} else if (params.is_60hz) { } else if (params->is_60hz) {
linestart_top = linestart_newer; linestart_top = linestart_newer;
linestart_bottom = linestart_older; linestart_bottom = linestart_older;
} else { } else {
...@@ -1881,28 +1813,100 @@ void tpg_fill_plane_buffer(struct tpg_data *tpg, v4l2_std_id std, unsigned p, u8 ...@@ -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_TB:
case V4L2_FIELD_SEQ_BT: case V4L2_FIELD_SEQ_BT:
if (even) if (even)
memcpy(vbuf + buf_line * stride, linestart_top, img_width); memcpy(vbuf, linestart_top, img_width);
else else
memcpy(vbuf + buf_line * stride, linestart_bottom, img_width); memcpy(vbuf, linestart_bottom, img_width);
break; break;
case V4L2_FIELD_INTERLACED_BT: case V4L2_FIELD_INTERLACED_BT:
if (even) if (even)
memcpy(vbuf + buf_line * stride, linestart_bottom, img_width); memcpy(vbuf, linestart_bottom, img_width);
else else
memcpy(vbuf + buf_line * stride, linestart_top, img_width); memcpy(vbuf, linestart_top, img_width);
break; break;
case V4L2_FIELD_TOP: case V4L2_FIELD_TOP:
memcpy(vbuf + buf_line * stride, linestart_top, img_width); memcpy(vbuf, linestart_top, img_width);
break; break;
case V4L2_FIELD_BOTTOM: case V4L2_FIELD_BOTTOM:
memcpy(vbuf + buf_line * stride, linestart_bottom, img_width); memcpy(vbuf, linestart_bottom, img_width);
break; break;
case V4L2_FIELD_NONE: case V4L2_FIELD_NONE:
default: default:
memcpy(vbuf + buf_line * stride, linestart_older, img_width); memcpy(vbuf, linestart_older, img_width);
break; 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, tpg_fill_plane_extras(tpg, &params, p, h,
vbuf + buf_line * params.stride); vbuf + buf_line * params.stride);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment