[media] vivid-tpg: precalculate downsampled lines
authorHans Verkuil <hans.verkuil@cisco.com>
Sat, 7 Mar 2015 17:06:43 +0000 (14:06 -0300)
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>
Thu, 2 Apr 2015 23:39:07 +0000 (20:39 -0300)
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>
drivers/media/platform/vivid/vivid-tpg.c
drivers/media/platform/vivid/vivid-tpg.h

index fa50a1f8a6c11fdd42e39004290ca173dd8df52d..f99756dff3f29c6921b0a819a7c0ce69ee869dfa 100644 (file)
@@ -128,6 +128,11 @@ int tpg_alloc(struct tpg_data *tpg, unsigned max_w)
                        tpg->lines[pat][plane] = vzalloc(max_w * 2 * pixelsz);
                        if (!tpg->lines[pat][plane])
                                return -ENOMEM;
+                       if (plane == 0)
+                               continue;
+                       tpg->downsampled_lines[pat][plane] = vzalloc(max_w * 2 * pixelsz);
+                       if (!tpg->downsampled_lines[pat][plane])
+                               return -ENOMEM;
                }
        }
        for (plane = 0; plane < TPG_MAX_PLANES; plane++) {
@@ -155,6 +160,10 @@ void tpg_free(struct tpg_data *tpg)
                for (plane = 0; plane < TPG_MAX_PLANES; plane++) {
                        vfree(tpg->lines[pat][plane]);
                        tpg->lines[pat][plane] = NULL;
+                       if (plane == 0)
+                               continue;
+                       vfree(tpg->downsampled_lines[pat][plane]);
+                       tpg->downsampled_lines[pat][plane] = NULL;
                }
        for (plane = 0; plane < TPG_MAX_PLANES; plane++) {
                vfree(tpg->contrast_line[plane]);
@@ -1029,12 +1038,39 @@ static void tpg_precalculate_line(struct tpg_data *tpg)
                        gen_twopix(tpg, pix, tpg->hflip ? color1 : color2, 1);
                        for (p = 0; p < tpg->planes; p++) {
                                unsigned twopixsize = tpg->twopixelsize[p];
-                               u8 *pos = tpg->lines[pat][p] + x * twopixsize / 2;
+                               unsigned hdiv = tpg->hdownsampling[p];
+                               u8 *pos = tpg->lines[pat][p] +
+                                               (x / hdiv) * twopixsize / 2;
+
+                               memcpy(pos, pix[p], twopixsize / hdiv);
+                       }
+               }
+       }
+
+       if (tpg->vdownsampling[tpg->planes - 1] > 1) {
+               unsigned pat_lines = tpg_get_pat_lines(tpg);
+
+               for (pat = 0; pat < pat_lines; pat++) {
+                       unsigned next_pat = (pat + 1) % pat_lines;
+
+                       for (p = 1; p < tpg->planes; p++) {
+                               unsigned twopixsize = tpg->twopixelsize[p];
+                               unsigned hdiv = tpg->hdownsampling[p];
 
-                               memcpy(pos, pix[p], twopixsize);
+                               for (x = 0; x < tpg->scaled_width * 2; x += 2) {
+                                       unsigned offset = (x / hdiv) * twopixsize / 2;
+                                       u8 *pos1 = tpg->lines[pat][p] + offset;
+                                       u8 *pos2 = tpg->lines[next_pat][p] + offset;
+                                       u8 *dest = tpg->downsampled_lines[pat][p] + offset;
+                                       unsigned i;
+
+                                       for (i = 0; i < twopixsize / hdiv; i++, dest++, pos1++, pos2++)
+                                               *dest = ((u16)*pos1 + (u16)*pos2) / 2;
+                               }
                        }
                }
        }
+
        for (x = 0; x < tpg->scaled_width; x += 2) {
                u8 pix[TPG_MAX_PLANES][8];
 
index cec5bb4f36326aa9d7f64b97ddb6398fefd3bc06..5a53eb99b6de5969d5b1ff1870d2d08d7fee5ae8 100644 (file)
@@ -175,6 +175,7 @@ struct tpg_data {
        /* Used to store TPG_MAX_PAT_LINES lines, each with up to two planes */
        unsigned                        max_line_width;
        u8                              *lines[TPG_MAX_PAT_LINES][TPG_MAX_PLANES];
+       u8                              *downsampled_lines[TPG_MAX_PAT_LINES][TPG_MAX_PLANES];
        u8                              *random_line[TPG_MAX_PLANES];
        u8                              *contrast_line[TPG_MAX_PLANES];
        u8                              *black_line[TPG_MAX_PLANES];
This page took 0.099858 seconds and 5 git commands to generate.