mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-17 11:45:25 +00:00
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:
parent
4b72e8cad5
commit
a967db3b20
4 changed files with 401 additions and 214 deletions
|
@ -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
|
||||
|
|
|
@ -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__ */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in a new issue