summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorJan Schmidt <thaytan@noraisin.net>2009-05-16 01:11:33 +0100
committerJan Schmidt <thaytan@noraisin.net>2009-05-16 01:11:33 +0100
commitbba3e907682a806b90b73f10a1a28f2231fd6cf7 (patch)
tree7e663b1dcbab007190fcfe2cfcbd897aed1c0b12 /sys
parentbf58596e160a1d9fffc1da8a53b1e97f23e032f0 (diff)
Moved 'directdraw' from -good to -bad
Diffstat (limited to 'sys')
-rw-r--r--sys/Makefile.am10
-rw-r--r--sys/directdraw/Makefile.am12
-rw-r--r--sys/directdraw/gstdirectdrawplugin.c47
-rw-r--r--sys/directdraw/gstdirectdrawsink.c1945
-rw-r--r--sys/directdraw/gstdirectdrawsink.h141
5 files changed, 2 insertions, 2153 deletions
diff --git a/sys/Makefile.am b/sys/Makefile.am
index 8e1528e4..ee72a6e1 100644
--- a/sys/Makefile.am
+++ b/sys/Makefile.am
@@ -10,12 +10,6 @@ else
OSS_DIR=
endif
-if USE_DIRECTDRAW
-DIRECTDRAW_DIR=directdraw
-else
-DIRECTDRAW_DIR=
-endif
-
if USE_DIRECTSOUND
DIRECTSOUND_DIR=directsound
else
@@ -76,6 +70,6 @@ else
XIMAGE_DIR=
endif
-SUBDIRS=$(DIRECTDRAW_DIR) $(DIRECTSOUND_DIR) $(OSS_DIR) $(OSX_AUDIO_DIR) $(OSX_VIDEO_DIR) $(SUNAUDIO_DIR) $(V4L2_DIR) $(XIMAGE_DIR)
+SUBDIRS=$(DIRECTSOUND_DIR) $(OSS_DIR) $(OSX_AUDIO_DIR) $(OSX_VIDEO_DIR) $(SUNAUDIO_DIR) $(V4L2_DIR) $(XIMAGE_DIR)
-DIST_SUBDIRS=directdraw directsound oss osxaudio osxvideo sunaudio v4l2 waveform ximage
+DIST_SUBDIRS=directsound oss osxaudio osxvideo sunaudio v4l2 waveform ximage
diff --git a/sys/directdraw/Makefile.am b/sys/directdraw/Makefile.am
deleted file mode 100644
index 647d58ac..00000000
--- a/sys/directdraw/Makefile.am
+++ /dev/null
@@ -1,12 +0,0 @@
-plugin_LTLIBRARIES = libgstdirectdrawsink.la
-
-libgstdirectdrawsink_la_SOURCES = gstdirectdrawsink.c gstdirectdrawplugin.c
-libgstdirectdrawsink_la_CFLAGS = $(GST_CFLAGS) $(GST_BASE_CFLAGS) \
- $(GST_PLUGINS_BASE_CFLAGS) $(DIRECTDRAW_CFLAGS)
-libgstdirectdrawsink_la_LIBADD = $(DIRECTDRAW_LIBS) \
- $(GST_BASE_LIBS) $(GST_PLUGINS_BASE_LIBS) -lgstvideo-$(GST_MAJORMINOR) \
- -lgstinterfaces-$(GST_MAJORMINOR)
-libgstdirectdrawsink_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) $(DIRECTDRAW_LDFLAGS)
-libgstdirectdrawsink_la_LIBTOOLFLAGS = --tag=disable-static
-
-noinst_HEADERS= gstdirectdrawsink.h
diff --git a/sys/directdraw/gstdirectdrawplugin.c b/sys/directdraw/gstdirectdrawplugin.c
deleted file mode 100644
index 190bd02e..00000000
--- a/sys/directdraw/gstdirectdrawplugin.c
+++ /dev/null
@@ -1,47 +0,0 @@
-/* GStreamer
-* Copyright (C) 2005 Sebastien Moutte <sebastien@moutte.net>
-* Copyright (C) 2007 Pioneers of the Inevitable <songbird@songbirdnest.com>
-*
-* gstdirectdrawplugin.c:
-*
-* 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., 59 Temple Place - Suite 330,
-* Boston, MA 02111-1307, USA.
-*
-* The development of this code was made possible due to the involvement
-* of Pioneers of the Inevitable, the creators of the Songbird Music player
-*
-*/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "gstdirectdrawsink.h"
-
-static gboolean
-plugin_init (GstPlugin * plugin)
-{
- if (!gst_element_register (plugin, "directdrawsink", GST_RANK_PRIMARY,
- GST_TYPE_DIRECTDRAW_SINK))
- return FALSE;
-
- return TRUE;
-}
-
-GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
- GST_VERSION_MINOR,
- "directdraw",
- "Direct Draw plugin library",
- plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
diff --git a/sys/directdraw/gstdirectdrawsink.c b/sys/directdraw/gstdirectdrawsink.c
deleted file mode 100644
index 144f6595..00000000
--- a/sys/directdraw/gstdirectdrawsink.c
+++ /dev/null
@@ -1,1945 +0,0 @@
-/* GStreamer
- * Copyright (C) 2005 Sebastien Moutte <sebastien@moutte.net>
- * Copyright (C) 2007 Pioneers of the Inevitable <songbird@songbirdnest.com>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * The development of this code was made possible due to the involvement
- * of Pioneers of the Inevitable, the creators of the Songbird Music player
- *
- */
-
-/**
- * SECTION:element-directdrawsink
- *
- * DirectdrawSink renders video RGB frames to any win32 window. This element
- * can receive a window ID from the application through the #XOverlay interface
- * and will then render video frames in this window.
- * If no Window ID was provided by the application, the element will create its
- * own internal window and render into it.
- *
- * <refsect2>
- * <title>Example pipelines</title>
- * |[
- * gst-launch -v videotestsrc ! directdrawsink
- * ]| a simple pipeline to test the sink
- * </refsect2>
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "gstdirectdrawsink.h"
-
-GST_DEBUG_CATEGORY_STATIC (directdrawsink_debug);
-#define GST_CAT_DEFAULT directdrawsink_debug
-
-/* elementfactory information */
-static const GstElementDetails gst_directdraw_sink_details =
-GST_ELEMENT_DETAILS ("Direct Draw Video Sink",
- "Sink/Video",
- "Output to a video card via Direct Draw",
- "Sebastien Moutte <sebastien@moutte.net>");
-
-static void gst_directdraw_sink_init_interfaces (GType type);
-
-GST_BOILERPLATE_FULL (GstDirectDrawSink, gst_directdraw_sink, GstVideoSink,
- GST_TYPE_VIDEO_SINK, gst_directdraw_sink_init_interfaces);
-
-static void gst_directdraw_sink_finalize (GObject * object);
-static void gst_directdraw_sink_set_property (GObject * object,
- guint prop_id, const GValue * value, GParamSpec * pspec);
-static void gst_directdraw_sink_get_property (GObject * object,
- guint prop_id, GValue * value, GParamSpec * pspec);
-static GstCaps *gst_directdraw_sink_get_caps (GstBaseSink * bsink);
-static gboolean gst_directdraw_sink_set_caps (GstBaseSink * bsink,
- GstCaps * caps);
-static GstStateChangeReturn gst_directdraw_sink_change_state (GstElement *
- element, GstStateChange transition);
-static GstFlowReturn gst_directdraw_sink_buffer_alloc (GstBaseSink * bsink,
- guint64 offset, guint size, GstCaps * caps, GstBuffer ** buf);
-static void gst_directdraw_sink_get_times (GstBaseSink * bsink, GstBuffer * buf,
- GstClockTime * start, GstClockTime * end);
-static GstFlowReturn gst_directdraw_sink_show_frame (GstBaseSink * bsink,
- GstBuffer * buf);
-
-/* utils */
-static gboolean gst_directdraw_sink_setup_ddraw (GstDirectDrawSink * ddrawsink);
-static gboolean gst_directdraw_sink_create_default_window (GstDirectDrawSink *
- ddrawsink);
-static gboolean gst_directdraw_sink_check_primary_surface (GstDirectDrawSink *
- ddrawsink);
-static gboolean gst_directdraw_sink_check_offscreen_surface (GstDirectDrawSink *
- ddrawsink);
-static GstCaps *gst_directdraw_sink_get_ddrawcaps (GstDirectDrawSink *
- ddrawsink);
-static GstCaps
- * gst_directdraw_sink_create_caps_from_surfacedesc (LPDDSURFACEDESC2 desc);
-static void gst_directdraw_sink_cleanup (GstDirectDrawSink * ddrawsink);
-static void gst_directdraw_sink_bufferpool_clear (GstDirectDrawSink *
- ddrawsink);
-static int gst_directdraw_sink_get_depth (LPDDPIXELFORMAT lpddpfPixelFormat);
-static gboolean gst_ddrawvideosink_get_format_from_caps (GstDirectDrawSink *
- ddrawsink, GstCaps * caps, DDPIXELFORMAT * pPixelFormat);
-static void gst_directdraw_sink_center_rect (GstDirectDrawSink * ddrawsink,
- RECT src, RECT dst, RECT * result);
-char *DDErrorString (HRESULT hr);
-
-/* surfaces management functions */
-static void gst_directdraw_sink_surface_destroy (GstDirectDrawSink * ddrawsink,
- GstDDrawSurface * surface);
-static GstDDrawSurface *gst_directdraw_sink_surface_create (GstDirectDrawSink *
- ddrawsink, GstCaps * caps, size_t size);
-static gboolean gst_directdraw_sink_surface_check (GstDirectDrawSink *
- ddrawsink, GstDDrawSurface * surface);
-
-static GstStaticPadTemplate directdrawsink_sink_factory =
-GST_STATIC_PAD_TEMPLATE ("sink",
- GST_PAD_SINK,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("video/x-raw-rgb, "
- "framerate = (fraction) [ 0, MAX ], "
- "width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ]")
- );
-
-enum
-{
- PROP_0,
- PROP_KEEP_ASPECT_RATIO
-};
-
-/* XOverlay interface implementation */
-static gboolean
-gst_directdraw_sink_interface_supported (GstImplementsInterface * iface,
- GType type)
-{
- g_assert (type == GST_TYPE_X_OVERLAY);
- return TRUE;
-}
-
-static void
-gst_directdraw_sink_interface_init (GstImplementsInterfaceClass * klass)
-{
- klass->supported = gst_directdraw_sink_interface_supported;
-}
-
-static void
-gst_directdraw_sink_set_window_id (GstXOverlay * overlay, ULONG window_id)
-{
- GstDirectDrawSink *ddrawsink = GST_DIRECTDRAW_SINK (overlay);
-
- GST_OBJECT_LOCK (ddrawsink);
- /* check if we are already using this window id */
- if (ddrawsink->video_window == (HWND) window_id) {
- GST_OBJECT_UNLOCK (ddrawsink);
- return;
- }
-
- if (window_id) {
- HRESULT hres;
-
- /* If we had an internal window, close it first */
- if (ddrawsink->video_window && ddrawsink->our_video_window) {
- /* Trick to let the event thread know that it has to die silently */
- ddrawsink->our_video_window = FALSE;
- /* Post quit message and wait for our event window thread */
- PostMessage (ddrawsink->video_window, WM_QUIT, 0, 0);
- }
-
- ddrawsink->video_window = (HWND) window_id;
- ddrawsink->our_video_window = FALSE;
- if (ddrawsink->setup) {
- /* update the clipper object with the new window */
- hres = IDirectDrawClipper_SetHWnd (ddrawsink->clipper, 0,
- ddrawsink->video_window);
- }
- }
- /* FIXME: Handle the case where window_id is 0 and we want the sink to
- * create a new window when playback was already started (after set_caps) */
- GST_OBJECT_UNLOCK (ddrawsink);
-}
-
-static void
-gst_directdraw_sink_expose (GstXOverlay * overlay)
-{
- GstDirectDrawSink *ddrawsink = GST_DIRECTDRAW_SINK (overlay);
-
- gst_directdraw_sink_show_frame (GST_BASE_SINK (ddrawsink), NULL);
-}
-
-static void
-gst_directdraw_sink_xoverlay_interface_init (GstXOverlayClass * iface)
-{
- iface->set_xwindow_id = gst_directdraw_sink_set_window_id;
- iface->expose = gst_directdraw_sink_expose;
-}
-
-static void
-gst_directdraw_sink_init_interfaces (GType type)
-{
- static const GInterfaceInfo iface_info = {
- (GInterfaceInitFunc) gst_directdraw_sink_interface_init,
- NULL,
- NULL,
- };
-
- static const GInterfaceInfo xoverlay_info = {
- (GInterfaceInitFunc) gst_directdraw_sink_xoverlay_interface_init,
- NULL,
- NULL,
- };
-
- g_type_add_interface_static (type, GST_TYPE_IMPLEMENTS_INTERFACE,
- &iface_info);
- g_type_add_interface_static (type, GST_TYPE_X_OVERLAY, &xoverlay_info);
-}
-
-/* Subclass of GstBuffer which manages buffer_pool surfaces lifetime */
-static void gst_ddrawsurface_finalize (GstMiniObject * mini_object);
-static GstBufferClass *ddrawsurface_parent_class = NULL;
-
-static void
-gst_ddrawsurface_init (GstDDrawSurface * surface, gpointer g_class)
-{
- surface->surface = NULL;
- surface->width = 0;
- surface->height = 0;
- surface->ddrawsink = NULL;
- surface->locked = FALSE;
- surface->system_memory = FALSE;
- memset (&surface->dd_pixel_format, 0, sizeof (DDPIXELFORMAT));
-}
-
-static void
-gst_ddrawsurface_class_init (gpointer g_class, gpointer class_data)
-{
- GstMiniObjectClass *mini_object_class = GST_MINI_OBJECT_CLASS (g_class);
-
- ddrawsurface_parent_class = g_type_class_peek_parent (g_class);
-
- mini_object_class->finalize = GST_DEBUG_FUNCPTR (gst_ddrawsurface_finalize);
-}
-
-GType
-gst_ddrawsurface_get_type (void)
-{
- static GType _gst_ddrawsurface_type;
-
- if (G_UNLIKELY (_gst_ddrawsurface_type == 0)) {
- static const GTypeInfo ddrawsurface_info = {
- sizeof (GstBufferClass),
- NULL,
- NULL,
- gst_ddrawsurface_class_init,
- NULL,
- NULL,
- sizeof (GstDDrawSurface),
- 0,
- (GInstanceInitFunc) gst_ddrawsurface_init,
- NULL
- };
- _gst_ddrawsurface_type = g_type_register_static (GST_TYPE_BUFFER,
- "GstDDrawSurface", &ddrawsurface_info, 0);
- }
- return _gst_ddrawsurface_type;
-}
-
-static void
-gst_ddrawsurface_finalize (GstMiniObject * mini_object)
-{
- GstDirectDrawSink *ddrawsink = NULL;
- GstDDrawSurface *surface;
-
- surface = (GstDDrawSurface *) mini_object;
-
- ddrawsink = surface->ddrawsink;
- if (!ddrawsink)
- goto no_sink;
-
- /* If our geometry changed we can't reuse that image. */
- if ((surface->width != ddrawsink->video_width) ||
- (surface->height != ddrawsink->video_height) ||
- (memcmp (&surface->dd_pixel_format, &ddrawsink->dd_pixel_format,
- sizeof (DDPIXELFORMAT)) != 0 ||
- !gst_directdraw_sink_surface_check (ddrawsink, surface))
- ) {
- GST_CAT_INFO_OBJECT (directdrawsink_debug, ddrawsink,
- "destroy image as its size changed %dx%d vs current %dx%d",
- surface->width, surface->height, ddrawsink->video_width,
- ddrawsink->video_height);
- gst_directdraw_sink_surface_destroy (ddrawsink, surface);
- GST_MINI_OBJECT_CLASS (ddrawsurface_parent_class)->finalize (mini_object);
- } else {
- /* In that case we can reuse the image and add it to our image pool. */
- GST_CAT_INFO_OBJECT (directdrawsink_debug, ddrawsink,
- "recycling image in pool");
-
- /* need to increment the refcount again to recycle */
- gst_buffer_ref (GST_BUFFER (surface));
-
- g_mutex_lock (ddrawsink->pool_lock);
- ddrawsink->buffer_pool = g_slist_prepend (ddrawsink->buffer_pool, surface);
- g_mutex_unlock (ddrawsink->pool_lock);
- }
-
- return;
-
-no_sink:
- GST_CAT_WARNING (directdrawsink_debug, "no sink found");
- GST_MINI_OBJECT_CLASS (ddrawsurface_parent_class)->finalize (mini_object);
- return;
-}
-
-/************************************************************************/
-/* Directdraw sink functions */
-/************************************************************************/
-static void
-gst_directdraw_sink_base_init (gpointer g_class)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
- gst_element_class_set_details (element_class, &gst_directdraw_sink_details);
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&directdrawsink_sink_factory));
-}
-
-static void
-gst_directdraw_sink_class_init (GstDirectDrawSinkClass * klass)
-{
- GObjectClass *gobject_class;
- GstElementClass *gstelement_class;
- GstBaseSinkClass *gstbasesink_class;
-
- gobject_class = (GObjectClass *) klass;
- gstbasesink_class = (GstBaseSinkClass *) klass;
- gstelement_class = (GstElementClass *) klass;
-
- GST_DEBUG_CATEGORY_INIT (directdrawsink_debug, "directdrawsink", 0,
- "Directdraw sink");
-
- gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_directdraw_sink_finalize);
- gobject_class->get_property =
- GST_DEBUG_FUNCPTR (gst_directdraw_sink_get_property);
- gobject_class->set_property =
- GST_DEBUG_FUNCPTR (gst_directdraw_sink_set_property);
- gstelement_class->change_state =
- GST_DEBUG_FUNCPTR (gst_directdraw_sink_change_state);
- gstbasesink_class->get_caps =
- GST_DEBUG_FUNCPTR (gst_directdraw_sink_get_caps);
- gstbasesink_class->set_caps =
- GST_DEBUG_FUNCPTR (gst_directdraw_sink_set_caps);
- gstbasesink_class->preroll =
- GST_DEBUG_FUNCPTR (gst_directdraw_sink_show_frame);
- gstbasesink_class->render =
- GST_DEBUG_FUNCPTR (gst_directdraw_sink_show_frame);
- gstbasesink_class->get_times =
- GST_DEBUG_FUNCPTR (gst_directdraw_sink_get_times);
- gstbasesink_class->buffer_alloc =
- GST_DEBUG_FUNCPTR (gst_directdraw_sink_buffer_alloc);
-
- /* install properties */
- /* setup aspect ratio mode */
- 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", FALSE,
- G_PARAM_READWRITE));
-}
-
-static void
-gst_directdraw_sink_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec)
-{
- GstDirectDrawSink *ddrawsink = GST_DIRECTDRAW_SINK (object);
-
- switch (prop_id) {
- case PROP_KEEP_ASPECT_RATIO:
- ddrawsink->keep_aspect_ratio = g_value_get_boolean (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gst_directdraw_sink_get_property (GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec)
-{
- GstDirectDrawSink *ddrawsink = GST_DIRECTDRAW_SINK (object);
-
- switch (prop_id) {
- case PROP_KEEP_ASPECT_RATIO:
- g_value_set_boolean (value, ddrawsink->keep_aspect_ratio);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gst_directdraw_sink_finalize (GObject * object)
-{
- GstDirectDrawSink *ddrawsink = GST_DIRECTDRAW_SINK (object);
-
- if (ddrawsink->pool_lock) {
- g_mutex_free (ddrawsink->pool_lock);
- ddrawsink->pool_lock = NULL;
- }
- if (ddrawsink->caps) {
- gst_caps_unref (ddrawsink->caps);
- ddrawsink->caps = NULL;
- }
- if (ddrawsink->setup) {
- gst_directdraw_sink_cleanup (ddrawsink);
- }
-
- G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-static void
-gst_directdraw_sink_init (GstDirectDrawSink * ddrawsink,
- GstDirectDrawSinkClass * g_class)
-{
- /*init members variables */
- ddrawsink->ddraw_object = NULL;
- ddrawsink->primary_surface = NULL;
- ddrawsink->offscreen_surface = NULL;
- ddrawsink->clipper = NULL;
- ddrawsink->video_window = NULL;
- ddrawsink->our_video_window = TRUE;
- ddrawsink->last_buffer = NULL;
- ddrawsink->caps = NULL;
- ddrawsink->window_thread = NULL;
- ddrawsink->setup = FALSE;
- ddrawsink->buffer_pool = NULL;
- ddrawsink->keep_aspect_ratio = FALSE;
- ddrawsink->pool_lock = g_mutex_new ();
- ddrawsink->can_blit_between_colorspace = TRUE;
- ddrawsink->must_recreate_offscreen = FALSE;
- memset (&ddrawsink->dd_pixel_format, 0, sizeof (DDPIXELFORMAT));
-
- /*video default values */
- ddrawsink->video_height = 0;
- ddrawsink->video_width = 0;
- ddrawsink->fps_n = 0;
- ddrawsink->fps_d = 0;
-}
-
-static GstCaps *
-gst_directdraw_sink_get_caps (GstBaseSink * bsink)
-{
- GstDirectDrawSink *ddrawsink = GST_DIRECTDRAW_SINK (bsink);
- GstCaps *caps = NULL;
-
- if (!ddrawsink->setup) {
- caps = gst_caps_copy (gst_pad_get_pad_template_caps (GST_VIDEO_SINK_PAD
- (ddrawsink)));
- GST_CAT_INFO_OBJECT (directdrawsink_debug, ddrawsink,
- "getcaps called and we are not setup yet, " "returning template %"
- GST_PTR_FORMAT, caps);
- } else {
- caps = gst_caps_ref (ddrawsink->caps);
- }
-
- return caps;
-}
-
-static gboolean
-gst_directdraw_sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
-{
- GstDirectDrawSink *ddrawsink = GST_DIRECTDRAW_SINK (bsink);
- GstStructure *structure = NULL;
- gboolean ret;
- const GValue *fps;
-
- structure = gst_caps_get_structure (caps, 0);
- if (!structure)
- return FALSE;
-
- ret = gst_structure_get_int (structure, "width", &ddrawsink->video_width);
- ret &= gst_structure_get_int (structure, "height", &ddrawsink->video_height);
- fps = gst_structure_get_value (structure, "framerate");
- ret &= (fps != NULL);
- ret &=
- gst_ddrawvideosink_get_format_from_caps (ddrawsink, caps,
- &ddrawsink->dd_pixel_format);
- if (!ret) {
- GST_ELEMENT_ERROR (ddrawsink, CORE, NEGOTIATION,
- ("Failed to get caps properties from caps"), (NULL));
- return FALSE;
- }
-
- ddrawsink->fps_n = gst_value_get_fraction_numerator (fps);
- ddrawsink->fps_d = gst_value_get_fraction_denominator (fps);
-
- /* Notify application to set window id now */
- if (!ddrawsink->video_window) {
- gst_x_overlay_prepare_xwindow_id (GST_X_OVERLAY (ddrawsink));
- }
-
- /* If we still don't have a window at that stage we create our own */
- if (!ddrawsink->video_window) {
- gst_directdraw_sink_create_default_window (ddrawsink);
- }
-
- /* if we are rendering to our own window, resize it to video size */
- if (ddrawsink->video_window && ddrawsink->our_video_window) {
- SetWindowPos (ddrawsink->video_window, NULL,
- 0, 0, ddrawsink->video_width + (GetSystemMetrics (SM_CXSIZEFRAME) * 2),
- ddrawsink->video_height + GetSystemMetrics (SM_CYCAPTION) +
- (GetSystemMetrics (SM_CYSIZEFRAME) * 2), SWP_SHOWWINDOW | SWP_NOMOVE);
- }
-
- /* release the surface, we have to recreate it! */
- if (ddrawsink->offscreen_surface) {
- IDirectDrawSurface7_Release (ddrawsink->offscreen_surface);
- ddrawsink->offscreen_surface = NULL;
- }
-
- /* create an offscreen surface with the caps */
- ret = gst_directdraw_sink_check_offscreen_surface (ddrawsink);
- if (!ret) {
- GST_ELEMENT_ERROR (ddrawsink, CORE, NEGOTIATION,
- ("Can't create a directdraw offscreen surface with the input caps"),
- (NULL));
- }
-
- return ret;
-}
-
-static GstStateChangeReturn
-gst_directdraw_sink_change_state (GstElement * element,
- GstStateChange transition)
-{
- GstDirectDrawSink *ddrawsink = GST_DIRECTDRAW_SINK (element);
- GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
-
- switch (transition) {
- case GST_STATE_CHANGE_NULL_TO_READY:
- if (!gst_directdraw_sink_setup_ddraw (ddrawsink)) {
- ret = GST_STATE_CHANGE_FAILURE;
- goto beach;
- }
-
- if (!(ddrawsink->caps = gst_directdraw_sink_get_ddrawcaps (ddrawsink))) {
- ret = GST_STATE_CHANGE_FAILURE;
- goto beach;
- }
- break;
- default:
- break;
- }
-
- ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
-
- switch (transition) {
- case GST_STATE_CHANGE_PAUSED_TO_READY:
- ddrawsink->fps_n = 0;
- ddrawsink->fps_d = 1;
- ddrawsink->video_width = 0;
- ddrawsink->video_height = 0;
- if (ddrawsink->buffer_pool)
- gst_directdraw_sink_bufferpool_clear (ddrawsink);
- break;
- case GST_STATE_CHANGE_READY_TO_NULL:
- if (ddrawsink->setup)
- gst_directdraw_sink_cleanup (ddrawsink);
- break;
- default:
- break;
- }
-
-beach:
- return ret;
-}
-
-static GstFlowReturn
-gst_directdraw_sink_buffer_alloc (GstBaseSink * bsink, guint64 offset,
- guint size, GstCaps * caps, GstBuffer ** buf)
-{
- GstDirectDrawSink *ddrawsink = GST_DIRECTDRAW_SINK (bsink);
- GstStructure *structure;
- gint width, height;
- GstDDrawSurface *surface = NULL;
- GstFlowReturn ret = GST_FLOW_OK;
- GstCaps *buffer_caps = caps;
- gboolean buffercaps_unref = FALSE;
-
- GST_CAT_INFO_OBJECT (directdrawsink_debug, ddrawsink,
- "a buffer of %u bytes was requested", size);
-
- structure = gst_caps_get_structure (caps, 0);
- if (!gst_structure_get_int (structure, "width", &width) ||
- !gst_structure_get_int (structure, "height", &height)) {
- GST_WARNING_OBJECT (ddrawsink, "invalid caps for buffer allocation %"
- GST_PTR_FORMAT, caps);
- return GST_FLOW_UNEXPECTED;
- }
-
- g_mutex_lock (ddrawsink->pool_lock);
-
- /* Inspect our buffer pool */
- while (ddrawsink->buffer_pool) {
- surface = (GstDDrawSurface *) ddrawsink->buffer_pool->data;
- if (surface) {
- /* Removing from the pool */
- ddrawsink->buffer_pool = g_slist_delete_link (ddrawsink->buffer_pool,
- ddrawsink->buffer_pool);
-
- /* If the surface is invalid for our need, destroy */
- if ((surface->width != width) ||
- (surface->height != height) ||
- (memcmp (&surface->dd_pixel_format, &ddrawsink->dd_pixel_format,
- sizeof (DDPIXELFORMAT)) ||
- !gst_directdraw_sink_surface_check (ddrawsink, surface))
- ) {
- gst_directdraw_sink_surface_destroy (ddrawsink, surface);
- gst_buffer_unref (GST_BUFFER_CAST (surface));
- surface = NULL;
- } else {
- /* We found a suitable surface */
- break;
- }
- }
- }
-
- if (!ddrawsink->can_blit_between_colorspace) {
- /* Hardware doesn't support blit from one colorspace to another.
- * Check if the colorspace of the current display mode has changed since
- * the last negociation. If it's the case, we will have to renegociate
- */
- guint depth;
- HRESULT hres;
- DDSURFACEDESC2 surface_desc;
- DDSURFACEDESC2 *sd;
-
- if (!gst_structure_get_int (structure, "depth", (gint *) & depth)) {
- GST_CAT_DEBUG_OBJECT (directdrawsink_debug, ddrawsink,
- "Can't get depth from buffer_alloc caps");
- return GST_FLOW_ERROR;
- }
- surface_desc.dwSize = sizeof (surface_desc);
- sd = &surface_desc;
- hres =
- IDirectDraw7_GetDisplayMode (ddrawsink->ddraw_object,
- (DDSURFACEDESC *) sd);
- if (hres != DD_OK) {
- GST_CAT_DEBUG_OBJECT (directdrawsink_debug, ddrawsink,
- "Can't get current display mode (error=%ld)", (glong) hres);
- return GST_FLOW_ERROR;
- }
-
- if (depth != gst_directdraw_sink_get_depth (&surface_desc.ddpfPixelFormat)) {
- GstCaps *copy_caps = NULL;
- GstStructure *copy_structure = NULL;
- GstCaps *display_caps = NULL;
- GstStructure *display_structure = NULL;
-
- /* make a copy of the original caps */
- copy_caps = gst_caps_copy (caps);
- copy_structure = gst_caps_get_structure (copy_caps, 0);
-
- display_caps =
- gst_directdraw_sink_create_caps_from_surfacedesc (&surface_desc);
- if (display_caps) {
- display_structure = gst_caps_get_structure (display_caps, 0);
- if (display_structure) {
- gint bpp, endianness, red_mask, green_mask, blue_mask;
-
- /* get new display mode properties */
- gst_structure_get_int (display_structure, "depth", (gint *) & depth);
- gst_structure_get_int (display_structure, "bpp", &bpp);
- gst_structure_get_int (display_structure, "endianness", &endianness);
- gst_structure_get_int (display_structure, "red_mask", &red_mask);
- gst_structure_get_int (display_structure, "green_mask", &green_mask);
- gst_structure_get_int (display_structure, "blue_mask", &blue_mask);
-
- /* apply the new display mode changes to the previous caps */
- gst_structure_set (copy_structure,
- "bpp", G_TYPE_INT, bpp,
- "depth", G_TYPE_INT, depth,
- "endianness", G_TYPE_INT, endianness,
- "red_mask", G_TYPE_INT, red_mask,
- "green_mask", G_TYPE_INT, green_mask,
- "blue_mask", G_TYPE_INT, blue_mask, NULL);
-
- if (gst_pad_peer_accept_caps (GST_VIDEO_SINK_PAD (ddrawsink),
- copy_caps)) {
- buffer_caps = copy_caps;
- buffercaps_unref = TRUE;
- /* update buffer size needed to store video frames according to new caps */
- size = width * height * (bpp / 8);
-
- /* update our member pixel format */
- gst_ddrawvideosink_get_format_from_caps (ddrawsink, buffer_caps,
- &ddrawsink->dd_pixel_format);
- ddrawsink->must_recreate_offscreen = TRUE;
-
- GST_CAT_DEBUG_OBJECT (directdrawsink_debug, ddrawsink,
- " desired caps %s \n\n new caps %s", gst_caps_to_string (caps),
- gst_caps_to_string (buffer_caps));
- } else {
- GST_CAT_DEBUG_OBJECT (directdrawsink_debug, ddrawsink,
- "peer refused caps re-negociation "
- "and we can't render with the current caps.");
- ret = GST_FLOW_ERROR;
- }
- }
- gst_caps_unref (display_caps);
- }
-
- if (!buffercaps_unref)
- gst_caps_unref (copy_caps);
- }
- }
-
- /* We haven't found anything, creating a new one */
- if (!surface) {
- surface = gst_directdraw_sink_surface_create (ddrawsink, buffer_caps, size);
- }
-
- /* Now we should have a surface, set appropriate caps on it */
- if (surface) {
- GST_BUFFER_FLAGS (GST_BUFFER (surface)) = 0;
- gst_buffer_set_caps (GST_BUFFER (surface), buffer_caps);
- }
-
- g_mutex_unlock (ddrawsink->pool_lock);
-
- *buf = GST_BUFFER (surface);
-
- if (buffercaps_unref)
- gst_caps_unref (buffer_caps);
-
- return ret;
-}
-
-static void
-gst_directdraw_sink_draw_borders (GstDirectDrawSink * ddrawsink, RECT dst_rect)
-{
- RECT win_rect, fill_rect;
- POINT win_point;
- HDC hdc;
-
- g_return_if_fail (GST_IS_DIRECTDRAW_SINK (ddrawsink));
-
- /* Get the target window rect */
- win_point.x = 0;
- win_point.y = 0;
- ClientToScreen (ddrawsink->video_window, &win_point);
- GetClientRect (ddrawsink->video_window, &win_rect);
- OffsetRect (&win_rect, win_point.x, win_point.y);
-
- /* We acquire a drawing context */
- if (IDirectDrawSurface7_GetDC (ddrawsink->primary_surface, &hdc) == DD_OK) {
- HBRUSH brush = CreateSolidBrush (RGB (0, 0, 0));
-
- /* Left border */
- if (dst_rect.left > win_rect.left) {
- fill_rect.left = win_rect.left;
- fill_rect.top = win_rect.top;
- fill_rect.bottom = win_rect.bottom;
- fill_rect.right = dst_rect.left;
- FillRect (hdc, &fill_rect, brush);
- }
- /* Right border */
- if (dst_rect.right < win_rect.right) {
- fill_rect.top = win_rect.top;
- fill_rect.left = dst_rect.right;
- fill_rect.bottom = win_rect.bottom;
- fill_rect.right = win_rect.right;
- FillRect (hdc, &fill_rect, brush);
- }
- /* Top border */
- if (dst_rect.top > win_rect.top) {
- fill_rect.top = win_rect.top;
- fill_rect.left = win_rect.left;
- fill_rect.right = win_rect.right;
- fill_rect.bottom = dst_rect.top;
- FillRect (hdc, &fill_rect, brush);
- }
- /* Bottom border */
- if (dst_rect.bottom < win_rect.bottom) {
- fill_rect.top = dst_rect.bottom;
- fill_rect.left = win_rect.left;
- fill_rect.right = win_rect.right;
- fill_rect.bottom = win_rect.bottom;
- FillRect (hdc, &fill_rect, brush);
- }
- DeleteObject (brush);
- IDirectDrawSurface7_ReleaseDC (ddrawsink->primary_surface, hdc);
- }
-}
-
-static GstFlowReturn
-gst_directdraw_sink_show_frame (GstBaseSink * bsink, GstBuffer * buf)
-{
- GstDirectDrawSink *ddrawsink = GST_DIRECTDRAW_SINK (bsink);
- HRESULT hRes;
- RECT destsurf_rect, src_rect;
- POINT dest_surf_point;
-
- if (buf) {
- /* save a reference to the input buffer */
- gst_buffer_ref (buf);
- if (ddrawsink->last_buffer != NULL)
- gst_buffer_unref (ddrawsink->last_buffer);
- ddrawsink->last_buffer = buf;
- } else {
- /* use last buffer */
- buf = ddrawsink->last_buffer;
- }
-
- if (buf == NULL) {
- GST_ERROR_OBJECT (ddrawsink, "No buffer to render.");
- return GST_FLOW_ERROR;
- } else if (!ddrawsink->video_window) {
- GST_WARNING_OBJECT (ddrawsink, "No video window to render to.");
- return GST_FLOW_ERROR;
- }
-
- /* get the video window position */
- GST_OBJECT_LOCK (ddrawsink);
- if (G_UNLIKELY (!ddrawsink->video_window)) {
- GST_OBJECT_UNLOCK (ddrawsink);
- GST_CAT_WARNING_OBJECT (directdrawsink_debug, ddrawsink,
- "gst_directdraw_sink_show_frame our video window disappeared");
- GST_ELEMENT_ERROR (ddrawsink, RESOURCE, NOT_FOUND,
- ("Output window was closed"), (NULL));
- return GST_FLOW_ERROR;
- }
- dest_surf_point.x = 0;
- dest_surf_point.y = 0;
- ClientToScreen (ddrawsink->video_window, &dest_surf_point);
- GetClientRect (ddrawsink->video_window, &destsurf_rect);
- OffsetRect (&destsurf_rect, dest_surf_point.x, dest_surf_point.y);
-
- if (ddrawsink->keep_aspect_ratio) {
- /* center image to dest image keeping aspect ratio */
- src_rect.top = 0;
- src_rect.left = 0;
- src_rect.bottom = ddrawsink->video_height;
- src_rect.right = ddrawsink->video_width;
- gst_directdraw_sink_center_rect (ddrawsink, src_rect, destsurf_rect,
- &destsurf_rect);
- gst_directdraw_sink_draw_borders (ddrawsink, destsurf_rect);
- }
- GST_OBJECT_UNLOCK (ddrawsink);
-
- if (ddrawsink->must_recreate_offscreen && ddrawsink->offscreen_surface) {
- IDirectDrawSurface7_Release (ddrawsink->offscreen_surface);
- ddrawsink->offscreen_surface = NULL;
- }
-
- /* check for surfaces lost */
- if (!gst_directdraw_sink_check_primary_surface (ddrawsink) ||
- !gst_directdraw_sink_check_offscreen_surface (ddrawsink)) {
- return GST_FLOW_ERROR;
- }
-
- if (!GST_IS_DDRAWSURFACE (buf) ||
- ((GST_IS_DDRAWSURFACE (buf)) && (GST_BUFFER (buf)->malloc_data))) {
- /* We are receiving a system memory buffer so we will copy
- to the memory of our offscreen surface and next blit this surface
- on the primary surface */
- LPBYTE data = NULL;
- guint src_pitch, line;
- DDSURFACEDESC2 surf_desc;
- DDSURFACEDESC2 *sd;
-
- ZeroMemory (&surf_desc, sizeof (surf_desc));
- surf_desc.dwSize = sizeof (surf_desc);
- sd = &surf_desc;
-
- /* Lock the surface */
- hRes =
- IDirectDrawSurface7_Lock (ddrawsink->offscreen_surface, NULL,
- (DDSURFACEDESC *) sd, DDLOCK_WAIT, NULL);
- if (hRes != DD_OK) {
- GST_CAT_WARNING_OBJECT (directdrawsink_debug, ddrawsink,
- "gst_directdraw_sink_show_frame failed locking surface %s",
- DDErrorString (hRes));
-
- if (IDirectDrawSurface7_IsLost (ddrawsink->offscreen_surface) == DD_OK)
- return GST_FLOW_OK;
- else
- return GST_FLOW_ERROR;
- }
-
- /* Write each line respecting the destination surface pitch */
- data = surf_desc.lpSurface;
- src_pitch = GST_BUFFER_SIZE (buf) / ddrawsink->video_height;
- for (line = 0; line < surf_desc.dwHeight; line++) {
- memcpy (data, GST_BUFFER_DATA (buf) + (line * src_pitch), src_pitch);
- data += surf_desc.lPitch;
- }
-
- /* Unlock the surface */
- hRes = IDirectDrawSurface7_Unlock (ddrawsink->offscreen_surface, NULL);
- if (hRes != DD_OK) {
- GST_CAT_WARNING_OBJECT (directdrawsink_debug, ddrawsink,
- "gst_directdraw_sink_show_frame failed unlocking surface %s",
- DDErrorString (hRes));
- return GST_FLOW_ERROR;
- }
-
- /* blit to primary surface ( Blt will scale the video the dest rect surface
- * if needed */
- hRes = IDirectDrawSurface7_Blt (ddrawsink->primary_surface, &destsurf_rect,
- ddrawsink->offscreen_surface, NULL, DDBLT_WAIT, NULL);
- if (hRes != DD_OK) /* FIXME: Is it really safe to continue past here ? */
- GST_CAT_WARNING_OBJECT (directdrawsink_debug, ddrawsink,
- "IDirectDrawSurface7_Blt (object's offscreen surface) " "returned %s",
- DDErrorString (hRes));
-
- } else {
- /* We are receiving a directdraw surface (previously returned by our buffer
- * pool so we will simply blit it on the primary surface */
- GstDDrawSurface *surface = NULL;
-
- surface = GST_DDRAWSURFACE (buf);
-
- /* Unlocking surface before blit */
- IDirectDrawSurface7_Unlock (surface->surface, NULL);
- surface->locked = FALSE;
-
- /* blit to our primary surface */
- hRes = IDirectDrawSurface7_Blt (ddrawsink->primary_surface, &destsurf_rect,
- surface->surface, NULL, DDBLT_WAIT, NULL);
- if (hRes != DD_OK) /* FIXME: Is it really safe to continue past here ? */
- GST_CAT_WARNING_OBJECT (directdrawsink_debug, ddrawsink,
- "IDirectDrawSurface7_Blt (offscreen surface from buffer_alloc) "
- "returned %s", DDErrorString (hRes));
- }
-
- return GST_FLOW_OK;
-}
-
-static void
-gst_directdraw_sink_get_times (GstBaseSink * bsink, GstBuffer * buf,
- GstClockTime * start, GstClockTime * end)
-{
- GstDirectDrawSink *ddrawsink;
-
- ddrawsink = GST_DIRECTDRAW_SINK (bsink);
-
- if (GST_BUFFER_TIMESTAMP_IS_VALID (buf)) {
- *start = GST_BUFFER_TIMESTAMP (buf);
- if (GST_BUFFER_DURATION_IS_VALID (buf)) {
- *end = *start + GST_BUFFER_DURATION (buf);
- } else {
- if (ddrawsink->fps_n > 0) {
- *end = *start + (GST_SECOND * ddrawsink->fps_d) / ddrawsink->fps_n;
- }
- }
- }
-}
-
-/* Utility functions */
-
-/* this function fill a DDPIXELFORMAT using Gstreamer caps */
-static gboolean
-gst_ddrawvideosink_get_format_from_caps (GstDirectDrawSink * ddrawsink,
- GstCaps * caps, DDPIXELFORMAT * pPixelFormat)
-{
- GstStructure *structure = NULL;
- gboolean ret = TRUE;
-
- /* check params */
- g_return_val_if_fail (pPixelFormat, FALSE);
- g_return_val_if_fail (caps, FALSE);
-
- /* init structure */
- memset (pPixelFormat, 0, sizeof (DDPIXELFORMAT));
- pPixelFormat->dwSize = sizeof (DDPIXELFORMAT);
-
- if (!(structure = gst_caps_get_structure (caps, 0))) {
- GST_CAT_ERROR_OBJECT (directdrawsink_debug, ddrawsink,
- "can't get structure pointer from caps");
- return FALSE;
- }
-
- if (gst_structure_has_name (structure, "video/x-raw-rgb")) {
- gint depth, bitcount, bitmask, endianness;
-
- pPixelFormat->dwFlags = DDPF_RGB;
- ret &= gst_structure_get_int (structure, "bpp", &bitcount);
- pPixelFormat->dwRGBBitCount = bitcount;
- ret &= gst_structure_get_int (structure, "depth", &depth);
- ret &= gst_structure_get_int (structure, "red_mask", &bitmask);
- pPixelFormat->dwRBitMask = bitmask;
- ret &= gst_structure_get_int (structure, "green_mask", &bitmask);
- pPixelFormat->dwGBitMask = bitmask;
- ret &= gst_structure_get_int (structure, "blue_mask", &bitmask);
- pPixelFormat->dwBBitMask = bitmask;
-
- gst_structure_get_int (structure, "endianness", &endianness);
- if (endianness == G_BIG_ENDIAN) {
- endianness = G_LITTLE_ENDIAN;
- pPixelFormat->dwRBitMask = GUINT32_TO_BE (pPixelFormat->dwRBitMask);
- pPixelFormat->dwGBitMask = GUINT32_TO_BE (pPixelFormat->dwGBitMask);
- pPixelFormat->dwBBitMask = GUINT32_TO_BE (pPixelFormat->dwBBitMask);
- }
- } else if (gst_structure_has_name (structure, "video/x-raw-yuv")) {
- guint32 fourcc;
-
- pPixelFormat->dwFlags = DDPF_FOURCC;
- ret &= gst_structure_get_fourcc (structure, "format", &fourcc);
- pPixelFormat->dwFourCC = fourcc;
- } else {
- GST_CAT_WARNING_OBJECT (directdrawsink_debug, ddrawsink,
- "unknown caps name received %" GST_PTR_FORMAT, caps);
- ret = FALSE;
- }
-
- return ret;
-}
-
-/* This function centers the RECT of source surface to
-a dest surface and set the result RECT into result */
-static void
-gst_directdraw_sink_center_rect (GstDirectDrawSink * ddrawsink, RECT src,
- RECT dst, RECT * result)
-{
- gdouble src_ratio, dst_ratio;
- long src_width = src.right;
- long src_height = src.bottom;
- long dst_width = dst.right - dst.left;
- long dst_heigth = dst.bottom - dst.top;
- long result_width = 0, result_height = 0;
-
- g_return_if_fail (result != NULL);
-
- src_ratio = (gdouble) src_width / src_height;
- dst_ratio = (gdouble) dst_width / dst_heigth;
-
- if (src_ratio > dst_ratio) {
- /* new height */
- result_height = (long) (dst_width / src_ratio);
-
- result->left = dst.left;
- result->right = dst.right;
- result->top = dst.top + (dst_heigth - result_height) / 2;
- result->bottom = result->top + result_height;
-
- } else if (src_ratio < dst_ratio) {
- /* new width */
- result_width = (long) (dst_heigth * src_ratio);
-
- result->top = dst.top;
- result->bottom = dst.bottom;
- result->left = dst.left + (dst_width - result_width) / 2;
- result->right = result->left + result_width;
-
- } else {
- /* same ratio */
- memcpy (result, &dst, sizeof (RECT));
- }
-
- GST_CAT_INFO_OBJECT (directdrawsink_debug, ddrawsink,
- "source is %ldx%ld dest is %ldx%ld, result is %ldx%ld with x,y %ldx%ld",
- src_width, src_height, dst_width, dst_heigth,
- result->right - result->left, result->bottom - result->top, result->left,
- result->right);
-}
-
-/**
- * Get DirectDraw error message.
- * @hr: HRESULT code
- * Returns: Text representation of the error.
- */
-char *
-DDErrorString (HRESULT hr)
-{
- switch (hr) {
- case DDERR_ALREADYINITIALIZED:
- return "DDERR_ALREADYINITIALIZED";
- case DDERR_CANNOTATTACHSURFACE:
- return "DDERR_CANNOTATTACHSURFACE";
- case DDERR_CANNOTDETACHSURFACE:
- return "DDERR_CANNOTDETACHSURFACE";
- case DDERR_CURRENTLYNOTAVAIL:
- return "DDERR_CURRENTLYNOTAVAIL";
- case DDERR_EXCEPTION:
- return "DDERR_EXCEPTION";
- case DDERR_GENERIC:
- return "DDERR_GENERIC";
- case DDERR_HEIGHTALIGN:
- return "DDERR_HEIGHTALIGN";
- case DDERR_INCOMPATIBLEPRIMARY:
- return "DDERR_INCOMPATIBLEPRIMARY";
- case DDERR_INVALIDCAPS:
- return "DDERR_INVALIDCAPS";
- case DDERR_INVALIDCLIPLIST:
- return "DDERR_INVALIDCLIPLIST";
- case DDERR_INVALIDMODE:
- return "DDERR_INVALIDMODE";
- case DDERR_INVALIDOBJECT:
- return "DDERR_INVALIDOBJECT";
- case DDERR_INVALIDPARAMS:
- return "DDERR_INVALIDPARAMS";
- case DDERR_INVALIDPIXELFORMAT:
- return "DDERR_INVALIDPIXELFORMAT";
- case DDERR_INVALIDRECT:
- return "DDERR_INVALIDRECT";
- case DDERR_LOCKEDSURFACES:
- return "DDERR_LOCKEDSURFACES";
- case DDERR_NO3D:
- return "DDERR_NO3D";
- case DDERR_NOALPHAHW:
- return "DDERR_NOALPHAHW";
- case DDERR_NOCLIPLIST:
- return "DDERR_NOCLIPLIST";
- case DDERR_NOCOLORCONVHW:
- return "DDERR_NOCOLORCONVHW";
- case DDERR_NOCOOPERATIVELEVELSET:
- return "DDERR_NOCOOPERATIVELEVELSET";
- case DDERR_NOCOLORKEY:
- return "DDERR_NOCOLORKEY";
- case DDERR_NOCOLORKEYHW:
- return "DDERR_NOCOLORKEYHW";
- case DDERR_NODIRECTDRAWSUPPORT:
- return "DDERR_NODIRECTDRAWSUPPORT";
- case DDERR_NOEXCLUSIVEMODE:
- return "DDERR_NOEXCLUSIVEMODE";
- case DDERR_NOFLIPHW:
- return "DDERR_NOFLIPHW";
- case DDERR_NOGDI:
- return "DDERR_NOGDI";
- case DDERR_NOMIRRORHW:
- return "DDERR_NOMIRRORHW";
- case DDERR_NOTFOUND:
- return "DDERR_NOTFOUND";
- case DDERR_NOOVERLAYHW:
- return "DDERR_NOOVERLAYHW";
- case DDERR_NORASTEROPHW:
- return "DDERR_NORASTEROPHW";
- case DDERR_NOROTATIONHW:
- return "DDERR_NOROTATIONHW";
- case DDERR_NOSTRETCHHW:
- return "DDERR_NOSTRETCHHW";
- case DDERR_NOT4BITCOLOR:
- return "DDERR_NOT4BITCOLOR";
- case DDERR_NOT4BITCOLORINDEX:
- return "DDERR_NOT4BITCOLORINDEX";
- case DDERR_NOT8BITCOLOR:
- return "DDERR_NOT8BITCOLOR";
- case DDERR_NOTEXTUREHW:
- return "DDERR_NOTEXTUREHW";
- case DDERR_NOVSYNCHW:
- return "DDERR_NOVSYNCHW";
- case DDERR_NOZBUFFERHW:
- return "DDERR_NOZBUFFERHW";
- case DDERR_NOZOVERLAYHW:
- return "DDERR_NOZOVERLAYHW";
- case DDERR_OUTOFCAPS:
- return "DDERR_OUTOFCAPS";
- case DDERR_OUTOFMEMORY:
- return "DDERR_OUTOFMEMORY";
- case DDERR_OUTOFVIDEOMEMORY:
- return "DDERR_OUTOFVIDEOMEMORY";
- case DDERR_OVERLAYCANTCLIP:
- return "DDERR_OVERLAYCANTCLIP";
- case DDERR_OVERLAYCOLORKEYONLYONEACTIVE:
- return "DDERR_OVERLAYCOLORKEYONLYONEACTIVE";
- case DDERR_PALETTEBUSY:
- return "DDERR_PALETTEBUSY";
- case DDERR_COLORKEYNOTSET:
- return "DDERR_COLORKEYNOTSET";
- case DDERR_SURFACEALREADYATTACHED:
- return "DDERR_SURFACEALREADYATTACHED";
- case DDERR_SURFACEALREADYDEPENDENT:
- return "DDERR_SURFACEALREADYDEPENDENT";
- case DDERR_SURFACEBUSY:
- return "DDERR_SURFACEBUSY";
- case DDERR_CANTLOCKSURFACE:
- return "DDERR_CANTLOCKSURFACE";
- case DDERR_SURFACEISOBSCURED:
- return "DDERR_SURFACEISOBSCURED";
- case DDERR_SURFACELOST:
- return "DDERR_SURFACELOST";
- case DDERR_SURFACENOTATTACHED:
- return "DDERR_SURFACENOTATTACHED";
- case DDERR_TOOBIGHEIGHT:
- return "DDERR_TOOBIGHEIGHT";
- case DDERR_TOOBIGSIZE:
- return "DDERR_TOOBIGSIZE";
- case DDERR_TOOBIGWIDTH:
- return "DDERR_TOOBIGWIDTH";
- case DDERR_UNSUPPORTED:
- return "DDERR_UNSUPPORTED";
- case DDERR_UNSUPPORTEDFORMAT:
- return "DDERR_UNSUPPORTEDFORMAT";
- case DDERR_UNSUPPORTEDMASK:
- return "DDERR_UNSUPPORTEDMASK";
- case DDERR_VERTICALBLANKINPROGRESS:
- return "DDERR_VERTICALBLANKINPROGRESS";
- case DDERR_WASSTILLDRAWING:
- return "DDERR_WASSTILLDRAWING";
- case DDERR_XALIGN:
- return "DDERR_XALIGN";
- case DDERR_INVALIDDIRECTDRAWGUID:
- return "DDERR_INVALIDDIRECTDRAWGUID";
- case DDERR_DIRECTDRAWALREADYCREATED:
- return "DDERR_DIRECTDRAWALREADYCREATED";
- case DDERR_NODIRECTDRAWHW:
- return "DDERR_NODIRECTDRAWHW";
- case DDERR_PRIMARYSURFACEALREADYEXISTS:
- return "DDERR_PRIMARYSURFACEALREADYEXISTS";
- case DDERR_NOEMULATION:
- return "DDERR_NOEMULATION";
- case DDERR_REGIONTOOSMALL:
- return "DDERR_REGIONTOOSMALL";
- case DDERR_CLIPPERISUSINGHWND:
- return "DDERR_CLIPPERISUSINGHWND";
- case DDERR_NOCLIPPERATTACHED:
- return "DDERR_NOCLIPPERATTACHED";
- case DDERR_NOHWND:
- return "DDERR_NOHWND";
- case DDERR_HWNDSUBCLASSED:
- return "DDERR_HWNDSUBCLASSED";
- case DDERR_HWNDALREADYSET:
- return "DDERR_HWNDALREADYSET";
- case DDERR_NOPALETTEATTACHED:
- return "DDERR_NOPALETTEATTACHED";
- case DDERR_NOPALETTEHW:
- return "DDERR_NOPALETTEHW";
- case DDERR_BLTFASTCANTCLIP:
- return "DDERR_BLTFASTCANTCLIP";
- case DDERR_NOBLTHW:
- return "DDERR_NOBLTHW";
- case DDERR_NODDROPSHW:
- return "DDERR_NODDROPSHW";
- case DDERR_OVERLAYNOTVISIBLE:
- return "DDERR_OVERLAYNOTVISIBLE";
- case DDERR_NOOVERLAYDEST:
- return "DDERR_NOOVERLAYDEST";
- case DDERR_INVALIDPOSITION:
- return "DDERR_INVALIDPOSITION";
- case DDERR_NOTAOVERLAYSURFACE:
- return "DDERR_NOTAOVERLAYSURFACE";
- case DDERR_EXCLUSIVEMODEALREADYSET:
- return "DDERR_EXCLUSIVEMODEALREADYSET";
- case DDERR_NOTFLIPPABLE:
- return "DDERR_NOTFLIPPABLE";
- case DDERR_CANTDUPLICATE:
- return "DDERR_CANTDUPLICATE";
- case DDERR_NOTLOCKED:
- return "DDERR_NOTLOCKED";
- case DDERR_CANTCREATEDC:
- return "DDERR_CANTCREATEDC";
- case DDERR_NODC:
- return "DDERR_NODC";
- case DDERR_WRONGMODE:
- return "DDERR_WRONGMODE";
- case DDERR_IMPLICITLYCREATED:
- return "DDERR_IMPLICITLYCREATED";
- case DDERR_NOTPALETTIZED:
- return "DDERR_NOTPALETTIZED";
- case DDERR_UNSUPPORTEDMODE:
- return "DDERR_UNSUPPORTEDMODE";
- case DDERR_NOMIPMAPHW:
- return "DDERR_NOMIPMAPHW";
- case DDERR_INVALIDSURFACETYPE:
- return "DDERR_INVALIDSURFACETYPE";
- case DDERR_DCALREADYCREATED:
- return "DDERR_DCALREADYCREATED";
- case DDERR_CANTPAGELOCK:
- return "DDERR_CANTPAGELOCK";
- case DDERR_CANTPAGEUNLOCK:
- return "DDERR_CANTPAGEUNLOCK";
- case DDERR_NOTPAGELOCKED:
- return "DDERR_NOTPAGELOCKED";
- case DDERR_NOTINITIALIZED:
- return "DDERR_NOTINITIALIZED";
- }
- return "Unknown Error";
-}
-
-static gboolean
-gst_directdraw_sink_setup_ddraw (GstDirectDrawSink * ddrawsink)
-{
- gboolean bRet = TRUE;
- HRESULT hRes;
-
- /* create an instance of the ddraw object use DDCREATE_EMULATIONONLY as first
- * parameter to force Directdraw to use the hardware emulation layer */
- hRes = DirectDrawCreateEx ( /*DDCREATE_EMULATIONONLY */ 0,
- (void **) &ddrawsink->ddraw_object, &IID_IDirectDraw7, NULL);
- if (hRes != DD_OK || ddrawsink->ddraw_object == NULL) {
- GST_ELEMENT_ERROR (ddrawsink, RESOURCE, WRITE,
- ("Failed to create the DirectDraw object error=%s",
- DDErrorString (hRes)), (NULL));
- return FALSE;
- }
-
- /* set cooperative level */
- hRes = IDirectDraw7_SetCooperativeLevel (ddrawsink->ddraw_object,
- NULL, DDSCL_NORMAL);
- if (hRes != DD_OK) {
- GST_ELEMENT_ERROR (ddrawsink, RESOURCE, WRITE,
- ("Failed to set the set the cooperative level error=%s",
- DDErrorString (hRes)), (NULL));
- return FALSE;
- }
-
- /* setup the clipper object */
- hRes = IDirectDraw7_CreateClipper (ddrawsink->ddraw_object, 0,
- &ddrawsink->clipper, NULL);
-
- if (hRes == DD_OK && ddrawsink->video_window)
- IDirectDrawClipper_SetHWnd (ddrawsink->clipper, 0, ddrawsink->video_window);
-
- /* create our primary surface */
- if (!gst_directdraw_sink_check_primary_surface (ddrawsink))
- return FALSE;
-
- /* directdraw objects are setup */
- ddrawsink->setup = TRUE;
-
- return bRet;
-}
-
-long FAR PASCAL
-WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
-{
- switch (message) {
- case WM_ERASEBKGND:
- return TRUE;
- case WM_CLOSE:
- DestroyWindow (hWnd);
- case WM_DESTROY:
- PostQuitMessage (0);
- return 0;
- }
-
- return DefWindowProc (hWnd, message, wParam, lParam);
-}
-
-static gpointer
-gst_directdraw_sink_window_thread (GstDirectDrawSink * ddrawsink)
-{
- WNDCLASS WndClass;
- MSG msg;
-
- memset (&WndClass, 0, sizeof (WNDCLASS));
- WndClass.style = CS_HREDRAW | CS_VREDRAW;
- WndClass.hInstance = GetModuleHandle (NULL);
- WndClass.lpszClassName = "GStreamer-DirectDraw";
- WndClass.hbrBackground = (HBRUSH) GetStockObject (BLACK_BRUSH);
- WndClass.cbClsExtra = 0;
- WndClass.cbWndExtra = 0;
- WndClass.lpfnWndProc = WndProc;
- WndClass.hCursor = LoadCursor (NULL, IDC_ARROW);
- RegisterClass (&WndClass);
-
- ddrawsink->video_window = CreateWindowEx (0, "GStreamer-DirectDraw",
- "GStreamer-DirectDraw sink default window",
- WS_OVERLAPPEDWINDOW | WS_SIZEBOX, 0, 0, 640, 480, NULL, NULL,
- WndClass.hInstance, NULL);
- if (ddrawsink->video_window == NULL)
- return NULL;
-
- /* Set the clipper on that window */
- IDirectDrawClipper_SetHWnd (ddrawsink->clipper, 0, ddrawsink->video_window);
-
- /* signal application we created a window */
- gst_x_overlay_got_xwindow_id (GST_X_OVERLAY (ddrawsink),
- (gulong) ddrawsink->video_window);
-
- ReleaseSemaphore (ddrawsink->window_created_signal, 1, NULL);
-
- /* start message loop processing our default window messages */
- while (GetMessage (&msg, NULL, 0, 0) != FALSE) {
- TranslateMessage (&msg);
- DispatchMessage (&msg);
- }
-
- GST_CAT_LOG_OBJECT (directdrawsink_debug, ddrawsink,
- "our window received WM_QUIT or error.");
- /* The window could have changed, if it is not ours anymore we don't
- * overwrite the current video window with NULL */
- if (ddrawsink->our_video_window) {
- GST_OBJECT_LOCK (ddrawsink);
- ddrawsink->video_window = NULL;
- GST_OBJECT_UNLOCK (ddrawsink);
- }
-
- return NULL;
-}
-
-static gboolean
-gst_directdraw_sink_create_default_window (GstDirectDrawSink * ddrawsink)
-{
- ddrawsink->window_created_signal = CreateSemaphore (NULL, 0, 1, NULL);
- if (ddrawsink->window_created_signal == NULL)
- return FALSE;
-
- ddrawsink->window_thread = g_thread_create (
- (GThreadFunc) gst_directdraw_sink_window_thread, ddrawsink, TRUE, NULL);
-
- if (ddrawsink->window_thread == NULL)
- goto failed;
-
- /* wait maximum 10 seconds for windows creating */
- if (WaitForSingleObject (ddrawsink->window_created_signal,
- 10000) != WAIT_OBJECT_0)
- goto failed;
-
- CloseHandle (ddrawsink->window_created_signal);
- return TRUE;
-
-failed:
- CloseHandle (ddrawsink->window_created_signal);
- GST_ELEMENT_ERROR (ddrawsink, RESOURCE, WRITE,
- ("Error creating our default window"), (NULL));
-
- return FALSE;
-}
-
-static gboolean
-gst_directdraw_sink_check_primary_surface (GstDirectDrawSink * ddrawsink)
-{
- HRESULT hres;
- DDSURFACEDESC2 dd_surface_desc;
- DDSURFACEDESC2 *sd;
-
- /* if our primary surface already exist, check if it's not lost */
- if (ddrawsink->primary_surface) {
- if (IDirectDrawSurface7_IsLost (ddrawsink->primary_surface) == DD_OK) {
- /* no problem with our primary surface */
- return TRUE;
- } else {
- /* our primary surface was lost, try to restore it */
- if (IDirectDrawSurface7_Restore (ddrawsink->primary_surface) == DD_OK) {
- /* restore is done */
- GST_CAT_LOG_OBJECT (directdrawsink_debug, ddrawsink,
- "Our primary surface" " was restored after lost");
- return TRUE;
- } else {
- /* failed to restore our primary surface,
- * probably because the display mode was changed.
- * Release this surface and recreate a new one.
- */
- GST_CAT_LOG_OBJECT (directdrawsink_debug, ddrawsink,
- "Our primary surface"
- " was lost and display mode has changed. Destroy and recreate our surface.");
- IDirectDrawSurface7_Release (ddrawsink->primary_surface);
- ddrawsink->primary_surface = NULL;
-
- /* also release offscreen surface */
- IDirectDrawSurface7_Release (ddrawsink->offscreen_surface);
- ddrawsink->offscreen_surface = NULL;
- }
- }
- }
-
- /* create our primary surface */
- memset (&dd_surface_desc, 0, sizeof (dd_surface_desc));
- dd_surface_desc.dwSize = sizeof (dd_surface_desc);
- dd_surface_desc.dwFlags = DDSD_CAPS;
- dd_surface_desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
- sd = &dd_surface_desc;
- hres =
- IDirectDraw7_CreateSurface (ddrawsink->ddraw_object, (DDSURFACEDESC *) sd,
- &ddrawsink->primary_surface, NULL);
- if (hres != DD_OK) {
- GST_ELEMENT_ERROR (ddrawsink, RESOURCE, WRITE,
- ("Failed to create our primary surface error=%s", DDErrorString (hres)),
- (NULL));
- return FALSE;
- }
-
- /* attach our clipper object to the new primary surface */
- if (ddrawsink->clipper) {
- hres = IDirectDrawSurface7_SetClipper (ddrawsink->primary_surface,
- ddrawsink->clipper);
- }
-
- return TRUE;
-}
-
-static gboolean
-gst_directdraw_sink_check_offscreen_surface (GstDirectDrawSink * ddrawsink)
-{
- DDSURFACEDESC2 dd_surface_desc;
- DDSURFACEDESC2 *sd;
- HRESULT hres;
-
- /* if our offscreen surface already exist, check if it's not lost */
- if (ddrawsink->offscreen_surface) {
- if (IDirectDrawSurface7_IsLost (ddrawsink->offscreen_surface) == DD_OK) {
- /* no problem with our offscreen surface */
- return TRUE;
- } else {
- /* our offscreen surface was lost, try to restore it */
- if (IDirectDrawSurface7_Restore (ddrawsink->offscreen_surface) == DD_OK) {
- /* restore is done */
- GST_CAT_LOG_OBJECT (directdrawsink_debug, ddrawsink,
- "Our offscreen surface" " was restored after lost");
- return TRUE;
- } else {
- /* failed to restore our offscreen surface,
- * probably because the display mode was changed.
- * Release this surface and recreate a new one.
- */
- GST_CAT_LOG_OBJECT (directdrawsink_debug, ddrawsink,
- "Our offscreen surface"
- " was lost and display mode has changed. Destroy and recreate our surface.");
- IDirectDrawSurface7_Release (ddrawsink->offscreen_surface);
- ddrawsink->offscreen_surface = NULL;
- }
- }
- }
-
- memset (&dd_surface_desc, 0, sizeof (dd_surface_desc));
- dd_surface_desc.dwSize = sizeof (dd_surface_desc);
- dd_surface_desc.dwFlags =
- DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
- dd_surface_desc.dwHeight = ddrawsink->video_height;
- dd_surface_desc.dwWidth = ddrawsink->video_width;
- memcpy (&(dd_surface_desc.ddpfPixelFormat), &ddrawsink->dd_pixel_format,
- sizeof (DDPIXELFORMAT));
-
- dd_surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
- sd = &dd_surface_desc;
- hres =
- IDirectDraw7_CreateSurface (ddrawsink->ddraw_object, (DDSURFACEDESC *) sd,
- &ddrawsink->offscreen_surface, NULL);
- if (hres != DD_OK) {
- GST_CAT_WARNING_OBJECT (directdrawsink_debug, ddrawsink,
- "create_ddraw_surface:CreateSurface (offscreen surface for buffer_pool) failed %s",
- DDErrorString (hres));
- return FALSE;
- }
-
- ddrawsink->must_recreate_offscreen = FALSE;
-
- return TRUE;
-}
-
-static int
-gst_directdraw_sink_get_depth (LPDDPIXELFORMAT lpddpfPixelFormat)
-{
- gint order = 0, binary;
-
- binary =
- lpddpfPixelFormat->dwRBitMask | lpddpfPixelFormat->
- dwGBitMask | lpddpfPixelFormat->dwBBitMask | lpddpfPixelFormat->
- dwRGBAlphaBitMask;
- while (binary != 0) {
- if ((binary % 2) == 1)
- order++;
- binary = binary >> 1;
- }
- return order;
-}
-
-HRESULT WINAPI
-EnumModesCallback2 (LPDDSURFACEDESC lpDDSurfaceDesc, LPVOID lpContext)
-{
- GstDirectDrawSink *ddrawsink = (GstDirectDrawSink *) lpContext;
- GstCaps *format_caps = NULL;
- LPDDSURFACEDESC2 sd;
-
- if (!ddrawsink || !lpDDSurfaceDesc)
- return DDENUMRET_CANCEL;
-
- sd = (LPDDSURFACEDESC2) lpDDSurfaceDesc;
- if ((sd->dwFlags & DDSD_PIXELFORMAT) != DDSD_PIXELFORMAT) {
- GST_CAT_INFO_OBJECT (directdrawsink_debug, ddrawsink,
- "Display mode found with DDSD_PIXELFORMAT not set");
- return DDENUMRET_OK;
- }
-
- if ((sd->ddpfPixelFormat.dwFlags & DDPF_RGB) != DDPF_RGB)
- return DDENUMRET_OK;
-
- format_caps = gst_directdraw_sink_create_caps_from_surfacedesc (sd);
-
- if (format_caps) {
- gst_caps_append (ddrawsink->caps, format_caps);
- }
-
- return DDENUMRET_OK;
-}
-
-static GstCaps *
-gst_directdraw_sink_create_caps_from_surfacedesc (LPDDSURFACEDESC2 desc)
-{
- GstCaps *caps = NULL;
- gint endianness = G_LITTLE_ENDIAN;
- gint depth;
-
- if ((desc->ddpfPixelFormat.dwFlags & DDPF_RGB) != DDPF_RGB)
- return NULL;
-
- depth = gst_directdraw_sink_get_depth (&desc->ddpfPixelFormat);
-
- if (desc->ddpfPixelFormat.dwRGBBitCount == 24 ||
- desc->ddpfPixelFormat.dwRGBBitCount == 32) {
- /* ffmpegcolorspace handles 24/32 bpp RGB as big-endian. */
- endianness = G_BIG_ENDIAN;
- desc->ddpfPixelFormat.dwRBitMask =
- GUINT32_TO_BE (desc->ddpfPixelFormat.dwRBitMask);
- desc->ddpfPixelFormat.dwGBitMask =
- GUINT32_TO_BE (desc->ddpfPixelFormat.dwGBitMask);
- desc->ddpfPixelFormat.dwBBitMask =
- GUINT32_TO_BE (desc->ddpfPixelFormat.dwBBitMask);
- if (desc->ddpfPixelFormat.dwRGBBitCount == 24) {
- desc->ddpfPixelFormat.dwRBitMask >>= 8;
- desc->ddpfPixelFormat.dwGBitMask >>= 8;
- desc->ddpfPixelFormat.dwBBitMask >>= 8;
- }
- }
-
- caps = gst_caps_new_simple ("video/x-raw-rgb",
- "width", GST_TYPE_INT_RANGE, 1, G_MAXINT,
- "height", GST_TYPE_INT_RANGE, 1, G_MAXINT,
- "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1,
- "bpp", G_TYPE_INT, desc->ddpfPixelFormat.dwRGBBitCount,
- "depth", G_TYPE_INT, depth,
- "endianness", G_TYPE_INT, endianness,
- "red_mask", G_TYPE_INT, desc->ddpfPixelFormat.dwRBitMask,
- "green_mask", G_TYPE_INT, desc->ddpfPixelFormat.dwGBitMask,
- "blue_mask", G_TYPE_INT, desc->ddpfPixelFormat.dwBBitMask, NULL);
-
- return caps;
-}
-
-static GstCaps *
-gst_directdraw_sink_get_ddrawcaps (GstDirectDrawSink * ddrawsink)
-{
- HRESULT hRes = S_OK;
- DDCAPS ddcaps_hardware;
- DDCAPS ddcaps_emulation;
- GstCaps *format_caps = NULL;
-
- ddrawsink->caps = gst_caps_new_empty ();
- if (!ddrawsink->caps)
- return FALSE;
-
- /* get hardware caps */
- ddcaps_hardware.dwSize = sizeof (DDCAPS);
- ddcaps_emulation.dwSize = sizeof (DDCAPS);
- IDirectDraw7_GetCaps (ddrawsink->ddraw_object, &ddcaps_hardware,
- &ddcaps_emulation);
-
- /* we don't test for DDCAPS_BLTSTRETCH on the hardware as the directdraw
- * emulation layer can do it */
- if (!(ddcaps_hardware.dwCaps & DDCAPS_BLTFOURCC)) {
- DDSURFACEDESC2 surface_desc;
- DDSURFACEDESC2 *sd;
-
- GST_CAT_INFO_OBJECT (directdrawsink_debug, ddrawsink,
- "hardware doesn't support blit from one colorspace to another one. "
- "so we will create a caps with only the current display mode");
-
- /* save blit caps */
- ddrawsink->can_blit_between_colorspace = FALSE;
-
- surface_desc.dwSize = sizeof (surface_desc);
- sd = &surface_desc;
- hRes =
- IDirectDraw7_GetDisplayMode (ddrawsink->ddraw_object,
- (DDSURFACEDESC *) sd);
- if (hRes != DD_OK) {
- GST_ELEMENT_ERROR (ddrawsink, CORE, NEGOTIATION,
- ("Error getting the current display mode error=%s",
- DDErrorString (hRes)), (NULL));
- return NULL;
- }
-
- format_caps =
- gst_directdraw_sink_create_caps_from_surfacedesc (&surface_desc);
- if (format_caps) {
- gst_caps_append (ddrawsink->caps, format_caps);
- }
-
- GST_CAT_INFO_OBJECT (directdrawsink_debug, ddrawsink, "returning caps %s",
- gst_caps_to_string (ddrawsink->caps));
- return ddrawsink->caps;
- }
-
- GST_CAT_INFO_OBJECT (directdrawsink_debug, ddrawsink,
- "the hardware can blit from one colorspace to another, "
- "then enumerate the colorspace supported by the hardware");
-
- /* save blit caps */
- ddrawsink->can_blit_between_colorspace = TRUE;
-
- /* enumerate display modes exposed by directdraw object
- to know supported RGB modes */
- hRes =
- IDirectDraw7_EnumDisplayModes (ddrawsink->ddraw_object,
- DDEDM_REFRESHRATES, NULL, ddrawsink, EnumModesCallback2);
- if (hRes != DD_OK) {
- GST_ELEMENT_ERROR (ddrawsink, CORE, NEGOTIATION,
- ("Error enumerating display modes error=%s", DDErrorString (hRes)),
- (NULL));
-
- return NULL;
- }
-
- if (gst_caps_is_empty (ddrawsink->caps)) {
- gst_caps_unref (ddrawsink->caps);
- ddrawsink->caps = NULL;
- GST_ELEMENT_ERROR (ddrawsink, CORE, NEGOTIATION,
- ("No supported caps found."), (NULL));
- return NULL;
- }
-
- /*GST_CAT_INFO_OBJECT (directdrawsink_debug, ddrawsink, "returning caps %s",
- * gst_caps_to_string (ddrawsink->caps)); */
-
- return ddrawsink->caps;
-}
-
-/* Creates miniobject and our internal surface */
-static GstDDrawSurface *
-gst_directdraw_sink_surface_create (GstDirectDrawSink * ddrawsink,
- GstCaps * caps, size_t size)
-{
- GstDDrawSurface *surface = NULL;
- GstStructure *structure = NULL;
- gint pitch;
-
-#if 0
- HRESULT hRes;
-#endif
- DDSURFACEDESC2 surf_desc, surf_lock_desc;
-
- g_return_val_if_fail (GST_IS_DIRECTDRAW_SINK (ddrawsink), NULL);
-
- /*init structures */
- memset (&surf_desc, 0, sizeof (surf_desc));
- memset (&surf_lock_desc, 0, sizeof (surf_desc));
- surf_desc.dwSize = sizeof (surf_desc);
- surf_lock_desc.dwSize = sizeof (surf_lock_desc);
-
- /*create miniobject and initialize it */
- surface = (GstDDrawSurface *) gst_mini_object_new (GST_TYPE_DDRAWSURFACE);
- surface->locked = FALSE;
-
- structure = gst_caps_get_structure (caps, 0);
- if (!gst_structure_get_int (structure, "width", &surface->width) ||
- !gst_structure_get_int (structure, "height", &surface->height)) {
- GST_CAT_WARNING_OBJECT (directdrawsink_debug, ddrawsink,
- "failed getting geometry from caps %" GST_PTR_FORMAT, caps);
- }
-
- pitch = GST_ROUND_UP_8 (size / surface->height);
- if (!gst_ddrawvideosink_get_format_from_caps (ddrawsink, caps,
- &surface->dd_pixel_format)) {
- GST_CAT_WARNING_OBJECT (directdrawsink_debug, ddrawsink,
- "failed getting pixel format from caps %" GST_PTR_FORMAT, caps);
- }
-
- /* disable return of directdraw surface to buffer alloc because actually I
- * have no solution to handle display mode changes. The problem is that when
- * the display mode is changed surface's memory is freed then the upstream
- * filter would crash trying to write to this memory. Directdraw has a system
- * lock (DDLOCK_NOSYSLOCK to disable it) to prevent display mode changes
- * when a surface memory is locked but we need to disable this lock to return
- * multiple buffers (surfaces) and do not lock directdraw API calls.
- */
-#if 0
-/* if (ddrawsink->ddraw_object) {*/
- /* Creating an internal surface which will be used as GstBuffer, we used
- the detected pixel format and video dimensions */
-
- surf_desc.ddsCaps.dwCaps =
- DDSCAPS_OFFSCREENPLAIN /* | DDSCAPS_SYSTEMMEMORY */ ;
- surf_desc.dwFlags =
- DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT | DDSD_PITCH;
- surf_desc.dwHeight = surface->height;
- surf_desc.dwWidth = surface->width;
- memcpy (&(surf_desc.ddpfPixelFormat), &surface->dd_pixel_format,
- sizeof (DDPIXELFORMAT));
-
- hRes = IDirectDraw7_CreateSurface (ddrawsink->ddraw_object, &surf_desc,
- &surface->surface, NULL);
- if (hRes != DD_OK) {
- goto surface_pitch_bad;
- }
-
- /* Locking the surface to acquire the memory pointer.
- Use DDLOCK_NOSYSLOCK to disable syslock which can cause a deadlock
- if directdraw api is used while a buffer is lock */
-lock:
- hRes = IDirectDrawSurface7_Lock (surface->surface, NULL, &surf_lock_desc,
- DDLOCK_WAIT | DDLOCK_NOSYSLOCK, NULL);
- if (hRes == DDERR_SURFACELOST) {
- IDirectDrawSurface7_Restore (surface->surface);
- goto lock;
- }
- surface->locked = TRUE;
-
- if (surf_lock_desc.lPitch != pitch) {
- GST_CAT_INFO_OBJECT (directdrawsink_debug, ddrawsink,
- "DDraw stride/pitch %ld isn't as expected value %d, let's continue allocating a system memory buffer.",
- surf_lock_desc.lPitch, pitch);
-
- /*Unlock the surface as we will change it to use system memory with a GStreamer compatible pitch */
- hRes = IDirectDrawSurface_Unlock (surface->surface, NULL);
- goto surface_pitch_bad;
- }
- GST_BUFFER_DATA (surface) = surf_lock_desc.lpSurface;
- GST_BUFFER_SIZE (surface) = surf_lock_desc.lPitch * surface->height;
- GST_CAT_INFO_OBJECT (directdrawsink_debug, ddrawsink,
- "allocating a surface of %d bytes (stride=%ld)\n", size,
- surf_lock_desc.lPitch);
-
-surface_pitch_bad:
-#else
- GST_BUFFER (surface)->malloc_data = g_malloc (size);
- GST_BUFFER_DATA (surface) = GST_BUFFER (surface)->malloc_data;
- GST_BUFFER_SIZE (surface) = size;
- surface->surface = NULL;
- GST_CAT_INFO_OBJECT (directdrawsink_debug, ddrawsink,
- "allocating a system memory buffer of %d bytes", size);
-
-#endif
-
- /* Keep a ref to our sink */
- surface->ddrawsink = gst_object_ref (ddrawsink);
-
- return surface;
-}
-
-/* We are called from the finalize method of miniobject, the object will be
- * destroyed so we just have to clean our internal stuff */
-static void
-gst_directdraw_sink_surface_destroy (GstDirectDrawSink * ddrawsink,
- GstDDrawSurface * surface)
-{
- g_return_if_fail (GST_IS_DIRECTDRAW_SINK (ddrawsink));
-
- /* Release our internal surface */
- if (surface->surface) {
- if (surface->locked) {
- IDirectDrawSurface7_Unlock (surface->surface, NULL);
- surface->locked = FALSE;
- }
- IDirectDrawSurface7_Release (surface->surface);
- surface->surface = NULL;
- }
-
- if (GST_BUFFER (surface)->malloc_data) {
- g_free (GST_BUFFER (surface)->malloc_data);
- GST_BUFFER (surface)->malloc_data = NULL;
- }
-
- if (!surface->ddrawsink) {
- goto no_sink;
- }
-
- /* Release the ref to our sink */
- surface->ddrawsink = NULL;
- gst_object_unref (ddrawsink);
-
- return;
-
-no_sink:
- GST_WARNING ("no sink found in surface");
- return;
-}
-
-static gboolean
-gst_directdraw_sink_surface_check (GstDirectDrawSink * ddrawsink,
- GstDDrawSurface * surface)
-{
- if (!surface->surface)
- return TRUE; /* system memory buffer */
-
- if (IDirectDrawSurface7_IsLost (surface->surface) == DD_OK) {
- /* no problem with this surface */
- return TRUE;
- } else {
- /* this surface was lost, try to restore it */
- if (IDirectDrawSurface7_Restore (ddrawsink->offscreen_surface) == DD_OK) {
- /* restore is done */
- GST_CAT_LOG_OBJECT (directdrawsink_debug, ddrawsink, "A surface from our"
- " bufferpool was restored after lost");
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-static void
-gst_directdraw_sink_bufferpool_clear (GstDirectDrawSink * ddrawsink)
-{
- g_mutex_lock (ddrawsink->pool_lock);
- while (ddrawsink->buffer_pool) {
- GstDDrawSurface *surface = ddrawsink->buffer_pool->data;
-
- ddrawsink->buffer_pool = g_slist_delete_link (ddrawsink->buffer_pool,
- ddrawsink->buffer_pool);
- gst_directdraw_sink_surface_destroy (ddrawsink, surface);
- gst_buffer_unref (GST_BUFFER_CAST (surface));
- }
- g_mutex_unlock (ddrawsink->pool_lock);
-}
-
-static void
-gst_directdraw_sink_cleanup (GstDirectDrawSink * ddrawsink)
-{
- /* Post quit message and wait for our event window thread */
- if (ddrawsink->video_window && ddrawsink->our_video_window)
- PostMessage (ddrawsink->video_window, WM_QUIT, 0, 0);
-
- if (ddrawsink->window_thread) {
- g_thread_join (ddrawsink->window_thread);
- ddrawsink->window_thread = NULL;
- }
-
- if (ddrawsink->buffer_pool) {
- gst_directdraw_sink_bufferpool_clear (ddrawsink);
- ddrawsink->buffer_pool = NULL;
- }
-
- if (ddrawsink->offscreen_surface) {
- IDirectDrawSurface7_Release (ddrawsink->offscreen_surface);
- ddrawsink->offscreen_surface = NULL;
- }
-
- if (ddrawsink->clipper) {
- IDirectDrawClipper_Release (ddrawsink->clipper);
- ddrawsink->clipper = NULL;
- }
-
- if (ddrawsink->primary_surface) {
- IDirectDrawSurface7_Release (ddrawsink->primary_surface);
- ddrawsink->primary_surface = NULL;
- }
-
- if (ddrawsink->ddraw_object) {
- IDirectDraw7_Release (ddrawsink->ddraw_object);
- ddrawsink->ddraw_object = NULL;
- }
-
- if (ddrawsink->last_buffer) {
- gst_buffer_unref (ddrawsink->last_buffer);
- ddrawsink->last_buffer = NULL;
- }
-
- ddrawsink->setup = FALSE;
-}
diff --git a/sys/directdraw/gstdirectdrawsink.h b/sys/directdraw/gstdirectdrawsink.h
deleted file mode 100644
index 9cb5f788..00000000
--- a/sys/directdraw/gstdirectdrawsink.h
+++ /dev/null
@@ -1,141 +0,0 @@
-/* GStreamer
- * Copyright (C) 2005 Sebastien Moutte <sebastien@moutte.net>
- * Copyright (C) 2007 Pioneers of the Inevitable <songbird@songbirdnest.com>
- *
- * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * The development of this code was made possible due to the involvement
- * of Pioneers of the Inevitable, the creators of the Songbird Music player
- *
- */
-
-#ifndef __GST_DIRECTDRAWSINK_H__
-#define __GST_DIRECTDRAWSINK_H__
-
-#define DIRECTDRAW_VERSION 0x0700
-
-#include <gst/gst.h>
-#include <gst/video/gstvideosink.h>
-#include <gst/interfaces/xoverlay.h>
-
-#include <windows.h>
-#include <ddraw.h>
-
-G_BEGIN_DECLS
-
-#define GST_TYPE_DIRECTDRAW_SINK (gst_directdraw_sink_get_type())
-#define GST_DIRECTDRAW_SINK(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_DIRECTDRAW_SINK,GstDirectDrawSink))
-#define GST_DIRECTDRAW_SINK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_DIRECTDRAW_SINK,GstDirectDrawSinkClass))
-#define GST_IS_DIRECTDRAW_SINK(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_DIRECTDRAW_SINK))
-#define GST_IS_DIRECTDRAW_SINK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_DIRECTDRAW_SINK))
-typedef struct _GstDirectDrawSink GstDirectDrawSink;
-typedef struct _GstDirectDrawSinkClass GstDirectDrawSinkClass;
-
-#define GST_TYPE_DDRAWSURFACE (gst_ddrawsurface_get_type())
-#define GST_IS_DDRAWSURFACE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_DDRAWSURFACE))
-#define GST_DDRAWSURFACE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_DDRAWSURFACE, GstDDrawSurface))
-
-typedef struct _GstDDrawSurface GstDDrawSurface;
-
-struct _GstDDrawSurface
-{
- /* Extension of GstBuffer to store directdraw surfaces */
- GstBuffer buffer;
-
- /* directdraw surface */
- LPDIRECTDRAWSURFACE surface;
-
- /* surface dimensions */
- gint width;
- gint height;
-
- /*TRUE when surface is locked*/
- gboolean locked;
-
- /*TRUE when surface is using a system memory buffer
- (i'm using system memory when directdraw optimized pitch is not the same as the GStreamer one)*/
- gboolean system_memory;
-
- /* pixel format of the encapsulated surface */
- DDPIXELFORMAT dd_pixel_format;
-
- /* pointer to parent */
- GstDirectDrawSink *ddrawsink;
-};
-
-struct _GstDirectDrawSink
-{
- GstVideoSink videosink;
-
- /* directdraw offscreen surfaces pool */
- GSList *buffer_pool;
- GMutex *pool_lock;
-
- /* directdraw objects */
- LPDIRECTDRAW ddraw_object;
- LPDIRECTDRAWSURFACE primary_surface;
- LPDIRECTDRAWSURFACE offscreen_surface;
- LPDIRECTDRAWCLIPPER clipper;
-
- /* last buffer displayed (used for XOverlay interface expose method) */
- GstBuffer * last_buffer;
-
- /* directdraw caps */
- GstCaps *caps;
-
- /* video window management */
- HWND video_window;
- gboolean our_video_window;
- HANDLE window_created_signal;
-
- /* video properties */
- gint video_width, video_height;
- gint out_width, out_height;
- gint fps_n;
- gint fps_d;
-
- /* properties */
- gboolean keep_aspect_ratio;
-
- /*pixel format */
- DDPIXELFORMAT dd_pixel_format;
-
- /* thread processing our default window messages */
- GThread *window_thread;
-
- /* TRUE when directdraw object is set up */
- gboolean setup;
-
- /* TRUE if the hardware supports blitting from one colorspace to another */
- gboolean can_blit_between_colorspace;
-
- /* This flag is used to force re-creation of our offscreen surface.
- * It's needed when hardware doesn't support fourcc blit and the bit depth
- * of the current display mode changes.
- */
- gboolean must_recreate_offscreen;
-};
-
-struct _GstDirectDrawSinkClass
-{
- GstVideoSinkClass parent_class;
-};
-
-GType gst_directdraw_sink_get_type (void);
-
-G_END_DECLS
-
-#endif /* __GST_DIRECTDRAWSINK_H__ */