From: Ville Syrjälä <ville.syrjala@xxxxxxxxxxxxxxx> 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@xxxxxxxxxxx Signed-off-by: Ville Syrjälä <ville.syrjala@xxxxxxxxxxxxxxx> --- 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 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx