From: Seungha Yang Date: Tue, 3 Dec 2019 13:54:26 +0000 (+0900) Subject: d3d11videosink: Add color conversion support X-Git-Tag: 1.19.3~507^2~2581 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ca3ddf784814c0427daefbc175c17e66dff91c11;p=platform%2Fupstream%2Fgstreamer.git d3d11videosink: Add color conversion support Draw to back buffer texture directly. It would reduce the number of copy at least once when color conversion is required. --- diff --git a/sys/d3d11/gstd3d11colorconverter.c b/sys/d3d11/gstd3d11colorconverter.c index f05bfb0..d0a2934 100644 --- a/sys/d3d11/gstd3d11colorconverter.c +++ b/sys/d3d11/gstd3d11colorconverter.c @@ -943,3 +943,17 @@ gst_d3d11_color_converter_convert (GstD3D11ColorConverter * converter, return data.ret; } + +gboolean +gst_d3d11_color_converter_update_rect (GstD3D11ColorConverter * converter, + RECT * rect) +{ + g_return_val_if_fail (converter != NULL, FALSE); + + converter->viewport.TopLeftX = rect->left; + converter->viewport.TopLeftY = rect->top; + converter->viewport.Width = rect->right - rect->left; + converter->viewport.Height = rect->bottom - rect->top; + + return TRUE; +} diff --git a/sys/d3d11/gstd3d11colorconverter.h b/sys/d3d11/gstd3d11colorconverter.h index 760d6cf..ad9fde9 100644 --- a/sys/d3d11/gstd3d11colorconverter.h +++ b/sys/d3d11/gstd3d11colorconverter.h @@ -38,6 +38,9 @@ gboolean gst_d3d11_color_converter_convert (GstD3D11ColorConvert ID3D11ShaderResourceView *srv[GST_VIDEO_MAX_PLANES], ID3D11RenderTargetView *rtv[GST_VIDEO_MAX_PLANES]); +gboolean gst_d3d11_color_converter_update_rect (GstD3D11ColorConverter * converter, + RECT *rect); + G_END_DECLS #endif /* __GST_D3D11_COLOR_CONVERTER_H__ */ diff --git a/sys/d3d11/gstd3d11videosink.c b/sys/d3d11/gstd3d11videosink.c index 35e96b6..cb1f7fc 100644 --- a/sys/d3d11/gstd3d11videosink.c +++ b/sys/d3d11/gstd3d11videosink.c @@ -26,6 +26,7 @@ #include "gstd3d11utils.h" #include "gstd3d11device.h" #include "gstd3d11bufferpool.h" +#include "gstd3d11format.h" enum { @@ -39,13 +40,11 @@ enum #define DEFAULT_FORCE_ASPECT_RATIO TRUE #define DEFAULT_ENABLE_NAVIGATION_EVENTS TRUE -#define CAPS_FORMAT "{ BGRA, RGBA, RGB10A2_LE }" - static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE_WITH_FEATURES - (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY, CAPS_FORMAT) + (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY, GST_D3D11_FORMATS) )); GST_DEBUG_CATEGORY (d3d11_video_sink_debug); @@ -221,10 +220,9 @@ gst_d3d11_video_sink_get_caps (GstBaseSink * sink, GstCaps * filter) GstD3D11VideoSink *self = GST_D3D11_VIDEO_SINK (sink); GstCaps *caps = NULL; - if (self->device) + if (self->device && !self->can_convert) caps = gst_d3d11_device_get_supported_caps (self->device, - D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_DISPLAY | - D3D11_FORMAT_SUPPORT_RENDER_TARGET); + D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_DISPLAY); if (!caps) caps = gst_pad_get_pad_template_caps (GST_VIDEO_SINK_PAD (sink)); @@ -243,36 +241,20 @@ static gboolean gst_d3d11_video_sink_set_caps (GstBaseSink * sink, GstCaps * caps) { GstD3D11VideoSink *self = GST_D3D11_VIDEO_SINK (sink); - GstCaps *sink_caps = NULL; gint video_width, video_height; gint video_par_n, video_par_d; /* video's PAR */ gint display_par_n = 1, display_par_d = 1; /* display's PAR */ guint num, den; GError *error = NULL; - const GstD3D11Format *d3d11_format = NULL; GstStructure *config; + GstD3D11AllocationParams *d3d11_params; + gint i; GST_DEBUG_OBJECT (self, "set caps %" GST_PTR_FORMAT, caps); - sink_caps = gst_d3d11_device_get_supported_caps (self->device, - D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_DISPLAY | - D3D11_FORMAT_SUPPORT_RENDER_TARGET); - - GST_DEBUG_OBJECT (self, "supported caps %" GST_PTR_FORMAT, sink_caps); - - if (!gst_caps_can_intersect (sink_caps, caps)) - goto incompatible_caps; - - gst_clear_caps (&sink_caps); - if (!gst_video_info_from_caps (&self->info, caps)) goto invalid_format; - d3d11_format = - gst_d3d11_format_from_gst (GST_VIDEO_INFO_FORMAT (&self->info)); - if (!d3d11_format || d3d11_format->dxgi_format == DXGI_FORMAT_UNKNOWN) - goto invalid_format; - video_width = GST_VIDEO_INFO_WIDTH (&self->info); video_height = GST_VIDEO_INFO_HEIGHT (&self->info); video_par_n = GST_VIDEO_INFO_PAR_N (&self->info); @@ -326,8 +308,6 @@ gst_d3d11_video_sink_set_caps (GstBaseSink * sink, GstCaps * caps) if (GST_VIDEO_SINK_WIDTH (self) <= 0 || GST_VIDEO_SINK_HEIGHT (self) <= 0) goto no_display_size; - self->dxgi_format = d3d11_format->dxgi_format; - if (!self->window_id) gst_video_overlay_prepare_window_handle (GST_VIDEO_OVERLAY (self)); @@ -359,7 +339,7 @@ gst_d3d11_video_sink_set_caps (GstBaseSink * sink, GstCaps * caps) if (!gst_d3d11_window_prepare (self->window, GST_VIDEO_SINK_WIDTH (self), GST_VIDEO_SINK_HEIGHT (self), video_par_n, video_par_d, - self->dxgi_format, caps, &error)) { + caps, &error)) { GstMessage *error_msg; GST_ERROR_OBJECT (self, "cannot create swapchain"); @@ -380,17 +360,26 @@ gst_d3d11_video_sink_set_caps (GstBaseSink * sink, GstCaps * caps) config = gst_buffer_pool_get_config (self->fallback_pool); gst_buffer_pool_config_set_params (config, caps, GST_VIDEO_INFO_SIZE (&self->info), 0, 2); + + d3d11_params = gst_buffer_pool_config_get_d3d11_allocation_params (config); + if (!d3d11_params) { + d3d11_params = gst_d3d11_allocation_params_new (&self->info, + GST_D3D11_ALLOCATION_FLAG_USE_RESOURCE_FORMAT, D3D11_USAGE_DEFAULT, + D3D11_BIND_SHADER_RESOURCE); + } else { + /* Set bind flag */ + for (i = 0; i < GST_VIDEO_INFO_N_PLANES (&self->info); i++) { + d3d11_params->desc[i].BindFlags |= D3D11_BIND_SHADER_RESOURCE; + } + } + + gst_buffer_pool_config_set_d3d11_allocation_params (config, d3d11_params); + gst_d3d11_allocation_params_free (d3d11_params); gst_buffer_pool_set_config (self->fallback_pool, config); return TRUE; /* ERRORS */ -incompatible_caps: - { - GST_ERROR_OBJECT (sink, "caps incompatible"); - gst_clear_caps (&sink_caps); - return FALSE; - } invalid_format: { GST_DEBUG_OBJECT (sink, @@ -447,6 +436,7 @@ static gboolean gst_d3d11_video_sink_start (GstBaseSink * sink) { GstD3D11VideoSink *self = GST_D3D11_VIDEO_SINK (sink); + gboolean is_hardware = TRUE; GST_DEBUG_OBJECT (self, "Start"); @@ -462,6 +452,15 @@ gst_d3d11_video_sink_start (GstBaseSink * sink) return FALSE; } + g_object_get (self->device, "hardware", &is_hardware, NULL); + + if (!is_hardware) { + GST_WARNING_OBJECT (self, "D3D11 device is running on software emulation"); + self->can_convert = FALSE; + } else { + self->can_convert = TRUE; + } + g_object_set (self->window, "enable-navigation-events", self->enable_navigation_events, NULL); @@ -520,6 +519,9 @@ gst_d3d11_video_sink_propose_allocation (GstBaseSink * sink, GstQuery * query) size = info.size; if (need_pool) { + GstD3D11AllocationParams *d3d11_params; + gint i; + GST_DEBUG_OBJECT (self, "create new pool"); pool = gst_d3d11_buffer_pool_new (self->device); @@ -527,6 +529,21 @@ gst_d3d11_video_sink_propose_allocation (GstBaseSink * sink, GstQuery * query) gst_buffer_pool_config_set_params (config, caps, size, 2, DXGI_MAX_SWAP_CHAIN_BUFFERS); + d3d11_params = gst_buffer_pool_config_get_d3d11_allocation_params (config); + if (!d3d11_params) { + d3d11_params = gst_d3d11_allocation_params_new (&info, + GST_D3D11_ALLOCATION_FLAG_USE_RESOURCE_FORMAT, D3D11_USAGE_DEFAULT, + D3D11_BIND_SHADER_RESOURCE); + } else { + /* Set bind flag */ + for (i = 0; i < GST_VIDEO_INFO_N_PLANES (&info); i++) { + d3d11_params->desc[i].BindFlags |= D3D11_BIND_SHADER_RESOURCE; + } + } + + gst_buffer_pool_config_set_d3d11_allocation_params (config, d3d11_params); + gst_d3d11_allocation_params_free (d3d11_params); + if (!gst_buffer_pool_set_config (pool, config)) { g_object_unref (pool); goto config_failed; @@ -612,19 +629,34 @@ gst_d3d11_video_sink_show_frame (GstVideoSink * sink, GstBuffer * buf) GstD3D11VideoSink *self = GST_D3D11_VIDEO_SINK (sink); GstMapInfo map; GstFlowReturn ret; - GstMemory *mem; GstVideoRectangle rect = { 0, }; GstVideoCropMeta *crop; GstBuffer *render_buf; gboolean need_unref = FALSE; + gint i; + + render_buf = buf; + + for (i = 0; i < gst_buffer_n_memory (buf); i++) { + GstMemory *mem; + GstD3D11Memory *dmem; - if (gst_buffer_n_memory (buf) == 1 && (mem = gst_buffer_peek_memory (buf, 0)) - && gst_memory_is_type (mem, GST_D3D11_MEMORY_NAME)) { - GstD3D11Memory *dmem = (GstD3D11Memory *) mem; + mem = gst_buffer_peek_memory (buf, i); + if (!gst_is_d3d11_memory (mem)) { + render_buf = NULL; + break; + } - /* If this buffer has been allocated using our buffer management we simply - put the ximage which is in the PRIVATE pointer */ - GST_TRACE_OBJECT (self, "buffer %p from our pool, writing directly", buf); + dmem = (GstD3D11Memory *) mem; + if (dmem->device != self->device) { + render_buf = NULL; + break; + } + + if (!gst_d3d11_memory_ensure_shader_resource_view (mem)) { + render_buf = NULL; + break; + } if (dmem->desc.Usage == D3D11_USAGE_DEFAULT) { if (!gst_memory_map (mem, &map, (GST_MAP_READ | GST_MAP_D3D11))) { @@ -634,9 +666,9 @@ gst_d3d11_video_sink_show_frame (GstVideoSink * sink, GstBuffer * buf) gst_memory_unmap (mem, &map); } + } - render_buf = buf; - } else { + if (!render_buf) { GstVideoFrame frame, fallback_frame; if (!self->fallback_pool || diff --git a/sys/d3d11/gstd3d11videosink.h b/sys/d3d11/gstd3d11videosink.h index 5e6ac7c..768bdf0 100644 --- a/sys/d3d11/gstd3d11videosink.h +++ b/sys/d3d11/gstd3d11videosink.h @@ -50,7 +50,6 @@ struct _GstD3D11VideoSink gint video_height; GstVideoInfo info; - DXGI_FORMAT dxgi_format; guintptr window_id; @@ -64,6 +63,7 @@ struct _GstD3D11VideoSink gboolean pending_render_rect; GstBufferPool *fallback_pool; + gboolean can_convert; }; struct _GstD3D11VideoSinkClass diff --git a/sys/d3d11/gstd3d11window.c b/sys/d3d11/gstd3d11window.c index 316d591..bd68617 100644 --- a/sys/d3d11/gstd3d11window.c +++ b/sys/d3d11/gstd3d11window.c @@ -27,6 +27,7 @@ #include "gstd3d11window.h" #include "gstd3d11device.h" #include "gstd3d11memory.h" +#include "gstd3d11utils.h" #include @@ -258,6 +259,11 @@ gst_d3d11_window_dispose (GObject * object) (GstD3D11DeviceThreadFunc) gst_d3d11_window_release_resources, self); } + if (self->converter) { + gst_d3d11_color_converter_free (self->converter); + self->converter = NULL; + } + gst_clear_buffer (&self->cached_buffer); gst_clear_object (&self->device); @@ -521,52 +527,75 @@ gst_d3d11_window_on_resize (GstD3D11Device * device, GstD3D11Window * window) window->rtv = NULL; } - /* NOTE: there can be various way to resize texture, but - * we just copy incoming texture toward resized swap chain buffer in order to - * avoid shader coding. - * To keep aspect ratio, required vertical or horizontal padding area - * will be calculated in here. - */ width = window->width; height = window->height; if (width != window->surface_width || height != window->surface_height) { GstVideoRectangle src_rect, dst_rect; - gdouble src_ratio, dst_ratio; - gdouble aspect_ratio = - (gdouble) window->aspect_ratio_n / (gdouble) window->aspect_ratio_d; - - src_ratio = (gdouble) width / height; - dst_ratio = - (gdouble) window->surface_width / window->surface_height / aspect_ratio; src_rect.x = 0; src_rect.y = 0; - src_rect.w = width; - src_rect.h = height; + src_rect.w = width * window->aspect_ratio_n; + src_rect.h = height * window->aspect_ratio_d; dst_rect.x = 0; dst_rect.y = 0; + dst_rect.w = window->surface_width; + dst_rect.h = window->surface_height; - if (window->force_aspect_ratio) { - if (src_ratio > dst_ratio) { - /* padding top and bottom */ - dst_rect.w = width; - dst_rect.h = width / dst_ratio; + if (window->converter) { + if (window->force_aspect_ratio) { + src_rect.w = width * window->aspect_ratio_n; + src_rect.h = height * window->aspect_ratio_d; + + gst_video_sink_center_rect (src_rect, dst_rect, &window->render_rect, + TRUE); } else { - /* padding left and right */ - dst_rect.w = height * dst_ratio; - dst_rect.h = height; + window->render_rect = dst_rect; } + + width = window->surface_width; + height = window->surface_height; } else { - dst_rect.w = width; - dst_rect.h = height; - } + /* NOTE: there can be various way to resize texture, but + * we just copy incoming texture toward resized swap chain buffer in order to + * avoid shader coding. + * To keep aspect ratio, required vertical or horizontal padding area + * will be calculated in here. + */ + gdouble src_ratio, dst_ratio; + gdouble aspect_ratio = + (gdouble) window->aspect_ratio_n / (gdouble) window->aspect_ratio_d; + + src_ratio = (gdouble) width / height; + dst_ratio = + (gdouble) window->surface_width / window->surface_height / + aspect_ratio; + + src_rect.w = width; + src_rect.h = height; + + if (window->force_aspect_ratio) { + if (src_ratio > dst_ratio) { + /* padding top and bottom */ + dst_rect.w = width; + dst_rect.h = width / dst_ratio; + } else { + /* padding left and right */ + dst_rect.w = height * dst_ratio; + dst_rect.h = height; + } + } else { + dst_rect.w = width; + dst_rect.h = height; + } - gst_video_sink_center_rect (src_rect, dst_rect, &window->render_rect, TRUE); + gst_video_sink_center_rect (src_rect, dst_rect, &window->render_rect, + TRUE); - width = dst_rect.w; - height = dst_rect.h; + width = dst_rect.w; + height = dst_rect.h; + } } hr = IDXGISwapChain_ResizeBuffers (window->swap_chain, @@ -824,21 +853,63 @@ mastering_display_gst_to_dxgi (GstVideoMasteringDisplayInfo * m, gboolean gst_d3d11_window_prepare (GstD3D11Window * window, guint width, guint height, - guint aspect_ratio_n, guint aspect_ratio_d, DXGI_FORMAT format, - GstCaps * caps, GError ** error) + guint aspect_ratio_n, guint aspect_ratio_d, GstCaps * caps, GError ** error) { DXGI_SWAP_CHAIN_DESC desc = { 0, }; gboolean have_cll = FALSE; gboolean have_mastering = FALSE; gboolean hdr_api_available = FALSE; GstD3D11ThreadFuncData data; + GstCaps *render_caps; g_return_val_if_fail (GST_IS_D3D11_WINDOW (window), FALSE); g_return_val_if_fail (aspect_ratio_n > 0, FALSE); g_return_val_if_fail (aspect_ratio_d > 0, FALSE); - GST_DEBUG_OBJECT (window, "Prepare window with %dx%d format %d", - width, height, format); + GST_DEBUG_OBJECT (window, "Prepare window with %dx%d caps %" GST_PTR_FORMAT, + width, height, caps); + + render_caps = gst_d3d11_device_get_supported_caps (window->device, + 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"); + 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_format_from_gst (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"); + return FALSE; + } + + gst_video_info_from_caps (&window->info, caps); + + if (window->converter) + gst_d3d11_color_converter_free (window->converter); + window->converter = NULL; + + if (GST_VIDEO_INFO_FORMAT (&window->info) != + GST_VIDEO_INFO_FORMAT (&window->render_info)) { + window->converter = + gst_d3d11_color_converter_new (window->device, &window->info, + &window->render_info); + + if (!window->converter) { + GST_ERROR_OBJECT (window, "Cannot create converter"); + return FALSE; + } + } data.self = window; data.error = error; @@ -861,7 +932,6 @@ gst_d3d11_window_prepare (GstD3D11Window * window, guint width, guint height, window->thread = NULL; } - gst_video_info_from_caps (&window->info, caps); if (!gst_video_content_light_level_from_caps (&window->content_light_level, caps)) { gst_video_content_light_level_init (&window->content_light_level); @@ -897,7 +967,7 @@ gst_d3d11_window_prepare (GstD3D11Window * window, guint width, guint height, /* don't care refresh rate */ desc.BufferDesc.RefreshRate.Numerator = 0; desc.BufferDesc.RefreshRate.Denominator = 1; - desc.BufferDesc.Format = format; + desc.BufferDesc.Format = window->render_format->dxgi_format; desc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; desc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; desc.SampleDesc.Count = 1; @@ -925,7 +995,8 @@ gst_d3d11_window_prepare (GstD3D11Window * window, guint width, guint height, return FALSE; } #ifdef HAVE_DXGI_1_5_H - if (hdr_api_available && format == DXGI_FORMAT_R10G10B10A2_UNORM && + if (hdr_api_available && + window->render_format->dxgi_format == DXGI_FORMAT_R10G10B10A2_UNORM && have_cll && have_mastering) { UINT can_support = 0; HRESULT hr; @@ -1068,24 +1139,47 @@ _present_on_device_thread (GstD3D11Device * device, FramePresentData * data) gst_buffer_replace (&self->cached_buffer, data->buffer); if (self->cached_buffer) { - GstD3D11Memory *mem = - (GstD3D11Memory *) gst_buffer_peek_memory (self->cached_buffer, 0); - - self->rect = *data->rect; - src_box.left = self->rect.x; - src_box.right = self->rect.x + self->rect.w; - src_box.top = self->rect.y; - src_box.bottom = self->rect.y + self->rect.h; - src_box.front = 0; - src_box.back = 1; - - ID3D11DeviceContext_OMSetRenderTargets (device_context, - 1, &self->rtv, NULL); - ID3D11DeviceContext_ClearRenderTargetView (device_context, self->rtv, - black); - ID3D11DeviceContext_CopySubresourceRegion (device_context, - (ID3D11Resource *) self->backbuffer, 0, self->render_rect.x, - self->render_rect.y, 0, (ID3D11Resource *) mem->texture, 0, &src_box); + if (self->converter) { + ID3D11ShaderResourceView *srv[GST_VIDEO_MAX_PLANES]; + gint i, j, k; + RECT rect; + + for (i = 0, j = 0; i < gst_buffer_n_memory (self->cached_buffer); i++) { + GstD3D11Memory *mem = + (GstD3D11Memory *) gst_buffer_peek_memory (self->cached_buffer, i); + for (k = 0; k < mem->num_shader_resource_views; k++) { + srv[j] = mem->shader_resource_view[k]; + j++; + } + } + + rect.left = self->render_rect.x; + rect.right = self->render_rect.x + self->render_rect.w; + rect.top = self->render_rect.y; + rect.bottom = self->render_rect.y + self->render_rect.h; + + gst_d3d11_color_converter_update_rect (self->converter, &rect); + gst_d3d11_color_converter_convert (self->converter, srv, &self->rtv); + } else { + GstD3D11Memory *mem = + (GstD3D11Memory *) gst_buffer_peek_memory (self->cached_buffer, 0); + + self->rect = *data->rect; + src_box.left = self->rect.x; + src_box.right = self->rect.x + self->rect.w; + src_box.top = self->rect.y; + src_box.bottom = self->rect.y + self->rect.h; + src_box.front = 0; + src_box.back = 1; + + ID3D11DeviceContext_OMSetRenderTargets (device_context, + 1, &self->rtv, NULL); + ID3D11DeviceContext_ClearRenderTargetView (device_context, self->rtv, + black); + ID3D11DeviceContext_CopySubresourceRegion (device_context, + (ID3D11Resource *) self->backbuffer, 0, self->render_rect.x, + self->render_rect.y, 0, (ID3D11Resource *) mem->texture, 0, &src_box); + } } hr = IDXGISwapChain_Present (self->swap_chain, 0, DXGI_PRESENT_DO_NOT_WAIT); diff --git a/sys/d3d11/gstd3d11window.h b/sys/d3d11/gstd3d11window.h index 91229e3..dc9d0dc 100644 --- a/sys/d3d11/gstd3d11window.h +++ b/sys/d3d11/gstd3d11window.h @@ -25,6 +25,7 @@ #include #include #include "gstd3d11_fwd.h" +#include "gstd3d11colorconverter.h" G_BEGIN_DECLS @@ -45,6 +46,10 @@ struct _GstD3D11Window GstObject parent; GstVideoInfo info; + GstVideoInfo render_info; + const GstD3D11Format *render_format; + GstD3D11ColorConverter *converter; + GstVideoMasteringDisplayInfo mastering_display_info; GstVideoContentLightLevel content_light_level; @@ -124,7 +129,6 @@ gboolean gst_d3d11_window_prepare (GstD3D11Window * window, guint height, guint aspect_ratio_n, guint aspect_ratio_d, - DXGI_FORMAT format, GstCaps * caps, GError ** error);