d3d11format: Add util methods for mapping DXGI color space with ours
authorSeungha Yang <seungha.yang@navercorp.com>
Wed, 29 Jan 2020 08:29:04 +0000 (17:29 +0900)
committerGStreamer Merge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Wed, 5 Feb 2020 00:52:48 +0000 (00:52 +0000)
Move color space mapping and hdr10 metadata conversion methods to
d3d11format in order to reuse the code.

sys/d3d11/gstd3d11format.c
sys/d3d11/gstd3d11format.h
sys/d3d11/gstd3d11window.cpp
sys/d3d11/gstd3d11window.h

index ebdf258..292b784 100644 (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
index 0b9bfef..4c85bca 100644 (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__ */
index c7e8e48..922c787 100644 (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,34 +492,11 @@ 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;
-  }
-
-  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;
-    }
+  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);
@@ -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)) {
+      DXGI_COLOR_SPACE_TYPE ctype;
 
-      if (!gst_d3d11_result (hr, window->device)) {
-        GST_WARNING_OBJECT (window, "Failed to set colorspace %d, hr: 0x%x",
+      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
index 6118fd7..2d743d3 100644 (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;