From: Ville Syrjälä <ville.syrj...@linux.intel.com>

Add a new Xv port attribute XV_COLOR_RANGE to select the incoming YUV
quantization range. 0 means limited range (Y: 16-235, Cb/Cr: 16-240),
1 means full range (0-255).

We'll forward the quantization range information to the kernel via
the COLOR_RANGE kms property.

Cc: xorg-devel@lists.x.org
Signed-off-by: Ville Syrjälä <ville.syrj...@linux.intel.com>
---
 src/sna/sna.h              |  3 +-
 src/sna/sna_display.c      | 72 ++++++++++++++++++++++++++++++++++++++++------
 src/sna/sna_video_sprite.c | 18 +++++++++---
 3 files changed, 80 insertions(+), 13 deletions(-)

diff --git a/src/sna/sna.h b/src/sna/sna.h
index 496460ca6a84..658093f3c04c 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -633,7 +633,8 @@ static inline void sna_present_cancel_flip(struct sna *sna) 
{ }
 
 extern unsigned sna_crtc_count_sprites(xf86CrtcPtr crtc);
 extern bool sna_crtc_set_sprite_rotation(xf86CrtcPtr crtc, unsigned idx, 
uint32_t rotation);
-extern void sna_crtc_set_sprite_colorspace(xf86CrtcPtr crtc, unsigned idx, int 
colorspace);
+extern void sna_crtc_set_sprite_colorspace(xf86CrtcPtr crtc, unsigned idx,
+                                          int colorspace, int color_range);
 extern uint32_t sna_crtc_to_sprite(xf86CrtcPtr crtc, unsigned idx);
 extern bool sna_crtc_is_transformed(xf86CrtcPtr crtc);
 bool sna_has_sprite_format(struct sna *sna, uint32_t format);
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 96e7b1bc50d3..9438408b937f 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -226,6 +226,10 @@ struct sna_crtc {
                        uint32_t prop;
                        uint64_t values[2];
                } color_encoding;
+               struct {
+                       uint32_t prop;
+                       uint64_t values[2];
+               } color_range;
                struct list link;
        } primary;
        struct list sprites;
@@ -3374,8 +3378,55 @@ static void parse_color_encoding_prop(struct sna *sna, 
struct plane *p,
                p->color_encoding.prop = prop->prop_id;
 }
 
+inline static bool prop_is_color_range(const struct drm_mode_get_property 
*prop)
+{
+       return prop_has_type_and_name(prop, 3, "COLOR_RANGE");
+}
+
+static void parse_color_range_prop(struct sna *sna, struct plane *p,
+                                  struct drm_mode_get_property *prop,
+                                  uint64_t value)
+{
+       struct drm_mode_property_enum *enums;
+       unsigned int supported = 0;
+       int j;
+
+       DBG(("%s: found color range property .id=%d, value=%ld, num_enums=%d\n",
+            __FUNCTION__, prop->prop_id, (long)value, prop->count_enum_blobs));
+
+       enums = malloc(prop->count_enum_blobs * sizeof(struct 
drm_mode_property_enum));
+       if (!enums)
+               return;
+
+       prop->count_values = 0;
+       prop->enum_blob_ptr = (uintptr_t)enums;
+
+       if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPERTY, prop)) {
+               free(enums);
+               return;
+       }
+
+       VG(VALGRIND_MAKE_MEM_DEFINED(enums, 
sizeof(*enums)*prop->count_enum_blobs));
+       for (j = 0; j < prop->count_enum_blobs; j++) {
+               if (!strcmp(enums[j].name, "YCbCr limited range")) {
+                       p->color_range.values[0] = enums[j].value;
+                       supported |= 1 << 0;
+               } else if (!strcmp(enums[j].name, "YCbCr full range")) {
+                       p->color_range.values[1] = enums[j].value;
+                       supported |= 1 << 1;
+               }
+       }
+
+       free(enums);
+
+       if (supported == 3)
+               p->color_range.prop = prop->prop_id;
+}
+
 void sna_crtc_set_sprite_colorspace(xf86CrtcPtr crtc,
-                                   unsigned idx, int colorspace)
+                                   unsigned idx,
+                                   int colorspace,
+                                   int color_range)
 {
        struct plane *p;
 
@@ -3384,13 +3435,16 @@ void sna_crtc_set_sprite_colorspace(xf86CrtcPtr crtc,
 
        p = lookup_sprite(to_sna_crtc(crtc), idx);
 
-       if (!p->color_encoding.prop)
-               return;
-
-       drmModeObjectSetProperty(to_sna(crtc->scrn)->kgem.fd,
-                                p->id, DRM_MODE_OBJECT_PLANE,
-                                p->color_encoding.prop,
-                                p->color_encoding.values[colorspace]);
+       if (p->color_encoding.prop)
+               drmModeObjectSetProperty(to_sna(crtc->scrn)->kgem.fd,
+                                        p->id, DRM_MODE_OBJECT_PLANE,
+                                        p->color_encoding.prop,
+                                        p->color_encoding.values[colorspace]);
+       if (p->color_range.prop)
+               drmModeObjectSetProperty(to_sna(crtc->scrn)->kgem.fd,
+                                        p->id, DRM_MODE_OBJECT_PLANE,
+                                        p->color_range.prop,
+                                        p->color_range.values[color_range]);
 }
 
 static int plane_details(struct sna *sna, struct plane *p)
@@ -3452,6 +3506,8 @@ static int plane_details(struct sna *sna, struct plane *p)
                        parse_rotation_prop(sna, p, &prop, values[i]);
                } else if (prop_is_color_encoding(&prop)) {
                        parse_color_encoding_prop(sna, p, &prop, values[i]);
+               } else if (prop_is_color_range(&prop)) {
+                       parse_color_range_prop(sna, p, &prop, values[i]);
                }
        }
 
diff --git a/src/sna/sna_video_sprite.c b/src/sna/sna_video_sprite.c
index 8b7ae8ae9e75..1f41e3f8528d 100644
--- a/src/sna/sna_video_sprite.c
+++ b/src/sna/sna_video_sprite.c
@@ -70,7 +70,7 @@ struct local_mode_set_plane {
 
 #define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, true)
 
-static Atom xvColorKey, xvAlwaysOnTop, xvSyncToVblank, xvColorspace;
+static Atom xvColorKey, xvAlwaysOnTop, xvSyncToVblank, xvColorspace, 
xvColorRange;
 
 static XvFormatRec formats[] = { {15}, {16}, {24} };
 static const XvImageRec images[] = { XVIMAGE_YUY2, XVIMAGE_UYVY,
@@ -81,6 +81,7 @@ static const XvImageRec images_nv12[] = { XVIMAGE_YUY2, 
XVIMAGE_UYVY,
                                          XVIMAGE_NV12, XVMC_RGB888, 
XVMC_RGB565 };
 static const XvAttributeRec attribs[] = {
        { XvSettable | XvGettable, 0, 1, (char *)"XV_COLORSPACE" }, /* BT.601, 
BT.709 */
+       { XvSettable | XvGettable, 0, 1, (char *)"XV_COLOR_RANGE" }, /* 
limited, full */
        { XvSettable | XvGettable, 0, 0xffffff, (char *)"XV_COLORKEY" },
        { XvSettable | XvGettable, 0, 1, (char *)"XV_ALWAYS_ON_TOP" },
 };
@@ -130,6 +131,10 @@ static int 
sna_video_sprite_set_attr(ddSetPortAttribute_ARGS)
                video->colorspace_changed = ~0;
                video->colorspace = value;
                DBG(("COLORSPACE = %ld\n", (long)value));
+       } else if (attribute == xvColorRange) {
+               video->colorspace_changed = ~0;
+               video->color_range = value;
+               DBG(("COLOR_RANGE = %ld\n", (long)value));
        } else if (attribute == xvSyncToVblank) {
                DBG(("%s: SYNC_TO_VBLANK: %d -> %d\n", __FUNCTION__,
                     video->SyncToVblank, !!value));
@@ -153,6 +158,8 @@ static int 
sna_video_sprite_get_attr(ddGetPortAttribute_ARGS)
                *value = video->color_key;
        else if (attribute == xvColorspace)
                *value = video->colorspace;
+       else if (attribute == xvColorRange)
+               *value = video->color_range;
        else if (attribute == xvAlwaysOnTop)
                *value = video->AlwaysOnTop;
        else if (attribute == xvSyncToVblank)
@@ -289,11 +296,12 @@ sna_video_sprite_show(struct sna *sna,
        }
 
        if (video->colorspace_changed & (1 << pipe)) {
-               DBG(("%s: updating colorspace: %x\n",
-                    __FUNCTION__, video->colorspace));
+               DBG(("%s: updating colorspace: %x / color_range: %x\n",
+                    __FUNCTION__, video->colorspace, video->color_range));
 
                sna_crtc_set_sprite_colorspace(crtc, video->idx,
-                                              video->colorspace);
+                                              video->colorspace,
+                                              video->color_range);
 
                video->colorspace_changed &= ~(1 << pipe);
        }
@@ -851,6 +859,7 @@ void sna_video_sprite_setup(struct sna *sna, ScreenPtr 
screen)
                video->color_key = sna_video_sprite_color_key(sna);
                video->color_key_changed = ~0;
                video->colorspace = 1; /* BT.709 */
+               video->color_range = 0; /* limited */
                video->colorspace_changed = ~0;
                video->has_color_key = true;
                video->brightness = -19;        /* (255/219) * -16 */
@@ -873,6 +882,7 @@ void sna_video_sprite_setup(struct sna *sna, ScreenPtr 
screen)
 
        xvColorKey = MAKE_ATOM("XV_COLORKEY");
        xvColorspace = MAKE_ATOM("XV_COLORSPACE");
+       xvColorRange = MAKE_ATOM("XV_COLOR_RANGE");
        xvAlwaysOnTop = MAKE_ATOM("XV_ALWAYS_ON_TOP");
        xvSyncToVblank = MAKE_ATOM("XV_SYNC_TO_VBLANK");
 
-- 
2.16.4

_______________________________________________
xorg-devel@lists.x.org: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: https://lists.x.org/mailman/listinfo/xorg-devel

Reply via email to