vl: Apply luma key filter before CSC conversion
authorNayan Deshmukh <nayan26deshmukh@gmail.com>
Wed, 8 Jun 2016 09:22:48 +0000 (14:52 +0530)
committerChristian König <christian.koenig@amd.com>
Thu, 9 Jun 2016 12:23:07 +0000 (14:23 +0200)
    Apply the luma key filter to the YCbCr values during the CSC conversion
    in video buffer shader. The initial values of max and min luma are set
    to opposite values to disable the filter initially and will be set when
    enabling it.

    Add extra parmeters min and max luma for the luma key filter in
    vl_compositor_set_csc_matrix in va, xvmc. Setting them
    to opposite value 1.f and 0.f respectively won't effect the CSC
    conversion

    v2: -Squash 1,2 and 3 into one patch to avoid breaking build of
        other components. (Christian)
        -use ureg_swizzle. (Christian)
        -change name of the variables. (Christian)

    v3: -Squash all patches in one to avoid breaking of build. (Emil)
        -wrap functions properly. (Emil)
        -use 0.0f and 1.0f instead of 0.f and 1.f respectively. (Emil)

    v4: -Divide it in two patches one which introduces the functionality
 and assigs dummy values to the changed functions and second which
 implements the lumakey filter. (Christian)
-use ureg_scalar instead ureg_swizzle. (Christian)

Signed-off-by: Nayan Deshmukh <nayan26deshmukh@gmail.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
src/gallium/auxiliary/vl/vl_compositor.c
src/gallium/auxiliary/vl/vl_compositor.h
src/gallium/state_trackers/va/context.c
src/gallium/state_trackers/vdpau/mixer.c
src/gallium/state_trackers/vdpau/output.c
src/gallium/state_trackers/xvmc/attributes.c
src/gallium/state_trackers/xvmc/context.c

index acb2f4f4b976bcff4d27aed0e95d02d90343393f..1a383f29425ce6657f7f913b7f7fb0dc9cfbaf99 100644 (file)
@@ -132,8 +132,10 @@ create_frag_shader_video_buffer(struct vl_compositor *c)
    struct ureg_src tc;
    struct ureg_src csc[3];
    struct ureg_src sampler[3];
+   struct ureg_src lumakey;
    struct ureg_dst texel;
    struct ureg_dst fragment;
+   struct ureg_dst temp[2];
    unsigned i;
 
    shader = ureg_create(PIPE_SHADER_FRAGMENT);
@@ -145,6 +147,11 @@ create_frag_shader_video_buffer(struct vl_compositor *c)
       csc[i] = ureg_DECL_constant(shader, i);
       sampler[i] = ureg_DECL_sampler(shader, i);
    }
+
+   for (i = 0; i < 2; ++i)
+      temp[i] = ureg_DECL_temporary(shader);
+
+   lumakey = ureg_DECL_constant(shader, 3);
    texel = ureg_DECL_temporary(shader);
    fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0);
 
@@ -160,7 +167,17 @@ create_frag_shader_video_buffer(struct vl_compositor *c)
    for (i = 0; i < 3; ++i)
       ureg_DP4(shader, ureg_writemask(fragment, TGSI_WRITEMASK_X << i), csc[i], ureg_src(texel));
 
-   ureg_MOV(shader, ureg_writemask(fragment, TGSI_WRITEMASK_W), ureg_imm1f(shader, 1.0f));
+   ureg_MOV(shader, ureg_writemask(temp[0], TGSI_WRITEMASK_W),
+            ureg_scalar(ureg_src(texel), TGSI_SWIZZLE_Z));
+   ureg_SLE(shader, ureg_writemask(temp[1],TGSI_WRITEMASK_W),
+            ureg_src(temp[0]), ureg_scalar(lumakey, TGSI_SWIZZLE_X));
+   ureg_SGT(shader, ureg_writemask(temp[0],TGSI_WRITEMASK_W),
+            ureg_src(temp[0]), ureg_scalar(lumakey, TGSI_SWIZZLE_Y));
+   ureg_MAX(shader, ureg_writemask(fragment, TGSI_WRITEMASK_W),
+            ureg_src(temp[0]), ureg_src(temp[1]));
+
+   for (i = 0; i < 2; ++i)
+       ureg_release_temporary(shader, temp[i]);
 
    ureg_release_temporary(shader, texel);
    ureg_END(shader);
@@ -852,20 +869,23 @@ vl_compositor_cleanup(struct vl_compositor *c)
 }
 
 void
-vl_compositor_set_csc_matrix(struct vl_compositor_state *s, vl_csc_matrix const *matrix)
+vl_compositor_set_csc_matrix(struct vl_compositor_state *s,
+                             vl_csc_matrix const *matrix,
+                             float luma_min, float luma_max)
 {
    struct pipe_transfer *buf_transfer;
 
    assert(s);
 
-   memcpy
-   (
-      pipe_buffer_map(s->pipe, s->csc_matrix,
-                      PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD_RANGE,
-                      &buf_transfer),
-      matrix,
-      sizeof(vl_csc_matrix)
-   );
+   float *ptr = pipe_buffer_map(s->pipe, s->csc_matrix,
+                               PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD_RANGE,
+                               &buf_transfer);
+
+   memcpy(ptr, matrix, sizeof(vl_csc_matrix));
+
+   ptr += sizeof(vl_csc_matrix)/sizeof(float);
+   ptr[0] = luma_min;
+   ptr[1] = luma_max;
 
    pipe_buffer_unmap(s->pipe, buf_transfer);
 }
@@ -1142,13 +1162,13 @@ vl_compositor_init_state(struct vl_compositor_state *s, struct pipe_context *pip
       pipe->screen,
       PIPE_BIND_CONSTANT_BUFFER,
       PIPE_USAGE_DEFAULT,
-      sizeof(csc_matrix)
+      sizeof(csc_matrix) + 2*sizeof(float)
    );
 
    vl_compositor_clear_layers(s);
 
    vl_csc_get_matrix(VL_CSC_COLOR_STANDARD_IDENTITY, NULL, true, &csc_matrix);
-   vl_compositor_set_csc_matrix(s, (const vl_csc_matrix *)&csc_matrix);
+   vl_compositor_set_csc_matrix(s, (const vl_csc_matrix *)&csc_matrix, 1.0f, 0.0f);
 
    return true;
 }
index 934b634b39051a5a2f3c420cc9007d7acb7cac07..12976fc95a107bf786bc2fb2fd1b827b04d0d552 100644 (file)
@@ -138,7 +138,9 @@ vl_compositor_init_state(struct vl_compositor_state *state, struct pipe_context
  * set yuv -> rgba conversion matrix
  */
 void
-vl_compositor_set_csc_matrix(struct vl_compositor_state *settings, const vl_csc_matrix *matrix);
+vl_compositor_set_csc_matrix(struct vl_compositor_state *settings,
+                             const vl_csc_matrix *matrix,
+                             float luma_min, float luma_max);
 
 /**
  * reset dirty area, so it's cleared with the clear colour
index 51abd87cc4ee48f8e4e0a0592b7adeedb055be3a..402fbb23497e14dbf505caaf461ba52097a9e9af 100644 (file)
@@ -159,7 +159,7 @@ VA_DRIVER_INIT_FUNC(VADriverContextP ctx)
    vl_compositor_init_state(&drv->cstate, drv->pipe);
 
    vl_csc_get_matrix(VL_CSC_COLOR_STANDARD_BT_601, NULL, true, &drv->csc);
-   vl_compositor_set_csc_matrix(&drv->cstate, (const vl_csc_matrix *)&drv->csc);
+   vl_compositor_set_csc_matrix(&drv->cstate, (const vl_csc_matrix *)&drv->csc, 1.0f, 0.0f);
    pipe_mutex_init(drv->mutex);
 
    ctx->pDriverData = (void *)drv;
index dec79ff95e23f7353216cfdf5662fc44e37a2b3e..1070e96679f8a381a01e70f72715bc4004669cc3 100644 (file)
@@ -69,7 +69,7 @@ vlVdpVideoMixerCreate(VdpDevice device,
 
    vl_csc_get_matrix(VL_CSC_COLOR_STANDARD_BT_601, NULL, true, &vmixer->csc);
    if (!debug_get_bool_option("G3DVL_NO_CSC", FALSE))
-      vl_compositor_set_csc_matrix(&vmixer->cstate, (const vl_csc_matrix *)&vmixer->csc);
+      vl_compositor_set_csc_matrix(&vmixer->cstate, (const vl_csc_matrix *)&vmixer->csc, 1.0f, 0.0f);
 
    *mixer = vlAddDataHTAB(vmixer);
    if (*mixer == 0) {
@@ -671,7 +671,7 @@ vlVdpVideoMixerSetAttributeValues(VdpVideoMixer mixer,
          else
             memcpy(vmixer->csc, vdp_csc, sizeof(vl_csc_matrix));
          if (!debug_get_bool_option("G3DVL_NO_CSC", FALSE))
-            vl_compositor_set_csc_matrix(&vmixer->cstate, (const vl_csc_matrix *)&vmixer->csc);
+            vl_compositor_set_csc_matrix(&vmixer->cstate, (const vl_csc_matrix *)&vmixer->csc, 1.0f, 0.0f);
          break;
 
       case VDP_VIDEO_MIXER_ATTRIBUTE_NOISE_REDUCTION_LEVEL:
index 2192f71544e91e3ae18a67164f8e93a3abe32c51..8a064e849b65d99852344b6f0c340a460002433e 100644 (file)
@@ -492,9 +492,9 @@ vlVdpOutputSurfacePutBitsYCbCr(VdpOutputSurface surface,
    if (!csc_matrix) {
       vl_csc_matrix csc;
       vl_csc_get_matrix(VL_CSC_COLOR_STANDARD_BT_601, NULL, 1, &csc);
-      vl_compositor_set_csc_matrix(cstate, (const vl_csc_matrix*)&csc);
+      vl_compositor_set_csc_matrix(cstate, (const vl_csc_matrix*)&csc, 1.0f, 0.0f);
    } else {
-      vl_compositor_set_csc_matrix(cstate, csc_matrix);
+      vl_compositor_set_csc_matrix(cstate, csc_matrix, 1.0f, 0.0f);
    }
 
    vl_compositor_clear_layers(cstate);
index 2d8f00ba769153ec76258e6315208b12cd386ffd..375705669b02c03148c1d52fc078b23e382f3a46 100644 (file)
@@ -110,7 +110,7 @@ Status XvMCSetAttribute(Display *dpy, XvMCContext *context, Atom attribute, int
       context_priv->color_standard,
       &context_priv->procamp, true, &csc
    );
-   vl_compositor_set_csc_matrix(&context_priv->cstate, (const vl_csc_matrix *)&csc);
+   vl_compositor_set_csc_matrix(&context_priv->cstate, (const vl_csc_matrix *)&csc, 1.0f, 0.0f);
 
    XVMC_MSG(XVMC_TRACE, "[XvMC] Set attribute %s to value %d.\n", attr, value);
 
index a6991ab8d6107153550b21683bc30491a696d40a..e9014c8bf53ff700a2827bb82909d60f0d4fef73 100644 (file)
@@ -293,7 +293,7 @@ Status XvMCCreateContext(Display *dpy, XvPortID port, int surface_type_id,
       context_priv->color_standard,
       &context_priv->procamp, true, &csc
    );
-   vl_compositor_set_csc_matrix(&context_priv->cstate, (const vl_csc_matrix *)&csc);
+   vl_compositor_set_csc_matrix(&context_priv->cstate, (const vl_csc_matrix *)&csc, 1.0f, 0.0f);
 
    context_priv->vscreen = vscreen;
    context_priv->pipe = pipe;