d3d11format: Add util methods for mapping DXGI color space with ours

Move color space mapping and hdr10 metadata conversion methods to
d3d11format in order to reuse the code.
This commit is contained in:
Seungha Yang 2020-01-29 17:29:04 +09:00 committed by GStreamer Merge Bot
parent 4b72e8cad5
commit a967db3b20
4 changed files with 401 additions and 214 deletions

View file

@ -26,6 +26,8 @@
#include "gstd3d11device.h"
#include "gstd3d11memory.h"
#include <string.h>
GST_DEBUG_CATEGORY_EXTERN (gst_d3d11_format_debug);
#define GST_CAT_DEFAULT gst_d3d11_format_debug
@ -164,3 +166,344 @@ gst_d3d11_device_get_supported_caps (GstD3D11Device * device,
return supported_caps;
}
#if (DXGI_HEADER_VERSION >= 5)
static inline UINT16
fraction_to_uint (guint num, guint den, guint scale)
{
gdouble val;
gst_util_fraction_to_double (num, den, &val);
return (UINT16) val *scale;
}
gboolean
gst_d3d11_hdr_meta_data_to_dxgi (GstVideoMasteringDisplayInfo * minfo,
GstVideoContentLightLevel * cll, DXGI_HDR_METADATA_HDR10 * dxgi_hdr10)
{
g_return_val_if_fail (dxgi_hdr10 != NULL, FALSE);
memset (dxgi_hdr10, 0, sizeof (DXGI_HDR_METADATA_HDR10));
if (minfo) {
dxgi_hdr10->RedPrimary[0] =
fraction_to_uint (minfo->Rx_n, minfo->Rx_d, 50000);
dxgi_hdr10->RedPrimary[1] =
fraction_to_uint (minfo->Ry_n, minfo->Ry_d, 50000);
dxgi_hdr10->GreenPrimary[0] =
fraction_to_uint (minfo->Gx_n, minfo->Gx_d, 50000);
dxgi_hdr10->GreenPrimary[1] =
fraction_to_uint (minfo->Gy_n, minfo->Gy_d, 50000);
dxgi_hdr10->BluePrimary[0] =
fraction_to_uint (minfo->Bx_n, minfo->Bx_d, 50000);
dxgi_hdr10->BluePrimary[1] =
fraction_to_uint (minfo->By_n, minfo->By_d, 50000);
dxgi_hdr10->WhitePoint[0] =
fraction_to_uint (minfo->Wx_n, minfo->Wx_d, 50000);
dxgi_hdr10->WhitePoint[1] =
fraction_to_uint (minfo->Wy_n, minfo->Wy_d, 50000);
dxgi_hdr10->MaxMasteringLuminance =
fraction_to_uint (minfo->max_luma_n, minfo->max_luma_d, 1);
dxgi_hdr10->MinMasteringLuminance =
fraction_to_uint (minfo->min_luma_n, minfo->min_luma_d, 1);
}
if (cll) {
dxgi_hdr10->MaxContentLightLevel =
fraction_to_uint (cll->maxCLL_n, cll->maxCLL_d, 1);
dxgi_hdr10->MaxFrameAverageLightLevel =
fraction_to_uint (cll->maxFALL_n, cll->maxFALL_d, 1);
}
return TRUE;
}
#endif
#if (DXGI_HEADER_VERSION >= 4)
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;
typedef struct
{
GST_DXGI_COLOR_SPACE_TYPE type;
GstVideoColorRange range;
GstVideoColorMatrix matrix;
GstVideoTransferFunction transfer;
GstVideoColorPrimaries primaries;
} DxgiColorSpaceMap;
/* 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 DxgiColorSpaceMap rgb_colorspace_map[] = {
/* RGB_FULL_G22_NONE_P709 */
MAKE_COLOR_MAP (RGB_FULL_G22_NONE_P709, _0_255, UNKNOWN, BT709, BT709),
/* RGB_FULL_G10_NONE_P709 */
MAKE_COLOR_MAP (RGB_FULL_G22_NONE_P709, _0_255, UNKNOWN, GAMMA10, BT709),
/* RGB_STUDIO_G22_NONE_P709 */
MAKE_COLOR_MAP (RGB_FULL_G22_NONE_P709, _16_235, UNKNOWN, BT709, BT709),
/* RGB_STUDIO_G22_NONE_P2020 */
MAKE_COLOR_MAP (RGB_FULL_G22_NONE_P709, _16_235, UNKNOWN, BT2020_10, BT2020),
MAKE_COLOR_MAP (RGB_FULL_G22_NONE_P709, _16_235, UNKNOWN, BT2020_12, BT2020),
/* RGB_FULL_G2084_NONE_P2020 */
MAKE_COLOR_MAP (RGB_FULL_G2084_NONE_P2020, _0_255, UNKNOWN, SMPTE2084,
BT2020),
/* RGB_STUDIO_G2084_NONE_P2020 */
MAKE_COLOR_MAP (RGB_STUDIO_G2084_NONE_P2020,
_16_235, UNKNOWN, SMPTE2084, BT2020),
/* RGB_FULL_G22_NONE_P2020 */
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),
/* RGB_STUDIO_G24_NONE_P709 */
MAKE_COLOR_MAP (RGB_STUDIO_G24_NONE_P709, _16_235, UNKNOWN, SRGB, BT709),
/* RGB_STUDIO_G24_NONE_P2020 */
MAKE_COLOR_MAP (RGB_STUDIO_G24_NONE_P709, _16_235, UNKNOWN, SRGB, BT2020),
};
static const DxgiColorSpaceMap yuv_colorspace_map[] = {
/* YCBCR_FULL_G22_NONE_P709_X601 */
MAKE_COLOR_MAP (YCBCR_FULL_G22_NONE_P709_X601, _0_255, BT601, BT709, BT709),
/* YCBCR_STUDIO_G22_LEFT_P601 */
MAKE_COLOR_MAP (YCBCR_STUDIO_G22_LEFT_P601, _16_235, BT601, BT709, SMPTE170M),
/* YCBCR_FULL_G22_LEFT_P601 */
MAKE_COLOR_MAP (YCBCR_FULL_G22_LEFT_P601, _0_255, BT601, BT709, SMPTE170M),
/* YCBCR_STUDIO_G22_LEFT_P709 */
MAKE_COLOR_MAP (YCBCR_STUDIO_G22_LEFT_P709, _16_235, BT709, BT709, BT709),
/* YCBCR_FULL_G22_LEFT_P709 */
MAKE_COLOR_MAP (YCBCR_FULL_G22_LEFT_P709, _0_255, BT709, BT709, BT709),
/* YCBCR_STUDIO_G22_LEFT_P2020 */
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),
/* YCBCR_FULL_G22_LEFT_P2020 */
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),
/* YCBCR_STUDIO_G2084_LEFT_P2020 */
MAKE_COLOR_MAP (YCBCR_STUDIO_G2084_LEFT_P2020, _16_235, BT2020, SMPTE2084,
BT2020),
/* 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),
/* 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),
/* YCBCR_STUDIO_GHLG_TOPLEFT_P2020 */
MAKE_COLOR_MAP (YCBCR_STUDIO_GHLG_TOPLEFT_P2020, _16_235, BT2020,
ARIB_STD_B67, BT2020),
/* YCBCR_STUDIO_GHLG_TOPLEFT_P2020 */
MAKE_COLOR_MAP (YCBCR_FULL_GHLG_TOPLEFT_P2020, _0_255, BT2020, ARIB_STD_B67,
BT2020),
/* YCBCR_STUDIO_G24_LEFT_P709 */
MAKE_COLOR_MAP (YCBCR_STUDIO_G22_LEFT_P709, _16_235, BT709, SRGB, BT709),
/* YCBCR_STUDIO_G24_LEFT_P2020 */
MAKE_COLOR_MAP (YCBCR_STUDIO_G24_LEFT_P2020, _16_235, BT2020, SRGB, BT2020),
/* 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 1
#define SCORE_MATRIX_MISMATCH 5
#define SCORE_TRANSFER_MISMATCH 5
#define SCORE_PRIMARY_MISMATCH 10
static gint
get_score (GstVideoInfo * info, const DxgiColorSpaceMap * color_map,
gboolean is_yuv)
{
gint loss = 0;
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 (GstVideoInfo * info,
DXGI_COLOR_SPACE_TYPE * colorspace)
{
gint best_score = G_MAXINT;
gint score, i;
GST_DXGI_COLOR_SPACE_TYPE type = GST_DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709;
for (i = 0; i < G_N_ELEMENTS (rgb_colorspace_map); i++) {
score = get_score (info, &rgb_colorspace_map[i], TRUE);
if (score < best_score) {
best_score = score;
type = rgb_colorspace_map[i].type;
if (score == 0)
break;
}
}
*colorspace = (DXGI_COLOR_SPACE_TYPE) type;
return TRUE;
}
static gboolean
gst_d3d11_video_info_to_dxgi_color_space_yuv (GstVideoInfo * info,
DXGI_COLOR_SPACE_TYPE * colorspace)
{
gint best_score = G_MAXINT;
gint score, i;
GST_DXGI_COLOR_SPACE_TYPE type =
GST_DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P709;
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;
type = yuv_colorspace_map[i].type;
if (score == 0)
break;
}
}
*colorspace = (DXGI_COLOR_SPACE_TYPE) type;
return TRUE;
}
gboolean
gst_d3d11_video_info_to_dxgi_color_space (GstVideoInfo * info,
DXGI_COLOR_SPACE_TYPE * colorspace)
{
g_return_val_if_fail (info != NULL, FALSE);
g_return_val_if_fail (colorspace != NULL, FALSE);
if (GST_VIDEO_INFO_IS_RGB (info)) {
return gst_d3d11_video_info_to_dxgi_color_space_rgb (info, colorspace);
} else if (GST_VIDEO_INFO_IS_YUV (info)) {
return gst_d3d11_video_info_to_dxgi_color_space_yuv (info, colorspace);
}
return FALSE;
}
gboolean
gst_d3d11_find_swap_chain_color_space (GstVideoInfo * info,
IDXGISwapChain3 * swapchain, DXGI_COLOR_SPACE_TYPE * colorspace)
{
GST_DXGI_COLOR_SPACE_TYPE best_type;
gint best_score = G_MAXINT;
gint i;
g_return_val_if_fail (info != NULL, FALSE);
g_return_val_if_fail (swapchain != NULL, FALSE);
g_return_val_if_fail (colorspace != NULL, FALSE);
if (!GST_VIDEO_INFO_IS_RGB (info)) {
GST_WARNING ("Swapchain colorspace should be RGB format");
return FALSE;
}
for (i = 0; i < G_N_ELEMENTS (rgb_colorspace_map); i++) {
UINT can_support = 0;
HRESULT hr;
gint score;
GST_DXGI_COLOR_SPACE_TYPE cur_type = rgb_colorspace_map[i].type;
hr = IDXGISwapChain3_CheckColorSpaceSupport (swapchain,
cur_type, &can_support);
if (FAILED (hr))
continue;
if ((can_support & DXGI_SWAP_CHAIN_COLOR_SPACE_SUPPORT_FLAG_PRESENT) ==
DXGI_SWAP_CHAIN_COLOR_SPACE_SUPPORT_FLAG_PRESENT) {
score = get_score (info, &rgb_colorspace_map[i], FALSE);
GST_DEBUG ("colorspace %d supported, score %d", cur_type, score);
if (score < best_score) {
best_score = score;
best_type = cur_type;
}
}
}
if (best_score == G_MAXINT)
return FALSE;
*colorspace = (DXGI_COLOR_SPACE_TYPE) best_type;
return TRUE;
}
#endif

View file

@ -55,6 +55,21 @@ gboolean gst_d3d11_dxgi_format_get_size (DXGI_FORMAT format,
GstCaps * gst_d3d11_device_get_supported_caps (GstD3D11Device * device,
D3D11_FORMAT_SUPPORT flags);
#if (DXGI_HEADER_VERSION >= 5)
gboolean gst_d3d11_hdr_meta_data_to_dxgi (GstVideoMasteringDisplayInfo * minfo,
GstVideoContentLightLevel * cll,
DXGI_HDR_METADATA_HDR10 * dxgi_hdr10);
#endif
#if (DXGI_HEADER_VERSION >= 4)
gboolean gst_d3d11_video_info_to_dxgi_color_space (GstVideoInfo * info,
DXGI_COLOR_SPACE_TYPE * colorspace);
gboolean gst_d3d11_find_swap_chain_color_space (GstVideoInfo * info,
IDXGISwapChain3 * swapchain,
DXGI_COLOR_SPACE_TYPE * colorspace);
#endif
G_END_DECLS
#endif /* __GST_D3D11_FORMAT_H__ */

View file

@ -404,167 +404,6 @@ gst_d3d11_window_on_mouse_event (GstD3D11Window * window, const gchar * event,
event, button, x, y);
}
#if (DXGI_HEADER_VERSION >= 5)
static inline UINT16
fraction_to_uint (guint num, guint den, guint scale)
{
gdouble val;
gst_util_fraction_to_double (num, den, &val);
return (UINT16) val *scale;
}
static void
mastering_display_gst_to_dxgi (GstVideoMasteringDisplayInfo * m,
GstVideoContentLightLevel * c, DXGI_HDR_METADATA_HDR10 * meta)
{
meta->RedPrimary[0] = fraction_to_uint (m->Rx_n, m->Rx_d, 50000);
meta->RedPrimary[1] = fraction_to_uint (m->Ry_n, m->Ry_d, 50000);
meta->GreenPrimary[0] = fraction_to_uint (m->Gx_n, m->Gx_d, 50000);
meta->GreenPrimary[1] = fraction_to_uint (m->Gy_n, m->Gy_d, 50000);
meta->BluePrimary[0] = fraction_to_uint (m->Bx_n, m->Bx_d, 50000);
meta->BluePrimary[1] = fraction_to_uint (m->By_n, m->By_d, 50000);
meta->WhitePoint[0] = fraction_to_uint (m->Wx_n, m->Wx_d, 50000);
meta->WhitePoint[1] = fraction_to_uint (m->Wy_n, m->Wy_d, 50000);
meta->MaxMasteringLuminance =
fraction_to_uint (m->max_luma_n, m->max_luma_d, 1);
meta->MinMasteringLuminance =
fraction_to_uint (m->min_luma_n, m->min_luma_d, 1);
meta->MaxContentLightLevel = fraction_to_uint (c->maxCLL_n, c->maxCLL_d, 1);
meta->MaxFrameAverageLightLevel =
fraction_to_uint (c->maxFALL_n, c->maxFALL_d, 1);
}
/* missing in mingw header... */
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;
typedef struct
{
GST_DXGI_COLOR_SPACE_TYPE type;
GstVideoColorRange range;
GstVideoTransferFunction transfer;
GstVideoColorPrimaries primaries;
} DxgiColorSpaceMap;
/* https://docs.microsoft.com/en-us/windows/win32/api/dxgicommon/ne-dxgicommon-dxgi_color_space_type */
static const DxgiColorSpaceMap colorspace_map[] = {
/* RGB, bt709 */
{GST_DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709, GST_VIDEO_COLOR_RANGE_0_255,
GST_VIDEO_TRANSFER_BT709, GST_VIDEO_COLOR_PRIMARIES_BT709},
{GST_DXGI_COLOR_SPACE_RGB_FULL_G10_NONE_P709, GST_VIDEO_COLOR_RANGE_0_255,
GST_VIDEO_TRANSFER_GAMMA10, GST_VIDEO_COLOR_PRIMARIES_BT709},
{GST_DXGI_COLOR_SPACE_RGB_STUDIO_G22_NONE_P709, GST_VIDEO_COLOR_RANGE_16_235,
GST_VIDEO_TRANSFER_BT709, GST_VIDEO_COLOR_PRIMARIES_BT709},
/* RGB, bt2020 */
{GST_DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P2020, GST_VIDEO_COLOR_RANGE_0_255,
GST_VIDEO_TRANSFER_BT2020_10, GST_VIDEO_COLOR_PRIMARIES_BT2020},
{GST_DXGI_COLOR_SPACE_RGB_STUDIO_G22_NONE_P2020, GST_VIDEO_COLOR_RANGE_16_235,
GST_VIDEO_TRANSFER_BT2020_10, GST_VIDEO_COLOR_PRIMARIES_BT2020},
/* RGB, bt2084 */
{GST_DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020, GST_VIDEO_COLOR_RANGE_0_255,
GST_VIDEO_TRANSFER_SMPTE2084, GST_VIDEO_COLOR_PRIMARIES_BT2020},
{GST_DXGI_COLOR_SPACE_RGB_STUDIO_G2084_NONE_P2020,
GST_VIDEO_COLOR_RANGE_16_235,
GST_VIDEO_TRANSFER_SMPTE2084, GST_VIDEO_COLOR_PRIMARIES_BT2020},
/* RGB, SRGB */
{GST_DXGI_COLOR_SPACE_RGB_STUDIO_G24_NONE_P709, GST_VIDEO_COLOR_RANGE_16_235,
GST_VIDEO_TRANSFER_SRGB, GST_VIDEO_COLOR_PRIMARIES_BT709},
{GST_DXGI_COLOR_SPACE_RGB_STUDIO_G24_NONE_P2020, GST_VIDEO_COLOR_RANGE_16_235,
GST_VIDEO_TRANSFER_SRGB, GST_VIDEO_COLOR_PRIMARIES_BT2020},
};
static gboolean
gst_d3d11_window_color_space_from_video_info (GstD3D11Window * self,
GstVideoInfo * info, IDXGISwapChain4 * swapchain,
GST_DXGI_COLOR_SPACE_TYPE * dxgi_colorspace)
{
guint i;
gint best_idx = -1;
gint best_score = 0;
g_return_val_if_fail (info != NULL, FALSE);
g_return_val_if_fail (dxgi_colorspace != NULL, FALSE);
/* We render only RGB for now */
if (!GST_VIDEO_FORMAT_INFO_IS_RGB (info->finfo))
return FALSE;
/* find the best matching colorspace */
for (i = 0; i < G_N_ELEMENTS (colorspace_map); i++) {
GstVideoColorimetry *cinfo = &info->colorimetry;
UINT can_support = 0;
HRESULT hr;
gint score = 0;
GstVideoTransferFunction transfer = cinfo->transfer;
DXGI_COLOR_SPACE_TYPE type = (DXGI_COLOR_SPACE_TYPE) colorspace_map[i].type;
if (transfer == GST_VIDEO_TRANSFER_BT2020_12)
transfer = GST_VIDEO_TRANSFER_BT2020_10;
hr = swapchain->CheckColorSpaceSupport (type, &can_support);
if (SUCCEEDED (hr) &&
(can_support & DXGI_SWAP_CHAIN_COLOR_SPACE_SUPPORT_FLAG_PRESENT) ==
DXGI_SWAP_CHAIN_COLOR_SPACE_SUPPORT_FLAG_PRESENT) {
if (cinfo->range == colorspace_map[i].range)
score++;
if (transfer == colorspace_map[i].transfer)
score++;
if (cinfo->primaries == colorspace_map[i].primaries)
score++;
GST_DEBUG_OBJECT (self,
"colorspace %d supported, score %d", type, score);
if (score > best_score) {
best_score = score;
best_idx = i;
}
} else {
GST_DEBUG_OBJECT (self,
"colorspace %d not supported", type);
}
}
if (best_idx < 0)
return FALSE;
*dxgi_colorspace = colorspace_map[best_idx].type;
return TRUE;
}
#endif
gboolean
gst_d3d11_window_prepare (GstD3D11Window * window, guint width, guint height,
guint aspect_ratio_n, guint aspect_ratio_d, GstCaps * caps, GError ** error)
@ -572,11 +411,6 @@ gst_d3d11_window_prepare (GstD3D11Window * window, guint width, guint height,
GstD3D11WindowClass *klass;
GstCaps *render_caps;
guint swapchain_flags = 0;
#if (DXGI_HEADER_VERSION >= 5)
gboolean have_cll = FALSE;
gboolean have_mastering = FALSE;
gboolean swapchain4_available = FALSE;
#endif
g_return_val_if_fail (GST_IS_D3D11_WINDOW (window), FALSE);
g_return_val_if_fail (aspect_ratio_n > 0, FALSE);
@ -658,35 +492,12 @@ gst_d3d11_window_prepare (GstD3D11Window * window, guint width, guint height,
}
window->allow_tearing = FALSE;
#if (DXGI_HEADER_VERSION >= 5)
if (!gst_video_content_light_level_from_caps (&window->content_light_level,
caps)) {
gst_video_content_light_level_init (&window->content_light_level);
} else {
have_cll = TRUE;
g_object_get (window->device, "allow-tearing", &window->allow_tearing, NULL);
if (window->allow_tearing) {
GST_DEBUG_OBJECT (window, "device support tearning");
swapchain_flags |= DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING;
}
if (!gst_video_mastering_display_info_from_caps
(&window->mastering_display_info, caps)) {
gst_video_mastering_display_info_init (&window->mastering_display_info);
} else {
have_mastering = TRUE;
}
if (gst_d3d11_device_get_chosen_dxgi_factory_version (window->device) >=
GST_D3D11_DXGI_FACTORY_5) {
GST_DEBUG_OBJECT (window, "DXGI 1.5 interface is available");
swapchain4_available = TRUE;
g_object_get (window->device,
"allow-tearing", &window->allow_tearing, NULL);
if (window->allow_tearing) {
GST_DEBUG_OBJECT (window, "device support tearning");
swapchain_flags |= DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING;
}
}
#endif
if (window->swap_chain) {
gst_d3d11_device_lock (window->device);
gst_d3d11_window_release_resources (window->device, window);
@ -713,41 +524,62 @@ gst_d3d11_window_prepare (GstD3D11Window * window, guint width, guint height,
return FALSE;
}
#if (DXGI_HEADER_VERSION >= 5)
if (swapchain4_available) {
#if (DXGI_HEADER_VERSION >= 4)
{
IDXGISwapChain3 *swapchain3 = NULL;
HRESULT hr;
GST_DXGI_COLOR_SPACE_TYPE ctype;
IDXGISwapChain4* swap_chain4 = (IDXGISwapChain4 *) window->swap_chain;
if (gst_d3d11_window_color_space_from_video_info (window,
&window->render_info, swap_chain4, &ctype)) {
hr = swap_chain4->SetColorSpace1 ((DXGI_COLOR_SPACE_TYPE) ctype);
hr = window->swap_chain->QueryInterface (IID_IDXGISwapChain3,
(void **) &swapchain3);
if (!gst_d3d11_result (hr, window->device)) {
GST_WARNING_OBJECT (window, "Failed to set colorspace %d, hr: 0x%x",
if (gst_d3d11_result (hr, window->device)) {
DXGI_COLOR_SPACE_TYPE ctype;
if (gst_d3d11_find_swap_chain_color_space (&window->render_info,
swapchain3, &ctype)) {
hr = swapchain3->SetColorSpace1 (ctype);
if (!gst_d3d11_result (hr, window->device)) {
GST_WARNING_OBJECT (window, "Failed to set colorspace %d, hr: 0x%x",
ctype, (guint) hr);
} else {
GST_DEBUG_OBJECT (window, "Set colorspace %d", ctype);
} else {
GST_DEBUG_OBJECT (window, "Set colorspace %d", ctype);
}
}
if (have_cll && have_mastering) {
swapchain3->Release ();
}
}
#endif
#if (DXGI_HEADER_VERSION >= 5)
{
GstVideoMasteringDisplayInfo minfo;
GstVideoContentLightLevel cll;
if (gst_video_mastering_display_info_from_caps (&minfo, caps) &&
gst_video_content_light_level_from_caps (&cll, caps)) {
IDXGISwapChain4 *swapchain4 = NULL;
HRESULT hr;
hr = window->swap_chain->QueryInterface (IID_IDXGISwapChain4,
(void **) &swapchain4);
if (gst_d3d11_result (hr, window->device)) {
DXGI_HDR_METADATA_HDR10 metadata = { 0, };
GST_DEBUG_OBJECT (window, "Have HDR metadata, set to DXGI swapchain");
mastering_display_gst_to_dxgi (&window->mastering_display_info,
&window->content_light_level, &metadata);
gst_d3d11_hdr_meta_data_to_dxgi (&minfo, &cll, &metadata);
hr = swap_chain4->SetHDRMetaData (DXGI_HDR_METADATA_TYPE_HDR10,
hr = swapchain4->SetHDRMetaData (DXGI_HDR_METADATA_TYPE_HDR10,
sizeof (DXGI_HDR_METADATA_HDR10), &metadata);
if (!gst_d3d11_result (hr, window->device)) {
GST_WARNING_OBJECT (window, "Couldn't set HDR metadata, hr 0x%x",
(guint) hr);
}
swapchain4->Release ();
}
} else {
GST_DEBUG_OBJECT (window,
"Could not get color space from %" GST_PTR_FORMAT, caps);
}
}
#endif

View file

@ -82,9 +82,6 @@ struct _GstD3D11Window
GstD3D11ColorConverter *converter;
GstD3D11OverlayCompositor *compositor;
GstVideoMasteringDisplayInfo mastering_display_info;
GstVideoContentLightLevel content_light_level;
/* calculated rect with aspect ratio and window area */
RECT render_rect;