PROP_ROTATE_METHOD,
PROP_GAMMA_MODE,
PROP_PRIMARIES_MODE,
+ PROP_DISPLAY_FORMAT,
};
#define DEFAULT_ADAPTER -1
#define DEFAULT_DRAW_ON_SHARED_TEXTURE FALSE
#define DEFAULT_GAMMA_MODE GST_VIDEO_GAMMA_MODE_NONE
#define DEFAULT_PRIMARIES_MODE GST_VIDEO_PRIMARIES_MODE_NONE
+#define DEFAULT_DISPLAY_FORMAT DXGI_FORMAT_UNKNOWN
+
+#define GST_TYPE_D3D11_VIDEO_SINK_DISPLAY_FORMAT (gst_d3d11_video_sink_display_format_type())
+static GType
+gst_d3d11_video_sink_display_format_type (void)
+{
+ static GType format_type = 0;
+
+ GST_D3D11_CALL_ONCE_BEGIN {
+ static const GEnumValue format_types[] = {
+ {DXGI_FORMAT_UNKNOWN, "DXGI_FORMAT_UNKNOWN", "unknown"},
+ {DXGI_FORMAT_R10G10B10A2_UNORM,
+ "DXGI_FORMAT_R10G10B10A2_UNORM", "r10g10b10a2-unorm"},
+ {DXGI_FORMAT_R8G8B8A8_UNORM,
+ "DXGI_FORMAT_R8G8B8A8_UNORM", "r8g8b8a8-unorm"},
+ {DXGI_FORMAT_B8G8R8A8_UNORM,
+ "DXGI_FORMAT_B8G8R8A8_UNORM", "b8g8r8a8-unorm"},
+ {0, nullptr, nullptr},
+ };
+
+ format_type = g_enum_register_static ("GstD3D11VideoSinkDisplayFormat",
+ format_types);
+ } GST_D3D11_CALL_ONCE_END;
+
+ return format_type;
+}
enum
{
gboolean draw_on_shared_texture;
GstVideoGammaMode gamma_mode;
GstVideoPrimariesMode primaries_mode;
+ DXGI_FORMAT display_format;
/* saved render rectangle until we have a window */
GstVideoRectangle render_rect;
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
/**
+ * GstD3D11VideoSink:display-format:
+ *
+ * Swapchain display format
+ *
+ * Since: 1.22
+ */
+ g_object_class_install_property (gobject_class, PROP_DISPLAY_FORMAT,
+ g_param_spec_enum ("display-format", "Display Format",
+ "Swapchain display format", GST_TYPE_D3D11_VIDEO_SINK_DISPLAY_FORMAT,
+ DEFAULT_DISPLAY_FORMAT, (GParamFlags) (G_PARAM_READWRITE |
+ GST_PARAM_MUTABLE_READY | G_PARAM_STATIC_STRINGS)));
+
+ /**
* GstD3D11VideoSink::begin-draw:
* @videosink: the #d3d11videosink
*
gst_type_mark_as_plugin_api (GST_D3D11_WINDOW_TOGGLE_MODE_GET_TYPE,
(GstPluginAPIFlags) 0);
+ gst_type_mark_as_plugin_api (GST_TYPE_D3D11_VIDEO_SINK_DISPLAY_FORMAT,
+ (GstPluginAPIFlags) 0);
}
static void
self->draw_on_shared_texture = DEFAULT_DRAW_ON_SHARED_TEXTURE;
self->gamma_mode = DEFAULT_GAMMA_MODE;
self->primaries_mode = DEFAULT_PRIMARIES_MODE;
+ self->display_format = DEFAULT_DISPLAY_FORMAT;
InitializeCriticalSection (&self->lock);
}
case PROP_PRIMARIES_MODE:
self->primaries_mode = (GstVideoPrimariesMode) g_value_get_enum (value);
break;
+ case PROP_DISPLAY_FORMAT:
+ self->display_format = (DXGI_FORMAT) g_value_get_enum (value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
case PROP_PRIMARIES_MODE:
g_value_set_enum (value, self->primaries_mode);
break;
+ case PROP_DISPLAY_FORMAT:
+ g_value_set_enum (value, self->display_format);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
GST_TYPE_VIDEO_PRIMARIES_MODE, self->primaries_mode, nullptr);
if (!gst_d3d11_window_prepare (self->window, GST_VIDEO_SINK_WIDTH (self),
- GST_VIDEO_SINK_HEIGHT (self), caps, config, &error)) {
+ GST_VIDEO_SINK_HEIGHT (self), caps, config, self->display_format,
+ &error)) {
GstMessage *error_msg;
LeaveCriticalSection (&self->lock);
guint width, guint height);
static gboolean gst_d3d11_window_prepare_default (GstD3D11Window * window,
guint display_width, guint display_height, GstCaps * caps,
- GstStructure * config, GError ** error);
+ GstStructure * config, DXGI_FORMAT display_format, GError ** error);
static void
gst_d3d11_window_class_init (GstD3D11WindowClass * klass)
gboolean
gst_d3d11_window_prepare (GstD3D11Window * window, guint display_width,
guint display_height, GstCaps * caps, GstStructure * config,
- GError ** error)
+ DXGI_FORMAT display_format, GError ** error)
{
GstD3D11WindowClass *klass;
GST_PTR_FORMAT, display_width, display_height, caps);
return klass->prepare (window, display_width, display_height, caps, config,
- error);
+ display_format, error);
}
static gboolean
gst_d3d11_window_prepare_default (GstD3D11Window * window, guint display_width,
guint display_height, GstCaps * caps, GstStructure * config,
- GError ** error)
+ DXGI_FORMAT display_format, GError ** error)
{
GstD3D11Device *device = window->device;
GstD3D11WindowClass *klass;
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_R8G8B8A8_UNORM, GST_VIDEO_FORMAT_RGBA, FALSE},
{DXGI_FORMAT_R10G10B10A2_UNORM, GST_VIDEO_FORMAT_RGB10A2_LE, FALSE},
};
- const GstD3D11WindowDisplayFormat *chosen_format = NULL;
+ const GstD3D11WindowDisplayFormat *chosen_format = nullptr;
DXGI_COLOR_SPACE_TYPE swapchain_colorspace =
DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709;
gboolean hdr10_aware = FALSE;
return FALSE;
}
- for (guint 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];
+ if (display_format != DXGI_FORMAT_UNKNOWN) {
+ for (guint i = 0; i < G_N_ELEMENTS (formats); i++) {
+ if (display_format == formats[i].dxgi_format && formats[i].supported) {
+ GST_DEBUG_OBJECT (window, "Requested format %s is supported",
+ gst_d3d11_dxgi_format_to_string (display_format));
+ chosen_format = &formats[i];
+ break;
+ }
+ }
+
+ if (!chosen_format) {
+ GST_ERROR_OBJECT (window, "Requested DXGI FORMAT %d is not supported",
+ display_format);
+ g_set_error (error, GST_RESOURCE_ERROR, GST_RESOURCE_ERROR_FAILED,
+ "Cannot determine render format");
+ if (config)
+ gst_structure_free (config);
+
+ return FALSE;
+ }
+ } else {
+ for (guint 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;
}
- break;
}
}
guint display_height,
GstCaps * caps,
GstStructure * config,
+ DXGI_FORMAT display_format,
GError ** error);
void (*unprepare) (GstD3D11Window * window);
guint display_height,
GstCaps * caps,
GstStructure * config,
+ DXGI_FORMAT display_format,
GError ** error);
GstFlowReturn gst_d3d11_window_render (GstD3D11Window * window,
guint width, guint height);
static gboolean gst_d3d11_window_dummy_prepare (GstD3D11Window * window,
guint display_width, guint display_height, GstCaps * caps,
- GstStructure * config, GError ** error);
+ GstStructure * config, DXGI_FORMAT display_format, GError ** error);
static void gst_d3d11_window_dummy_unprepare (GstD3D11Window * window);
static gboolean
gst_d3d11_window_dummy_open_shared_handle (GstD3D11Window * window,
static gboolean
gst_d3d11_window_dummy_prepare (GstD3D11Window * window,
guint display_width, guint display_height, GstCaps * caps,
- GstStructure * config, GError ** error)
+ GstStructure * config, DXGI_FORMAT display_format, GError ** error)
{
gst_clear_object (&window->compositor);
gst_clear_object (&window->converter);