#define DEFAULT_ENABLE_NAVIGATION_EVENTS TRUE
#define DEFAULT_FULLSCREEN_TOGGLE_MODE GST_D3D11_WINDOW_FULLSCREEN_TOGGLE_MODE_NONE
#define DEFAULT_FULLSCREEN FALSE
-#define DEFAULT_RENDER_STATS FALSE
#define DEFAULT_DRAW_ON_SHARED_TEXTURE FALSE
enum
gboolean enable_navigation_events;
GstD3D11WindowFullscreenToggleMode fullscreen_toggle_mode;
gboolean fullscreen;
- gboolean render_stats;
gboolean draw_on_shared_texture;
/* saved render rectangle until we have a window */
DEFAULT_FULLSCREEN,
(GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-#ifdef HAVE_DIRECT_WRITE
- g_object_class_install_property (gobject_class, PROP_RENDER_STATS,
- g_param_spec_boolean ("render-stats",
- "Render Stats",
- "Render statistics data (e.g., average framerate) on window",
- DEFAULT_RENDER_STATS,
- (GParamFlags) (GST_PARAM_CONDITIONALLY_AVAILABLE |
- GST_PARAM_MUTABLE_READY | G_PARAM_READWRITE |
- G_PARAM_STATIC_STRINGS)));
-#endif
-
/**
* GstD3D11VideoSink:draw-on-shared-texture:
*
self->enable_navigation_events = DEFAULT_ENABLE_NAVIGATION_EVENTS;
self->fullscreen_toggle_mode = DEFAULT_FULLSCREEN_TOGGLE_MODE;
self->fullscreen = DEFAULT_FULLSCREEN;
- self->render_stats = DEFAULT_RENDER_STATS;
self->draw_on_shared_texture = DEFAULT_DRAW_ON_SHARED_TEXTURE;
g_rec_mutex_init (&self->draw_lock);
g_object_set (self->window, "fullscreen", self->fullscreen, NULL);
}
break;
-#ifdef HAVE_DIRECT_WRITE
- case PROP_RENDER_STATS:
- self->render_stats = g_value_get_boolean (value);
- break;
-#endif
case PROP_DRAW_ON_SHARED_TEXTURE:
self->draw_on_shared_texture = g_value_get_boolean (value);
break;
g_value_set_boolean (value, self->fullscreen);
}
break;
-#ifdef HAVE_DIRECT_WRITE
- case PROP_RENDER_STATS:
- g_value_set_boolean (value, self->render_stats);
- break;
-#endif
case PROP_DRAW_ON_SHARED_TEXTURE:
g_value_set_boolean (value, self->draw_on_shared_texture);
break;
"fullscreen-toggle-mode", self->fullscreen_toggle_mode,
"fullscreen", self->fullscreen,
"enable-navigation-events", self->enable_navigation_events, NULL);
-#ifdef HAVE_DIRECT_WRITE
- g_object_set (self->window, "render-stats", self->render_stats, NULL);
-#endif
GST_OBJECT_UNLOCK (self);
g_signal_connect (self->window, "key-event",
GstFlowReturn ret = GST_FLOW_OK;
GstVideoRectangle rect = { 0, };
GstBuffer *fallback_buf = NULL;
- GstStructure *stats = NULL;
ID3D11Device *device_handle =
gst_d3d11_device_get_device_handle (self->device);
ID3D11ShaderResourceView *view[GST_VIDEO_MAX_PLANES];
self->current_buffer = NULL;
g_rec_mutex_unlock (&self->draw_lock);
} else {
- if (self->render_stats)
- stats = gst_base_sink_get_stats (GST_BASE_SINK_CAST (self));
-
ret = gst_d3d11_window_render (self->window,
- fallback_buf ? fallback_buf : buf, &rect, stats);
+ fallback_buf ? fallback_buf : buf, &rect);
}
gst_clear_buffer (&fallback_buf);
rect.w = GST_VIDEO_SINK_WIDTH (self);
rect.h = GST_VIDEO_SINK_HEIGHT (self);
- gst_d3d11_window_render (self->window, NULL, &rect, NULL);
+ gst_d3d11_window_render (self->window, NULL, &rect);
}
}
#include <windows.applicationmodel.core.h>
#endif
-#ifdef HAVE_DIRECT_WRITE
-#include <dwrite.h>
-#include <d2d1_1.h>
-#include <sstream>
-#endif
-
#include <wrl.h>
/* *INDENT-OFF* */
using namespace Microsoft::WRL;
G_END_DECLS
/* *INDENT-ON* */
-struct _GstD3D11WindowPrivate
-{
-#ifdef HAVE_DIRECT_WRITE
- IDWriteFactory *dwrite_factory;
- IDWriteTextFormat *dwrite_format;
-
- ID2D1Factory1 *d2d_factory;
- ID2D1Device *d2d_device;
- ID2D1DeviceContext *d2d_device_context;
- ID2D1SolidColorBrush *d2d_brush;
-#else
- gpointer dummy;
-#endif
-};
-
enum
{
PROP_0,
}
#define gst_d3d11_window_parent_class parent_class
-G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GstD3D11Window, gst_d3d11_window,
- GST_TYPE_OBJECT);
+G_DEFINE_ABSTRACT_TYPE (GstD3D11Window, gst_d3d11_window, GST_TYPE_OBJECT);
static void gst_d3d11_window_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec);
GValue * value, GParamSpec * pspec);
static void gst_d3d11_window_dispose (GObject * object);
static GstFlowReturn gst_d3d111_window_present (GstD3D11Window * self,
- GstBuffer * buffer, GstStructure * stats,
- ID3D11VideoProcessorOutputView * pov, ID3D11RenderTargetView * rtv);
+ GstBuffer * buffer, ID3D11VideoProcessorOutputView * pov,
+ ID3D11RenderTargetView * rtv);
static void gst_d3d11_window_on_resize_default (GstD3D11Window * window,
guint width, guint height);
static gboolean gst_d3d11_window_prepare_default (GstD3D11Window * window,
(GParamFlags) (G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS)));
-#ifdef HAVE_DIRECT_WRITE
- g_object_class_install_property (gobject_class, PROP_RENDER_STATS,
- g_param_spec_boolean ("render-stats",
- "Render Stats",
- "Render statistics data (e.g., average framerate) on window",
- DEFAULT_RENDER_STATS,
- (GParamFlags) (G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS)));
-#endif
-
d3d11_window_signals[SIGNAL_KEY_EVENT] =
g_signal_new ("key-event", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL,
self->fullscreen_toggle_mode = GST_D3D11_WINDOW_FULLSCREEN_TOGGLE_MODE_NONE;
self->fullscreen = DEFAULT_FULLSCREEN;
self->render_stats = DEFAULT_RENDER_STATS;
-
- self->priv =
- (GstD3D11WindowPrivate *) gst_d3d11_window_get_instance_private (self);
}
static void
case PROP_WINDOW_HANDLE:
self->external_handle = (guintptr) g_value_get_pointer (value);
break;
-#ifdef HAVE_DIRECT_WRITE
- case PROP_RENDER_STATS:
- self->render_stats = g_value_get_boolean (value);
- break;
-#endif
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
-#ifdef HAVE_DIRECT_WRITE
-static void
-gst_d3d11_window_release_dwrite_resources (GstD3D11Window * self)
-{
- GstD3D11WindowPrivate *priv = self->priv;
-
- GST_D3D11_CLEAR_COM (priv->d2d_device_context);
- GST_D3D11_CLEAR_COM (priv->d2d_factory);
- GST_D3D11_CLEAR_COM (priv->d2d_device);
- GST_D3D11_CLEAR_COM (priv->d2d_brush);
- GST_D3D11_CLEAR_COM (priv->dwrite_factory);
- GST_D3D11_CLEAR_COM (priv->dwrite_format);
-}
-
-static void
-gst_d3d11_window_prepare_dwrite_device (GstD3D11Window * self)
-{
- GstD3D11WindowPrivate *priv = self->priv;
- HRESULT hr;
- /* *INDENT-OFF* */
- ComPtr<IDXGIDevice> dxgi_device;
- /* *INDENT-ON* */
- ID3D11Device *device_handle;
-
- if (!self->device) {
- GST_ERROR_OBJECT (self, "D3D11Device is unavailable");
- return;
- }
-
- /* Already prepared */
- if (priv->d2d_device)
- return;
-
- hr = D2D1CreateFactory (D2D1_FACTORY_TYPE_MULTI_THREADED,
- IID_PPV_ARGS (&priv->d2d_factory));
- if (!gst_d3d11_result (hr, self->device))
- goto error;
-
- device_handle = gst_d3d11_device_get_device_handle (self->device);
- hr = device_handle->QueryInterface (IID_PPV_ARGS (&dxgi_device));
- if (!gst_d3d11_result (hr, self->device))
- goto error;
-
- hr = priv->d2d_factory->CreateDevice (dxgi_device.Get (), &priv->d2d_device);
- if (!gst_d3d11_result (hr, self->device))
- goto error;
-
- hr = priv->d2d_device->CreateDeviceContext
- (D2D1_DEVICE_CONTEXT_OPTIONS_ENABLE_MULTITHREADED_OPTIMIZATIONS,
- &priv->d2d_device_context);
- if (!gst_d3d11_result (hr, self->device))
- goto error;
-
- hr = priv->
- d2d_device_context->CreateSolidColorBrush (D2D1::ColorF (D2D1::ColorF::
- Yellow), &priv->d2d_brush);
- if (!gst_d3d11_result (hr, self->device))
- goto error;
-
- hr = DWriteCreateFactory (DWRITE_FACTORY_TYPE_SHARED,
- __uuidof (IDWriteFactory), (IUnknown **) & priv->dwrite_factory);
- if (!gst_d3d11_result (hr, self->device))
- goto error;
-
- /* Configure font */
- hr = priv->dwrite_factory->CreateTextFormat (L"Arial", NULL,
- DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STYLE_NORMAL,
- DWRITE_FONT_STRETCH_NORMAL, 12.0f, L"en-US", &priv->dwrite_format);
- if (!gst_d3d11_result (hr, self->device))
- goto error;
-
- GST_DEBUG_OBJECT (self, "Direct2D device is prepared");
-
- return;
-
-error:
- gst_d3d11_window_release_dwrite_resources (self);
-}
-
-static void
-gst_d3d11_window_dwrite_on_resize (GstD3D11Window * self,
- ID3D11Texture2D * backbuffer)
-{
- GstD3D11WindowPrivate *priv = self->priv;
- /* *INDENT-OFF* */
- ComPtr<IDXGISurface> dxgi_surface;
- ComPtr<ID2D1Bitmap1> bitmap;
- /* *INDENT-ON* */
- D2D1_BITMAP_PROPERTIES1 prop;
- HRESULT hr;
-
- if (!priv->d2d_device)
- return;
-
- prop.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
- prop.pixelFormat.alphaMode = D2D1_ALPHA_MODE_IGNORE;
- /* default dpi */
- prop.dpiX = 96.0f;
- prop.dpiY = 96.0f;
- prop.bitmapOptions =
- D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW;
- prop.colorContext = NULL;
-
- hr = backbuffer->QueryInterface (IID_PPV_ARGS (&dxgi_surface));
- if (!gst_d3d11_result (hr, self->device))
- goto error;
-
- hr = priv->d2d_device_context->
- CreateBitmapFromDxgiSurface (dxgi_surface.Get (), &prop, &bitmap);
- if (!gst_d3d11_result (hr, self->device))
- goto error;
-
- priv->d2d_device_context->SetTarget (bitmap.Get ());
-
- GST_LOG_OBJECT (self, "New D2D bitmap has been configured");
-
- return;
-
-error:
- gst_d3d11_window_release_dwrite_resources (self);
-}
-
-#endif
-
static void
gst_d3d11_window_release_resources (GstD3D11Device * device,
GstD3D11Window * window)
{
-#ifdef HAVE_DIRECT_WRITE
- gst_d3d11_window_release_dwrite_resources (window);
-#endif
-
GST_D3D11_CLEAR_COM (window->rtv);
GST_D3D11_CLEAR_COM (window->pov);
GST_D3D11_CLEAR_COM (window->swap_chain);
gst_d3d11_window_on_resize_default (GstD3D11Window * window, guint width,
guint height)
{
-#ifdef HAVE_DIRECT_WRITE
- GstD3D11WindowPrivate *priv = window->priv;
-#endif
HRESULT hr;
ID3D11Device *device_handle;
D3D11_TEXTURE2D_DESC desc;
GST_D3D11_CLEAR_COM (window->rtv);
GST_D3D11_CLEAR_COM (window->pov);
-#ifdef HAVE_DIRECT_WRITE
- /* D2D bitmap need to be cleared before resizing swapchain buffer */
- if (priv->d2d_device_context)
- priv->d2d_device_context->SetTarget (NULL);
-#endif
-
swap_chain->GetDesc (&swap_desc);
hr = swap_chain->ResizeBuffers (0, width, height, window->dxgi_format,
swap_desc.Flags);
&pov_desc, (ID3D11Resource *) backbuffer, &window->pov))
goto done;
}
-#ifdef HAVE_DIRECT_WRITE
- if (window->render_stats)
- gst_d3d11_window_dwrite_on_resize (window, backbuffer);
-#endif
window->first_present = TRUE;
/* redraw the last scene if cached buffer exits */
if (window->cached_buffer) {
- gst_d3d111_window_present (window, window->cached_buffer, NULL,
+ gst_d3d111_window_present (window, window->cached_buffer,
window->pov, window->rtv);
}
"Cannot determine render format");
return FALSE;
}
-#ifdef HAVE_DIRECT_WRITE
- if (window->render_stats && formats[1].supported) {
- /* FIXME: D2D seems to be accepting only DXGI_FORMAT_B8G8R8A8_UNORM */
- chosen_format = &formats[1];
- } else
-#else
- {
- 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;
+
+ 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;
}
}
-#endif
if (!chosen_format) {
/* prefer native format over conversion */
"Cannot create overlay compositor");
goto error;
}
-#ifdef HAVE_DIRECT_WRITE
- if (window->render_stats)
- gst_d3d11_window_prepare_dwrite_device (window);
-#endif
gst_d3d11_device_unlock (window->device);
/* call resize to allocated resources */
return TRUE;
}
-#ifdef HAVE_DIRECT_WRITE
-static void
-gst_d3d11_window_present_d2d (GstD3D11Window * self, GstStructure * stats)
-{
- GstD3D11WindowPrivate *priv = self->priv;
- HRESULT hr;
- gdouble framerate = 0.0;
- guint64 dropped = 0;
- guint64 rendered = 0;
- std::wostringstream stats_str;
- /* *INDENT-OFF* */
- ComPtr<IDWriteTextLayout> layout;
- /* *INDENT-ON* */
- FLOAT left;
- FLOAT top;
-
- if (!priv->d2d_device)
- return;
-
- if (!stats)
- return;
-
- gst_structure_get_double (stats, "average-rate", &framerate);
- gst_structure_get_uint64 (stats, "dropped", &dropped);
- gst_structure_get_uint64 (stats, "rendered", &rendered);
-
- stats_str.precision (5);
- stats_str << "Average-rate: " << framerate << std::endl;
- stats_str << "Dropped: " << dropped << std::endl;
- stats_str << "Rendered: " << rendered << std::endl;
-
- hr = priv->dwrite_factory->CreateTextLayout (stats_str.str ().c_str (),
- (UINT32) stats_str.str ().size (), priv->dwrite_format,
- self->render_rect.right - self->render_rect.left,
- self->render_rect.bottom - self->render_rect.top, &layout);
- if (!gst_d3d11_result (hr, self->device))
- return;
-
- left = self->render_rect.left + 5.0f;
- top = self->render_rect.top + 5.0f;
-
- priv->d2d_device_context->BeginDraw ();
- priv->d2d_device_context->DrawTextLayout (D2D1::Point2F (left, top),
- layout.Get (), priv->d2d_brush);
-
- hr = priv->d2d_device_context->EndDraw ();
- gst_d3d11_result (hr, self->device);
-
- return;
-}
-#endif
-
static gboolean
gst_d3d11_window_do_processor (GstD3D11Window * self,
ID3D11VideoProcessorInputView * piv, ID3D11VideoProcessorOutputView * pov)
static GstFlowReturn
gst_d3d111_window_present (GstD3D11Window * self, GstBuffer * buffer,
- GstStructure * stats, ID3D11VideoProcessorOutputView * pov,
- ID3D11RenderTargetView * rtv)
+ ID3D11VideoProcessorOutputView * pov, ID3D11RenderTargetView * rtv)
{
GstD3D11WindowClass *klass = GST_D3D11_WINDOW_GET_CLASS (self);
GstFlowReturn ret = GST_FLOW_OK;
}
#endif
-#if HAVE_DIRECT_WRITE
- gst_d3d11_window_present_d2d (self, stats);
-#endif
-
if (klass->present)
ret = klass->present (self, present_flags);
GstFlowReturn
gst_d3d11_window_render (GstD3D11Window * window, GstBuffer * buffer,
- GstVideoRectangle * rect, GstStructure * stats)
+ GstVideoRectangle * rect)
{
GstMemory *mem;
GstFlowReturn ret;
if (!gst_is_d3d11_memory (mem)) {
GST_ERROR_OBJECT (window, "Invalid buffer");
- if (stats)
- gst_structure_free (stats);
-
return GST_FLOW_ERROR;
}
gst_d3d11_device_lock (window->device);
gst_buffer_replace (&window->cached_buffer, buffer);
- ret = gst_d3d111_window_present (window, window->cached_buffer, stats,
+ ret = gst_d3d111_window_present (window, window->cached_buffer,
window->pov, window->rtv);
gst_d3d11_device_unlock (window->device);
- if (stats)
- gst_structure_free (stats);
-
return ret;
}
pov = data.pov;
}
- ret = gst_d3d111_window_present (window, buffer, NULL, pov, rtv);
+ ret = gst_d3d111_window_present (window, buffer, pov, rtv);
klass->release_shared_handle (window, &data);
gst_d3d11_device_unlock (window->device);