if (!cpad->convert) {
GstD3D11Format in_format, out_format;
+ GstDxgiColorSpace in_space, out_space;
cpad->convert = gst_d3d11_converter_new (self->device, &pad->info, info);
if (!cpad->convert) {
in_format.dxgi_format != DXGI_FORMAT_UNKNOWN &&
gst_d3d11_device_get_format (self->device,
GST_VIDEO_INFO_FORMAT (info), &out_format) &&
- out_format.dxgi_format != DXGI_FORMAT_UNKNOWN) {
- const GstDxgiColorSpace *in_space;
- const GstDxgiColorSpace *out_space;
-
- in_space = gst_d3d11_video_info_to_dxgi_color_space (&pad->info);
- out_space = gst_d3d11_video_info_to_dxgi_color_space (info);
-
- if (in_space && out_space) {
- GstD3D11VideoProcessor *processor =
- gst_d3d11_video_processor_new (self->device,
- pad->info.width, pad->info.height, info->width,
- info->height);
-
- if (processor) {
- if (gst_d3d11_video_processor_check_format_conversion (processor,
- in_format.dxgi_format,
- (DXGI_COLOR_SPACE_TYPE) in_space->dxgi_color_space_type,
- in_format.dxgi_format,
- (DXGI_COLOR_SPACE_TYPE) out_space->dxgi_color_space_type) &&
- gst_d3d11_video_processor_set_input_dxgi_color_space (processor,
- (DXGI_COLOR_SPACE_TYPE) in_space->dxgi_color_space_type) &&
- gst_d3d11_video_processor_set_output_dxgi_color_space (processor,
- (DXGI_COLOR_SPACE_TYPE) out_space->dxgi_color_space_type)) {
- cpad->processor = processor;
- GST_DEBUG_OBJECT (pad, "Video processor is available");
- } else {
- gst_d3d11_video_processor_free (processor);
- }
+ out_format.dxgi_format != DXGI_FORMAT_UNKNOWN &&
+ gst_d3d11_video_info_to_dxgi_color_space (&pad->info, &in_space) &&
+ gst_d3d11_video_info_to_dxgi_color_space (info, &out_space)) {
+ GstD3D11VideoProcessor *processor =
+ gst_d3d11_video_processor_new (self->device,
+ pad->info.width, pad->info.height, info->width,
+ info->height);
+
+ if (processor) {
+ if (gst_d3d11_video_processor_check_format_conversion (processor,
+ in_format.dxgi_format,
+ (DXGI_COLOR_SPACE_TYPE) in_space.dxgi_color_space_type,
+ in_format.dxgi_format,
+ (DXGI_COLOR_SPACE_TYPE) out_space.dxgi_color_space_type) &&
+ gst_d3d11_video_processor_set_input_dxgi_color_space (processor,
+ (DXGI_COLOR_SPACE_TYPE) in_space.dxgi_color_space_type) &&
+ gst_d3d11_video_processor_set_output_dxgi_color_space (processor,
+ (DXGI_COLOR_SPACE_TYPE) out_space.dxgi_color_space_type)) {
+ cpad->processor = processor;
+ GST_DEBUG_OBJECT (pad, "Video processor is available");
+ } else {
+ gst_d3d11_video_processor_free (processor);
}
}
}
}
if (processor) {
- const GstDxgiColorSpace *in_color_space;
- const GstDxgiColorSpace *out_color_space;
+ GstDxgiColorSpace in_space, out_space;
- in_color_space = gst_d3d11_video_info_to_dxgi_color_space (in_info);
- out_color_space = gst_d3d11_video_info_to_dxgi_color_space (out_info);
-
- if (in_color_space && out_color_space) {
+ if (gst_d3d11_video_info_to_dxgi_color_space (in_info, &in_space) &&
+ gst_d3d11_video_info_to_dxgi_color_space (out_info, &out_space)) {
DXGI_FORMAT in_dxgi_format = self->in_d3d11_format.dxgi_format;
DXGI_FORMAT out_dxgi_format = self->out_d3d11_format.dxgi_format;
DXGI_COLOR_SPACE_TYPE in_dxgi_color_space =
- (DXGI_COLOR_SPACE_TYPE) in_color_space->dxgi_color_space_type;
+ (DXGI_COLOR_SPACE_TYPE) in_space.dxgi_color_space_type;
DXGI_COLOR_SPACE_TYPE out_dxgi_color_space =
- (DXGI_COLOR_SPACE_TYPE) out_color_space->dxgi_color_space_type;
+ (DXGI_COLOR_SPACE_TYPE) out_space.dxgi_color_space_type;
if (!gst_d3d11_video_processor_check_format_conversion (processor,
in_dxgi_format, in_dxgi_color_space, out_dxgi_format,
#define SCORE_PRIMARY_MISMATCH 10
static gint
-get_score (GstVideoInfo * info, const GstDxgiColorSpace * color_map,
+get_score (const GstVideoInfo * info, const GstDxgiColorSpace * color_map,
gboolean is_yuv)
{
gint loss = 0;
- GstVideoColorimetry *color = &info->colorimetry;
+ const GstVideoColorimetry *color = &info->colorimetry;
if (color->range != color_map->range)
loss += SCORE_RANGE_MISMATCH;
return loss;
}
-static const GstDxgiColorSpace *
-gst_d3d11_video_info_to_dxgi_color_space_rgb (GstVideoInfo * info)
+static gboolean
+gst_d3d11_video_info_to_dxgi_color_space_rgb (const GstVideoInfo * info,
+ GstDxgiColorSpace * color_space)
{
gint best_score = G_MAXINT;
gint score;
guint i;
- const GstDxgiColorSpace *colorspace = NULL;
+ const GstDxgiColorSpace *best = nullptr;
for (i = 0; i < G_N_ELEMENTS (rgb_colorspace_map); i++) {
score = get_score (info, &rgb_colorspace_map[i], FALSE);
if (score < best_score) {
best_score = score;
- colorspace = &rgb_colorspace_map[i];
+ best = &rgb_colorspace_map[i];
- if (score == 0)
- break;
+ if (score == 0) {
+ *color_space = rgb_colorspace_map[i];
+ return TRUE;
+ }
}
}
- return colorspace;
+ if (best) {
+ *color_space = *best;
+ return TRUE;
+ }
+
+ return FALSE;
}
-static const GstDxgiColorSpace *
-gst_d3d11_video_info_to_dxgi_color_space_yuv (GstVideoInfo * info)
+static gboolean
+gst_d3d11_video_info_to_dxgi_color_space_yuv (const GstVideoInfo * info,
+ GstDxgiColorSpace * color_space)
{
gint best_score = G_MAXINT;
gint score;
guint i;
- const GstDxgiColorSpace *colorspace = NULL;
+ const GstDxgiColorSpace *best = nullptr;
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;
- colorspace = &yuv_colorspace_map[i];
+ best = &yuv_colorspace_map[i];
- if (score == 0)
- break;
+ if (score == 0) {
+ *color_space = rgb_colorspace_map[i];
+ return TRUE;
+ }
}
}
- return colorspace;
+ if (best) {
+ *color_space = *best;
+ return TRUE;
+ }
+
+ return FALSE;
}
-const GstDxgiColorSpace *
-gst_d3d11_video_info_to_dxgi_color_space (GstVideoInfo * info)
+gboolean
+gst_d3d11_video_info_to_dxgi_color_space (const GstVideoInfo * info,
+ GstDxgiColorSpace * color_space)
{
- g_return_val_if_fail (info != NULL, NULL);
+ g_return_val_if_fail (info != nullptr, FALSE);
+ g_return_val_if_fail (color_space != nullptr, FALSE);
- if (GST_VIDEO_INFO_IS_RGB (info)) {
- 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);
- }
+ if (GST_VIDEO_INFO_IS_RGB (info))
+ return gst_d3d11_video_info_to_dxgi_color_space_rgb (info, color_space);
- return NULL;
+ return gst_d3d11_video_info_to_dxgi_color_space_yuv (info, color_space);
}
-const GstDxgiColorSpace *
-gst_d3d11_find_swap_chain_color_space (GstVideoInfo * info,
- IDXGISwapChain3 * swapchain)
+gboolean
+gst_d3d11_find_swap_chain_color_space (const GstVideoInfo * info,
+ IDXGISwapChain3 * swapchain, GstDxgiColorSpace * color_space)
{
- const GstDxgiColorSpace *colorspace = NULL;
- gint best_score = G_MAXINT;
- guint i;
UINT can_support = 0;
HRESULT hr;
- GST_DXGI_COLOR_SPACE_TYPE cur_type;
- /* list of tested display color spaces */
- static GST_DXGI_COLOR_SPACE_TYPE whitelist[] = {
- GST_DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709,
- GST_DXGI_COLOR_SPACE_RGB_FULL_G10_NONE_P709,
- };
g_return_val_if_fail (info != NULL, FALSE);
g_return_val_if_fail (swapchain != NULL, FALSE);
+ g_return_val_if_fail (color_space != NULL, FALSE);
if (!GST_VIDEO_INFO_IS_RGB (info)) {
GST_WARNING ("Swapchain colorspace should be RGB format");
hr = swapchain->CheckColorSpaceSupport ((DXGI_COLOR_SPACE_TYPE) pq,
&can_support);
if (SUCCEEDED (hr) && can_support) {
- for (i = 0; i < G_N_ELEMENTS (rgb_colorspace_map); i++) {
- if (rgb_colorspace_map[i].dxgi_color_space_type == pq)
- return &rgb_colorspace_map[i];
- }
+ color_space->dxgi_color_space_type = pq;
+ color_space->range = GST_VIDEO_COLOR_RANGE_0_255;
+ color_space->matrix = GST_VIDEO_COLOR_MATRIX_RGB;
+ color_space->transfer = GST_VIDEO_TRANSFER_SMPTE2084;
+ color_space->primaries = GST_VIDEO_COLOR_PRIMARIES_BT2020;
+ return TRUE;
}
}
- for (i = 0; i < G_N_ELEMENTS (rgb_colorspace_map); i++) {
- can_support = 0;
- gint score;
- gboolean valid = FALSE;
-
- cur_type =
- (GST_DXGI_COLOR_SPACE_TYPE) rgb_colorspace_map[i].dxgi_color_space_type;
-
- for (guint j = 0; j < G_N_ELEMENTS (whitelist); j++) {
- if (whitelist[j] == cur_type) {
- valid = TRUE;
- break;
- }
- }
-
- if (!valid)
- continue;
-
- hr = swapchain->CheckColorSpaceSupport ((DXGI_COLOR_SPACE_TYPE) 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;
- colorspace = &rgb_colorspace_map[i];
- }
- }
+ /* otherwise use standard sRGB color space */
+ hr = swapchain->CheckColorSpaceSupport (
+ (DXGI_COLOR_SPACE_TYPE) GST_DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709,
+ &can_support);
+ if (SUCCEEDED (hr) && can_support) {
+ color_space->dxgi_color_space_type =
+ GST_DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709;
+ color_space->range = GST_VIDEO_COLOR_RANGE_0_255;
+ color_space->matrix = GST_VIDEO_COLOR_MATRIX_RGB;
+ color_space->transfer = GST_VIDEO_TRANSFER_BT709;
+ color_space->primaries = GST_VIDEO_COLOR_PRIMARIES_BT709;
+ return TRUE;
}
- return colorspace;
+ return FALSE;
}
static void
GstVideoContentLightLevel * cll,
DXGI_HDR_METADATA_HDR10 * dxgi_hdr10);
-const GstDxgiColorSpace * gst_d3d11_video_info_to_dxgi_color_space (GstVideoInfo * info);
+gboolean gst_d3d11_video_info_to_dxgi_color_space (const GstVideoInfo * info,
+ GstDxgiColorSpace * color_space);
-const GstDxgiColorSpace * gst_d3d11_find_swap_chain_color_space (GstVideoInfo * info,
- IDXGISwapChain3 * swapchain);
+gboolean gst_d3d11_find_swap_chain_color_space (const GstVideoInfo * info,
+ IDXGISwapChain3 * swapchain,
+ GstDxgiColorSpace * color_space);
GstBuffer * gst_d3d11_allocate_staging_buffer_for (GstBuffer * buffer,
const GstVideoInfo * info,
{DXGI_FORMAT_R10G10B10A2_UNORM, GST_VIDEO_FORMAT_RGB10A2_LE, FALSE},
};
const GstD3D11WindowDisplayFormat *chosen_format = NULL;
- const GstDxgiColorSpace *chosen_colorspace = NULL;
+ GstDxgiColorSpace swapchain_colorspace;
+ gboolean found_swapchain_colorspace = FALSE;
gboolean have_hdr10 = FALSE;
DXGI_COLOR_SPACE_TYPE native_colorspace_type =
DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709;
DXGI_HDR_METADATA_HDR10 hdr10_metadata = { 0, };
+ GstDxgiColorSpace in_dxgi_colorspace;
/* Step 1: Clear old resources and objects */
gst_clear_buffer (&window->cached_buffer);
hr = window->swap_chain->QueryInterface (IID_PPV_ARGS (&swapchain3));
if (gst_d3d11_result (hr, window->device)) {
- chosen_colorspace =
+ found_swapchain_colorspace =
gst_d3d11_find_swap_chain_color_space (&window->render_info,
- swapchain3.Get ());
- if (chosen_colorspace) {
+ swapchain3.Get (), &swapchain_colorspace);
+ if (found_swapchain_colorspace) {
native_colorspace_type =
- (DXGI_COLOR_SPACE_TYPE) chosen_colorspace->dxgi_color_space_type;
+ (DXGI_COLOR_SPACE_TYPE) swapchain_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;
+ found_swapchain_colorspace = FALSE;
native_colorspace_type = DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709;
} else {
GST_DEBUG_OBJECT (window,
/* update with selected display color space */
window->render_info.colorimetry.primaries =
- chosen_colorspace->primaries;
+ swapchain_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;
+ swapchain_colorspace.transfer;
+ window->render_info.colorimetry.range = swapchain_colorspace.range;
+ window->render_info.colorimetry.matrix = swapchain_colorspace.matrix;
}
}
}
/* otherwise, use most common DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709
* color space */
- if (!chosen_colorspace) {
+ if (!found_swapchain_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;
- }
-
- if (chosen_colorspace) {
- const GstDxgiColorSpace *in_color_space =
- gst_d3d11_video_info_to_dxgi_color_space (&window->info);
+ window->render_info.colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_RGB;
+ } else if (gst_d3d11_video_info_to_dxgi_color_space (&window->info,
+ &in_dxgi_colorspace)) {
GstD3D11Format in_format;
gboolean hardware = FALSE;
GstD3D11VideoProcessor *processor = NULL;
GST_VIDEO_INFO_FORMAT (&window->info), &in_format);
in_dxgi_format = in_format.dxgi_format;
- if (in_color_space && in_format.dxgi_format != DXGI_FORMAT_UNKNOWN) {
+ if (in_format.dxgi_format != DXGI_FORMAT_UNKNOWN) {
g_object_get (window->device, "hardware", &hardware, NULL);
}
if (processor) {
DXGI_FORMAT out_dxgi_format = chosen_format->dxgi_format;
DXGI_COLOR_SPACE_TYPE in_dxgi_color_space =
- (DXGI_COLOR_SPACE_TYPE) in_color_space->dxgi_color_space_type;
+ (DXGI_COLOR_SPACE_TYPE) in_dxgi_colorspace.dxgi_color_space_type;
DXGI_COLOR_SPACE_TYPE out_dxgi_color_space = native_colorspace_type;
if (!gst_d3d11_video_processor_check_format_conversion (processor,
guint display_width, guint display_height, GstCaps * caps,
gboolean * video_processor_available, GError ** error)
{
+ GstDxgiColorSpace in_space;
+
g_clear_pointer (&window->processor, gst_d3d11_video_processor_free);
g_clear_pointer (&window->compositor, gst_d3d11_overlay_compositor_free);
gst_clear_object (&window->converter);
gst_d3d11_device_lock (window->device);
- {
- const GstDxgiColorSpace *in_color_space =
- gst_d3d11_video_info_to_dxgi_color_space (&window->info);
+ if (gst_d3d11_video_info_to_dxgi_color_space (&window->info, &in_space)) {
GstD3D11Format in_format;
gboolean hardware = FALSE;
GstD3D11VideoProcessor *processor = NULL;
GST_VIDEO_INFO_FORMAT (&window->info), &in_format);
in_dxgi_format = in_format.dxgi_format;
- if (in_color_space && in_format.dxgi_format != DXGI_FORMAT_UNKNOWN) {
+ if (in_format.dxgi_format != DXGI_FORMAT_UNKNOWN) {
g_object_get (window->device, "hardware", &hardware, NULL);
}
for (i = 0; i < G_N_ELEMENTS (formats_to_check) && processor; i++) {
DXGI_FORMAT out_dxgi_format = formats_to_check[i];
DXGI_COLOR_SPACE_TYPE in_dxgi_color_space =
- (DXGI_COLOR_SPACE_TYPE) in_color_space->dxgi_color_space_type;
+ (DXGI_COLOR_SPACE_TYPE) in_space.dxgi_color_space_type;
if (!gst_d3d11_video_processor_check_format_conversion (processor,
in_dxgi_format, in_dxgi_color_space, out_dxgi_format,
if (processor) {
gst_d3d11_video_processor_set_input_dxgi_color_space (processor,
- (DXGI_COLOR_SPACE_TYPE) in_color_space->dxgi_color_space_type);
+ (DXGI_COLOR_SPACE_TYPE) in_space.dxgi_color_space_type);
gst_d3d11_video_processor_set_output_dxgi_color_space (processor,
DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709);
}