diff options
author | Roland Krikava <rkrikava@gmail.com> | 2012-12-22 11:24:28 +0100 |
---|---|---|
committer | Sebastian Dröge <sebastian.droege@collabora.co.uk> | 2012-12-22 11:24:28 +0100 |
commit | fe5f514049029fd9004074c9a3970e27b8bc5120 (patch) | |
tree | 91e5f6f65299e39c2abd41ba0fb2033b9a1b03e3 /sys/d3dvideosink | |
parent | c636b45c9ac455b74f07916ab46e587a44faee3e (diff) | |
download | gstreamer-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')
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__ */ |