summaryrefslogtreecommitdiff
path: root/sys/d3dvideosink
diff options
context:
space:
mode:
authorRoland Krikava <rkrikava@gmail.com>2012-12-22 11:24:28 +0100
committerSebastian Dröge <sebastian.droege@collabora.co.uk>2012-12-22 11:24:28 +0100
commitfe5f514049029fd9004074c9a3970e27b8bc5120 (patch)
tree91e5f6f65299e39c2abd41ba0fb2033b9a1b03e3 /sys/d3dvideosink
parentc636b45c9ac455b74f07916ab46e587a44faee3e (diff)
downloadgstreamer-plugins-bad-fe5f514049029fd9004074c9a3970e27b8bc5120.tar.gz
d3dvideosink: Various improvements
* XOverlay set_render_rectangle support (Useful for rendering in QT QML) * Video format negotiation (with preference ordering) * Using Direct3D9 (No benefit to using newer D3D versions)
Diffstat (limited to 'sys/d3dvideosink')
-rw-r--r--sys/d3dvideosink/Makefile.am14
-rw-r--r--sys/d3dvideosink/d3dvideosink.c2585
-rw-r--r--sys/d3dvideosink/d3dvideosink.h137
-rw-r--r--sys/d3dvideosink/directx/directx.h33
-rw-r--r--sys/d3dvideosink/directx/directx10/dx10.c27
-rw-r--r--sys/d3dvideosink/directx/directx10/dx10.h39
-rw-r--r--sys/d3dvideosink/directx/directx10/dx10_d3d.c77
-rw-r--r--sys/d3dvideosink/directx/directx10/dx10_d3d.h72
-rw-r--r--sys/d3dvideosink/directx/directx11/dx11.c27
-rw-r--r--sys/d3dvideosink/directx/directx11/dx11.h39
-rw-r--r--sys/d3dvideosink/directx/directx11/dx11_d3d.c75
-rw-r--r--sys/d3dvideosink/directx/directx11/dx11_d3d.h72
-rw-r--r--sys/d3dvideosink/directx/directx9/dx9.c27
-rw-r--r--sys/d3dvideosink/directx/directx9/dx9.h38
-rw-r--r--sys/d3dvideosink/directx/directx9/dx9_d3d.c89
-rw-r--r--sys/d3dvideosink/directx/directx9/dx9_d3d.h71
-rw-r--r--sys/d3dvideosink/directx/directx_d3d.c65
-rw-r--r--sys/d3dvideosink/directx/directx_d3d.h99
-rw-r--r--sys/d3dvideosink/directx/dx.c282
-rw-r--r--sys/d3dvideosink/directx/dx.h265
20 files changed, 525 insertions, 3608 deletions
diff --git a/sys/d3dvideosink/Makefile.am b/sys/d3dvideosink/Makefile.am
index a1b3967e9..cf80bcea8 100644
--- a/sys/d3dvideosink/Makefile.am
+++ b/sys/d3dvideosink/Makefile.am
@@ -1,17 +1,11 @@
plugin_LTLIBRARIES = libgstd3dvideosink.la
-libgstd3dvideosink_la_SOURCES = d3dvideosink.c directx/directx_d3d.c directx/dx.c \
- directx/directx9/dx9.c directx/directx9/dx9_d3d.c \
- directx/directx10/dx10.c directx/directx10/dx10_d3d.c \
- directx/directx11/dx11.c directx/directx11/dx11_d3d.c
-libgstd3dvideosink_la_CFLAGS = $(GST_PLUGINS_BAD_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) $(DIRECTX_CFLAGS)
+libgstd3dvideosink_la_SOURCES = d3dvideosink.c d3dhelpers.c
+libgstd3dvideosink_la_CFLAGS = $(GST_PLUGINS_BAD_CFLAGS) $(GST_CFLAGS) $(DIRECTX_CFLAGS)
libgstd3dvideosink_la_LIBADD = $(GST_BASE_LIBS) $(GST_PLUGINS_BASE_LIBS) \
- -lgstvideo-$(GST_API_VERSION) $(GMODULE_NO_EXPORT_LIBS) \
+ -lgstvideo-$(GST_API_VERSION) \
$(DIRECT3D_LIBS)
libgstd3dvideosink_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) $(DIRECTX_LDFAGS) -e D3dDllMain
libgstd3dvideosink_la_LIBTOOLFLAGS = --tag=disable-static
-noinst_HEADERS = d3dvideosink.h directx/directx_d3d.h directx/dx.h directx/directx.h \
- directx/directx9/dx9.h directx/directx9/dx9_d3d.h \
- directx/directx10/dx10.h directx/directx10/dx10_d3d.h \
- directx/directx11/dx11.h directx/directx11/dx11_d3d.h
+noinst_HEADERS = d3dvideosink.h d3dhelpers.h
diff --git a/sys/d3dvideosink/d3dvideosink.c b/sys/d3dvideosink/d3dvideosink.c
index d4462f239..afb444482 100644
--- a/sys/d3dvideosink/d3dvideosink.c
+++ b/sys/d3dvideosink/d3dvideosink.c
@@ -1,4 +1,5 @@
/* GStreamer
+ * Copyright (C) 2012 Roland Krikava <info@bluedigits.com>
* Copyright (C) 2010-2011 David Hoyt <dhoyt@hoytsoft.org>
* Copyright (C) 2010 Andoni Morales <ylatuya@gmail.com>
*
@@ -14,232 +15,98 @@
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
*/
-
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "d3dvideosink.h"
-#define IPC_SET_WINDOW 1
-#define IDT_DEVICELOST 1
-
-/* Provide access to data that will be shared among all instantiations of this element */
-#define GST_D3DVIDEOSINK_SHARED_D3D_LOCK g_static_mutex_lock (&shared_d3d_lock)
-#define GST_D3DVIDEOSINK_SHARED_D3D_UNLOCK g_static_mutex_unlock (&shared_d3d_lock)
-#define GST_D3DVIDEOSINK_SHARED_D3D_HOOK_LOCK g_static_mutex_lock (&shared_d3d_hook_lock)
-#define GST_D3DVIDEOSINK_SHARED_D3D_HOOK_UNLOCK g_static_mutex_unlock (&shared_d3d_hook_lock)
-typedef struct _GstD3DVideoSinkShared GstD3DVideoSinkShared;
-struct _GstD3DVideoSinkShared
-{
- LPDIRECT3D9 d3d;
- D3DCAPS9 d3dcaps;
-
- GList *element_list;
- gint32 element_count;
-
- gboolean device_lost;
- UINT_PTR device_lost_timer;
- GstD3DVideoSink *device_lost_sink;
+#define ELEMENT_NAME "d3dvideosink"
- HWND hidden_window_handle;
- HANDLE hidden_window_created_signal;
- GThread *hidden_window_thread;
-
- GHashTable *hook_tbl;
-};
-typedef struct _GstD3DVideoSinkHookData GstD3DVideoSinkHookData;
-struct _GstD3DVideoSinkHookData
-{
- HHOOK hook;
- HWND window_handle;
- DWORD thread_id;
- DWORD process_id;
-};
-/* Holds our shared information */
-static GstD3DVideoSinkShared shared;
-/* Define a shared lock to synchronize the creation/destruction of the d3d device */
-static GStaticMutex shared_d3d_lock = G_STATIC_MUTEX_INIT;
-static GStaticMutex shared_d3d_hook_lock = G_STATIC_MUTEX_INIT;
-/* Hold a reference to our dll's HINSTANCE */
-static HINSTANCE g_hinstDll = NULL;
-
-typedef struct _IPCData IPCData;
-struct _IPCData
+enum
{
- HWND hwnd;
- LONG_PTR wnd_proc;
+ PROP_0,
+ PROP_KEEP_ASPECT_RATIO,
+ PROP_CREATE_RENDER_WINDOW,
+ PROP_STREAM_STOP_ON_CLOSE,
+ PROP_ENABLE_NAVIGATION_EVENTS,
+ PROP_LAST
};
-/* Holds data that may be used to communicate across processes */
-/*static IPCData ipc_data;*/
-/*static COPYDATASTRUCT ipc_cds;*/
-GST_DEBUG_CATEGORY (d3dvideosink_debug);
-#define GST_CAT_DEFAULT d3dvideosink_debug
+#define DEFAULT_KEEP_ASPECT_RATIO FALSE
+#define DEFAULT_CREATE_RENDER_WINDOW TRUE
+#define DEFAULT_STREAM_STOP_ON_CLOSE TRUE
+#define DEFAULT_ENABLE_NAVIGATION_EVENTS TRUE
static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS ("video/x-raw, "
- "format = (string) { I420, YV12, NV12, YUY2, UYVY, BGR, BGRA, BGRx }, "
+ "format = (string) { I420, YV12, UYVY, YUY2, NV12, BGRx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, RGB16, BGR16, RGB15, BGR15 }, "
"framerate = (fraction) [ 0, MAX ], "
"width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ]")
);
-static void gst_d3dvideosink_navigation_init (GstNavigationInterface * iface);
-static void gst_d3dvideosink_video_overlay_init (GstVideoOverlayInterface *
- iface);
-#define gst_d3dvideosink_parent_class parent_class
-G_DEFINE_TYPE_WITH_CODE (GstD3DVideoSink, gst_d3dvideosink, GST_TYPE_VIDEO_SINK,
- G_IMPLEMENT_INTERFACE (GST_TYPE_NAVIGATION,
- gst_d3dvideosink_navigation_init);
- G_IMPLEMENT_INTERFACE (GST_TYPE_VIDEO_OVERLAY,
- gst_d3dvideosink_video_overlay_init));
-
-enum
-{
- PROP_0, PROP_KEEP_ASPECT_RATIO, PROP_PIXEL_ASPECT_RATIO,
- PROP_ENABLE_NAVIGATION_EVENTS, PROP_LAST
-};
+GST_DEBUG_CATEGORY (gst_d3dvideosink_debug);
+#define GST_CAT_DEFAULT gst_d3dvideosink_debug
-/* GObject methods */
-static void gst_d3dvideosink_finalize (GObject * gobject);
+/** FWD DECLS **/
+/* Interfaces */
+static void gst_d3dvideosink_init_interfaces (GType type);
+/* GstXOverlay Interface */
+static void
+gst_d3dvideosink_video_overlay_interface_init (GstVideoOverlayInterface *
+ iface);
+static void gst_d3dvideosink_set_window_handle (GstVideoOverlay * overlay,
+ guintptr window_id);
+static void gst_d3dvideosink_set_render_rectangle (GstVideoOverlay * overlay,
+ gint x, gint y, gint width, gint height);
+static void gst_d3dvideosink_expose (GstVideoOverlay * overlay);
+/* GstNavigation Interface */
+static void gst_d3dvideosink_navigation_interface_init (GstNavigationInterface *
+ iface);
+static void gst_d3dvideosink_navigation_send_event (GstNavigation * navigation,
+ GstStructure * structure);
+/* GObject */
static void gst_d3dvideosink_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec);
static void gst_d3dvideosink_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
-
-/* GstElement methods */
-static GstStateChangeReturn gst_d3dvideosink_change_state (GstElement * element,
- GstStateChange transition);
-
-/* GstBaseSink methods */
-static gboolean gst_d3dvideosink_start (GstBaseSink * bsink);
-static gboolean gst_d3dvideosink_stop (GstBaseSink * bsink);
-static gboolean gst_d3dvideosink_set_caps (GstBaseSink * bsink, GstCaps * caps);
-static GstCaps *gst_d3dvideosink_get_caps (GstBaseSink * bsink,
+static void gst_d3dvideosink_finalize (GObject * gobject);
+/* GstBaseSink */
+static GstCaps *gst_d3dvideosink_get_caps (GstBaseSink * basesink,
GstCaps * filter);
-static GstFlowReturn gst_d3dvideosink_show_frame (GstVideoSink * sink,
+static gboolean gst_d3dvideosink_set_caps (GstBaseSink * bsink, GstCaps * caps);
+static gboolean gst_d3dvideosink_stop (GstBaseSink * sink);
+/* GstVideoSink */
+static GstFlowReturn gst_d3dvideosink_show_frame (GstVideoSink * vsink,
GstBuffer * buffer);
-/* GstVideoOverlay methods */
-static void gst_d3dvideosink_set_window_handle (GstVideoOverlay * overlay,
- guintptr window_id);
-static void gst_d3dvideosink_expose (GstVideoOverlay * overlay);
+#define _do_init \
+ G_IMPLEMENT_INTERFACE (GST_TYPE_NAVIGATION, gst_d3dvideosink_navigation_interface_init); \
+ G_IMPLEMENT_INTERFACE (GST_TYPE_VIDEO_OVERLAY, gst_d3dvideosink_video_overlay_interface_init); \
+ GST_DEBUG_CATEGORY_INIT (gst_d3dvideosink_debug, ELEMENT_NAME, 0, "Direct3D Video");
-/* GstNavigation methods */
-static void gst_d3dvideosink_navigation_send_event (GstNavigation * navigation,
- GstStructure * structure);
-
-/* WndProc methods */
-LRESULT APIENTRY WndProc (HWND hWnd, UINT message, WPARAM wParam,
- LPARAM lParam);
-LRESULT APIENTRY SharedHiddenWndProc (HWND hWnd, UINT message, WPARAM wParam,
- LPARAM lParam);
-static void gst_d3dvideosink_wnd_proc (GstD3DVideoSink * sink, HWND hWnd,
- UINT message, WPARAM wParam, LPARAM lParam);
-
-/* HookProc methods */
-LRESULT APIENTRY WndProcHook (HWND hWnd, UINT message, WPARAM wParam,
- LPARAM lParam);
-LRESULT CALLBACK gst_d3dvideosink_hook_proc (int nCode, WPARAM wParam,
- LPARAM lParam);
-
-/* Paint/update methods */
-static void gst_d3dvideosink_update (GstBaseSink * bsink);
-static gboolean gst_d3dvideosink_refresh (GstD3DVideoSink * sink);
-static gboolean gst_d3dvideosink_update_all (GstD3DVideoSink * sink);
-static gboolean gst_d3dvideosink_refresh_all (GstD3DVideoSink * sink);
-static void gst_d3dvideosink_stretch (GstD3DVideoSink * sink,
- LPDIRECT3DSURFACE9 backBuffer);
-
-/* Misc methods */
-BOOL WINAPI D3dDllMain (HINSTANCE hinstDll, DWORD fdwReason, PVOID fImpLoad);
-static void gst_d3dvideosink_remove_window_for_renderer (GstD3DVideoSink *
- sink);
-static gboolean gst_d3dvideosink_initialize_direct3d (GstD3DVideoSink * sink);
-static gboolean gst_d3dvideosink_initialize_d3d_device (GstD3DVideoSink * sink);
-
-static gboolean gst_d3dvideosink_notify_device_init (GstD3DVideoSink * sink);
-static gboolean gst_d3dvideosink_notify_device_lost (GstD3DVideoSink * sink);
-static gboolean gst_d3dvideosink_notify_device_reset (GstD3DVideoSink * sink);
-static gboolean gst_d3dvideosink_notify_device_reinit (GstD3DVideoSink * sink);
-static gboolean gst_d3dvideosink_device_lost (GstD3DVideoSink * sink);
-static gboolean gst_d3dvideosink_release_d3d_device (GstD3DVideoSink * sink);
-static gboolean gst_d3dvideosink_release_direct3d (GstD3DVideoSink * sink);
-static gboolean gst_d3dvideosink_window_size (GstD3DVideoSink * sink,
- gint * width, gint * height);
-static gboolean gst_d3dvideosink_direct3d_supported (GstD3DVideoSink * sink);
-static gboolean gst_d3dvideosink_shared_hidden_window_thread (GstD3DVideoSink *
- sink);
-static void gst_d3dvideosink_flush_gpu (GstD3DVideoSink * sink);
-static void gst_d3dvideosink_hook_window_for_renderer (GstD3DVideoSink * sink);
-static void gst_d3dvideosink_unhook_window_for_renderer (GstD3DVideoSink *
- sink);
-static void gst_d3dvideosink_unhook_all_windows (void);
-static void gst_d3dvideosink_log_debug (const gchar * file,
- const gchar * function, gint line, const gchar * format, va_list args);
-static void gst_d3dvideosink_log_warning (const gchar * file,
- const gchar * function, gint line, const gchar * format, va_list args);
-static void gst_d3dvideosink_log_error (const gchar * file,
- const gchar * function, gint line, const gchar * format, va_list args);
-static void gst_d3dvideosink_set_window_for_renderer (GstD3DVideoSink * sink);
-static DirectXInitParams directx_init_params = {
- gst_d3dvideosink_log_debug, gst_d3dvideosink_log_warning,
- gst_d3dvideosink_log_error
-};
-
-/* TODO: event, preroll, buffer_alloc?
- * buffer_alloc won't generally be all that useful because the renderers require a
- * different stride to GStreamer's implicit values.
- */
+G_DEFINE_TYPE_WITH_CODE (GstD3DVideoSink, gst_d3dvideosink, GST_TYPE_VIDEO_SINK,
+ _do_init);
-BOOL WINAPI
-D3dDllMain (HINSTANCE hinstDll, DWORD fdwReason, PVOID fImpLoad)
-{
- switch (fdwReason) {
- case DLL_PROCESS_ATTACH:
- g_hinstDll = hinstDll;
- break;
- case DLL_THREAD_ATTACH:
- break;
- case DLL_THREAD_DETACH:
- break;
- case DLL_PROCESS_DETACH:
- gst_d3dvideosink_unhook_all_windows ();
- break;
- }
- return TRUE;
-}
-static void
-gst_d3dvideosink_video_overlay_init (GstVideoOverlayInterface * iface)
-{
- iface->set_window_handle = gst_d3dvideosink_set_window_handle;
- iface->expose = gst_d3dvideosink_expose;
-}
-
-static void
-gst_d3dvideosink_navigation_init (GstNavigationInterface * iface)
-{
- iface->send_event = gst_d3dvideosink_navigation_send_event;
-}
static void
gst_d3dvideosink_class_init (GstD3DVideoSinkClass * klass)
{
GObjectClass *gobject_class;
GstElementClass *gstelement_class;
- GstBaseSinkClass *gstbasesink_class;
GstVideoSinkClass *gstvideosink_class;
+ GstBaseSinkClass *gstbasesink_class;
gobject_class = (GObjectClass *) klass;
gstelement_class = (GstElementClass *) klass;
- gstbasesink_class = (GstBaseSinkClass *) klass;
gstvideosink_class = (GstVideoSinkClass *) klass;
+ gstbasesink_class = (GstBaseSinkClass *) klass;
gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_d3dvideosink_finalize);
gobject_class->set_property =
@@ -247,15 +114,9 @@ gst_d3dvideosink_class_init (GstD3DVideoSinkClass * klass)
gobject_class->get_property =
GST_DEBUG_FUNCPTR (gst_d3dvideosink_get_property);
- gstelement_class->change_state =
- GST_DEBUG_FUNCPTR (gst_d3dvideosink_change_state);
-
gstbasesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_d3dvideosink_get_caps);
gstbasesink_class->set_caps = GST_DEBUG_FUNCPTR (gst_d3dvideosink_set_caps);
- gstbasesink_class->start = GST_DEBUG_FUNCPTR (gst_d3dvideosink_start);
gstbasesink_class->stop = GST_DEBUG_FUNCPTR (gst_d3dvideosink_stop);
- /*gstbasesink_class->unlock = GST_DEBUG_FUNCPTR (gst_d3dvideosink_unlock); */
- /*gstbasesink_class->unlock_stop = GST_DEBUG_FUNCPTR (gst_d3dvideosink_unlock_stop); */
gstvideosink_class->show_frame =
GST_DEBUG_FUNCPTR (gst_d3dvideosink_show_frame);
@@ -264,88 +125,79 @@ gst_d3dvideosink_class_init (GstD3DVideoSinkClass * klass)
g_object_class_install_property (G_OBJECT_CLASS (klass),
PROP_KEEP_ASPECT_RATIO, g_param_spec_boolean ("force-aspect-ratio",
"Force aspect ratio",
- "When enabled, scaling will respect original aspect ratio", TRUE,
- (GParamFlags) G_PARAM_READWRITE));
+ "When enabled, scaling will respect original aspect ratio",
+ DEFAULT_KEEP_ASPECT_RATIO, (GParamFlags) G_PARAM_READWRITE));
+ g_object_class_install_property (G_OBJECT_CLASS (klass),
+ PROP_CREATE_RENDER_WINDOW, g_param_spec_boolean ("create-render-window",
+ "Create render window",
+ "If no window ID is given, a new render window is created",
+ DEFAULT_CREATE_RENDER_WINDOW, (GParamFlags) G_PARAM_READWRITE));
+ g_object_class_install_property (G_OBJECT_CLASS (klass),
+ PROP_STREAM_STOP_ON_CLOSE, g_param_spec_boolean ("stream-stop-on-close",
+ "Stop streaming on window close",
+ "If the render window is closed stop stream",
+ DEFAULT_STREAM_STOP_ON_CLOSE, (GParamFlags) G_PARAM_READWRITE));
+#if 0
g_object_class_install_property (G_OBJECT_CLASS (klass),
PROP_PIXEL_ASPECT_RATIO, g_param_spec_string ("pixel-aspect-ratio",
"Pixel Aspect Ratio",
"The pixel aspect ratio of the device", "1/1",
(GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
+#endif
g_object_class_install_property (G_OBJECT_CLASS (klass),
PROP_ENABLE_NAVIGATION_EVENTS,
g_param_spec_boolean ("enable-navigation-events",
"Enable navigation events",
- "When enabled, navigation events are sent upstream", TRUE,
- (GParamFlags) G_PARAM_READWRITE));
-
- gst_element_class_add_pad_template (gstelement_class,
- gst_static_pad_template_get (&sink_template));
+ "When enabled, navigation events are sent upstream",
+ DEFAULT_ENABLE_NAVIGATION_EVENTS, (GParamFlags) G_PARAM_READWRITE));
gst_element_class_set_static_metadata (gstelement_class,
"Direct3D video sink", "Sink/Video",
"Display data using a Direct3D video renderer",
- "David Hoyt <dhoyt@hoytsoft.org>");
-
- /* Initialize DirectX abstraction */
- GST_DEBUG ("Initializing DirectX abstraction layer");
- directx_initialize (&directx_init_params);
-
- /* Initialize DirectX API */
- if (!directx_initialize_best_available_api ())
- GST_DEBUG ("Unable to initialize DirectX");
-
- /* Determine DirectX version */
- klass->directx_api = directx_get_best_available_api ();
- klass->directx_version =
- (klass->directx_api !=
- NULL ? klass->directx_api->version : DIRECTX_VERSION_UNKNOWN);
- klass->is_directx_supported = directx_is_supported ();
-}
+ "David Hoyt <dhoyt@hoytsoft.org>, Roland Krikava <info@bluedigits.com>");
-static void
-gst_d3dvideosink_clear (GstD3DVideoSink * sink)
-{
- sink->enable_navigation_events = TRUE;
- sink->keep_aspect_ratio = FALSE;
+ gst_element_class_add_pad_template (gstelement_class,
+ gst_static_pad_template_get (&sink_template));
- sink->window_closed = FALSE;
- sink->window_handle = NULL;
- sink->is_new_window = FALSE;
- sink->is_hooked = FALSE;
+ g_static_rec_mutex_init (&klass->lock);
}
static void
gst_d3dvideosink_init (GstD3DVideoSink * sink)
{
- gst_d3dvideosink_clear (sink);
+ GST_DEBUG_OBJECT (sink, " ");
+
+ d3d_class_init (sink);
- g_mutex_init (&sink->d3d_device_lock);
+ g_value_init (&sink->par, GST_TYPE_FRACTION);
+ gst_value_set_fraction (&sink->par, 1, 1);
- sink->par = g_new0 (GValue, 1);
- g_value_init (sink->par, GST_TYPE_FRACTION);
- gst_value_set_fraction (sink->par, 1, 1);
+ /* Init Properties */
+ sink->keep_aspect_ratio = DEFAULT_KEEP_ASPECT_RATIO;
+ sink->create_internal_window = DEFAULT_CREATE_RENDER_WINDOW;
+ sink->stream_stop_on_close = DEFAULT_STREAM_STOP_ON_CLOSE;
+ sink->enable_navigation_events = DEFAULT_ENABLE_NAVIGATION_EVENTS;
- /* TODO: Copied from GstVideoSink; should we use that as base class? */
- /* 20ms is more than enough, 80-130ms is noticable */
- gst_base_sink_set_max_lateness (GST_BASE_SINK (sink), 20 * GST_MSECOND);
- gst_base_sink_set_qos_enabled (GST_BASE_SINK (sink), TRUE);
+ g_static_rec_mutex_init (&sink->lock);
}
+/** GObject Functions **/
+
static void
gst_d3dvideosink_finalize (GObject * gobject)
{
GstD3DVideoSink *sink = GST_D3DVIDEOSINK (gobject);
- if (sink->par) {
- g_free (sink->par);
- sink->par = NULL;
- }
+ GST_DEBUG_OBJECT (sink, " ");
- g_mutex_clear (&sink->d3d_device_lock);
+ d3d_class_destroy (sink);
- G_OBJECT_CLASS (parent_class)->finalize (gobject);
+ g_static_rec_mutex_free (&sink->lock);
+
+ G_OBJECT_CLASS (gst_d3dvideosink_parent_class)->finalize (gobject);
}
+
static void
gst_d3dvideosink_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
@@ -353,23 +205,17 @@ gst_d3dvideosink_set_property (GObject * object, guint prop_id,
GstD3DVideoSink *sink = GST_D3DVIDEOSINK (object);
switch (prop_id) {
- case PROP_ENABLE_NAVIGATION_EVENTS:
- sink->enable_navigation_events = g_value_get_boolean (value);
- break;
case PROP_KEEP_ASPECT_RATIO:
sink->keep_aspect_ratio = g_value_get_boolean (value);
break;
- case PROP_PIXEL_ASPECT_RATIO:
- g_free (sink->par);
- sink->par = g_new0 (GValue, 1);
- g_value_init (sink->par, GST_TYPE_FRACTION);
- if (!g_value_transform (value, sink->par)) {
- g_warning ("Could not transform string to aspect ratio");
- gst_value_set_fraction (sink->par, 1, 1);
- }
- GST_DEBUG_OBJECT (sink, "set PAR to %d/%d",
- gst_value_get_fraction_numerator (sink->par),
- gst_value_get_fraction_denominator (sink->par));
+ case PROP_CREATE_RENDER_WINDOW:
+ sink->create_internal_window = g_value_get_boolean (value);
+ break;
+ case PROP_STREAM_STOP_ON_CLOSE:
+ sink->stream_stop_on_close = g_value_get_boolean (value);
+ break;
+ case PROP_ENABLE_NAVIGATION_EVENTS:
+ sink->enable_navigation_events = g_value_get_boolean (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -378,20 +224,23 @@ gst_d3dvideosink_set_property (GObject * object, guint prop_id,
}
static void
-gst_d3dvideosink_get_property (GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec)
+gst_d3dvideosink_get_property (GObject * object, guint prop_id, GValue * value,
+ GParamSpec * pspec)
{
GstD3DVideoSink *sink = GST_D3DVIDEOSINK (object);
switch (prop_id) {
- case PROP_ENABLE_NAVIGATION_EVENTS:
- g_value_set_boolean (value, sink->enable_navigation_events);
- break;
case PROP_KEEP_ASPECT_RATIO:
g_value_set_boolean (value, sink->keep_aspect_ratio);
break;
- case PROP_PIXEL_ASPECT_RATIO:
- g_value_transform (sink->par, value);
+ case PROP_CREATE_RENDER_WINDOW:
+ g_value_set_boolean (value, sink->create_internal_window);
+ break;
+ case PROP_STREAM_STOP_ON_CLOSE:
+ g_value_set_boolean (value, sink->stream_stop_on_close);
+ break;
+ case PROP_ENABLE_NAVIGATION_EVENTS:
+ g_value_set_boolean (value, sink->enable_navigation_events);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -399,70 +248,7 @@ gst_d3dvideosink_get_property (GObject * object, guint prop_id,
}
}
-static GstCaps *
-gst_d3dvideosink_get_device_caps (GstBaseSink * basesink, D3DDISPLAYMODE d3ddm)
-{
- GstD3DVideoSink *sink = GST_D3DVIDEOSINK (basesink);
- gint i;
- GstCaps *caps;
- GstCaps *c;
-
- caps = gst_caps_new_empty ();
- c = gst_caps_normalize (gst_pad_get_pad_template_caps (GST_VIDEO_SINK_PAD
- (sink)));
-
- for (i = 0; i < gst_caps_get_size (c); i++) {
- GstStructure *stru;
- stru = gst_caps_get_structure (c, i);
- if (gst_structure_has_name (stru, "video/x-raw")) {
- GstVideoFormat format;
- const gchar *s;
- D3DFORMAT d3dfourcc = 0;
- s = gst_structure_get_string (stru, "format");
- format = gst_video_format_from_string (s);
- switch (format) {
- case GST_VIDEO_FORMAT_YV12:
- case GST_VIDEO_FORMAT_I420:
- d3dfourcc = (D3DFORMAT) MAKEFOURCC ('Y', 'V', '1', '2');
- break;
- case GST_VIDEO_FORMAT_BGR:
- d3dfourcc = D3DFMT_R8G8B8;
- break;
- case GST_VIDEO_FORMAT_BGRA:
- d3dfourcc = D3DFMT_A8R8G8B8;
- break;
- case GST_VIDEO_FORMAT_BGRx:
- d3dfourcc = D3DFMT_X8R8G8B8;
- break;
- case GST_VIDEO_FORMAT_RGB16:
- d3dfourcc = D3DFMT_R5G6B5;
- break;
- case GST_VIDEO_FORMAT_UYVY:
- d3dfourcc = D3DFMT_UYVY;
- break;
- case GST_VIDEO_FORMAT_YUY2:
- d3dfourcc = D3DFMT_YUY2;
- break;
- case GST_VIDEO_FORMAT_NV12:
- d3dfourcc = (D3DFORMAT) MAKEFOURCC ('N', 'V', '1', '2');
- break;
- default:
- break;
- }
- if (d3dfourcc == 0)
- continue;
- if (SUCCEEDED (IDirect3D9_CheckDeviceFormat (shared.d3d,
- D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, d3ddm.Format, 0,
- D3DRTYPE_SURFACE, d3dfourcc))) {
- /* hw supports this format */
- gst_caps_append (caps, gst_caps_copy_nth (c, i));
- }
- }
- }
-
- gst_caps_unref (c);
- return caps;
-}
+/** GstBaseSinkClass Functions **/
static GstCaps *
gst_d3dvideosink_get_caps (GstBaseSink * basesink, GstCaps * filter)
@@ -470,1037 +256,370 @@ gst_d3dvideosink_get_caps (GstBaseSink * basesink, GstCaps * filter)
GstD3DVideoSink *sink = GST_D3DVIDEOSINK (basesink);
GstCaps *caps;
- /* restrict caps based on the hw capabilities */
- if (shared.d3d) {
- D3DDISPLAYMODE d3ddm;
- if (FAILED (IDirect3D9_GetAdapterDisplayMode (shared.d3d,
- D3DADAPTER_DEFAULT, &d3ddm))) {
- GST_WARNING ("Unable to request adapter display mode");
- caps = gst_pad_get_pad_template_caps (GST_VIDEO_SINK_PAD (sink));
- } else {
- caps = gst_d3dvideosink_get_device_caps (basesink, d3ddm);
- }
- } else {
+ caps = d3d_supported_caps (sink);
+ if (!caps)
caps = gst_pad_get_pad_template_caps (GST_VIDEO_SINK_PAD (sink));
- if (filter) {
- GstCaps *intersection;
-
- intersection =
- gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
- gst_caps_unref (caps);
- caps = intersection;
- }
- }
- return caps;
-}
-
-static void
-gst_d3dvideosink_close_window (GstD3DVideoSink * sink)
-{
- if (!sink || !sink->window_handle)
- return;
-
- if (!sink->is_new_window) {
- gst_d3dvideosink_remove_window_for_renderer (sink);
- return;
- }
-
- SendMessage (sink->window_handle, WM_CLOSE, (WPARAM) NULL, (WPARAM) NULL);
- g_thread_join (sink->window_thread);
- sink->is_new_window = FALSE;
-}
-
-static gboolean
-gst_d3dvideosink_create_shared_hidden_window (GstD3DVideoSink * sink)
-{
- GST_DEBUG ("Creating Direct3D hidden window");
-
- shared.hidden_window_created_signal = CreateSemaphore (NULL, 0, 1, NULL);
- if (shared.hidden_window_created_signal == NULL)
- goto failed;
-
- shared.hidden_window_thread = g_thread_try_new ("shared hidden window thread",
- (GThreadFunc) gst_d3dvideosink_shared_hidden_window_thread, sink, NULL);
-
- /* wait maximum 60 seconds for window to be created */
- if (WaitForSingleObject (shared.hidden_window_created_signal,
- 60000) != WAIT_OBJECT_0)
- goto failed;
-
- CloseHandle (shared.hidden_window_created_signal);
-
- GST_DEBUG ("Successfully created Direct3D hidden window, handle: %p",
- shared.hidden_window_handle);
-
- return (shared.hidden_window_handle != NULL);
-
-failed:
- CloseHandle (shared.hidden_window_created_signal);
- GST_ELEMENT_ERROR (sink, RESOURCE, WRITE,
- ("Error creating Direct3D hidden window"), (NULL));
- return FALSE;
-}
-
-static gboolean
-gst_d3dvideosink_shared_hidden_window_created (GstD3DVideoSink * sink)
-{
- /* Should only be called from the shared window thread. */
- ReleaseSemaphore (shared.hidden_window_created_signal, 1, NULL);
- return TRUE;
-}
-
-static gboolean
-gst_d3dvideosink_shared_hidden_window_thread (GstD3DVideoSink * sink)
-{
- WNDCLASS WndClass;
- HWND hWnd;
- MSG msg;
-
- memset (&WndClass, 0, sizeof (WNDCLASS));
- WndClass.hInstance = GetModuleHandle (NULL);
- WndClass.lpszClassName = TEXT ("GST-Shared-Hidden-D3DSink");
- WndClass.lpfnWndProc = SharedHiddenWndProc;
- if (!RegisterClass (&WndClass)) {
- GST_ERROR ("Unable to register Direct3D hidden window class");
- return FALSE;
- }
-
- hWnd = CreateWindowEx (0, WndClass.lpszClassName,
- TEXT ("GStreamer Direct3D hidden window"),
- WS_POPUP, 0, 0, 1, 1, HWND_MESSAGE, NULL, WndClass.hInstance, sink);
-
- if (hWnd == NULL) {
- GST_ERROR_OBJECT (sink, "Failed to create Direct3D hidden window");
- goto error;
- }
-
- GST_DEBUG ("Direct3D hidden window handle: %p", hWnd);
-
- shared.hidden_window_handle = hWnd;
- shared.device_lost_timer = 0;
- shared.device_lost = FALSE;
-
- gst_d3dvideosink_shared_hidden_window_created (sink);
-
- GST_DEBUG ("Entering Direct3D hidden window message loop");
-
- /* start message loop processing */
- while (TRUE) {
- while (GetMessage (&msg, NULL, 0, 0)) {
- TranslateMessage (&msg);
- DispatchMessage (&msg);
- }
-
- if (msg.message == WM_QUIT || msg.message == WM_CLOSE)
- break;
- }
-
- GST_DEBUG ("Leaving Direct3D hidden window message loop");
-
-/*success:*/
- /* Kill the device lost timer if it's running */
- if (shared.device_lost_timer != 0)
- KillTimer (hWnd, shared.device_lost_timer);
- UnregisterClass (WndClass.lpszClassName, WndClass.hInstance);
-
- shared.device_lost_timer = 0;
- return TRUE;
-
-error:
- /* Kill the device lost timer if it's running */
- if (shared.device_lost_timer != 0)
- KillTimer (hWnd, shared.device_lost_timer);
- if (hWnd)
- DestroyWindow (hWnd);
- UnregisterClass (WndClass.lpszClassName, WndClass.hInstance);
-
- shared.hidden_window_handle = NULL;
- shared.device_lost_timer = 0;
-
- ReleaseSemaphore (shared.hidden_window_created_signal, 1, NULL);
- return FALSE;
-}
-
-LRESULT APIENTRY
-SharedHiddenWndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
-{
- GstD3DVideoSink *sink;
-
- /* lParam holds pointer to the sink. */
-
- sink = (GstD3DVideoSink *) lParam;
- switch (message) {
- case WM_DIRECTX_D3D_INIT_DEVICE:
- {
- shared.device_lost_sink = NULL;
- GST_DEBUG ("Initializing Direct3D");
- if (!gst_d3dvideosink_initialize_d3d_device (sink))
- gst_d3dvideosink_notify_device_lost (sink);
- else
- GST_DEBUG ("Direct3D initialization complete");
- break;
-
- }
- case WM_DIRECTX_D3D_INIT_DEVICELOST:
- {
- if (shared.device_lost)
- break;
-
- shared.device_lost = TRUE;
- GST_D3DVIDEOSINK_D3D_DEVICE_LOCK (sink);
-
-
- /* Handle device lost by creating a timer and posting WM_D3D_DEVICELOST twice a second */
- /* Create a timer to periodically check the d3d device and attempt to recreate it */
- shared.device_lost_timer = SetTimer (hWnd, IDT_DEVICELOST, 500, NULL);
- shared.device_lost_sink = sink;
-
- /* Try it once immediately */
- SendMessage (hWnd, WM_DIRECTX_D3D_DEVICELOST, 0, (LPARAM) sink);
- break;
- }
- case WM_TIMER:
- {
- /* Did we receive a message to check if the device is available again? */
- if (wParam == IDT_DEVICELOST) {
- /* This will synchronously call SharedHiddenWndProc() because this thread is the one that created the window. */
- SendMessage (hWnd, WM_DIRECTX_D3D_DEVICELOST, 0,
- (LPARAM) shared.device_lost_sink);
- return 0;
- }
- break;
- }
- case WM_DIRECTX_D3D_DEVICELOST:
- {
- return gst_d3dvideosink_device_lost (sink);
- }
- case WM_DIRECTX_D3D_END_DEVICELOST:
- {
- if (!shared.device_lost)
- break;
-
- /* gst_d3dvideosink_notify_device_reset() sends this message. */
- if (shared.device_lost_timer != 0)
- KillTimer (hWnd, shared.device_lost_timer);
-
- shared.device_lost_timer = 0;
- shared.device_lost = FALSE;
-
- GST_D3DVIDEOSINK_D3D_DEVICE_UNLOCK (sink);
-
- /* Refresh the video with the last buffer */
- gst_d3dvideosink_update_all (sink);
-
- /* Then redraw just in case we don't have a last buffer */
- gst_d3dvideosink_refresh_all (sink);
-
- shared.device_lost_sink = NULL;
- break;
- }
- case WM_DESTROY:
- {
- PostQuitMessage (0);
- return 0;
- }
- case WM_DIRECTX_D3D_RESIZE:
- {
- return gst_d3dvideosink_device_lost (sink);
- }
- }
-
- return DefWindowProc (hWnd, message, wParam, lParam);
-}
-
-static void
-gst_d3dvideosink_close_shared_hidden_window (GstD3DVideoSink * sink)
-{
- if (!shared.hidden_window_handle)
- return;
-
- SendMessage (shared.hidden_window_handle, WM_CLOSE, (WPARAM) NULL,
- (WPARAM) NULL);
- if (shared.hidden_window_thread) {
- g_thread_join (shared.hidden_window_thread);
- shared.hidden_window_thread = NULL;
- }
- shared.hidden_window_handle = NULL;
-
- GST_DEBUG ("Successfully closed Direct3D hidden window");
-}
-
-/* WNDPROC for application-supplied windows */
-LRESULT APIENTRY
-WndProcHook (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
-{
- /* Handle certain actions specially on the window passed to us.
- * Then forward back to the original window.
- */
- GstD3DVideoSink *sink =
- (GstD3DVideoSink *) GetProp (hWnd, TEXT ("GstD3DVideoSink"));
-
- if (!sink)
- return FALSE;
-
- switch (message) {
- case WM_ERASEBKGND:
- return TRUE;
- case WM_COPYDATA:
- {
- gst_d3dvideosink_wnd_proc (sink, hWnd, message, wParam, lParam);
- return TRUE;
- }
- case WM_PAINT:
- {
- LRESULT ret;
- ret = CallWindowProc (sink->prevWndProc, hWnd, message, wParam, lParam);
- /* Call this afterwards to ensure that our paint happens last */
- gst_d3dvideosink_wnd_proc (sink, hWnd, message, wParam, lParam);
- return ret;
- }
- default:
- {
- /* Check it */
- gst_d3dvideosink_wnd_proc (sink, hWnd, message, wParam, lParam);
- return CallWindowProc (sink->prevWndProc, hWnd, message, wParam, lParam);
- }
- }
-}
-
-/* WndProc for our default window, if the application didn't supply one */
-LRESULT APIENTRY
-WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
-{
- GstD3DVideoSink *sink;
-
- if (message == WM_CREATE) {
- /* lParam holds a pointer to a CREATESTRUCT instance which in turn holds the parameter used when creating the window. */
- GstD3DVideoSink *sink =
- (GstD3DVideoSink *) ((LPCREATESTRUCT) lParam)->lpCreateParams;
-
- /* In our case, this is a pointer to the sink. So we immediately attach it for use in subsequent calls. */
- SetWindowLongPtr (hWnd, GWLP_USERDATA, (LONG_PTR) sink);
-
- /* signal application we created a window */
- gst_video_overlay_got_window_handle (GST_VIDEO_OVERLAY (sink),
- (guintptr) hWnd);
- }
-
-
- sink = (GstD3DVideoSink *) GetWindowLongPtr (hWnd, GWLP_USERDATA);
- gst_d3dvideosink_wnd_proc (sink, hWnd, message, wParam, lParam);
-
- switch (message) {
- case WM_ERASEBKGND:
- case WM_COPYDATA:
- return TRUE;
-
- case WM_DESTROY:
- {
- PostQuitMessage (0);
- return 0;
- }
- }
-
- return DefWindowProc (hWnd, message, wParam, lParam);
-}
-
-static void
-gst_d3dvideosink_wnd_proc (GstD3DVideoSink * sink, HWND hWnd, UINT message,
- WPARAM wParam, LPARAM lParam)
-{
- if (!sink)
- return;
- switch (message) {
- case WM_COPYDATA:
- {
- PCOPYDATASTRUCT p_ipc_cds;
- p_ipc_cds = (PCOPYDATASTRUCT) lParam;
- switch (p_ipc_cds->dwData) {
- case IPC_SET_WINDOW:
- {
- IPCData *p_ipc_data;
- p_ipc_data = (IPCData *) p_ipc_cds->dwData;
-
- GST_DEBUG ("Received IPC call to subclass the window handler");
-
- sink->window_handle = p_ipc_data->hwnd;
- sink->prevWndProc =
- (WNDPROC) SetWindowLongPtr (sink->window_handle, GWLP_WNDPROC,
- (LONG_PTR) p_ipc_data->wnd_proc);
- break;
- }
- }
- break;
- }
- case WM_PAINT:
- {
- gst_d3dvideosink_refresh (sink);
- break;
- }
- case WM_CLOSE:
- case WM_DESTROY:
- {
- sink->window_closed = TRUE;
- //GST_ELEMENT_ERROR (sink, RESOURCE, NOT_FOUND, ("Output window was closed"), (NULL));
- break;
- }
- case WM_CHAR:
- case WM_KEYDOWN:
- case WM_KEYUP:
- {
- if (!sink->enable_navigation_events)
- break;
- }
- {
- gunichar2 wcrep[128];
- if (GetKeyNameTextW (lParam, (LPWSTR) wcrep, 128)) {
- gchar *utfrep = g_utf16_to_utf8 (wcrep, 128, NULL, NULL, NULL);
- if (utfrep) {
- if (message == WM_CHAR || message == WM_KEYDOWN)
- gst_navigation_send_key_event (GST_NAVIGATION (sink), "key-press",
- utfrep);
- if (message == WM_CHAR || message == WM_KEYUP)
- gst_navigation_send_key_event (GST_NAVIGATION (sink),
- "key-release", utfrep);
- g_free (utfrep);
- }
- }
- break;
- }
- case WM_LBUTTONDOWN:
- case WM_LBUTTONUP:
- case WM_RBUTTONDOWN:
- case WM_RBUTTONUP:
- case WM_MBUTTONDOWN:
- case WM_MBUTTONUP:
- case WM_MOUSEMOVE:
- {
- if (!sink->enable_navigation_events)
- break;
- }
- {
- gint x, y, button;
- const gchar *action;
-
- switch (message) {
- case WM_MOUSEMOVE:
- button = 0;
- action = "mouse-move";
- break;
- case WM_LBUTTONDOWN:
- button = 1;
- action = "mouse-button-press";
- break;
- case WM_LBUTTONUP:
- button = 1;
- action = "mouse-button-release";
- break;
- case WM_RBUTTONDOWN:
- button = 2;
- action = "mouse-button-press";
- break;
- case WM_RBUTTONUP:
- button = 2;
- action = "mouse-button-release";
- break;
- case WM_MBUTTONDOWN:
- button = 3;
- action = "mouse-button-press";
- break;
- case WM_MBUTTONUP:
- button = 3;
- action = "mouse-button-release";
- break;
- default:
- button = 4;
- action = NULL;
- break;
- }
-
- x = LOWORD (lParam);
- y = HIWORD (lParam);
-
- if (button == 0) {
- GST_DEBUG_OBJECT (sink, "Mouse moved to %dx%d", x, y);
- } else
- GST_DEBUG_OBJECT (sink, "Mouse button %d pressed at %dx%d", button, x,
- y);
-
- if (button < 4)
- gst_navigation_send_mouse_event (GST_NAVIGATION (sink), action,
- button, x, y);
-
- break;
- }
- }
-}
-
-static gpointer
-gst_d3dvideosink_window_thread (GstD3DVideoSink * sink)
-{
- WNDCLASS WndClass;
- int width, height;
- int offx, offy;
- DWORD exstyle, style;
- HWND video_window;
- RECT rect;
- int screenwidth;
- int screenheight;
- MSG msg;
-
- memset (&WndClass, 0, sizeof (WNDCLASS));
- WndClass.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
- WndClass.hInstance = GetModuleHandle (NULL);
- WndClass.lpszClassName = TEXT ("GST-D3DSink");
- WndClass.hbrBackground = (HBRUSH) GetStockObject (BLACK_BRUSH);
- WndClass.hCursor = LoadCursor (NULL, IDC_ARROW);
- WndClass.hIcon = LoadIcon (NULL, IDI_APPLICATION);
- WndClass.cbClsExtra = 0;
- WndClass.cbWndExtra = 0;
- WndClass.lpfnWndProc = WndProc;
- RegisterClass (&WndClass);
-
- /* By default, create a normal top-level window, the size of the video. */
-
- /* GST_VIDEO_SINK_WIDTH() is the aspect-ratio-corrected size of the video. */
- /* GetSystemMetrics() returns the width of the dialog's border (doubled b/c of left and right borders). */
- width = GST_VIDEO_SINK_WIDTH (sink) + GetSystemMetrics (SM_CXSIZEFRAME) * 2;
- height = GST_VIDEO_SINK_HEIGHT (sink) + GetSystemMetrics (SM_CYCAPTION) +
- (GetSystemMetrics (SM_CYSIZEFRAME) * 2);
-
- SystemParametersInfo (SPI_GETWORKAREA, 0, &rect, 0);
- screenwidth = rect.right - rect.left;
- screenheight = rect.bottom - rect.top;
- offx = rect.left;
- offy = rect.top;
-
- /* Make it fit into the screen without changing the aspect ratio. */
- if (width > screenwidth) {
- double ratio = (double) screenwidth / (double) width;
- width = screenwidth;
- height = (int) (height * ratio);
- }
-
- if (height > screenheight) {
- double ratio = (double) screenheight / (double) height;
- height = screenheight;
- width = (int) (width * ratio);
- }
-
- style = WS_OVERLAPPEDWINDOW; /* Normal top-level window */
- exstyle = 0;
-
- video_window = CreateWindowEx (exstyle, TEXT ("GST-D3DSink"),
- TEXT ("GStreamer Direct3D sink default window"),
- style, offx, offy, width, height, NULL, NULL, WndClass.hInstance, sink);
- if (video_window == NULL) {
- GST_ERROR_OBJECT (sink, "Failed to create window");
- return NULL;
+ if (caps && filter) {
+ GstCaps *isect;
+ isect = gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
+ gst_caps_unref (caps);
+ caps = isect;
}
- sink->is_new_window = TRUE;
- sink->window_handle = video_window;
-
- /* Now show the window, as appropriate */
- ShowWindow (video_window, SW_SHOWNORMAL);
-
- /* Trigger the initial paint of the window */
- UpdateWindow (video_window);
-
- ReleaseSemaphore (sink->window_created_signal, 1, NULL);
-
- /* start message loop processing our default window messages */
- while (TRUE) {
- while (GetMessage (&msg, NULL, 0, 0)) {
- TranslateMessage (&msg);
- DispatchMessage (&msg);
- }
-
- if (msg.message == WM_QUIT || msg.message == WM_CLOSE)
- break;
- }
-
- UnregisterClass (WndClass.lpszClassName, WndClass.hInstance);
- sink->window_handle = NULL;
- return NULL;
-
-}
-
-static gboolean
-gst_d3dvideosink_create_default_window (GstD3DVideoSink * sink)
-{
- if (shared.device_lost)
- return FALSE;
-
- sink->window_created_signal = CreateSemaphore (NULL, 0, 1, NULL);
- if (sink->window_created_signal == NULL)
- goto failed;
-
- sink->window_thread = g_thread_try_new ("window thread",
- (GThreadFunc) gst_d3dvideosink_window_thread, sink, NULL);
-
- /* wait maximum 10 seconds for window to be created */
- if (WaitForSingleObject (sink->window_created_signal, 10000) != WAIT_OBJECT_0)
- goto failed;
-
- CloseHandle (sink->window_created_signal);
- return (sink->window_handle != NULL);
-
-failed:
- CloseHandle (sink->window_created_signal);
- GST_ELEMENT_ERROR (sink, RESOURCE, WRITE,
- ("Error creating our default window"), (NULL));
- return FALSE;
+ return caps;
}
-static void
-gst_d3dvideosink_set_window_handle (GstVideoOverlay * overlay,
- guintptr window_id)
+static guint16
+flip_b16 (guint16 b)
{
- GstD3DVideoSink *sink = GST_D3DVIDEOSINK (overlay);
- HWND hWnd = (HWND) window_id;
-
- if (hWnd == sink->window_handle) {
- GST_DEBUG ("Window already set");
- return;
- }
+ guint16 ret = 0, tmp = 0x8000;
+ gint i;
- GST_D3DVIDEOSINK_D3D_DEVICE_LOCK (sink);
- /* If we're already playing/paused, then we need to lock the swap chain, and recreate it with the new window. */
- if (sink->d3ddev != NULL) {
- /* Close our existing window if there is one */
- gst_d3dvideosink_close_window (sink);
- /* Save our window id */
- sink->window_handle = hWnd;
- gst_d3dvideosink_set_window_for_renderer (sink);
- sink->window_closed = FALSE;
-
- gst_d3dvideosink_notify_device_reinit (sink);
- } else {
- sink->window_handle = hWnd;
+ for (i = 0, tmp = 1; tmp != 0; i++) {
+ //printf("%x\n", tmp);
+ if (b & tmp)
+ ret |= (0x8000 >> i);
+ tmp <<= 1;
}
-
- GST_D3DVIDEOSINK_D3D_DEVICE_UNLOCK (sink);
-
- GST_DEBUG_OBJECT (sink, "Direct3D window id successfully changed to %p",
- hWnd);
-
- gst_d3dvideosink_update (GST_BASE_SINK_CAST (sink));
- return;
+ return ret;
}
-/* Hook for out-of-process rendering */
-LRESULT CALLBACK
-gst_d3dvideosink_hook_proc (int nCode, WPARAM wParam, LPARAM lParam)
+static guint32
+flip_b32 (guint32 b, gboolean bitshift)
{
- return CallNextHookEx (NULL, nCode, wParam, lParam);
-}
+ guint32 ret = 0, tmp = 0x80000000;
+ gint i;
-static void
-gst_d3dvideosink_set_window_for_renderer (GstD3DVideoSink * sink)
-{
- WNDPROC currWndProc;
-
- /* Application has requested a specific window ID */
- sink->is_new_window = FALSE;
- currWndProc = (WNDPROC) GetWindowLongPtr (sink->window_handle, GWLP_WNDPROC);
- if (sink->prevWndProc != currWndProc && currWndProc != WndProcHook)
- sink->prevWndProc =
- (WNDPROC) SetWindowLongPtr (sink->window_handle, GWLP_WNDPROC,
- (LONG_PTR) WndProcHook);
-
- /* Allows us to pick up the video sink inside the msg handler */
- SetProp (sink->window_handle, TEXT ("GstD3DVideoSink"), sink);
-
- if (!(sink->prevWndProc)) {
- /* If we were unable to set the window procedure, it's possible we're attempting to render into the */
- /* window from a separate process. In that case, we need to use a windows hook to see the messages */
- /* going to the window we're drawing on. We must take special care that our hook is properly removed */
- /* when we're done. */
- GST_DEBUG ("Unable to set window procedure. Error: %s",
- g_win32_error_message (GetLastError ()));
- GST_D3DVIDEOSINK_SHARED_D3D_HOOK_LOCK;
- gst_d3dvideosink_hook_window_for_renderer (sink);
- GST_D3DVIDEOSINK_SHARED_D3D_HOOK_UNLOCK;
- } else {
- GST_DEBUG ("Set wndproc to %p from %p", WndProcHook, sink->prevWndProc);
- GST_DEBUG ("Set renderer window to %p", sink->window_handle);
+ for (i = 0, tmp = 1; tmp != 0; i++) {
+ //printf("%x\n", tmp);
+ if (b & tmp)
+ ret |= (0x80000000 >> i);
+ tmp <<= 1;
}
- sink->is_new_window = FALSE;
-}
+ if (bitshift && G_BYTE_ORDER == G_LITTLE_ENDIAN)
+ ret >>= 8;
-static HHOOK
-gst_d3dvideosink_find_hook (DWORD pid, DWORD tid)
-{
- HWND key;
- GHashTableIter iter;
- GstD3DVideoSinkHookData *value;
-
- if (!shared.hook_tbl)
- return NULL;
-
- g_hash_table_iter_init (&iter, shared.hook_tbl);
- while (g_hash_table_iter_next (&iter, (gpointer) & key, (gpointer) & value)) {
- if (value && value->process_id == pid && value->thread_id == tid)
- return value->hook;
- }
- return NULL;
-}
-
-static GstD3DVideoSinkHookData *
-gst_d3dvideosink_hook_data (HWND window_id)
-{
- if (!shared.hook_tbl)
- return NULL;
- return (GstD3DVideoSinkHookData *) g_hash_table_lookup (shared.hook_tbl,
- window_id);
+ return ret;
}
-static GstD3DVideoSinkHookData *
-gst_d3dvideosink_register_hook_data (HWND window_id)
-{
- GstD3DVideoSinkHookData *data;
- if (!shared.hook_tbl)
- shared.hook_tbl = g_hash_table_new (NULL, NULL);
- data =
- (GstD3DVideoSinkHookData *) g_hash_table_lookup (shared.hook_tbl,
- window_id);
- if (!data) {
- data =
- (GstD3DVideoSinkHookData *) g_malloc (sizeof (GstD3DVideoSinkHookData));
- memset (data, 0, sizeof (GstD3DVideoSinkHookData));
- g_hash_table_insert (shared.hook_tbl, window_id, data);
- }
- return data;
-}
+typedef enum
+{
+ VFMT_RGBx = 0,
+ VFMT_BGRx,
+ VFMT_xRGB,
+ VFMT_xBGR,
+ VFMT_RGBA,
+ VFMT_BGRA,
+ VFMT_ARGB,
+ VFMT_ABGR,
+ VFMT_RGB,
+ VFMT_BGR,
+ VFMT_RGB16,
+ VFMT_BGR16,
+ VFMT_RGB15,
+ VFMT_BGR15,
+} VFmtMap;
+
+static GstVideoFormatDetails vfmt_details[] = {
+ { // GST_VIDEO_FORMAT_RGBx
+ 0xff000000, 0x00ff0000, 0x0000ff00, 0,
+ 0, 0, 0, 0,
+ 0, 8, 16, 0,
+ 8, 8, 8, 0,
+ 32, 24, G_BIG_ENDIAN, 4},
+ { // GST_VIDEO_FORMAT_BGRx
+ 0x0000ff00, 0x00ff0000, 0xff000000, 0,
+ 0, 0, 0, 0,
+ 16, 8, 0, 0,
+ 8, 8, 8, 0,
+ 32, 24, G_BIG_ENDIAN, 4},
+ { // GST_VIDEO_FORMAT_xRGB
+ 0x00ff0000, 0x0000ff00, 0x000000ff, 0,
+ 0, 0, 0, 0,
+ 8, 16, 24, 0,
+ 8, 8, 8, 0,
+ 32, 24, G_BIG_ENDIAN, 4},
+ { // GST_VIDEO_FORMAT_xBGR
+ 0x000000ff, 0x0000ff00, 0x00ff0000, 0,
+ 0, 0, 0, 0,
+ 24, 16, 8, 0,
+ 8, 8, 8, 0,
+ 32, 24, G_BIG_ENDIAN, 4},
+ { // GST_VIDEO_FORMAT_RGBA
+ 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff,
+ 0, 0, 0, 0,
+ 0, 8, 16, 24,
+ 8, 8, 8, 8,
+ 32, 32, G_BIG_ENDIAN, 4},
+ { // GST_VIDEO_FORMAT_BGRA
+ 0x0000ff00, 0x00ff0000, 0xff000000, 0x000000ff,
+ 0, 0, 0, 0,
+ 16, 8, 0, 24,
+ 8, 8, 8, 8,
+ 32, 32, G_BIG_ENDIAN, 4},
+ { // GST_VIDEO_FORMAT_ARGB
+ 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000,
+ 0, 0, 0, 0,
+ 8, 16, 24, 0,
+ 8, 8, 8, 8,
+ 32, 32, G_BIG_ENDIAN, 4},
+ { // GST_VIDEO_FORMAT_ABGR
+ 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000,
+ 0, 0, 0, 0,
+ 24, 16, 8, 0,
+ 8, 8, 8, 8,
+ 32, 32, G_BIG_ENDIAN, 4},
+ { // GST_VIDEO_FORMAT_RGB
+ 0x00ff0000, 0x0000ff00, 0x000000ff, 0,
+ 0, 0, 0, 0,
+ 0, 8, 16, 0,
+ 8, 8, 8, 0,
+ 24, 24, G_BIG_ENDIAN, 3},
+ { // GST_VIDEO_FORMAT_BGR
+ 0x000000ff, 0x0000ff00, 0x00ff0000, 0,
+ 0, 0, 0, 0,
+ 16, 8, 0, 0,
+ 8, 8, 8, 0,
+ 24, 24, G_BIG_ENDIAN, 3},
+ { // GST_VIDEO_FORMAT_RGB16
+ 0, 0, 0, 0,
+ 0xf800, 0x07e0, 0x001f, 0,
+ 11, 5, 0, 0,
+ 5, 6, 5, 0,
+ 16, 16, G_LITTLE_ENDIAN, 2},
+ { // GST_VIDEO_FORMAT_BGR16
+ 0, 0, 0, 0,
+ 0x001f, 0x07e0, 0xf800, 0,
+ 0, 5, 11, 0,
+ 5, 6, 5, 0,
+ 16, 16, G_LITTLE_ENDIAN, 2},
+ { // GST_VIDEO_FORMAT_RGB15
+ 0, 0, 0, 0,
+ 0x7c00, 0x03e0, 0x001f, 0,
+ 10, 5, 0, 0,
+ 5, 5, 5, 0,
+ 16, 15, G_LITTLE_ENDIAN, 2},
+ { // GST_VIDEO_FORMAT_BGR15
+ 0, 0, 0, 0,
+ 0x001f, 0x03e0, 0x7c00, 0,
+ 0, 5, 10, 0,
+ 5, 5, 5, 0,
+ 16, 15, G_LITTLE_ENDIAN, 2}
+};
static gboolean
-gst_d3dvideosink_unregister_hook_data (HWND window_id)
-{
- GstD3DVideoSinkHookData *data;
- if (!shared.hook_tbl)
- return FALSE;
- data =
- (GstD3DVideoSinkHookData *) g_hash_table_lookup (shared.hook_tbl,
- window_id);
- if (!data)
- return TRUE;
- if (g_hash_table_remove (shared.hook_tbl, window_id))
- g_free (data);
- return TRUE;
-}
-
-static void
-gst_d3dvideosink_hook_window_for_renderer (GstD3DVideoSink * sink)
-{
- /* Ensure that our window hook isn't already installed. */
- if (!sink->is_new_window && !sink->is_hooked && sink->window_handle) {
- DWORD pid;
- DWORD tid;
-
- GST_DEBUG ("Attempting to apply a windows hook in process %lu.",
- GetCurrentProcessId ());
-
- /* Get thread id of the window in question. */
- tid = GetWindowThreadProcessId (sink->window_handle, &pid);
-
- if (tid) {
- HHOOK hook;
- GstD3DVideoSinkHookData *data;
-
- /* Only apply a hook if there's not one already there. It's possible this is the case if there are multiple */
- /* embedded windows that we're hooking inside of the same dialog/thread. */
-
- hook = gst_d3dvideosink_find_hook (pid, tid);
- data = gst_d3dvideosink_register_hook_data (sink->window_handle);
- if (data && !hook) {
- GST_DEBUG
- ("No other hooks exist for pid %lu and tid %lu. Attempting to add one.",
- pid, tid);
- hook =
- SetWindowsHookEx (WH_CALLWNDPROCRET, gst_d3dvideosink_hook_proc,
- g_hinstDll, tid);
- }
-
- sink->is_hooked = (hook ? TRUE : FALSE);
-
- if (sink->is_hooked) {
- data->hook = hook;
- data->process_id = pid;
- data->thread_id = tid;
- data->window_handle = sink->window_handle;
-
- PostThreadMessage (tid, WM_NULL, 0, 0);
-
- GST_DEBUG ("Window successfully hooked. GetLastError() returned: %s",
- g_win32_error_message (GetLastError ()));
- } else {
- /* Ensure that we clean up any allocated memory. */
- if (data)
- gst_d3dvideosink_unregister_hook_data (sink->window_handle);
- GST_DEBUG
- ("Unable to hook the window. The system provided error was: %s",
- g_win32_error_message (GetLastError ()));
- }
- }
- }
-}
-
-static void
-gst_d3dvideosink_unhook_window_for_renderer (GstD3DVideoSink * sink)
-{
- if (!sink->is_new_window && sink->is_hooked && sink->window_handle) {
- GstD3DVideoSinkHookData *data;
-
- GST_DEBUG ("Unhooking a window in process %lu.", GetCurrentProcessId ());
-
- data = gst_d3dvideosink_hook_data (sink->window_handle);
- if (data) {
- DWORD pid;
- DWORD tid;
- HHOOK hook;
-
- /* Save off a temp ref to the data */
- hook = data->hook;
- tid = data->thread_id;
- pid = data->process_id;
-
- /* Free the memory */
- if (gst_d3dvideosink_unregister_hook_data (sink->window_handle)) {
- /* Check if there's anyone else who still has the hook. If so, then we do nothing. */
- /* If not, then go ahead and unhook. */
- if (gst_d3dvideosink_find_hook (pid, tid)) {
- UnhookWindowsHookEx (hook);
- GST_DEBUG ("Unhooked the window for process %lu and thread %lu.", pid,
- tid);
- }
- }
- }
-
- sink->is_hooked = FALSE;
-
- GST_DEBUG ("Window successfully unhooked in process %lu.",
- GetCurrentProcessId ());
- }
-}
-
-static void
-gst_d3dvideosink_unhook_all_windows (void)
-{
- /* Unhook all windows that may be currently hooked. This is mainly a precaution in case */
- /* a wayward process doesn't properly set state back to NULL (which would remove the hook). */
-
- GST_D3DVIDEOSINK_SHARED_D3D_LOCK;
- GST_D3DVIDEOSINK_SHARED_D3D_HOOK_LOCK;
- {
- GList *item;
- GstD3DVideoSink *s;
-
- GST_DEBUG ("Attempting to unhook all windows for process %lu",
- GetCurrentProcessId ());
-
- for (item = g_list_first (shared.element_list); item; item = item->next) {
- s = (GstD3DVideoSink *) item->data;
- gst_d3dvideosink_unhook_window_for_renderer (s);
- }
- }
- GST_D3DVIDEOSINK_SHARED_D3D_HOOK_UNLOCK;
- GST_D3DVIDEOSINK_SHARED_D3D_UNLOCK;
-}
-
-static void
-gst_d3dvideosink_remove_window_for_renderer (GstD3DVideoSink * sink)
-{
- {
- GST_DEBUG ("Removing custom rendering window procedure");
- if (!sink->is_new_window && sink->window_handle) {
- WNDPROC currWndProc;
-
- /* Retrieve current msg handler */
- currWndProc =
- (WNDPROC) GetWindowLongPtr (sink->window_handle, GWLP_WNDPROC);
-
- /* Return control of application window */
- if (sink->prevWndProc != NULL && currWndProc == WndProcHook) {
- SetWindowLongPtr (sink->window_handle, GWLP_WNDPROC,
- (LONG_PTR) sink->prevWndProc);
-
- sink->prevWndProc = NULL;
- sink->window_handle = NULL;
- sink->is_new_window = FALSE;
- }
+gst_video_format_get_rgb_masks (GstD3DVideoSink * sink, GstVideoFormat fmt,
+ GstVideoFormatDetails * details)
+{
+ gboolean ret = FALSE;
+
+ g_return_val_if_fail (details != NULL, FALSE);
+
+ switch (fmt) {
+ case GST_VIDEO_FORMAT_RGBx:
+ memcpy (details, &vfmt_details[VFMT_RGBx],
+ sizeof (GstVideoFormatDetails));
+ ret = TRUE;
+ break;
+ case GST_VIDEO_FORMAT_BGRx:
+ memcpy (details, &vfmt_details[VFMT_BGRx],
+ sizeof (GstVideoFormatDetails));
+ ret = TRUE;
+ break;
+ case GST_VIDEO_FORMAT_xRGB:
+ memcpy (details, &vfmt_details[VFMT_xRGB],
+ sizeof (GstVideoFormatDetails));
+ ret = TRUE;
+ break;
+ case GST_VIDEO_FORMAT_xBGR:
+ memcpy (details, &vfmt_details[VFMT_xBGR],
+ sizeof (GstVideoFormatDetails));
+ ret = TRUE;
+ break;
+ case GST_VIDEO_FORMAT_RGBA:
+ memcpy (details, &vfmt_details[VFMT_RGBA],
+ sizeof (GstVideoFormatDetails));
+ ret = TRUE;
+ break;
+ case GST_VIDEO_FORMAT_BGRA:
+ memcpy (details, &vfmt_details[VFMT_BGRA],
+ sizeof (GstVideoFormatDetails));
+ ret = TRUE;
+ break;
+ case GST_VIDEO_FORMAT_ARGB:
+ memcpy (details, &vfmt_details[VFMT_ARGB],
+ sizeof (GstVideoFormatDetails));
+ ret = TRUE;
+ break;
+ case GST_VIDEO_FORMAT_ABGR:
+ memcpy (details, &vfmt_details[VFMT_ABGR],
+ sizeof (GstVideoFormatDetails));
+ ret = TRUE;
+ break;
+ case GST_VIDEO_FORMAT_RGB:
+ memcpy (details, &vfmt_details[VFMT_RGB], sizeof (GstVideoFormatDetails));
+ ret = TRUE;
+ break;
+ case GST_VIDEO_FORMAT_BGR:
+ memcpy (details, &vfmt_details[VFMT_BGR], sizeof (GstVideoFormatDetails));
+ ret = TRUE;
+ break;
+ case GST_VIDEO_FORMAT_RGB16:
+ memcpy (details, &vfmt_details[VFMT_RGB16],
+ sizeof (GstVideoFormatDetails));
+ ret = TRUE;
+ break;
+ case GST_VIDEO_FORMAT_BGR16:
+ memcpy (details, &vfmt_details[VFMT_BGR16],
+ sizeof (GstVideoFormatDetails));
+ ret = TRUE;
+ break;
+ case GST_VIDEO_FORMAT_RGB15:
+ memcpy (details, &vfmt_details[VFMT_RGB15],
+ sizeof (GstVideoFormatDetails));
+ ret = TRUE;
+ break;
+ case GST_VIDEO_FORMAT_BGR15:
+ memcpy (details, &vfmt_details[VFMT_BGR15],
+ sizeof (GstVideoFormatDetails));
+ ret = TRUE;
+ break;
+ default:;
+ }
+
+ if (ret) {
+ if (details->endianness != G_BYTE_ORDER) {
+ gboolean bitshift = (details->bpp == 24 && details->depth == 24);
+ GST_DEBUG_OBJECT (sink, "Flipping masks%s, byte order missmatch",
+ bitshift ? " (w/ bitshift)" : "");
+ details->r_mask = flip_b32 (details->r_mask, bitshift);
+ details->g_mask = flip_b32 (details->g_mask, bitshift);
+ details->b_mask = flip_b32 (details->b_mask, bitshift);
+ details->a_mask = flip_b32 (details->a_mask, bitshift);
+ details->r_mask16 = flip_b16 (details->r_mask16);
+ details->g_mask16 = flip_b16 (details->g_mask16);
+ details->b_mask16 = flip_b16 (details->b_mask16);
+ details->a_mask16 = flip_b16 (details->a_mask16);
+ }
+ if (details->bpp == 16) {
+ GST_DEBUG_OBJECT (sink, "RED MASK: 0x%04x SHIFT: %2u BITS: %u (%u)",
+ details->r_mask16, details->r_shift, details->r_bits,
+ details->r_mask16);
+ GST_DEBUG_OBJECT (sink, "GREEN MASK: 0x%04x SHIFT: %2u BITS: %u (%u)",
+ details->g_mask16, details->g_shift, details->g_bits,
+ details->g_mask16);
+ GST_DEBUG_OBJECT (sink, "BLUE MASK: 0x%04x SHIFT: %2u BITS: %u (%u)",
+ details->b_mask16, details->b_shift, details->b_bits,
+ details->b_mask16);
+ GST_DEBUG_OBJECT (sink, "ALPHA MASK: 0x%04x SHIFT: %2u BITS: %u (%u)",
+ details->a_mask16, details->a_shift, details->a_bits,
+ details->a_mask16);
+ } else {
+ GST_DEBUG_OBJECT (sink, "RED MASK: 0x%08x SHIFT: %2u BITS: %u (%u)",
+ details->r_mask, details->r_shift, details->r_bits, details->r_mask);
+ GST_DEBUG_OBJECT (sink, "GREEN MASK: 0x%08x SHIFT: %2u BITS: %u (%u)",
+ details->g_mask, details->g_shift, details->g_bits, details->g_mask);
+ GST_DEBUG_OBJECT (sink, "BLUE MASK: 0x%08x SHIFT: %2u BITS: %u (%u)",
+ details->b_mask, details->b_shift, details->b_bits, details->b_mask);
+ GST_DEBUG_OBJECT (sink, "ALPHA MASK: 0x%08x SHIFT: %2u BITS: %u (%u)",
+ details->a_mask, details->a_shift, details->a_bits, details->a_mask);
}
-
- GST_D3DVIDEOSINK_SHARED_D3D_HOOK_LOCK;
- gst_d3dvideosink_unhook_window_for_renderer (sink);
- GST_D3DVIDEOSINK_SHARED_D3D_HOOK_UNLOCK;
- /* Remove the property associating our sink with the window */
- RemoveProp (sink->window_handle, TEXT ("GstD3DVideoSink"));
- }
-}
-
-static void
-gst_d3dvideosink_prepare_window (GstD3DVideoSink * sink)
-{
- /* Give the app a last chance to supply a window id */
- if (!sink->window_handle) {
- gst_video_overlay_prepare_window_handle (GST_VIDEO_OVERLAY (sink));
- }
-
- /* If the app supplied one, use it. Otherwise, go ahead
- * and create (and use) our own window, if we didn't create
- * one before */
- if (sink->window_handle && sink->is_new_window) {
- GST_D3DVIDEOSINK_D3D_DEVICE_LOCK (sink);
- gst_d3dvideosink_release_d3d_device (sink);
- GST_D3DVIDEOSINK_D3D_DEVICE_UNLOCK (sink);
- } else if (sink->window_handle) {
- gst_d3dvideosink_set_window_for_renderer (sink);
- } else {
- gst_d3dvideosink_create_default_window (sink);
- }
- GST_D3DVIDEOSINK_D3D_DEVICE_LOCK (sink);
- gst_d3dvideosink_notify_device_init (sink);
- GST_D3DVIDEOSINK_D3D_DEVICE_UNLOCK (sink);
-}
-
-static GstStateChangeReturn
-gst_d3dvideosink_change_state (GstElement * element, GstStateChange transition)
-{
- GstD3DVideoSink *sink = GST_D3DVIDEOSINK (element);
- GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
-
- switch (transition) {
- case GST_STATE_CHANGE_NULL_TO_READY:
- if (!gst_d3dvideosink_initialize_direct3d (sink))
- return GST_STATE_CHANGE_FAILURE;
- break;
- case GST_STATE_CHANGE_READY_TO_PAUSED:
- break;
- case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
- break;
- case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
- break;
- case GST_STATE_CHANGE_PAUSED_TO_READY:
- break;
- case GST_STATE_CHANGE_READY_TO_NULL:
- break;
- }
-
- ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
- if (ret == GST_STATE_CHANGE_FAILURE)
- return ret;
-
- switch (transition) {
- case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
- break;
- case GST_STATE_CHANGE_PAUSED_TO_READY:
- if (!sink->is_new_window) {
- gst_d3dvideosink_remove_window_for_renderer (sink);
- }
- break;
- case GST_STATE_CHANGE_READY_TO_NULL:
- gst_d3dvideosink_release_direct3d (sink);
- gst_d3dvideosink_clear (sink);
- break;
- case GST_STATE_CHANGE_NULL_TO_READY:
- break;
- case GST_STATE_CHANGE_READY_TO_PAUSED:
- break;
- case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
- break;
+ GST_DEBUG_OBJECT (sink, "ENDIANESS: %s",
+ (details->endianness ==
+ G_BIG_ENDIAN) ? "G_BIG_ENDIAN" : "G_LITTLE_ENDIAN");
+ GST_DEBUG_OBJECT (sink, "PIXEL WIDTH: %d", details->pixel_width);
}
return ret;
}
static gboolean
-gst_d3dvideosink_start (GstBaseSink * bsink)
-{
- GstD3DVideoSink *sink = GST_D3DVIDEOSINK (bsink);
-
- /* Determine if Direct 3D is supported */
- return gst_d3dvideosink_direct3d_supported (sink);
-}
-
-static gboolean
gst_d3dvideosink_set_caps (GstBaseSink * bsink, GstCaps * caps)
{
GstD3DVideoSink *sink;
- /*GstStructure *structure; */
GstCaps *sink_caps;
- GstVideoInfo info;
gint video_width, video_height;
gint video_par_n, video_par_d; /* video's PAR */
gint display_par_n, display_par_d; /* display's PAR */
+ gint fps_n, fps_d;
guint num, den;
+ gchar *tmp = NULL;
+ GST_DEBUG_OBJECT (bsink, " ");
+
+ GST_DEBUG_OBJECT (bsink, "Caps: %s", (tmp = gst_caps_to_string (caps)));
sink = GST_D3DVIDEOSINK (bsink);
- sink_caps = gst_static_pad_template_get_caps (&sink_template);
- GST_DEBUG_OBJECT (sink,
- "In setcaps. Possible caps %" GST_PTR_FORMAT ", setting caps %"
- GST_PTR_FORMAT, sink_caps, caps);
+ sink_caps = d3d_supported_caps (sink);
if (!gst_caps_can_intersect (sink_caps, caps))
goto incompatible_caps;
- if (!gst_video_info_from_caps (&info, caps))
+ memset (&sink->info, 0, sizeof (GstVideoInfo));
+ if (!gst_video_info_from_caps (&sink->info, caps))
goto invalid_format;
- /*structure = gst_caps_get_structure (caps, 0); */
+ sink->format = sink->info.finfo->format;
+ video_width = sink->info.width;
+ video_height = sink->info.height;
+ fps_n = sink->info.fps_n;
+ fps_d = sink->info.fps_d;
+ video_par_n = sink->info.par_n;
+ video_par_d = sink->info.par_d;
- video_width = info.width;
- video_height = info.height;
+ GST_DEBUG_OBJECT (bsink, "Set Caps Format: %s",
+ gst_video_format_to_string (sink->format));
+
+ if (GST_VIDEO_INFO_IS_RGB (&sink->info)) {
+ if (!gst_video_format_get_rgb_masks (sink, sink->format,
+ &sink->fmt_details)) {
+ GST_ERROR_OBJECT (sink, "No RGB mapping found for format: %s",
+ gst_video_format_to_string (sink->format));
+ goto incompatible_caps;
+ }
+ }
/* get aspect ratio from caps if it's present, and
* convert video width and height to a display width and height
* using wd / hd = wv / hv * PARv / PARd */
/* get video's PAR */
- video_par_n = info.par_n;
- video_par_d = info.par_d;
-
- /* get display's PAR */
- if (sink->par) {
- display_par_n = gst_value_get_fraction_numerator (sink->par);
- display_par_d = gst_value_get_fraction_denominator (sink->par);
- } else {
- display_par_n = 1;
- display_par_d = 1;
- }
+ display_par_n = gst_value_get_fraction_numerator (&sink->par);
+ display_par_d = gst_value_get_fraction_denominator (&sink->par);
- if (!gst_video_calculate_display_ratio (&num, &den, info.width,
- info.height, video_par_n, video_par_d, display_par_n, display_par_d))
+ if (!gst_video_calculate_display_ratio (&num, &den, video_width,
+ video_height, video_par_n, video_par_d, display_par_n, display_par_d))
goto no_disp_ratio;
GST_DEBUG_OBJECT (sink,
- "video width/height: %dx%d, calculated display ratio: %d/%d",
- video_width, video_height, num, den);
+ "video width/height: %dx%d, calculated display ratio: %d/%d format: %u",
+ video_width, video_height, num, den, sink->format);
/* now find a width x height that respects this display ratio.
* prefer those that have one of w/h the same as the incoming video
- * using wd / hd = num / den */
+ * using wd / hd = num / den
+ */
- /* start with same height, because of interlaced video */
- /* check hd / den is an integer scale factor, and scale wd with the PAR */
- if (info.height % den == 0) {
+ /* start with same height, because of interlaced video
+ * check hd / den is an integer scale factor, and scale wd with the PAR
+ */
+ if (video_height % den == 0) {
GST_DEBUG_OBJECT (sink, "keeping video height");
GST_VIDEO_SINK_WIDTH (sink) = (guint)
- gst_util_uint64_scale_int (info.height, num, den);
- GST_VIDEO_SINK_HEIGHT (sink) = info.height;
- } else if (info.width % num == 0) {
+ gst_util_uint64_scale_int (video_height, num, den);
+ GST_VIDEO_SINK_HEIGHT (sink) = video_height;
+ } else if (video_width % num == 0) {
GST_DEBUG_OBJECT (sink, "keeping video width");
- GST_VIDEO_SINK_WIDTH (sink) = info.width;
+ GST_VIDEO_SINK_WIDTH (sink) = video_width;
GST_VIDEO_SINK_HEIGHT (sink) = (guint)
- gst_util_uint64_scale_int (info.width, den, num);
+ gst_util_uint64_scale_int (video_width, den, num);
} else {
GST_DEBUG_OBJECT (sink, "approximating while keeping video height");
GST_VIDEO_SINK_WIDTH (sink) = (guint)
- gst_util_uint64_scale_int (info.height, num, den);
- GST_VIDEO_SINK_HEIGHT (sink) = info.height;
+ gst_util_uint64_scale_int (video_height, num, den);
+ GST_VIDEO_SINK_HEIGHT (sink) = video_height;
}
GST_DEBUG_OBJECT (sink, "scaling to %dx%d",
GST_VIDEO_SINK_WIDTH (sink), GST_VIDEO_SINK_HEIGHT (sink));
@@ -1508,11 +627,18 @@ gst_d3dvideosink_set_caps (GstBaseSink * bsink, GstCaps * caps)
if (GST_VIDEO_SINK_WIDTH (sink) <= 0 || GST_VIDEO_SINK_HEIGHT (sink) <= 0)
goto no_display_size;
- sink->info = info;
- sink->format = GST_VIDEO_INFO_FORMAT (&info);
+ sink->width = video_width;
+ sink->height = video_height;
+
+ GST_DEBUG_OBJECT (bsink, "Selected caps: %s", (tmp =
+ gst_caps_to_string (caps)));
+ g_free (tmp);
+
+ if (!d3d_set_render_format (sink))
+ goto incompatible_caps;
/* Create a window (or start using an application-supplied one, then connect the graph */
- gst_d3dvideosink_prepare_window (sink);
+ d3d_prepare_window (sink);
return TRUE;
/* ERRORS */
@@ -1547,893 +673,94 @@ static gboolean
gst_d3dvideosink_stop (GstBaseSink * bsink)
{
GstD3DVideoSink *sink = GST_D3DVIDEOSINK (bsink);
- gst_d3dvideosink_close_window (sink);
+ GST_DEBUG_OBJECT (bsink, "Stop() called");
+ d3d_stop (sink);
return TRUE;
}
-static void
-gst_d3dvideosink_flush_gpu (GstD3DVideoSink * sink)
-{
- LPDIRECT3DQUERY9 pEventQuery = NULL;
-
- IDirect3DDevice9_CreateQuery (sink->d3ddev, D3DQUERYTYPE_EVENT, &pEventQuery);
- if (pEventQuery) {
- IDirect3DQuery9_Issue (pEventQuery, D3DISSUE_END);
- /* Empty the command buffer and wait until the GPU is idle. */
- while (S_FALSE == IDirect3DQuery9_GetData (pEventQuery, NULL, 0,
- D3DGETDATA_FLUSH));
- IDirect3DQuery9_Release (pEventQuery);
- }
-}
-
-static G_GNUC_UNUSED void
-gst_d3dvideosink_wait_for_vsync (GstD3DVideoSink * sink)
-{
- if (sink->d3dpp.PresentationInterval == D3DPRESENT_INTERVAL_IMMEDIATE) {
- D3DRASTER_STATUS raster_stat;
- D3DDISPLAYMODE d3ddm;
- UINT lastScanline = 0;
- UINT vblankStart = 0;
- HANDLE thdl = GetCurrentThread ();
- int prio = GetThreadPriority (thdl);
- ZeroMemory (&d3ddm, sizeof (d3ddm));
-
- IDirect3DDevice9_GetDisplayMode (sink->d3ddev, 0, &d3ddm);
- vblankStart = d3ddm.Height - 10;
- SetThreadPriority (thdl, THREAD_PRIORITY_TIME_CRITICAL);
- do {
- if (FAILED (IDirect3DDevice9_GetRasterStatus (sink->d3ddev, 0,
- &raster_stat))) {
- GST_ERROR_OBJECT (sink, "GetRasterStatus failed");
- }
- break;
- if (!raster_stat.InVBlank) {
- if (raster_stat.ScanLine < lastScanline) {
- GST_INFO_OBJECT (sink, "missed last vsync curr : %d",
- raster_stat.ScanLine);
- break;
- }
- lastScanline = raster_stat.ScanLine;
- SwitchToThread ();
- }
- } while (raster_stat.ScanLine < vblankStart);
- SetThreadPriority (thdl, prio);
- }
-}
-
-static GstFlowReturn
-gst_d3dvideosink_show_frame (GstVideoSink * vsink, GstBuffer * buffer)
-{
- GstD3DVideoSink *sink = GST_D3DVIDEOSINK (vsink);
- LPDIRECT3DSURFACE9 drawSurface = NULL;
-
- if (!GST_D3DVIDEOSINK_D3D_DEVICE_TRYLOCK (sink))
- return GST_FLOW_OK;
- if (!sink->d3ddev) {
- if (!shared.device_lost) {
- GST_ERROR_OBJECT (sink, "No Direct3D device has been created, stopping");
- goto error;
- } else {
- GST_WARNING_OBJECT (sink,
- "Direct3D device is lost. Maintaining flow until it has been reset.");
- goto success;
- }
- }
-
- if (sink->window_closed) {
- GST_ERROR_OBJECT (sink, "Window has been closed, stopping");
- goto error;
- }
-
+/** PUBLIC FUNCTIONS **/
- drawSurface = sink->d3d_offscreen_surface;
-
- if (SUCCEEDED (IDirect3DDevice9_BeginScene (sink->d3ddev))) {
- GstMapInfo map;
- if (gst_buffer_map (buffer, &map, GST_MAP_READ)) {
- D3DLOCKED_RECT lr;
- guint8 *dest, *source;
- int srcstride, dststride, i;
-
- IDirect3DSurface9_LockRect (drawSurface, &lr, NULL, 0);
- dest = (guint8 *) lr.pBits;
- source = map.data;
-
- if (dest) {
- if (GST_VIDEO_INFO_IS_YUV (&sink->info)) {
- switch (sink->format) {
- case GST_VIDEO_FORMAT_YUY2:
- case GST_VIDEO_FORMAT_UYVY:
- dststride = lr.Pitch;
- srcstride =
- gst_buffer_get_size (buffer) / GST_VIDEO_SINK_HEIGHT (sink);
- for (i = 0; i < GST_VIDEO_SINK_HEIGHT (sink); ++i)
- memcpy (dest + dststride * i, source + srcstride * i,
- srcstride);
- break;
- case GST_VIDEO_FORMAT_I420:
- case GST_VIDEO_FORMAT_YV12:
- {
- int srcystride, srcvstride, srcustride;
- int dstystride, dstvstride, dstustride;
- int rows;
- guint8 *srcv, *srcu, *dstv, *dstu;
-
- rows = GST_VIDEO_SINK_HEIGHT (sink);
-
- /* Source y, u and v strides */
- srcystride = GST_ROUND_UP_4 (GST_VIDEO_SINK_WIDTH (sink));
- srcustride = GST_ROUND_UP_8 (GST_VIDEO_SINK_WIDTH (sink)) / 2;
- srcvstride = GST_ROUND_UP_8 (srcystride) / 2;
-
- /* Destination y, u and v strides */
- dstystride = lr.Pitch;
- dstustride = dstystride / 2;
- dstvstride = dstustride;
-
- srcu = source + srcystride * GST_ROUND_UP_2 (rows);
- srcv = srcu + srcustride * GST_ROUND_UP_2 (rows) / 2;
-
- if (sink->format == GST_VIDEO_FORMAT_I420) {
- /* swap u and v planes */
- dstv = dest + dstystride * rows;
- dstu = dstv + dstustride * rows / 2;
- } else {
- dstu = dest + dstystride * rows;
- dstv = dstu + dstustride * rows / 2;
- }
-
- for (i = 0; i < rows; ++i) {
- /* Copy the y plane */
- memcpy (dest + dstystride * i, source + srcystride * i,
- srcystride);
- }
-
- for (i = 0; i < rows / 2; ++i) {
- /* Copy the u plane */
- memcpy (dstu + dstustride * i, srcu + srcustride * i,
- srcustride);
- /* Copy the v plane */
- memcpy (dstv + dstvstride * i, srcv + srcvstride * i,
- srcvstride);
- }
- break;
- }
- case GST_VIDEO_FORMAT_NV12:
- {
- guint8 *dst = dest;
- int component;
- dststride = lr.Pitch;
- for (component = 0; component < 2; component++) {
- const int compHeight =
- GST_VIDEO_INFO_COMP_HEIGHT (&sink->info, component);
- guint8 *src = source + GST_VIDEO_INFO_COMP_OFFSET (&sink->info,
- component);
- srcstride = GST_VIDEO_INFO_COMP_STRIDE (&sink->info, component);
- for (i = 0; i < compHeight; i++) {
- memcpy (dst + dststride * i, src + srcstride * i, srcstride);
- }
- dst += dststride * compHeight;
- }
- break;
- }
- default:
- g_assert_not_reached ();
- }
- } else if (GST_VIDEO_INFO_IS_RGB (&sink->info)) {
- dststride = lr.Pitch;
- srcstride =
- gst_buffer_get_size (buffer) / GST_VIDEO_SINK_HEIGHT (sink);
- for (i = 0; i < GST_VIDEO_SINK_HEIGHT (sink); ++i)
- memcpy (dest + dststride * i, source + srcstride * i, srcstride);
- }
- }
- IDirect3DSurface9_UnlockRect (drawSurface);
- gst_buffer_unmap (buffer, &map);
- }
- IDirect3DDevice9_EndScene (sink->d3ddev);
- }
-success:
- GST_D3DVIDEOSINK_D3D_DEVICE_UNLOCK (sink);
- gst_d3dvideosink_refresh (sink);
- return GST_FLOW_OK;
-error:
- GST_D3DVIDEOSINK_D3D_DEVICE_UNLOCK (sink);
- return GST_FLOW_ERROR;
-}
+/* Iterface Registrations */
-/* Simply redraws the last item on our offscreen surface to the window */
-static gboolean
-gst_d3dvideosink_refresh (GstD3DVideoSink * sink)
+static void
+gst_d3dvideosink_video_overlay_interface_init (GstVideoOverlayInterface * iface)
{
- HRESULT hr;
- LPDIRECT3DSURFACE9 backBuffer;
-
- if (!GST_D3DVIDEOSINK_D3D_DEVICE_TRYLOCK (sink))
- return TRUE;
-
- if (!sink->d3ddev) {
- if (!shared.device_lost)
- GST_DEBUG ("No Direct3D device has been created");
- goto error;
- }
-
- if (!sink->d3d_offscreen_surface) {
- GST_DEBUG ("No Direct3D offscreen surface has been created");
- goto error;
- }
-
- if (sink->window_closed) {
- GST_DEBUG ("Window has been closed");
- goto error;
- }
-
- /* Set the render target to our swap chain */
- if (FAILED (IDirect3DDevice9_GetBackBuffer (sink->d3ddev, 0, 0,
- D3DBACKBUFFER_TYPE_MONO, &backBuffer))) {
- GST_ERROR_OBJECT (sink, "failed to get back buffer");
- goto error;
- }
- IDirect3DDevice9_SetRenderTarget (sink->d3ddev, 0, backBuffer);
- IDirect3DSurface9_Release (backBuffer);
-
- /* Clear the target */
- IDirect3DDevice9_Clear (sink->d3ddev, 0, NULL, D3DCLEAR_TARGET,
- D3DCOLOR_XRGB (0, 0, 0), 1.0f, 0);
-
- if (SUCCEEDED (IDirect3DDevice9_BeginScene (sink->d3ddev))) {
- gst_d3dvideosink_stretch (sink, backBuffer);
- IDirect3DDevice9_EndScene (sink->d3ddev);
- }
- IDirect3DSurface9_Release (backBuffer);
- gst_d3dvideosink_flush_gpu (sink);
- /* Swap back and front buffers on video card and present to the user */
- if (FAILED (hr =
- IDirect3DDevice9_Present (sink->d3ddev, NULL, NULL, NULL, NULL))) {
- switch (hr) {
- case D3DERR_DEVICELOST:
- case D3DERR_DEVICENOTRESET:
- gst_d3dvideosink_notify_device_lost (sink);
- break;
- default:
- goto error;
- }
- }
-
- GST_D3DVIDEOSINK_D3D_DEVICE_UNLOCK (sink);
- return TRUE;
-
-error:
- GST_D3DVIDEOSINK_D3D_DEVICE_UNLOCK (sink);
- return FALSE;
+ iface->set_window_handle = gst_d3dvideosink_set_window_handle;
+ iface->set_render_rectangle = gst_d3dvideosink_set_render_rectangle;
+ iface->expose = gst_d3dvideosink_expose;
}
-static gboolean
-gst_d3dvideosink_update_all (GstD3DVideoSink * sink)
+static void
+gst_d3dvideosink_navigation_interface_init (GstNavigationInterface * iface)
{
- GList *item;
- GstD3DVideoSink *s;
-
- GST_D3DVIDEOSINK_SHARED_D3D_LOCK;
- for (item = g_list_first (shared.element_list); item; item = item->next) {
- s = (GstD3DVideoSink *) item->data;
- gst_d3dvideosink_update (GST_BASE_SINK (s));
- }
- GST_D3DVIDEOSINK_SHARED_D3D_UNLOCK;
- return TRUE;
+ iface->send_event = gst_d3dvideosink_navigation_send_event;
}
-static gboolean
-gst_d3dvideosink_refresh_all (GstD3DVideoSink * sink)
-{
- GList *item;
- GstD3DVideoSink *s;
-
- GST_D3DVIDEOSINK_SHARED_D3D_LOCK;
- for (item = g_list_first (shared.element_list); item; item = item->next) {
- s = (GstD3DVideoSink *) item->data;
- gst_d3dvideosink_refresh (s);
- }
- GST_D3DVIDEOSINK_SHARED_D3D_UNLOCK;
- return TRUE;
-}
+/* Video Render Code */
static void
-gst_d3dvideosink_stretch (GstD3DVideoSink * sink, LPDIRECT3DSURFACE9 backBuffer)
+gst_d3dvideosink_set_window_handle (GstVideoOverlay * overlay,
+ guintptr window_id)
{
- if (sink->keep_aspect_ratio) {
- gint window_width;
- gint window_height;
- RECT r;
- GstVideoRectangle src;
- GstVideoRectangle dst;
- GstVideoRectangle result;
- gdouble x_scale, y_scale;
-
- gst_d3dvideosink_window_size (sink, &window_width, &window_height);
-
- src.x = 0;
- src.y = 0;
- src.w = GST_VIDEO_SINK_WIDTH (sink);
- src.h = GST_VIDEO_SINK_HEIGHT (sink);
-
- dst.x = 0;
- dst.y = 0;
- dst.w = window_width;
- dst.h = window_height;
-
- x_scale = (gdouble) src.w / (gdouble) dst.w;
- y_scale = (gdouble) src.h / (gdouble) dst.h;
- gst_video_sink_center_rect (src, dst, &result, TRUE);
-
- result.x = result.x * x_scale;
- result.y = result.y * y_scale;
- result.w = result.w * x_scale;
- result.h = result.h * y_scale;
-
- //clip to src
- gst_video_sink_center_rect (result, src, &result, FALSE);
-
- r.left = result.x;
- r.top = result.y;
- r.right = result.x + result.w;
- r.bottom = result.y + result.h;
-
- if (FAILED (IDirect3DDevice9_StretchRect (sink->d3ddev,
- sink->d3d_offscreen_surface, NULL, backBuffer, &r,
- sink->d3dfiltertype))) {
- GST_ERROR_OBJECT (sink, "StretchRect failed");
- }
- } else {
- IDirect3DDevice9_StretchRect (sink->d3ddev, sink->d3d_offscreen_surface,
- NULL, backBuffer, NULL, sink->d3dfiltertype);
- }
+ d3d_set_window_handle (GST_D3DVIDEOSINK (overlay), window_id, FALSE);
}
static void
-gst_d3dvideosink_expose (GstVideoOverlay * overlay)
+gst_d3dvideosink_set_render_rectangle (GstVideoOverlay * overlay, gint x,
+ gint y, gint width, gint height)
{
- GstBaseSink *sink = GST_BASE_SINK (overlay);
- gst_d3dvideosink_update (sink);
+ GstD3DVideoSink *sink = GST_D3DVIDEOSINK (overlay);
+ sink->render_rect.x = x;
+ sink->render_rect.y = y;
+ sink->render_rect.w = width;
+ sink->render_rect.h = height;
+ d3d_set_render_rectangle (sink);
}
static void
-gst_d3dvideosink_update (GstBaseSink * bsink)
-{
- GstSample *last_sample;
- GstBuffer *last_buffer;
-
- last_sample = gst_base_sink_get_last_sample (bsink);
- if (last_sample) {
- last_buffer = gst_sample_get_buffer (last_sample);
- if (last_buffer)
- gst_d3dvideosink_show_frame (GST_VIDEO_SINK (bsink), last_buffer);
- gst_sample_unref (last_sample);
- }
-}
-
-/* TODO: How can we implement these? Figure that out... */
-/*
-static gboolean
-gst_d3dvideosink_unlock (GstBaseSink * bsink)
-{
- GstD3DVideoSink *sink = GST_D3DVIDEOSINK (bsink);
-
- return TRUE;
-}
-
-static gboolean
-gst_d3dvideosink_unlock_stop (GstBaseSink * bsink)
-{
- GstD3DVideoSink *sink = GST_D3DVIDEOSINK (bsink);
-
- return TRUE;
-}
-*/
-
-static gboolean
-gst_d3dvideosink_initialize_direct3d (GstD3DVideoSink * sink)
-{
- DirectXAPI *api;
- GstD3DVideoSinkClass *klass;
-
- /* Let's hope this is never a problem (they have millions of d3d elements going at the same time) */
- if (shared.element_count >= G_MAXINT32) {
- GST_ERROR
- ("There are too many d3dvideosink elements. Creating more elements would put this element into an unknown state.");
- return FALSE;
- }
-
- GST_D3DVIDEOSINK_SHARED_D3D_LOCK;
- /* Add to our GList containing all of our elements. */
- /* GLists are doubly-linked lists and calling prepend() prevents it from having to traverse the entire list just to add one item. */
- shared.element_list = g_list_prepend (shared.element_list, sink);
-
- /* Increment our count of the number of elements we have */
- shared.element_count++;
- if (shared.element_count > 1)
- goto success;
-
- /* We want to initialize direct3d only for the first element that's using it. */
- /* We'll destroy this once all elements using direct3d have been finalized. */
- /* See gst_d3dvideosink_release_direct3d() for details. */
-
- if (!sink) {
- GST_WARNING ("Missing gobject instance.");
- return FALSE;
- }
-
- klass = GST_D3DVIDEOSINK_GET_CLASS (sink);
- if (!klass) {
- GST_WARNING ("Unable to retrieve gobject class");
- goto error;
- }
-
- api = klass->directx_api;
- if (!api) {
- GST_WARNING ("Missing DirectX api");
- goto error;
- }
-
- shared.d3d =
- (LPDIRECT3D9) DX9_D3D_COMPONENT_CALL_FUNC (DIRECTX_D3D (api),
- Direct3DCreate9, D3D_SDK_VERSION);
- if (!shared.d3d) {
- GST_ERROR ("Unable to create Direct3D interface");
- goto error;
- }
-
- /* We create a window that's hidden, so we can control the
- device's from a single thread */
-
- GST_DEBUG ("Creating hidden window for Direct3D");
- if (!gst_d3dvideosink_create_shared_hidden_window (sink))
- goto error;
-
-success:
- GST_D3DVIDEOSINK_SHARED_D3D_UNLOCK;
- return TRUE;
-error:
- GST_D3DVIDEOSINK_SHARED_D3D_UNLOCK;
- return FALSE;
-}
-
-static gboolean
-gst_d3dvideosink_initialize_d3d_device (GstD3DVideoSink * sink)
-{
- HRESULT hr;
- DWORD d3dcreate;
- D3DCAPS9 d3dcaps;
- HWND hwnd = sink->window_handle;
- D3DFORMAT d3dformat = sink->d3dformat;
- D3DFORMAT d3dfourcc;
- D3DDISPLAYMODE d3ddm;
- D3DTEXTUREFILTERTYPE d3dfiltertype;
- gint width, height;
-
- /* Get the current size of the window */
- gst_d3dvideosink_window_size (sink, &width, &height);
-
- if (!shared.d3d) {
- GST_WARNING ("Direct3D object has not been initialized");
- goto error;
- }
- if (FAILED (IDirect3D9_GetAdapterDisplayMode (shared.d3d, D3DADAPTER_DEFAULT,
- &d3ddm))) {
- GST_WARNING ("Unable to request adapter display mode");
- goto error;
- }
-
- if (FAILED (IDirect3D9_GetDeviceCaps (shared.d3d, D3DADAPTER_DEFAULT,
- D3DDEVTYPE_HAL, &d3dcaps))) {
- GST_WARNING ("Unable to request device caps");
- goto error;
- }
-
- /* Ask DirectX to please not clobber the FPU state when making DirectX API calls. */
- /* This can cause libraries such as cairo to misbehave in certain scenarios. */
- d3dcreate = 0 | D3DCREATE_FPU_PRESERVE | D3DCREATE_MULTITHREADED;
-
- /* Determine vertex processing capabilities. Some cards have issues using software vertex processing. */
- /* Courtesy http://www.chadvernon.com/blog/resources/directx9/improved-direct3d-initialization/ */
- if ((d3dcaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) ==
- D3DDEVCAPS_HWTRANSFORMANDLIGHT) {
- d3dcreate |= D3DCREATE_HARDWARE_VERTEXPROCESSING;
- /* if ((d3dcaps.DevCaps & D3DDEVCAPS_PUREDEVICE) == D3DDEVCAPS_PUREDEVICE) */
- /* d3dcreate |= D3DCREATE_PUREDEVICE; */
- } else {
- d3dcreate |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;
- }
-
- /* Check the filter type. */
- if ((d3dcaps.StretchRectFilterCaps & D3DPTFILTERCAPS_MINFLINEAR) ==
- D3DPTFILTERCAPS_MINFLINEAR
- && (d3dcaps.StretchRectFilterCaps & D3DPTFILTERCAPS_MAGFLINEAR) ==
- D3DPTFILTERCAPS_MAGFLINEAR) {
- d3dfiltertype = D3DTEXF_LINEAR;
- } else {
- d3dfiltertype = D3DTEXF_NONE;
- }
-
- if (GST_VIDEO_INFO_IS_YUV (&sink->info)) {
- switch (sink->format) {
- case GST_VIDEO_FORMAT_YUY2:
- d3dformat = D3DFMT_X8R8G8B8;
- d3dfourcc = (D3DFORMAT) MAKEFOURCC ('Y', 'U', 'Y', '2');
- break;
- //case GST_MAKE_FOURCC ('Y', 'U', 'V', 'Y'):
- // d3dformat = D3DFMT_X8R8G8B8;
- // d3dfourcc = (D3DFORMAT)MAKEFOURCC('Y', 'U', 'V', 'Y');
- // break;
- case GST_VIDEO_FORMAT_UYVY:
- d3dformat = D3DFMT_X8R8G8B8;
- d3dfourcc = (D3DFORMAT) MAKEFOURCC ('U', 'Y', 'V', 'Y');
- break;
- case GST_VIDEO_FORMAT_YV12:
- case GST_VIDEO_FORMAT_I420:
- d3dformat = D3DFMT_X8R8G8B8;
- d3dfourcc = (D3DFORMAT) MAKEFOURCC ('Y', 'V', '1', '2');
- break;
- case GST_VIDEO_FORMAT_NV12:
- d3dformat = D3DFMT_X8R8G8B8;
- d3dfourcc = (D3DFORMAT) MAKEFOURCC ('N', 'V', '1', '2');
- break;
- default:
- g_assert_not_reached ();
- goto error;
- }
- } else if (GST_VIDEO_INFO_IS_RGB (&sink->info)) {
- d3dformat = D3DFMT_X8R8G8B8;
- d3dfourcc = D3DFMT_X8R8G8B8;
- } else {
- g_assert_not_reached ();
- goto error;
- }
-
- GST_DEBUG ("Determined Direct3D format: %" GST_FOURCC_FORMAT,
- GST_FOURCC_ARGS (d3dfourcc));
-
-
- GST_DEBUG ("Direct3D back buffer size: %dx%d", GST_VIDEO_SINK_WIDTH (sink),
- GST_VIDEO_SINK_HEIGHT (sink));
-
- sink->d3dformat = d3dformat;
- sink->d3dfourcc = d3dfourcc;
-
-
- ZeroMemory (&sink->d3dpp, sizeof (sink->d3dpp));
- sink->d3dpp.Flags = D3DPRESENTFLAG_VIDEO | D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
- sink->d3dpp.Windowed = TRUE;
- sink->d3dpp.hDeviceWindow = hwnd;
- sink->d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
- sink->d3dpp.BackBufferCount = 1;
- //sink->d3dpp.BackBufferFormat = d3dformat;
- sink->d3dpp.BackBufferWidth = GST_VIDEO_SINK_WIDTH (sink);
- sink->d3dpp.BackBufferHeight = GST_VIDEO_SINK_HEIGHT (sink);
- sink->d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
- sink->d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
-
- GST_DEBUG ("Creating Direct3D device for window %p", hwnd);
-
- sink->d3ddev = NULL;
-
- hr = IDirect3D9_CreateDevice (shared.d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
- hwnd, d3dcreate, &sink->d3dpp, &sink->d3ddev);
- if (FAILED (hr)) {
- GST_WARNING ("Unable to create Direct3D device. Result: %ld (0x%lx)", hr,
- hr);
- goto error;
- }
-
- hr = IDirect3DDevice9_CreateOffscreenPlainSurface (sink->d3ddev,
- GST_VIDEO_SINK_WIDTH (sink), GST_VIDEO_SINK_HEIGHT (sink), d3dfourcc,
- D3DPOOL_DEFAULT, &sink->d3d_offscreen_surface, NULL);
- if (FAILED (hr)) {
- goto error;
- }
-
- /* Determine texture filtering support. If it's supported for this format, use the filter
- type determined when we created the dev and checked the dev caps.
- */
- if (FAILED (IDirect3D9_CheckDeviceFormat (shared.d3d, D3DADAPTER_DEFAULT,
- D3DDEVTYPE_HAL, d3dformat, D3DUSAGE_QUERY_FILTER,
- D3DRTYPE_TEXTURE, d3dformat))) {
- d3dfiltertype = D3DTEXF_NONE;
- }
-
- GST_DEBUG ("Direct3D stretch rect texture filter: %d", d3dfiltertype);
-
- sink->d3dfiltertype = d3dfiltertype;
-
-/*success:*/
- return TRUE;
-error:
- return FALSE;
-}
-
-static gboolean
-gst_d3dvideosink_notify_device_init (GstD3DVideoSink * sink)
-{
- if (sink->window_handle) {
- SendMessage (shared.hidden_window_handle, WM_DIRECTX_D3D_INIT_DEVICE, 0,
- (LPARAM) sink);
- }
- return TRUE;
-}
-
-static gboolean
-gst_d3dvideosink_notify_device_reinit (GstD3DVideoSink * sink)
-{
- if (sink->window_handle) {
- SendMessage (shared.hidden_window_handle, WM_DIRECTX_D3D_DEVICELOST, 0,
- (LPARAM) sink);
- }
- return TRUE;
-}
-
-static gboolean
-gst_d3dvideosink_notify_device_lost (GstD3DVideoSink * sink)
-{
- /* Send notification asynchronously */
- PostMessage (shared.hidden_window_handle, WM_DIRECTX_D3D_INIT_DEVICELOST, 0,
- (LPARAM) sink);
-
- GST_DEBUG ("Successfully sent notification of device lost event for sink %p",
- sink);
- return TRUE;
-}
-
-static gboolean
-gst_d3dvideosink_notify_device_reset (GstD3DVideoSink * sink)
-{
- {
- /* Send notification synchronously -- let's ensure the timer's been killed before returning */
- SendMessage (shared.hidden_window_handle, WM_DIRECTX_D3D_END_DEVICELOST, 0,
- (LPARAM) sink);
- }
- GST_DEBUG ("Successfully sent notification of device reset event for sink %p",
- sink);
- return TRUE;
-}
-
-static gboolean
-gst_d3dvideosink_device_lost (GstD3DVideoSink * sink)
-{
- /* Must be called from hidden window's message loop! */
-
- if (shared.device_lost)
- GST_DEBUG ("Direct3D device lost");
-
- GST_DEBUG_OBJECT (sink, ". Resetting the device.");
-
- if (g_thread_self () != shared.hidden_window_thread) {
- GST_ERROR
- ("Direct3D device can only be reset by the thread that created it.");
- goto error;
- }
-
- if (!shared.d3d) {
- GST_ERROR ("Direct3D device has not been initialized");
- goto error;
- }
-
- /* This is technically a bit different from the normal. We don't call reset(), instead */
- /* we recreate everything from scratch. */
-
- /* Release the device */
- if (!gst_d3dvideosink_release_d3d_device (sink))
- goto error;
-
- /* Recreate device */
- if (!gst_d3dvideosink_initialize_d3d_device (sink))
- goto error;
-
- /* Let the hidden window know that it's okay to kill the timer */
- gst_d3dvideosink_notify_device_reset (sink);
-
- GST_DEBUG ("Direct3D device has successfully been reset.");
- return TRUE;
-error:
- GST_DEBUG ("Unable to successfully reset the Direct3D device.");
- return FALSE;
-}
-
-static gboolean
-gst_d3dvideosink_release_d3d_device (GstD3DVideoSink * sink)
+gst_d3dvideosink_expose (GstVideoOverlay * overlay)
{
- if (sink->d3d_offscreen_surface) {
- int ref_count;
- ref_count = IDirect3DSurface9_Release (sink->d3d_offscreen_surface);
- sink->d3d_offscreen_surface = NULL;
- GST_DEBUG_OBJECT (sink,
- "Direct3D offscreen surface released. Reference count: %d", ref_count);
- }
- if (sink->d3ddev) {
- int ref_count;
- ref_count = IDirect3DDevice9_Release (sink->d3ddev);
- sink->d3ddev = NULL;
- GST_DEBUG_OBJECT (sink, "Direct3D device released. Reference count: %d",
- ref_count);
- }
- return TRUE;
+ GstD3DVideoSink *sink = GST_D3DVIDEOSINK (overlay);
+ d3d_expose_window (sink);
}
-static gboolean
-gst_d3dvideosink_release_direct3d (GstD3DVideoSink * sink)
+static GstFlowReturn
+gst_d3dvideosink_show_frame (GstVideoSink * vsink, GstBuffer * buffer)
{
- GST_DEBUG ("Cleaning all Direct3D objects");
- GST_D3DVIDEOSINK_SHARED_D3D_LOCK;
- /* Be absolutely sure that we've released this sink's hook (if any). */
- gst_d3dvideosink_unhook_window_for_renderer (sink);
-
- /* Remove item from the list */
- shared.element_list = g_list_remove (shared.element_list, sink);
-
- /* Decrement our count of the number of elements we have */
- shared.element_count--;
- if (shared.element_count < 0)
- shared.element_count = 0;
- if (shared.element_count > 0)
- goto success;
-
- GST_D3DVIDEOSINK_D3D_DEVICE_LOCK (sink);
- gst_d3dvideosink_release_d3d_device (sink);
- GST_D3DVIDEOSINK_D3D_DEVICE_UNLOCK (sink);
-
- if (shared.d3d) {
- int ref_count;
- ref_count = IDirect3D9_Release (shared.d3d);
- shared.d3d = NULL;
- GST_DEBUG ("Direct3D object released. Reference count: %d", ref_count);
- }
-
- GST_DEBUG ("Closing hidden Direct3D window");
- gst_d3dvideosink_close_shared_hidden_window (sink);
-
-success:
- GST_D3DVIDEOSINK_SHARED_D3D_UNLOCK;
- return TRUE;
+ GstD3DVideoSink *sink = GST_D3DVIDEOSINK (vsink);
+ return d3d_render_buffer (sink, buffer);
}
-static gboolean
-gst_d3dvideosink_window_size (GstD3DVideoSink * sink, gint * width,
- gint * height)
-{
- if (!sink || !sink->window_handle) {
- if (width && height) {
- *width = 0;
- *height = 0;
- }
- return FALSE;
- }
-
- {
- RECT sz;
- GetClientRect (sink->window_handle, &sz);
-
- *width = MAX (1, ABS (sz.right - sz.left));
- *height = MAX (1, ABS (sz.bottom - sz.top));
- }
- return TRUE;
-}
+/* Video Navigation Events */
static void
gst_d3dvideosink_navigation_send_event (GstNavigation * navigation,
GstStructure * structure)
{
GstD3DVideoSink *sink = GST_D3DVIDEOSINK (navigation);
- gint window_width;
- gint window_height;
GstEvent *e;
- GstVideoRectangle src, dst, result;
- double x, y, old_x, old_y;
- GstPad *pad = NULL;
-
- gst_d3dvideosink_window_size (sink, &window_width, &window_height);
-
- src.w = GST_VIDEO_SINK_WIDTH (sink);
- src.h = GST_VIDEO_SINK_HEIGHT (sink);
- dst.w = window_width;
- dst.h = window_height;
-
- e = gst_event_new_navigation (structure);
-
- if (sink->keep_aspect_ratio) {
- gst_video_sink_center_rect (src, dst, &result, TRUE);
- } else {
- result.x = 0;
- result.y = 0;
- result.w = dst.w;
- result.h = dst.h;
- }
- /* Our coordinates can be wrong here if we centered the video */
-
- /* Converting pointer coordinates to the non scaled geometry */
- if (gst_structure_get_double (structure, "pointer_x", &old_x)) {
- x = old_x;
-
- if (x <= result.x) {
- x = 0;
- } else if (x >= result.x + result.w) {
- x = src.w;
- } else {
- x = MAX (0, MIN (src.w, MAX (0, x - result.x) / result.w * src.w));
+ if ((e = gst_event_new_navigation (structure))) {
+ GstPad *pad;
+ if ((pad = gst_pad_get_peer (GST_VIDEO_SINK_PAD (sink)))) {
+ gst_pad_send_event (pad, e);
+ gst_object_unref (pad);
}
- GST_DEBUG_OBJECT (sink,
- "translated navigation event x coordinate from %f to %f", old_x, x);
- gst_structure_set (structure, "pointer_x", G_TYPE_DOUBLE, x, NULL);
- }
- if (gst_structure_get_double (structure, "pointer_y", &old_y)) {
- y = old_y;
-
- if (y <= result.y) {
- y = 0;
- } else if (y >= result.y + result.h) {
- y = src.h;
- } else {
- y = MAX (0, MIN (src.h, MAX (0, y - result.y) / result.h * src.h));
- }
- GST_DEBUG_OBJECT (sink,
- "translated navigation event y coordinate from %f to %f", old_y, y);
- gst_structure_set (structure, "pointer_y", G_TYPE_DOUBLE, y, NULL);
- }
-
- pad = gst_pad_get_peer (GST_VIDEO_SINK_PAD (sink));
-
- if (GST_IS_PAD (pad) && GST_IS_EVENT (e)) {
- gst_pad_send_event (pad, e);
- gst_object_unref (pad);
}
}
-static gboolean
-gst_d3dvideosink_direct3d_supported (GstD3DVideoSink * sink)
-{
- GstD3DVideoSinkClass *klass = GST_D3DVIDEOSINK_GET_CLASS (sink);
-
- return (klass != NULL && klass->is_directx_supported);
-}
+/** PRIVATE FUNCTIONS **/
-static void
-gst_d3dvideosink_log_debug (const gchar * file, const gchar * function,
- gint line, const gchar * format, va_list args)
-{
- if (G_UNLIKELY (GST_LEVEL_DEBUG <= _gst_debug_min))
- gst_debug_log_valist (GST_CAT_DEFAULT, GST_LEVEL_DEBUG, file, function,
- line, NULL, format, args);
-}
-
-static void
-gst_d3dvideosink_log_warning (const gchar * file, const gchar * function,
- gint line, const gchar * format, va_list args)
-{
- if (G_UNLIKELY (GST_LEVEL_WARNING <= _gst_debug_min))
- gst_debug_log_valist (GST_CAT_DEFAULT, GST_LEVEL_WARNING, file, function,
- line, NULL, format, args);
-}
-
-static void
-gst_d3dvideosink_log_error (const gchar * file, const gchar * function,
- gint line, const gchar * format, va_list args)
-{
- if (G_UNLIKELY (GST_LEVEL_ERROR <= _gst_debug_min))
- gst_debug_log_valist (GST_CAT_DEFAULT, GST_LEVEL_ERROR, file, function,
- line, NULL, format, args);
-}
/* Plugin entry point */
static gboolean
plugin_init (GstPlugin * plugin)
{
/* PRIMARY: this is the best videosink to use on windows */
- if (!gst_element_register (plugin, "d3dvideosink",
+ if (!gst_element_register (plugin, ELEMENT_NAME,
GST_RANK_PRIMARY, GST_TYPE_D3DVIDEOSINK))
return FALSE;
- GST_DEBUG_CATEGORY_INIT (d3dvideosink_debug, "d3dvideosink", 0,
- "Direct3D video sink");
-
return TRUE;
}
diff --git a/sys/d3dvideosink/d3dvideosink.h b/sys/d3dvideosink/d3dvideosink.h
index d03084a21..5a203d285 100644
--- a/sys/d3dvideosink/d3dvideosink.h
+++ b/sys/d3dvideosink/d3dvideosink.h
@@ -1,5 +1,7 @@
/* GStreamer
- * Copyright (C) 2010 David Hoyt <dhoyt@hoytsoft.org>
+ * Copyright (C) 2012 Roland Krikava <info@bluedigits.com>
+ * Copyright (C) 2010-2011 David Hoyt <dhoyt@hoytsoft.org>
+ * Copyright (C) 2010 Andoni Morales <ylatuya@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -13,12 +15,11 @@
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
*/
-
-#ifndef __D3DVIDEOSINK_H__
-#define __D3DVIDEOSINK_H__
+#ifndef _GSTD3DVIDEOSINK_H_
+#define _GSTD3DVIDEOSINK_H_
#include <gst/gst.h>
#include <gst/video/video.h>
@@ -26,33 +27,10 @@
#include <gst/video/videooverlay.h>
#include <gst/video/navigation.h>
-#include <windows.h>
-#if defined(__MINGW32__)
-# ifndef _OBJC_NO_COM_
-# if defined(__cplusplus) && !defined(CINTERFACE)
-# if defined(__GNUC__) && __GNUC__ < 3 && !defined(NOCOMATTRIBUTE)
-# define DECLARE_INTERFACE_IID_(i,b,d) _COM_interface __attribute__((com_interface)) i : public b
-# else
-# define DECLARE_INTERFACE_IID_(i,b,d) _COM_interface i : public b
-# endif
-# elif !defined(DECLARE_INTERFACE_IID_)
-# define DECLARE_INTERFACE_IID_(i,b,d) DECLARE_INTERFACE(i)
-# endif
-# endif
-# if !defined(__MSABI_LONG)
-# define __MSABI_LONG(x) x ## l
-# endif
-#endif
-#include <d3d9.h>
-#include <d3dx9tex.h>
-
-#include "directx/directx.h"
-
-#ifdef _MSC_VER
-#pragma warning( disable : 4090 4024)
-#endif
+#include "d3dhelpers.h"
G_BEGIN_DECLS
+
#define GST_TYPE_D3DVIDEOSINK (gst_d3dvideosink_get_type())
#define GST_D3DVIDEOSINK(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_D3DVIDEOSINK,GstD3DVideoSink))
#define GST_D3DVIDEOSINK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_D3DVIDEOSINK,GstD3DVideoSinkClass))
@@ -63,61 +41,76 @@ G_BEGIN_DECLS
typedef struct _GstD3DVideoSink GstD3DVideoSink;
typedef struct _GstD3DVideoSinkClass GstD3DVideoSinkClass;
-#define GST_D3DVIDEOSINK_D3D_DEVICE_LOCK(sink) g_mutex_lock (&GST_D3DVIDEOSINK (sink)->d3d_device_lock)
-#define GST_D3DVIDEOSINK_D3D_DEVICE_TRYLOCK(sink) g_mutex_trylock (&GST_D3DVIDEOSINK (sink)->d3d_device_lock)
-#define GST_D3DVIDEOSINK_D3D_DEVICE_UNLOCK(sink) g_mutex_unlock (&GST_D3DVIDEOSINK (sink)->d3d_device_lock)
+typedef struct _GstVideoFormatDetails {
+ guint32 r_mask;
+ guint32 g_mask;
+ guint32 b_mask;
+ guint32 a_mask;
+ guint32 r_mask16;
+ guint32 g_mask16;
+ guint32 b_mask16;
+ guint32 a_mask16;
+ guint r_shift;
+ guint g_shift;
+ guint b_shift;
+ guint a_shift;
+ guint r_bits;
+ guint g_bits;
+ guint b_bits;
+ guint a_bits;
+ gint bpp;
+ gint depth;
+ gint endianness;
+ gint pixel_width;
+} GstVideoFormatDetails;
struct _GstD3DVideoSink
{
- GstVideoSink sink;
-
- /* source rectangle */
-
- GstVideoFormat format;
- GstVideoInfo info;
+ GstVideoSink sink;
+ GstD3DData d3d;
- gboolean enable_navigation_events;
-
- gboolean keep_aspect_ratio;
- GValue *par;
+ GstCaps * supported_caps;
- /* If the window is closed, we set this and error out */
- gboolean window_closed;
+ GValue par;
+ GstVideoFormat format;
+ GstVideoInfo info;
+ GstVideoFormatDetails fmt_details;
+ gint width;
+ gint height;
- /* The video window set through GstXOverlay */
- HWND window_handle;
-
- /* If we created the window, it needs to be closed in ::stop() */
- gboolean is_new_window;
+ GstVideoRectangle render_rect;
- /* If we create our own window, we run it from another thread */
- GThread *window_thread;
- HANDLE window_created_signal;
+ GStaticRecMutex lock;
- /* If we use an app-supplied window, we need to hook its WNDPROC */
- WNDPROC prevWndProc;
- gboolean is_hooked;
-
- GMutex d3d_device_lock;
- LPDIRECT3DSURFACE9 d3d_offscreen_surface;
- LPDIRECT3DDEVICE9 d3ddev;
- D3DPRESENT_PARAMETERS d3dpp;
-
- D3DFORMAT d3dformat;
- D3DFORMAT d3dfourcc;
- D3DTEXTUREFILTERTYPE d3dfiltertype;
+ /* Properties */
+ gboolean keep_aspect_ratio;
+ gboolean create_internal_window;
+ gboolean stream_stop_on_close;
+ gboolean enable_navigation_events;
};
struct _GstD3DVideoSinkClass
{
GstVideoSinkClass parent_class;
-
- gboolean is_directx_supported;
- gint directx_version;
- DirectXAPI *directx_api;
+ GstD3DDataClass d3d;
+ GStaticRecMutex lock;
};
-GType gst_d3dvideosink_get_type (void);
+#if 1
+# define LOCK_SINK(sink) g_static_rec_mutex_lock(&sink->lock);
+# define UNLOCK_SINK(sink) g_static_rec_mutex_unlock(&sink->lock);
+# define LOCK_CLASS(obj, class) g_static_rec_mutex_lock(&class->lock);
+# define UNLOCK_CLASS(obj, class) g_static_rec_mutex_unlock(&class->lock);
+#else
+# define LOCK_SINK(sink) GST_LOG_OBJECT(sink, "SINK LOCK"); g_static_rec_mutex_lock(&sink->lock); GST_LOG_OBJECT(sink, "SINK LOCKED");
+# define UNLOCK_SINK(sink) g_static_rec_mutex_unlock(&sink->lock); GST_LOG_OBJECT(sink, "SINK UNLOCKED");
+# define LOCK_CLASS(obj, class) GST_LOG_OBJECT(obj, "CLASS LOCK"); g_static_rec_mutex_lock(&class->lock); GST_LOG_OBJECT(obj, "CLASS LOCKED");
+# define UNLOCK_CLASS(obj, class) g_static_rec_mutex_unlock(&class->lock); GST_LOG_OBJECT(obj, "CLASS UNLOCKED");
+#endif
+
+GType gst_d3dvideosink_get_type (void);
G_END_DECLS
-#endif /* __D3DVIDEOSINK_H__ */
+
+
+#endif /* _GSTD3DVIDEOSINK_H_ */
diff --git a/sys/d3dvideosink/directx/directx.h b/sys/d3dvideosink/directx/directx.h
deleted file mode 100644
index 48dac0e96..000000000
--- a/sys/d3dvideosink/directx/directx.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* GStreamer
- * Copyright (C) 2011 David Hoyt <dhoyt@hoytsoft.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef __DIRECTX_DIRECTX_H__
-#define __DIRECTX_DIRECTX_H__
-
-#include "dx.h"
-#include "directx_d3d.h"
-
-/* TODO: Remove these headers -- they should not be publically distributed. */
-/* They're included for now only for expediancy in getting d3dvideosink */
-/* out the door. */
-#include "directx9/dx9.h"
-#include "directx10/dx10.h"
-#include "directx11/dx11.h"
-
-#endif /* __DIRECTX_DIRECTX_H__ */
diff --git a/sys/d3dvideosink/directx/directx10/dx10.c b/sys/d3dvideosink/directx/directx10/dx10.c
deleted file mode 100644
index f969a191c..000000000
--- a/sys/d3dvideosink/directx/directx10/dx10.c
+++ /dev/null
@@ -1,27 +0,0 @@
-/* GStreamer
- * Copyright (C) 2011 David Hoyt <dhoyt@hoytsoft.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#include "dx10.h"
-
-void
-dx10_init (const DirectXAPI * api)
-{
- DIRECTX_DEBUG ("Initializing DirectX10 API");
- INITIALIZE_DIRECTX_D3D_API (DIRECTX_10, api);
-}
diff --git a/sys/d3dvideosink/directx/directx10/dx10.h b/sys/d3dvideosink/directx/directx10/dx10.h
deleted file mode 100644
index 518346711..000000000
--- a/sys/d3dvideosink/directx/directx10/dx10.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/* GStreamer
- * Copyright (C) 2011 David Hoyt <dhoyt@hoytsoft.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef __DIRECTX_DIRECTX10_DX10_H__
-#define __DIRECTX_DIRECTX10_DX10_H__
-
-#include "../dx.h"
-
-#include "dx10_d3d.h"
-
-/* Function declarations */
-void dx10_init(const DirectXAPI* api);
-
-DIRECTX_API(
- DIRECTX_10,
- dx10_init,
- "d3d10",
- "D3D10CreateDevice",
- "DirectX10Description",
- "DirectX 10.0"
-)
-
-#endif /* __DIRECTX_DIRECTX10_DX10_H__ */
diff --git a/sys/d3dvideosink/directx/directx10/dx10_d3d.c b/sys/d3dvideosink/directx/directx10/dx10_d3d.c
deleted file mode 100644
index 7939752d9..000000000
--- a/sys/d3dvideosink/directx/directx10/dx10_d3d.c
+++ /dev/null
@@ -1,77 +0,0 @@
-/* GStreamer
- * Copyright (C) 2011 David Hoyt <dhoyt@hoytsoft.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#define CINTERFACE
-#define D3D10_IGNORE_SDK_LAYERS
-
-#include <windows.h>
-#include <d3d10.h>
-
-#include "dx10_d3d.h"
-
-void
-dx10_d3d_init (DirectXAPIComponent * component, gpointer data)
-{
- DIRECTX_DEBUG ("Initializing Direct3D");
- DIRECTX_OPEN_COMPONENT_MODULE (component, "d3d10");
- DIRECTX_DEBUG ("Completed Initializing Direct3D");
-
- DIRECTX_DEBUG ("Setting Direct3D dispatch table");
- DIRECTX_OPEN_COMPONENT_SYMBOL (component, D3D10DispatchTable,
- D3D10CreateDevice);
-
- //{
- // ID3D10Device* pDevice = NULL;
- // DIRECTX_DEBUG("Calling D3D10CreateDevice");
- // DX10_D3D_COMPONENT_CALL_FUNC(component, D3D10CreateDevice, NULL, D3D10_DRIVER_TYPE_HARDWARE, NULL, 0, D3D10_SDK_VERSION, &pDevice);
- // DIRECTX_DEBUG("Releasing D3D10 device");
- // ID3D10Device_Release(pDevice);
- // DIRECTX_DEBUG("Released D3D10 device");
- //}
-}
-
-DirectXD3D *
-dx10_d3d_create (const DirectXAPI * api)
-{
- return NULL;
-}
-
-gboolean
-dx10_d3d_resize (const DirectXD3D * d3d)
-{
- return TRUE;
-}
-
-gboolean
-dx10_d3d_device_lost (const DirectXD3D * d3d)
-{
- return TRUE;
-}
-
-gboolean
-dx10_d3d_notify_device_reset (const DirectXD3D * d3d)
-{
- return TRUE;
-}
-
-gboolean
-dx10_d3d_release (const DirectXD3D * d3d)
-{
- return TRUE;
-}
diff --git a/sys/d3dvideosink/directx/directx10/dx10_d3d.h b/sys/d3dvideosink/directx/directx10/dx10_d3d.h
deleted file mode 100644
index e5289655d..000000000
--- a/sys/d3dvideosink/directx/directx10/dx10_d3d.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/* GStreamer
- * Copyright (C) 2011 David Hoyt <dhoyt@hoytsoft.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef __DIRECTX_DIRECTX10_DX10_D3D_H__
-#define __DIRECTX_DIRECTX10_DX10_D3D_H__
-
-#include <windows.h>
-
-#include "../directx_d3d.h"
-
-#define DX10_D3D_API_CALL_FUNC(api, func_name, ...) (DIRECTX_CALL_COMPONENT_SYMBOL(DIRECTX_D3D(api), D3D10DispatchTable, func_name, __VA_ARGS__))
-#define DX10_D3D_COMPONENT_CALL_FUNC(component, func_name, ...) (DIRECTX_CALL_COMPONENT_SYMBOL(component, D3D10DispatchTable, func_name, __VA_ARGS__))
-
-/* Structs */
-typedef struct _D3D10 D3D10;
-typedef struct _D3D10DispatchTable D3D10DispatchTable;
-
-/* Functions */
-/* Courtesy http://code.google.com/p/theaimworldeditor/source/browse/trunk/DXUT/Core/DXUTmisc.cpp */
-typedef HRESULT (WINAPI *LPD3D10CREATEDEVICE)(gpointer /* IDXGIAdapter* */, UINT /* D3D10_DRIVER_TYPE */, HMODULE, UINT, UINT32, gpointer* /* ID3D10Device** */ );
-
-struct _D3D10DispatchTable
-{
- LPD3D10CREATEDEVICE D3D10CreateDevice;
-};
-
-/* Global data */
-struct _D3D10
-{
- D3D10DispatchTable vtable;
-};
-
-/* Global vars */
-static D3D10 dx10_d3d;
-
-/* Function declarations */
-
-void dx10_d3d_init(DirectXAPIComponent* component, gpointer data);
-DirectXD3D* dx10_d3d_create(const DirectXAPI* api);
-gboolean dx10_d3d_resize(const DirectXD3D* d3d);
-gboolean dx10_d3d_device_lost(const DirectXD3D* d3d);
-gboolean dx10_d3d_notify_device_reset(const DirectXD3D* d3d);
-gboolean dx10_d3d_release(const DirectXD3D* d3d);
-
-DIRECTX_D3D_API(
- DIRECTX_10,
- dx10_d3d.vtable,
- dx10_d3d_init,
- dx10_d3d_create,
- dx10_d3d_resize,
- dx10_d3d_device_lost,
- dx10_d3d_notify_device_reset,
- dx10_d3d_release
-)
-
-#endif /* __DIRECTX_DIRECTX10_DX10_D3D_H__ */
diff --git a/sys/d3dvideosink/directx/directx11/dx11.c b/sys/d3dvideosink/directx/directx11/dx11.c
deleted file mode 100644
index 1a72ac1c8..000000000
--- a/sys/d3dvideosink/directx/directx11/dx11.c
+++ /dev/null
@@ -1,27 +0,0 @@
-/* GStreamer
- * Copyright (C) 2011 David Hoyt <dhoyt@hoytsoft.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#include "dx11.h"
-
-void
-dx11_init (const DirectXAPI * api)
-{
- DIRECTX_DEBUG ("Initializing DirectX11 API");
- INITIALIZE_DIRECTX_D3D_API (DIRECTX_11, api);
-}
diff --git a/sys/d3dvideosink/directx/directx11/dx11.h b/sys/d3dvideosink/directx/directx11/dx11.h
deleted file mode 100644
index 5740bd0fd..000000000
--- a/sys/d3dvideosink/directx/directx11/dx11.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/* GStreamer
- * Copyright (C) 2011 David Hoyt <dhoyt@hoytsoft.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef __DIRECTX_DIRECTX11_DX11_H__
-#define __DIRECTX_DIRECTX11_DX11_H__
-
-#include "../dx.h"
-
-#include "dx11_d3d.h"
-
-/* Function declarations */
-void dx11_init(const DirectXAPI* api);
-
-DIRECTX_API(
- DIRECTX_11,
- dx11_init,
- "d3d11",
- "D3D11CreateDevice",
- "DirectX11Description",
- "DirectX 11.0"
-)
-
-#endif /* __DIRECTX_DIRECTX10_DX10_H__ */
diff --git a/sys/d3dvideosink/directx/directx11/dx11_d3d.c b/sys/d3dvideosink/directx/directx11/dx11_d3d.c
deleted file mode 100644
index 4f86e0dff..000000000
--- a/sys/d3dvideosink/directx/directx11/dx11_d3d.c
+++ /dev/null
@@ -1,75 +0,0 @@
-/* GStreamer
- * Copyright (C) 2011 David Hoyt <dhoyt@hoytsoft.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#define CINTERFACE
-
-#include <windows.h>
-//#include <d3d11.h>
-
-#include "dx11_d3d.h"
-
-void
-dx11_d3d_init (DirectXAPIComponent * component, gpointer data)
-{
- DIRECTX_DEBUG ("Initializing Direct3D");
- DIRECTX_OPEN_COMPONENT_MODULE (component, "d3d11");
- DIRECTX_DEBUG ("Completed Initializing Direct3D");
-
- DIRECTX_DEBUG ("Setting Direct3D dispatch table");
- //DIRECTX_OPEN_COMPONENT_SYMBOL(component, D3D11DispatchTable, D3D11CreateDevice);
-
- //{
- // ID3D11Device* pDevice = NULL;
- // DIRECTX_DEBUG("Calling D3D11CreateDevice");
- // DX11_D3D_COMPONENT_CALL_FUNC(component, D3D11CreateDevice, NULL, D3D11_DRIVER_TYPE_HARDWARE, NULL, 0, D3D11_SDK_VERSION, &pDevice);
- // DIRECTX_DEBUG("Releasing D3D11 device");
- // ID3D11Device_Release(pDevice);
- // DIRECTX_DEBUG("Released D3D11 device");
- //}
-}
-
-DirectXD3D *
-dx11_d3d_create (const DirectXAPI * api)
-{
- return NULL;
-}
-
-gboolean
-dx11_d3d_resize (const DirectXD3D * d3d)
-{
- return TRUE;
-}
-
-gboolean
-dx11_d3d_device_lost (const DirectXD3D * d3d)
-{
- return TRUE;
-}
-
-gboolean
-dx11_d3d_notify_device_reset (const DirectXD3D * d3d)
-{
- return TRUE;
-}
-
-gboolean
-dx11_d3d_release (const DirectXD3D * d3d)
-{
- return TRUE;
-}
diff --git a/sys/d3dvideosink/directx/directx11/dx11_d3d.h b/sys/d3dvideosink/directx/directx11/dx11_d3d.h
deleted file mode 100644
index de41606c2..000000000
--- a/sys/d3dvideosink/directx/directx11/dx11_d3d.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/* GStreamer
- * Copyright (C) 2011 David Hoyt <dhoyt@hoytsoft.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef __DIRECTX_DIRECTX11_DX11_D3D_H__
-#define __DIRECTX_DIRECTX11_DX11_D3D_H__
-
-#include <windows.h>
-
-#include "../directx_d3d.h"
-
-#define DX11_D3D_API_CALL_FUNC(api, func_name, ...) (DIRECTX_CALL_COMPONENT_SYMBOL(DIRECTX_D3D(api), D3D11DispatchTable, func_name, __VA_ARGS__))
-#define DX11_D3D_COMPONENT_CALL_FUNC(component, func_name, ...) (DIRECTX_CALL_COMPONENT_SYMBOL(component, D3D11DispatchTable, func_name, __VA_ARGS__))
-
-/* Structs */
-typedef struct _D3D11 D3D11;
-typedef struct _D3D11DispatchTable D3D11DispatchTable;
-
-/* Functions */
-/* Courtesy http://code.google.com/p/theaimworldeditor/source/browse/trunk/DXUT/Core/DXUTmisc.cpp */
-typedef HRESULT (WINAPI *LPD3D11CREATEDEVICE)(gpointer /* IDXGIAdapter* */, UINT /* D3D11_DRIVER_TYPE */, HMODULE, UINT, UINT32, gpointer* /* ID3D11Device** */ );
-
-struct _D3D11DispatchTable
-{
- LPD3D11CREATEDEVICE D3D11CreateDevice;
-};
-
-/* Global data */
-struct _D3D11
-{
- D3D11DispatchTable vtable;
-};
-
-/* Global vars */
-static D3D11 dx11_d3d;
-
-/* Function declarations */
-
-void dx11_d3d_init(DirectXAPIComponent* component, gpointer data);
-DirectXD3D* dx11_d3d_create(const DirectXAPI* api);
-gboolean dx11_d3d_resize(const DirectXD3D* d3d);
-gboolean dx11_d3d_device_lost(const DirectXD3D* d3d);
-gboolean dx11_d3d_notify_device_reset(const DirectXD3D* d3d);
-gboolean dx11_d3d_release(const DirectXD3D* d3d);
-
-DIRECTX_D3D_API(
- DIRECTX_11,
- dx11_d3d.vtable,
- dx11_d3d_init,
- dx11_d3d_create,
- dx11_d3d_resize,
- dx11_d3d_device_lost,
- dx11_d3d_notify_device_reset,
- dx11_d3d_release
-)
-
-#endif /* __DIRECTX_DIRECTX11_DX11_D3D_H__ */
diff --git a/sys/d3dvideosink/directx/directx9/dx9.c b/sys/d3dvideosink/directx/directx9/dx9.c
deleted file mode 100644
index ace027ca1..000000000
--- a/sys/d3dvideosink/directx/directx9/dx9.c
+++ /dev/null
@@ -1,27 +0,0 @@
-/* GStreamer
- * Copyright (C) 2011 David Hoyt <dhoyt@hoytsoft.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#include "dx9.h"
-
-void
-dx9_init (const DirectXAPI * api)
-{
- DIRECTX_DEBUG ("Initializing DirectX9 API");
- INITIALIZE_DIRECTX_D3D_API (DIRECTX_9, api);
-}
diff --git a/sys/d3dvideosink/directx/directx9/dx9.h b/sys/d3dvideosink/directx/directx9/dx9.h
deleted file mode 100644
index 4286d9d8a..000000000
--- a/sys/d3dvideosink/directx/directx9/dx9.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/* GStreamer
- * Copyright (C) 2011 David Hoyt <dhoyt@hoytsoft.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef __DIRECTX_DIRECTX9_DX10_H__
-#define __DIRECTX_DIRECTX9_DX10_H__
-
-#include "../dx.h"
-
-#include "dx9_d3d.h"
-
-void dx9_init(const DirectXAPI* api);
-
-DIRECTX_API(
- DIRECTX_9,
- dx9_init,
- "d3d9",
- "Direct3DCreate9",
- "DirectX9Description",
- "DirectX 9.0"
-)
-
-#endif /* __DIRECTX_DIRECTX9_DX10_H__ */
diff --git a/sys/d3dvideosink/directx/directx9/dx9_d3d.c b/sys/d3dvideosink/directx/directx9/dx9_d3d.c
deleted file mode 100644
index 9458ee06f..000000000
--- a/sys/d3dvideosink/directx/directx9/dx9_d3d.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/* GStreamer
- * Copyright (C) 2011 David Hoyt <dhoyt@hoytsoft.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#if defined(__MINGW32__)
-# ifndef _OBJC_NO_COM_
-# if defined(__cplusplus) && !defined(CINTERFACE)
-# if defined(__GNUC__) && __GNUC__ < 3 && !defined(NOCOMATTRIBUTE)
-# define DECLARE_INTERFACE_IID_(i,b,d) _COM_interface __attribute__((com_interface)) i : public b
-# else
-# define DECLARE_INTERFACE_IID_(i,b,d) _COM_interface i : public b
-# endif
-# else
-# define DECLARE_INTERFACE_IID_(i,b,d) DECLARE_INTERFACE(i)
-# endif
-# endif
-# if !defined(__MSABI_LONG)
-# define __MSABI_LONG(x) x ## l
-# endif
-#endif
-#include <d3d9.h>
-#include <d3dx9tex.h>
-
-#include "dx9_d3d.h"
-
-void
-dx9_d3d_init (DirectXAPIComponent * component, gpointer data)
-{
- DIRECTX_DEBUG ("Initializing Direct3D");
- DIRECTX_OPEN_COMPONENT_MODULE (component, "d3d9");
-
- DIRECTX_DEBUG ("Setting Direct3D dispatch table");
- DIRECTX_OPEN_COMPONENT_SYMBOL (component, D3D9DispatchTable, Direct3DCreate9);
-
- //{
- // IDirect3D9* blah;
- // DIRECTX_DEBUG("CALLING CREATE9!");
- // //blah = DX9_CALL_FUNC(data, Direct3DCreate9, D3D_SDK_VERSION);
- // blah = DX9_D3D_COMPONENT_CALL_FUNC(component, Direct3DCreate9, D3D_SDK_VERSION);
- // DIRECTX_DEBUG("RELEASING CREATE9!");
- // IDirect3D9_Release(blah);
- // DIRECTX_DEBUG("RELEASED CREATE9!");
- //}
-}
-
-DirectXD3D *
-dx9_d3d_create (const DirectXAPI * api)
-{
- return NULL;
-}
-
-gboolean
-dx9_d3d_resize (const DirectXD3D * d3d)
-{
- return TRUE;
-}
-
-gboolean
-dx9_d3d_device_lost (const DirectXD3D * d3d)
-{
- return TRUE;
-}
-
-gboolean
-dx9_d3d_notify_device_reset (const DirectXD3D * d3d)
-{
- return TRUE;
-}
-
-gboolean
-dx9_d3d_release (const DirectXD3D * d3d)
-{
- return TRUE;
-}
diff --git a/sys/d3dvideosink/directx/directx9/dx9_d3d.h b/sys/d3dvideosink/directx/directx9/dx9_d3d.h
deleted file mode 100644
index c21b1ffe1..000000000
--- a/sys/d3dvideosink/directx/directx9/dx9_d3d.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/* GStreamer
- * Copyright (C) 2011 David Hoyt <dhoyt@hoytsoft.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef __DIRECTX_DIRECTX9_DX9_D3D_H__
-#define __DIRECTX_DIRECTX9_DX9_D3D_H__
-
-#include <windows.h>
-
-#include "../directx_d3d.h"
-
-#define DX9_D3D_API_CALL_FUNC(api, func_name, ...) (DIRECTX_CALL_COMPONENT_SYMBOL(DIRECTX_D3D(api), D3D9DispatchTable, func_name, __VA_ARGS__))
-#define DX9_D3D_COMPONENT_CALL_FUNC(component, func_name, ...) (DIRECTX_CALL_COMPONENT_SYMBOL(component, D3D9DispatchTable, func_name, __VA_ARGS__))
-
-/* Structs */
-typedef struct _D3D9 D3D9;
-typedef struct _D3D9DispatchTable D3D9DispatchTable;
-
-/* Functions */
-typedef gpointer /* IDirect3D9* */ (WINAPI *LPDIRECT3DCREATE9) (UINT);
-
-struct _D3D9DispatchTable
-{
- LPDIRECT3DCREATE9 Direct3DCreate9;
-};
-
-/* Global data */
-struct _D3D9
-{
- D3D9DispatchTable vtable;
-};
-
-/* Global vars */
-static D3D9 dx9_d3d;
-
-/* Function declarations */
-
-void dx9_d3d_init(DirectXAPIComponent* component, gpointer data);
-DirectXD3D* dx9_d3d_create(const DirectXAPI* api);
-gboolean dx9_d3d_resize(const DirectXD3D* d3d);
-gboolean dx9_d3d_device_lost(const DirectXD3D* d3d);
-gboolean dx9_d3d_notify_device_reset(const DirectXD3D* d3d);
-gboolean dx9_d3d_release(const DirectXD3D* d3d);
-
-DIRECTX_D3D_API(
- DIRECTX_9,
- dx9_d3d.vtable,
- dx9_d3d_init,
- dx9_d3d_create,
- dx9_d3d_resize,
- dx9_d3d_device_lost,
- dx9_d3d_notify_device_reset,
- dx9_d3d_release
-)
-
-#endif /* __DIRECTX_DIRECTX9_DX9_D3D_H__ */
diff --git a/sys/d3dvideosink/directx/directx_d3d.c b/sys/d3dvideosink/directx/directx_d3d.c
deleted file mode 100644
index 9f0f93548..000000000
--- a/sys/d3dvideosink/directx/directx_d3d.c
+++ /dev/null
@@ -1,65 +0,0 @@
-/* GStreamer
- * Copyright (C) 2011 David Hoyt <dhoyt@hoytsoft.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#include "directx.h"
-
-const DirectXD3D *
-directx_d3d_create (const DirectXAPI * api)
-{
- if (!api)
- return NULL;
-
- return DIRECTX_D3D_CALL_API_FUNCTION (api, create, api);
-}
-
-gboolean
-directx_d3d_resize (const DirectXD3D * d3d)
-{
- if (!d3d)
- return FALSE;
-
- return DIRECTX_D3D_CALL_FUNCTION (d3d, resize, d3d);
-}
-
-gboolean
-directx_d3d_device_lost (const DirectXD3D * d3d)
-{
- if (!d3d)
- return FALSE;
-
- return DIRECTX_D3D_CALL_FUNCTION (d3d, device_lost, d3d);
-}
-
-gboolean
-directx_d3d_notify_device_reset (const DirectXD3D * d3d)
-{
- if (!d3d)
- return FALSE;
-
- return DIRECTX_D3D_CALL_FUNCTION (d3d, notify_device_reset, d3d);
-}
-
-gboolean
-directx_d3d_release (const DirectXD3D * d3d)
-{
- if (!d3d)
- return FALSE;
-
- return DIRECTX_D3D_CALL_FUNCTION (d3d, release, d3d);
-}
diff --git a/sys/d3dvideosink/directx/directx_d3d.h b/sys/d3dvideosink/directx/directx_d3d.h
deleted file mode 100644
index 54e0c08dd..000000000
--- a/sys/d3dvideosink/directx/directx_d3d.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/* GStreamer
- * Copyright (C) 2011 David Hoyt <dhoyt@hoytsoft.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef __DIRECTX_D3D_H__
-#define __DIRECTX_D3D_H__
-
-#include <glib.h>
-
-#include "dx.h"
-
-G_BEGIN_DECLS
-
-#define WM_DIRECTX_D3D_INIT_DEVICE WM_DIRECTX + 1
-#define WM_DIRECTX_D3D_INIT_DEVICELOST WM_DIRECTX + 2
-#define WM_DIRECTX_D3D_DEVICELOST WM_DIRECTX + 3
-#define WM_DIRECTX_D3D_END_DEVICELOST WM_DIRECTX + 4
-#define WM_DIRECTX_D3D_RESIZE WM_DIRECTX + 5
-
-#define DIRECTX_D3D_API(version, dispatch_table, init_function, create_function, resize_function, device_lost_function, notify_device_reset_function, release_function) \
- static gpointer G_GNUC_UNUSED DIRECTX_API_COMPONENT_D3D_ ## version ## _DISPATCH_TABLE = &dispatch_table; \
- static DirectXAPIComponentD3D G_GNUC_UNUSED DIRECTX_API_COMPONENT_D3D_ ## version ## _INIT = { \
- create_function /*create_function*/ \
- , resize_function /*resize_function*/ \
- , device_lost_function /*device_lost_function*/ \
- , notify_device_reset_function /*notify_device_reset_function*/ \
- , release_function /*release_function*/ \
- , NULL /*private_data*/ \
- }; \
- static void G_GNUC_UNUSED init_directx_api_component_d3d_ ## version ## _(const DirectXAPI* api) { \
- gpointer private_data = &DIRECTX_API_COMPONENT_D3D_ ## version ## _INIT; \
- gpointer vtable = DIRECTX_API_COMPONENT_D3D_ ## version ## _DISPATCH_TABLE; \
- DIRECTX_SET_COMPONENT_INIT(DIRECTX_D3D(api), init_function); \
- DIRECTX_SET_COMPONENT_DATA(DIRECTX_D3D(api), private_data); \
- DIRECTX_SET_COMPONENT_DISPATCH_TABLE(DIRECTX_D3D(api), vtable); \
- }
-
-#define INITIALIZE_DIRECTX_D3D_API(version, api) \
- init_directx_api_component_d3d_ ## version ## _(api);
-
-#define DIRECTX_D3D_FUNCTIONS(d3d) ((DirectXAPIComponentD3D*)d3d->d3d_component)
-#define DIRECTX_D3D_API_FUNCTIONS(api) ((DirectXAPIComponentD3D*)DIRECTX_D3D_COMPONENT_DATA(api))
-#define DIRECTX_D3D_CALL_FUNCTION(d3d, func_name, ...) (DIRECTX_D3D_FUNCTIONS(d3d)->func_name(__VA_ARGS__))
-#define DIRECTX_D3D_CALL_API_FUNCTION(api, func_name, ...) (DIRECTX_D3D_API_FUNCTIONS(api)->func_name(__VA_ARGS__))
-
-typedef struct _DirectXD3D DirectXD3D;
-typedef struct _DirectXAPIComponentD3D DirectXAPIComponentD3D;
-
-/* Function pointers */
-typedef DirectXD3D* (*DirectXD3DCreateFunction) (const DirectXAPI* api);
-typedef gboolean (*DirectXD3DResizeFunction) (const DirectXD3D* d3d);
-typedef gboolean (*DirectXD3DDeviceLostFunction) (const DirectXD3D* d3d);
-typedef gboolean (*DirectXD3DNotifyDeviceResetFunction) (const DirectXD3D* d3d);
-typedef gboolean (*DirectXD3DReleaseFunction) (const DirectXD3D* d3d);
-
-struct _DirectXAPIComponentD3D
-{
- DirectXD3DCreateFunction create;
- DirectXD3DResizeFunction resize;
- DirectXD3DDeviceLostFunction device_lost;
- DirectXD3DNotifyDeviceResetFunction notify_device_reset;
- DirectXD3DReleaseFunction release;
-
- gpointer private_data;
-};
-
-struct _DirectXD3D
-{
- DirectXAPI* api;
- DirectXAPIComponent* api_component;
- DirectXAPIComponentD3D* d3d_component;
-
- gpointer private_data;
-};
-
-const DirectXD3D* directx_d3d_create(const DirectXAPI* api);
-gboolean directx_d3d_resize(const DirectXD3D* d3d);
-gboolean directx_d3d_device_lost(const DirectXD3D* d3d);
-gboolean directx_d3d_notify_device_reset(const DirectXD3D* d3d);
-gboolean directx_d3d_release(const DirectXD3D* d3d);
-
-G_END_DECLS
-
-#endif /* __DIRECTX_D3D_H__ */
diff --git a/sys/d3dvideosink/directx/dx.c b/sys/d3dvideosink/directx/dx.c
deleted file mode 100644
index c19faeb70..000000000
--- a/sys/d3dvideosink/directx/dx.c
+++ /dev/null
@@ -1,282 +0,0 @@
-/* GStreamer
- * Copyright (C) 2011 David Hoyt <dhoyt@hoytsoft.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#include <glib.h>
-#include <glib/gprintf.h>
-#include <gmodule.h>
-
-#include "dx.h"
-#include "directx9/dx9.h"
-#include "directx10/dx10.h"
-#include "directx11/dx11.h"
-
-
-
-static void
-init_supported_apis (void)
-{
- /* Gather information we'll need about each version of DirectX. */
- /* Insert in reverse order of desired priority due to the g_list_prepend() call in directx_determine_best_available_api(). */
- INITIALIZE_SUPPORTED_DIRECTX_API (DIRECTX_9);
- /* TODO: Add DirectX 10 support. */
- /*INITIALIZE_SUPPORTED_DIRECTX_API(DIRECTX_10); */
- /* TODO: Add DirectX 11 support. */
- /*INITIALIZE_SUPPORTED_DIRECTX_API(DIRECTX_11); */
-}
-
-
-
-/* Function declarations */
-static DirectXAPI *directx_determine_best_available_api (void);
-
-/* Mutex macros */
-#define DIRECTX_LOCK g_rec_mutex_lock (&dx_lock);
-#define DIRECTX_UNLOCK g_rec_mutex_unlock (&dx_lock);
-
-typedef struct _DirectXInfo DirectXInfo;
-struct _DirectXInfo
-{
- gboolean initialized;
- gboolean supported;
-
- DirectXInitParams *init_params;
- DirectXAPI *best_api;
- GList *supported_api_list;
- gint32 supported_api_count;
-};
-
-/* Private vars */
-static DirectXInfo dx;
-static GRecMutex dx_lock;
-
-gboolean
-directx_initialize (DirectXInitParams * init_params)
-{
- DIRECTX_LOCK if (dx.initialized)
- goto success;
-
- dx.init_params = NULL;
- dx.init_params = init_params;
-
- init_supported_apis ();
-
- dx.best_api = directx_determine_best_available_api ();
- dx.supported = (dx.best_api != NULL
- && !DIRECTX_VERSION_IS_UNKNOWN (dx.best_api->version));
- dx.initialized = TRUE;
-
-success:
- DIRECTX_UNLOCK return TRUE;
-}
-
-gboolean
-directx_api_initialize (DirectXAPI * api)
-{
- if (!api)
- return FALSE;
-
- DIRECTX_LOCK if (!directx_is_initialized ())
- goto error;
-
- if (api->initialized)
- goto success;
-
- /* API init */
- api->initialize (api);
-
- /* Component initialization */
- DIRECTX_COMPONENT_INIT (DIRECTX_D3D (api));
- DIRECTX_COMPONENT_INIT (DIRECTX_DINPUT (api));
- DIRECTX_COMPONENT_INIT (DIRECTX_DSOUND (api));
- DIRECTX_COMPONENT_INIT (DIRECTX_DWRITE (api));
- DIRECTX_COMPONENT_INIT (DIRECTX_D2D (api));
- DIRECTX_COMPONENT_INIT (DIRECTX_DCOMPUTE (api));
-
- /* All done */
- api->initialized = TRUE;
-
-success:
- DIRECTX_UNLOCK return TRUE;
-error:
- DIRECTX_UNLOCK return FALSE;
-}
-
-gboolean
-directx_initialize_best_available_api (void)
-{
- return directx_api_initialize (directx_get_best_available_api ());
-}
-
-gboolean
-directx_is_initialized (void)
-{
- gboolean initialized = FALSE;
-
- DIRECTX_LOCK initialized = dx.initialized;
- DIRECTX_UNLOCK return initialized;
-}
-
-gboolean
-directx_api_is_initialized (const DirectXAPI * api)
-{
- if (!api)
- return FALSE;
- {
- gboolean initialized;
-
- DIRECTX_LOCK initialized = api->initialized;
- DIRECTX_UNLOCK return initialized;
- }
-}
-
-gboolean
-directx_best_available_api_is_initialized (void)
-{
- return directx_api_is_initialized (directx_get_best_available_api ());
-}
-
-gboolean
-directx_is_supported (void)
-{
- return dx.supported;
-}
-
-GList *
-directx_get_supported_apis (void)
-{
- return dx.supported_api_list;
-}
-
-gint32
-directx_get_supported_api_count (void)
-{
- return dx.supported_api_count;
-}
-
-DirectXAPI *
-directx_get_best_available_api (void)
-{
- return dx.best_api;
-}
-
-void
-directx_log_debug (const gchar * file, const gchar * function, gint line,
- const gchar * format, ...)
-{
- if (!dx.init_params || !dx.init_params->log_debug)
- return;
- {
- va_list args;
- va_start (args, format);
- dx.init_params->log_debug (file, function, line, format, args);
- va_end (args);
- }
-}
-
-void
-directx_log_warning (const gchar * file, const gchar * function, gint line,
- const gchar * format, ...)
-{
- if (!dx.init_params || !dx.init_params->log_warning)
- return;
- {
- va_list args;
- va_start (args, format);
- dx.init_params->log_warning (file, function, line, format, args);
- va_end (args);
- }
-}
-
-void
-directx_log_error (const gchar * file, const gchar * function, gint line,
- const gchar * format, ...)
-{
- if (!dx.init_params || !dx.init_params->log_error)
- return;
- {
- va_list args;
- va_start (args, format);
- dx.init_params->log_error (file, function, line, format, args);
- va_end (args);
- }
-}
-
-/* This should only be called through use of the DIRECTX_API() macro. It should never be called directly. */
-gboolean
-directx_add_supported_api (DirectXAPI * api)
-{
- if (!api)
- return FALSE;
-
- DIRECTX_LOCK {
-
- /* Add to our GList containing all of our supported APIs. */
- /* GLists are doubly-linked lists and calling prepend() prevents it from having to traverse the entire list just to add one item. */
- dx.supported_api_list = g_list_prepend (dx.supported_api_list, api);
- dx.supported_api_count++;
-
- }
-/*success:*/
- DIRECTX_UNLOCK return TRUE;
-}
-
-static DirectXAPI *
-directx_determine_best_available_api (void)
-{
- if (!g_module_supported ())
- return NULL;
-
- {
- GList *item;
- GModule *lib;
- DirectXAPI *dxlib = NULL;
-
- DIRECTX_LOCK {
- /* Search supported APIs (DirectX9, DirectX10, etc.) looking for the first one that works. */
- DIRECTX_DEBUG
- ("Searching supported DirectX APIs for the best (most recent) one available");
- for (item = g_list_first (dx.supported_api_list); item; item = item->next) {
- if ((dxlib = (DirectXAPI *) item->data) == NULL)
- continue;
-
- DIRECTX_DEBUG ("Determining support for %s", dxlib->description);
- DIRECTX_DEBUG ("Searching for module \"%s\" with the symbol \"%s\"",
- dxlib->module_test, dxlib->symbol_test);
-
- /* Can we locate and open a Direct3D library (e.g. d3d9.dll or d3d10.dll)? */
- if ((lib =
- g_module_open (dxlib->module_test,
- G_MODULE_BIND_LAZY)) != NULL) {
- /* Look for a symbol/function (e.g. "Direct3DCreate9") in the module and if it exists, we found one! */
- gpointer symbol;
- if (g_module_symbol (lib, dxlib->symbol_test, &symbol)) {
- g_module_close (lib);
- DIRECTX_DEBUG ("Selected %s", dxlib->description);
- goto done;
- }
- /* Ensure we don't have a mem leak. */
- g_module_close (lib);
- }
- }
-
- }
- done:
- DIRECTX_UNLOCK return dxlib;
- }
-}
diff --git a/sys/d3dvideosink/directx/dx.h b/sys/d3dvideosink/directx/dx.h
deleted file mode 100644
index e197da70a..000000000
--- a/sys/d3dvideosink/directx/dx.h
+++ /dev/null
@@ -1,265 +0,0 @@
-/* GStreamer
- * Copyright (C) 2011 David Hoyt <dhoyt@hoytsoft.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef __DIRECTX_DX_H__
-#define __DIRECTX_DX_H__
-
-#include <glib.h>
-#include <gmodule.h>
-
-G_BEGIN_DECLS
-
-#define WM_DIRECTX WM_USER + 500
-
-#define DIRECTX_VERSION_UNKNOWN 0
-
-#define DIRECTX_VERSION_ENCODE_FULL(major, minor, micro) ( \
- ((major) * 10000) \
- + ((minor) * 100) \
- + ((micro) * 1))
-
-#define DIRECTX_VERSION_ENCODE(major) \
- DIRECTX_VERSION_ENCODE_FULL(major, 0, 0)
-
-typedef enum
-{
- DIRECTX_UNKNOWN = DIRECTX_VERSION_UNKNOWN,
- DIRECTX_9 = DIRECTX_VERSION_ENCODE(9),
- DIRECTX_10 = DIRECTX_VERSION_ENCODE(10),
- DIRECTX_10_1 = DIRECTX_VERSION_ENCODE_FULL(10, 1, 0),
- DIRECTX_11 = DIRECTX_VERSION_ENCODE(11)
-} DirectXVersion;
-
-#define DIRECTX_API(version, initialization_function, module_test, symbol_test, i18n_key, description) \
- static DirectXAPIComponent DIRECTX_ ## version ## _DIRECT3D_COMPONENT = { \
- NULL /*api*/ \
- , FALSE /*initialized*/ \
- , NULL /*initialize*/ \
- , NULL /*module*/ \
- , NULL /*module_name*/ \
- , NULL /*private_data*/ \
- }; \
- static DirectXAPIComponent DIRECTX_ ## version ## _DIRECTINPUT_COMPONENT = { \
- NULL /*api*/ \
- , FALSE /*initialized*/ \
- , NULL /*initialize*/ \
- , NULL /*module*/ \
- , NULL /*module_name*/ \
- , NULL /*private_data*/ \
- }; \
- static DirectXAPIComponent DIRECTX_ ## version ## _DIRECTSOUND_COMPONENT = { \
- NULL /*api*/ \
- , FALSE /*initialized*/ \
- , NULL /*initialize*/ \
- , NULL /*module*/ \
- , NULL /*module_name*/ \
- , NULL /*private_data*/ \
- }; \
- static DirectXAPIComponent DIRECTX_ ## version ## _DIRECTWRITE_COMPONENT = { \
- NULL /*api*/ \
- , FALSE /*initialized*/ \
- , NULL /*initialize*/ \
- , NULL /*module*/ \
- , NULL /*module_name*/ \
- , NULL /*private_data*/ \
- }; \
- static DirectXAPIComponent DIRECTX_ ## version ## _DIRECT2D_COMPONENT = { \
- NULL /*api*/ \
- , FALSE /*initialized*/ \
- , NULL /*initialize*/ \
- , NULL /*module*/ \
- , NULL /*module_name*/ \
- , NULL /*private_data*/ \
- }; \
- static DirectXAPIComponent DIRECTX_ ## version ## _DIRECTCOMPUTE_COMPONENT = { \
- NULL /*api*/ \
- , FALSE /*initialized*/ \
- , NULL /*initialize*/ \
- , NULL /*module*/ \
- , NULL /*module_name*/ \
- , NULL /*private_data*/ \
- }; \
- static DirectXAPI DIRECTX_ ## version ## _API = { \
- version \
- , module_test "." G_MODULE_SUFFIX \
- , symbol_test \
- , i18n_key \
- , description \
- , FALSE \
- , initialization_function \
- , &DIRECTX_ ## version ## _DIRECT3D_COMPONENT \
- , &DIRECTX_ ## version ## _DIRECTINPUT_COMPONENT \
- , &DIRECTX_ ## version ## _DIRECTSOUND_COMPONENT \
- , &DIRECTX_ ## version ## _DIRECTWRITE_COMPONENT \
- , &DIRECTX_ ## version ## _DIRECT2D_COMPONENT \
- , &DIRECTX_ ## version ## _DIRECTCOMPUTE_COMPONENT \
- , {NULL, NULL, NULL} /*reserved*/ \
- }; \
- static void G_GNUC_UNUSED init_directx_ ## version ## _supported_api(void) { \
- DirectXAPI* api; \
- api = &DIRECTX_ ## version ## _API; \
- api->d3d->api = api; \
- api->dinput->api = api; \
- api->dsound->api = api; \
- api->dwrite->api = api; \
- api->d2d->api = api; \
- api->dcompute->api = api; \
- directx_add_supported_api(api); \
- }
-
-#define INITIALIZE_SUPPORTED_DIRECTX_API(version) \
- init_directx_ ## version ## _supported_api();
-
-#define DIRECTX_COMPONENT_INIT(component) \
- { \
- if (component != NULL && component->initialize != NULL && !component->initialized) { \
- component->initialize(component, DIRECTX_COMPONENT_DATA(component)); \
- } \
- }
-
-#define DIRECTX_OPEN_COMPONENT_MODULE(component, component_module_name) \
- { \
- GModule* lib; \
- if (component && component->module == NULL && (lib = g_module_open(component_module_name "." G_MODULE_SUFFIX, G_MODULE_BIND_LAZY)) != NULL) { \
- component->module_name = component_module_name "." G_MODULE_SUFFIX; \
- component->module = lib; \
- } \
- }
-
-#define DIRECTX_OPEN_COMPONENT_SYMBOL(component, dispatch_table_type, component_symbol_name) \
- { \
- gpointer symbol; \
- if (component && component->module && g_module_symbol(component->module, #component_symbol_name, &symbol)) { \
- ((dispatch_table_type*)component->vtable)->component_symbol_name = symbol; \
- } \
- }
-
-#define DIRECTX_CALL_COMPONENT_SYMBOL(component, dispatch_table_type, component_symbol_name, ...) \
- (((dispatch_table_type*)component->vtable)->component_symbol_name(__VA_ARGS__))
-
-
-/* Borrowed from GST_FUNCTION */
-#ifndef DIRECTX_FUNCTION
-#if defined (__GNUC__) || (defined (_MSC_VER) && _MSC_VER >= 1300)
-# define DIRECTX_FUNCTION ((const char*) (__FUNCTION__))
-#elif defined (__STDC__) && defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
-# define DIRECTX_FUNCTION ((const char*) (__func__))
-#else
-# define DIRECTX_FUNCTION ((const char*) ("???"))
-#endif
-#endif
-
-#define DIRECTX_DEBUG(...) (directx_log_debug(__FILE__, DIRECTX_FUNCTION, __LINE__, __VA_ARGS__))
-#define DIRECTX_WARNING(...) (directx_log_warning(__FILE__, DIRECTX_FUNCTION, __LINE__, __VA_ARGS__))
-#define DIRECTX_ERROR(...) (directx_log_error(__FILE__, DIRECTX_FUNCTION, __LINE__, __VA_ARGS__))
-
-#define DIRECTX_COMPONENT_API(component) (component->api)
-#define DIRECTX_COMPONENT_DATA(component) (component->private_data)
-#define DIRECTX_SET_COMPONENT_DATA(component, data) (component->private_data = data)
-#define DIRECTX_SET_COMPONENT_INIT(component, init_function) (component->initialize = init_function)
-#define DIRECTX_SET_COMPONENT_DISPATCH_TABLE(component, dispatch_table) (component->vtable = dispatch_table)
-#define DIRECTX_VERSION_IS_UNKNOWN(version) (version == DIRECTX_VERSION_UNKNOWN)
-#define DIRECTX_SUPPORTED_API_IS_LAST(lib) (lib == NULL || lib->version == DIRECTX_VERSION_UNKNOWN || lib->module_name == NULL)
-
-typedef struct _DirectXInitParams DirectXInitParams;
-typedef struct _DirectXAPI DirectXAPI;
-typedef struct _DirectXAPIComponent DirectXAPIComponent;
-
-/* Function pointers */
-typedef void (*DirectXInitializationFunction) (const DirectXAPI* api);
-typedef void (*DirectXLogFunction) (const gchar* file, const gchar* function, gint line, const gchar* format, va_list args); /* vprintf-style logging function */
-
-struct _DirectXInitParams
-{
- DirectXLogFunction log_debug;
- DirectXLogFunction log_warning;
- DirectXLogFunction log_error;
-};
-
-struct _DirectXAPI
-{
- gint version;
- const gchar* module_test;
- const gchar* symbol_test;
- const gchar* i18n_key;
- const gchar* description;
- gboolean initialized;
- DirectXInitializationFunction initialize;
- DirectXAPIComponent* d3d;
- DirectXAPIComponent* dinput;
- DirectXAPIComponent* dsound;
- DirectXAPIComponent* dwrite;
- DirectXAPIComponent* d2d;
- DirectXAPIComponent* dcompute;
- gpointer reserved[3];
-};
-
-#define DIRECTX_D3D(api) (api->d3d)
-#define DIRECTX_DINPUT(api) (api->dinput)
-#define DIRECTX_DSOUND(api) (api->dsound)
-#define DIRECTX_DWRITE(api) (api->dwrite)
-#define DIRECTX_D2D(api) (api->d2d)
-#define DIRECTX_DCOMPUTE(api) (api->dcompute)
-
-#define DIRECTX_D3D_COMPONENT_DATA(api) (DIRECTX_COMPONENT_DATA(DIRECTX_D3D(api)))
-#define DIRECTX_DINPUT_COMPONENT_DATA(api) (DIRECTX_COMPONENT_DATA(DIRECTX_DINPUT(api)))
-#define DIRECTX_DSOUND_COMPONENT_DATA(api) (DIRECTX_COMPONENT_DATA(DIRECTX_DSOUND(api)))
-#define DIRECTX_DWRITE_COMPONENT_DATA(api) (DIRECTX_COMPONENT_DATA(DIRECTX_DWRITE(api)))
-#define DIRECTX_D2D_COMPONENT_DATA(api) (DIRECTX_COMPONENT_DATA(DIRECTX_D2D(api)))
-#define DIRECTX_DCOMPUTE_COMPONENT_DATA(api) (DIRECTX_COMPONENT_DATA(DIRECTX_DCOMPUTE(api)))
-
-/* DirectX component function table */
-typedef void (*DirectXComponentInitializeFunction) (DirectXAPIComponent* d3d, gpointer data);
-struct _DirectXAPIComponent
-{
- DirectXAPI* api;
- gboolean initialized;
- DirectXComponentInitializeFunction initialize;
-
- GModule* module;
- const gchar* module_name;
-
- gpointer vtable;
-
- gpointer private_data;
-};
-
-gboolean directx_initialize (DirectXInitParams* init_params);
-gboolean directx_is_initialized (void);
-
-gboolean directx_is_supported (void);
-
-void directx_log_debug(const gchar* file, const gchar* function, gint line, const gchar * format, ...);
-void directx_log_warning(const gchar* file, const gchar* function, gint line, const gchar * format, ...);
-void directx_log_error(const gchar* file, const gchar* function, gint line, const gchar * format, ...);
-
-GList* directx_get_supported_apis (void);
-gint32 directx_get_supported_api_count (void);
-gboolean directx_add_supported_api (DirectXAPI* api);
-
-DirectXAPI* directx_get_best_available_api (void);
-gboolean directx_initialize_best_available_api (void);
-gboolean directx_best_available_api_is_initialized (void);
-
-gboolean directx_api_initialize (DirectXAPI* api);
-gboolean directx_api_is_initialized (const DirectXAPI* api);
-
-G_END_DECLS
-
-#endif /* __DIRECTX_DX_H__ */