aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/platform/vivid
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2015-03-07 12:06:43 -0500
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>2015-04-02 19:39:07 -0400
commit5d7c539e194af598a8f8d8f616ce97581f3d079a (patch)
treeeb5a1eef4ff5adf1f98e48278763812de3e1af25 /drivers/media/platform/vivid
parentba01f673e031ade4f60583ab1ac4f06dd260a972 (diff)
[media] vivid-tpg: precalculate downsampled lines
When dealing with vertical downsampling two successive lines have to be averaged. In the case of the test pattern generator that only happens if the two lines are using different patterns. So precalculate the average between two pattern lines: one of pattern P and one of pattern P + 1. That way there is no need to do any on-the-fly downsampling: it's all done in the precalculate phase. This patch also implements horizontal downsampling in the precalculate phase. The only thing that needs to be done is to half the width since the actual downsampling happens when two pixels at a time are generated. Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
Diffstat (limited to 'drivers/media/platform/vivid')
-rw-r--r--drivers/media/platform/vivid/vivid-tpg.c40
-rw-r--r--drivers/media/platform/vivid/vivid-tpg.h1
2 files changed, 39 insertions, 2 deletions
diff --git a/drivers/media/platform/vivid/vivid-tpg.c b/drivers/media/platform/vivid/vivid-tpg.c
index fa50a1f8a6c1..f99756dff3f2 100644
--- a/drivers/media/platform/vivid/vivid-tpg.c
+++ b/drivers/media/platform/vivid/vivid-tpg.c
@@ -128,6 +128,11 @@ int tpg_alloc(struct tpg_data *tpg, unsigned max_w)
128 tpg->lines[pat][plane] = vzalloc(max_w * 2 * pixelsz); 128 tpg->lines[pat][plane] = vzalloc(max_w * 2 * pixelsz);
129 if (!tpg->lines[pat][plane]) 129 if (!tpg->lines[pat][plane])
130 return -ENOMEM; 130 return -ENOMEM;
131 if (plane == 0)
132 continue;
133 tpg->downsampled_lines[pat][plane] = vzalloc(max_w * 2 * pixelsz);
134 if (!tpg->downsampled_lines[pat][plane])
135 return -ENOMEM;
131 } 136 }
132 } 137 }
133 for (plane = 0; plane < TPG_MAX_PLANES; plane++) { 138 for (plane = 0; plane < TPG_MAX_PLANES; plane++) {
@@ -155,6 +160,10 @@ void tpg_free(struct tpg_data *tpg)
155 for (plane = 0; plane < TPG_MAX_PLANES; plane++) { 160 for (plane = 0; plane < TPG_MAX_PLANES; plane++) {
156 vfree(tpg->lines[pat][plane]); 161 vfree(tpg->lines[pat][plane]);
157 tpg->lines[pat][plane] = NULL; 162 tpg->lines[pat][plane] = NULL;
163 if (plane == 0)
164 continue;
165 vfree(tpg->downsampled_lines[pat][plane]);
166 tpg->downsampled_lines[pat][plane] = NULL;
158 } 167 }
159 for (plane = 0; plane < TPG_MAX_PLANES; plane++) { 168 for (plane = 0; plane < TPG_MAX_PLANES; plane++) {
160 vfree(tpg->contrast_line[plane]); 169 vfree(tpg->contrast_line[plane]);
@@ -1029,12 +1038,39 @@ static void tpg_precalculate_line(struct tpg_data *tpg)
1029 gen_twopix(tpg, pix, tpg->hflip ? color1 : color2, 1); 1038 gen_twopix(tpg, pix, tpg->hflip ? color1 : color2, 1);
1030 for (p = 0; p < tpg->planes; p++) { 1039 for (p = 0; p < tpg->planes; p++) {
1031 unsigned twopixsize = tpg->twopixelsize[p]; 1040 unsigned twopixsize = tpg->twopixelsize[p];
1032 u8 *pos = tpg->lines[pat][p] + x * twopixsize / 2; 1041 unsigned hdiv = tpg->hdownsampling[p];
1042 u8 *pos = tpg->lines[pat][p] +
1043 (x / hdiv) * twopixsize / 2;
1044
1045 memcpy(pos, pix[p], twopixsize / hdiv);
1046 }
1047 }
1048 }
1049
1050 if (tpg->vdownsampling[tpg->planes - 1] > 1) {
1051 unsigned pat_lines = tpg_get_pat_lines(tpg);
1052
1053 for (pat = 0; pat < pat_lines; pat++) {
1054 unsigned next_pat = (pat + 1) % pat_lines;
1055
1056 for (p = 1; p < tpg->planes; p++) {
1057 unsigned twopixsize = tpg->twopixelsize[p];
1058 unsigned hdiv = tpg->hdownsampling[p];
1033 1059
1034 memcpy(pos, pix[p], twopixsize); 1060 for (x = 0; x < tpg->scaled_width * 2; x += 2) {
1061 unsigned offset = (x / hdiv) * twopixsize / 2;
1062 u8 *pos1 = tpg->lines[pat][p] + offset;
1063 u8 *pos2 = tpg->lines[next_pat][p] + offset;
1064 u8 *dest = tpg->downsampled_lines[pat][p] + offset;
1065 unsigned i;
1066
1067 for (i = 0; i < twopixsize / hdiv; i++, dest++, pos1++, pos2++)
1068 *dest = ((u16)*pos1 + (u16)*pos2) / 2;
1069 }
1035 } 1070 }
1036 } 1071 }
1037 } 1072 }
1073
1038 for (x = 0; x < tpg->scaled_width; x += 2) { 1074 for (x = 0; x < tpg->scaled_width; x += 2) {
1039 u8 pix[TPG_MAX_PLANES][8]; 1075 u8 pix[TPG_MAX_PLANES][8];
1040 1076
diff --git a/drivers/media/platform/vivid/vivid-tpg.h b/drivers/media/platform/vivid/vivid-tpg.h
index cec5bb4f3632..5a53eb99b6de 100644
--- a/drivers/media/platform/vivid/vivid-tpg.h
+++ b/drivers/media/platform/vivid/vivid-tpg.h
@@ -175,6 +175,7 @@ struct tpg_data {
175 /* Used to store TPG_MAX_PAT_LINES lines, each with up to two planes */ 175 /* Used to store TPG_MAX_PAT_LINES lines, each with up to two planes */
176 unsigned max_line_width; 176 unsigned max_line_width;
177 u8 *lines[TPG_MAX_PAT_LINES][TPG_MAX_PLANES]; 177 u8 *lines[TPG_MAX_PAT_LINES][TPG_MAX_PLANES];
178 u8 *downsampled_lines[TPG_MAX_PAT_LINES][TPG_MAX_PLANES];
178 u8 *random_line[TPG_MAX_PLANES]; 179 u8 *random_line[TPG_MAX_PLANES];
179 u8 *contrast_line[TPG_MAX_PLANES]; 180 u8 *contrast_line[TPG_MAX_PLANES];
180 u8 *black_line[TPG_MAX_PLANES]; 181 u8 *black_line[TPG_MAX_PLANES];