d3d11format: Move DXGI color space mapping method to gst-libs

Expose color space mapping method to public so that application
can configure GstCaps or GstVideoInfo using DXGI color space

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2776>
This commit is contained in:
Seungha Yang 2022-07-17 04:48:24 +09:00
parent 43052fabb5
commit 16f4567a50
7 changed files with 517 additions and 588 deletions

View file

@ -440,3 +440,476 @@ gst_d3d11_dxgi_format_to_string (DXGI_FORMAT format)
return "Unknown";
}
/* Some values are not defined in old MinGW toolchain */
typedef enum
{
GST_DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709 = 0,
GST_DXGI_COLOR_SPACE_RGB_FULL_G10_NONE_P709 = 1,
GST_DXGI_COLOR_SPACE_RGB_STUDIO_G22_NONE_P709 = 2,
GST_DXGI_COLOR_SPACE_RGB_STUDIO_G22_NONE_P2020 = 3,
GST_DXGI_COLOR_SPACE_RESERVED = 4,
GST_DXGI_COLOR_SPACE_YCBCR_FULL_G22_NONE_P709_X601 = 5,
GST_DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P601 = 6,
GST_DXGI_COLOR_SPACE_YCBCR_FULL_G22_LEFT_P601 = 7,
GST_DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P709 = 8,
GST_DXGI_COLOR_SPACE_YCBCR_FULL_G22_LEFT_P709 = 9,
GST_DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P2020 = 10,
GST_DXGI_COLOR_SPACE_YCBCR_FULL_G22_LEFT_P2020 = 11,
GST_DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020 = 12,
GST_DXGI_COLOR_SPACE_YCBCR_STUDIO_G2084_LEFT_P2020 = 13,
GST_DXGI_COLOR_SPACE_RGB_STUDIO_G2084_NONE_P2020 = 14,
GST_DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_TOPLEFT_P2020 = 15,
GST_DXGI_COLOR_SPACE_YCBCR_STUDIO_G2084_TOPLEFT_P2020 = 16,
GST_DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P2020 = 17,
GST_DXGI_COLOR_SPACE_YCBCR_STUDIO_GHLG_TOPLEFT_P2020 = 18,
GST_DXGI_COLOR_SPACE_YCBCR_FULL_GHLG_TOPLEFT_P2020 = 19,
GST_DXGI_COLOR_SPACE_RGB_STUDIO_G24_NONE_P709 = 20,
GST_DXGI_COLOR_SPACE_RGB_STUDIO_G24_NONE_P2020 = 21,
GST_DXGI_COLOR_SPACE_YCBCR_STUDIO_G24_LEFT_P709 = 22,
GST_DXGI_COLOR_SPACE_YCBCR_STUDIO_G24_LEFT_P2020 = 23,
GST_DXGI_COLOR_SPACE_YCBCR_STUDIO_G24_TOPLEFT_P2020 = 24,
} GST_DXGI_COLOR_SPACE_TYPE;
static gboolean
rgb_to_colorspace (const GstVideoColorimetry * cinfo,
DXGI_COLOR_SPACE_TYPE * color_space)
{
/* sRGB */
GST_DXGI_COLOR_SPACE_TYPE type = GST_DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709;
/* Defined DXGI RGB colorspace
* 1) DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709 = 0 (sRGB)
* 2) DXGI_COLOR_SPACE_RGB_FULL_G10_NONE_P709 = 1 (scRGB)
* 3) DXGI_COLOR_SPACE_RGB_STUDIO_G22_NONE_P709 = 2 (BT601/BT709 studio range)
* 4) DXGI_COLOR_SPACE_RGB_STUDIO_G22_NONE_P2020 = 3 (BT2020 SDR studio range)
* 5) DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020 = 12 (HDR10 full range)
* 6) DXGI_COLOR_SPACE_RGB_STUDIO_G2084_NONE_P2020 = 13 (HDR10 studio range)
* 7) DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P2020 = 17 (BT2020 SDR fullrange)
* 8) DXGI_COLOR_SPACE_RGB_STUDIO_G24_NONE_P709 = 20 (unused)
* 9) DXGI_COLOR_SPACE_RGB_STUDIO_G24_NONE_P2020 = 21 (unused)
*
* Note that GStreamer does not define gamma2.4. So, 8) and 9) are excluded
*/
if (cinfo->transfer == GST_VIDEO_TRANSFER_GAMMA10) {
type = GST_DXGI_COLOR_SPACE_RGB_FULL_G10_NONE_P709;
goto done;
}
/* HLG RGB colorspace is not defined, approximated to HDR10 */
if (cinfo->transfer == GST_VIDEO_TRANSFER_SMPTE2084 ||
cinfo->transfer == GST_VIDEO_TRANSFER_ARIB_STD_B67) {
if (cinfo->range == GST_VIDEO_COLOR_RANGE_16_235) {
type = GST_DXGI_COLOR_SPACE_RGB_STUDIO_G2084_NONE_P2020;
} else {
type = GST_DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020;
}
goto done;
}
if (cinfo->primaries == GST_VIDEO_COLOR_PRIMARIES_BT2020) {
if (cinfo->range == GST_VIDEO_COLOR_RANGE_16_235) {
type = GST_DXGI_COLOR_SPACE_RGB_STUDIO_G22_NONE_P2020;
} else {
type = GST_DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P2020;
}
goto done;
}
if (cinfo->range == GST_VIDEO_COLOR_RANGE_16_235)
type = GST_DXGI_COLOR_SPACE_RGB_STUDIO_G22_NONE_P709;
done:
*color_space = (DXGI_COLOR_SPACE_TYPE) type;
return TRUE;
}
static gboolean
yuv_to_colorspace (const GstVideoColorimetry * cinfo,
GstVideoChromaSite chroma_site, DXGI_COLOR_SPACE_TYPE * color_space)
{
/* BT709 */
GST_DXGI_COLOR_SPACE_TYPE type =
GST_DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P709;
/* Defined DXGI RGB colorspace
* 1) DXGI_COLOR_SPACE_YCBCR_FULL_G22_NONE_P709_X601 = 5 (common JPG)
* 2) DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P601 = 6 (BT601 studio range)
* 3) DXGI_COLOR_SPACE_YCBCR_FULL_G22_LEFT_P601 = 7 (BT601 full range)
* 4) DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P709 = 8 (BT709 studio range)
* 5) DXGI_COLOR_SPACE_YCBCR_FULL_G22_LEFT_P709 = 9 (BT709 full range)
* 6) DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P2020 = 10 (BT2020 4:2:0 studio range)
* 7) DXGI_COLOR_SPACE_YCBCR_FULL_G22_LEFT_P2020 = 11 (BT2020 full range)
* 8) DXGI_COLOR_SPACE_YCBCR_STUDIO_G2084_LEFT_P2020 = 13 (HDR10 4:2:0 studio range)
* 9) DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_TOPLEFT_P2020 = 15 (BT2020 4:2:2 or 4:4:4: studio range)
* 10) DXGI_COLOR_SPACE_YCBCR_STUDIO_G2084_TOPLEFT_P2020 = 16 (HDR10 4:2:2 or 4:4:4 studio range)
* 11) DXGI_COLOR_SPACE_YCBCR_STUDIO_GHLG_TOPLEFT_P2020 = 18 (HLG studio range)
* 12) DXGI_COLOR_SPACE_YCBCR_FULL_GHLG_TOPLEFT_P2020 = 19 (HLG full range)
* 13) DXGI_COLOR_SPACE_YCBCR_STUDIO_G24_LEFT_P709 = 22 (unused)
* 14) DXGI_COLOR_SPACE_YCBCR_STUDIO_G24_LEFT_P2020 = 23 (unused)
* 15) DXGI_COLOR_SPACE_YCBCR_STUDIO_G24_TOPLEFT_P2020 = 24 (unused)
*
* Note that GStreamer does not define gamma2.4. So, 13) ~ 15) are excluded
*/
/* HLG */
if (cinfo->transfer == GST_VIDEO_TRANSFER_ARIB_STD_B67) {
if (cinfo->range == GST_VIDEO_COLOR_RANGE_0_255) {
type = GST_DXGI_COLOR_SPACE_YCBCR_FULL_GHLG_TOPLEFT_P2020;
} else {
type = GST_DXGI_COLOR_SPACE_YCBCR_STUDIO_GHLG_TOPLEFT_P2020;
}
goto done;
}
/* HDR10 */
if (cinfo->transfer == GST_VIDEO_TRANSFER_SMPTE2084) {
if (chroma_site == GST_VIDEO_CHROMA_SITE_H_COSITED) {
type = GST_DXGI_COLOR_SPACE_YCBCR_STUDIO_G2084_LEFT_P2020;
} else {
type = GST_DXGI_COLOR_SPACE_YCBCR_STUDIO_G2084_TOPLEFT_P2020;
}
goto done;
}
/* BT2020 */
if (cinfo->primaries == GST_VIDEO_COLOR_PRIMARIES_BT2020) {
if (cinfo->range == GST_VIDEO_COLOR_RANGE_0_255) {
type = GST_DXGI_COLOR_SPACE_YCBCR_FULL_G22_LEFT_P2020;
} else if (chroma_site == GST_VIDEO_CHROMA_SITE_H_COSITED) {
type = GST_DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P2020;
} else {
type = GST_DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_TOPLEFT_P2020;
}
goto done;
}
/* BT601/BT709 primaries are similar. Depends on RGB matrix */
if (cinfo->matrix == GST_VIDEO_COLOR_MATRIX_BT601) {
if (cinfo->range == GST_VIDEO_COLOR_RANGE_0_255) {
if (cinfo->primaries == GST_VIDEO_COLOR_PRIMARIES_BT709) {
type = GST_DXGI_COLOR_SPACE_YCBCR_FULL_G22_NONE_P709_X601;
} else {
type = GST_DXGI_COLOR_SPACE_YCBCR_FULL_G22_LEFT_P601;
}
} else {
type = GST_DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P601;
}
goto done;
}
if (cinfo->range == GST_VIDEO_COLOR_RANGE_0_255)
type = GST_DXGI_COLOR_SPACE_YCBCR_FULL_G22_LEFT_P709;
done:
*color_space = (DXGI_COLOR_SPACE_TYPE) type;
return TRUE;
}
/**
* gst_video_info_to_dxgi_color_space:
* @info: a #GstVideoInfo
* @color_space: (out): DXGI color space
*
* Derives DXGI_COLOR_SPACE_TYPE from @info
*
* Returns: %TRUE if successful
*
* Since: 1.22
*/
gboolean
gst_video_info_to_dxgi_color_space (const GstVideoInfo * info,
DXGI_COLOR_SPACE_TYPE * color_space)
{
const GstVideoColorimetry *cinfo;
GstVideoColorimetry c;
g_return_val_if_fail (info != nullptr, FALSE);
g_return_val_if_fail (color_space != nullptr, FALSE);
cinfo = &info->colorimetry;
if (GST_VIDEO_INFO_IS_RGB (info)) {
/* ensure RGB matrix if format is already RGB */
c.matrix = GST_VIDEO_COLOR_MATRIX_RGB;
} else if (GST_VIDEO_INFO_IS_YUV (info) &&
cinfo->matrix == GST_VIDEO_COLOR_MATRIX_RGB) {
/* Invalid matrix */
c.matrix = GST_VIDEO_COLOR_MATRIX_UNKNOWN;
} else {
c.matrix = cinfo->matrix;
}
switch (cinfo->range) {
case GST_VIDEO_COLOR_RANGE_0_255:
c.range = GST_VIDEO_COLOR_RANGE_0_255;
break;
case GST_VIDEO_COLOR_RANGE_16_235:
c.range = GST_VIDEO_COLOR_RANGE_16_235;
break;
default:
if (c.matrix == GST_VIDEO_COLOR_MATRIX_RGB)
c.range = GST_VIDEO_COLOR_RANGE_0_255;
else
c.range = GST_VIDEO_COLOR_RANGE_16_235;
break;
}
/* DXGI primaries: BT601, BT709, BT2020 */
switch (cinfo->primaries) {
case GST_VIDEO_COLOR_PRIMARIES_BT2020:
c.primaries = GST_VIDEO_COLOR_PRIMARIES_BT2020;
break;
case GST_VIDEO_COLOR_PRIMARIES_SMPTE170M:
case GST_VIDEO_COLOR_PRIMARIES_SMPTE240M:
c.primaries = GST_VIDEO_COLOR_PRIMARIES_SMPTE170M;
break;
default:
c.primaries = GST_VIDEO_COLOR_PRIMARIES_BT709;
break;
}
/* DXGI gamma functions: linear (RGB only), gamma2.2, PQ, and HLG */
switch (cinfo->transfer) {
case GST_VIDEO_TRANSFER_SMPTE2084:
c.transfer = GST_VIDEO_TRANSFER_SMPTE2084;
break;
case GST_VIDEO_TRANSFER_ARIB_STD_B67:
c.transfer = GST_VIDEO_TRANSFER_ARIB_STD_B67;
break;
case GST_VIDEO_TRANSFER_GAMMA10:
/* Only DXGI_COLOR_SPACE_RGB_FULL_G10_NONE_P709 supports linear gamma */
if (c.matrix == GST_VIDEO_COLOR_MATRIX_RGB) {
c.transfer = GST_VIDEO_TRANSFER_GAMMA10;
c.range = GST_VIDEO_COLOR_RANGE_0_255;
} else {
c.transfer = GST_VIDEO_TRANSFER_GAMMA22;
}
break;
default:
/* Simply map the rest of values to gamma 2.2. We don't have any other
* choice */
c.transfer = GST_VIDEO_TRANSFER_GAMMA22;
break;
}
/* DXGI transform matrix: BT601, BT709, and BT2020 */
switch (c.matrix) {
case GST_VIDEO_COLOR_MATRIX_RGB:
c.matrix = GST_VIDEO_COLOR_MATRIX_RGB;
break;
case GST_VIDEO_COLOR_MATRIX_FCC:
case GST_VIDEO_COLOR_MATRIX_BT601:
c.matrix = GST_VIDEO_COLOR_MATRIX_BT601;
break;
case GST_VIDEO_COLOR_MATRIX_BT2020:
c.matrix = GST_VIDEO_COLOR_MATRIX_BT2020;
break;
default:
c.matrix = GST_VIDEO_COLOR_MATRIX_BT709;
break;
}
if (c.matrix == GST_VIDEO_COLOR_MATRIX_RGB)
return rgb_to_colorspace (&c, color_space);
return yuv_to_colorspace (&c, info->chroma_site, color_space);
}
static gboolean
dxgi_color_space_is_rgb (GST_DXGI_COLOR_SPACE_TYPE color_space)
{
switch (color_space) {
case GST_DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709:
case GST_DXGI_COLOR_SPACE_RGB_FULL_G10_NONE_P709:
case GST_DXGI_COLOR_SPACE_RGB_STUDIO_G22_NONE_P709:
case GST_DXGI_COLOR_SPACE_RGB_STUDIO_G22_NONE_P2020:
case GST_DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020:
case GST_DXGI_COLOR_SPACE_RGB_STUDIO_G2084_NONE_P2020:
case GST_DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P2020:
case GST_DXGI_COLOR_SPACE_RGB_STUDIO_G24_NONE_P709:
case GST_DXGI_COLOR_SPACE_RGB_STUDIO_G24_NONE_P2020:
return TRUE;
default:
break;
}
return FALSE;
}
/**
* gst_video_info_apply_dxgi_color_space:
* @color_space: DXGI color space
* @info: (inout): a #GstVideoInfo
*
* Updates color information of @info using @color_space
*
* Returns: %TRUE if successful
*
* Since: 1.22
*/
gboolean
gst_video_info_apply_dxgi_color_space (DXGI_COLOR_SPACE_TYPE color_space,
GstVideoInfo * info)
{
GST_DXGI_COLOR_SPACE_TYPE type;
GstVideoColorimetry c;
g_return_val_if_fail (info != nullptr, FALSE);
type = (GST_DXGI_COLOR_SPACE_TYPE) color_space;
if (GST_VIDEO_INFO_IS_RGB (info) && !dxgi_color_space_is_rgb (type)) {
GST_WARNING ("Invalid DXGI color space mapping");
return FALSE;
}
switch (type) {
case GST_DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709:
c.range = GST_VIDEO_COLOR_RANGE_0_255;
c.matrix = GST_VIDEO_COLOR_MATRIX_RGB;
c.transfer = GST_VIDEO_TRANSFER_SRGB;
c.primaries = GST_VIDEO_COLOR_PRIMARIES_BT709;
break;
case GST_DXGI_COLOR_SPACE_RGB_FULL_G10_NONE_P709:
c.range = GST_VIDEO_COLOR_RANGE_0_255;
c.matrix = GST_VIDEO_COLOR_MATRIX_RGB;
c.transfer = GST_VIDEO_TRANSFER_GAMMA10;
c.primaries = GST_VIDEO_COLOR_PRIMARIES_BT709;
break;
case GST_DXGI_COLOR_SPACE_RGB_STUDIO_G22_NONE_P709:
case GST_DXGI_COLOR_SPACE_RGB_STUDIO_G24_NONE_P709:
c.range = GST_VIDEO_COLOR_RANGE_16_235;
c.matrix = GST_VIDEO_COLOR_MATRIX_RGB;
c.transfer = GST_VIDEO_TRANSFER_BT709;
c.primaries = GST_VIDEO_COLOR_PRIMARIES_BT709;
break;
case GST_DXGI_COLOR_SPACE_RGB_STUDIO_G22_NONE_P2020:
case GST_DXGI_COLOR_SPACE_RGB_STUDIO_G24_NONE_P2020:
c.range = GST_VIDEO_COLOR_RANGE_16_235;
c.matrix = GST_VIDEO_COLOR_MATRIX_RGB;
if (GST_VIDEO_INFO_COMP_DEPTH (info, 0) >= 12)
c.transfer = GST_VIDEO_TRANSFER_BT2020_12;
else
c.transfer = GST_VIDEO_TRANSFER_BT2020_10;
c.primaries = GST_VIDEO_COLOR_PRIMARIES_BT2020;
break;
case GST_DXGI_COLOR_SPACE_RESERVED:
GST_WARNING ("Reserved color space");
return FALSE;
case GST_DXGI_COLOR_SPACE_YCBCR_FULL_G22_NONE_P709_X601:
c.range = GST_VIDEO_COLOR_RANGE_0_255;
c.matrix = GST_VIDEO_COLOR_MATRIX_BT601;
c.transfer = GST_VIDEO_TRANSFER_BT601;
c.primaries = GST_VIDEO_COLOR_PRIMARIES_BT709;
break;
case GST_DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P601:
c.range = GST_VIDEO_COLOR_RANGE_16_235;
c.matrix = GST_VIDEO_COLOR_MATRIX_BT601;
c.transfer = GST_VIDEO_TRANSFER_BT601;
c.primaries = GST_VIDEO_COLOR_PRIMARIES_SMPTE170M;
break;
case GST_DXGI_COLOR_SPACE_YCBCR_FULL_G22_LEFT_P601:
c.range = GST_VIDEO_COLOR_RANGE_0_255;
c.matrix = GST_VIDEO_COLOR_MATRIX_BT601;
c.transfer = GST_VIDEO_TRANSFER_BT601;
c.primaries = GST_VIDEO_COLOR_PRIMARIES_SMPTE170M;
break;
case GST_DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P709:
case GST_DXGI_COLOR_SPACE_YCBCR_STUDIO_G24_LEFT_P709:
c.range = GST_VIDEO_COLOR_RANGE_16_235;
c.matrix = GST_VIDEO_COLOR_MATRIX_BT709;
c.transfer = GST_VIDEO_TRANSFER_BT709;
c.primaries = GST_VIDEO_COLOR_PRIMARIES_BT709;
break;
case GST_DXGI_COLOR_SPACE_YCBCR_FULL_G22_LEFT_P709:
c.range = GST_VIDEO_COLOR_RANGE_0_255;
c.matrix = GST_VIDEO_COLOR_MATRIX_BT709;
c.transfer = GST_VIDEO_TRANSFER_BT709;
c.primaries = GST_VIDEO_COLOR_PRIMARIES_BT709;
break;
case GST_DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P2020:
case GST_DXGI_COLOR_SPACE_YCBCR_STUDIO_G24_LEFT_P2020:
c.range = GST_VIDEO_COLOR_RANGE_16_235;
c.matrix = GST_VIDEO_COLOR_MATRIX_BT2020;
if (GST_VIDEO_INFO_COMP_DEPTH (info, 0) >= 12)
c.transfer = GST_VIDEO_TRANSFER_BT2020_12;
else
c.transfer = GST_VIDEO_TRANSFER_BT2020_10;
c.primaries = GST_VIDEO_COLOR_PRIMARIES_BT2020;
break;
case GST_DXGI_COLOR_SPACE_YCBCR_FULL_G22_LEFT_P2020:
c.range = GST_VIDEO_COLOR_RANGE_0_255;
c.matrix = GST_VIDEO_COLOR_MATRIX_BT2020;
if (GST_VIDEO_INFO_COMP_DEPTH (info, 0) >= 12)
c.transfer = GST_VIDEO_TRANSFER_BT2020_12;
else
c.transfer = GST_VIDEO_TRANSFER_BT2020_10;
c.primaries = GST_VIDEO_COLOR_PRIMARIES_BT2020;
break;
case GST_DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020:
c.range = GST_VIDEO_COLOR_RANGE_0_255;
c.matrix = GST_VIDEO_COLOR_MATRIX_RGB;
c.transfer = GST_VIDEO_TRANSFER_SMPTE2084;
c.primaries = GST_VIDEO_COLOR_PRIMARIES_BT2020;
break;
case GST_DXGI_COLOR_SPACE_YCBCR_STUDIO_G2084_LEFT_P2020:
c.range = GST_VIDEO_COLOR_RANGE_16_235;
c.matrix = GST_VIDEO_COLOR_MATRIX_RGB;
c.transfer = GST_VIDEO_TRANSFER_SMPTE2084;
c.primaries = GST_VIDEO_COLOR_PRIMARIES_BT2020;
break;
case GST_DXGI_COLOR_SPACE_RGB_STUDIO_G2084_NONE_P2020:
c.range = GST_VIDEO_COLOR_RANGE_16_235;
c.matrix = GST_VIDEO_COLOR_MATRIX_RGB;
c.transfer = GST_VIDEO_TRANSFER_SMPTE2084;
c.primaries = GST_VIDEO_COLOR_PRIMARIES_BT2020;
break;
case GST_DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_TOPLEFT_P2020:
case GST_DXGI_COLOR_SPACE_YCBCR_STUDIO_G24_TOPLEFT_P2020:
c.range = GST_VIDEO_COLOR_RANGE_16_235;
c.matrix = GST_VIDEO_COLOR_MATRIX_BT2020;
if (GST_VIDEO_INFO_COMP_DEPTH (info, 0) >= 12)
c.transfer = GST_VIDEO_TRANSFER_BT2020_12;
else
c.transfer = GST_VIDEO_TRANSFER_BT2020_10;
c.primaries = GST_VIDEO_COLOR_PRIMARIES_BT2020;
break;
case GST_DXGI_COLOR_SPACE_YCBCR_STUDIO_G2084_TOPLEFT_P2020:
c.range = GST_VIDEO_COLOR_RANGE_16_235;
c.matrix = GST_VIDEO_COLOR_MATRIX_BT2020;
c.transfer = GST_VIDEO_TRANSFER_SMPTE2084;
c.primaries = GST_VIDEO_COLOR_PRIMARIES_BT2020;
break;
case GST_DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P2020:
c.range = GST_VIDEO_COLOR_RANGE_0_255;
c.matrix = GST_VIDEO_COLOR_MATRIX_RGB;
if (GST_VIDEO_INFO_COMP_DEPTH (info, 0) >= 12)
c.transfer = GST_VIDEO_TRANSFER_BT2020_12;
else
c.transfer = GST_VIDEO_TRANSFER_BT2020_10;
c.primaries = GST_VIDEO_COLOR_PRIMARIES_BT2020;
break;
case GST_DXGI_COLOR_SPACE_YCBCR_STUDIO_GHLG_TOPLEFT_P2020:
c.range = GST_VIDEO_COLOR_RANGE_16_235;
c.matrix = GST_VIDEO_COLOR_MATRIX_BT2020;
c.transfer = GST_VIDEO_TRANSFER_ARIB_STD_B67;
c.primaries = GST_VIDEO_COLOR_PRIMARIES_BT2020;
break;
case GST_DXGI_COLOR_SPACE_YCBCR_FULL_GHLG_TOPLEFT_P2020:
c.range = GST_VIDEO_COLOR_RANGE_0_255;
c.matrix = GST_VIDEO_COLOR_MATRIX_BT2020;
c.transfer = GST_VIDEO_TRANSFER_ARIB_STD_B67;
c.primaries = GST_VIDEO_COLOR_PRIMARIES_BT2020;
break;
default:
GST_WARNING ("Unknown DXGI color space %d", type);
return FALSE;
}
info->colorimetry = c;
return TRUE;
}

View file

@ -91,5 +91,13 @@ guint gst_d3d11_dxgi_format_get_alignment (DXGI_FORMAT format);
GST_D3D11_API
const gchar * gst_d3d11_dxgi_format_to_string (DXGI_FORMAT format);
GST_D3D11_API
gboolean gst_video_info_to_dxgi_color_space (const GstVideoInfo * info,
DXGI_COLOR_SPACE_TYPE * color_space);
GST_D3D11_API
gboolean gst_video_info_apply_dxgi_color_space (DXGI_COLOR_SPACE_TYPE color_space,
GstVideoInfo * info);
G_END_DECLS

View file

@ -2698,7 +2698,7 @@ gst_d3d11_converter_setup_processor (GstD3D11Converter * self)
ComPtr < ID3D11VideoProcessor > processor;
UINT support_flags;
BOOL conversion_supported = TRUE;
GstDxgiColorSpace in_space, out_space;
DXGI_COLOR_SPACE_TYPE in_space, out_space;
DXGI_FORMAT in_dxgi_format = priv->in_d3d11_format.dxgi_format;
DXGI_FORMAT out_dxgi_format = priv->out_d3d11_format.dxgi_format;
UINT in_format_flags = priv->in_d3d11_format.format_support[0];
@ -2721,12 +2721,12 @@ gst_d3d11_converter_setup_processor (GstD3D11Converter * self)
return FALSE;
}
if (!gst_d3d11_video_info_to_dxgi_color_space (&priv->in_info, &in_space)) {
if (!gst_video_info_to_dxgi_color_space (&priv->in_info, &in_space)) {
GST_WARNING_OBJECT (self, "Unknown input DXGI colorspace");
return FALSE;
}
if (!gst_d3d11_video_info_to_dxgi_color_space (&priv->out_info, &out_space)) {
if (!gst_video_info_to_dxgi_color_space (&priv->out_info, &out_space)) {
GST_WARNING_OBJECT (self, "Unknown output DXGI colorspace");
return FALSE;
}
@ -2787,9 +2787,7 @@ gst_d3d11_converter_setup_processor (GstD3D11Converter * self)
}
hr = enumerator1->CheckVideoProcessorFormatConversion (in_dxgi_format,
(DXGI_COLOR_SPACE_TYPE) in_space.dxgi_color_space_type,
out_dxgi_format, (DXGI_COLOR_SPACE_TYPE) out_space.dxgi_color_space_type,
&conversion_supported);
in_space, out_dxgi_format, out_space, &conversion_supported);
if (!gst_d3d11_result (hr, device) || !conversion_supported) {
GST_DEBUG_OBJECT (self, "Conversion is not supported");
return FALSE;
@ -2812,9 +2810,9 @@ gst_d3d11_converter_setup_processor (GstD3D11Converter * self)
video_context1->VideoProcessorSetStreamAutoProcessingMode
(processor.Get (), 0, FALSE);
video_context1->VideoProcessorSetStreamColorSpace1 (processor.Get (),
0, (DXGI_COLOR_SPACE_TYPE) in_space.dxgi_color_space_type);
0, in_space);
video_context1->VideoProcessorSetOutputColorSpace1 (processor.Get (),
(DXGI_COLOR_SPACE_TYPE) in_space.dxgi_color_space_type);
out_space);
priv->video_device = video_device;
video_device->AddRef ();

View file

@ -163,523 +163,13 @@ gst_d3d11_hdr_meta_data_to_dxgi (GstVideoMasteringDisplayInfo * minfo,
return TRUE;
}
typedef enum
{
GST_DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709 = 0,
GST_DXGI_COLOR_SPACE_RGB_FULL_G10_NONE_P709 = 1,
GST_DXGI_COLOR_SPACE_RGB_STUDIO_G22_NONE_P709 = 2,
GST_DXGI_COLOR_SPACE_RGB_STUDIO_G22_NONE_P2020 = 3,
GST_DXGI_COLOR_SPACE_RESERVED = 4,
GST_DXGI_COLOR_SPACE_YCBCR_FULL_G22_NONE_P709_X601 = 5,
GST_DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P601 = 6,
GST_DXGI_COLOR_SPACE_YCBCR_FULL_G22_LEFT_P601 = 7,
GST_DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P709 = 8,
GST_DXGI_COLOR_SPACE_YCBCR_FULL_G22_LEFT_P709 = 9,
GST_DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P2020 = 10,
GST_DXGI_COLOR_SPACE_YCBCR_FULL_G22_LEFT_P2020 = 11,
GST_DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020 = 12,
GST_DXGI_COLOR_SPACE_YCBCR_STUDIO_G2084_LEFT_P2020 = 13,
GST_DXGI_COLOR_SPACE_RGB_STUDIO_G2084_NONE_P2020 = 14,
GST_DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_TOPLEFT_P2020 = 15,
GST_DXGI_COLOR_SPACE_YCBCR_STUDIO_G2084_TOPLEFT_P2020 = 16,
GST_DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P2020 = 17,
GST_DXGI_COLOR_SPACE_YCBCR_STUDIO_GHLG_TOPLEFT_P2020 = 18,
GST_DXGI_COLOR_SPACE_YCBCR_FULL_GHLG_TOPLEFT_P2020 = 19,
GST_DXGI_COLOR_SPACE_RGB_STUDIO_G24_NONE_P709 = 20,
GST_DXGI_COLOR_SPACE_RGB_STUDIO_G24_NONE_P2020 = 21,
GST_DXGI_COLOR_SPACE_YCBCR_STUDIO_G24_LEFT_P709 = 22,
GST_DXGI_COLOR_SPACE_YCBCR_STUDIO_G24_LEFT_P2020 = 23,
GST_DXGI_COLOR_SPACE_YCBCR_STUDIO_G24_TOPLEFT_P2020 = 24,
GST_DXGI_COLOR_SPACE_CUSTOM = 0xFFFFFFFF
} GST_DXGI_COLOR_SPACE_TYPE;
/* https://docs.microsoft.com/en-us/windows/win32/api/dxgicommon/ne-dxgicommon-dxgi_color_space_type */
#define MAKE_COLOR_MAP(d,r,m,t,p) \
{ GST_DXGI_COLOR_SPACE_ ##d, GST_VIDEO_COLOR_RANGE ##r, \
GST_VIDEO_COLOR_MATRIX_ ##m, GST_VIDEO_TRANSFER_ ##t, \
GST_VIDEO_COLOR_PRIMARIES_ ##p }
static const GstDxgiColorSpace rgb_colorspace_map[] = {
/* 1) DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709
* 2) DXGI_COLOR_SPACE_RGB_FULL_G10_NONE_P709
* 3) DXGI_COLOR_SPACE_RGB_STUDIO_G22_NONE_P709
* 4) DXGI_COLOR_SPACE_RGB_STUDIO_G22_NONE_P2020
* 5) DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020
* 6) DXGI_COLOR_SPACE_RGB_STUDIO_G2084_NONE_P2020
* 7) DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P2020
* 8) DXGI_COLOR_SPACE_RGB_STUDIO_G24_NONE_P709
* 9) DXGI_COLOR_SPACE_RGB_STUDIO_G24_NONE_P2020
*
* NOTE: if G24 (Gamma 2.4, SRGB) transfer is not defined,
* it will be approximated as G22.
* NOTE: BT470BG ~= BT709
*/
/* 1) RGB_FULL_G22_NONE_P709 */
MAKE_COLOR_MAP (RGB_FULL_G22_NONE_P709, _0_255, UNKNOWN, SRGB, BT709),
/* 1-1) Approximation for RGB_FULL_G22_NONE_P709 */
MAKE_COLOR_MAP (RGB_FULL_G22_NONE_P709, _0_255, UNKNOWN, BT709, BT709),
MAKE_COLOR_MAP (RGB_FULL_G22_NONE_P709, _0_255, UNKNOWN, BT601, BT709),
MAKE_COLOR_MAP (RGB_FULL_G22_NONE_P709, _0_255, UNKNOWN, BT2020_10, BT709),
MAKE_COLOR_MAP (RGB_FULL_G22_NONE_P709, _0_255, UNKNOWN, BT2020_12, BT709),
MAKE_COLOR_MAP (RGB_FULL_G22_NONE_P709, _0_255, UNKNOWN, SRGB, BT470BG),
MAKE_COLOR_MAP (RGB_FULL_G22_NONE_P709, _0_255, UNKNOWN, BT709, BT470BG),
MAKE_COLOR_MAP (RGB_FULL_G22_NONE_P709, _0_255, UNKNOWN, BT601, BT470BG),
MAKE_COLOR_MAP (RGB_FULL_G22_NONE_P709, _0_255, UNKNOWN, BT2020_10, BT470BG),
MAKE_COLOR_MAP (RGB_FULL_G22_NONE_P709, _0_255, UNKNOWN, BT2020_12, BT470BG),
/* 2) RGB_FULL_G10_NONE_P709 */
MAKE_COLOR_MAP (RGB_FULL_G10_NONE_P709, _0_255, UNKNOWN, GAMMA10, BT709),
/* 2-1 ) Approximation for RGB_FULL_G10_NONE_P709 */
MAKE_COLOR_MAP (RGB_FULL_G10_NONE_P709, _0_255, UNKNOWN, GAMMA10, BT470BG),
/* 3) RGB_STUDIO_G22_NONE_P709 */
MAKE_COLOR_MAP (RGB_STUDIO_G22_NONE_P709, _16_235, UNKNOWN, BT709, BT709),
MAKE_COLOR_MAP (RGB_STUDIO_G22_NONE_P709, _16_235, UNKNOWN, BT601, BT709),
MAKE_COLOR_MAP (RGB_STUDIO_G22_NONE_P709, _16_235, UNKNOWN, BT2020_10, BT709),
MAKE_COLOR_MAP (RGB_STUDIO_G22_NONE_P709, _16_235, UNKNOWN, BT2020_12, BT709),
/* 3-1) Approximation for RGB_STUDIO_G22_NONE_P709 */
MAKE_COLOR_MAP (RGB_STUDIO_G22_NONE_P709, _16_235, UNKNOWN, BT709, BT470BG),
MAKE_COLOR_MAP (RGB_STUDIO_G22_NONE_P709, _16_235, UNKNOWN, BT601, BT470BG),
MAKE_COLOR_MAP (RGB_STUDIO_G22_NONE_P709, _16_235, UNKNOWN, BT2020_10,
BT470BG),
MAKE_COLOR_MAP (RGB_STUDIO_G22_NONE_P709, _16_235, UNKNOWN, BT2020_12,
BT470BG),
MAKE_COLOR_MAP (RGB_STUDIO_G22_NONE_P709, _16_235, UNKNOWN, SRGB, BT709),
MAKE_COLOR_MAP (RGB_STUDIO_G22_NONE_P709, _16_235, UNKNOWN, SRGB, BT470BG),
/* 4) RGB_STUDIO_G22_NONE_P2020 */
MAKE_COLOR_MAP (RGB_STUDIO_G22_NONE_P2020, _16_235, UNKNOWN, BT709, BT2020),
MAKE_COLOR_MAP (RGB_STUDIO_G22_NONE_P2020, _16_235, UNKNOWN, BT601, BT2020),
MAKE_COLOR_MAP (RGB_STUDIO_G22_NONE_P2020, _16_235, UNKNOWN, BT2020_10,
BT2020),
MAKE_COLOR_MAP (RGB_STUDIO_G22_NONE_P2020, _16_235, UNKNOWN, BT2020_12,
BT2020),
/* 5) RGB_FULL_G2084_NONE_P2020 */
MAKE_COLOR_MAP (RGB_FULL_G2084_NONE_P2020, _0_255, UNKNOWN, SMPTE2084,
BT2020),
/* 6) RGB_STUDIO_G2084_NONE_P2020 */
MAKE_COLOR_MAP (RGB_STUDIO_G2084_NONE_P2020, _16_235, UNKNOWN, SMPTE2084,
BT2020),
/* 7) RGB_FULL_G22_NONE_P2020 */
MAKE_COLOR_MAP (RGB_FULL_G22_NONE_P2020, _0_255, UNKNOWN, BT709, BT2020),
MAKE_COLOR_MAP (RGB_FULL_G22_NONE_P2020, _0_255, UNKNOWN, BT601, BT2020),
MAKE_COLOR_MAP (RGB_FULL_G22_NONE_P2020, _0_255, UNKNOWN, BT2020_10, BT2020),
MAKE_COLOR_MAP (RGB_FULL_G22_NONE_P2020, _0_255, UNKNOWN, BT2020_12, BT2020),
/* 7-1) Approximation for RGB_FULL_G22_NONE_P2020 */
MAKE_COLOR_MAP (RGB_FULL_G22_NONE_P2020, _0_255, UNKNOWN, SRGB, BT2020),
/* 8) RGB_STUDIO_G24_NONE_P709 */
MAKE_COLOR_MAP (RGB_STUDIO_G24_NONE_P709, _16_235, UNKNOWN, SRGB, BT709),
/* 8-1) Approximation for RGB_STUDIO_G24_NONE_P709 */
MAKE_COLOR_MAP (RGB_STUDIO_G24_NONE_P709, _16_235, UNKNOWN, SRGB, BT470BG),
/* 9) RGB_STUDIO_G24_NONE_P2020 */
MAKE_COLOR_MAP (RGB_STUDIO_G24_NONE_P2020, _16_235, UNKNOWN, SRGB, BT2020),
};
static const GstDxgiColorSpace yuv_colorspace_map[] = {
/* 1) YCBCR_FULL_G22_NONE_P709_X601
* 2) YCBCR_STUDIO_G22_LEFT_P601
* 3) YCBCR_FULL_G22_LEFT_P601
* 4) YCBCR_STUDIO_G22_LEFT_P709
* 5) YCBCR_FULL_G22_LEFT_P709
* 6) YCBCR_STUDIO_G22_LEFT_P2020
* 7) YCBCR_FULL_G22_LEFT_P2020
* 8) YCBCR_STUDIO_G2084_LEFT_P2020
* 9) YCBCR_STUDIO_G22_TOPLEFT_P2020
* 10) YCBCR_STUDIO_G2084_TOPLEFT_P2020
* 11) YCBCR_STUDIO_GHLG_TOPLEFT_P2020
* 12) YCBCR_FULL_GHLG_TOPLEFT_P2020
* 13) YCBCR_STUDIO_G24_LEFT_P709
* 14) YCBCR_STUDIO_G24_LEFT_P2020
* 15) YCBCR_STUDIO_G24_TOPLEFT_P2020
*
* NOTE: BT470BG ~= BT709
*/
/* 1) YCBCR_FULL_G22_NONE_P709_X601 */
MAKE_COLOR_MAP (YCBCR_FULL_G22_NONE_P709_X601, _0_255, BT601, BT709, BT709),
MAKE_COLOR_MAP (YCBCR_FULL_G22_NONE_P709_X601, _0_255, BT601, BT601, BT709),
MAKE_COLOR_MAP (YCBCR_FULL_G22_NONE_P709_X601, _0_255, BT601, BT2020_10,
BT709),
MAKE_COLOR_MAP (YCBCR_FULL_G22_NONE_P709_X601, _0_255, BT601, BT2020_12,
BT709),
MAKE_COLOR_MAP (YCBCR_FULL_G22_NONE_P709_X601, _0_255, BT601, BT709, BT470BG),
MAKE_COLOR_MAP (YCBCR_FULL_G22_NONE_P709_X601, _0_255, BT601, BT601, BT470BG),
MAKE_COLOR_MAP (YCBCR_FULL_G22_NONE_P709_X601, _0_255, BT601, BT2020_10,
BT470BG),
MAKE_COLOR_MAP (YCBCR_FULL_G22_NONE_P709_X601, _0_255, BT601, BT2020_12,
BT470BG),
/* 2) YCBCR_STUDIO_G22_LEFT_P601 */
MAKE_COLOR_MAP (YCBCR_STUDIO_G22_LEFT_P601, _16_235, BT601, BT601, SMPTE170M),
MAKE_COLOR_MAP (YCBCR_STUDIO_G22_LEFT_P601, _16_235, BT601, BT709, SMPTE170M),
MAKE_COLOR_MAP (YCBCR_STUDIO_G22_LEFT_P601, _16_235, BT601, BT2020_10,
SMPTE170M),
MAKE_COLOR_MAP (YCBCR_STUDIO_G22_LEFT_P601, _16_235, BT601, BT2020_12,
SMPTE170M),
MAKE_COLOR_MAP (YCBCR_STUDIO_G22_LEFT_P601, _16_235, BT601, BT601, SMPTE240M),
MAKE_COLOR_MAP (YCBCR_STUDIO_G22_LEFT_P601, _16_235, BT601, BT709, SMPTE240M),
MAKE_COLOR_MAP (YCBCR_STUDIO_G22_LEFT_P601, _16_235, BT601, BT2020_10,
SMPTE240M),
MAKE_COLOR_MAP (YCBCR_STUDIO_G22_LEFT_P601, _16_235, BT601, BT2020_12,
SMPTE240M),
/* 3) YCBCR_FULL_G22_LEFT_P601 */
MAKE_COLOR_MAP (YCBCR_FULL_G22_LEFT_P601, _0_255, BT601, BT601, SMPTE170M),
MAKE_COLOR_MAP (YCBCR_FULL_G22_LEFT_P601, _0_255, BT601, BT709, SMPTE170M),
MAKE_COLOR_MAP (YCBCR_FULL_G22_LEFT_P601, _0_255, BT601, BT2020_10,
SMPTE170M),
MAKE_COLOR_MAP (YCBCR_FULL_G22_LEFT_P601, _0_255, BT601, BT2020_12,
SMPTE170M),
MAKE_COLOR_MAP (YCBCR_FULL_G22_LEFT_P601, _0_255, BT601, BT601, SMPTE240M),
MAKE_COLOR_MAP (YCBCR_FULL_G22_LEFT_P601, _0_255, BT601, BT709, SMPTE240M),
MAKE_COLOR_MAP (YCBCR_FULL_G22_LEFT_P601, _0_255, BT601, BT2020_10,
SMPTE240M),
MAKE_COLOR_MAP (YCBCR_FULL_G22_LEFT_P601, _0_255, BT601, BT2020_12,
SMPTE240M),
/* 4) YCBCR_STUDIO_G22_LEFT_P709 */
MAKE_COLOR_MAP (YCBCR_STUDIO_G22_LEFT_P709, _16_235, BT709, BT709, BT709),
MAKE_COLOR_MAP (YCBCR_STUDIO_G22_LEFT_P709, _16_235, BT709, BT601, BT709),
MAKE_COLOR_MAP (YCBCR_STUDIO_G22_LEFT_P709, _16_235, BT709, BT2020_10,
BT709),
MAKE_COLOR_MAP (YCBCR_STUDIO_G22_LEFT_P709, _16_235, BT709, BT2020_12,
BT709),
MAKE_COLOR_MAP (YCBCR_STUDIO_G22_LEFT_P709, _16_235, BT709, BT709, BT470BG),
MAKE_COLOR_MAP (YCBCR_STUDIO_G22_LEFT_P709, _16_235, BT709, BT601, BT470BG),
MAKE_COLOR_MAP (YCBCR_STUDIO_G22_LEFT_P709, _16_235, BT709, BT2020_10,
BT470BG),
MAKE_COLOR_MAP (YCBCR_STUDIO_G22_LEFT_P709, _16_235, BT709, BT2020_12,
BT470BG),
/* 5) YCBCR_FULL_G22_LEFT_P709 */
MAKE_COLOR_MAP (YCBCR_FULL_G22_LEFT_P709, _0_255, BT709, BT709, BT709),
MAKE_COLOR_MAP (YCBCR_FULL_G22_LEFT_P709, _0_255, BT709, BT601, BT709),
MAKE_COLOR_MAP (YCBCR_FULL_G22_LEFT_P709, _0_255, BT709, BT2020_10, BT709),
MAKE_COLOR_MAP (YCBCR_FULL_G22_LEFT_P709, _0_255, BT709, BT2020_12, BT709),
MAKE_COLOR_MAP (YCBCR_FULL_G22_LEFT_P709, _0_255, BT709, BT709, BT470BG),
MAKE_COLOR_MAP (YCBCR_FULL_G22_LEFT_P709, _0_255, BT709, BT601, BT470BG),
MAKE_COLOR_MAP (YCBCR_FULL_G22_LEFT_P709, _0_255, BT709, BT2020_10, BT470BG),
MAKE_COLOR_MAP (YCBCR_FULL_G22_LEFT_P709, _0_255, BT709, BT2020_12, BT470BG),
/* 6) YCBCR_STUDIO_G22_LEFT_P2020 */
MAKE_COLOR_MAP (YCBCR_STUDIO_G22_LEFT_P2020, _16_235, BT2020, BT709, BT2020),
MAKE_COLOR_MAP (YCBCR_STUDIO_G22_LEFT_P2020, _16_235, BT2020, BT601, BT2020),
MAKE_COLOR_MAP (YCBCR_STUDIO_G22_LEFT_P2020, _16_235, BT2020, BT2020_10,
BT2020),
MAKE_COLOR_MAP (YCBCR_STUDIO_G22_LEFT_P2020, _16_235, BT2020, BT2020_12,
BT2020),
/* 7) YCBCR_FULL_G22_LEFT_P2020 */
MAKE_COLOR_MAP (YCBCR_FULL_G22_LEFT_P2020, _0_255, BT2020, BT709, BT2020),
MAKE_COLOR_MAP (YCBCR_FULL_G22_LEFT_P2020, _0_255, BT2020, BT601, BT2020),
MAKE_COLOR_MAP (YCBCR_FULL_G22_LEFT_P2020, _0_255, BT2020, BT2020_10,
BT2020),
MAKE_COLOR_MAP (YCBCR_FULL_G22_LEFT_P2020, _0_255, BT2020, BT2020_12,
BT2020),
/* 8) YCBCR_STUDIO_G2084_LEFT_P2020 */
MAKE_COLOR_MAP (YCBCR_STUDIO_G2084_LEFT_P2020, _16_235, BT2020, SMPTE2084,
BT2020),
/* 9) YCBCR_STUDIO_G22_TOPLEFT_P2020 */
MAKE_COLOR_MAP (YCBCR_STUDIO_G22_TOPLEFT_P2020, _16_235, BT2020, BT2020_10,
BT2020),
MAKE_COLOR_MAP (YCBCR_STUDIO_G22_TOPLEFT_P2020, _16_235, BT2020, BT2020_12,
BT2020),
/* 10) YCBCR_STUDIO_G2084_TOPLEFT_P2020 */
/* FIXME: check chroma-site to differentiate this from
* YCBCR_STUDIO_G2084_LEFT_P2020 */
MAKE_COLOR_MAP (YCBCR_STUDIO_G2084_TOPLEFT_P2020, _16_235, BT2020, SMPTE2084,
BT2020),
/* 11) YCBCR_STUDIO_GHLG_TOPLEFT_P2020 */
MAKE_COLOR_MAP (YCBCR_STUDIO_GHLG_TOPLEFT_P2020, _16_235, BT2020,
ARIB_STD_B67, BT2020),
/* 12) YCBCR_FULL_GHLG_TOPLEFT_P2020 */
MAKE_COLOR_MAP (YCBCR_FULL_GHLG_TOPLEFT_P2020, _0_255, BT2020, ARIB_STD_B67,
BT2020),
/* 13) YCBCR_STUDIO_G24_LEFT_P709 */
MAKE_COLOR_MAP (YCBCR_STUDIO_G24_LEFT_P709, _16_235, BT709, SRGB, BT709),
/* 14) YCBCR_STUDIO_G24_LEFT_P2020 */
MAKE_COLOR_MAP (YCBCR_STUDIO_G24_LEFT_P2020, _16_235, BT2020, SRGB, BT2020),
/* 15) YCBCR_STUDIO_G24_TOPLEFT_P2020 */
/* FIXME: check chroma-site to differentiate this from
* YCBCR_STUDIO_G24_LEFT_P2020 */
MAKE_COLOR_MAP (YCBCR_STUDIO_G24_TOPLEFT_P2020, _16_235, BT2020, SRGB,
BT2020),
};
#define SCORE_RANGE_MISMATCH 5
#define SCORE_MATRIX_MISMATCH 5
#define SCORE_TRANSFER_MISMATCH 5
#define SCORE_PRIMARY_MISMATCH 10
static gint
get_score (const GstVideoInfo * info, const GstDxgiColorSpace * color_map,
gboolean is_yuv)
{
gint loss = 0;
const GstVideoColorimetry *color = &info->colorimetry;
if (color->range != color_map->range)
loss += SCORE_RANGE_MISMATCH;
if (is_yuv && color->matrix != color_map->matrix)
loss += SCORE_MATRIX_MISMATCH;
if (color->transfer != color_map->transfer)
loss += SCORE_TRANSFER_MISMATCH;
if (color->primaries != color_map->primaries)
loss += SCORE_PRIMARY_MISMATCH;
return loss;
}
static gboolean
gst_d3d11_video_info_to_dxgi_color_space_rgb (const GstVideoInfo * info,
GstDxgiColorSpace * color_space)
{
gint best_score = G_MAXINT;
gint score;
guint i;
const GstDxgiColorSpace *best = nullptr;
for (i = 0; i < G_N_ELEMENTS (rgb_colorspace_map); i++) {
score = get_score (info, &rgb_colorspace_map[i], FALSE);
if (score < best_score) {
best_score = score;
best = &rgb_colorspace_map[i];
if (score == 0) {
*color_space = rgb_colorspace_map[i];
return TRUE;
}
}
}
if (best) {
*color_space = *best;
return TRUE;
}
return FALSE;
}
static gboolean
gst_d3d11_video_info_to_dxgi_color_space_yuv (const GstVideoInfo * info,
GstDxgiColorSpace * color_space)
{
gint best_score = G_MAXINT;
gint score;
guint i;
const GstDxgiColorSpace *best = nullptr;
for (i = 0; i < G_N_ELEMENTS (yuv_colorspace_map); i++) {
score = get_score (info, &yuv_colorspace_map[i], TRUE);
if (score < best_score) {
best_score = score;
best = &yuv_colorspace_map[i];
if (score == 0) {
*color_space = rgb_colorspace_map[i];
return TRUE;
}
}
}
if (best) {
*color_space = *best;
return TRUE;
}
return FALSE;
}
gboolean
gst_d3d11_video_info_to_dxgi_color_space (const GstVideoInfo * info,
GstDxgiColorSpace * color_space)
{
g_return_val_if_fail (info != nullptr, FALSE);
g_return_val_if_fail (color_space != nullptr, FALSE);
if (GST_VIDEO_INFO_IS_RGB (info))
return gst_d3d11_video_info_to_dxgi_color_space_rgb (info, color_space);
return gst_d3d11_video_info_to_dxgi_color_space_yuv (info, color_space);
}
gboolean
gst_d3d11_colorimetry_from_dxgi_color_space (DXGI_COLOR_SPACE_TYPE colorspace,
GstVideoColorimetry * colorimetry)
{
/* XXX: because of ancient MinGW header */
GST_DXGI_COLOR_SPACE_TYPE type = (GST_DXGI_COLOR_SPACE_TYPE) colorspace;
GstVideoColorimetry color;
switch (type) {
case GST_DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709:
color.range = GST_VIDEO_COLOR_RANGE_0_255;
color.matrix = GST_VIDEO_COLOR_MATRIX_RGB;
color.transfer = GST_VIDEO_TRANSFER_SRGB;
color.primaries = GST_VIDEO_COLOR_PRIMARIES_BT709;
break;
case GST_DXGI_COLOR_SPACE_RGB_FULL_G10_NONE_P709:
color.range = GST_VIDEO_COLOR_RANGE_0_255;
color.matrix = GST_VIDEO_COLOR_MATRIX_RGB;
color.transfer = GST_VIDEO_TRANSFER_GAMMA10;
color.primaries = GST_VIDEO_COLOR_PRIMARIES_BT709;
break;
case GST_DXGI_COLOR_SPACE_RGB_STUDIO_G22_NONE_P709:
color.range = GST_VIDEO_COLOR_RANGE_16_235;
color.matrix = GST_VIDEO_COLOR_MATRIX_RGB;
color.transfer = GST_VIDEO_TRANSFER_BT709;
color.primaries = GST_VIDEO_COLOR_PRIMARIES_BT709;
break;
case GST_DXGI_COLOR_SPACE_RGB_STUDIO_G22_NONE_P2020:
color.range = GST_VIDEO_COLOR_RANGE_16_235;
color.matrix = GST_VIDEO_COLOR_MATRIX_RGB;
color.transfer = GST_VIDEO_TRANSFER_BT2020_10;
color.primaries = GST_VIDEO_COLOR_PRIMARIES_BT2020;
break;
case GST_DXGI_COLOR_SPACE_YCBCR_FULL_G22_NONE_P709_X601:
color.range = GST_VIDEO_COLOR_RANGE_0_255;
color.matrix = GST_VIDEO_COLOR_MATRIX_BT601;
color.transfer = GST_VIDEO_TRANSFER_BT601;
color.primaries = GST_VIDEO_COLOR_PRIMARIES_BT709;
break;
case GST_DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P601:
color.range = GST_VIDEO_COLOR_RANGE_16_235;
color.matrix = GST_VIDEO_COLOR_MATRIX_BT601;
color.transfer = GST_VIDEO_TRANSFER_BT601;
color.primaries = GST_VIDEO_COLOR_PRIMARIES_SMPTE170M;
break;
case GST_DXGI_COLOR_SPACE_YCBCR_FULL_G22_LEFT_P601:
color.range = GST_VIDEO_COLOR_RANGE_0_255;
color.matrix = GST_VIDEO_COLOR_MATRIX_BT601;
color.transfer = GST_VIDEO_TRANSFER_BT601;
color.primaries = GST_VIDEO_COLOR_PRIMARIES_SMPTE170M;
break;
case GST_DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P709:
color.range = GST_VIDEO_COLOR_RANGE_16_235;
color.matrix = GST_VIDEO_COLOR_MATRIX_BT709;
color.transfer = GST_VIDEO_TRANSFER_BT709;
color.primaries = GST_VIDEO_COLOR_PRIMARIES_BT709;
break;
case GST_DXGI_COLOR_SPACE_YCBCR_FULL_G22_LEFT_P709:
color.range = GST_VIDEO_COLOR_RANGE_0_255;
color.matrix = GST_VIDEO_COLOR_MATRIX_BT709;
color.transfer = GST_VIDEO_TRANSFER_BT709;
color.primaries = GST_VIDEO_COLOR_PRIMARIES_BT709;
break;
case GST_DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P2020:
color.range = GST_VIDEO_COLOR_RANGE_16_235;
color.matrix = GST_VIDEO_COLOR_MATRIX_BT2020;
color.transfer = GST_VIDEO_TRANSFER_BT2020_10;
color.primaries = GST_VIDEO_COLOR_PRIMARIES_BT2020;
break;
case GST_DXGI_COLOR_SPACE_YCBCR_FULL_G22_LEFT_P2020:
color.range = GST_VIDEO_COLOR_RANGE_0_255;
color.matrix = GST_VIDEO_COLOR_MATRIX_BT2020;
color.transfer = GST_VIDEO_TRANSFER_BT2020_10;
color.primaries = GST_VIDEO_COLOR_PRIMARIES_BT2020;
break;
case GST_DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020:
color.range = GST_VIDEO_COLOR_RANGE_0_255;
color.matrix = GST_VIDEO_COLOR_MATRIX_RGB;
color.transfer = GST_VIDEO_TRANSFER_SMPTE2084;
color.primaries = GST_VIDEO_COLOR_PRIMARIES_BT2020;
break;
case GST_DXGI_COLOR_SPACE_RGB_STUDIO_G2084_NONE_P2020:
color.range = GST_VIDEO_COLOR_RANGE_16_235;
color.matrix = GST_VIDEO_COLOR_MATRIX_RGB;
color.transfer = GST_VIDEO_TRANSFER_SMPTE2084;
color.primaries = GST_VIDEO_COLOR_PRIMARIES_BT2020;
break;
case GST_DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_TOPLEFT_P2020:
color.range = GST_VIDEO_COLOR_RANGE_16_235;
color.matrix = GST_VIDEO_COLOR_MATRIX_BT2020;
color.transfer = GST_VIDEO_TRANSFER_BT2020_10;
color.primaries = GST_VIDEO_COLOR_PRIMARIES_BT2020;
break;
case GST_DXGI_COLOR_SPACE_YCBCR_STUDIO_G2084_TOPLEFT_P2020:
color.range = GST_VIDEO_COLOR_RANGE_16_235;
color.matrix = GST_VIDEO_COLOR_MATRIX_BT2020;
color.transfer = GST_VIDEO_TRANSFER_SMPTE2084;
color.primaries = GST_VIDEO_COLOR_PRIMARIES_BT2020;
break;
case GST_DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P2020:
color.range = GST_VIDEO_COLOR_RANGE_0_255;
color.matrix = GST_VIDEO_COLOR_MATRIX_RGB;
color.transfer = GST_VIDEO_TRANSFER_SMPTE2084;
color.primaries = GST_VIDEO_COLOR_PRIMARIES_BT2020;
break;
case GST_DXGI_COLOR_SPACE_YCBCR_STUDIO_GHLG_TOPLEFT_P2020:
color.range = GST_VIDEO_COLOR_RANGE_16_235;
color.matrix = GST_VIDEO_COLOR_MATRIX_BT2020;
color.transfer = GST_VIDEO_TRANSFER_ARIB_STD_B67;
color.primaries = GST_VIDEO_COLOR_PRIMARIES_BT2020;
break;
case GST_DXGI_COLOR_SPACE_YCBCR_FULL_GHLG_TOPLEFT_P2020:
color.range = GST_VIDEO_COLOR_RANGE_0_255;
color.matrix = GST_VIDEO_COLOR_MATRIX_BT2020;
color.transfer = GST_VIDEO_TRANSFER_ARIB_STD_B67;
color.primaries = GST_VIDEO_COLOR_PRIMARIES_BT2020;
break;
case GST_DXGI_COLOR_SPACE_RGB_STUDIO_G24_NONE_P709:
color.range = GST_VIDEO_COLOR_RANGE_16_235;
color.matrix = GST_VIDEO_COLOR_MATRIX_RGB;
color.transfer = GST_VIDEO_TRANSFER_SRGB;
color.primaries = GST_VIDEO_COLOR_PRIMARIES_BT709;
break;
case GST_DXGI_COLOR_SPACE_RGB_STUDIO_G24_NONE_P2020:
color.range = GST_VIDEO_COLOR_RANGE_16_235;
color.matrix = GST_VIDEO_COLOR_MATRIX_RGB;
color.transfer = GST_VIDEO_TRANSFER_SRGB;
color.primaries = GST_VIDEO_COLOR_PRIMARIES_BT2020;
break;
case GST_DXGI_COLOR_SPACE_YCBCR_STUDIO_G24_LEFT_P709:
color.range = GST_VIDEO_COLOR_RANGE_16_235;
color.matrix = GST_VIDEO_COLOR_MATRIX_RGB;
color.transfer = GST_VIDEO_TRANSFER_SRGB;
color.primaries = GST_VIDEO_COLOR_PRIMARIES_BT709;
break;
case GST_DXGI_COLOR_SPACE_YCBCR_STUDIO_G24_LEFT_P2020:
case GST_DXGI_COLOR_SPACE_YCBCR_STUDIO_G24_TOPLEFT_P2020:
color.range = GST_VIDEO_COLOR_RANGE_16_235;
color.matrix = GST_VIDEO_COLOR_MATRIX_RGB;
color.transfer = GST_VIDEO_TRANSFER_SRGB;
color.primaries = GST_VIDEO_COLOR_PRIMARIES_BT2020;
break;
default:
return FALSE;
}
*colorimetry = color;
return TRUE;
}
gboolean
gst_d3d11_find_swap_chain_color_space (const GstVideoInfo * info,
IDXGISwapChain3 * swapchain, GstDxgiColorSpace * color_space)
IDXGISwapChain3 * swapchain, DXGI_COLOR_SPACE_TYPE * color_space)
{
UINT can_support = 0;
HRESULT hr;
DXGI_COLOR_SPACE_TYPE color;
g_return_val_if_fail (info != NULL, FALSE);
g_return_val_if_fail (swapchain != NULL, FALSE);
@ -693,30 +183,19 @@ gst_d3d11_find_swap_chain_color_space (const GstVideoInfo * info,
/* Select PQ color space only if input is also PQ */
if (info->colorimetry.primaries == GST_VIDEO_COLOR_PRIMARIES_BT2020 &&
info->colorimetry.transfer == GST_VIDEO_TRANSFER_SMPTE2084) {
guint pq = GST_DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020;
hr = swapchain->CheckColorSpaceSupport ((DXGI_COLOR_SPACE_TYPE) pq,
&can_support);
color = (DXGI_COLOR_SPACE_TYPE) 12;
hr = swapchain->CheckColorSpaceSupport (color, &can_support);
if (SUCCEEDED (hr) && can_support) {
color_space->dxgi_color_space_type = pq;
color_space->range = GST_VIDEO_COLOR_RANGE_0_255;
color_space->matrix = GST_VIDEO_COLOR_MATRIX_RGB;
color_space->transfer = GST_VIDEO_TRANSFER_SMPTE2084;
color_space->primaries = GST_VIDEO_COLOR_PRIMARIES_BT2020;
*color_space = color;
return TRUE;
}
}
/* otherwise use standard sRGB color space */
hr = swapchain->CheckColorSpaceSupport (
(DXGI_COLOR_SPACE_TYPE) GST_DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709,
&can_support);
color = (DXGI_COLOR_SPACE_TYPE) 0;
hr = swapchain->CheckColorSpaceSupport (color, &can_support);
if (SUCCEEDED (hr) && can_support) {
color_space->dxgi_color_space_type =
GST_DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709;
color_space->range = GST_VIDEO_COLOR_RANGE_0_255;
color_space->matrix = GST_VIDEO_COLOR_MATRIX_RGB;
color_space->transfer = GST_VIDEO_TRANSFER_SRGB;
color_space->primaries = GST_VIDEO_COLOR_PRIMARIES_BT709;
*color_space = color;
return TRUE;
}

View file

@ -38,15 +38,6 @@ typedef enum
GST_D3D11_DEVICE_VENDOR_XBOX,
} GstD3D11DeviceVendor;
typedef struct _GstDxgiColorSpace
{
guint dxgi_color_space_type;
GstVideoColorRange range;
GstVideoColorMatrix matrix;
GstVideoTransferFunction transfer;
GstVideoColorPrimaries primaries;
} GstDxgiColorSpace;
typedef struct _GstD3D11ColorMatrix
{
gdouble matrix[3][3];
@ -67,15 +58,9 @@ gboolean gst_d3d11_hdr_meta_data_to_dxgi (GstVideoMasteringDisplayInf
GstVideoContentLightLevel * cll,
DXGI_HDR_METADATA_HDR10 * dxgi_hdr10);
gboolean gst_d3d11_video_info_to_dxgi_color_space (const GstVideoInfo * info,
GstDxgiColorSpace * color_space);
gboolean gst_d3d11_colorimetry_from_dxgi_color_space (DXGI_COLOR_SPACE_TYPE colorspace,
GstVideoColorimetry * colorimetry);
gboolean gst_d3d11_find_swap_chain_color_space (const GstVideoInfo * info,
IDXGISwapChain3 * swapchain,
GstDxgiColorSpace * color_space);
DXGI_COLOR_SPACE_TYPE * color_space);
GstBuffer * gst_d3d11_allocate_staging_buffer_for (GstBuffer * buffer,
const GstVideoInfo * info,

View file

@ -1843,6 +1843,7 @@ gst_d3d11_screen_capture_get_colorimetry (GstD3D11ScreenCapture * capture,
GstVideoColorimetry * colorimetry)
{
DXGI_COLOR_SPACE_TYPE dxgi_cs;
GstVideoInfo info;
g_return_val_if_fail (GST_IS_D3D11_SCREEN_CAPTURE (capture), FALSE);
g_return_val_if_fail (colorimetry != nullptr, FALSE);
@ -1862,7 +1863,13 @@ gst_d3d11_screen_capture_get_colorimetry (GstD3D11ScreenCapture * capture,
dxgi_cs = desc.ColorSpace;
}
return gst_d3d11_colorimetry_from_dxgi_color_space (dxgi_cs, colorimetry);
gst_video_info_set_format (&info, GST_VIDEO_FORMAT_BGRA, 16, 16);
if (gst_video_info_apply_dxgi_color_space (dxgi_cs, &info)) {
*colorimetry = info.colorimetry;
return TRUE;
}
return FALSE;
}
GstFlowReturn

View file

@ -448,12 +448,10 @@ gst_d3d11_window_prepare_default (GstD3D11Window * window, guint display_width,
{DXGI_FORMAT_R10G10B10A2_UNORM, GST_VIDEO_FORMAT_RGB10A2_LE, FALSE},
};
const GstD3D11WindowDisplayFormat *chosen_format = NULL;
GstDxgiColorSpace swapchain_colorspace;
gboolean found_swapchain_colorspace = FALSE;
DXGI_COLOR_SPACE_TYPE swapchain_colorspace =
DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709;
gboolean hdr10_aware = FALSE;
gboolean have_hdr10_meta = FALSE;
DXGI_COLOR_SPACE_TYPE native_colorspace_type =
DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709;
ComPtr < IDXGIFactory5 > factory5;
IDXGIFactory1 *factory_handle;
BOOL allow_tearing = FALSE;
@ -603,34 +601,19 @@ gst_d3d11_window_prepare_default (GstD3D11Window * window, guint display_width,
hr = window->swap_chain->QueryInterface (IID_PPV_ARGS (&swapchain3));
if (gst_d3d11_result (hr, device)) {
found_swapchain_colorspace =
gst_d3d11_find_swap_chain_color_space (&window->render_info,
swapchain3.Get (), &swapchain_colorspace);
if (found_swapchain_colorspace) {
native_colorspace_type =
(DXGI_COLOR_SPACE_TYPE) swapchain_colorspace.dxgi_color_space_type;
hr = swapchain3->SetColorSpace1 (native_colorspace_type);
if (gst_d3d11_find_swap_chain_color_space (&window->render_info,
swapchain3.Get (), &swapchain_colorspace)) {
hr = swapchain3->SetColorSpace1 (swapchain_colorspace);
if (!gst_d3d11_result (hr, window->device)) {
GST_WARNING_OBJECT (window, "Failed to set colorspace %d, hr: 0x%x",
native_colorspace_type, (guint) hr);
found_swapchain_colorspace = FALSE;
native_colorspace_type = DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709;
swapchain_colorspace, (guint) hr);
swapchain_colorspace = DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709;
} else {
ComPtr < IDXGISwapChain4 > swapchain4;
GST_DEBUG_OBJECT (window, "Set colorspace %d", native_colorspace_type);
/* update with selected display color space */
window->render_info.colorimetry.primaries =
swapchain_colorspace.primaries;
window->render_info.colorimetry.transfer =
swapchain_colorspace.transfer;
window->render_info.colorimetry.range = swapchain_colorspace.range;
window->render_info.colorimetry.matrix = swapchain_colorspace.matrix;
/* DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020 = 12, undefined in old
* mingw header */
if (native_colorspace_type == 12 && have_hdr10_meta) {
if (swapchain_colorspace == 12 && have_hdr10_meta) {
hr = swapchain3.As (&swapchain4);
if (gst_d3d11_result (hr, device)) {
DXGI_HDR_METADATA_HDR10 hdr10_metadata = { 0, };
@ -654,15 +637,11 @@ gst_d3d11_window_prepare_default (GstD3D11Window * window, guint display_width,
}
}
/* otherwise, use most common DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709
* color space */
if (!found_swapchain_colorspace) {
GST_DEBUG_OBJECT (window, "No selected render color space, use BT709");
window->render_info.colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_BT709;
window->render_info.colorimetry.transfer = GST_VIDEO_TRANSFER_BT709;
window->render_info.colorimetry.range = GST_VIDEO_COLOR_RANGE_0_255;
window->render_info.colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_RGB;
}
GST_DEBUG_OBJECT (window, "Set colorspace %d", swapchain_colorspace);
/* update with selected display color space */
gst_video_info_apply_dxgi_color_space (swapchain_colorspace,
&window->render_info);
window->converter = gst_d3d11_converter_new (device,
&window->info, &window->render_info, nullptr);