d3d11screencapturesrc: Fix wrong color with HDR enabled

Even if IDXGIOutput6 says current display colorspace is HDR,
captured texture via IDXGIOutputDuplication::AcquireNextFrame()
is converted frame by OS unless we use IDXGIOutput5::DuplicateOutput1()
with DXGI_FORMAT_R16G16B16A16_FLOAT format, in order for captured
frame to be scRGB color space. Then application should perform
tonemap operation based on reported display white level, color primaries, etc.

Since we don't have any tonemapping implementation, ignores colorimetry
reported by IDXGIOutput6.

Fixes: https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/3128
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5679>
This commit is contained in:
Seungha Yang 2023-11-15 22:41:47 +09:00 committed by GStreamer Marge Bot
parent 1eca0a1049
commit d2646e0a19
6 changed files with 8 additions and 85 deletions

View file

@ -1529,9 +1529,6 @@ gst_d3d11_dxgi_capture_prepare (GstD3D11ScreenCapture * capture);
static gboolean static gboolean
gst_d3d11_dxgi_capture_get_size (GstD3D11ScreenCapture * capture, gst_d3d11_dxgi_capture_get_size (GstD3D11ScreenCapture * capture,
guint * width, guint * height); guint * width, guint * height);
static gboolean
gst_d3d11_dxgi_capture_get_colorimetry (GstD3D11ScreenCapture * capture,
GstVideoColorimetry * colorimetry);
static GstFlowReturn static GstFlowReturn
gst_d3d11_dxgi_capture_do_capture (GstD3D11ScreenCapture * capture, gst_d3d11_dxgi_capture_do_capture (GstD3D11ScreenCapture * capture,
GstD3D11Device * device, ID3D11Texture2D * texture, GstD3D11Device * device, ID3D11Texture2D * texture,
@ -1570,8 +1567,6 @@ gst_d3d11_dxgi_capture_class_init (GstD3D11DxgiCaptureClass * klass)
capture_class->prepare = GST_DEBUG_FUNCPTR (gst_d3d11_dxgi_capture_prepare); capture_class->prepare = GST_DEBUG_FUNCPTR (gst_d3d11_dxgi_capture_prepare);
capture_class->get_size = GST_DEBUG_FUNCPTR (gst_d3d11_dxgi_capture_get_size); capture_class->get_size = GST_DEBUG_FUNCPTR (gst_d3d11_dxgi_capture_get_size);
capture_class->get_colorimetry =
GST_DEBUG_FUNCPTR (gst_d3d11_dxgi_capture_get_colorimetry);
capture_class->do_capture = capture_class->do_capture =
GST_DEBUG_FUNCPTR (gst_d3d11_dxgi_capture_do_capture); GST_DEBUG_FUNCPTR (gst_d3d11_dxgi_capture_do_capture);
} }
@ -1862,38 +1857,6 @@ gst_d3d11_dxgi_capture_get_size (GstD3D11ScreenCapture * capture,
return gst_d3d11_dxgi_capture_get_size_unlocked (self, width, height); return gst_d3d11_dxgi_capture_get_size_unlocked (self, width, height);
} }
static gboolean
gst_d3d11_dxgi_capture_get_colorimetry (GstD3D11ScreenCapture * capture,
GstVideoColorimetry * colorimetry)
{
GstD3D11DxgiCapture *self = GST_D3D11_DXGI_CAPTURE (capture);
DXGI_COLOR_SPACE_TYPE dxgi_cs;
GstVideoInfo info;
dxgi_cs = DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709;
if (self->output) {
ComPtr < IDXGIOutput6 > output;
HRESULT hr;
DXGI_OUTPUT_DESC1 desc;
hr = self->output->QueryInterface (IID_PPV_ARGS (&output));
if (SUCCEEDED (hr))
hr = output->GetDesc1 (&desc);
if (SUCCEEDED (hr))
dxgi_cs = desc.ColorSpace;
}
gst_video_info_set_format (&info, GST_VIDEO_FORMAT_BGRA, 16, 16);
if (gst_video_info_apply_dxgi_color_space (dxgi_cs, &info)) {
*colorimetry = info.colorimetry;
return TRUE;
}
return FALSE;
}
static GstFlowReturn static GstFlowReturn
gst_d3d11_dxgi_capture_do_capture (GstD3D11ScreenCapture * capture, gst_d3d11_dxgi_capture_do_capture (GstD3D11ScreenCapture * capture,
GstD3D11Device * device, ID3D11Texture2D * texture, GstD3D11Device * device, ID3D11Texture2D * texture,

View file

@ -78,21 +78,6 @@ gst_d3d11_screen_capture_get_size (GstD3D11ScreenCapture * capture,
return klass->get_size (capture, width, height); return klass->get_size (capture, width, height);
} }
gboolean
gst_d3d11_screen_capture_get_colorimetry (GstD3D11ScreenCapture * capture,
GstVideoColorimetry * colorimetry)
{
GstD3D11ScreenCaptureClass *klass;
g_return_val_if_fail (GST_IS_D3D11_SCREEN_CAPTURE (capture), FALSE);
g_return_val_if_fail (colorimetry != nullptr, FALSE);
klass = GST_D3D11_SCREEN_CAPTURE_GET_CLASS (capture);
g_assert (klass->get_colorimetry);
return klass->get_colorimetry (capture, colorimetry);
}
gboolean gboolean
gst_d3d11_screen_capture_unlock (GstD3D11ScreenCapture * capture) gst_d3d11_screen_capture_unlock (GstD3D11ScreenCapture * capture)
{ {

View file

@ -56,9 +56,6 @@ struct _GstD3D11ScreenCaptureClass
guint * width, guint * width,
guint * height); guint * height);
gboolean (*get_colorimetry) (GstD3D11ScreenCapture * capture,
GstVideoColorimetry * colorimetry);
gboolean (*unlock) (GstD3D11ScreenCapture * capture); gboolean (*unlock) (GstD3D11ScreenCapture * capture);
gboolean (*unlock_stop) (GstD3D11ScreenCapture * capture); gboolean (*unlock_stop) (GstD3D11ScreenCapture * capture);
@ -87,9 +84,6 @@ gboolean gst_d3d11_screen_capture_get_size (GstD3D11ScreenCapture * captu
guint * width, guint * width,
guint * height); guint * height);
gboolean gst_d3d11_screen_capture_get_colorimetry (GstD3D11ScreenCapture * capture,
GstVideoColorimetry * colorimetry);
gboolean gst_d3d11_screen_capture_unlock (GstD3D11ScreenCapture * capture); gboolean gst_d3d11_screen_capture_unlock (GstD3D11ScreenCapture * capture);
gboolean gst_d3d11_screen_capture_unlock_stop (GstD3D11ScreenCapture * capture); gboolean gst_d3d11_screen_capture_unlock_stop (GstD3D11ScreenCapture * capture);

View file

@ -39,8 +39,10 @@ GST_DEBUG_CATEGORY_EXTERN (gst_d3d11_screen_capture_device_debug);
static GstStaticCaps template_caps = static GstStaticCaps template_caps =
GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE_WITH_FEATURES GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE_WITH_FEATURES
(GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY, "BGRA") ", pixel-aspect-ratio = 1/1;" (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY,
GST_VIDEO_CAPS_MAKE ("BGRA") ", pixel-aspect-ratio = 1/1"); "BGRA") ", pixel-aspect-ratio = 1/1, colorimetry = (string) sRGB; "
GST_VIDEO_CAPS_MAKE ("BGRA") ", pixel-aspect-ratio = 1/1, "
"colorimetry = (string) sRGB");
enum enum
{ {

View file

@ -119,8 +119,10 @@ gst_d3d11_screen_capture_api_get_type (void)
static GstStaticCaps template_caps = static GstStaticCaps template_caps =
GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE_WITH_FEATURES GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE_WITH_FEATURES
(GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY, "BGRA") ", pixel-aspect-ratio = 1/1;" (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY,
GST_VIDEO_CAPS_MAKE ("BGRA") ", pixel-aspect-ratio = 1/1"); "BGRA") ", pixel-aspect-ratio = 1/1, colorimetry = (string) sRGB; "
GST_VIDEO_CAPS_MAKE ("BGRA") ", pixel-aspect-ratio = 1/1, "
"colorimetry = (string) sRGB");
struct _GstD3D11ScreenCaptureSrc struct _GstD3D11ScreenCaptureSrc
{ {
@ -565,7 +567,6 @@ gst_d3d11_screen_capture_src_get_caps (GstBaseSrc * bsrc, GstCaps * filter)
GstD3D11ScreenCaptureSrc *self = GST_D3D11_SCREEN_CAPTURE_SRC (bsrc); GstD3D11ScreenCaptureSrc *self = GST_D3D11_SCREEN_CAPTURE_SRC (bsrc);
GstCaps *caps = NULL; GstCaps *caps = NULL;
guint width, height; guint width, height;
GstVideoColorimetry color;
if (!self->capture) { if (!self->capture) {
GST_DEBUG_OBJECT (self, "capture object is not configured yet"); GST_DEBUG_OBJECT (self, "capture object is not configured yet");
@ -582,16 +583,6 @@ gst_d3d11_screen_capture_src_get_caps (GstBaseSrc * bsrc, GstCaps * filter)
gst_caps_set_simple (caps, "width", G_TYPE_INT, width, "height", gst_caps_set_simple (caps, "width", G_TYPE_INT, width, "height",
G_TYPE_INT, height, nullptr); G_TYPE_INT, height, nullptr);
if (gst_d3d11_screen_capture_get_colorimetry (self->capture, &color)) {
gchar *color_str = gst_video_colorimetry_to_string (&color);
if (color_str) {
gst_caps_set_simple (caps, "colorimetry", G_TYPE_STRING, color_str,
nullptr);
g_free (color_str);
}
}
if (filter) { if (filter) {
GstCaps *tmp = GstCaps *tmp =
gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST); gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);

View file

@ -241,9 +241,6 @@ static gboolean
gst_d3d11_winrt_capture_get_size (GstD3D11ScreenCapture * capture, gst_d3d11_winrt_capture_get_size (GstD3D11ScreenCapture * capture,
guint * width, guint * height); guint * width, guint * height);
static gboolean static gboolean
gst_d3d11_winrt_capture_get_colorimetry (GstD3D11ScreenCapture * capture,
GstVideoColorimetry * colorimetry);
static gboolean
gst_d3d11_winrt_capture_unlock (GstD3D11ScreenCapture * capture); gst_d3d11_winrt_capture_unlock (GstD3D11ScreenCapture * capture);
static gboolean static gboolean
gst_d3d11_winrt_capture_unlock_stop (GstD3D11ScreenCapture * capture); gst_d3d11_winrt_capture_unlock_stop (GstD3D11ScreenCapture * capture);
@ -296,8 +293,6 @@ gst_d3d11_winrt_capture_class_init (GstD3D11WinRTCaptureClass * klass)
capture_class->prepare = GST_DEBUG_FUNCPTR (gst_d3d11_winrt_capture_prepare); capture_class->prepare = GST_DEBUG_FUNCPTR (gst_d3d11_winrt_capture_prepare);
capture_class->get_size = capture_class->get_size =
GST_DEBUG_FUNCPTR (gst_d3d11_winrt_capture_get_size); GST_DEBUG_FUNCPTR (gst_d3d11_winrt_capture_get_size);
capture_class->get_colorimetry =
GST_DEBUG_FUNCPTR (gst_d3d11_winrt_capture_get_colorimetry);
capture_class->unlock = GST_DEBUG_FUNCPTR (gst_d3d11_winrt_capture_unlock); capture_class->unlock = GST_DEBUG_FUNCPTR (gst_d3d11_winrt_capture_unlock);
capture_class->unlock_stop = capture_class->unlock_stop =
GST_DEBUG_FUNCPTR (gst_d3d11_winrt_capture_unlock_stop); GST_DEBUG_FUNCPTR (gst_d3d11_winrt_capture_unlock_stop);
@ -750,13 +745,6 @@ gst_d3d11_winrt_capture_get_size (GstD3D11ScreenCapture * capture,
return TRUE; return TRUE;
} }
static gboolean
gst_d3d11_winrt_capture_get_colorimetry (GstD3D11ScreenCapture * capture,
GstVideoColorimetry * colorimetry)
{
return FALSE;
}
static gboolean static gboolean
gst_d3d11_winrt_capture_unlock (GstD3D11ScreenCapture * capture) gst_d3d11_winrt_capture_unlock (GstD3D11ScreenCapture * capture)
{ {