d3d11window: Reorganize display colorspace selection

The set of supported color space by DXGI is not full combination of
our colorimetry. That means we should convert color space to one
of supported color space by DXGI. This commit modifies the color space
selection step so that d3d11window can find the best matching DXGI color space
first and then the selected input/output color space will be referenced
by shader and/or d3d11videoprocessor.
This commit is contained in:
Seungha Yang 2020-03-09 20:29:17 +09:00 committed by GStreamer Merge Bot
parent 7f5347a664
commit f9f6916aa1
4 changed files with 331 additions and 239 deletions

View file

@ -250,15 +250,6 @@ typedef enum
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) \
@ -266,7 +257,7 @@ typedef struct
GST_VIDEO_COLOR_MATRIX_ ##m, GST_VIDEO_TRANSFER_ ##t, \
GST_VIDEO_COLOR_PRIMARIES_ ##p }
static const DxgiColorSpaceMap rgb_colorspace_map[] = {
static const GstDxgiColorSpace rgb_colorspace_map[] = {
/* RGB_FULL_G22_NONE_P709 */
MAKE_COLOR_MAP (RGB_FULL_G22_NONE_P709, _0_255, UNKNOWN, BT709, BT709),
@ -299,7 +290,7 @@ static const DxgiColorSpaceMap rgb_colorspace_map[] = {
MAKE_COLOR_MAP (RGB_STUDIO_G24_NONE_P709, _16_235, UNKNOWN, SRGB, BT2020),
};
static const DxgiColorSpaceMap yuv_colorspace_map[] = {
static const GstDxgiColorSpace yuv_colorspace_map[] = {
/* YCBCR_FULL_G22_NONE_P709_X601 */
MAKE_COLOR_MAP (YCBCR_FULL_G22_NONE_P709_X601, _0_255, BT601, BT709, BT709),
@ -368,7 +359,7 @@ static const DxgiColorSpaceMap yuv_colorspace_map[] = {
#define SCORE_PRIMARY_MISMATCH 10
static gint
get_score (GstVideoInfo * info, const DxgiColorSpaceMap * color_map,
get_score (GstVideoInfo * info, const GstDxgiColorSpace * color_map,
gboolean is_yuv)
{
gint loss = 0;
@ -389,84 +380,74 @@ get_score (GstVideoInfo * info, const DxgiColorSpaceMap * color_map,
return loss;
}
static gboolean
gst_d3d11_video_info_to_dxgi_color_space_rgb (GstVideoInfo * info,
DXGI_COLOR_SPACE_TYPE * colorspace)
static const GstDxgiColorSpace *
gst_d3d11_video_info_to_dxgi_color_space_rgb (GstVideoInfo * info)
{
gint best_score = G_MAXINT;
gint score, i;
GST_DXGI_COLOR_SPACE_TYPE type = GST_DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709;
const GstDxgiColorSpace *colorspace = NULL;
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;
colorspace = &rgb_colorspace_map[i];
if (score == 0)
break;
}
}
*colorspace = (DXGI_COLOR_SPACE_TYPE) type;
return TRUE;
return colorspace;
}
static gboolean
gst_d3d11_video_info_to_dxgi_color_space_yuv (GstVideoInfo * info,
DXGI_COLOR_SPACE_TYPE * colorspace)
static const GstDxgiColorSpace *
gst_d3d11_video_info_to_dxgi_color_space_yuv (GstVideoInfo * info)
{
gint best_score = G_MAXINT;
gint score, i;
GST_DXGI_COLOR_SPACE_TYPE type =
GST_DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P709;
const GstDxgiColorSpace *colorspace = NULL;
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;
colorspace = &yuv_colorspace_map[i];
if (score == 0)
break;
}
}
*colorspace = (DXGI_COLOR_SPACE_TYPE) type;
return TRUE;
return colorspace;
}
gboolean
gst_d3d11_video_info_to_dxgi_color_space (GstVideoInfo * info,
DXGI_COLOR_SPACE_TYPE * colorspace)
const GstDxgiColorSpace *
gst_d3d11_video_info_to_dxgi_color_space (GstVideoInfo * info)
{
g_return_val_if_fail (info != NULL, FALSE);
g_return_val_if_fail (colorspace != NULL, FALSE);
g_return_val_if_fail (info != NULL, NULL);
if (GST_VIDEO_INFO_IS_RGB (info)) {
return gst_d3d11_video_info_to_dxgi_color_space_rgb (info, colorspace);
return gst_d3d11_video_info_to_dxgi_color_space_rgb (info);
} else if (GST_VIDEO_INFO_IS_YUV (info)) {
return gst_d3d11_video_info_to_dxgi_color_space_yuv (info, colorspace);
return gst_d3d11_video_info_to_dxgi_color_space_yuv (info);
}
return FALSE;
return NULL;
}
gboolean
const GstDxgiColorSpace *
gst_d3d11_find_swap_chain_color_space (GstVideoInfo * info,
IDXGISwapChain3 * swapchain, DXGI_COLOR_SPACE_TYPE * colorspace)
IDXGISwapChain3 * swapchain, gboolean use_hdr10)
{
GST_DXGI_COLOR_SPACE_TYPE best_type;
const GstDxgiColorSpace *colorspace = NULL;
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");
@ -477,7 +458,16 @@ gst_d3d11_find_swap_chain_color_space (GstVideoInfo * info,
UINT can_support = 0;
HRESULT hr;
gint score;
GST_DXGI_COLOR_SPACE_TYPE cur_type = rgb_colorspace_map[i].type;
GST_DXGI_COLOR_SPACE_TYPE cur_type =
rgb_colorspace_map[i].dxgi_color_space_type;
/* FIXME: Non-HDR colorspace with BT2020 primaries will break rendering.
* https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/issues/1175
* To workaround it, BT709 colorspace will be chosen for non-HDR case.
*/
if (!use_hdr10 &&
rgb_colorspace_map[i].primaries == GST_VIDEO_COLOR_PRIMARIES_BT2020)
continue;
hr = IDXGISwapChain3_CheckColorSpaceSupport (swapchain,
cur_type, &can_support);
@ -493,17 +483,12 @@ gst_d3d11_find_swap_chain_color_space (GstVideoInfo * info,
if (score < best_score) {
best_score = score;
best_type = cur_type;
colorspace = &rgb_colorspace_map[i];
}
}
}
if (best_score == G_MAXINT)
return FALSE;
*colorspace = (DXGI_COLOR_SPACE_TYPE) best_type;
return TRUE;
return colorspace;
}
#endif

View file

@ -31,6 +31,8 @@
G_BEGIN_DECLS
typedef struct _GstDxgiColorSpace GstDxgiColorSpace;
struct _GstD3D11Format
{
GstVideoFormat format;
@ -42,6 +44,15 @@ struct _GstD3D11Format
DXGI_FORMAT resource_format[GST_VIDEO_MAX_COMPONENTS];
};
struct _GstDxgiColorSpace
{
guint dxgi_color_space_type;
GstVideoColorRange range;
GstVideoColorMatrix matrix;
GstVideoTransferFunction transfer;
GstVideoColorPrimaries primaries;
};
guint gst_d3d11_dxgi_format_n_planes (DXGI_FORMAT format);
gboolean gst_d3d11_dxgi_format_get_size (DXGI_FORMAT format,
@ -62,12 +73,11 @@ gboolean gst_d3d11_hdr_meta_data_to_dxgi (GstVideoMasteringDisplayInf
#endif
#if (DXGI_HEADER_VERSION >= 4)
gboolean gst_d3d11_video_info_to_dxgi_color_space (GstVideoInfo * info,
DXGI_COLOR_SPACE_TYPE * colorspace);
const GstDxgiColorSpace * gst_d3d11_video_info_to_dxgi_color_space (GstVideoInfo * info);
gboolean gst_d3d11_find_swap_chain_color_space (GstVideoInfo * info,
IDXGISwapChain3 * swapchain,
DXGI_COLOR_SPACE_TYPE * colorspace);
const GstDxgiColorSpace * gst_d3d11_find_swap_chain_color_space (GstVideoInfo * info,
IDXGISwapChain3 * swapchain,
gboolean use_hdr10);
#endif
G_END_DECLS

View file

@ -416,77 +416,260 @@ gst_d3d11_window_on_mouse_event (GstD3D11Window * window, const gchar * event,
event, button, x, y);
}
typedef struct
{
DXGI_FORMAT dxgi_format;
GstVideoFormat gst_format;
gboolean supported;
} GstD3D11WindowDisplayFormat;
gboolean
gst_d3d11_window_prepare (GstD3D11Window * window, guint display_width,
guint display_height, GstCaps * caps, gboolean * video_processor_available,
GError ** error)
{
GstD3D11WindowClass *klass;
GstCaps *render_caps;
guint swapchain_flags = 0;
gboolean need_processor_output_configure = FALSE;
gboolean need_processor_input_configure = FALSE;
ID3D11Device *device_handle;
guint i;
guint num_supported_format = 0;
HRESULT hr;
UINT display_flags =
D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_DISPLAY;
UINT supported_flags = 0;
GstD3D11WindowDisplayFormat formats[] = {
{ DXGI_FORMAT_R8G8B8A8_UNORM, GST_VIDEO_FORMAT_RGBA, FALSE },
{ DXGI_FORMAT_B8G8R8A8_UNORM, GST_VIDEO_FORMAT_BGRA, FALSE },
{ DXGI_FORMAT_R10G10B10A2_UNORM, GST_VIDEO_FORMAT_RGB10A2_LE, FALSE },
};
const GstD3D11WindowDisplayFormat *chosen_format = NULL;
const GstDxgiColorSpace * chosen_colorspace = NULL;
#if (DXGI_HEADER_VERSION >= 4)
gboolean have_hdr10 = FALSE;
DXGI_COLOR_SPACE_TYPE native_colorspace_type =
DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709;
#endif
#if (DXGI_HEADER_VERSION >= 5)
DXGI_HDR_METADATA_HDR10 hdr10_metadata = { 0, };
#endif
g_return_val_if_fail (GST_IS_D3D11_WINDOW (window), FALSE);
GST_DEBUG_OBJECT (window, "Prepare window, display resolution %dx%d, caps %"
GST_PTR_FORMAT, display_width, display_height, caps);
/* Step 1: Clear old resources and objects */
gst_clear_buffer (&window->cached_buffer);
g_clear_pointer (&window->processor, gst_d3d11_video_processor_free);
g_clear_pointer (&window->converter, gst_d3d11_color_converter_free);
g_clear_pointer (&window->compositor, gst_d3d11_overlay_compositor_free);
render_caps = gst_d3d11_device_get_supported_caps (window->device,
(D3D11_FORMAT_SUPPORT) (D3D11_FORMAT_SUPPORT_TEXTURE2D |
D3D11_FORMAT_SUPPORT_DISPLAY));
GST_DEBUG_OBJECT (window, "rendering caps %" GST_PTR_FORMAT, render_caps);
render_caps = gst_d3d11_caps_fixate_format (caps, render_caps);
if (!render_caps || gst_caps_is_empty (render_caps)) {
GST_ERROR_OBJECT (window, "Couldn't define render caps");
g_set_error (error, GST_RESOURCE_ERROR, GST_RESOURCE_ERROR_FAILED,
"Couldn't define render caps");
gst_clear_caps (&render_caps);
return FALSE;
}
render_caps = gst_caps_fixate (render_caps);
gst_video_info_from_caps (&window->render_info, render_caps);
gst_clear_caps (&render_caps);
window->render_format =
gst_d3d11_device_format_from_gst (window->device,
GST_VIDEO_INFO_FORMAT (&window->render_info));
if (!window->render_format ||
window->render_format->dxgi_format == DXGI_FORMAT_UNKNOWN) {
GST_ERROR_OBJECT (window, "Unknown dxgi render format");
g_set_error (error, GST_RESOURCE_ERROR, GST_RESOURCE_ERROR_FAILED,
"Unknown dxgi render format");
return FALSE;
}
/* Step 2: Decide display color format
* If upstream format is 10bits, try DXGI_FORMAT_R10G10B10A2_UNORM first
* Otherwise, use DXGI_FORMAT_B8G8R8A8_UNORM or DXGI_FORMAT_B8G8R8A8_UNORM
*/
gst_video_info_from_caps (&window->info, caps);
device_handle = gst_d3d11_device_get_device_handle (window->device);
for (i = 0; i < G_N_ELEMENTS (formats); i++) {
hr = device_handle->CheckFormatSupport (formats[i].dxgi_format,
&supported_flags);
if (SUCCEEDED (hr) && (supported_flags & display_flags) == display_flags) {
GST_DEBUG_OBJECT (window, "Device supports format %s (DXGI_FORMAT %d)",
gst_video_format_to_string (formats[i].gst_format),
formats[i].dxgi_format);
formats[i].supported = TRUE;
num_supported_format++;
}
}
if (window->processor)
gst_d3d11_video_processor_free (window->processor);
window->processor = NULL;
if (num_supported_format == 0) {
GST_ERROR_OBJECT (window, "Cannot determine render format");
g_set_error (error, GST_RESOURCE_ERROR, GST_RESOURCE_ERROR_FAILED,
"Cannot determine render format");
return FALSE;
}
if (window->converter)
gst_d3d11_color_converter_free (window->converter);
window->converter = NULL;
for (i = 0; i < GST_VIDEO_INFO_N_COMPONENTS (&window->info); i++) {
if (GST_VIDEO_INFO_COMP_DEPTH (&window->info, i) > 8) {
if (formats[2].supported) {
chosen_format = &formats[2];
}
break;
}
}
if (window->compositor)
gst_d3d11_overlay_compositor_free (window->compositor);
window->compositor = NULL;
if (!chosen_format) {
/* prefer native format over conversion */
for (i = 0; i < 2; i++) {
if (formats[i].supported &&
formats[i].gst_format == GST_VIDEO_INFO_FORMAT (&window->info)) {
chosen_format = &formats[i];
break;
}
}
/* choose any color space then */
if (!chosen_format) {
for (i = 0; i < G_N_ELEMENTS (formats); i++) {
if (formats[i].supported) {
chosen_format = &formats[i];
break;
}
}
}
}
g_assert (chosen_format != NULL);
GST_DEBUG_OBJECT (window, "chosen rendero format %s (DXGI_FORMAT %d)",
gst_video_format_to_string (chosen_format->gst_format),
chosen_format->dxgi_format);
/* Step 3: Create swapchain
* (or reuse old swapchain if the format is not changed) */
window->allow_tearing = FALSE;
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;
}
/* release swapchain if render format is being changed */
gst_d3d11_device_lock (window->device);
if (window->swap_chain &&
window->dxgi_format != chosen_format->dxgi_format) {
gst_d3d11_window_release_resources (window->device, window);
}
window->dxgi_format = chosen_format->dxgi_format;
klass = GST_D3D11_WINDOW_GET_CLASS (window);
if (!window->swap_chain &&
!klass->create_swap_chain (window, window->dxgi_format,
display_width, display_height, swapchain_flags, &window->swap_chain)) {
GST_ERROR_OBJECT (window, "Cannot create swapchain");
g_set_error (error, GST_RESOURCE_ERROR, GST_RESOURCE_ERROR_FAILED,
"Cannot create swapchain");
gst_d3d11_device_unlock (window->device);
return FALSE;
}
gst_d3d11_device_unlock (window->device);
/* this rect struct will be used to calculate render area */
window->render_rect.left = 0;
window->render_rect.top = 0;
window->render_rect.right = display_width;
window->render_rect.bottom = display_height;
window->input_rect.left = 0;
window->input_rect.top = 0;
window->input_rect.right = GST_VIDEO_INFO_WIDTH (&window->info);
window->input_rect.bottom = GST_VIDEO_INFO_HEIGHT (&window->info);
/* Step 4: Decide render color space and set it on converter/processor */
/* check HDR10 metadata. If HDR APIs are available, BT2020 primaries colorspcae
* will be used.
*
* FIXME: need to query h/w level support. If that's not the case, tone-mapping
* should be placed somewhere.
*
* FIXME: Non-HDR colorspace with BT2020 primaries will break rendering.
* https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/issues/1175
* To workaround it, BT709 colorspace will be chosen for non-HDR case.
*/
#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)) {
GST_DEBUG_OBJECT (window, "Have HDR metadata, set to DXGI swapchain");
gst_d3d11_hdr_meta_data_to_dxgi (&minfo, &cll, &hdr10_metadata);
hr = swapchain4->SetHDRMetaData (DXGI_HDR_METADATA_TYPE_HDR10,
sizeof (DXGI_HDR_METADATA_HDR10), &hdr10_metadata);
if (!gst_d3d11_result (hr, window->device)) {
GST_WARNING_OBJECT (window, "Couldn't set HDR metadata, hr 0x%x",
(guint) hr);
} else {
have_hdr10 = TRUE;
}
swapchain4->Release ();
}
}
}
#endif
/* Step 5: Choose display color space */
gst_video_info_set_format (&window->render_info,
chosen_format->gst_format, display_width, display_height);
/* preserve upstream colorimetry */
window->render_info.width = display_width;
window->render_info.height = display_height;
window->render_info.colorimetry.primaries =
window->info.colorimetry.primaries;
window->render_info.colorimetry.transfer = window->info.colorimetry.transfer;
window->render_info.colorimetry.range = window->info.colorimetry.range;
#if (DXGI_HEADER_VERSION >= 4)
{
IDXGISwapChain3 *swapchain3 = NULL;
HRESULT hr;
hr = window->swap_chain->QueryInterface (IID_IDXGISwapChain3,
(void **) &swapchain3);
if (gst_d3d11_result (hr, window->device)) {
chosen_colorspace = gst_d3d11_find_swap_chain_color_space (&window->render_info,
swapchain3, have_hdr10);
if (chosen_colorspace) {
native_colorspace_type =
(DXGI_COLOR_SPACE_TYPE) chosen_colorspace->dxgi_color_space_type;
hr = swapchain3->SetColorSpace1 (native_colorspace_type);
if (!gst_d3d11_result (hr, window->device)) {
GST_WARNING_OBJECT (window, "Failed to set colorspace %d, hr: 0x%x",
native_colorspace_type, (guint) hr);
chosen_colorspace = NULL;
native_colorspace_type = DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709;
} else {
GST_DEBUG_OBJECT (window,
"Set colorspace %d", native_colorspace_type);
/* update with selected display color space */
window->render_info.colorimetry.primaries =
chosen_colorspace->primaries;
window->render_info.colorimetry.transfer =
chosen_colorspace->transfer;
window->render_info.colorimetry.range =
chosen_colorspace->range;
window->render_info.colorimetry.matrix =
chosen_colorspace->matrix;
}
}
swapchain3->Release ();
}
}
#endif
/* otherwise, use most common DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709
* color space */
if (!chosen_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->processor =
gst_d3d11_video_processor_new (window->device,
@ -526,10 +709,60 @@ gst_d3d11_window_prepare (GstD3D11Window * window, guint display_width,
gst_d3d11_video_processor_free (window->processor);
window->processor = NULL;
} else {
gboolean processor_input_configureed = FALSE;
gboolean processor_output_configured = FALSE;
GST_DEBUG_OBJECT (window, "IVideoProcessor interface available");
*video_processor_available = TRUE;
need_processor_input_configure = TRUE;
need_processor_output_configure = TRUE;
#if (DXGI_HEADER_VERSION >= 5)
if (have_hdr10) {
GST_DEBUG_OBJECT (window, "Set HDR metadata on video processor");
gst_d3d11_video_processor_set_input_hdr10_metadata (window->processor,
&hdr10_metadata);
gst_d3d11_video_processor_set_output_hdr10_metadata (window->processor,
&hdr10_metadata);
}
#endif
#if (DXGI_HEADER_VERSION >= 4)
{
DXGI_COLOR_SPACE_TYPE in_native_cs =
DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709;
const GstDxgiColorSpace *in_cs =
gst_d3d11_video_info_to_dxgi_color_space (&window->info);
if (in_cs) {
in_native_cs = (DXGI_COLOR_SPACE_TYPE) in_cs->dxgi_color_space_type;
} else {
GST_WARNING_OBJECT (window,
"Cannot figure out input dxgi color space");
if (GST_VIDEO_INFO_IS_RGB (&window->info)) {
in_native_cs = DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709;
} else {
in_native_cs = DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P709;
}
}
GST_DEBUG_OBJECT (window,
"Set color space on video processor, in %d, out %d",
in_native_cs, native_colorspace_type);
processor_input_configureed =
gst_d3d11_video_processor_set_input_dxgi_color_space
(window->processor, in_native_cs);
processor_output_configured =
gst_d3d11_video_processor_set_output_dxgi_color_space
(window->processor, native_colorspace_type);
}
#endif
if (!processor_input_configureed) {
gst_d3d11_video_processor_set_input_color_space (window->processor,
&window->info.colorimetry);
}
if (!processor_output_configured) {
gst_d3d11_video_processor_set_output_color_space (window->processor,
&window->render_info.colorimetry);
}
}
}
@ -556,141 +789,6 @@ gst_d3d11_window_prepare (GstD3D11Window * window, guint display_width,
return FALSE;
}
window->allow_tearing = FALSE;
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;
}
/* release swapchain if render format is being changed */
gst_d3d11_device_lock (window->device);
if (window->swap_chain &&
window->render_format->dxgi_format != window->dxgi_format) {
gst_d3d11_window_release_resources (window->device, window);
}
window->dxgi_format = window->render_format->dxgi_format;
window->render_rect.left = 0;
window->render_rect.top = 0;
window->render_rect.right = display_width;
window->render_rect.bottom = display_height;
window->input_rect.left = 0;
window->input_rect.top = 0;
window->input_rect.right = GST_VIDEO_INFO_WIDTH (&window->info);
window->input_rect.bottom = GST_VIDEO_INFO_HEIGHT (&window->info);
klass = GST_D3D11_WINDOW_GET_CLASS (window);
if (!window->swap_chain &&
!klass->create_swap_chain (window, window->dxgi_format,
display_width, display_height, swapchain_flags, &window->swap_chain)) {
GST_ERROR_OBJECT (window, "Cannot create swapchain");
g_set_error (error, GST_RESOURCE_ERROR, GST_RESOURCE_ERROR_FAILED,
"Cannot create swapchain");
gst_d3d11_device_unlock (window->device);
return FALSE;
}
gst_d3d11_device_unlock (window->device);
#if (DXGI_HEADER_VERSION >= 4)
{
IDXGISwapChain3 *swapchain3 = NULL;
HRESULT hr;
hr = window->swap_chain->QueryInterface (IID_IDXGISwapChain3,
(void **) &swapchain3);
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);
if (window->processor)
need_processor_output_configure =
!gst_d3d11_video_processor_set_output_dxgi_color_space
(window->processor, ctype);
}
}
swapchain3->Release ();
}
}
if (window->processor) {
if (need_processor_output_configure) {
/* Set most common color space */
need_processor_output_configure =
!gst_d3d11_video_processor_set_output_dxgi_color_space
(window->processor, DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709);
}
if (need_processor_input_configure) {
DXGI_COLOR_SPACE_TYPE ctype;
gst_d3d11_video_info_to_dxgi_color_space (&window->info, &ctype);
need_processor_input_configure =
!gst_d3d11_video_processor_set_input_dxgi_color_space
(window->processor, ctype);
}
}
#endif
if (window->processor && need_processor_output_configure) {
gst_d3d11_video_processor_set_output_color_space (window->processor,
&window->render_info.colorimetry);
}
if (window->processor && need_processor_input_configure) {
gst_d3d11_video_processor_set_input_color_space (window->processor,
&window->info.colorimetry);
}
#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");
gst_d3d11_hdr_meta_data_to_dxgi (&minfo, &cll, &metadata);
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);
} else if (window->processor) {
gst_d3d11_video_processor_set_input_hdr10_metadata (window->processor,
&metadata);
gst_d3d11_video_processor_set_output_hdr10_metadata (window->processor,
&metadata);
}
swapchain4->Release ();
}
}
}
#endif
/* call resize to allocated resources */
klass->on_resize (window, display_width, display_height);

View file

@ -79,7 +79,6 @@ struct _GstD3D11Window
GstVideoInfo info;
GstVideoInfo render_info;
const GstD3D11Format *render_format;
GstD3D11VideoProcessor *processor;
GstD3D11ColorConverter *converter;
GstD3D11OverlayCompositor *compositor;