Module: Mesa
Branch: main
Commit: 8a21efce3a2345a21683667f076d7f34a31e500d
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=8a21efce3a2345a21683667f076d7f34a31e500d

Author: David Rosca <[email protected]>
Date:   Mon Jul 17 12:22:41 2023 +0200

frontends/va: Add postproc support for converting to full range

Acked-by: Ruijing Dong <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24174>

---

 src/gallium/auxiliary/vl/vl_compositor.c | 12 +++++++-----
 src/gallium/auxiliary/vl/vl_compositor.h |  3 ++-
 src/gallium/auxiliary/vl/vl_csc.c        |  8 +++++++-
 src/gallium/frontends/va/picture.c       |  1 +
 src/gallium/frontends/va/postproc.c      | 15 ++++++++++++---
 src/gallium/frontends/va/va_private.h    |  1 +
 src/gallium/include/pipe/p_video_state.h |  1 +
 7 files changed, 31 insertions(+), 10 deletions(-)

diff --git a/src/gallium/auxiliary/vl/vl_compositor.c 
b/src/gallium/auxiliary/vl/vl_compositor.c
index 92e7462c11e..108c92c8bdb 100644
--- a/src/gallium/auxiliary/vl/vl_compositor.c
+++ b/src/gallium/auxiliary/vl/vl_compositor.c
@@ -382,7 +382,8 @@ set_yuv_layer(struct vl_compositor_state *s, struct 
vl_compositor *c,
 static void
 set_rgb_to_yuv_layer(struct vl_compositor_state *s, struct vl_compositor *c,
                      unsigned layer, struct pipe_sampler_view *v,
-                     struct u_rect *src_rect, struct u_rect *dst_rect, bool y)
+                     struct u_rect *src_rect, struct u_rect *dst_rect, bool y,
+                     bool full_range)
 {
    vl_csc_matrix csc_matrix;
 
@@ -394,7 +395,7 @@ set_rgb_to_yuv_layer(struct vl_compositor_state *s, struct 
vl_compositor *c,
 
    s->layers[layer].fs = y? c->fs_rgb_yuv.y : c->fs_rgb_yuv.uv;
 
-   vl_csc_get_matrix(VL_CSC_COLOR_STANDARD_BT_709_REV, NULL, false, 
&csc_matrix);
+   vl_csc_get_matrix(VL_CSC_COLOR_STANDARD_BT_709_REV, NULL, full_range, 
&csc_matrix);
    vl_compositor_set_csc_matrix(s, (const vl_csc_matrix *)&csc_matrix, 1.0f, 
0.0f);
 
    s->layers[layer].samplers[0] = c->sampler_linear;
@@ -725,7 +726,8 @@ vl_compositor_convert_rgb_to_yuv(struct vl_compositor_state 
*s,
                                  struct pipe_resource *src_res,
                                  struct pipe_video_buffer *dst,
                                  struct u_rect *src_rect,
-                                 struct u_rect *dst_rect)
+                                 struct u_rect *dst_rect,
+                                 bool full_range)
 {
    struct pipe_sampler_view *sv, sv_templ;
    struct pipe_surface **dst_surfaces;
@@ -738,7 +740,7 @@ vl_compositor_convert_rgb_to_yuv(struct vl_compositor_state 
*s,
 
    vl_compositor_clear_layers(s);
 
-   set_rgb_to_yuv_layer(s, c, 0, sv, src_rect, NULL, true);
+   set_rgb_to_yuv_layer(s, c, 0, sv, src_rect, NULL, true, full_range);
    vl_compositor_set_layer_dst_area(s, 0, dst_rect);
    vl_compositor_render(s, c, dst_surfaces[0], NULL, false);
 
@@ -747,7 +749,7 @@ vl_compositor_convert_rgb_to_yuv(struct vl_compositor_state 
*s,
       dst_rect->y1 /= 2;
    }
 
-   set_rgb_to_yuv_layer(s, c, 0, sv, src_rect, NULL, false);
+   set_rgb_to_yuv_layer(s, c, 0, sv, src_rect, NULL, false, full_range);
    vl_compositor_set_layer_dst_area(s, 0, dst_rect);
    vl_compositor_render(s, c, dst_surfaces[1], NULL, false);
    pipe_sampler_view_reference(&sv, NULL);
diff --git a/src/gallium/auxiliary/vl/vl_compositor.h 
b/src/gallium/auxiliary/vl/vl_compositor.h
index be82e156cbc..3d55c31f260 100644
--- a/src/gallium/auxiliary/vl/vl_compositor.h
+++ b/src/gallium/auxiliary/vl/vl_compositor.h
@@ -302,7 +302,8 @@ vl_compositor_convert_rgb_to_yuv(struct vl_compositor_state 
*state,
                                  struct pipe_resource *src_res,
                                  struct pipe_video_buffer *dst,
                                  struct u_rect *src_rect,
-                                 struct u_rect *dst_rect);
+                                 struct u_rect *dst_rect,
+                                 bool full_range);
 
 /*@}*/
 
diff --git a/src/gallium/auxiliary/vl/vl_csc.c 
b/src/gallium/auxiliary/vl/vl_csc.c
index 861eda683a6..dccedf821e0 100644
--- a/src/gallium/auxiliary/vl/vl_csc.c
+++ b/src/gallium/auxiliary/vl/vl_csc.c
@@ -137,6 +137,12 @@ static const vl_csc_matrix bt_709_rev  = {
    { 0.439f, -0.399f, -0.040f, 0.5f   }
 };
 
+static const vl_csc_matrix bt_709_full  = {
+   { 0.0f,  1.0f, 0.0f, 0.0f },
+   { 0.0f, -0.5f, 0.5f, 0.5f },
+   { 0.5f, -0.5f, 0.0f, 0.5f }
+};
+
 static const vl_csc_matrix identity =
 {
    { 1.0f, 0.0f, 0.0f, 0.0f, },
@@ -191,7 +197,7 @@ void vl_csc_get_matrix(enum VL_CSC_COLOR_STANDARD cs,
          cstd = &smpte240m;
          break;
       case VL_CSC_COLOR_STANDARD_BT_709_REV:
-         memcpy(matrix, bt_709_rev, sizeof(vl_csc_matrix));
+         memcpy(matrix, full_range ? bt_709_full : bt_709_rev, 
sizeof(vl_csc_matrix));
          return;
       case VL_CSC_COLOR_STANDARD_IDENTITY:
       default:
diff --git a/src/gallium/frontends/va/picture.c 
b/src/gallium/frontends/va/picture.c
index 76220dcfb1b..ec81ed3f33f 100644
--- a/src/gallium/frontends/va/picture.c
+++ b/src/gallium/frontends/va/picture.c
@@ -1089,6 +1089,7 @@ vlVaEndPicture(VADriverContextP ctx, VAContextID 
context_id)
       }
 
       context->desc.base.input_format = surf->buffer->buffer_format;
+      context->desc.base.input_full_range = surf->full_range;
       context->desc.base.output_format = surf->encoder_format;
 
       context->decoder->begin_frame(context->decoder, context->target, 
&context->desc.base);
diff --git a/src/gallium/frontends/va/postproc.c 
b/src/gallium/frontends/va/postproc.c
index a0f595a3c83..243ac8d0f8b 100644
--- a/src/gallium/frontends/va/postproc.c
+++ b/src/gallium/frontends/va/postproc.c
@@ -191,7 +191,8 @@ static VAStatus vlVaPostProcBlit(vlVaDriver *drv, 
vlVaContext *context,
                                  const VARectangle *dst_region,
                                  struct pipe_video_buffer *src,
                                  struct pipe_video_buffer *dst,
-                                 enum vl_compositor_deinterlace deinterlace)
+                                 enum vl_compositor_deinterlace deinterlace,
+                                 bool full_range)
 {
    struct pipe_surface **src_surfaces;
    struct pipe_surface **dst_surfaces;
@@ -248,7 +249,7 @@ static VAStatus vlVaPostProcBlit(vlVaDriver *drv, 
vlVaContext *context,
    if (grab) {
       vl_compositor_convert_rgb_to_yuv(&drv->cstate, &drv->compositor, 0,
                                        ((struct vl_video_buffer 
*)src)->resources[0],
-                                       dst, &src_rect, &dst_rect);
+                                       dst, &src_rect, &dst_rect, full_range);
 
       return VA_STATUS_SUCCESS;
    }
@@ -419,6 +420,13 @@ vlVaHandleVAProcPipelineParameterBufferType(vlVaDriver 
*drv, vlVaContext *contex
    if (!src_surface->buffer || !dst_surface->buffer)
       return VA_STATUS_ERROR_INVALID_SURFACE;
 
+   /* Assume full range input when not set */
+   src_surface->full_range =
+      param->input_color_properties.color_range != VA_SOURCE_RANGE_REDUCED;
+   /* Assume limited range output when not set */
+   dst_surface->full_range =
+      param->output_color_properties.color_range == VA_SOURCE_RANGE_FULL;
+
    pscreen = drv->vscreen->pscreen;
 
    src_region = vlVaRegionDefault(param->surface_region, src_surface, 
&def_src_region);
@@ -539,5 +547,6 @@ vlVaHandleVAProcPipelineParameterBufferType(vlVaDriver 
*drv, vlVaContext *contex
                                     src, context->target, deinterlace);
    else
       return vlVaPostProcBlit(drv, context, src_region, dst_region,
-                              src, context->target, deinterlace);
+                              src, context->target, deinterlace,
+                              dst_surface->full_range);
 }
diff --git a/src/gallium/frontends/va/va_private.h 
b/src/gallium/frontends/va/va_private.h
index 2341efe47c6..6d4b8709c3c 100644
--- a/src/gallium/frontends/va/va_private.h
+++ b/src/gallium/frontends/va/va_private.h
@@ -391,6 +391,7 @@ typedef struct {
    bool force_flushed;
    struct pipe_video_buffer *obsolete_buf;
    enum pipe_format encoder_format;
+   bool full_range;
    struct pipe_fence_handle *fence;
 } vlVaSurface;
 
diff --git a/src/gallium/include/pipe/p_video_state.h 
b/src/gallium/include/pipe/p_video_state.h
index 3c32b753c0b..ccf86e548db 100644
--- a/src/gallium/include/pipe/p_video_state.h
+++ b/src/gallium/include/pipe/p_video_state.h
@@ -186,6 +186,7 @@ struct pipe_picture_desc
    uint8_t *decrypt_key;
    uint32_t key_size;
    enum pipe_format input_format;
+   bool input_full_range;
    enum pipe_format output_format;
    /* A fence used on PIPE_VIDEO_ENTRYPOINT_DECODE/PROCESSING to signal job 
completion */
    struct pipe_fence_handle **fence;

Reply via email to