From 4b4b81c3e5eca940776492e0908b82c642fd3eb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Moutte?= Date: Thu, 5 Jan 2006 23:17:44 +0000 Subject: [MOVED FROM GOOD] added sys/directdraw added sys/directsound added win32/vs6/gst_plugins_bad.dsw added win32/vs6/libgstdirectsound.dsp ... Original commit message from CVS: 2006-01-05 Sebastien Moutte * added sys/directdraw * added sys/directsound * added win32/vs6/gst_plugins_bad.dsw * added win32/vs6/libgstdirectsound.dsp * added win32/vs6/libgstdirectdraw.dsp * added win32/common/config.h --- sys/directdraw/gstdirectdrawplugin.c | 42 + sys/directdraw/gstdirectdrawsink.c | 1733 ++++++++++++++++++++++++++++++++++ sys/directdraw/gstdirectdrawsink.h | 132 +++ 3 files changed, 1907 insertions(+) create mode 100644 sys/directdraw/gstdirectdrawplugin.c create mode 100644 sys/directdraw/gstdirectdrawsink.c create mode 100644 sys/directdraw/gstdirectdrawsink.h (limited to 'sys') diff --git a/sys/directdraw/gstdirectdrawplugin.c b/sys/directdraw/gstdirectdrawplugin.c new file mode 100644 index 00000000..69d79507 --- /dev/null +++ b/sys/directdraw/gstdirectdrawplugin.c @@ -0,0 +1,42 @@ +/* GStreamer +* Copyright (C) 2005 Sebastien Moutte +* +* 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. +*/ + +#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_NONE, + GST_TYPE_DIRECTDRAW_SINK)) + return FALSE; + + return TRUE; +} + +GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, + GST_VERSION_MINOR, + "directdraw", + "DIRECTDRAW plugin library", + plugin_init, VERSION, "LGPL", GST_PACKAGE, GST_ORIGIN) diff --git a/sys/directdraw/gstdirectdrawsink.c b/sys/directdraw/gstdirectdrawsink.c new file mode 100644 index 00000000..55a0d54a --- /dev/null +++ b/sys/directdraw/gstdirectdrawsink.c @@ -0,0 +1,1733 @@ +/* GStreamer +* Copyright (C) 2005 Sebastien Moutte +* +* Based on directfb video sink +* gstdirectdrawsink.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. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "gstdirectdrawsink.h" + +#include +#include +#include +#include + +GST_DEBUG_CATEGORY_STATIC (directdrawsink_debug); +#define GST_CAT_DEFAULT directdrawsink_debug + +/* elementfactory information */ +static GstElementDetails gst_directdrawsink_details = +GST_ELEMENT_DETAILS ("Video Sink (DIRECTDRAW)", + "Sink/Video", + "Output to a video card via DIRECTDRAW", + "Sebastien Moutte "); + +static void +_do_init (GType directdrawsink_type) +{ + GST_DEBUG_CATEGORY_INIT (directdrawsink_debug, "directdrawsink", 0, + "Direct draw sink"); +} + +GST_BOILERPLATE_FULL (GstDirectDrawSink, gst_directdrawsink, GstVideoSink, + GST_TYPE_VIDEO_SINK, _do_init); + +static void gst_directdrawsink_finalize (GObject * object); + +static void gst_directdrawsink_set_property (GObject * object, + guint prop_id, const GValue * value, GParamSpec * pspec); +static void gst_directdrawsink_get_property (GObject * object, + guint prop_id, GValue * value, GParamSpec * pspec); + +static GstCaps *gst_directdrawsink_get_caps (GstBaseSink * bsink); +static gboolean gst_directdrawsink_set_caps (GstBaseSink * bsink, + GstCaps * caps); + +static GstStateChangeReturn +gst_directdrawsink_change_state (GstElement * element, + GstStateChange transition); + +static GstFlowReturn +gst_directdrawsink_buffer_alloc (GstBaseSink * bsink, guint64 offset, + guint size, GstCaps * caps, GstBuffer ** buf); + +static void +gst_directdrawsink_get_times (GstBaseSink * bsink, GstBuffer * buf, + GstClockTime * start, GstClockTime * end); + +static GstFlowReturn +gst_directdrawsink_show_frame (GstBaseSink * bsink, GstBuffer * buf); + +static gboolean gst_directdrawsink_setup_ddraw (GstDirectDrawSink * ddrawsink); +static gboolean gst_directdrawsink_create_default_window (GstDirectDrawSink * + ddrawsink); +static gboolean gst_directdrawsink_create_ddraw_surfaces (GstDirectDrawSink * + ddrawsink); + +static GstCaps *gst_directdrawsink_get_ddrawcaps (GstDirectDrawSink * + ddrawsink); + +static void gst_directdrawsink_cleanup (GstDirectDrawSink * ddrawsink); +static void gst_directdrawsink_bufferpool_clear (GstDirectDrawSink * ddrawsink); + + +/*surfaces management functions*/ +static void +gst_directdrawsink_surface_destroy (GstDirectDrawSink * ddrawsink, + GstDDrawSurface * surface); + +static GstDDrawSurface *gst_directdrawsink_surface_create (GstDirectDrawSink * + ddrawsink, GstCaps * caps, size_t size); + +static GstStaticPadTemplate directdrawsink_sink_factory = + GST_STATIC_PAD_TEMPLATE ("sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_STATIC_CAPS ("video/x-raw-rgb, " + "bpp = (int) { 8, 16, 24, 32 }, " + "depth = (int) { 0, 8, 16, 24, 32 }, " + "endianness = (int) LITTLE_ENDIAN, " + "framerate = (fraction) [ 0, MAX ], " + "width = (int) [ 1, MAX ], " + "height = (int) [ 1, MAX ]" + "; " + "video/x-raw-yuv, " + "framerate = (fraction) [ 0, MAX ], " + "width = (int) [ 1, MAX ], " + "height = (int) [ 1, MAX ], " + "format = (fourcc) { YUY2, UYVY, YVU9, YV12, AYUV }") + ); + +enum +{ + PROP_0, + PROP_SURFACE, + PROP_WINDOW, + PROP_FULLSCREEN +}; + +/* Utility functions */ +static gboolean +gst_ddrawvideosink_get_format_from_caps (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))) + return FALSE; + + if (gst_structure_has_name (structure, "video/x-raw-rgb")) { + gint depth, bitcount, bitmask; + + 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; + } else if (gst_structure_has_name (structure, "video/x-raw-yuv")) { + gint fourcc; + + pPixelFormat->dwFlags = DDPF_FOURCC; + ret &= gst_structure_get_fourcc (structure, "format", &fourcc); + pPixelFormat->dwFourCC = fourcc; + } else { + GST_WARNING ("unknown caps name received %" GST_PTR_FORMAT, caps); + ret = FALSE; + } + + return ret; +} + +static GstCaps * +gst_ddrawvideosink_get_caps_from_format (DDPIXELFORMAT pixel_format) +{ + GstCaps *caps = NULL; + gint bpp, depth; + guint32 fourcc; + + if ((pixel_format.dwFlags & DDPF_RGB) == DDPF_RGB) { + bpp = pixel_format.dwRGBBitCount; + if (bpp != 32) + depth = bpp; + else { + if ((pixel_format.dwFlags & DDPF_ALPHAPREMULT) == DDPF_ALPHAPREMULT) + depth = 32; + else + depth = 24; + } + caps = gst_caps_new_simple ("video/x-raw-rgb", + "bpp", G_TYPE_INT, bpp, + "depth", G_TYPE_INT, depth, + "endianness", G_TYPE_INT, G_LITTLE_ENDIAN, NULL); + } + + if ((pixel_format.dwFlags & DDPF_YUV) == DDPF_YUV) { + fourcc = pixel_format.dwFourCC; + caps = gst_caps_new_simple ("video/x-raw-yuv", + "format", GST_TYPE_FOURCC, fourcc, NULL); + } + + g_assert (caps != NULL); + + return caps; +} + +static void +gst_directdrawsink_center_rect (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_DEBUG ("source is %dx%d dest is %dx%d, result is %dx%d with x,y %dx%d", + src_width, src_height, dst_width, dst_heigth, result_width, result_height, + result->left, result->right); +} + +/*subclass of GstBuffer which manages surfaces lifetime*/ +static void +gst_ddrawsurface_finalize (GstDDrawSurface * surface) +{ + GstDirectDrawSink *ddrawsink = NULL; + + g_return_if_fail (surface != NULL); + + 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_DEBUG ("destroy image as its size changed %dx%d vs current %dx%d", + surface->width, surface->height, + ddrawsink->video_width, ddrawsink->video_height); + gst_directdrawsink_surface_destroy (ddrawsink, surface); + + } else { + /* In that case we can reuse the image and add it to our image pool. */ + GST_DEBUG ("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_WARNING ("no sink found"); + return; +} + +static void +gst_ddrawsurface_init (GstDDrawSurface * surface, gpointer g_class) +{ + surface->surface = NULL; + surface->width = 0; + surface->height = 0; + surface->ddrawsink = NULL; + 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); + + mini_object_class->finalize = (GstMiniObjectFinalizeFunction) + 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 GstDirectDrawSink *global_ddrawsink = NULL; + +/*GType +gst_directdrawsink_get_type (void) +{ + static GType directdrawsink_type = 0; + + if (!directdrawsink_type) { + static const GTypeInfo directdrawsink_info = { + sizeof (GstDirectDrawSinkClass), + gst_directdrawsink_base_init, + NULL, + (GClassInitFunc) gst_directdrawsink_class_init, + NULL, + NULL, + sizeof (GstDirectDrawSink), + 0, + (GInstanceInitFunc) gst_directdrawsink_init, + }; + + directdrawsink_type = + g_type_register_static (GST_TYPE_VIDEO_SINK, "GstDirectDrawSink", + &directdrawsink_info, 0); + } + + return directdrawsink_type; +} +*/ +static void +gst_directdrawsink_base_init (gpointer g_class) +{ + GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); + + gst_element_class_set_details (element_class, &gst_directdrawsink_details); + + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&directdrawsink_sink_factory)); +} + +static void +gst_directdrawsink_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; + + gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_directdrawsink_finalize); + + gobject_class->get_property = + GST_DEBUG_FUNCPTR (gst_directdrawsink_get_property); + gobject_class->set_property = + GST_DEBUG_FUNCPTR (gst_directdrawsink_set_property); + + gstelement_class->change_state = + GST_DEBUG_FUNCPTR (gst_directdrawsink_change_state); + gstbasesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_directdrawsink_get_caps); + gstbasesink_class->set_caps = GST_DEBUG_FUNCPTR (gst_directdrawsink_set_caps); + gstbasesink_class->preroll = + GST_DEBUG_FUNCPTR (gst_directdrawsink_show_frame); + gstbasesink_class->render = GST_DEBUG_FUNCPTR (gst_directdrawsink_show_frame); + + gstbasesink_class->get_times = + GST_DEBUG_FUNCPTR (gst_directdrawsink_get_times); + gstbasesink_class->buffer_alloc = + GST_DEBUG_FUNCPTR (gst_directdrawsink_buffer_alloc); + + /*install properties */ + g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_FULLSCREEN, + g_param_spec_boolean ("fullscreen", "fullscreen", + "boolean to activate fullscreen", FALSE, G_PARAM_READWRITE)); + + /*extern window where we will display the video */ + g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_WINDOW, + g_param_spec_long ("window", "Window", + "The target window for video", G_MINLONG, G_MAXLONG, 0, + G_PARAM_WRITABLE)); + + /*extern surface where we will blit the video */ + g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_SURFACE, + g_param_spec_pointer ("surface", "Surface", + "The target surface for video", G_PARAM_WRITABLE)); + + /*should add a color_key property to permit applications to define the color used for overlays */ +} + +static void +gst_directdrawsink_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + GstDirectDrawSink *ddrawsink; + + ddrawsink = GST_DIRECTDRAW_SINK (object); + + switch (prop_id) { + case PROP_SURFACE: + ddrawsink->extern_surface = g_value_get_pointer (value); + break; + case PROP_WINDOW: + ddrawsink->video_window = (HWND) g_value_get_long (value); + ddrawsink->resize_window = FALSE; + break; + case PROP_FULLSCREEN: + if (g_value_get_boolean (value)) + ddrawsink->bFullScreen = TRUE; + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_directdrawsink_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) +{ + GstDirectDrawSink *ddrawsink; + + ddrawsink = GST_DIRECTDRAW_SINK (object); + + switch (prop_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_directdrawsink_finalize (GObject * object) +{ + GstDirectDrawSink *ddrawsink; + + ddrawsink = GST_DIRECTDRAW_SINK (object); + + if (ddrawsink->pool_lock) { + g_mutex_free (ddrawsink->pool_lock); + ddrawsink->pool_lock = NULL; + } + if (ddrawsink->setup) { + gst_directdrawsink_cleanup (ddrawsink); + } +} + +static void +gst_directdrawsink_init (GstDirectDrawSink * ddrawsink, + GstDirectDrawSinkClass * g_class) +{ + /*init members variables */ + ddrawsink->ddraw_object = NULL; + ddrawsink->primary_surface = NULL; + ddrawsink->overlays = NULL; + ddrawsink->clipper = NULL; + ddrawsink->extern_surface = NULL; + + /*video default values */ + ddrawsink->video_height = 0; + ddrawsink->video_width = 0; + ddrawsink->fps_n = 0; + ddrawsink->fps_d = 0; + + memset (&ddrawsink->dd_pixel_format, 0, sizeof (DDPIXELFORMAT)); + + ddrawsink->caps = NULL; + + ddrawsink->window_thread = NULL; + + ddrawsink->bUseOverlay = TRUE; + ddrawsink->color_key = 0; /*need to be a public property and may be we can enable overlays when this property is set ... */ + + ddrawsink->bFullScreen = FALSE; + ddrawsink->setup = FALSE; + + ddrawsink->display_modes = NULL; + ddrawsink->buffer_pool = NULL; + + ddrawsink->resize_window = TRUE; /*resize only our internal window to the video size */ + global_ddrawsink = ddrawsink; + + ddrawsink->pool_lock = g_mutex_new (); +} + +static GstCaps * +gst_directdrawsink_get_caps (GstBaseSink * bsink) +{ + GstDirectDrawSink *ddrawsink; + GstCaps *caps = NULL; + + ddrawsink = GST_DIRECTDRAW_SINK (bsink); + + if (!ddrawsink->setup) { + caps = gst_caps_copy (gst_pad_get_pad_template_caps (GST_VIDEO_SINK_PAD + (ddrawsink))); + + GST_DEBUG ("getcaps called and we are not setup yet, " + "returning template %" GST_PTR_FORMAT, caps); + } else { + /*if (ddrawsink->extern_surface) { + * We are not rendering to our own surface, returning this surface's + * pixel format * + GST_WARNING ("using extern surface"); + caps = gst_ddrawvideosink_get_caps_from_format (ddrawsink->dd_pixel_format); + } else */ + + /* i think we can't really use the format of the extern surface as the application owning the surface doesn't know + the format we will render. But we need to use overlays to overlay any format on the extern surface */ + caps = gst_caps_ref (ddrawsink->caps); + } + + return caps; +} + +static gboolean +gst_directdrawsink_set_caps (GstBaseSink * bsink, GstCaps * caps) +{ + GstDirectDrawSink *ddrawsink; + GstStructure *structure = NULL; + gboolean ret; + const GValue *fps; + + ddrawsink = GST_DIRECTDRAW_SINK (bsink); + + 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 (caps, + &ddrawsink->dd_pixel_format); + + if (!ret) + return FALSE; + + ddrawsink->fps_n = gst_value_get_fraction_numerator (fps); + ddrawsink->fps_d = gst_value_get_fraction_denominator (fps); + + if (ddrawsink->video_window && ddrawsink->resize_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); + } + + /*create overlays flipping chain and an offscreen surface */ + gst_directdrawsink_create_ddraw_surfaces (ddrawsink); + + return TRUE; +} + +static GstStateChangeReturn +gst_directdrawsink_change_state (GstElement * element, + GstStateChange transition) +{ + GstDirectDrawSink *ddrawsink; + + ddrawsink = GST_DIRECTDRAW_SINK (element); + + switch (transition) { + case GST_STATE_CHANGE_NULL_TO_READY: + GST_DEBUG ("GST_STATE_CHANGE_NULL_TO_READY\n"); + + if (ddrawsink->video_window == NULL && ddrawsink->extern_surface == NULL) + if (!gst_directdrawsink_create_default_window (ddrawsink)) + return GST_STATE_CHANGE_FAILURE; + + if (!gst_directdrawsink_setup_ddraw (ddrawsink)) + return GST_STATE_CHANGE_FAILURE; + + if (!(ddrawsink->caps = gst_directdrawsink_get_ddrawcaps (ddrawsink))) + return GST_STATE_CHANGE_FAILURE; + + break; + case GST_STATE_CHANGE_READY_TO_PAUSED: + GST_DEBUG ("GST_STATE_CHANGE_READY_TO_PAUSED\n"); + break; + case GST_STATE_CHANGE_PAUSED_TO_PLAYING: + GST_DEBUG ("GST_STATE_CHANGE_PAUSED_TO_PLAYING\n"); + break; + case GST_STATE_CHANGE_PLAYING_TO_PAUSED: + GST_DEBUG ("GST_STATE_CHANGE_PLAYING_TO_PAUSED\n"); + break; + case GST_STATE_CHANGE_PAUSED_TO_READY: + GST_DEBUG ("GST_STATE_CHANGE_PAUSED_TO_READY\n"); + + ddrawsink->fps_n = 0; + ddrawsink->fps_d = 1; + ddrawsink->video_width = 0; + ddrawsink->video_height = 0; + + if (ddrawsink->buffer_pool) + gst_directdrawsink_bufferpool_clear (ddrawsink); + + break; + case GST_STATE_CHANGE_READY_TO_NULL: + GST_DEBUG ("GST_STATE_CHANGE_READY_TO_NULL\n"); + + if (ddrawsink->setup) + gst_directdrawsink_cleanup (ddrawsink); + + break; + } + + return GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); +} + +/** + * 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 gint gtempcpt = 0; +static GstFlowReturn +gst_directdrawsink_buffer_alloc (GstBaseSink * bsink, guint64 offset, + guint size, GstCaps * caps, GstBuffer ** buf) +{ + GstDirectDrawSink *ddrawsink = NULL; + GstDDrawSurface *surface = NULL; + GstStructure *structure = NULL; + GstFlowReturn ret = GST_FLOW_OK; + + ddrawsink = GST_DIRECTDRAW_SINK (bsink); + GST_DEBUG ("a buffer of %d bytes was requested", size); + + structure = gst_caps_get_structure (caps, 0); + + 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 != ddrawsink->video_width) || + (surface->height != ddrawsink->video_height) || + (memcmp (&surface->dd_pixel_format, &ddrawsink->dd_pixel_format, + sizeof (DDPIXELFORMAT))) + ) { + gst_directdrawsink_surface_destroy (ddrawsink, surface); + surface = NULL; + } else { + /* We found a suitable surface */ + break; + } + } + } + + /* We haven't found anything, creating a new one */ + if (!surface) { + surface = gst_directdrawsink_surface_create (ddrawsink, caps, size); + gtempcpt++; + } + + /* Now we should have a surface, set appropriate caps on it */ + if (surface) { + gst_buffer_set_caps (GST_BUFFER (surface), caps); + } + + g_mutex_unlock (ddrawsink->pool_lock); + + *buf = GST_BUFFER (surface); + + return ret; +} + +static gboolean +gst_directdrawsink_fill_colorkey (LPDIRECTDRAWSURFACE surface, DWORD dwColorKey) +{ + DDBLTFX ddbfx; + + if (!surface) + return FALSE; + + ddbfx.dwSize = sizeof (DDBLTFX); + ddbfx.dwFillColor = dwColorKey; + + if (IDirectDrawSurface_Blt (surface, + NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbfx) == DD_OK) + return TRUE; + else + return FALSE; +} + + +static void +gst_directdrawsink_show_overlay (GstDirectDrawSink * ddrawsink) +{ + HRESULT hRes; + RECT destsurf_rect, src_rect; + POINT dest_surf_point; + DDOVERLAYFX ddofx; + LPDIRECTDRAWSURFACE surface = NULL; + + if (!ddrawsink || !ddrawsink->overlays) + return; + + if (ddrawsink->extern_surface) + surface = ddrawsink->extern_surface; + else + surface = ddrawsink->primary_surface; + + if (ddrawsink->extern_surface) { + destsurf_rect.left = 0; + destsurf_rect.top = 0; + destsurf_rect.right = ddrawsink->out_width; + destsurf_rect.bottom = ddrawsink->out_height; + } else { + 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); + } + + src_rect.top = 0; + src_rect.left = 0; + src_rect.bottom = ddrawsink->video_height; + src_rect.right = ddrawsink->video_width; + gst_directdrawsink_center_rect (src_rect, destsurf_rect, &destsurf_rect); + + gst_directdrawsink_fill_colorkey (surface, ddrawsink->color_key); + + ddofx.dwSize = sizeof (DDOVERLAYFX); + ddofx.dckDestColorkey.dwColorSpaceLowValue = ddrawsink->color_key; + ddofx.dckDestColorkey.dwColorSpaceHighValue = ddrawsink->color_key; + + hRes = IDirectDrawSurface_UpdateOverlay (ddrawsink->overlays, + NULL, surface, &destsurf_rect, DDOVER_KEYDESTOVERRIDE | DDOVER_SHOW, + &ddofx); +} + +static GstFlowReturn +gst_directdrawsink_show_frame (GstBaseSink * bsink, GstBuffer * buf) +{ + GstDirectDrawSink *ddrawsink; + HRESULT hRes; + + DDSURFACEDESC surf_desc; + RECT destsurf_rect, src_rect; + POINT dest_surf_point; + LPDIRECTDRAWSURFACE lpSurface = NULL; + + ddrawsink = GST_DIRECTDRAW_SINK (bsink); + + if (ddrawsink->extern_surface) { + destsurf_rect.left = 0; + destsurf_rect.top = 0; + destsurf_rect.right = ddrawsink->out_width; + destsurf_rect.bottom = ddrawsink->out_height; + } else { + 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); + } + + src_rect.top = 0; + src_rect.left = 0; + src_rect.bottom = ddrawsink->video_height; + src_rect.right = ddrawsink->video_width; + gst_directdrawsink_center_rect (src_rect, destsurf_rect, &destsurf_rect); + + if (ddrawsink->bUseOverlay) { + /*get the back buffer of the overlays flipping chain */ + DDSCAPS ddbackcaps; + + ddbackcaps.dwCaps = DDSCAPS_BACKBUFFER; + IDirectDrawSurface_GetAttachedSurface (ddrawsink->overlays, &ddbackcaps, + &lpSurface); + } else { + /*use our offscreen surface */ + lpSurface = ddrawsink->offscreen_surface; + } + + if (lpSurface == NULL) + return GST_FLOW_ERROR; + + if (!GST_IS_DDRAWSURFACE (buf) || + ((GST_IS_DDRAWSURFACE (buf)) && (GST_BUFFER (buf)->malloc_data))) { + + LPBYTE data = NULL; + guint src_pitch, line; + + /* Check for lost surface */ + if (IDirectDrawSurface_IsLost (lpSurface) == DDERR_SURFACELOST) { + IDirectDrawSurface_Restore (lpSurface); + } + + ZeroMemory (&surf_desc, sizeof (surf_desc)); + surf_desc.dwSize = sizeof (surf_desc); + + /* Lock the surface */ + hRes = + IDirectDrawSurface_Lock (lpSurface, NULL, &surf_desc, DDLOCK_WAIT, + NULL); + if (hRes != DD_OK) { + GST_DEBUG ("gst_directdrawsink_show_frame failed locking surface %s", + DDErrorString (hRes)); + return GST_FLOW_ERROR; + } + + /* Write data */ + data = surf_desc.lpSurface; + + /* Source video rowbytes */ + src_pitch = GST_BUFFER_SIZE (buf) / ddrawsink->video_height; + + /* Write each line respecting dest surface pitch */ + 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 = IDirectDrawSurface_Unlock (lpSurface, NULL); + if (hRes != DD_OK) { + GST_DEBUG ("gst_directdrawsink_show_frame failed unlocking surface %s", + DDErrorString (hRes)); + return GST_FLOW_ERROR; + } + + if (ddrawsink->bUseOverlay) { + /*Flip to front overlay */ + hRes = + IDirectDrawSurface_Flip (ddrawsink->overlays, lpSurface, DDFLIP_WAIT); + IDirectDrawSurface_Release (lpSurface); + lpSurface = NULL; + } else { + if (ddrawsink->extern_surface) { + if (ddrawsink->out_height == ddrawsink->video_height && + ddrawsink->out_width == ddrawsink->video_width) { + /*Fast blit to extern surface */ + hRes = IDirectDrawSurface_BltFast (ddrawsink->extern_surface, 0, 0, + lpSurface, NULL, DDBLTFAST_WAIT); + + } else { + /*blit to extern surface (Blt will scale the video the dest rect surface if needed) */ + hRes = + IDirectDrawSurface_Blt (ddrawsink->extern_surface, &destsurf_rect, + lpSurface, NULL, DDBLT_WAIT, NULL); + } + } else { + /*blit to primary surface ( Blt will scale the video the dest rect surface if needed */ + hRes = + IDirectDrawSurface_Blt (ddrawsink->primary_surface, &destsurf_rect, + lpSurface, NULL, DDBLT_WAIT, NULL); + } + } + } else { + + GstDDrawSurface *surface = NULL; + + surface = GST_DDRAWSURFACE (buf); + + /* Unlocking surface before blit */ + IDirectDrawSurface_Unlock (surface->surface, NULL); + surface->locked = FALSE; + + /* Check for lost surfaces */ + if (IDirectDrawSurface_IsLost (surface->surface) == DDERR_SURFACELOST) { + IDirectDrawSurface_Restore (surface->surface); + } + + if (ddrawsink->bUseOverlay) { + /* blit to the overlays back buffer */ + hRes = IDirectDrawSurface_Blt (lpSurface, NULL, + surface->surface, NULL, DDBLT_WAIT, NULL); + + hRes = IDirectDrawSurface_Flip (ddrawsink->overlays, NULL, DDFLIP_WAIT); + if (hRes != DD_OK) + GST_WARNING ("error flipping"); + + } else { + if (ddrawsink->extern_surface) { + /*blit to the extern surface */ + if (ddrawsink->out_height == ddrawsink->video_height && + ddrawsink->out_width == ddrawsink->video_width) { + /*Fast blit to extern surface */ + hRes = IDirectDrawSurface_BltFast (ddrawsink->extern_surface, 0, 0, + surface->surface, NULL, DDBLTFAST_WAIT); + + } else { + /*blit to extern surface (Blt will scale the video the dest rect surface if needed) */ + hRes = + IDirectDrawSurface_Blt (ddrawsink->extern_surface, &destsurf_rect, + surface->surface, NULL, DDBLT_WAIT, NULL); + } + } else { + /*blit to our primary surface */ + hRes = + IDirectDrawSurface_Blt (ddrawsink->primary_surface, &destsurf_rect, + surface->surface, NULL, DDBLT_WAIT, NULL); + if (hRes != DD_OK) + GST_WARNING ("IDirectDrawSurface_Blt returned %s", + DDErrorString (hRes)); + } + } + } + + if (ddrawsink->bUseOverlay) + gst_directdrawsink_show_overlay (ddrawsink); + + return GST_FLOW_OK; +} + +static gboolean +gst_directdrawsink_setup_ddraw (GstDirectDrawSink * ddrawsink) +{ + gboolean bRet = TRUE; + HRESULT hRes; + DWORD dwCooperativeLevel; + DDSURFACEDESC dd_surface_desc; + + /*create an instance of the ddraw object */ + hRes = DirectDrawCreate (NULL, &ddrawsink->ddraw_object, NULL); + if (hRes != DD_OK || ddrawsink->ddraw_object == NULL) + return FALSE; + + /*set cooperative level */ + if (ddrawsink->bFullScreen) + dwCooperativeLevel = DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN; + else + dwCooperativeLevel = DDSCL_NORMAL; + + hRes = IDirectDraw_SetCooperativeLevel (ddrawsink->ddraw_object, + ddrawsink->video_window, dwCooperativeLevel); + if (hRes != DD_OK) + bRet = FALSE; + + /*for fullscreen mode, setup display mode */ + if (ddrawsink->bFullScreen) { + hRes = IDirectDraw_SetDisplayMode (ddrawsink->ddraw_object, 640, 480, 32); + } + + if (!ddrawsink->extern_surface) { + /*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; + + hRes = IDirectDraw_CreateSurface (ddrawsink->ddraw_object, &dd_surface_desc, + &ddrawsink->primary_surface, NULL); + if (hRes != DD_OK) + bRet = FALSE; + + if (bRet == FALSE) { + if (ddrawsink->ddraw_object) { + IDirectDraw_Release (ddrawsink->ddraw_object); + GST_DEBUG ("CreateSurface failed with: %s", DDErrorString (hRes)); + return FALSE; + } + } + + hRes = IDirectDraw_CreateClipper (ddrawsink->ddraw_object, 0, + &ddrawsink->clipper, NULL); + if (hRes == DD_OK) { + hRes = IDirectDrawClipper_SetHWnd (ddrawsink->clipper, 0, + ddrawsink->video_window); + hRes = IDirectDrawSurface_SetClipper (ddrawsink->primary_surface, + ddrawsink->clipper); + } + } else { + DDSURFACEDESC desc_surface; + + desc_surface.dwSize = sizeof (DDSURFACEDESC); + + /*get extern surface size */ + hRes = IDirectDrawSurface_GetSurfaceDesc (ddrawsink->extern_surface, + &desc_surface); + if (hRes != DD_OK) { + /*error while retrieving ext surface description */ + return FALSE; + } + + ddrawsink->out_width = desc_surface.dwWidth; + ddrawsink->out_height = desc_surface.dwHeight; + + /*get extern surface pixel format (FIXME not needed if we are using overlays) */ + ddrawsink->dd_pixel_format.dwSize = sizeof (DDPIXELFORMAT); + hRes = IDirectDrawSurface_GetPixelFormat (ddrawsink->extern_surface, + &ddrawsink->dd_pixel_format); + if (hRes != DD_OK) { + /*error while retrieving ext surface pixel format */ + return FALSE; + } + + /*get specific caps if needed ... */ + } + + 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_WINDOWPOSCHANGED: + case WM_MOVE: + case WM_SIZE: + if(global_ddrawsink && global_ddrawsink->bUseOverlay) + gst_directdrawsink_show_overlay(global_ddrawsink); + break; + case WM_PAINT: + if(global_ddrawsink && global_ddrawsink->bUseOverlay) + { + if(global_ddrawsink->extern_surface) + gst_directdrawsink_fill_colorkey(global_ddrawsink->extern_surface, + global_ddrawsink->color_key); + else + gst_directdrawsink_fill_colorkey(global_ddrawsink->primary_surface, + global_ddrawsink->color_key); + } + break; +*/ + case WM_DESTROY: + PostQuitMessage (0); + break; + case WM_CLOSE: + DestroyWindow (hWnd); + return 0; + } + return DefWindowProc (hWnd, message, wParam, lParam); +} + +static gpointer +gst_directdrawsink_window_thread (GstDirectDrawSink * ddrawsink) +{ + WNDCLASS WndClass; + + 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 FALSE; + + ShowWindow (ddrawsink->video_window, SW_SHOW); + + /*start message loop processing our default window messages */ + while (1) { + MSG msg; + + if (!GetMessage (&msg, ddrawsink->video_window, 0, 0)) + break; + DispatchMessage (&msg); + } + + return NULL; +} + +static gboolean +gst_directdrawsink_create_default_window (GstDirectDrawSink * ddrawsink) +{ + ddrawsink->window_thread = g_thread_create ( + (GThreadFunc) gst_directdrawsink_window_thread, ddrawsink, TRUE, NULL); + + if (ddrawsink->window_thread == NULL) + return FALSE; + + /*TODO:wait for the window to be created with timeout */ + + return TRUE; +} + +static gboolean +gst_directdrawsink_create_ddraw_surfaces (GstDirectDrawSink * ddrawsink) +{ + DDSURFACEDESC dd_surface_desc; + HRESULT hRes; + + 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)); + + if (ddrawsink->bUseOverlay) { + /*create overlays flipping chain */ + dd_surface_desc.ddsCaps.dwCaps = + DDSCAPS_OVERLAY | DDSCAPS_VIDEOMEMORY | DDSCAPS_FLIP | DDSCAPS_COMPLEX; + dd_surface_desc.dwFlags |= DDSD_BACKBUFFERCOUNT; + dd_surface_desc.dwBackBufferCount = 1; + + hRes = IDirectDraw_CreateSurface (ddrawsink->ddraw_object, &dd_surface_desc, + &ddrawsink->overlays, NULL); + + if (hRes != DD_OK) { + GST_DEBUG ("create_ddraw_surfaces:CreateSurface(overlays) failed %s", + DDErrorString (hRes)); + return FALSE; + } + } else { + dd_surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; + + hRes = IDirectDraw_CreateSurface (ddrawsink->ddraw_object, &dd_surface_desc, + &ddrawsink->offscreen_surface, NULL); + + if (hRes != DD_OK) { + GST_DEBUG ("create_ddraw_surfaces:CreateSurface(offscreen) failed %s", + DDErrorString (hRes)); + return FALSE; + } + } + + return TRUE; +} + +static void +gst_directdrawsink_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; + } + } + } +} + +static int +gst_directdrawsink_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 (LPDDSURFACEDESC2 lpDDSurfaceDesc, LPVOID lpContext) +{ + GstDirectDrawSink *ddrawsink = (GstDirectDrawSink *) lpContext; + GstCaps *format_caps = NULL; + + if (!ddrawsink || !lpDDSurfaceDesc) + return DDENUMRET_CANCEL; + + if ((lpDDSurfaceDesc->dwFlags & DDSD_PIXELFORMAT) != DDSD_PIXELFORMAT) { + GST_DEBUG ("Display mode found with DDSD_PIXELFORMAT not set"); + return DDENUMRET_OK; + } + + if ((lpDDSurfaceDesc->ddpfPixelFormat.dwFlags & DDPF_RGB) != DDPF_RGB) + return DDENUMRET_OK; + + format_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, lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount, + "depth", G_TYPE_INT, + gst_directdrawsink_get_depth (&lpDDSurfaceDesc->ddpfPixelFormat), + "endianness", G_TYPE_INT, G_LITTLE_ENDIAN, "red_mask", G_TYPE_INT, + lpDDSurfaceDesc->ddpfPixelFormat.dwRBitMask, "green_mask", G_TYPE_INT, + lpDDSurfaceDesc->ddpfPixelFormat.dwGBitMask, "blue_mask", G_TYPE_INT, + lpDDSurfaceDesc->ddpfPixelFormat.dwBBitMask, NULL); + + if (format_caps) { + gst_caps_append (ddrawsink->caps, format_caps); + } + + return DDENUMRET_OK; +} + +static GstCaps * +gst_directdrawsink_get_ddrawcaps (GstDirectDrawSink * ddrawsink) +{ + HRESULT hRes = S_OK; + DWORD dwFourccCodeIndex = 0; + LPDWORD pdwFourccCodes = NULL; + DWORD dwNbFourccCodes = 0; + GstCaps *format_caps = NULL; + + ddrawsink->caps = gst_caps_new_empty (); + if (!ddrawsink->caps) + return FALSE; + + /*enumerate display modes exposed by directdraw object */ + hRes = + IDirectDraw_EnumDisplayModes (ddrawsink->ddraw_object, DDEDM_REFRESHRATES, + NULL, ddrawsink, EnumModesCallback2); + if (hRes != DD_OK) { + GST_DEBUG ("EnumDisplayModes returns: %s", DDErrorString (hRes)); + return FALSE; + } + + /* enumerate non-rgb modes exposed by directdraw object */ + IDirectDraw_GetFourCCCodes (ddrawsink->ddraw_object, &dwNbFourccCodes, NULL); + if (dwNbFourccCodes != 0) { + pdwFourccCodes = g_new0 (DWORD, dwNbFourccCodes); + if (!pdwFourccCodes) + return FALSE; + + if (FAILED (IDirectDraw_GetFourCCCodes (ddrawsink->ddraw_object, + &dwNbFourccCodes, pdwFourccCodes))) { + g_free (pdwFourccCodes); + return FALSE; + } + + for (dwFourccCodeIndex = 0; dwFourccCodeIndex < dwNbFourccCodes; + dwFourccCodeIndex++) { + /*support only yuv formats YUY2, UYVY, YVU9, YV12, AYUV */ + if (pdwFourccCodes[dwFourccCodeIndex] == mmioFOURCC ('Y', 'U', 'Y', '2') + || pdwFourccCodes[dwFourccCodeIndex] == mmioFOURCC ('U', 'Y', 'V', + 'Y') + || pdwFourccCodes[dwFourccCodeIndex] == mmioFOURCC ('Y', 'V', 'U', + '9') + || pdwFourccCodes[dwFourccCodeIndex] == mmioFOURCC ('Y', 'V', '1', + '2') + || pdwFourccCodes[dwFourccCodeIndex] == mmioFOURCC ('A', 'Y', 'U', + 'V') + ) { + format_caps = gst_caps_new_simple ("video/x-raw-yuv", + "format", GST_TYPE_FOURCC, pdwFourccCodes[dwFourccCodeIndex], + "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, NULL); + + if (format_caps) + gst_caps_append (ddrawsink->caps, format_caps); + } + } + + g_free (pdwFourccCodes); + } + + if (gst_caps_is_empty (ddrawsink->caps)) { + gst_caps_unref (ddrawsink->caps); + + GST_ELEMENT_ERROR (ddrawsink, STREAM, WRONG_TYPE, (NULL), + ("No supported format found")); + return NULL; + } + + return ddrawsink->caps; +} + +/* Creates miniobject and our internal surface */ +static GstDDrawSurface * +gst_directdrawsink_surface_create (GstDirectDrawSink * ddrawsink, + GstCaps * caps, size_t size) +{ + GstDDrawSurface *surface = NULL; + GstStructure *structure = NULL; + + HRESULT hRes; + DDSURFACEDESC 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_WARNING ("failed getting geometry from caps %" GST_PTR_FORMAT, caps); + } + + if (!gst_ddrawvideosink_get_format_from_caps (caps, + &surface->dd_pixel_format)) { + GST_WARNING ("failed getting pixel format from caps %" GST_PTR_FORMAT, + caps); + } + + if (ddrawsink->ddraw_object) { + /* Creating an internal surface which will be used as GstBuffer, we used + the detected pixel format and video dimensions */ + gint pitch = GST_ROUND_UP_8 (size / surface->height); + + surf_desc.lPitch = pitch; + + surf_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; + 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 = IDirectDraw_CreateSurface (ddrawsink->ddraw_object, &surf_desc, + &surface->surface, NULL); + if (hRes != DD_OK) { + gst_object_unref (surface); + surface = NULL; + goto beach; + } + + /* 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 */ + hRes = IDirectDrawSurface_Lock (surface->surface, NULL, &surf_lock_desc, + DDLOCK_WAIT | DDLOCK_NOSYSLOCK, NULL); + surface->locked = TRUE; + + if (surf_lock_desc.lPitch != pitch) { + GST_DEBUG + ("DDraw stride/pitch %d isn't as expected value %d, let's continue allocating buffer.", + surf_lock_desc.lPitch, pitch); + IDirectDrawSurface_Release (surface->surface); + goto surface_pitch_bad; + } + + GST_DEBUG ("allocating a surface of %d bytes (stride=%d)\n", size, + surf_lock_desc.lPitch); + GST_BUFFER_DATA (surface) = surf_lock_desc.lpSurface; + GST_BUFFER_SIZE (surface) = surf_lock_desc.lPitch * surface->height; + } else { + + surface_pitch_bad: + 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; + printf ("allocating a buffer of %d bytes\n", size); + } + + /* Keep a ref to our sink */ + surface->ddrawsink = gst_object_ref (ddrawsink); + +beach: + 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_directdrawsink_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) { + IDirectDrawSurface_Unlock (surface->surface, NULL); + surface->locked = FALSE; + } + IDirectDrawSurface_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 void +gst_directdrawsink_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_directdrawsink_surface_destroy (ddrawsink, surface); + } + g_mutex_unlock (ddrawsink->pool_lock); +} + +static void +gst_directdrawsink_cleanup (GstDirectDrawSink * ddrawsink) +{ + /* Post quit message and wait for our event window thread */ + if (ddrawsink->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_directdrawsink_bufferpool_clear (ddrawsink); + ddrawsink->buffer_pool = NULL; + } + + if (ddrawsink->display_modes) { + GSList *walk = ddrawsink->display_modes; + + while (walk) { + g_free (walk->data); + walk = g_slist_next (walk); + } + g_slist_free (ddrawsink->display_modes); + ddrawsink->display_modes = NULL; + } + + if (ddrawsink->overlays) { + IDirectDrawSurface_Release (ddrawsink->overlays); + ddrawsink->overlays = NULL; + } + + if (ddrawsink->offscreen_surface) { + IDirectDrawSurface_Release (ddrawsink->offscreen_surface); + ddrawsink->offscreen_surface = NULL; + } + + if (ddrawsink->clipper) { + IDirectDrawClipper_Release (ddrawsink->clipper); + ddrawsink->clipper = NULL; + } + + if (ddrawsink->primary_surface) { + IDirectDrawSurface_Release (ddrawsink->primary_surface); + ddrawsink->primary_surface = NULL; + } + + if (ddrawsink->ddraw_object) { + IDirectDraw_Release (ddrawsink->ddraw_object); + ddrawsink->ddraw_object = NULL; + } + + ddrawsink->setup = FALSE; +} diff --git a/sys/directdraw/gstdirectdrawsink.h b/sys/directdraw/gstdirectdrawsink.h new file mode 100644 index 00000000..7476eaac --- /dev/null +++ b/sys/directdraw/gstdirectdrawsink.h @@ -0,0 +1,132 @@ +/* GStreamer + * Copyright (C) 2005 Sebastien Moutte + * + * gstdirectdrawsink.h: + * + * 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. + */ + + +#ifndef __GST_DIRECTDRAWSINK_H__ +#define __GST_DIRECTDRAWSINK_H__ + +#define DIRECTDRAW_VERSION 0x0700 + +#include +#include +#include + +#include + +G_BEGIN_DECLS +#define GST_TYPE_DIRECTDRAW_SINK (gst_directdrawsink_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(obj) (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; + + gint width; + gint height; + gboolean locked; + + DDPIXELFORMAT dd_pixel_format; + + GstDirectDrawSink *ddrawsink; +}; + + +typedef struct _GstDDDDisplayMode GstDDDisplayMode; + +struct _GstDDDDisplayMode +{ + gint width; + gint height; + gint bpp; +}; + +struct _GstDirectDrawSink +{ + GstVideoSink videosink; + + /*directdraw offscreen surfaces pool */ + GSList *buffer_pool; + + GSList *display_modes; + //GstDDDisplayMode display_mode; + + /*directdraw objects */ + LPDIRECTDRAW ddraw_object; + LPDIRECTDRAWSURFACE primary_surface; + LPDIRECTDRAWSURFACE offscreen_surface; + LPDIRECTDRAWSURFACE overlays; + LPDIRECTDRAWCLIPPER clipper; + LPDIRECTDRAWSURFACE extern_surface; + + /*Directdraw caps */ + GstCaps *caps; + + /*handle of the video window */ + HWND video_window; + gboolean resize_window; + + /*video properties */ + gint video_width, video_height; + gint out_width, out_height; + //gdouble framerate; + gint fps_n; + gint fps_d; + + /*pixel format */ + DDPIXELFORMAT dd_pixel_format; + + GThread *window_thread; + + gboolean bUseOverlay; + gboolean bIsOverlayVisible; + gboolean bFullScreen; + gboolean setup; + + GMutex *pool_lock; + + guint color_key; + /*LPDIRECTDRAWSURFACE extern_surface; */ +}; + +struct _GstDirectDrawSinkClass +{ + GstVideoSinkClass parent_class; +}; + +GType gst_directdrawsink_get_type (void); + +G_END_DECLS +#endif /* __GST_DIRECTDRAWSINK_H__ */ -- cgit v1.2.1 From c7c875e85b1bf997b942907069295f7bbe49296f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Moutte?= Date: Fri, 3 Mar 2006 23:45:23 +0000 Subject: [MOVED FROM GOOD] sys/: sinks are now using GST_RANK_PRIMARY to be used with autodectection Original commit message from CVS: * sys/directdraw: * sys/directsound: sinks are now using GST_RANK_PRIMARY to be used with autodectection * win32/vs6: project files updated to fix some bugs * win32/vs7: * win32/vs8: vs7 and vs8 project files added --- sys/directdraw/gstdirectdrawplugin.c | 2 +- sys/directdraw/gstdirectdrawsink.c | 32 ++++++++++++++++++++++++-------- sys/directdraw/gstdirectdrawsink.h | 5 +++++ 3 files changed, 30 insertions(+), 9 deletions(-) (limited to 'sys') diff --git a/sys/directdraw/gstdirectdrawplugin.c b/sys/directdraw/gstdirectdrawplugin.c index 69d79507..de5452f3 100644 --- a/sys/directdraw/gstdirectdrawplugin.c +++ b/sys/directdraw/gstdirectdrawplugin.c @@ -28,7 +28,7 @@ static gboolean plugin_init (GstPlugin * plugin) { - if (!gst_element_register (plugin, "directdrawsink", GST_RANK_NONE, + if (!gst_element_register (plugin, "directdrawsink", GST_RANK_PRIMARY, GST_TYPE_DIRECTDRAW_SINK)) return FALSE; diff --git a/sys/directdraw/gstdirectdrawsink.c b/sys/directdraw/gstdirectdrawsink.c index 55a0d54a..2f837496 100644 --- a/sys/directdraw/gstdirectdrawsink.c +++ b/sys/directdraw/gstdirectdrawsink.c @@ -296,6 +296,8 @@ gst_ddrawsurface_init (GstDDrawSurface * surface, gpointer g_class) surface->width = 0; surface->height = 0; surface->ddrawsink = NULL; + surface->locked = FALSE; + surface->system_memory = FALSE; memset (&surface->dd_pixel_format, 0, sizeof (DDPIXELFORMAT)); } @@ -1184,9 +1186,10 @@ gst_directdrawsink_setup_ddraw (GstDirectDrawSink * ddrawsink) bRet = FALSE; /*for fullscreen mode, setup display mode */ - if (ddrawsink->bFullScreen) { +/* if (ddrawsink->bFullScreen) { hRes = IDirectDraw_SetDisplayMode (ddrawsink->ddraw_object, 640, 480, 32); } + */ if (!ddrawsink->extern_surface) { /*create our primary surface */ @@ -1309,8 +1312,6 @@ gst_directdrawsink_window_thread (GstDirectDrawSink * ddrawsink) if (ddrawsink->video_window == NULL) return FALSE; - ShowWindow (ddrawsink->video_window, SW_SHOW); - /*start message loop processing our default window messages */ while (1) { MSG msg; @@ -1422,7 +1423,7 @@ gst_directdrawsink_get_depth (LPDDPIXELFORMAT lpddpfPixelFormat) } HRESULT WINAPI -EnumModesCallback2 (LPDDSURFACEDESC2 lpDDSurfaceDesc, LPVOID lpContext) +EnumModesCallback2 (LPDDSURFACEDESC lpDDSurfaceDesc, LPVOID lpContext) { GstDirectDrawSink *ddrawsink = (GstDirectDrawSink *) lpContext; GstCaps *format_caps = NULL; @@ -1537,6 +1538,7 @@ gst_directdrawsink_surface_create (GstDirectDrawSink * ddrawsink, { GstDDrawSurface *surface = NULL; GstStructure *structure = NULL; + gint pitch; HRESULT hRes; DDSURFACEDESC surf_desc, surf_lock_desc; @@ -1559,6 +1561,8 @@ gst_directdrawsink_surface_create (GstDirectDrawSink * ddrawsink, GST_WARNING ("failed getting geometry from caps %" GST_PTR_FORMAT, caps); } + pitch = GST_ROUND_UP_8 (size / surface->height); + if (!gst_ddrawvideosink_get_format_from_caps (caps, &surface->dd_pixel_format)) { GST_WARNING ("failed getting pixel format from caps %" GST_PTR_FORMAT, @@ -1568,9 +1572,6 @@ gst_directdrawsink_surface_create (GstDirectDrawSink * ddrawsink, if (ddrawsink->ddraw_object) { /* Creating an internal surface which will be used as GstBuffer, we used the detected pixel format and video dimensions */ - gint pitch = GST_ROUND_UP_8 (size / surface->height); - - surf_desc.lPitch = pitch; surf_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; surf_desc.dwFlags = @@ -1600,7 +1601,9 @@ gst_directdrawsink_surface_create (GstDirectDrawSink * ddrawsink, GST_DEBUG ("DDraw stride/pitch %d isn't as expected value %d, let's continue allocating buffer.", surf_lock_desc.lPitch, pitch); - IDirectDrawSurface_Release (surface->surface); + + /*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; } @@ -1614,6 +1617,19 @@ gst_directdrawsink_surface_create (GstDirectDrawSink * ddrawsink, GST_BUFFER (surface)->malloc_data = g_malloc (size); GST_BUFFER_DATA (surface) = GST_BUFFER (surface)->malloc_data; GST_BUFFER_SIZE (surface) = size; + +/* surf_desc.dwSize = sizeof(DDSURFACEDESC); + surf_desc.dwFlags = DDSD_PITCH | DDSD_LPSURFACE | DDSD_HEIGHT | DDSD_WIDTH ||DDSD_PIXELFORMAT; + surf_desc.lpSurface = GST_BUFFER (surface)->malloc_data; + surf_desc.lPitch = pitch; + //surf_desc.dwHeight = surface->height; + surf_desc.dwWidth = surface->width; + hRes = IDirectDrawSurface7_SetSurfaceDesc(surface->surface, &surf_desc, 0); + printf("%\n", DDErrorString(hRes)); + + hRes = IDirectDrawSurface7_Lock (surface->surface, NULL, &surf_lock_desc, + DDLOCK_WAIT | DDLOCK_NOSYSLOCK, NULL); +*/ surface->surface = NULL; printf ("allocating a buffer of %d bytes\n", size); } diff --git a/sys/directdraw/gstdirectdrawsink.h b/sys/directdraw/gstdirectdrawsink.h index 7476eaac..c144f646 100644 --- a/sys/directdraw/gstdirectdrawsink.h +++ b/sys/directdraw/gstdirectdrawsink.h @@ -56,7 +56,12 @@ struct _GstDDrawSurface 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; DDPIXELFORMAT dd_pixel_format; -- cgit v1.2.1 From e291df2299862f81495def5c187ba8885396b0ff Mon Sep 17 00:00:00 2001 From: Thomas Vander Stichele Date: Sat, 1 Apr 2006 10:09:11 +0000 Subject: [MOVED FROM GOOD] rework build; add translations for v4l2 Original commit message from CVS: rework build; add translations for v4l2 --- sys/directdraw/gstdirectdrawplugin.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sys') diff --git a/sys/directdraw/gstdirectdrawplugin.c b/sys/directdraw/gstdirectdrawplugin.c index de5452f3..728551e0 100644 --- a/sys/directdraw/gstdirectdrawplugin.c +++ b/sys/directdraw/gstdirectdrawplugin.c @@ -39,4 +39,4 @@ GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, GST_VERSION_MINOR, "directdraw", "DIRECTDRAW plugin library", - plugin_init, VERSION, "LGPL", GST_PACKAGE, GST_ORIGIN) + plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN) -- cgit v1.2.1 From 3ab843a4c9b2637d20cf9b2d1ece4733dbd8832c Mon Sep 17 00:00:00 2001 From: Stefan Kost Date: Tue, 25 Apr 2006 21:56:38 +0000 Subject: [MOVED FROM GOOD] Define GstElementDetails as const and also static (when defined as global) Original commit message from CVS: * ext/amrwb/gstamrwbdec.c: * ext/amrwb/gstamrwbenc.c: * ext/amrwb/gstamrwbparse.c: * ext/arts/gst_arts.c: * ext/artsd/gstartsdsink.c: * ext/audiofile/gstafparse.c: * ext/audiofile/gstafsink.c: * ext/audiofile/gstafsrc.c: * ext/audioresample/gstaudioresample.c: * ext/bz2/gstbz2dec.c: * ext/bz2/gstbz2enc.c: * ext/cdaudio/gstcdaudio.c: * ext/directfb/dfbvideosink.c: * ext/divx/gstdivxdec.c: * ext/divx/gstdivxenc.c: * ext/dts/gstdtsdec.c: (gst_dtsdec_base_init): * ext/faac/gstfaac.c: (gst_faac_base_init): * ext/faad/gstfaad.c: * ext/gsm/gstgsmdec.c: * ext/gsm/gstgsmenc.c: * ext/hermes/gsthermescolorspace.c: * ext/ivorbis/vorbisfile.c: * ext/lcs/gstcolorspace.c: * ext/libfame/gstlibfame.c: * ext/libmms/gstmms.c: (gst_mms_base_init): * ext/musepack/gstmusepackdec.c: (gst_musepackdec_base_init): * ext/musicbrainz/gsttrm.c: (gst_musicbrainz_base_init): * ext/nas/nassink.c: (gst_nassink_base_init): * ext/neon/gstneonhttpsrc.c: * ext/sdl/sdlaudiosink.c: * ext/sdl/sdlvideosink.c: * ext/shout/gstshout.c: * ext/snapshot/gstsnapshot.c: * ext/sndfile/gstsf.c: * ext/swfdec/gstswfdec.c: * ext/tarkin/gsttarkindec.c: * ext/tarkin/gsttarkinenc.c: * ext/theora/theoradec.c: * ext/wavpack/gstwavpackdec.c: (gst_wavpack_dec_base_init): * ext/wavpack/gstwavpackparse.c: (gst_wavpack_parse_base_init): * ext/xvid/gstxviddec.c: * ext/xvid/gstxvidenc.c: * gst/cdxaparse/gstcdxaparse.c: (gst_cdxa_parse_base_init): * gst/cdxaparse/gstcdxastrip.c: (gst_cdxastrip_base_init): * gst/chart/gstchart.c: * gst/colorspace/gstcolorspace.c: * gst/deinterlace/gstdeinterlace.c: * gst/equalizer/gstiirequalizer.c: (gst_iir_equalizer_base_init): * gst/festival/gstfestival.c: * gst/filter/gstbpwsinc.c: * gst/filter/gstiir.c: * gst/filter/gstlpwsinc.c: * gst/freeze/gstfreeze.c: * gst/games/gstpuzzle.c: (gst_puzzle_base_init): * gst/librfb/gstrfbsrc.c: * gst/mixmatrix/mixmatrix.c: * gst/mpeg1sys/gstmpeg1systemencode.c: * gst/mpeg1videoparse/gstmp1videoparse.c: * gst/mpeg2sub/gstmpeg2subt.c: * gst/mpegaudioparse/gstmpegaudioparse.c: * gst/multifilesink/gstmultifilesink.c: * gst/overlay/gstoverlay.c: * gst/passthrough/gstpassthrough.c: * gst/playondemand/gstplayondemand.c: * gst/qtdemux/qtdemux.c: * gst/rtjpeg/gstrtjpegdec.c: * gst/rtjpeg/gstrtjpegenc.c: * gst/smooth/gstsmooth.c: * gst/smoothwave/gstsmoothwave.c: * gst/spectrum/gstspectrum.c: * gst/speed/gstspeed.c: * gst/stereo/gststereo.c: * gst/switch/gstswitch.c: * gst/tta/gstttadec.c: (gst_tta_dec_base_init): * gst/tta/gstttaparse.c: (gst_tta_parse_base_init): * gst/vbidec/gstvbidec.c: * gst/videocrop/gstvideocrop.c: * gst/videodrop/gstvideodrop.c: * gst/virtualdub/gstxsharpen.c: * gst/xingheader/gstxingmux.c: (gst_xing_mux_base_init): * gst/y4m/gsty4mencode.c: * sys/cdrom/gstcdplayer.c: * sys/directdraw/gstdirectdrawsink.c: * sys/directsound/gstdirectsoundsink.c: * sys/glsink/glimagesink.c: * sys/qcam/gstqcamsrc.c: * sys/v4l2/gstv4l2src.c: * sys/vcd/vcdsrc.c: (gst_vcdsrc_base_init): * sys/ximagesrc/ximagesrc.c: Define GstElementDetails as const and also static (when defined as global) --- sys/directdraw/gstdirectdrawsink.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sys') diff --git a/sys/directdraw/gstdirectdrawsink.c b/sys/directdraw/gstdirectdrawsink.c index 2f837496..237ebb9b 100644 --- a/sys/directdraw/gstdirectdrawsink.c +++ b/sys/directdraw/gstdirectdrawsink.c @@ -35,7 +35,7 @@ GST_DEBUG_CATEGORY_STATIC (directdrawsink_debug); #define GST_CAT_DEFAULT directdrawsink_debug /* elementfactory information */ -static GstElementDetails gst_directdrawsink_details = +static const GstElementDetails gst_directdrawsink_details = GST_ELEMENT_DETAILS ("Video Sink (DIRECTDRAW)", "Sink/Video", "Output to a video card via DIRECTDRAW", -- cgit v1.2.1 From e191ec4eb4590ca37bf7a9bad7ead6e4b29855a9 Mon Sep 17 00:00:00 2001 From: Stefan Kost Date: Thu, 1 Jun 2006 22:00:26 +0000 Subject: [MOVED FROM GOOD] Fix more gobject macros: obj<->klass, GstXXX<->GstXXXClass Original commit message from CVS: * ext/alsaspdif/alsaspdifsink.h: * ext/amrwb/gstamrwbdec.h: * ext/amrwb/gstamrwbenc.h: * ext/amrwb/gstamrwbparse.h: * ext/arts/gst_arts.h: * ext/artsd/gstartsdsink.h: * ext/audiofile/gstafparse.h: * ext/audiofile/gstafsink.h: * ext/audiofile/gstafsrc.h: * ext/audioresample/gstaudioresample.h: * ext/bz2/gstbz2dec.h: * ext/bz2/gstbz2enc.h: * ext/dirac/gstdiracdec.h: * ext/directfb/dfbvideosink.h: * ext/divx/gstdivxdec.h: * ext/divx/gstdivxenc.h: * ext/dts/gstdtsdec.h: * ext/faac/gstfaac.h: * ext/gsm/gstgsmdec.h: * ext/gsm/gstgsmenc.h: * ext/ivorbis/vorbisenc.h: * ext/libfame/gstlibfame.h: * ext/nas/nassink.h: * ext/neon/gstneonhttpsrc.h: * ext/polyp/polypsink.h: * ext/sdl/sdlaudiosink.h: * ext/sdl/sdlvideosink.h: * ext/shout/gstshout.h: * ext/snapshot/gstsnapshot.h: * ext/sndfile/gstsf.h: * ext/swfdec/gstswfdec.h: * ext/tarkin/gsttarkindec.h: * ext/tarkin/gsttarkinenc.h: * ext/theora/theoradec.h: * ext/wavpack/gstwavpackdec.h: * ext/wavpack/gstwavpackparse.h: * ext/xine/gstxine.h: * ext/xvid/gstxviddec.h: * ext/xvid/gstxvidenc.h: * gst/cdxaparse/gstcdxaparse.h: * gst/cdxaparse/gstcdxastrip.h: * gst/colorspace/gstcolorspace.h: * gst/festival/gstfestival.h: * gst/freeze/gstfreeze.h: * gst/gdp/gstgdpdepay.h: * gst/gdp/gstgdppay.h: * gst/modplug/gstmodplug.h: * gst/mpeg1sys/gstmpeg1systemencode.h: * gst/mpeg1videoparse/gstmp1videoparse.h: * gst/mpeg2sub/gstmpeg2subt.h: * gst/mpegaudioparse/gstmpegaudioparse.h: * gst/multifilesink/gstmultifilesink.h: * gst/overlay/gstoverlay.h: * gst/playondemand/gstplayondemand.h: * gst/qtdemux/qtdemux.h: * gst/rtjpeg/gstrtjpegdec.h: * gst/rtjpeg/gstrtjpegenc.h: * gst/smooth/gstsmooth.h: * gst/smoothwave/gstsmoothwave.h: * gst/spectrum/gstspectrum.h: * gst/speed/gstspeed.h: * gst/stereo/gststereo.h: * gst/switch/gstswitch.h: * gst/tta/gstttadec.h: * gst/tta/gstttaparse.h: * gst/videodrop/gstvideodrop.h: * gst/xingheader/gstxingmux.h: * sys/directdraw/gstdirectdrawsink.h: * sys/directsound/gstdirectsoundsink.h: * sys/dxr3/dxr3audiosink.h: * sys/dxr3/dxr3spusink.h: * sys/dxr3/dxr3videosink.h: * sys/qcam/gstqcamsrc.h: * sys/vcd/vcdsrc.h: Fix more gobject macros: obj<->klass, GstXXX<->GstXXXClass --- sys/directdraw/gstdirectdrawsink.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'sys') diff --git a/sys/directdraw/gstdirectdrawsink.h b/sys/directdraw/gstdirectdrawsink.h index c144f646..39d879eb 100644 --- a/sys/directdraw/gstdirectdrawsink.h +++ b/sys/directdraw/gstdirectdrawsink.h @@ -32,11 +32,11 @@ #include G_BEGIN_DECLS -#define GST_TYPE_DIRECTDRAW_SINK (gst_directdrawsink_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(obj) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_DIRECTDRAW_SINK)) +#define GST_TYPE_DIRECTDRAW_SINK (gst_directdrawsink_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; -- cgit v1.2.1 From 21c22dffd96ad9fe6fd62d44cfc91235932b6234 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Mon, 12 Jun 2006 10:53:26 +0000 Subject: [MOVED FROM GOOD] ext/libmms/gstmms.c: Set caps on outgoing buffers. Original commit message from CVS: * ext/libmms/gstmms.c: (gst_mms_create): Set caps on outgoing buffers. * sys/directdraw/gstdirectdrawsink.c: (gst_directdrawsink_init): Comment out unused global instance variable. --- sys/directdraw/gstdirectdrawsink.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'sys') diff --git a/sys/directdraw/gstdirectdrawsink.c b/sys/directdraw/gstdirectdrawsink.c index 237ebb9b..58a04c1b 100644 --- a/sys/directdraw/gstdirectdrawsink.c +++ b/sys/directdraw/gstdirectdrawsink.c @@ -334,7 +334,9 @@ gst_ddrawsurface_get_type (void) return _gst_ddrawsurface_type; } -static GstDirectDrawSink *global_ddrawsink = NULL; +/* FIXME: this is problematic if there is more than one sink instance at the + * same time, surely there exists a better solution than this? */ +/* static GstDirectDrawSink *global_ddrawsink = NULL; */ /*GType gst_directdrawsink_get_type (void) @@ -513,7 +515,7 @@ gst_directdrawsink_init (GstDirectDrawSink * ddrawsink, ddrawsink->buffer_pool = NULL; ddrawsink->resize_window = TRUE; /*resize only our internal window to the video size */ - global_ddrawsink = ddrawsink; + /* global_ddrawsink = ddrawsink; */ ddrawsink->pool_lock = g_mutex_new (); } -- cgit v1.2.1 From 622a56c9372c52835c3ebcaae8f939d9a87f3a5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Moutte?= Date: Mon, 24 Jul 2006 21:43:06 +0000 Subject: [MOVED FROM GOOD] sys/directsound/gstdirectsoundsink.*: Add an attenuation property that will directly attenuate the directsound buffer. Original commit message from CVS: * sys/directsound/gstdirectsoundsink.h: * sys/directsound/gstdirectsoundsink.c: Add an attenuation property that will directly attenuate the directsound buffer. Change the size of the directsound secondary buffer to a half second. Add more debug logs. Add a lock to protect dsound buffer write access. Fix a bad implementation of reset. * sys/directsound/gstdirectdrawsink.c: * sys/directsound/gstdirectdrawsink.h: Add a keep_aspect_ratio property. Do not use overlay if not supported. Add more debug logs. Remove overwrite of WM_ERASEBKGND message handling. It was not redrawing border when keep_aspect_ratio was enabled. * win32/common/config.h: update version waiting an auto-generated config.h --- sys/directdraw/gstdirectdrawsink.c | 231 +++++++++++++++++++++++-------------- sys/directdraw/gstdirectdrawsink.h | 13 ++- 2 files changed, 157 insertions(+), 87 deletions(-) (limited to 'sys') diff --git a/sys/directdraw/gstdirectdrawsink.c b/sys/directdraw/gstdirectdrawsink.c index 58a04c1b..fbccb80d 100644 --- a/sys/directdraw/gstdirectdrawsink.c +++ b/sys/directdraw/gstdirectdrawsink.c @@ -41,15 +41,8 @@ GST_ELEMENT_DETAILS ("Video Sink (DIRECTDRAW)", "Output to a video card via DIRECTDRAW", "Sebastien Moutte "); -static void -_do_init (GType directdrawsink_type) -{ - GST_DEBUG_CATEGORY_INIT (directdrawsink_debug, "directdrawsink", 0, - "Direct draw sink"); -} - -GST_BOILERPLATE_FULL (GstDirectDrawSink, gst_directdrawsink, GstVideoSink, - GST_TYPE_VIDEO_SINK, _do_init); +GST_BOILERPLATE (GstDirectDrawSink, gst_directdrawsink, GstVideoSink, + GST_TYPE_VIDEO_SINK); static void gst_directdrawsink_finalize (GObject * object); @@ -122,7 +115,8 @@ enum PROP_0, PROP_SURFACE, PROP_WINDOW, - PROP_FULLSCREEN + PROP_FULLSCREEN, + PROP_KEEP_ASPECT_RATIO }; /* Utility functions */ @@ -164,7 +158,8 @@ gst_ddrawvideosink_get_format_from_caps (GstCaps * caps, ret &= gst_structure_get_fourcc (structure, "format", &fourcc); pPixelFormat->dwFourCC = fourcc; } else { - GST_WARNING ("unknown caps name received %" GST_PTR_FORMAT, caps); + GST_CAT_WARNING (directdrawsink_debug, + "unknown caps name received %" GST_PTR_FORMAT, caps); ret = FALSE; } @@ -243,9 +238,11 @@ gst_directdrawsink_center_rect (RECT src, RECT dst, RECT * result) memcpy (result, &dst, sizeof (RECT)); } - GST_DEBUG ("source is %dx%d dest is %dx%d, result is %dx%d with x,y %dx%d", - src_width, src_height, dst_width, dst_heigth, result_width, result_height, - result->left, result->right); + GST_CAT_INFO (directdrawsink_debug, + "source is %dx%d dest is %dx%d, result is %dx%d with x,y %dx%d", + src_width, src_height, dst_width, dst_heigth, + result->right - result->left, result->bottom - result->top, result->left, + result->right); } /*subclass of GstBuffer which manages surfaces lifetime*/ @@ -266,14 +263,15 @@ gst_ddrawsurface_finalize (GstDDrawSurface * surface) (memcmp (&surface->dd_pixel_format, &ddrawsink->dd_pixel_format, sizeof (DDPIXELFORMAT)) != 0) ) { - GST_DEBUG ("destroy image as its size changed %dx%d vs current %dx%d", - surface->width, surface->height, - ddrawsink->video_width, ddrawsink->video_height); + GST_CAT_INFO (directdrawsink_debug, + "destroy image as its size changed %dx%d vs current %dx%d", + surface->width, surface->height, ddrawsink->video_width, + ddrawsink->video_height); gst_directdrawsink_surface_destroy (ddrawsink, surface); } else { /* In that case we can reuse the image and add it to our image pool. */ - GST_DEBUG ("recycling image in pool"); + GST_CAT_INFO (directdrawsink_debug, "recycling image in pool"); /* need to increment the refcount again to recycle */ gst_buffer_ref (GST_BUFFER (surface)); @@ -285,7 +283,7 @@ gst_ddrawsurface_finalize (GstDDrawSurface * surface) return; no_sink: - GST_WARNING ("no sink found"); + GST_CAT_WARNING (directdrawsink_debug, "no sink found"); return; } @@ -386,6 +384,9 @@ gst_directdrawsink_class_init (GstDirectDrawSinkClass * klass) gstbasesink_class = (GstBaseSinkClass *) klass; gstelement_class = (GstElementClass *) klass; + GST_DEBUG_CATEGORY_INIT (directdrawsink_debug, "directdrawsink", 0, + "Direct draw sink"); + gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_directdrawsink_finalize); gobject_class->get_property = @@ -422,6 +423,12 @@ gst_directdrawsink_class_init (GstDirectDrawSinkClass * klass) g_param_spec_pointer ("surface", "Surface", "The target surface for video", G_PARAM_WRITABLE)); + /*setup aspect ratio mode */ + g_object_class_install_property (G_OBJECT_CLASS (klass), + PROP_KEEP_ASPECT_RATIO, g_param_spec_boolean ("keep-aspect-ratio", + "keep-aspect-ratio", "boolean to video keep aspect ratio", FALSE, + G_PARAM_READWRITE)); + /*should add a color_key property to permit applications to define the color used for overlays */ } @@ -442,8 +449,10 @@ gst_directdrawsink_set_property (GObject * object, guint prop_id, ddrawsink->resize_window = FALSE; break; case PROP_FULLSCREEN: - if (g_value_get_boolean (value)) - ddrawsink->bFullScreen = TRUE; + /*ddrawsink->fullscreen = g_value_get_boolean (value); not working .... */ + break; + 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); @@ -460,6 +469,12 @@ gst_directdrawsink_get_property (GObject * object, guint prop_id, ddrawsink = GST_DIRECTDRAW_SINK (object); switch (prop_id) { + case PROP_FULLSCREEN: + g_value_set_boolean (value, ddrawsink->fullscreen); + break; + 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; @@ -505,19 +520,21 @@ gst_directdrawsink_init (GstDirectDrawSink * ddrawsink, ddrawsink->window_thread = NULL; - ddrawsink->bUseOverlay = TRUE; + ddrawsink->bUseOverlay = FALSE; ddrawsink->color_key = 0; /*need to be a public property and may be we can enable overlays when this property is set ... */ - ddrawsink->bFullScreen = FALSE; + ddrawsink->fullscreen = FALSE; ddrawsink->setup = FALSE; ddrawsink->display_modes = NULL; ddrawsink->buffer_pool = NULL; ddrawsink->resize_window = TRUE; /*resize only our internal window to the video size */ - /* global_ddrawsink = ddrawsink; */ ddrawsink->pool_lock = g_mutex_new (); + + ddrawsink->keep_aspect_ratio = TRUE; +/* ddrawsink->can_blit = TRUE;*/ } static GstCaps * @@ -532,8 +549,9 @@ gst_directdrawsink_get_caps (GstBaseSink * bsink) caps = gst_caps_copy (gst_pad_get_pad_template_caps (GST_VIDEO_SINK_PAD (ddrawsink))); - GST_DEBUG ("getcaps called and we are not setup yet, " - "returning template %" GST_PTR_FORMAT, caps); + GST_CAT_INFO (directdrawsink_debug, + "getcaps called and we are not setup yet, " "returning template %" + GST_PTR_FORMAT, caps); } else { /*if (ddrawsink->extern_surface) { * We are not rendering to our own surface, returning this surface's @@ -587,10 +605,25 @@ gst_directdrawsink_set_caps (GstBaseSink * bsink, GstCaps * caps) (GetSystemMetrics (SM_CYSIZEFRAME) * 2), SWP_SHOWWINDOW | SWP_NOMOVE); } - /*create overlays flipping chain and an offscreen surface */ - gst_directdrawsink_create_ddraw_surfaces (ddrawsink); + /*create overlays flipping chain */ + ret = gst_directdrawsink_create_ddraw_surfaces (ddrawsink); + if (!ret && ddrawsink->bUseOverlay) { + GST_CAT_WARNING (directdrawsink_debug, + "Can not create overlay surface, reverting to no overlay display"); + ddrawsink->bUseOverlay = FALSE; + ret = gst_directdrawsink_create_ddraw_surfaces (ddrawsink); + if (ret) { + return TRUE; + } - return TRUE; + /*could not create draw surfaces even with fallback, so leave + everything as is */ + ddrawsink->bUseOverlay = TRUE; + } + if (!ret) { + GST_CAT_ERROR (directdrawsink_debug, "Can not create ddraw surface"); + } + return ret; } static GstStateChangeReturn @@ -603,8 +636,6 @@ gst_directdrawsink_change_state (GstElement * element, switch (transition) { case GST_STATE_CHANGE_NULL_TO_READY: - GST_DEBUG ("GST_STATE_CHANGE_NULL_TO_READY\n"); - if (ddrawsink->video_window == NULL && ddrawsink->extern_surface == NULL) if (!gst_directdrawsink_create_default_window (ddrawsink)) return GST_STATE_CHANGE_FAILURE; @@ -617,16 +648,12 @@ gst_directdrawsink_change_state (GstElement * element, break; case GST_STATE_CHANGE_READY_TO_PAUSED: - GST_DEBUG ("GST_STATE_CHANGE_READY_TO_PAUSED\n"); break; case GST_STATE_CHANGE_PAUSED_TO_PLAYING: - GST_DEBUG ("GST_STATE_CHANGE_PAUSED_TO_PLAYING\n"); break; case GST_STATE_CHANGE_PLAYING_TO_PAUSED: - GST_DEBUG ("GST_STATE_CHANGE_PLAYING_TO_PAUSED\n"); break; case GST_STATE_CHANGE_PAUSED_TO_READY: - GST_DEBUG ("GST_STATE_CHANGE_PAUSED_TO_READY\n"); ddrawsink->fps_n = 0; ddrawsink->fps_d = 1; @@ -638,7 +665,6 @@ gst_directdrawsink_change_state (GstElement * element, break; case GST_STATE_CHANGE_READY_TO_NULL: - GST_DEBUG ("GST_STATE_CHANGE_READY_TO_NULL\n"); if (ddrawsink->setup) gst_directdrawsink_cleanup (ddrawsink); @@ -863,7 +889,6 @@ DDErrorString (HRESULT hr) } -static gint gtempcpt = 0; static GstFlowReturn gst_directdrawsink_buffer_alloc (GstBaseSink * bsink, guint64 offset, guint size, GstCaps * caps, GstBuffer ** buf) @@ -874,7 +899,8 @@ gst_directdrawsink_buffer_alloc (GstBaseSink * bsink, guint64 offset, GstFlowReturn ret = GST_FLOW_OK; ddrawsink = GST_DIRECTDRAW_SINK (bsink); - GST_DEBUG ("a buffer of %d bytes was requested", size); + GST_CAT_INFO (directdrawsink_debug, "a buffer of %d bytes was requested", + size); structure = gst_caps_get_structure (caps, 0); @@ -907,7 +933,6 @@ gst_directdrawsink_buffer_alloc (GstBaseSink * bsink, guint64 offset, /* We haven't found anything, creating a new one */ if (!surface) { surface = gst_directdrawsink_surface_create (ddrawsink, caps, size); - gtempcpt++; } /* Now we should have a surface, set appropriate caps on it */ @@ -971,11 +996,13 @@ gst_directdrawsink_show_overlay (GstDirectDrawSink * ddrawsink) OffsetRect (&destsurf_rect, dest_surf_point.x, dest_surf_point.y); } - src_rect.top = 0; - src_rect.left = 0; - src_rect.bottom = ddrawsink->video_height; - src_rect.right = ddrawsink->video_width; - gst_directdrawsink_center_rect (src_rect, destsurf_rect, &destsurf_rect); + if (ddrawsink->keep_aspect_ratio) { + src_rect.top = 0; + src_rect.left = 0; + src_rect.bottom = ddrawsink->video_height; + src_rect.right = ddrawsink->video_width; + gst_directdrawsink_center_rect (src_rect, destsurf_rect, &destsurf_rect); + } gst_directdrawsink_fill_colorkey (surface, ddrawsink->color_key); @@ -1014,11 +1041,14 @@ gst_directdrawsink_show_frame (GstBaseSink * bsink, GstBuffer * buf) OffsetRect (&destsurf_rect, dest_surf_point.x, dest_surf_point.y); } - src_rect.top = 0; - src_rect.left = 0; - src_rect.bottom = ddrawsink->video_height; - src_rect.right = ddrawsink->video_width; - gst_directdrawsink_center_rect (src_rect, destsurf_rect, &destsurf_rect); + 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_directdrawsink_center_rect (src_rect, destsurf_rect, &destsurf_rect); + } if (ddrawsink->bUseOverlay) { /*get the back buffer of the overlays flipping chain */ @@ -1054,7 +1084,8 @@ gst_directdrawsink_show_frame (GstBaseSink * bsink, GstBuffer * buf) IDirectDrawSurface_Lock (lpSurface, NULL, &surf_desc, DDLOCK_WAIT, NULL); if (hRes != DD_OK) { - GST_DEBUG ("gst_directdrawsink_show_frame failed locking surface %s", + GST_CAT_WARNING (directdrawsink_debug, + "gst_directdrawsink_show_frame failed locking surface %s", DDErrorString (hRes)); return GST_FLOW_ERROR; } @@ -1074,7 +1105,8 @@ gst_directdrawsink_show_frame (GstBaseSink * bsink, GstBuffer * buf) /* Unlock the surface */ hRes = IDirectDrawSurface_Unlock (lpSurface, NULL); if (hRes != DD_OK) { - GST_DEBUG ("gst_directdrawsink_show_frame failed unlocking surface %s", + GST_CAT_WARNING (directdrawsink_debug, + "gst_directdrawsink_show_frame failed unlocking surface %s", DDErrorString (hRes)); return GST_FLOW_ERROR; } @@ -1128,7 +1160,7 @@ gst_directdrawsink_show_frame (GstBaseSink * bsink, GstBuffer * buf) hRes = IDirectDrawSurface_Flip (ddrawsink->overlays, NULL, DDFLIP_WAIT); if (hRes != DD_OK) - GST_WARNING ("error flipping"); + GST_CAT_WARNING (directdrawsink_debug, "error flipping"); } else { if (ddrawsink->extern_surface) { @@ -1151,7 +1183,11 @@ gst_directdrawsink_show_frame (GstBaseSink * bsink, GstBuffer * buf) IDirectDrawSurface_Blt (ddrawsink->primary_surface, &destsurf_rect, surface->surface, NULL, DDBLT_WAIT, NULL); if (hRes != DD_OK) - GST_WARNING ("IDirectDrawSurface_Blt returned %s", + GST_CAT_WARNING (directdrawsink_debug, + "IDirectDrawSurface_Blt returned %s", DDErrorString (hRes)); + else + GST_CAT_INFO (directdrawsink_debug, + "allocated surface was blit to our primary", DDErrorString (hRes)); } } @@ -1171,27 +1207,43 @@ gst_directdrawsink_setup_ddraw (GstDirectDrawSink * ddrawsink) DWORD dwCooperativeLevel; DDSURFACEDESC dd_surface_desc; - /*create an instance of the ddraw object */ + /*UUID IDirectDraw7_ID; + + //IDirectDraw_QueryInterface() + /*create an instance of the ddraw object + hRes = DirectDrawCreateEx (DDCREATE_EMULATIONONLY, (void**)&ddrawsink->ddraw_object, + (REFIID)IID_IDirectDraw7, NULL); + */ hRes = DirectDrawCreate (NULL, &ddrawsink->ddraw_object, NULL); - if (hRes != DD_OK || ddrawsink->ddraw_object == NULL) + if (hRes != DD_OK || ddrawsink->ddraw_object == NULL) { + GST_CAT_ERROR (directdrawsink_debug, "DirectDrawCreate failed with: %s", + DDErrorString (hRes)); return FALSE; + } + /*get ddraw caps for the current hardware */ +/* ddrawsink->DDDriverCaps.dwSize = sizeof (DDCAPS); + ddrawsink->DDHELCaps.dwSize = sizeof (DDCAPS); + hRes = IDirectDraw_GetCaps (ddrawsink->ddraw_object, &ddrawsink->DDDriverCaps, &ddrawsink->DDHELCaps); +*/ /*set cooperative level */ - if (ddrawsink->bFullScreen) + if (ddrawsink->fullscreen) dwCooperativeLevel = DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN; else dwCooperativeLevel = DDSCL_NORMAL; hRes = IDirectDraw_SetCooperativeLevel (ddrawsink->ddraw_object, ddrawsink->video_window, dwCooperativeLevel); - if (hRes != DD_OK) + if (hRes != DD_OK) { + GST_CAT_ERROR (directdrawsink_debug, "SetCooperativeLevel failed with: %s", + DDErrorString (hRes)); bRet = FALSE; + } /*for fullscreen mode, setup display mode */ -/* if (ddrawsink->bFullScreen) { - hRes = IDirectDraw_SetDisplayMode (ddrawsink->ddraw_object, 640, 480, 32); + if (ddrawsink->fullscreen) { + hRes = IDirectDraw_SetDisplayMode (ddrawsink->ddraw_object, 1440, 900, 32); } - */ if (!ddrawsink->extern_surface) { /*create our primary surface */ @@ -1202,15 +1254,11 @@ gst_directdrawsink_setup_ddraw (GstDirectDrawSink * ddrawsink) hRes = IDirectDraw_CreateSurface (ddrawsink->ddraw_object, &dd_surface_desc, &ddrawsink->primary_surface, NULL); - if (hRes != DD_OK) - bRet = FALSE; - - if (bRet == FALSE) { - if (ddrawsink->ddraw_object) { - IDirectDraw_Release (ddrawsink->ddraw_object); - GST_DEBUG ("CreateSurface failed with: %s", DDErrorString (hRes)); - return FALSE; - } + if (hRes != DD_OK) { + GST_CAT_ERROR (directdrawsink_debug, + "CreateSurface (primary) failed with: %s", DDErrorString (hRes)); + IDirectDraw_Release (ddrawsink->ddraw_object); + return FALSE; } hRes = IDirectDraw_CreateClipper (ddrawsink->ddraw_object, 0, @@ -1221,6 +1269,7 @@ gst_directdrawsink_setup_ddraw (GstDirectDrawSink * ddrawsink) hRes = IDirectDrawSurface_SetClipper (ddrawsink->primary_surface, ddrawsink->clipper); } + } else { DDSURFACEDESC desc_surface; @@ -1243,6 +1292,9 @@ gst_directdrawsink_setup_ddraw (GstDirectDrawSink * ddrawsink) &ddrawsink->dd_pixel_format); if (hRes != DD_OK) { /*error while retrieving ext surface pixel format */ + GST_CAT_WARNING (directdrawsink_debug, + "GetPixelFormat (ddrawsink->extern_surface) failed with: %s", + DDErrorString (hRes)); return FALSE; } @@ -1258,8 +1310,8 @@ long FAR PASCAL WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { - case WM_ERASEBKGND: - return TRUE; + /*case WM_ERASEBKGND: + return TRUE; */ /* case WM_WINDOWPOSCHANGED: case WM_MOVE: case WM_SIZE: @@ -1367,18 +1419,24 @@ gst_directdrawsink_create_ddraw_surfaces (GstDirectDrawSink * ddrawsink) &ddrawsink->overlays, NULL); if (hRes != DD_OK) { - GST_DEBUG ("create_ddraw_surfaces:CreateSurface(overlays) failed %s", + GST_CAT_WARNING (directdrawsink_debug, + "create_ddraw_surfaces:CreateSurface(overlays) failed %s", DDErrorString (hRes)); return FALSE; + } else { + GST_CAT_INFO (directdrawsink_debug, + "An overlay surfaces flipping chain was created"); } } else { - dd_surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; + dd_surface_desc.ddsCaps.dwCaps = + DDSCAPS_OFFSCREENPLAIN /*|DDSCAPS_SYSTEMMEMORY */ ; hRes = IDirectDraw_CreateSurface (ddrawsink->ddraw_object, &dd_surface_desc, &ddrawsink->offscreen_surface, NULL); if (hRes != DD_OK) { - GST_DEBUG ("create_ddraw_surfaces:CreateSurface(offscreen) failed %s", + GST_CAT_WARNING (directdrawsink_debug, + "create_ddraw_surfaces:CreateSurface(offscreen) failed %s", DDErrorString (hRes)); return FALSE; } @@ -1434,7 +1492,8 @@ EnumModesCallback2 (LPDDSURFACEDESC lpDDSurfaceDesc, LPVOID lpContext) return DDENUMRET_CANCEL; if ((lpDDSurfaceDesc->dwFlags & DDSD_PIXELFORMAT) != DDSD_PIXELFORMAT) { - GST_DEBUG ("Display mode found with DDSD_PIXELFORMAT not set"); + GST_CAT_INFO (directdrawsink_debug, + "Display mode found with DDSD_PIXELFORMAT not set"); return DDENUMRET_OK; } @@ -1478,7 +1537,8 @@ gst_directdrawsink_get_ddrawcaps (GstDirectDrawSink * ddrawsink) IDirectDraw_EnumDisplayModes (ddrawsink->ddraw_object, DDEDM_REFRESHRATES, NULL, ddrawsink, EnumModesCallback2); if (hRes != DD_OK) { - GST_DEBUG ("EnumDisplayModes returns: %s", DDErrorString (hRes)); + GST_CAT_WARNING (directdrawsink_debug, "EnumDisplayModes returns: %s", + DDErrorString (hRes)); return FALSE; } @@ -1575,7 +1635,8 @@ gst_directdrawsink_surface_create (GstDirectDrawSink * ddrawsink, /* 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; + 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; @@ -1587,9 +1648,10 @@ gst_directdrawsink_surface_create (GstDirectDrawSink * ddrawsink, hRes = IDirectDraw_CreateSurface (ddrawsink->ddraw_object, &surf_desc, &surface->surface, NULL); if (hRes != DD_OK) { - gst_object_unref (surface); - surface = NULL; - goto beach; + /*gst_object_unref (surface); + surface = NULL; + goto beach; */ + goto surface_pitch_bad; } /* Locking the surface to acquire the memory pointer. @@ -1600,8 +1662,8 @@ gst_directdrawsink_surface_create (GstDirectDrawSink * ddrawsink, surface->locked = TRUE; if (surf_lock_desc.lPitch != pitch) { - GST_DEBUG - ("DDraw stride/pitch %d isn't as expected value %d, let's continue allocating buffer.", + GST_CAT_INFO (directdrawsink_debug, + "DDraw stride/pitch %d isn't as expected value %d, let's continue allocating buffer.", surf_lock_desc.lPitch, pitch); /*Unlock the surface as we will change it to use system memory with a GStreamer compatible pitch */ @@ -1609,7 +1671,8 @@ gst_directdrawsink_surface_create (GstDirectDrawSink * ddrawsink, goto surface_pitch_bad; } - GST_DEBUG ("allocating a surface of %d bytes (stride=%d)\n", size, + GST_CAT_INFO (directdrawsink_debug, + "allocating a surface of %d bytes (stride=%d)\n", size, surf_lock_desc.lPitch); GST_BUFFER_DATA (surface) = surf_lock_desc.lpSurface; GST_BUFFER_SIZE (surface) = surf_lock_desc.lPitch * surface->height; @@ -1633,7 +1696,7 @@ gst_directdrawsink_surface_create (GstDirectDrawSink * ddrawsink, DDLOCK_WAIT | DDLOCK_NOSYSLOCK, NULL); */ surface->surface = NULL; - printf ("allocating a buffer of %d bytes\n", size); + /*printf ("allocating a buffer of %d bytes\n", size); */ } /* Keep a ref to our sink */ diff --git a/sys/directdraw/gstdirectdrawsink.h b/sys/directdraw/gstdirectdrawsink.h index 39d879eb..f11c95ec 100644 --- a/sys/directdraw/gstdirectdrawsink.h +++ b/sys/directdraw/gstdirectdrawsink.h @@ -93,8 +93,11 @@ struct _GstDirectDrawSink LPDIRECTDRAWSURFACE primary_surface; LPDIRECTDRAWSURFACE offscreen_surface; LPDIRECTDRAWSURFACE overlays; - LPDIRECTDRAWCLIPPER clipper; - LPDIRECTDRAWSURFACE extern_surface; + LPDIRECTDRAWCLIPPER clipper; + + /*DDCAPS DDDriverCaps; + DDCAPS DDHELCaps; + gboolean can_blit;*/ /*Directdraw caps */ GstCaps *caps; @@ -110,6 +113,11 @@ struct _GstDirectDrawSink gint fps_n; gint fps_d; + /*properties*/ + LPDIRECTDRAWSURFACE extern_surface; + gboolean keep_aspect_ratio; + gboolean fullscreen; + /*pixel format */ DDPIXELFORMAT dd_pixel_format; @@ -117,7 +125,6 @@ struct _GstDirectDrawSink gboolean bUseOverlay; gboolean bIsOverlayVisible; - gboolean bFullScreen; gboolean setup; GMutex *pool_lock; -- cgit v1.2.1 From c807b70709f6bc292bfc6b4a3f6a098bf006fe44 Mon Sep 17 00:00:00 2001 From: Sergey Scobich Date: Wed, 1 Nov 2006 10:19:18 +0000 Subject: [MOVED FROM GOOD] sys/: Wait until the window is created before using it; guard unistd.h includes with HAVE_UNISTD_H. (#366523) Original commit message from CVS: Patch by: Sergey Scobich * sys/directdraw/gstdirectdrawsink.c: (gst_directdrawsink_window_thread), (gst_directdrawsink_create_default_window): * sys/directdraw/gstdirectdrawsink.h: * sys/directsound/gstdirectsoundsink.c: Wait until the window is created before using it; guard unistd.h includes with HAVE_UNISTD_H. (#366523) * win32/vs8/libgstdirectdraw.vcproj: * win32/vs8/libgstdirectsound.vcproj: Update project files. --- sys/directdraw/gstdirectdrawsink.c | 20 ++++++++++++++++++-- sys/directdraw/gstdirectdrawsink.h | 1 + 2 files changed, 19 insertions(+), 2 deletions(-) (limited to 'sys') diff --git a/sys/directdraw/gstdirectdrawsink.c b/sys/directdraw/gstdirectdrawsink.c index fbccb80d..ec449c7d 100644 --- a/sys/directdraw/gstdirectdrawsink.c +++ b/sys/directdraw/gstdirectdrawsink.c @@ -28,7 +28,9 @@ #include #include +#ifdef HAVE_UNISTD_H #include +#endif #include GST_DEBUG_CATEGORY_STATIC (directdrawsink_debug); @@ -1366,6 +1368,8 @@ gst_directdrawsink_window_thread (GstDirectDrawSink * ddrawsink) if (ddrawsink->video_window == NULL) return FALSE; + ReleaseSemaphore (ddrawsink->window_created_signal, 1, NULL); + /*start message loop processing our default window messages */ while (1) { MSG msg; @@ -1381,15 +1385,27 @@ gst_directdrawsink_window_thread (GstDirectDrawSink * ddrawsink) static gboolean gst_directdrawsink_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_directdrawsink_window_thread, ddrawsink, TRUE, NULL); if (ddrawsink->window_thread == NULL) - return FALSE; + goto failed; - /*TODO:wait for the window to be created with timeout */ + /* 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); + return FALSE; } static gboolean diff --git a/sys/directdraw/gstdirectdrawsink.h b/sys/directdraw/gstdirectdrawsink.h index f11c95ec..f9d4c865 100644 --- a/sys/directdraw/gstdirectdrawsink.h +++ b/sys/directdraw/gstdirectdrawsink.h @@ -104,6 +104,7 @@ struct _GstDirectDrawSink /*handle of the video window */ HWND video_window; + HANDLE window_created_signal; gboolean resize_window; /*video properties */ -- cgit v1.2.1 From 7a8bf9900c7c010d9fdd3ef6d29bdfa69e6986e9 Mon Sep 17 00:00:00 2001 From: Vincent Torri Date: Wed, 3 Jan 2007 19:54:33 +0000 Subject: [MOVED FROM GOOD] Add directdrawsink to build and dist it, so it gets built when compiling with MingW on win32 and the required headers... Original commit message from CVS: Patch by: Vincent Torri * configure.ac: * sys/Makefile.am: * sys/directdraw/Makefile.am: Add directdrawsink to build and dist it, so it gets built when compiling with MingW on win32 and the required headers and libraries are available (fixes: #392313). * sys/directdraw/gstdirectdrawsink.c: (gst_directdrawsink_center_rect), (gst_directdrawsink_show_frame), (gst_directdrawsink_setup_ddraw), (gst_directdrawsink_surface_create): Comment out some unused things and fix some printf format issues in order to avoid warnings when buildling with MingW (#392313). --- sys/directdraw/Makefile.am | 9 +++++++++ sys/directdraw/gstdirectdrawsink.c | 17 ++++++++++------- 2 files changed, 19 insertions(+), 7 deletions(-) create mode 100644 sys/directdraw/Makefile.am (limited to 'sys') diff --git a/sys/directdraw/Makefile.am b/sys/directdraw/Makefile.am new file mode 100644 index 00000000..999f026e --- /dev/null +++ b/sys/directdraw/Makefile.am @@ -0,0 +1,9 @@ +plugin_LTLIBRARIES = libgstdirectdrawsink.la + +libgstdirectdrawsink_la_SOURCES = gstdirectdrawsink.c gstdirectdrawplugin.c +libgstdirectdrawsink_la_CFLAGS = $(GST_CFLAGS) $(GST_BASE_CFLAGS) \ + $(GST_PLUGINS_BASE_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) diff --git a/sys/directdraw/gstdirectdrawsink.c b/sys/directdraw/gstdirectdrawsink.c index ec449c7d..ff1d8de4 100644 --- a/sys/directdraw/gstdirectdrawsink.c +++ b/sys/directdraw/gstdirectdrawsink.c @@ -168,6 +168,7 @@ gst_ddrawvideosink_get_format_from_caps (GstCaps * caps, return ret; } +/* static GstCaps * gst_ddrawvideosink_get_caps_from_format (DDPIXELFORMAT pixel_format) { @@ -201,6 +202,7 @@ gst_ddrawvideosink_get_caps_from_format (DDPIXELFORMAT pixel_format) return caps; } +*/ static void gst_directdrawsink_center_rect (RECT src, RECT dst, RECT * result) @@ -241,7 +243,7 @@ gst_directdrawsink_center_rect (RECT src, RECT dst, RECT * result) } GST_CAT_INFO (directdrawsink_debug, - "source is %dx%d dest is %dx%d, result is %dx%d with x,y %dx%d", + "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); @@ -1189,8 +1191,7 @@ gst_directdrawsink_show_frame (GstBaseSink * bsink, GstBuffer * buf) "IDirectDrawSurface_Blt returned %s", DDErrorString (hRes)); else GST_CAT_INFO (directdrawsink_debug, - "allocated surface was blit to our primary", - DDErrorString (hRes)); + "allocated surface was blit to our primary"); } } } @@ -1212,7 +1213,7 @@ gst_directdrawsink_setup_ddraw (GstDirectDrawSink * ddrawsink) /*UUID IDirectDraw7_ID; //IDirectDraw_QueryInterface() - /*create an instance of the ddraw object + create an instance of the ddraw object hRes = DirectDrawCreateEx (DDCREATE_EMULATIONONLY, (void**)&ddrawsink->ddraw_object, (REFIID)IID_IDirectDraw7, NULL); */ @@ -1679,7 +1680,7 @@ gst_directdrawsink_surface_create (GstDirectDrawSink * ddrawsink, if (surf_lock_desc.lPitch != pitch) { GST_CAT_INFO (directdrawsink_debug, - "DDraw stride/pitch %d isn't as expected value %d, let's continue allocating buffer.", + "DDraw stride/pitch %ld isn't as expected value %d, let's continue allocating buffer.", surf_lock_desc.lPitch, pitch); /*Unlock the surface as we will change it to use system memory with a GStreamer compatible pitch */ @@ -1688,7 +1689,7 @@ gst_directdrawsink_surface_create (GstDirectDrawSink * ddrawsink, } GST_CAT_INFO (directdrawsink_debug, - "allocating a surface of %d bytes (stride=%d)\n", size, + "allocating a surface of %d bytes (stride=%ld)\n", size, surf_lock_desc.lPitch); GST_BUFFER_DATA (surface) = surf_lock_desc.lpSurface; GST_BUFFER_SIZE (surface) = surf_lock_desc.lPitch * surface->height; @@ -1718,7 +1719,9 @@ gst_directdrawsink_surface_create (GstDirectDrawSink * ddrawsink, /* Keep a ref to our sink */ surface->ddrawsink = gst_object_ref (ddrawsink); -beach: + /* + beach: + */ return surface; } -- cgit v1.2.1 From 4dab9691c39ccf09da8ab487b0cd2a1e4101b951 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Moutte?= Date: Sun, 11 Feb 2007 15:26:49 +0000 Subject: [MOVED FROM GOOD] Makefile.am: Add win32 MANIFEST Original commit message from CVS: * Makefile.am: Add win32 MANIFEST * sys/directdraw/gstdirectdrawsink.c: * sys/directdraw/gstdirectdrawsink.h: Clear unused code and add comments. Remove yuv from template caps, it only supports RGB actually. Implement XOverlay interface and remove window and fullscreen properties. Add debug logs. Test for blit capabilities to return only the current colorspace if the hardware can't blit for one colorspace to another. * sys/directsound/gstdirectsoundsink.c: Add some debugs. * win32/MANIFEST: Add VS7 project files and solution. * win32/vs6/gst_plugins_bad.dsw: * win32/vs6/libgstdirectdraw.dsp: * win32/vs6/libgstdirectsound.dsp: * win32/vs6/libgstqtdemux.dsp: Update project files. --- sys/directdraw/gstdirectdrawsink.c | 584 +++++++++++++++++++++++-------------- sys/directdraw/gstdirectdrawsink.h | 54 ++-- 2 files changed, 385 insertions(+), 253 deletions(-) (limited to 'sys') diff --git a/sys/directdraw/gstdirectdrawsink.c b/sys/directdraw/gstdirectdrawsink.c index ff1d8de4..099be4e9 100644 --- a/sys/directdraw/gstdirectdrawsink.c +++ b/sys/directdraw/gstdirectdrawsink.c @@ -20,6 +20,20 @@ * Boston, MA 02111-1307, USA. */ +/** + * SECTION:element-directdrawsink + * + * + * + * DirectdrawSink renders video 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 drawable. + * If no Window ID was provided by the application, the element will create its + * own internal window and render into it. + * + * + */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -43,8 +57,10 @@ GST_ELEMENT_DETAILS ("Video Sink (DIRECTDRAW)", "Output to a video card via DIRECTDRAW", "Sebastien Moutte "); -GST_BOILERPLATE (GstDirectDrawSink, gst_directdrawsink, GstVideoSink, - GST_TYPE_VIDEO_SINK); +static void gst_directdrawsink_init_interfaces (GType type); + +GST_BOILERPLATE_FULL (GstDirectDrawSink, gst_directdrawsink, GstVideoSink, + GST_TYPE_VIDEO_SINK, gst_directdrawsink_init_interfaces); static void gst_directdrawsink_finalize (GObject * object); @@ -60,15 +76,12 @@ static gboolean gst_directdrawsink_set_caps (GstBaseSink * bsink, static GstStateChangeReturn gst_directdrawsink_change_state (GstElement * element, GstStateChange transition); - static GstFlowReturn gst_directdrawsink_buffer_alloc (GstBaseSink * bsink, guint64 offset, guint size, GstCaps * caps, GstBuffer ** buf); - static void gst_directdrawsink_get_times (GstBaseSink * bsink, GstBuffer * buf, GstClockTime * start, GstClockTime * end); - static GstFlowReturn gst_directdrawsink_show_frame (GstBaseSink * bsink, GstBuffer * buf); @@ -84,8 +97,12 @@ static GstCaps *gst_directdrawsink_get_ddrawcaps (GstDirectDrawSink * static void gst_directdrawsink_cleanup (GstDirectDrawSink * ddrawsink); static void gst_directdrawsink_bufferpool_clear (GstDirectDrawSink * ddrawsink); +static void +gst_directdrawsink_ddraw_put (GstDirectDrawSink * ddrawsink, + GstDDrawSurface * surface); + -/*surfaces management functions*/ +/* surfaces management functions */ static void gst_directdrawsink_surface_destroy (GstDirectDrawSink * ddrawsink, GstDDrawSurface * surface); @@ -98,29 +115,99 @@ static GstStaticPadTemplate directdrawsink_sink_factory = GST_PAD_SINK, GST_PAD_ALWAYS, GST_STATIC_CAPS ("video/x-raw-rgb, " - "bpp = (int) { 8, 16, 24, 32 }, " - "depth = (int) { 0, 8, 16, 24, 32 }, " - "endianness = (int) LITTLE_ENDIAN, " "framerate = (fraction) [ 0, MAX ], " - "width = (int) [ 1, MAX ], " - "height = (int) [ 1, MAX ]" - "; " - "video/x-raw-yuv, " + "width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ]" +/* "; " + "video/x-raw-yuv, " "framerate = (fraction) [ 0, MAX ], " "width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ], " - "format = (fourcc) { YUY2, UYVY, YVU9, YV12, AYUV }") + "format = (fourcc) YV12" +*/ + ) ); enum { PROP_0, PROP_SURFACE, - PROP_WINDOW, - PROP_FULLSCREEN, PROP_KEEP_ASPECT_RATIO }; +/* interfaces stuff */ +static gboolean +gst_directdrawsink_interface_supported (GstImplementsInterface * iface, + GType type) +{ + g_assert (type == GST_TYPE_X_OVERLAY); + return TRUE; +} + +static void +gst_directdrawsink_interface_init (GstImplementsInterfaceClass * klass) +{ + klass->supported = gst_directdrawsink_interface_supported; +} + +static void +gst_directdrawsink_set_window_id (GstXOverlay * overlay, ULONG window_id) +{ + GstDirectDrawSink *ddrawsink = GST_DIRECTDRAW_SINK (overlay); + + /* check if we are already using this window id */ + if (ddrawsink->video_window == (HWND) window_id) + return; + + if (window_id) { + HRESULT hres; + + 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); + } + } +} + +static void +gst_directdrawsink_expose (GstXOverlay * overlay) +{ + GstDirectDrawSink *ddrawsink = GST_DIRECTDRAW_SINK (overlay); + + gst_directdrawsink_show_frame (GST_BASE_SINK (ddrawsink), NULL); +} + +static void +gst_directdrawsink_xoverlay_interface_init (GstXOverlayClass * iface) +{ + iface->set_xwindow_id = gst_directdrawsink_set_window_id; + iface->expose = gst_directdrawsink_expose; +} + +static void +gst_directdrawsink_init_interfaces (GType type) +{ + static const GInterfaceInfo iface_info = { + (GInterfaceInitFunc) gst_directdrawsink_interface_init, + NULL, + NULL, + }; + + static const GInterfaceInfo xoverlay_info = { + (GInterfaceInitFunc) gst_directdrawsink_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); +} + + /* Utility functions */ static gboolean gst_ddrawvideosink_get_format_from_caps (GstCaps * caps, @@ -137,11 +224,14 @@ gst_ddrawvideosink_get_format_from_caps (GstCaps * caps, memset (pPixelFormat, 0, sizeof (DDPIXELFORMAT)); pPixelFormat->dwSize = sizeof (DDPIXELFORMAT); - if (!(structure = gst_caps_get_structure (caps, 0))) + if (!(structure = gst_caps_get_structure (caps, 0))) { + GST_CAT_ERROR (directdrawsink_debug, + "can't get structure pointer from caps"); return FALSE; + } if (gst_structure_has_name (structure, "video/x-raw-rgb")) { - gint depth, bitcount, bitmask; + gint depth, bitcount, bitmask, endianness; pPixelFormat->dwFlags = DDPF_RGB; ret &= gst_structure_get_int (structure, "bpp", &bitcount); @@ -153,6 +243,14 @@ gst_ddrawvideosink_get_format_from_caps (GstCaps * caps, 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")) { gint fourcc; @@ -187,15 +285,17 @@ gst_ddrawvideosink_get_caps_from_format (DDPIXELFORMAT pixel_format) depth = 24; } caps = gst_caps_new_simple ("video/x-raw-rgb", - "bpp", G_TYPE_INT, bpp, + "bpp", G_TYPE_INT, bpp, "depth", G_TYPE_INT, depth, - "endianness", G_TYPE_INT, G_LITTLE_ENDIAN, NULL); + "endianness", G_TYPE_INT, G_LITTLE_ENDIAN, + NULL); } if ((pixel_format.dwFlags & DDPF_YUV) == DDPF_YUV) { fourcc = pixel_format.dwFourCC; caps = gst_caps_new_simple ("video/x-raw-yuv", - "format", GST_TYPE_FOURCC, fourcc, NULL); + "format", GST_TYPE_FOURCC, fourcc, + NULL); } g_assert (caps != NULL); @@ -249,7 +349,10 @@ gst_directdrawsink_center_rect (RECT src, RECT dst, RECT * result) result->right); } -/*subclass of GstBuffer which manages surfaces lifetime*/ +/************************************************************************/ +/* subclass of GstBuffer which manages surfaces lifetime */ +/* */ +/************************************************************************/ static void gst_ddrawsurface_finalize (GstDDrawSurface * surface) { @@ -336,36 +439,8 @@ gst_ddrawsurface_get_type (void) return _gst_ddrawsurface_type; } -/* FIXME: this is problematic if there is more than one sink instance at the - * same time, surely there exists a better solution than this? */ -/* static GstDirectDrawSink *global_ddrawsink = NULL; */ -/*GType -gst_directdrawsink_get_type (void) -{ - static GType directdrawsink_type = 0; - if (!directdrawsink_type) { - static const GTypeInfo directdrawsink_info = { - sizeof (GstDirectDrawSinkClass), - gst_directdrawsink_base_init, - NULL, - (GClassInitFunc) gst_directdrawsink_class_init, - NULL, - NULL, - sizeof (GstDirectDrawSink), - 0, - (GInstanceInitFunc) gst_directdrawsink_init, - }; - - directdrawsink_type = - g_type_register_static (GST_TYPE_VIDEO_SINK, "GstDirectDrawSink", - &directdrawsink_info, 0); - } - - return directdrawsink_type; -} -*/ static void gst_directdrawsink_base_init (gpointer g_class) { @@ -412,16 +487,6 @@ gst_directdrawsink_class_init (GstDirectDrawSinkClass * klass) GST_DEBUG_FUNCPTR (gst_directdrawsink_buffer_alloc); /*install properties */ - g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_FULLSCREEN, - g_param_spec_boolean ("fullscreen", "fullscreen", - "boolean to activate fullscreen", FALSE, G_PARAM_READWRITE)); - - /*extern window where we will display the video */ - g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_WINDOW, - g_param_spec_long ("window", "Window", - "The target window for video", G_MINLONG, G_MAXLONG, 0, - G_PARAM_WRITABLE)); - /*extern surface where we will blit the video */ g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_SURFACE, g_param_spec_pointer ("surface", "Surface", @@ -448,13 +513,6 @@ gst_directdrawsink_set_property (GObject * object, guint prop_id, case PROP_SURFACE: ddrawsink->extern_surface = g_value_get_pointer (value); break; - case PROP_WINDOW: - ddrawsink->video_window = (HWND) g_value_get_long (value); - ddrawsink->resize_window = FALSE; - break; - case PROP_FULLSCREEN: - /*ddrawsink->fullscreen = g_value_get_boolean (value); not working .... */ - break; case PROP_KEEP_ASPECT_RATIO: ddrawsink->keep_aspect_ratio = g_value_get_boolean (value); break; @@ -473,9 +531,6 @@ gst_directdrawsink_get_property (GObject * object, guint prop_id, ddrawsink = GST_DIRECTDRAW_SINK (object); switch (prop_id) { - case PROP_FULLSCREEN: - g_value_set_boolean (value, ddrawsink->fullscreen); - break; case PROP_KEEP_ASPECT_RATIO: g_value_set_boolean (value, ddrawsink->keep_aspect_ratio); break; @@ -511,6 +566,9 @@ gst_directdrawsink_init (GstDirectDrawSink * ddrawsink, ddrawsink->overlays = NULL; ddrawsink->clipper = NULL; ddrawsink->extern_surface = NULL; + ddrawsink->video_window = NULL; + ddrawsink->our_video_window = TRUE; + ddrawsink->last_buffer = NULL; /*video default values */ ddrawsink->video_height = 0; @@ -521,24 +579,17 @@ gst_directdrawsink_init (GstDirectDrawSink * ddrawsink, memset (&ddrawsink->dd_pixel_format, 0, sizeof (DDPIXELFORMAT)); ddrawsink->caps = NULL; - ddrawsink->window_thread = NULL; - ddrawsink->bUseOverlay = FALSE; ddrawsink->color_key = 0; /*need to be a public property and may be we can enable overlays when this property is set ... */ - ddrawsink->fullscreen = FALSE; ddrawsink->setup = FALSE; - ddrawsink->display_modes = NULL; ddrawsink->buffer_pool = NULL; - ddrawsink->resize_window = TRUE; /*resize only our internal window to the video size */ ddrawsink->pool_lock = g_mutex_new (); - - ddrawsink->keep_aspect_ratio = TRUE; -/* ddrawsink->can_blit = TRUE;*/ + ddrawsink->keep_aspect_ratio = FALSE; } static GstCaps * @@ -582,34 +633,39 @@ gst_directdrawsink_set_caps (GstBaseSink * bsink, GstCaps * caps) ddrawsink = GST_DIRECTDRAW_SINK (bsink); + GST_CAT_INFO (directdrawsink_debug, "set_caps"); + 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 (caps, &ddrawsink->dd_pixel_format); - if (!ret) return FALSE; ddrawsink->fps_n = gst_value_get_fraction_numerator (fps); ddrawsink->fps_d = gst_value_get_fraction_denominator (fps); - if (ddrawsink->video_window && ddrawsink->resize_window) { + /* Notify application to set window id now */ + if (!ddrawsink->video_window) { + gst_x_overlay_prepare_xwindow_id (GST_X_OVERLAY (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); } - /*create overlays flipping chain */ + /* create an offscreen surface with the caps */ ret = gst_directdrawsink_create_ddraw_surfaces (ddrawsink); if (!ret && ddrawsink->bUseOverlay) { GST_CAT_WARNING (directdrawsink_debug, @@ -620,13 +676,13 @@ gst_directdrawsink_set_caps (GstBaseSink * bsink, GstCaps * caps) return TRUE; } - /*could not create draw surfaces even with fallback, so leave - everything as is */ + /*could not create draw surfaces even with fallback, so leave everything as is */ ddrawsink->bUseOverlay = TRUE; } if (!ret) { GST_CAT_ERROR (directdrawsink_debug, "Can not create ddraw surface"); } + return ret; } @@ -649,7 +705,6 @@ gst_directdrawsink_change_state (GstElement * element, if (!(ddrawsink->caps = gst_directdrawsink_get_ddrawcaps (ddrawsink))) return GST_STATE_CHANGE_FAILURE; - break; case GST_STATE_CHANGE_READY_TO_PAUSED: break; @@ -962,14 +1017,13 @@ gst_directdrawsink_fill_colorkey (LPDIRECTDRAWSURFACE surface, DWORD dwColorKey) ddbfx.dwSize = sizeof (DDBLTFX); ddbfx.dwFillColor = dwColorKey; - if (IDirectDrawSurface_Blt (surface, + if (IDirectDrawSurface7_Blt (surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbfx) == DD_OK) return TRUE; else return FALSE; } - static void gst_directdrawsink_show_overlay (GstDirectDrawSink * ddrawsink) { @@ -1014,7 +1068,7 @@ gst_directdrawsink_show_overlay (GstDirectDrawSink * ddrawsink) ddofx.dckDestColorkey.dwColorSpaceLowValue = ddrawsink->color_key; ddofx.dckDestColorkey.dwColorSpaceHighValue = ddrawsink->color_key; - hRes = IDirectDrawSurface_UpdateOverlay (ddrawsink->overlays, + hRes = IDirectDrawSurface7_UpdateOverlay (ddrawsink->overlays, NULL, surface, &destsurf_rect, DDOVER_KEYDESTOVERRIDE | DDOVER_SHOW, &ddofx); } @@ -1025,13 +1079,34 @@ gst_directdrawsink_show_frame (GstBaseSink * bsink, GstBuffer * buf) GstDirectDrawSink *ddrawsink; HRESULT hRes; - DDSURFACEDESC surf_desc; + DDSURFACEDESC2 surf_desc; RECT destsurf_rect, src_rect; POINT dest_surf_point; LPDIRECTDRAWSURFACE lpSurface = NULL; ddrawsink = GST_DIRECTDRAW_SINK (bsink); + + if (buf) { + /*save a reference to the input buffer */ + if (ddrawsink->last_buffer != buf) { + if (ddrawsink->last_buffer) { + GST_LOG_OBJECT (ddrawsink, "unreffing %p", ddrawsink->last_buffer); + gst_buffer_unref (ddrawsink->last_buffer); + } + } + GST_LOG_OBJECT (ddrawsink, "reffing %p as our current buffer", buf); + ddrawsink->last_buffer = gst_buffer_ref (buf); + } else { + /*use last buffer */ + buf = ddrawsink->last_buffer; + } + + if (buf == NULL) + return GST_FLOW_ERROR; + + + if (ddrawsink->extern_surface) { destsurf_rect.left = 0; destsurf_rect.top = 0; @@ -1046,7 +1121,7 @@ gst_directdrawsink_show_frame (GstBaseSink * bsink, GstBuffer * buf) } if (ddrawsink->keep_aspect_ratio) { - /*center image to dest image keeping aspect ratio */ + /* center image to dest image keeping aspect ratio */ src_rect.top = 0; src_rect.left = 0; src_rect.bottom = ddrawsink->video_height; @@ -1059,8 +1134,12 @@ gst_directdrawsink_show_frame (GstBaseSink * bsink, GstBuffer * buf) DDSCAPS ddbackcaps; ddbackcaps.dwCaps = DDSCAPS_BACKBUFFER; - IDirectDrawSurface_GetAttachedSurface (ddrawsink->overlays, &ddbackcaps, - &lpSurface); + hRes = + IDirectDrawSurface7_GetAttachedSurface (ddrawsink->overlays, + &ddbackcaps, &lpSurface); + GST_CAT_WARNING (directdrawsink_debug, + "gst_directdrawsink_show_frame failed getting overlay backbuffer %s", + DDErrorString (hRes)); } else { /*use our offscreen surface */ lpSurface = ddrawsink->offscreen_surface; @@ -1073,11 +1152,11 @@ gst_directdrawsink_show_frame (GstBaseSink * bsink, GstBuffer * buf) ((GST_IS_DDRAWSURFACE (buf)) && (GST_BUFFER (buf)->malloc_data))) { LPBYTE data = NULL; - guint src_pitch, line; + guint src_pitch; /* Check for lost surface */ - if (IDirectDrawSurface_IsLost (lpSurface) == DDERR_SURFACELOST) { - IDirectDrawSurface_Restore (lpSurface); + if (IDirectDrawSurface7_IsLost (lpSurface) == DDERR_SURFACELOST) { + IDirectDrawSurface7_Restore (lpSurface); } ZeroMemory (&surf_desc, sizeof (surf_desc)); @@ -1085,7 +1164,7 @@ gst_directdrawsink_show_frame (GstBaseSink * bsink, GstBuffer * buf) /* Lock the surface */ hRes = - IDirectDrawSurface_Lock (lpSurface, NULL, &surf_desc, DDLOCK_WAIT, + IDirectDrawSurface7_Lock (lpSurface, NULL, &surf_desc, DDLOCK_WAIT, NULL); if (hRes != DD_OK) { GST_CAT_WARNING (directdrawsink_debug, @@ -1101,13 +1180,15 @@ gst_directdrawsink_show_frame (GstBaseSink * bsink, GstBuffer * buf) src_pitch = GST_BUFFER_SIZE (buf) / ddrawsink->video_height; /* Write each line respecting dest surface pitch */ - for (line = 0; line < surf_desc.dwHeight; line++) { - memcpy (data, GST_BUFFER_DATA (buf) + (line * src_pitch), src_pitch); +/* for (line = 0; line < surf_desc.dwHeight; line++) { + memcpy (data, GST_BUFFER_DATA (buf) + (line * src_pitch), + src_pitch); data += surf_desc.lPitch; - } + }*/ + memcpy (data, GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf)); /* Unlock the surface */ - hRes = IDirectDrawSurface_Unlock (lpSurface, NULL); + hRes = IDirectDrawSurface7_Unlock (lpSurface, NULL); if (hRes != DD_OK) { GST_CAT_WARNING (directdrawsink_debug, "gst_directdrawsink_show_frame failed unlocking surface %s", @@ -1118,27 +1199,28 @@ gst_directdrawsink_show_frame (GstBaseSink * bsink, GstBuffer * buf) if (ddrawsink->bUseOverlay) { /*Flip to front overlay */ hRes = - IDirectDrawSurface_Flip (ddrawsink->overlays, lpSurface, DDFLIP_WAIT); - IDirectDrawSurface_Release (lpSurface); + IDirectDrawSurface7_Flip (ddrawsink->overlays, lpSurface, + DDFLIP_WAIT); + IDirectDrawSurface7_Release (lpSurface); lpSurface = NULL; } else { if (ddrawsink->extern_surface) { if (ddrawsink->out_height == ddrawsink->video_height && ddrawsink->out_width == ddrawsink->video_width) { /*Fast blit to extern surface */ - hRes = IDirectDrawSurface_BltFast (ddrawsink->extern_surface, 0, 0, + hRes = IDirectDrawSurface7_BltFast (ddrawsink->extern_surface, 0, 0, lpSurface, NULL, DDBLTFAST_WAIT); } else { /*blit to extern surface (Blt will scale the video the dest rect surface if needed) */ hRes = - IDirectDrawSurface_Blt (ddrawsink->extern_surface, &destsurf_rect, - lpSurface, NULL, DDBLT_WAIT, NULL); + IDirectDrawSurface7_Blt (ddrawsink->extern_surface, + &destsurf_rect, lpSurface, NULL, DDBLT_WAIT, NULL); } } else { /*blit to primary surface ( Blt will scale the video the dest rect surface if needed */ hRes = - IDirectDrawSurface_Blt (ddrawsink->primary_surface, &destsurf_rect, + IDirectDrawSurface7_Blt (ddrawsink->primary_surface, &destsurf_rect, lpSurface, NULL, DDBLT_WAIT, NULL); } } @@ -1149,20 +1231,20 @@ gst_directdrawsink_show_frame (GstBaseSink * bsink, GstBuffer * buf) surface = GST_DDRAWSURFACE (buf); /* Unlocking surface before blit */ - IDirectDrawSurface_Unlock (surface->surface, NULL); + IDirectDrawSurface7_Unlock (surface->surface, NULL); surface->locked = FALSE; /* Check for lost surfaces */ - if (IDirectDrawSurface_IsLost (surface->surface) == DDERR_SURFACELOST) { - IDirectDrawSurface_Restore (surface->surface); + if (IDirectDrawSurface7_IsLost (surface->surface) == DDERR_SURFACELOST) { + IDirectDrawSurface7_Restore (surface->surface); } if (ddrawsink->bUseOverlay) { /* blit to the overlays back buffer */ - hRes = IDirectDrawSurface_Blt (lpSurface, NULL, + hRes = IDirectDrawSurface7_Blt (lpSurface, NULL, surface->surface, NULL, DDBLT_WAIT, NULL); - hRes = IDirectDrawSurface_Flip (ddrawsink->overlays, NULL, DDFLIP_WAIT); + hRes = IDirectDrawSurface7_Flip (ddrawsink->overlays, NULL, DDFLIP_WAIT); if (hRes != DD_OK) GST_CAT_WARNING (directdrawsink_debug, "error flipping"); @@ -1172,23 +1254,23 @@ gst_directdrawsink_show_frame (GstBaseSink * bsink, GstBuffer * buf) if (ddrawsink->out_height == ddrawsink->video_height && ddrawsink->out_width == ddrawsink->video_width) { /*Fast blit to extern surface */ - hRes = IDirectDrawSurface_BltFast (ddrawsink->extern_surface, 0, 0, + hRes = IDirectDrawSurface7_BltFast (ddrawsink->extern_surface, 0, 0, surface->surface, NULL, DDBLTFAST_WAIT); } else { /*blit to extern surface (Blt will scale the video the dest rect surface if needed) */ hRes = - IDirectDrawSurface_Blt (ddrawsink->extern_surface, &destsurf_rect, - surface->surface, NULL, DDBLT_WAIT, NULL); + IDirectDrawSurface7_Blt (ddrawsink->extern_surface, + &destsurf_rect, surface->surface, NULL, DDBLT_WAIT, NULL); } } else { /*blit to our primary surface */ hRes = - IDirectDrawSurface_Blt (ddrawsink->primary_surface, &destsurf_rect, + IDirectDrawSurface7_Blt (ddrawsink->primary_surface, &destsurf_rect, surface->surface, NULL, DDBLT_WAIT, NULL); if (hRes != DD_OK) GST_CAT_WARNING (directdrawsink_debug, - "IDirectDrawSurface_Blt returned %s", DDErrorString (hRes)); + "IDirectDrawSurface7_Blt returned %s", DDErrorString (hRes)); else GST_CAT_INFO (directdrawsink_debug, "allocated surface was blit to our primary"); @@ -1207,47 +1289,29 @@ gst_directdrawsink_setup_ddraw (GstDirectDrawSink * ddrawsink) { gboolean bRet = TRUE; HRESULT hRes; - DWORD dwCooperativeLevel; - DDSURFACEDESC dd_surface_desc; + DDSURFACEDESC2 dd_surface_desc; - /*UUID IDirectDraw7_ID; + //create an instance of the ddraw object + hRes = + DirectDrawCreateEx ( /*DDCREATE_EMULATIONONLY */ 0, + (void **) &ddrawsink->ddraw_object, &IID_IDirectDraw7, NULL); - //IDirectDraw_QueryInterface() - create an instance of the ddraw object - hRes = DirectDrawCreateEx (DDCREATE_EMULATIONONLY, (void**)&ddrawsink->ddraw_object, - (REFIID)IID_IDirectDraw7, NULL); - */ - hRes = DirectDrawCreate (NULL, &ddrawsink->ddraw_object, NULL); if (hRes != DD_OK || ddrawsink->ddraw_object == NULL) { GST_CAT_ERROR (directdrawsink_debug, "DirectDrawCreate failed with: %s", DDErrorString (hRes)); return FALSE; } - /*get ddraw caps for the current hardware */ -/* ddrawsink->DDDriverCaps.dwSize = sizeof (DDCAPS); - ddrawsink->DDHELCaps.dwSize = sizeof (DDCAPS); - hRes = IDirectDraw_GetCaps (ddrawsink->ddraw_object, &ddrawsink->DDDriverCaps, &ddrawsink->DDHELCaps); -*/ - /*set cooperative level */ - if (ddrawsink->fullscreen) - dwCooperativeLevel = DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN; - else - dwCooperativeLevel = DDSCL_NORMAL; + /* set cooperative level */ + hRes = IDirectDraw7_SetCooperativeLevel (ddrawsink->ddraw_object, + ddrawsink->video_window, DDSCL_NORMAL); - hRes = IDirectDraw_SetCooperativeLevel (ddrawsink->ddraw_object, - ddrawsink->video_window, dwCooperativeLevel); if (hRes != DD_OK) { GST_CAT_ERROR (directdrawsink_debug, "SetCooperativeLevel failed with: %s", DDErrorString (hRes)); bRet = FALSE; } - /*for fullscreen mode, setup display mode */ - if (ddrawsink->fullscreen) { - hRes = IDirectDraw_SetDisplayMode (ddrawsink->ddraw_object, 1440, 900, 32); - } - if (!ddrawsink->extern_surface) { /*create our primary surface */ memset (&dd_surface_desc, 0, sizeof (dd_surface_desc)); @@ -1255,31 +1319,34 @@ gst_directdrawsink_setup_ddraw (GstDirectDrawSink * ddrawsink) dd_surface_desc.dwFlags = DDSD_CAPS; dd_surface_desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; - hRes = IDirectDraw_CreateSurface (ddrawsink->ddraw_object, &dd_surface_desc, + hRes = + IDirectDraw7_CreateSurface (ddrawsink->ddraw_object, &dd_surface_desc, &ddrawsink->primary_surface, NULL); if (hRes != DD_OK) { GST_CAT_ERROR (directdrawsink_debug, "CreateSurface (primary) failed with: %s", DDErrorString (hRes)); - IDirectDraw_Release (ddrawsink->ddraw_object); + IDirectDraw7_Release (ddrawsink->ddraw_object); return FALSE; } - hRes = IDirectDraw_CreateClipper (ddrawsink->ddraw_object, 0, + /* setup the clipper object */ + hRes = IDirectDraw7_CreateClipper (ddrawsink->ddraw_object, 0, &ddrawsink->clipper, NULL); if (hRes == DD_OK) { hRes = IDirectDrawClipper_SetHWnd (ddrawsink->clipper, 0, ddrawsink->video_window); - hRes = IDirectDrawSurface_SetClipper (ddrawsink->primary_surface, + + hRes = IDirectDrawSurface7_SetClipper (ddrawsink->primary_surface, ddrawsink->clipper); } } else { - DDSURFACEDESC desc_surface; + DDSURFACEDESC2 desc_surface; - desc_surface.dwSize = sizeof (DDSURFACEDESC); + desc_surface.dwSize = sizeof (DDSURFACEDESC2); /*get extern surface size */ - hRes = IDirectDrawSurface_GetSurfaceDesc (ddrawsink->extern_surface, + hRes = IDirectDrawSurface7_GetSurfaceDesc (ddrawsink->extern_surface, &desc_surface); if (hRes != DD_OK) { /*error while retrieving ext surface description */ @@ -1291,7 +1358,7 @@ gst_directdrawsink_setup_ddraw (GstDirectDrawSink * ddrawsink) /*get extern surface pixel format (FIXME not needed if we are using overlays) */ ddrawsink->dd_pixel_format.dwSize = sizeof (DDPIXELFORMAT); - hRes = IDirectDrawSurface_GetPixelFormat (ddrawsink->extern_surface, + hRes = IDirectDrawSurface7_GetPixelFormat (ddrawsink->extern_surface, &ddrawsink->dd_pixel_format); if (hRes != DD_OK) { /*error while retrieving ext surface pixel format */ @@ -1313,8 +1380,8 @@ long FAR PASCAL WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { - /*case WM_ERASEBKGND: - return TRUE; */ + case WM_ERASEBKGND: + return TRUE; /* case WM_WINDOWPOSCHANGED: case WM_MOVE: case WM_SIZE: @@ -1369,6 +1436,10 @@ gst_directdrawsink_window_thread (GstDirectDrawSink * ddrawsink) if (ddrawsink->video_window == NULL) return FALSE; + /* signal application we create a window */ + gst_x_overlay_got_xwindow_id (GST_X_OVERLAY (ddrawsink), + ddrawsink->video_window); + ReleaseSemaphore (ddrawsink->window_created_signal, 1, NULL); /*start message loop processing our default window messages */ @@ -1412,7 +1483,7 @@ failed: static gboolean gst_directdrawsink_create_ddraw_surfaces (GstDirectDrawSink * ddrawsink) { - DDSURFACEDESC dd_surface_desc; + DDSURFACEDESC2 dd_surface_desc; HRESULT hRes; memset (&dd_surface_desc, 0, sizeof (dd_surface_desc)); @@ -1432,7 +1503,8 @@ gst_directdrawsink_create_ddraw_surfaces (GstDirectDrawSink * ddrawsink) dd_surface_desc.dwFlags |= DDSD_BACKBUFFERCOUNT; dd_surface_desc.dwBackBufferCount = 1; - hRes = IDirectDraw_CreateSurface (ddrawsink->ddraw_object, &dd_surface_desc, + hRes = + IDirectDraw7_CreateSurface (ddrawsink->ddraw_object, &dd_surface_desc, &ddrawsink->overlays, NULL); if (hRes != DD_OK) { @@ -1447,10 +1519,9 @@ gst_directdrawsink_create_ddraw_surfaces (GstDirectDrawSink * ddrawsink) } else { dd_surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN /*|DDSCAPS_SYSTEMMEMORY */ ; - - hRes = IDirectDraw_CreateSurface (ddrawsink->ddraw_object, &dd_surface_desc, + hRes = + IDirectDraw7_CreateSurface (ddrawsink->ddraw_object, &dd_surface_desc, &ddrawsink->offscreen_surface, NULL); - if (hRes != DD_OK) { GST_CAT_WARNING (directdrawsink_debug, "create_ddraw_surfaces:CreateSurface(offscreen) failed %s", @@ -1500,7 +1571,7 @@ gst_directdrawsink_get_depth (LPDDPIXELFORMAT lpddpfPixelFormat) } HRESULT WINAPI -EnumModesCallback2 (LPDDSURFACEDESC lpDDSurfaceDesc, LPVOID lpContext) +EnumModesCallback2 (LPDDSURFACEDESC2 lpDDSurfaceDesc, LPVOID lpContext) { GstDirectDrawSink *ddrawsink = (GstDirectDrawSink *) lpContext; GstCaps *format_caps = NULL; @@ -1543,16 +1614,84 @@ gst_directdrawsink_get_ddrawcaps (GstDirectDrawSink * ddrawsink) DWORD dwFourccCodeIndex = 0; LPDWORD pdwFourccCodes = NULL; DWORD dwNbFourccCodes = 0; + DDCAPS ddcaps_hardware; + DDCAPS ddcaps_emulation; GstCaps *format_caps = NULL; ddrawsink->caps = gst_caps_new_empty (); if (!ddrawsink->caps) return FALSE; - /*enumerate display modes exposed by directdraw object */ + /* 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; + gint endianness = G_LITTLE_ENDIAN; + gint depth; + + GST_CAT_INFO (directdrawsink_debug, + "hardware doesn't support blit from one colorspace to another one. " + "so we will create a caps with only the current display mode"); + + surface_desc.dwSize = sizeof (DDSURFACEDESC); + hRes = IDirectDraw7_GetDisplayMode (ddrawsink->ddraw_object, &surface_desc); + if (hRes != DD_OK) { + GST_CAT_ERROR (directdrawsink_debug, + "Error getting the current display mode (%s)", DDErrorString (hRes)); + return NULL; + } + + depth = gst_directdrawsink_get_depth (&surface_desc.ddpfPixelFormat); + + if (surface_desc.ddpfPixelFormat.dwRGBBitCount == 24 || + surface_desc.ddpfPixelFormat.dwRGBBitCount == 32) { + /* ffmpegcolorspace handles 24/32 bpp RGB as big-endian. */ + endianness = G_BIG_ENDIAN; + surface_desc.ddpfPixelFormat.dwRBitMask = + GUINT32_TO_BE (surface_desc.ddpfPixelFormat.dwRBitMask); + surface_desc.ddpfPixelFormat.dwGBitMask = + GUINT32_TO_BE (surface_desc.ddpfPixelFormat.dwGBitMask); + surface_desc.ddpfPixelFormat.dwBBitMask = + GUINT32_TO_BE (surface_desc.ddpfPixelFormat.dwBBitMask); + } + + format_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, surface_desc.ddpfPixelFormat.dwRGBBitCount, + "depth", G_TYPE_INT, depth, + "endianness", G_TYPE_INT, endianness, + "red_mask", G_TYPE_INT, surface_desc.ddpfPixelFormat.dwRBitMask, + "green_mask", G_TYPE_INT, surface_desc.ddpfPixelFormat.dwGBitMask, + "blue_mask", G_TYPE_INT, surface_desc.ddpfPixelFormat.dwBBitMask, NULL); + + if (format_caps) { + gst_caps_append (ddrawsink->caps, format_caps); + } + + GST_CAT_INFO (directdrawsink_debug, "returning caps %s", + gst_caps_to_string (ddrawsink->caps)); + + return ddrawsink->caps; + } + + GST_CAT_INFO (directdrawsink_debug, + "the hardware can blit from one colorspace to another, " + "then enumerate the colorspace supported by the hardware"); + + /* enumerate display modes exposed by directdraw object + to know supported RGB mode */ hRes = - IDirectDraw_EnumDisplayModes (ddrawsink->ddraw_object, DDEDM_REFRESHRATES, - NULL, ddrawsink, EnumModesCallback2); + IDirectDraw7_EnumDisplayModes (ddrawsink->ddraw_object, + DDEDM_REFRESHRATES, NULL, ddrawsink, EnumModesCallback2); if (hRes != DD_OK) { GST_CAT_WARNING (directdrawsink_debug, "EnumDisplayModes returns: %s", DDErrorString (hRes)); @@ -1560,44 +1699,44 @@ gst_directdrawsink_get_ddrawcaps (GstDirectDrawSink * ddrawsink) } /* enumerate non-rgb modes exposed by directdraw object */ - IDirectDraw_GetFourCCCodes (ddrawsink->ddraw_object, &dwNbFourccCodes, NULL); - if (dwNbFourccCodes != 0) { - pdwFourccCodes = g_new0 (DWORD, dwNbFourccCodes); - if (!pdwFourccCodes) - return FALSE; - - if (FAILED (IDirectDraw_GetFourCCCodes (ddrawsink->ddraw_object, - &dwNbFourccCodes, pdwFourccCodes))) { - g_free (pdwFourccCodes); - return FALSE; - } - - for (dwFourccCodeIndex = 0; dwFourccCodeIndex < dwNbFourccCodes; - dwFourccCodeIndex++) { - /*support only yuv formats YUY2, UYVY, YVU9, YV12, AYUV */ - if (pdwFourccCodes[dwFourccCodeIndex] == mmioFOURCC ('Y', 'U', 'Y', '2') - || pdwFourccCodes[dwFourccCodeIndex] == mmioFOURCC ('U', 'Y', 'V', - 'Y') - || pdwFourccCodes[dwFourccCodeIndex] == mmioFOURCC ('Y', 'V', 'U', - '9') - || pdwFourccCodes[dwFourccCodeIndex] == mmioFOURCC ('Y', 'V', '1', - '2') - || pdwFourccCodes[dwFourccCodeIndex] == mmioFOURCC ('A', 'Y', 'U', - 'V') - ) { - format_caps = gst_caps_new_simple ("video/x-raw-yuv", - "format", GST_TYPE_FOURCC, pdwFourccCodes[dwFourccCodeIndex], - "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, NULL); - - if (format_caps) - gst_caps_append (ddrawsink->caps, format_caps); - } - } - - g_free (pdwFourccCodes); +/* IDirectDraw7_GetFourCCCodes(ddrawsink->ddraw_object, &dwNbFourccCodes, NULL); + if(dwNbFourccCodes != 0) + { + pdwFourccCodes = g_new0(DWORD, dwNbFourccCodes); + if(!pdwFourccCodes) + return FALSE; + + if (FAILED(IDirectDraw7_GetFourCCCodes(ddrawsink->ddraw_object, &dwNbFourccCodes, + pdwFourccCodes))) + { + g_free(pdwFourccCodes); + return FALSE; + } + + for(dwFourccCodeIndex = 0; dwFourccCodeIndex < dwNbFourccCodes; dwFourccCodeIndex++) + { + /*support only yuv formats YUY2, UYVY, YVU9, YV12, AYUV + if(/*pdwFourccCodes[dwFourccCodeIndex] == mmioFOURCC('Y','U','Y','2') || + pdwFourccCodes[dwFourccCodeIndex] == mmioFOURCC('U','Y','V','Y') || + pdwFourccCodes[dwFourccCodeIndex] == mmioFOURCC('Y','V','U','9') || + pdwFourccCodes[dwFourccCodeIndex] == mmioFOURCC('Y','V','1','2') /*|| + pdwFourccCodes[dwFourccCodeIndex] == mmioFOURCC('A','Y','U','V') + ) + { + format_caps = gst_caps_new_simple ("video/x-raw-yuv", + "format", GST_TYPE_FOURCC, pdwFourccCodes[dwFourccCodeIndex], + "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, NULL); + + if(format_caps) + gst_caps_append (ddrawsink->caps, format_caps); + } + } + + g_free(pdwFourccCodes); } +*/ if (gst_caps_is_empty (ddrawsink->caps)) { gst_caps_unref (ddrawsink->caps); @@ -1606,6 +1745,7 @@ gst_directdrawsink_get_ddrawcaps (GstDirectDrawSink * ddrawsink) ("No supported format found")); return NULL; } +// GST_CAT_INFO (directdrawsink_debug, "returning caps %s", gst_caps_to_string (ddrawsink->caps)); return ddrawsink->caps; } @@ -1620,7 +1760,7 @@ gst_directdrawsink_surface_create (GstDirectDrawSink * ddrawsink, gint pitch; HRESULT hRes; - DDSURFACEDESC surf_desc, surf_lock_desc; + DDSURFACEDESC2 surf_desc, surf_lock_desc; g_return_val_if_fail (GST_IS_DIRECTDRAW_SINK (ddrawsink), NULL); @@ -1662,7 +1802,7 @@ gst_directdrawsink_surface_create (GstDirectDrawSink * ddrawsink, memcpy (&(surf_desc.ddpfPixelFormat), &surface->dd_pixel_format, sizeof (DDPIXELFORMAT)); - hRes = IDirectDraw_CreateSurface (ddrawsink->ddraw_object, &surf_desc, + hRes = IDirectDraw7_CreateSurface (ddrawsink->ddraw_object, &surf_desc, &surface->surface, NULL); if (hRes != DD_OK) { /*gst_object_unref (surface); @@ -1674,8 +1814,14 @@ gst_directdrawsink_surface_create (GstDirectDrawSink * ddrawsink, /* 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 */ - hRes = IDirectDrawSurface_Lock (surface->surface, NULL, &surf_lock_desc, + 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) { @@ -1700,7 +1846,7 @@ gst_directdrawsink_surface_create (GstDirectDrawSink * ddrawsink, GST_BUFFER_DATA (surface) = GST_BUFFER (surface)->malloc_data; GST_BUFFER_SIZE (surface) = size; -/* surf_desc.dwSize = sizeof(DDSURFACEDESC); +/* surf_desc.dwSize = sizeof(DDSURFACEDESC2); surf_desc.dwFlags = DDSD_PITCH | DDSD_LPSURFACE | DDSD_HEIGHT | DDSD_WIDTH ||DDSD_PIXELFORMAT; surf_desc.lpSurface = GST_BUFFER (surface)->malloc_data; surf_desc.lPitch = pitch; @@ -1736,10 +1882,10 @@ gst_directdrawsink_surface_destroy (GstDirectDrawSink * ddrawsink, /* Release our internal surface */ if (surface->surface) { if (surface->locked) { - IDirectDrawSurface_Unlock (surface->surface, NULL); + IDirectDrawSurface7_Unlock (surface->surface, NULL); surface->locked = FALSE; } - IDirectDrawSurface_Release (surface->surface); + IDirectDrawSurface7_Release (surface->surface); surface->surface = NULL; } @@ -1780,9 +1926,11 @@ gst_directdrawsink_bufferpool_clear (GstDirectDrawSink * ddrawsink) static void gst_directdrawsink_cleanup (GstDirectDrawSink * ddrawsink) { + /* Post quit message and wait for our event window thread */ - if (ddrawsink->video_window) + 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; @@ -1793,24 +1941,13 @@ gst_directdrawsink_cleanup (GstDirectDrawSink * ddrawsink) ddrawsink->buffer_pool = NULL; } - if (ddrawsink->display_modes) { - GSList *walk = ddrawsink->display_modes; - - while (walk) { - g_free (walk->data); - walk = g_slist_next (walk); - } - g_slist_free (ddrawsink->display_modes); - ddrawsink->display_modes = NULL; - } - if (ddrawsink->overlays) { - IDirectDrawSurface_Release (ddrawsink->overlays); + IDirectDrawSurface7_Release (ddrawsink->overlays); ddrawsink->overlays = NULL; } if (ddrawsink->offscreen_surface) { - IDirectDrawSurface_Release (ddrawsink->offscreen_surface); + IDirectDrawSurface7_Release (ddrawsink->offscreen_surface); ddrawsink->offscreen_surface = NULL; } @@ -1820,14 +1957,19 @@ gst_directdrawsink_cleanup (GstDirectDrawSink * ddrawsink) } if (ddrawsink->primary_surface) { - IDirectDrawSurface_Release (ddrawsink->primary_surface); + IDirectDrawSurface7_Release (ddrawsink->primary_surface); ddrawsink->primary_surface = NULL; } if (ddrawsink->ddraw_object) { - IDirectDraw_Release (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 index f9d4c865..1a32c5a5 100644 --- a/sys/directdraw/gstdirectdrawsink.h +++ b/sys/directdraw/gstdirectdrawsink.h @@ -27,8 +27,9 @@ #include #include -#include +#include +#include #include G_BEGIN_DECLS @@ -51,87 +52,76 @@ struct _GstDDrawSurface /* Extension of GstBuffer to store directdraw surfaces */ GstBuffer buffer; - /*directdraw surface */ + /* 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; }; - -typedef struct _GstDDDDisplayMode GstDDDisplayMode; - -struct _GstDDDDisplayMode -{ - gint width; - gint height; - gint bpp; -}; - struct _GstDirectDrawSink { GstVideoSink videosink; - /*directdraw offscreen surfaces pool */ + /* directdraw offscreen surfaces pool */ GSList *buffer_pool; + GMutex *pool_lock; - GSList *display_modes; - //GstDDDisplayMode display_mode; - - /*directdraw objects */ + /* directdraw objects */ LPDIRECTDRAW ddraw_object; LPDIRECTDRAWSURFACE primary_surface; LPDIRECTDRAWSURFACE offscreen_surface; LPDIRECTDRAWSURFACE overlays; LPDIRECTDRAWCLIPPER clipper; - /*DDCAPS DDDriverCaps; - DDCAPS DDHELCaps; - gboolean can_blit;*/ + /* last buffer displayed (used for XOverlay interface expose method) */ + GstBuffer * last_buffer; - /*Directdraw caps */ + /* directdraw caps */ GstCaps *caps; - /*handle of the video window */ + /* video window management */ HWND video_window; + gboolean our_video_window; HANDLE window_created_signal; - gboolean resize_window; - - /*video properties */ + + /* video properties */ gint video_width, video_height; gint out_width, out_height; - //gdouble framerate; gint fps_n; gint fps_d; /*properties*/ LPDIRECTDRAWSURFACE extern_surface; gboolean keep_aspect_ratio; - gboolean fullscreen; /*pixel format */ DDPIXELFORMAT dd_pixel_format; + /* thread processing our default window messages */ GThread *window_thread; - gboolean bUseOverlay; - gboolean bIsOverlayVisible; + /* TRUE when directdraw objects are setup */ gboolean setup; - GMutex *pool_lock; - + /* overlays */ + gboolean bUseOverlay; + gboolean bIsOverlayVisible; guint color_key; - /*LPDIRECTDRAWSURFACE extern_surface; */ }; struct _GstDirectDrawSinkClass -- cgit v1.2.1 From 835917a6fef29c2e413e4b1b279076bbb985ad79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Moutte?= Date: Sun, 18 Feb 2007 18:00:51 +0000 Subject: [MOVED FROM GOOD] sys/directdraw/: Prepare the plugin to move to good: Original commit message from CVS: * sys/directdraw/gstdirectdrawplugin.c: * sys/directdraw/gstdirectdrawsink.c: * sys/directdraw/gstdirectdrawsink.h: Prepare the plugin to move to good: Remove unused/untested code (rendering to an extern surface, yuv format rendering).Use GST_(DEBUG/*)_OBJECT macros Rename all functions from gst_directdrawsink to gst_directdraw_sink. Add gtk doc section Fix a bug in gst_directdraw_sink_show_frame, memcpy line by line respecting destination surface stride. * sys/directsound/gstdirectsoundplugin.c: * sys/directsound/gstdirectsoundsink.c: * sys/directsound/gstdirectsoundsink.h: Prepare the plugin to move to good: Rename all functions from gst_directsoundsink to gst_directsound_sink. Add gtk doc section * win32/common/config.h.in: * win32/MANIFEST: Add config.h.in --- sys/directdraw/gstdirectdrawplugin.c | 2 +- sys/directdraw/gstdirectdrawsink.c | 1609 +++++++++++++--------------------- sys/directdraw/gstdirectdrawsink.h | 13 +- 3 files changed, 608 insertions(+), 1016 deletions(-) (limited to 'sys') diff --git a/sys/directdraw/gstdirectdrawplugin.c b/sys/directdraw/gstdirectdrawplugin.c index 728551e0..14943020 100644 --- a/sys/directdraw/gstdirectdrawplugin.c +++ b/sys/directdraw/gstdirectdrawplugin.c @@ -38,5 +38,5 @@ plugin_init (GstPlugin * plugin) GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, GST_VERSION_MINOR, "directdraw", - "DIRECTDRAW plugin library", + "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 index 099be4e9..4dd0d834 100644 --- a/sys/directdraw/gstdirectdrawsink.c +++ b/sys/directdraw/gstdirectdrawsink.c @@ -27,10 +27,17 @@ * * DirectdrawSink renders video 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 drawable. + * 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. * + * Examples + * + * Here is a simple pipeline to test the sink : + * + * gst-launch-0.10 -v videotestsrc ! directdrawsink + * + * * */ @@ -40,103 +47,76 @@ #include "gstdirectdrawsink.h" -#include -#include -#ifdef HAVE_UNISTD_H -#include -#endif -#include - GST_DEBUG_CATEGORY_STATIC (directdrawsink_debug); #define GST_CAT_DEFAULT directdrawsink_debug /* elementfactory information */ -static const GstElementDetails gst_directdrawsink_details = -GST_ELEMENT_DETAILS ("Video Sink (DIRECTDRAW)", +static const GstElementDetails gst_directdraw_sink_details = +GST_ELEMENT_DETAILS ("Direct Draw Video Sink", "Sink/Video", - "Output to a video card via DIRECTDRAW", + "Output to a video card via Direct Draw", "Sebastien Moutte "); -static void gst_directdrawsink_init_interfaces (GType type); - -GST_BOILERPLATE_FULL (GstDirectDrawSink, gst_directdrawsink, GstVideoSink, - GST_TYPE_VIDEO_SINK, gst_directdrawsink_init_interfaces); +static void gst_directdraw_sink_init_interfaces (GType type); -static void gst_directdrawsink_finalize (GObject * object); +GST_BOILERPLATE_FULL (GstDirectDrawSink, gst_directdraw_sink, GstVideoSink, + GST_TYPE_VIDEO_SINK, gst_directdraw_sink_init_interfaces); -static void gst_directdrawsink_set_property (GObject * object, +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_directdrawsink_get_property (GObject * object, +static void gst_directdraw_sink_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); - -static GstCaps *gst_directdrawsink_get_caps (GstBaseSink * bsink); -static gboolean gst_directdrawsink_set_caps (GstBaseSink * bsink, +static GstCaps *gst_directdraw_sink_get_caps (GstBaseSink * bsink); +static gboolean gst_directdraw_sink_set_caps (GstBaseSink * bsink, GstCaps * caps); - -static GstStateChangeReturn -gst_directdrawsink_change_state (GstElement * element, - GstStateChange transition); -static GstFlowReturn -gst_directdrawsink_buffer_alloc (GstBaseSink * bsink, guint64 offset, - guint size, GstCaps * caps, GstBuffer ** buf); -static void -gst_directdrawsink_get_times (GstBaseSink * bsink, GstBuffer * buf, +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_directdrawsink_show_frame (GstBaseSink * bsink, GstBuffer * buf); +static GstFlowReturn gst_directdraw_sink_show_frame (GstBaseSink * bsink, + GstBuffer * buf); -static gboolean gst_directdrawsink_setup_ddraw (GstDirectDrawSink * ddrawsink); -static gboolean gst_directdrawsink_create_default_window (GstDirectDrawSink * +/* utils */ +static gboolean gst_directdraw_sink_setup_ddraw (GstDirectDrawSink * ddrawsink); +static gboolean gst_directdraw_sink_create_default_window (GstDirectDrawSink * ddrawsink); -static gboolean gst_directdrawsink_create_ddraw_surfaces (GstDirectDrawSink * +static gboolean gst_directdraw_sink_create_ddraw_surface (GstDirectDrawSink * ddrawsink); - -static GstCaps *gst_directdrawsink_get_ddrawcaps (GstDirectDrawSink * +static GstCaps *gst_directdraw_sink_get_ddrawcaps (GstDirectDrawSink * ddrawsink); - -static void gst_directdrawsink_cleanup (GstDirectDrawSink * ddrawsink); -static void gst_directdrawsink_bufferpool_clear (GstDirectDrawSink * ddrawsink); - -static void -gst_directdrawsink_ddraw_put (GstDirectDrawSink * ddrawsink, +static void gst_directdraw_sink_cleanup (GstDirectDrawSink * ddrawsink); +static void gst_directdraw_sink_bufferpool_clear (GstDirectDrawSink * + ddrawsink); +static void gst_directdraw_sink_ddraw_put (GstDirectDrawSink * ddrawsink, GstDDrawSurface * surface); - /* surfaces management functions */ -static void -gst_directdrawsink_surface_destroy (GstDirectDrawSink * ddrawsink, +static void gst_directdraw_sink_surface_destroy (GstDirectDrawSink * ddrawsink, GstDDrawSurface * surface); - -static GstDDrawSurface *gst_directdrawsink_surface_create (GstDirectDrawSink * +static GstDDrawSurface *gst_directdraw_sink_surface_create (GstDirectDrawSink * ddrawsink, GstCaps * caps, size_t size); static GstStaticPadTemplate directdrawsink_sink_factory = - GST_STATIC_PAD_TEMPLATE ("sink", +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 ]" -/* "; " - "video/x-raw-yuv, " - "framerate = (fraction) [ 0, MAX ], " - "width = (int) [ 1, MAX ], " - "height = (int) [ 1, MAX ], " - "format = (fourcc) YV12" -*/ - ) + "width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ]") ); enum { PROP_0, - PROP_SURFACE, PROP_KEEP_ASPECT_RATIO }; -/* interfaces stuff */ +/* XOverlay interface implementation */ static gboolean -gst_directdrawsink_interface_supported (GstImplementsInterface * iface, +gst_directdraw_sink_interface_supported (GstImplementsInterface * iface, GType type) { g_assert (type == GST_TYPE_X_OVERLAY); @@ -144,13 +124,13 @@ gst_directdrawsink_interface_supported (GstImplementsInterface * iface, } static void -gst_directdrawsink_interface_init (GstImplementsInterfaceClass * klass) +gst_directdraw_sink_interface_init (GstImplementsInterfaceClass * klass) { - klass->supported = gst_directdrawsink_interface_supported; + klass->supported = gst_directdraw_sink_interface_supported; } static void -gst_directdrawsink_set_window_id (GstXOverlay * overlay, ULONG window_id) +gst_directdraw_sink_set_window_id (GstXOverlay * overlay, ULONG window_id) { GstDirectDrawSink *ddrawsink = GST_DIRECTDRAW_SINK (overlay); @@ -163,7 +143,6 @@ gst_directdrawsink_set_window_id (GstXOverlay * overlay, ULONG window_id) 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, @@ -173,31 +152,31 @@ gst_directdrawsink_set_window_id (GstXOverlay * overlay, ULONG window_id) } static void -gst_directdrawsink_expose (GstXOverlay * overlay) +gst_directdraw_sink_expose (GstXOverlay * overlay) { GstDirectDrawSink *ddrawsink = GST_DIRECTDRAW_SINK (overlay); - gst_directdrawsink_show_frame (GST_BASE_SINK (ddrawsink), NULL); + gst_directdraw_sink_show_frame (GST_BASE_SINK (ddrawsink), NULL); } static void -gst_directdrawsink_xoverlay_interface_init (GstXOverlayClass * iface) +gst_directdraw_sink_xoverlay_interface_init (GstXOverlayClass * iface) { - iface->set_xwindow_id = gst_directdrawsink_set_window_id; - iface->expose = gst_directdrawsink_expose; + iface->set_xwindow_id = gst_directdraw_sink_set_window_id; + iface->expose = gst_directdraw_sink_expose; } static void -gst_directdrawsink_init_interfaces (GType type) +gst_directdraw_sink_init_interfaces (GType type) { static const GInterfaceInfo iface_info = { - (GInterfaceInitFunc) gst_directdrawsink_interface_init, + (GInterfaceInitFunc) gst_directdraw_sink_interface_init, NULL, NULL, }; static const GInterfaceInfo xoverlay_info = { - (GInterfaceInitFunc) gst_directdrawsink_xoverlay_interface_init, + (GInterfaceInitFunc) gst_directdraw_sink_xoverlay_interface_init, NULL, NULL, }; @@ -207,25 +186,26 @@ gst_directdrawsink_init_interfaces (GType type) g_type_add_interface_static (type, GST_TYPE_X_OVERLAY, &xoverlay_info); } - /* Utility functions */ + +/* this function fill a DDPIXELFORMAT using Gstreamer caps */ static gboolean -gst_ddrawvideosink_get_format_from_caps (GstCaps * caps, - DDPIXELFORMAT * pPixelFormat) +gst_ddrawvideosink_get_format_from_caps (GstDirectDrawSink * ddrawsink, + GstCaps * caps, DDPIXELFORMAT * pPixelFormat) { GstStructure *structure = NULL; gboolean ret = TRUE; - /*check params */ + /* check params */ g_return_val_if_fail (pPixelFormat, FALSE); g_return_val_if_fail (caps, FALSE); - /*init structure */ + /* init structure */ memset (pPixelFormat, 0, sizeof (DDPIXELFORMAT)); pPixelFormat->dwSize = sizeof (DDPIXELFORMAT); if (!(structure = gst_caps_get_structure (caps, 0))) { - GST_CAT_ERROR (directdrawsink_debug, + GST_CAT_ERROR_OBJECT (directdrawsink_debug, ddrawsink, "can't get structure pointer from caps"); return FALSE; } @@ -238,500 +218,80 @@ gst_ddrawvideosink_get_format_from_caps (GstCaps * caps, 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")) { - gint fourcc; - - pPixelFormat->dwFlags = DDPF_FOURCC; - ret &= gst_structure_get_fourcc (structure, "format", &fourcc); - pPixelFormat->dwFourCC = fourcc; - } else { - GST_CAT_WARNING (directdrawsink_debug, - "unknown caps name received %" GST_PTR_FORMAT, caps); - ret = FALSE; - } - - return ret; -} - -/* -static GstCaps * -gst_ddrawvideosink_get_caps_from_format (DDPIXELFORMAT pixel_format) -{ - GstCaps *caps = NULL; - gint bpp, depth; - guint32 fourcc; - - if ((pixel_format.dwFlags & DDPF_RGB) == DDPF_RGB) { - bpp = pixel_format.dwRGBBitCount; - if (bpp != 32) - depth = bpp; - else { - if ((pixel_format.dwFlags & DDPF_ALPHAPREMULT) == DDPF_ALPHAPREMULT) - depth = 32; - else - depth = 24; - } - caps = gst_caps_new_simple ("video/x-raw-rgb", - "bpp", G_TYPE_INT, bpp, - "depth", G_TYPE_INT, depth, - "endianness", G_TYPE_INT, G_LITTLE_ENDIAN, - NULL); - } - - if ((pixel_format.dwFlags & DDPF_YUV) == DDPF_YUV) { - fourcc = pixel_format.dwFourCC; - caps = gst_caps_new_simple ("video/x-raw-yuv", - "format", GST_TYPE_FOURCC, fourcc, - NULL); - } - - g_assert (caps != NULL); - - return caps; -} -*/ - -static void -gst_directdrawsink_center_rect (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 (directdrawsink_debug, - "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); -} - -/************************************************************************/ -/* subclass of GstBuffer which manages surfaces lifetime */ -/* */ -/************************************************************************/ -static void -gst_ddrawsurface_finalize (GstDDrawSurface * surface) -{ - GstDirectDrawSink *ddrawsink = NULL; - - g_return_if_fail (surface != NULL); - - 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_CAT_INFO (directdrawsink_debug, - "destroy image as its size changed %dx%d vs current %dx%d", - surface->width, surface->height, ddrawsink->video_width, - ddrawsink->video_height); - gst_directdrawsink_surface_destroy (ddrawsink, surface); - - } else { - /* In that case we can reuse the image and add it to our image pool. */ - GST_CAT_INFO (directdrawsink_debug, "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"); - return; -} - -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); - - mini_object_class->finalize = (GstMiniObjectFinalizeFunction) - 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_directdrawsink_base_init (gpointer g_class) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); - - gst_element_class_set_details (element_class, &gst_directdrawsink_details); - - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&directdrawsink_sink_factory)); -} - -static void -gst_directdrawsink_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, - "Direct draw sink"); - - gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_directdrawsink_finalize); - - gobject_class->get_property = - GST_DEBUG_FUNCPTR (gst_directdrawsink_get_property); - gobject_class->set_property = - GST_DEBUG_FUNCPTR (gst_directdrawsink_set_property); - - gstelement_class->change_state = - GST_DEBUG_FUNCPTR (gst_directdrawsink_change_state); - gstbasesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_directdrawsink_get_caps); - gstbasesink_class->set_caps = GST_DEBUG_FUNCPTR (gst_directdrawsink_set_caps); - gstbasesink_class->preroll = - GST_DEBUG_FUNCPTR (gst_directdrawsink_show_frame); - gstbasesink_class->render = GST_DEBUG_FUNCPTR (gst_directdrawsink_show_frame); - - gstbasesink_class->get_times = - GST_DEBUG_FUNCPTR (gst_directdrawsink_get_times); - gstbasesink_class->buffer_alloc = - GST_DEBUG_FUNCPTR (gst_directdrawsink_buffer_alloc); - - /*install properties */ - /*extern surface where we will blit the video */ - g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_SURFACE, - g_param_spec_pointer ("surface", "Surface", - "The target surface for video", G_PARAM_WRITABLE)); - - /*setup aspect ratio mode */ - g_object_class_install_property (G_OBJECT_CLASS (klass), - PROP_KEEP_ASPECT_RATIO, g_param_spec_boolean ("keep-aspect-ratio", - "keep-aspect-ratio", "boolean to video keep aspect ratio", FALSE, - G_PARAM_READWRITE)); - - /*should add a color_key property to permit applications to define the color used for overlays */ -} - -static void -gst_directdrawsink_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec) -{ - GstDirectDrawSink *ddrawsink; - - ddrawsink = GST_DIRECTDRAW_SINK (object); - - switch (prop_id) { - case PROP_SURFACE: - ddrawsink->extern_surface = g_value_get_pointer (value); - break; - 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_directdrawsink_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec) -{ - GstDirectDrawSink *ddrawsink; - - 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_directdrawsink_finalize (GObject * object) -{ - GstDirectDrawSink *ddrawsink; - - ddrawsink = GST_DIRECTDRAW_SINK (object); - - if (ddrawsink->pool_lock) { - g_mutex_free (ddrawsink->pool_lock); - ddrawsink->pool_lock = NULL; - } - if (ddrawsink->setup) { - gst_directdrawsink_cleanup (ddrawsink); - } -} - -static void -gst_directdrawsink_init (GstDirectDrawSink * ddrawsink, - GstDirectDrawSinkClass * g_class) -{ - /*init members variables */ - ddrawsink->ddraw_object = NULL; - ddrawsink->primary_surface = NULL; - ddrawsink->overlays = NULL; - ddrawsink->clipper = NULL; - ddrawsink->extern_surface = NULL; - ddrawsink->video_window = NULL; - ddrawsink->our_video_window = TRUE; - ddrawsink->last_buffer = NULL; - - /*video default values */ - ddrawsink->video_height = 0; - ddrawsink->video_width = 0; - ddrawsink->fps_n = 0; - ddrawsink->fps_d = 0; - - memset (&ddrawsink->dd_pixel_format, 0, sizeof (DDPIXELFORMAT)); - - ddrawsink->caps = NULL; - ddrawsink->window_thread = NULL; - ddrawsink->bUseOverlay = FALSE; - ddrawsink->color_key = 0; /*need to be a public property and may be we can enable overlays when this property is set ... */ - - ddrawsink->setup = FALSE; - - ddrawsink->buffer_pool = NULL; - - - ddrawsink->pool_lock = g_mutex_new (); - ddrawsink->keep_aspect_ratio = FALSE; -} - -static GstCaps * -gst_directdrawsink_get_caps (GstBaseSink * bsink) -{ - GstDirectDrawSink *ddrawsink; - GstCaps *caps = NULL; - - ddrawsink = GST_DIRECTDRAW_SINK (bsink); - - if (!ddrawsink->setup) { - caps = gst_caps_copy (gst_pad_get_pad_template_caps (GST_VIDEO_SINK_PAD - (ddrawsink))); - - GST_CAT_INFO (directdrawsink_debug, - "getcaps called and we are not setup yet, " "returning template %" - GST_PTR_FORMAT, caps); - } else { - /*if (ddrawsink->extern_surface) { - * We are not rendering to our own surface, returning this surface's - * pixel format * - GST_WARNING ("using extern surface"); - caps = gst_ddrawvideosink_get_caps_from_format (ddrawsink->dd_pixel_format); - } else */ - - /* i think we can't really use the format of the extern surface as the application owning the surface doesn't know - the format we will render. But we need to use overlays to overlay any format on the extern surface */ - caps = gst_caps_ref (ddrawsink->caps); - } - - return caps; -} - -static gboolean -gst_directdrawsink_set_caps (GstBaseSink * bsink, GstCaps * caps) -{ - GstDirectDrawSink *ddrawsink; - GstStructure *structure = NULL; - gboolean ret; - const GValue *fps; - - ddrawsink = GST_DIRECTDRAW_SINK (bsink); - - GST_CAT_INFO (directdrawsink_debug, "set_caps"); - - 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 (caps, - &ddrawsink->dd_pixel_format); - if (!ret) - 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 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); - } + 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; - /* create an offscreen surface with the caps */ - ret = gst_directdrawsink_create_ddraw_surfaces (ddrawsink); - if (!ret && ddrawsink->bUseOverlay) { - GST_CAT_WARNING (directdrawsink_debug, - "Can not create overlay surface, reverting to no overlay display"); - ddrawsink->bUseOverlay = FALSE; - ret = gst_directdrawsink_create_ddraw_surfaces (ddrawsink); - if (ret) { - return TRUE; + 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")) { + gint fourcc; - /*could not create draw surfaces even with fallback, so leave everything as is */ - ddrawsink->bUseOverlay = TRUE; - } - if (!ret) { - GST_CAT_ERROR (directdrawsink_debug, "Can not create ddraw surface"); + 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; } -static GstStateChangeReturn -gst_directdrawsink_change_state (GstElement * element, - GstStateChange transition) +/* 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) { - GstDirectDrawSink *ddrawsink; - - ddrawsink = GST_DIRECTDRAW_SINK (element); - - switch (transition) { - case GST_STATE_CHANGE_NULL_TO_READY: - if (ddrawsink->video_window == NULL && ddrawsink->extern_surface == NULL) - if (!gst_directdrawsink_create_default_window (ddrawsink)) - return GST_STATE_CHANGE_FAILURE; + 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; - if (!gst_directdrawsink_setup_ddraw (ddrawsink)) - return GST_STATE_CHANGE_FAILURE; + g_return_if_fail (result != NULL); - if (!(ddrawsink->caps = gst_directdrawsink_get_ddrawcaps (ddrawsink))) - 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: + src_ratio = (gdouble) src_width / src_height; + dst_ratio = (gdouble) dst_width / dst_heigth; - ddrawsink->fps_n = 0; - ddrawsink->fps_d = 1; - ddrawsink->video_width = 0; - ddrawsink->video_height = 0; + if (src_ratio > dst_ratio) { + /* new height */ + result_height = (long) (dst_width / src_ratio); - if (ddrawsink->buffer_pool) - gst_directdrawsink_bufferpool_clear (ddrawsink); + result->left = dst.left; + result->right = dst.right; + result->top = dst.top + (dst_heigth - result_height) / 2; + result->bottom = result->top + result_height; - break; - case GST_STATE_CHANGE_READY_TO_NULL: + } else if (src_ratio < dst_ratio) { + /* new width */ + result_width = (long) (dst_heigth * src_ratio); - if (ddrawsink->setup) - gst_directdrawsink_cleanup (ddrawsink); + result->top = dst.top; + result->bottom = dst.bottom; + result->left = dst.left + (dst_width - result_width) / 2; + result->right = result->left + result_width; - break; + } else { + /* same ratio */ + memcpy (result, &dst, sizeof (RECT)); } - return GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); + 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); } /** @@ -944,31 +504,360 @@ DDErrorString (HRESULT hr) case DDERR_NOTINITIALIZED: return "DDERR_NOTINITIALIZED"; } - return "Unknown Error"; + return "Unknown Error"; +} + +/* Subclass of GstBuffer which manages buffer_pool surfaces lifetime */ +static void gst_ddrawsurface_finalize (GstDDrawSurface * surface); + +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); + + 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 (GstDDrawSurface * surface) +{ + GstDirectDrawSink *ddrawsink = NULL; + + g_return_if_fail (surface != NULL); + + 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_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); + + } 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_WARNING (directdrawsink_debug, "no sink found"); + 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 ("keep-aspect-ratio", + "keep-aspect-ratio", "keep the aspect ratio or not", 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); + } +} + +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 (); + 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 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); + } + + /* create an offscreen surface with the caps */ + ret = gst_directdraw_sink_create_ddraw_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);; + + switch (transition) { + case GST_STATE_CHANGE_NULL_TO_READY: + if (ddrawsink->video_window == NULL) + if (!gst_directdraw_sink_create_default_window (ddrawsink)) + return GST_STATE_CHANGE_FAILURE; + + if (!gst_directdraw_sink_setup_ddraw (ddrawsink)) + return GST_STATE_CHANGE_FAILURE; + + if (!(ddrawsink->caps = gst_directdraw_sink_get_ddrawcaps (ddrawsink))) + 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: + 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; + } + + return GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); +} static GstFlowReturn -gst_directdrawsink_buffer_alloc (GstBaseSink * bsink, guint64 offset, +gst_directdraw_sink_buffer_alloc (GstBaseSink * bsink, guint64 offset, guint size, GstCaps * caps, GstBuffer ** buf) { - GstDirectDrawSink *ddrawsink = NULL; + GstDirectDrawSink *ddrawsink = GST_DIRECTDRAW_SINK (bsink); GstDDrawSurface *surface = NULL; GstStructure *structure = NULL; GstFlowReturn ret = GST_FLOW_OK; - ddrawsink = GST_DIRECTDRAW_SINK (bsink); - GST_CAT_INFO (directdrawsink_debug, "a buffer of %d bytes was requested", - size); + GST_CAT_INFO_OBJECT (directdrawsink_debug, ddrawsink, + "a buffer of %d bytes was requested", size); structure = gst_caps_get_structure (caps, 0); - 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, @@ -980,7 +869,7 @@ gst_directdrawsink_buffer_alloc (GstBaseSink * bsink, guint64 offset, (memcmp (&surface->dd_pixel_format, &ddrawsink->dd_pixel_format, sizeof (DDPIXELFORMAT))) ) { - gst_directdrawsink_surface_destroy (ddrawsink, surface); + gst_directdraw_sink_surface_destroy (ddrawsink, surface); surface = NULL; } else { /* We found a suitable surface */ @@ -991,7 +880,7 @@ gst_directdrawsink_buffer_alloc (GstBaseSink * bsink, guint64 offset, /* We haven't found anything, creating a new one */ if (!surface) { - surface = gst_directdrawsink_surface_create (ddrawsink, caps, size); + surface = gst_directdraw_sink_surface_create (ddrawsink, caps, size); } /* Now we should have a surface, set appropriate caps on it */ @@ -1006,119 +895,39 @@ gst_directdrawsink_buffer_alloc (GstBaseSink * bsink, guint64 offset, return ret; } -static gboolean -gst_directdrawsink_fill_colorkey (LPDIRECTDRAWSURFACE surface, DWORD dwColorKey) -{ - DDBLTFX ddbfx; - - if (!surface) - return FALSE; - - ddbfx.dwSize = sizeof (DDBLTFX); - ddbfx.dwFillColor = dwColorKey; - - if (IDirectDrawSurface7_Blt (surface, - NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbfx) == DD_OK) - return TRUE; - else - return FALSE; -} - -static void -gst_directdrawsink_show_overlay (GstDirectDrawSink * ddrawsink) -{ - HRESULT hRes; - RECT destsurf_rect, src_rect; - POINT dest_surf_point; - DDOVERLAYFX ddofx; - LPDIRECTDRAWSURFACE surface = NULL; - - if (!ddrawsink || !ddrawsink->overlays) - return; - - if (ddrawsink->extern_surface) - surface = ddrawsink->extern_surface; - else - surface = ddrawsink->primary_surface; - - if (ddrawsink->extern_surface) { - destsurf_rect.left = 0; - destsurf_rect.top = 0; - destsurf_rect.right = ddrawsink->out_width; - destsurf_rect.bottom = ddrawsink->out_height; - } else { - 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) { - src_rect.top = 0; - src_rect.left = 0; - src_rect.bottom = ddrawsink->video_height; - src_rect.right = ddrawsink->video_width; - gst_directdrawsink_center_rect (src_rect, destsurf_rect, &destsurf_rect); - } - - gst_directdrawsink_fill_colorkey (surface, ddrawsink->color_key); - - ddofx.dwSize = sizeof (DDOVERLAYFX); - ddofx.dckDestColorkey.dwColorSpaceLowValue = ddrawsink->color_key; - ddofx.dckDestColorkey.dwColorSpaceHighValue = ddrawsink->color_key; - - hRes = IDirectDrawSurface7_UpdateOverlay (ddrawsink->overlays, - NULL, surface, &destsurf_rect, DDOVER_KEYDESTOVERRIDE | DDOVER_SHOW, - &ddofx); -} - static GstFlowReturn -gst_directdrawsink_show_frame (GstBaseSink * bsink, GstBuffer * buf) +gst_directdraw_sink_show_frame (GstBaseSink * bsink, GstBuffer * buf) { - GstDirectDrawSink *ddrawsink; + GstDirectDrawSink *ddrawsink = GST_DIRECTDRAW_SINK (bsink); HRESULT hRes; - - DDSURFACEDESC2 surf_desc; RECT destsurf_rect, src_rect; POINT dest_surf_point; - LPDIRECTDRAWSURFACE lpSurface = NULL; - - ddrawsink = GST_DIRECTDRAW_SINK (bsink); - if (buf) { - /*save a reference to the input buffer */ + /* save a reference to the input buffer */ if (ddrawsink->last_buffer != buf) { if (ddrawsink->last_buffer) { - GST_LOG_OBJECT (ddrawsink, "unreffing %p", ddrawsink->last_buffer); + GST_CAT_LOG_OBJECT (directdrawsink_debug, ddrawsink, "unreffing %p", + ddrawsink->last_buffer); gst_buffer_unref (ddrawsink->last_buffer); } } - GST_LOG_OBJECT (ddrawsink, "reffing %p as our current buffer", buf); + GST_CAT_LOG_OBJECT (directdrawsink_debug, ddrawsink, + "reffing %p as our current buffer", buf); ddrawsink->last_buffer = gst_buffer_ref (buf); } else { - /*use last buffer */ + /* use last buffer */ buf = ddrawsink->last_buffer; } - if (buf == NULL) return GST_FLOW_ERROR; - - - if (ddrawsink->extern_surface) { - destsurf_rect.left = 0; - destsurf_rect.top = 0; - destsurf_rect.right = ddrawsink->out_width; - destsurf_rect.bottom = ddrawsink->out_height; - } else { - 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); - } + /* get the video window position */ + 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 */ @@ -1126,106 +935,67 @@ gst_directdrawsink_show_frame (GstBaseSink * bsink, GstBuffer * buf) src_rect.left = 0; src_rect.bottom = ddrawsink->video_height; src_rect.right = ddrawsink->video_width; - gst_directdrawsink_center_rect (src_rect, destsurf_rect, &destsurf_rect); - } - - if (ddrawsink->bUseOverlay) { - /*get the back buffer of the overlays flipping chain */ - DDSCAPS ddbackcaps; - - ddbackcaps.dwCaps = DDSCAPS_BACKBUFFER; - hRes = - IDirectDrawSurface7_GetAttachedSurface (ddrawsink->overlays, - &ddbackcaps, &lpSurface); - GST_CAT_WARNING (directdrawsink_debug, - "gst_directdrawsink_show_frame failed getting overlay backbuffer %s", - DDErrorString (hRes)); - } else { - /*use our offscreen surface */ - lpSurface = ddrawsink->offscreen_surface; + gst_directdraw_sink_center_rect (ddrawsink, src_rect, destsurf_rect, + &destsurf_rect); } - if (lpSurface == NULL) - 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; - - /* Check for lost surface */ - if (IDirectDrawSurface7_IsLost (lpSurface) == DDERR_SURFACELOST) { - IDirectDrawSurface7_Restore (lpSurface); - } + guint src_pitch, line; + DDSURFACEDESC2 surf_desc; ZeroMemory (&surf_desc, sizeof (surf_desc)); surf_desc.dwSize = sizeof (surf_desc); + /* Check for lost surface */ + if (IDirectDrawSurface7_IsLost (ddrawsink->offscreen_surface) == + DDERR_SURFACELOST) { + IDirectDrawSurface7_Restore (ddrawsink->offscreen_surface); + } + /* Lock the surface */ hRes = - IDirectDrawSurface7_Lock (lpSurface, NULL, &surf_desc, DDLOCK_WAIT, - NULL); + IDirectDrawSurface7_Lock (ddrawsink->offscreen_surface, NULL, + &surf_desc, DDLOCK_WAIT, NULL); if (hRes != DD_OK) { - GST_CAT_WARNING (directdrawsink_debug, - "gst_directdrawsink_show_frame failed locking surface %s", + GST_CAT_WARNING_OBJECT (directdrawsink_debug, ddrawsink, + "gst_directdraw_sink_show_frame failed locking surface %s", DDErrorString (hRes)); return GST_FLOW_ERROR; } - /* Write data */ + /* Write each line respecting the destination surface pitch */ data = surf_desc.lpSurface; - - /* Source video rowbytes */ src_pitch = GST_BUFFER_SIZE (buf) / ddrawsink->video_height; - - /* Write each line respecting dest surface pitch */ -/* for (line = 0; line < surf_desc.dwHeight; line++) { - memcpy (data, GST_BUFFER_DATA (buf) + (line * src_pitch), - src_pitch); + for (line = 0; line < surf_desc.dwHeight; line++) { + memcpy (data, GST_BUFFER_DATA (buf) + (line * src_pitch), src_pitch); data += surf_desc.lPitch; - }*/ - memcpy (data, GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf)); + } /* Unlock the surface */ - hRes = IDirectDrawSurface7_Unlock (lpSurface, NULL); + hRes = IDirectDrawSurface7_Unlock (ddrawsink->offscreen_surface, NULL); if (hRes != DD_OK) { - GST_CAT_WARNING (directdrawsink_debug, - "gst_directdrawsink_show_frame failed unlocking surface %s", + GST_CAT_WARNING_OBJECT (directdrawsink_debug, ddrawsink, + "gst_directdraw_sink_show_frame failed unlocking surface %s", DDErrorString (hRes)); return GST_FLOW_ERROR; } - if (ddrawsink->bUseOverlay) { - /*Flip to front overlay */ - hRes = - IDirectDrawSurface7_Flip (ddrawsink->overlays, lpSurface, - DDFLIP_WAIT); - IDirectDrawSurface7_Release (lpSurface); - lpSurface = NULL; - } else { - if (ddrawsink->extern_surface) { - if (ddrawsink->out_height == ddrawsink->video_height && - ddrawsink->out_width == ddrawsink->video_width) { - /*Fast blit to extern surface */ - hRes = IDirectDrawSurface7_BltFast (ddrawsink->extern_surface, 0, 0, - lpSurface, NULL, DDBLTFAST_WAIT); - - } else { - /*blit to extern surface (Blt will scale the video the dest rect surface if needed) */ - hRes = - IDirectDrawSurface7_Blt (ddrawsink->extern_surface, - &destsurf_rect, lpSurface, NULL, DDBLT_WAIT, NULL); - } - } else { - /*blit to primary surface ( Blt will scale the video the dest rect surface if needed */ - hRes = - IDirectDrawSurface7_Blt (ddrawsink->primary_surface, &destsurf_rect, - lpSurface, NULL, DDBLT_WAIT, NULL); - } - } - } else { + /* 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) + 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); @@ -1239,138 +1009,72 @@ gst_directdrawsink_show_frame (GstBaseSink * bsink, GstBuffer * buf) IDirectDrawSurface7_Restore (surface->surface); } - if (ddrawsink->bUseOverlay) { - /* blit to the overlays back buffer */ - hRes = IDirectDrawSurface7_Blt (lpSurface, NULL, - surface->surface, NULL, DDBLT_WAIT, NULL); - - hRes = IDirectDrawSurface7_Flip (ddrawsink->overlays, NULL, DDFLIP_WAIT); - if (hRes != DD_OK) - GST_CAT_WARNING (directdrawsink_debug, "error flipping"); - - } else { - if (ddrawsink->extern_surface) { - /*blit to the extern surface */ - if (ddrawsink->out_height == ddrawsink->video_height && - ddrawsink->out_width == ddrawsink->video_width) { - /*Fast blit to extern surface */ - hRes = IDirectDrawSurface7_BltFast (ddrawsink->extern_surface, 0, 0, - surface->surface, NULL, DDBLTFAST_WAIT); - - } else { - /*blit to extern surface (Blt will scale the video the dest rect surface if needed) */ - hRes = - IDirectDrawSurface7_Blt (ddrawsink->extern_surface, - &destsurf_rect, surface->surface, NULL, DDBLT_WAIT, NULL); - } - } else { - /*blit to our primary surface */ - hRes = - IDirectDrawSurface7_Blt (ddrawsink->primary_surface, &destsurf_rect, - surface->surface, NULL, DDBLT_WAIT, NULL); - if (hRes != DD_OK) - GST_CAT_WARNING (directdrawsink_debug, - "IDirectDrawSurface7_Blt returned %s", DDErrorString (hRes)); - else - GST_CAT_INFO (directdrawsink_debug, - "allocated surface was blit to our primary"); - } - } + /* blit to our primary surface */ + hRes = IDirectDrawSurface7_Blt (ddrawsink->primary_surface, &destsurf_rect, + surface->surface, NULL, DDBLT_WAIT, NULL); + if (hRes != DD_OK) + GST_CAT_WARNING_OBJECT (directdrawsink_debug, ddrawsink, + "IDirectDrawSurface7_Blt (offscreen surface from buffer_alloc) " + "returned %s", DDErrorString (hRes)); } - if (ddrawsink->bUseOverlay) - gst_directdrawsink_show_overlay (ddrawsink); - return GST_FLOW_OK; } static gboolean -gst_directdrawsink_setup_ddraw (GstDirectDrawSink * ddrawsink) +gst_directdraw_sink_setup_ddraw (GstDirectDrawSink * ddrawsink) { gboolean bRet = TRUE; HRESULT hRes; DDSURFACEDESC2 dd_surface_desc; - //create an instance of the ddraw object + /* 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_CAT_ERROR (directdrawsink_debug, "DirectDrawCreate failed with: %s", - DDErrorString (hRes)); + 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, ddrawsink->video_window, DDSCL_NORMAL); - if (hRes != DD_OK) { - GST_CAT_ERROR (directdrawsink_debug, "SetCooperativeLevel failed with: %s", - DDErrorString (hRes)); - bRet = FALSE; + GST_ELEMENT_ERROR (ddrawsink, RESOURCE, WRITE, + ("Failed to set the set the cooperative level error=%s", + DDErrorString (hRes)), (NULL)); + return FALSE; } - if (!ddrawsink->extern_surface) { - /*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; - - hRes = - IDirectDraw7_CreateSurface (ddrawsink->ddraw_object, &dd_surface_desc, - &ddrawsink->primary_surface, NULL); - if (hRes != DD_OK) { - GST_CAT_ERROR (directdrawsink_debug, - "CreateSurface (primary) failed with: %s", DDErrorString (hRes)); - IDirectDraw7_Release (ddrawsink->ddraw_object); - return FALSE; - } - - /* setup the clipper object */ - hRes = IDirectDraw7_CreateClipper (ddrawsink->ddraw_object, 0, - &ddrawsink->clipper, NULL); - if (hRes == DD_OK) { - hRes = IDirectDrawClipper_SetHWnd (ddrawsink->clipper, 0, - ddrawsink->video_window); - - hRes = IDirectDrawSurface7_SetClipper (ddrawsink->primary_surface, - ddrawsink->clipper); - } - - } else { - DDSURFACEDESC2 desc_surface; - - desc_surface.dwSize = sizeof (DDSURFACEDESC2); - - /*get extern surface size */ - hRes = IDirectDrawSurface7_GetSurfaceDesc (ddrawsink->extern_surface, - &desc_surface); - if (hRes != DD_OK) { - /*error while retrieving ext surface description */ - return FALSE; - } - - ddrawsink->out_width = desc_surface.dwWidth; - ddrawsink->out_height = desc_surface.dwHeight; - - /*get extern surface pixel format (FIXME not needed if we are using overlays) */ - ddrawsink->dd_pixel_format.dwSize = sizeof (DDPIXELFORMAT); - hRes = IDirectDrawSurface7_GetPixelFormat (ddrawsink->extern_surface, - &ddrawsink->dd_pixel_format); - if (hRes != DD_OK) { - /*error while retrieving ext surface pixel format */ - GST_CAT_WARNING (directdrawsink_debug, - "GetPixelFormat (ddrawsink->extern_surface) failed with: %s", - DDErrorString (hRes)); - return FALSE; - } + /*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; + hRes = IDirectDraw7_CreateSurface (ddrawsink->ddraw_object, &dd_surface_desc, + &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; + } - /*get specific caps if needed ... */ + /* setup the clipper object */ + hRes = IDirectDraw7_CreateClipper (ddrawsink->ddraw_object, 0, + &ddrawsink->clipper, NULL); + if (hRes == DD_OK) { + hRes = IDirectDrawClipper_SetHWnd (ddrawsink->clipper, 0, + ddrawsink->video_window); + hRes = IDirectDrawSurface7_SetClipper (ddrawsink->primary_surface, + ddrawsink->clipper); } + /* directdraw objects are setup */ ddrawsink->setup = TRUE; return bRet; @@ -1382,24 +1086,6 @@ WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) switch (message) { case WM_ERASEBKGND: return TRUE; -/* case WM_WINDOWPOSCHANGED: - case WM_MOVE: - case WM_SIZE: - if(global_ddrawsink && global_ddrawsink->bUseOverlay) - gst_directdrawsink_show_overlay(global_ddrawsink); - break; - case WM_PAINT: - if(global_ddrawsink && global_ddrawsink->bUseOverlay) - { - if(global_ddrawsink->extern_surface) - gst_directdrawsink_fill_colorkey(global_ddrawsink->extern_surface, - global_ddrawsink->color_key); - else - gst_directdrawsink_fill_colorkey(global_ddrawsink->primary_surface, - global_ddrawsink->color_key); - } - break; -*/ case WM_DESTROY: PostQuitMessage (0); break; @@ -1411,12 +1097,11 @@ WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) } static gpointer -gst_directdrawsink_window_thread (GstDirectDrawSink * ddrawsink) +gst_directdraw_sink_window_thread (GstDirectDrawSink * ddrawsink) { WNDCLASS WndClass; memset (&WndClass, 0, sizeof (WNDCLASS)); - WndClass.style = CS_HREDRAW | CS_VREDRAW; WndClass.hInstance = GetModuleHandle (NULL); WndClass.lpszClassName = "GStreamer-DirectDraw"; @@ -1425,24 +1110,22 @@ gst_directdrawsink_window_thread (GstDirectDrawSink * ddrawsink) 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 FALSE; /* signal application we create a window */ gst_x_overlay_got_xwindow_id (GST_X_OVERLAY (ddrawsink), - ddrawsink->video_window); + (gulong) ddrawsink->video_window); ReleaseSemaphore (ddrawsink->window_created_signal, 1, NULL); - /*start message loop processing our default window messages */ + /* start message loop processing our default window messages */ while (1) { MSG msg; @@ -1455,14 +1138,14 @@ gst_directdrawsink_window_thread (GstDirectDrawSink * ddrawsink) } static gboolean -gst_directdrawsink_create_default_window (GstDirectDrawSink * ddrawsink) +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_directdrawsink_window_thread, ddrawsink, TRUE, NULL); + (GThreadFunc) gst_directdraw_sink_window_thread, ddrawsink, TRUE, NULL); if (ddrawsink->window_thread == NULL) goto failed; @@ -1477,18 +1160,20 @@ gst_directdrawsink_create_default_window (GstDirectDrawSink * ddrawsink) failed: CloseHandle (ddrawsink->window_created_signal); + GST_ELEMENT_ERROR (ddrawsink, RESOURCE, WRITE, + ("Error creating our default window"), (NULL)); + return FALSE; } static gboolean -gst_directdrawsink_create_ddraw_surfaces (GstDirectDrawSink * ddrawsink) +gst_directdraw_sink_create_ddraw_surface (GstDirectDrawSink * ddrawsink) { DDSURFACEDESC2 dd_surface_desc; HRESULT hRes; 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; @@ -1496,45 +1181,22 @@ gst_directdrawsink_create_ddraw_surfaces (GstDirectDrawSink * ddrawsink) memcpy (&(dd_surface_desc.ddpfPixelFormat), &ddrawsink->dd_pixel_format, sizeof (DDPIXELFORMAT)); - if (ddrawsink->bUseOverlay) { - /*create overlays flipping chain */ - dd_surface_desc.ddsCaps.dwCaps = - DDSCAPS_OVERLAY | DDSCAPS_VIDEOMEMORY | DDSCAPS_FLIP | DDSCAPS_COMPLEX; - dd_surface_desc.dwFlags |= DDSD_BACKBUFFERCOUNT; - dd_surface_desc.dwBackBufferCount = 1; - - hRes = - IDirectDraw7_CreateSurface (ddrawsink->ddraw_object, &dd_surface_desc, - &ddrawsink->overlays, NULL); - - if (hRes != DD_OK) { - GST_CAT_WARNING (directdrawsink_debug, - "create_ddraw_surfaces:CreateSurface(overlays) failed %s", - DDErrorString (hRes)); - return FALSE; - } else { - GST_CAT_INFO (directdrawsink_debug, - "An overlay surfaces flipping chain was created"); - } - } else { - dd_surface_desc.ddsCaps.dwCaps = - DDSCAPS_OFFSCREENPLAIN /*|DDSCAPS_SYSTEMMEMORY */ ; - hRes = - IDirectDraw7_CreateSurface (ddrawsink->ddraw_object, &dd_surface_desc, - &ddrawsink->offscreen_surface, NULL); - if (hRes != DD_OK) { - GST_CAT_WARNING (directdrawsink_debug, - "create_ddraw_surfaces:CreateSurface(offscreen) failed %s", - DDErrorString (hRes)); - return FALSE; - } + dd_surface_desc.ddsCaps.dwCaps = + DDSCAPS_OFFSCREENPLAIN /*|DDSCAPS_SYSTEMMEMORY */ ; + hRes = + IDirectDraw7_CreateSurface (ddrawsink->ddraw_object, &dd_surface_desc, + &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; } - return TRUE; } static void -gst_directdrawsink_get_times (GstBaseSink * bsink, GstBuffer * buf, +gst_directdraw_sink_get_times (GstBaseSink * bsink, GstBuffer * buf, GstClockTime * start, GstClockTime * end) { GstDirectDrawSink *ddrawsink; @@ -1554,7 +1216,7 @@ gst_directdrawsink_get_times (GstBaseSink * bsink, GstBuffer * buf, } static int -gst_directdrawsink_get_depth (LPDDPIXELFORMAT lpddpfPixelFormat) +gst_directdraw_sink_get_depth (LPDDPIXELFORMAT lpddpfPixelFormat) { gint order = 0, binary; @@ -1580,7 +1242,7 @@ EnumModesCallback2 (LPDDSURFACEDESC2 lpDDSurfaceDesc, LPVOID lpContext) return DDENUMRET_CANCEL; if ((lpDDSurfaceDesc->dwFlags & DDSD_PIXELFORMAT) != DDSD_PIXELFORMAT) { - GST_CAT_INFO (directdrawsink_debug, + GST_CAT_INFO_OBJECT (directdrawsink_debug, ddrawsink, "Display mode found with DDSD_PIXELFORMAT not set"); return DDENUMRET_OK; } @@ -1594,7 +1256,7 @@ EnumModesCallback2 (LPDDSURFACEDESC2 lpDDSurfaceDesc, LPVOID lpContext) "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, "bpp", G_TYPE_INT, lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount, "depth", G_TYPE_INT, - gst_directdrawsink_get_depth (&lpDDSurfaceDesc->ddpfPixelFormat), + gst_directdraw_sink_get_depth (&lpDDSurfaceDesc->ddpfPixelFormat), "endianness", G_TYPE_INT, G_LITTLE_ENDIAN, "red_mask", G_TYPE_INT, lpDDSurfaceDesc->ddpfPixelFormat.dwRBitMask, "green_mask", G_TYPE_INT, lpDDSurfaceDesc->ddpfPixelFormat.dwGBitMask, "blue_mask", G_TYPE_INT, @@ -1608,7 +1270,7 @@ EnumModesCallback2 (LPDDSURFACEDESC2 lpDDSurfaceDesc, LPVOID lpContext) } static GstCaps * -gst_directdrawsink_get_ddrawcaps (GstDirectDrawSink * ddrawsink) +gst_directdraw_sink_get_ddrawcaps (GstDirectDrawSink * ddrawsink) { HRESULT hRes = S_OK; DWORD dwFourccCodeIndex = 0; @@ -1629,26 +1291,25 @@ gst_directdrawsink_get_ddrawcaps (GstDirectDrawSink * ddrawsink) &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; gint endianness = G_LITTLE_ENDIAN; gint depth; - GST_CAT_INFO (directdrawsink_debug, + 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"); surface_desc.dwSize = sizeof (DDSURFACEDESC); hRes = IDirectDraw7_GetDisplayMode (ddrawsink->ddraw_object, &surface_desc); if (hRes != DD_OK) { - GST_CAT_ERROR (directdrawsink_debug, - "Error getting the current display mode (%s)", DDErrorString (hRes)); + GST_ELEMENT_ERROR (ddrawsink, CORE, NEGOTIATION, + ("Error getting the current display mode error=%s", + DDErrorString (hRes)), (NULL)); return NULL; } - depth = gst_directdrawsink_get_depth (&surface_desc.ddpfPixelFormat); + depth = gst_directdraw_sink_get_depth (&surface_desc.ddpfPixelFormat); if (surface_desc.ddpfPixelFormat.dwRGBBitCount == 24 || surface_desc.ddpfPixelFormat.dwRGBBitCount == 32) { @@ -1660,6 +1321,11 @@ gst_directdrawsink_get_ddrawcaps (GstDirectDrawSink * ddrawsink) GUINT32_TO_BE (surface_desc.ddpfPixelFormat.dwGBitMask); surface_desc.ddpfPixelFormat.dwBBitMask = GUINT32_TO_BE (surface_desc.ddpfPixelFormat.dwBBitMask); + if (surface_desc.ddpfPixelFormat.dwRGBBitCount == 24) { + surface_desc.ddpfPixelFormat.dwRBitMask >>= 8; + surface_desc.ddpfPixelFormat.dwGBitMask >>= 8; + surface_desc.ddpfPixelFormat.dwBBitMask >>= 8; + } } format_caps = gst_caps_new_simple ("video/x-raw-rgb", @@ -1677,88 +1343,48 @@ gst_directdrawsink_get_ddrawcaps (GstDirectDrawSink * ddrawsink) gst_caps_append (ddrawsink->caps, format_caps); } - GST_CAT_INFO (directdrawsink_debug, "returning caps %s", + GST_CAT_INFO_OBJECT (directdrawsink_debug, ddrawsink, "returning caps %s", gst_caps_to_string (ddrawsink->caps)); - return ddrawsink->caps; } - GST_CAT_INFO (directdrawsink_debug, + GST_CAT_INFO_OBJECT (directdrawsink_debug, ddrawsink, "the hardware can blit from one colorspace to another, " "then enumerate the colorspace supported by the hardware"); /* enumerate display modes exposed by directdraw object - to know supported RGB mode */ + to know supported RGB modes */ hRes = IDirectDraw7_EnumDisplayModes (ddrawsink->ddraw_object, DDEDM_REFRESHRATES, NULL, ddrawsink, EnumModesCallback2); if (hRes != DD_OK) { - GST_CAT_WARNING (directdrawsink_debug, "EnumDisplayModes returns: %s", - DDErrorString (hRes)); - return FALSE; - } + GST_ELEMENT_ERROR (ddrawsink, CORE, NEGOTIATION, + ("Error enumerating display modes error=%s", DDErrorString (hRes)), + (NULL)); - /* enumerate non-rgb modes exposed by directdraw object */ -/* IDirectDraw7_GetFourCCCodes(ddrawsink->ddraw_object, &dwNbFourccCodes, NULL); - if(dwNbFourccCodes != 0) - { - pdwFourccCodes = g_new0(DWORD, dwNbFourccCodes); - if(!pdwFourccCodes) - return FALSE; - - if (FAILED(IDirectDraw7_GetFourCCCodes(ddrawsink->ddraw_object, &dwNbFourccCodes, - pdwFourccCodes))) - { - g_free(pdwFourccCodes); - return FALSE; - } - - for(dwFourccCodeIndex = 0; dwFourccCodeIndex < dwNbFourccCodes; dwFourccCodeIndex++) - { - /*support only yuv formats YUY2, UYVY, YVU9, YV12, AYUV - if(/*pdwFourccCodes[dwFourccCodeIndex] == mmioFOURCC('Y','U','Y','2') || - pdwFourccCodes[dwFourccCodeIndex] == mmioFOURCC('U','Y','V','Y') || - pdwFourccCodes[dwFourccCodeIndex] == mmioFOURCC('Y','V','U','9') || - pdwFourccCodes[dwFourccCodeIndex] == mmioFOURCC('Y','V','1','2') /*|| - pdwFourccCodes[dwFourccCodeIndex] == mmioFOURCC('A','Y','U','V') - ) - { - format_caps = gst_caps_new_simple ("video/x-raw-yuv", - "format", GST_TYPE_FOURCC, pdwFourccCodes[dwFourccCodeIndex], - "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, NULL); - - if(format_caps) - gst_caps_append (ddrawsink->caps, format_caps); - } - } - - g_free(pdwFourccCodes); + return NULL; } -*/ if (gst_caps_is_empty (ddrawsink->caps)) { gst_caps_unref (ddrawsink->caps); - - GST_ELEMENT_ERROR (ddrawsink, STREAM, WRONG_TYPE, (NULL), - ("No supported format found")); + ddrawsink->caps = NULL; + GST_ELEMENT_ERROR (ddrawsink, CORE, NEGOTIATION, + ("No supported caps found."), (NULL)); return NULL; } -// GST_CAT_INFO (directdrawsink_debug, "returning caps %s", gst_caps_to_string (ddrawsink->caps)); + //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_directdrawsink_surface_create (GstDirectDrawSink * ddrawsink, +gst_directdraw_sink_surface_create (GstDirectDrawSink * ddrawsink, GstCaps * caps, size_t size) { GstDDrawSurface *surface = NULL; GstStructure *structure = NULL; gint pitch; - HRESULT hRes; DDSURFACEDESC2 surf_desc, surf_lock_desc; @@ -1777,15 +1403,15 @@ gst_directdrawsink_surface_create (GstDirectDrawSink * ddrawsink, 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_WARNING ("failed getting geometry from caps %" GST_PTR_FORMAT, caps); + 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 (caps, + if (!gst_ddrawvideosink_get_format_from_caps (ddrawsink, caps, &surface->dd_pixel_format)) { - GST_WARNING ("failed getting pixel format from caps %" GST_PTR_FORMAT, - caps); + GST_CAT_WARNING_OBJECT (directdrawsink_debug, ddrawsink, + "failed getting pixel format from caps %" GST_PTR_FORMAT, caps); } if (ddrawsink->ddraw_object) { @@ -1798,16 +1424,12 @@ gst_directdrawsink_surface_create (GstDirectDrawSink * ddrawsink, 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) { - /*gst_object_unref (surface); - surface = NULL; - goto beach; */ goto surface_pitch_bad; } @@ -1821,60 +1443,43 @@ gst_directdrawsink_surface_create (GstDirectDrawSink * ddrawsink, IDirectDrawSurface7_Restore (surface->surface); goto lock; } - surface->locked = TRUE; if (surf_lock_desc.lPitch != pitch) { - GST_CAT_INFO (directdrawsink_debug, - "DDraw stride/pitch %ld isn't as expected value %d, let's continue allocating buffer.", + 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_CAT_INFO (directdrawsink_debug, - "allocating a surface of %d bytes (stride=%ld)\n", size, - surf_lock_desc.lPitch); 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); } else { surface_pitch_bad: GST_BUFFER (surface)->malloc_data = g_malloc (size); GST_BUFFER_DATA (surface) = GST_BUFFER (surface)->malloc_data; GST_BUFFER_SIZE (surface) = size; - -/* surf_desc.dwSize = sizeof(DDSURFACEDESC2); - surf_desc.dwFlags = DDSD_PITCH | DDSD_LPSURFACE | DDSD_HEIGHT | DDSD_WIDTH ||DDSD_PIXELFORMAT; - surf_desc.lpSurface = GST_BUFFER (surface)->malloc_data; - surf_desc.lPitch = pitch; - //surf_desc.dwHeight = surface->height; - surf_desc.dwWidth = surface->width; - hRes = IDirectDrawSurface7_SetSurfaceDesc(surface->surface, &surf_desc, 0); - printf("%\n", DDErrorString(hRes)); - - hRes = IDirectDrawSurface7_Lock (surface->surface, NULL, &surf_lock_desc, - DDLOCK_WAIT | DDLOCK_NOSYSLOCK, NULL); -*/ surface->surface = NULL; - /*printf ("allocating a buffer of %d bytes\n", size); */ + GST_CAT_INFO_OBJECT (directdrawsink_debug, ddrawsink, + "allocating a system memory buffer of %d bytes", size); } /* Keep a ref to our sink */ surface->ddrawsink = gst_object_ref (ddrawsink); - /* - beach: - */ 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_directdrawsink_surface_destroy (GstDirectDrawSink * ddrawsink, +gst_directdraw_sink_surface_destroy (GstDirectDrawSink * ddrawsink, GstDDrawSurface * surface) { g_return_if_fail (GST_IS_DIRECTDRAW_SINK (ddrawsink)); @@ -1910,7 +1515,7 @@ no_sink: } static void -gst_directdrawsink_bufferpool_clear (GstDirectDrawSink * ddrawsink) +gst_directdraw_sink_bufferpool_clear (GstDirectDrawSink * ddrawsink) { g_mutex_lock (ddrawsink->pool_lock); while (ddrawsink->buffer_pool) { @@ -1918,15 +1523,14 @@ gst_directdrawsink_bufferpool_clear (GstDirectDrawSink * ddrawsink) ddrawsink->buffer_pool = g_slist_delete_link (ddrawsink->buffer_pool, ddrawsink->buffer_pool); - gst_directdrawsink_surface_destroy (ddrawsink, surface); + gst_directdraw_sink_surface_destroy (ddrawsink, surface); } g_mutex_unlock (ddrawsink->pool_lock); } static void -gst_directdrawsink_cleanup (GstDirectDrawSink * ddrawsink) +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); @@ -1937,15 +1541,10 @@ gst_directdrawsink_cleanup (GstDirectDrawSink * ddrawsink) } if (ddrawsink->buffer_pool) { - gst_directdrawsink_bufferpool_clear (ddrawsink); + gst_directdraw_sink_bufferpool_clear (ddrawsink); ddrawsink->buffer_pool = NULL; } - if (ddrawsink->overlays) { - IDirectDrawSurface7_Release (ddrawsink->overlays); - ddrawsink->overlays = NULL; - } - if (ddrawsink->offscreen_surface) { IDirectDrawSurface7_Release (ddrawsink->offscreen_surface); ddrawsink->offscreen_surface = NULL; diff --git a/sys/directdraw/gstdirectdrawsink.h b/sys/directdraw/gstdirectdrawsink.h index 1a32c5a5..85ed0824 100644 --- a/sys/directdraw/gstdirectdrawsink.h +++ b/sys/directdraw/gstdirectdrawsink.h @@ -33,7 +33,7 @@ #include G_BEGIN_DECLS -#define GST_TYPE_DIRECTDRAW_SINK (gst_directdrawsink_get_type()) +#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)) @@ -85,7 +85,6 @@ struct _GstDirectDrawSink LPDIRECTDRAW ddraw_object; LPDIRECTDRAWSURFACE primary_surface; LPDIRECTDRAWSURFACE offscreen_surface; - LPDIRECTDRAWSURFACE overlays; LPDIRECTDRAWCLIPPER clipper; /* last buffer displayed (used for XOverlay interface expose method) */ @@ -105,8 +104,7 @@ struct _GstDirectDrawSink gint fps_n; gint fps_d; - /*properties*/ - LPDIRECTDRAWSURFACE extern_surface; + /* properties */ gboolean keep_aspect_ratio; /*pixel format */ @@ -117,11 +115,6 @@ struct _GstDirectDrawSink /* TRUE when directdraw objects are setup */ gboolean setup; - - /* overlays */ - gboolean bUseOverlay; - gboolean bIsOverlayVisible; - guint color_key; }; struct _GstDirectDrawSinkClass @@ -129,7 +122,7 @@ struct _GstDirectDrawSinkClass GstVideoSinkClass parent_class; }; -GType gst_directdrawsink_get_type (void); +GType gst_direct_drawsink_get_type (void); G_END_DECLS #endif /* __GST_DIRECTDRAWSINK_H__ */ -- cgit v1.2.1 From 2949448e31eceb4f2066712d669efb4b4a9b85aa Mon Sep 17 00:00:00 2001 From: Christian Schaller Date: Tue, 27 Feb 2007 12:02:03 +0000 Subject: [MOVED FROM GOOD] update copyright statements Original commit message from CVS: update copyright statements --- sys/directdraw/gstdirectdrawplugin.c | 5 +++++ sys/directdraw/gstdirectdrawsink.c | 8 ++++++-- sys/directdraw/gstdirectdrawsink.h | 5 +++++ 3 files changed, 16 insertions(+), 2 deletions(-) (limited to 'sys') diff --git a/sys/directdraw/gstdirectdrawplugin.c b/sys/directdraw/gstdirectdrawplugin.c index 14943020..190bd02e 100644 --- a/sys/directdraw/gstdirectdrawplugin.c +++ b/sys/directdraw/gstdirectdrawplugin.c @@ -1,5 +1,6 @@ /* GStreamer * Copyright (C) 2005 Sebastien Moutte +* Copyright (C) 2007 Pioneers of the Inevitable * * gstdirectdrawplugin.c: * @@ -17,6 +18,10 @@ * 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 diff --git a/sys/directdraw/gstdirectdrawsink.c b/sys/directdraw/gstdirectdrawsink.c index 4dd0d834..b7e3fc86 100644 --- a/sys/directdraw/gstdirectdrawsink.c +++ b/sys/directdraw/gstdirectdrawsink.c @@ -1,5 +1,6 @@ /* GStreamer * Copyright (C) 2005 Sebastien Moutte +* Copyright (C) 2007 Pioneers of the Inevitable * * Based on directfb video sink * gstdirectdrawsink.c: @@ -18,6 +19,10 @@ * 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 +* */ /** @@ -1030,8 +1035,7 @@ gst_directdraw_sink_setup_ddraw (GstDirectDrawSink * ddrawsink) /* 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, + 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, diff --git a/sys/directdraw/gstdirectdrawsink.h b/sys/directdraw/gstdirectdrawsink.h index 85ed0824..3bd55dd3 100644 --- a/sys/directdraw/gstdirectdrawsink.h +++ b/sys/directdraw/gstdirectdrawsink.h @@ -1,5 +1,6 @@ /* GStreamer * Copyright (C) 2005 Sebastien Moutte + * Copyright (C) 2007 Pioneers of the Inevitable * * gstdirectdrawsink.h: * @@ -17,6 +18,10 @@ * 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 + * */ -- cgit v1.2.1 From bf5c0a89f0078ea886e80eeaaf826003cd515982 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Moutte?= Date: Sun, 11 Mar 2007 22:23:04 +0000 Subject: [MOVED FROM GOOD] sys/directdraw/gstdirectdrawsink.*: Handle display mode changes during playback. Original commit message from CVS: * sys/directdraw/gstdirectdrawsink.c: * sys/directdraw/gstdirectdrawsink.h: Handle display mode changes during playback. --- sys/directdraw/gstdirectdrawsink.c | 1137 +++++++++++++++++++++--------------- sys/directdraw/gstdirectdrawsink.h | 9 + 2 files changed, 686 insertions(+), 460 deletions(-) (limited to 'sys') diff --git a/sys/directdraw/gstdirectdrawsink.c b/sys/directdraw/gstdirectdrawsink.c index b7e3fc86..ab778c84 100644 --- a/sys/directdraw/gstdirectdrawsink.c +++ b/sys/directdraw/gstdirectdrawsink.c @@ -30,7 +30,7 @@ * * * - * DirectdrawSink renders video frames to any win32 window. This element can receive + * 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 @@ -88,21 +88,32 @@ static GstFlowReturn gst_directdraw_sink_show_frame (GstBaseSink * bsink, static gboolean gst_directdraw_sink_setup_ddraw (GstDirectDrawSink * ddrawsink); static gboolean gst_directdraw_sink_create_default_window (GstDirectDrawSink * ddrawsink); -static gboolean gst_directdraw_sink_create_ddraw_surface (GstDirectDrawSink * +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 void gst_directdraw_sink_ddraw_put (GstDirectDrawSink * ddrawsink, GstDDrawSurface * surface); +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", @@ -165,351 +176,30 @@ gst_directdraw_sink_expose (GstXOverlay * overlay) } 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); -} - -/* 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")) { - gint 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"; +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 */ @@ -574,7 +264,8 @@ gst_ddrawsurface_finalize (GstDDrawSurface * surface) if ((surface->width != ddrawsink->video_width) || (surface->height != ddrawsink->video_height) || (memcmp (&surface->dd_pixel_format, &ddrawsink->dd_pixel_format, - sizeof (DDPIXELFORMAT)) != 0) + 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", @@ -724,6 +415,8 @@ gst_directdraw_sink_init (GstDirectDrawSink * ddrawsink, 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 */ @@ -794,7 +487,7 @@ gst_directdraw_sink_set_caps (GstBaseSink * bsink, GstCaps * caps) } /* create an offscreen surface with the caps */ - ret = gst_directdraw_sink_create_ddraw_surface (ddrawsink); + 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"), @@ -851,13 +544,13 @@ gst_directdraw_sink_buffer_alloc (GstBaseSink * bsink, guint64 offset, { GstDirectDrawSink *ddrawsink = GST_DIRECTDRAW_SINK (bsink); GstDDrawSurface *surface = NULL; - GstStructure *structure = NULL; GstFlowReturn ret = GST_FLOW_OK; + GstCaps *buffer_caps = caps; + gboolean buffercaps_unref = FALSE; GST_CAT_INFO_OBJECT (directdrawsink_debug, ddrawsink, "a buffer of %d bytes was requested", size); - structure = gst_caps_get_structure (caps, 0); g_mutex_lock (ddrawsink->pool_lock); /* Inspect our buffer pool */ @@ -872,7 +565,8 @@ gst_directdraw_sink_buffer_alloc (GstBaseSink * bsink, guint64 offset, if ((surface->width != ddrawsink->video_width) || (surface->height != ddrawsink->video_height) || (memcmp (&surface->dd_pixel_format, &ddrawsink->dd_pixel_format, - sizeof (DDPIXELFORMAT))) + sizeof (DDPIXELFORMAT)) || + !gst_directdraw_sink_surface_check (ddrawsink, surface)) ) { gst_directdraw_sink_surface_destroy (ddrawsink, surface); surface = NULL; @@ -883,20 +577,111 @@ gst_directdraw_sink_buffer_alloc (GstBaseSink * bsink, guint64 offset, } } + 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; + GstStructure *structure = NULL; + + structure = gst_caps_get_structure (caps, 0); + if (!gst_structure_get_int (structure, "depth", &depth)) { + GST_CAT_DEBUG_OBJECT (directdrawsink_debug, ddrawsink, + "Can't get depth from buffer_alloc caps"); + return GST_FLOW_ERROR; + } + surface_desc.dwSize = sizeof (DDSURFACEDESC); + hres = IDirectDraw7_GetDisplayMode (ddrawsink->ddraw_object, &surface_desc); + if (hres != DD_OK) { + GST_CAT_DEBUG_OBJECT (directdrawsink_debug, ddrawsink, + "Can't get current display mode (error=%d)", 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", &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 = ddrawsink->video_width * ddrawsink->video_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, caps, size); + 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_set_caps (GST_BUFFER (surface), caps); + 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; } @@ -912,13 +697,9 @@ gst_directdraw_sink_show_frame (GstBaseSink * bsink, GstBuffer * buf) /* save a reference to the input buffer */ if (ddrawsink->last_buffer != buf) { if (ddrawsink->last_buffer) { - GST_CAT_LOG_OBJECT (directdrawsink_debug, ddrawsink, "unreffing %p", - ddrawsink->last_buffer); gst_buffer_unref (ddrawsink->last_buffer); } } - GST_CAT_LOG_OBJECT (directdrawsink_debug, ddrawsink, - "reffing %p as our current buffer", buf); ddrawsink->last_buffer = gst_buffer_ref (buf); } else { /* use last buffer */ @@ -944,6 +725,17 @@ gst_directdraw_sink_show_frame (GstBaseSink * bsink, GstBuffer * buf) &destsurf_rect); } + 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 @@ -956,12 +748,6 @@ gst_directdraw_sink_show_frame (GstBaseSink * bsink, GstBuffer * buf) ZeroMemory (&surf_desc, sizeof (surf_desc)); surf_desc.dwSize = sizeof (surf_desc); - /* Check for lost surface */ - if (IDirectDrawSurface7_IsLost (ddrawsink->offscreen_surface) == - DDERR_SURFACELOST) { - IDirectDrawSurface7_Restore (ddrawsink->offscreen_surface); - } - /* Lock the surface */ hRes = IDirectDrawSurface7_Lock (ddrawsink->offscreen_surface, NULL, @@ -1009,11 +795,6 @@ gst_directdraw_sink_show_frame (GstBaseSink * bsink, GstBuffer * buf) IDirectDrawSurface7_Unlock (surface->surface, NULL); surface->locked = FALSE; - /* Check for lost surfaces */ - if (IDirectDrawSurface7_IsLost (surface->surface) == DDERR_SURFACELOST) { - IDirectDrawSurface7_Restore (surface->surface); - } - /* blit to our primary surface */ hRes = IDirectDrawSurface7_Blt (ddrawsink->primary_surface, &destsurf_rect, surface->surface, NULL, DDBLT_WAIT, NULL); @@ -1022,8 +803,349 @@ gst_directdraw_sink_show_frame (GstBaseSink * bsink, GstBuffer * buf) "IDirectDrawSurface7_Blt (offscreen surface from buffer_alloc) " "returned %s", DDErrorString (hRes)); } - - return GST_FLOW_OK; + + 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")) { + gint 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 @@ -1031,7 +1153,6 @@ gst_directdraw_sink_setup_ddraw (GstDirectDrawSink * ddrawsink) { gboolean bRet = TRUE; HRESULT hRes; - DDSURFACEDESC2 dd_surface_desc; /* create an instance of the ddraw object use DDCREATE_EMULATIONONLY as first parameter to force Directdraw to use the hardware emulation layer */ @@ -1054,30 +1175,18 @@ gst_directdraw_sink_setup_ddraw (GstDirectDrawSink * ddrawsink) return FALSE; } - /*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; - hRes = IDirectDraw7_CreateSurface (ddrawsink->ddraw_object, &dd_surface_desc, - &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; - } - /* setup the clipper object */ hRes = IDirectDraw7_CreateClipper (ddrawsink->ddraw_object, 0, &ddrawsink->clipper, NULL); if (hRes == DD_OK) { hRes = IDirectDrawClipper_SetHWnd (ddrawsink->clipper, 0, ddrawsink->video_window); - hRes = IDirectDrawSurface7_SetClipper (ddrawsink->primary_surface, - ddrawsink->clipper); } + /* create our primary surface */ + if (!gst_directdraw_sink_check_primary_surface (ddrawsink)) + return FALSE; + /* directdraw objects are setup */ ddrawsink->setup = TRUE; @@ -1171,10 +1280,95 @@ failed: } static gboolean -gst_directdraw_sink_create_ddraw_surface (GstDirectDrawSink * ddrawsink) +gst_directdraw_sink_check_primary_surface (GstDirectDrawSink * ddrawsink) { + HRESULT hres; DDSURFACEDESC2 dd_surface_desc; - HRESULT hRes; + + /* 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; + hres = IDirectDraw7_CreateSurface (ddrawsink->ddraw_object, &dd_surface_desc, + &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; + 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); @@ -1185,38 +1379,19 @@ gst_directdraw_sink_create_ddraw_surface (GstDirectDrawSink * ddrawsink) memcpy (&(dd_surface_desc.ddpfPixelFormat), &ddrawsink->dd_pixel_format, sizeof (DDPIXELFORMAT)); - dd_surface_desc.ddsCaps.dwCaps = - DDSCAPS_OFFSCREENPLAIN /*|DDSCAPS_SYSTEMMEMORY */ ; - hRes = - IDirectDraw7_CreateSurface (ddrawsink->ddraw_object, &dd_surface_desc, + dd_surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; + hres = IDirectDraw7_CreateSurface (ddrawsink->ddraw_object, &dd_surface_desc, &ddrawsink->offscreen_surface, NULL); - if (hRes != DD_OK) { + if (hres != DD_OK) { GST_CAT_WARNING_OBJECT (directdrawsink_debug, ddrawsink, "create_ddraw_surface:CreateSurface (offscreen surface for buffer_pool) failed %s", - DDErrorString (hRes)); + DDErrorString (hres)); return FALSE; } - return TRUE; -} - -static void -gst_directdraw_sink_get_times (GstBaseSink * bsink, GstBuffer * buf, - GstClockTime * start, GstClockTime * end) -{ - GstDirectDrawSink *ddrawsink; - ddrawsink = GST_DIRECTDRAW_SINK (bsink); + ddrawsink->must_recreate_offscreen = FALSE; - 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; - } - } - } + return TRUE; } static int @@ -1254,17 +1429,8 @@ EnumModesCallback2 (LPDDSURFACEDESC2 lpDDSurfaceDesc, LPVOID lpContext) if ((lpDDSurfaceDesc->ddpfPixelFormat.dwFlags & DDPF_RGB) != DDPF_RGB) return DDENUMRET_OK; - format_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, lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount, - "depth", G_TYPE_INT, - gst_directdraw_sink_get_depth (&lpDDSurfaceDesc->ddpfPixelFormat), - "endianness", G_TYPE_INT, G_LITTLE_ENDIAN, "red_mask", G_TYPE_INT, - lpDDSurfaceDesc->ddpfPixelFormat.dwRBitMask, "green_mask", G_TYPE_INT, - lpDDSurfaceDesc->ddpfPixelFormat.dwGBitMask, "blue_mask", G_TYPE_INT, - lpDDSurfaceDesc->ddpfPixelFormat.dwBBitMask, NULL); + format_caps = + gst_directdraw_sink_create_caps_from_surfacedesc (lpDDSurfaceDesc); if (format_caps) { gst_caps_append (ddrawsink->caps, format_caps); @@ -1273,6 +1439,49 @@ EnumModesCallback2 (LPDDSURFACEDESC2 lpDDSurfaceDesc, LPVOID lpContext) 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) { @@ -1297,13 +1506,14 @@ gst_directdraw_sink_get_ddrawcaps (GstDirectDrawSink * ddrawsink) /* 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; - gint endianness = G_LITTLE_ENDIAN; - gint depth; 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 (DDSURFACEDESC); hRes = IDirectDraw7_GetDisplayMode (ddrawsink->ddraw_object, &surface_desc); if (hRes != DD_OK) { @@ -1313,36 +1523,8 @@ gst_directdraw_sink_get_ddrawcaps (GstDirectDrawSink * ddrawsink) return NULL; } - depth = gst_directdraw_sink_get_depth (&surface_desc.ddpfPixelFormat); - - if (surface_desc.ddpfPixelFormat.dwRGBBitCount == 24 || - surface_desc.ddpfPixelFormat.dwRGBBitCount == 32) { - /* ffmpegcolorspace handles 24/32 bpp RGB as big-endian. */ - endianness = G_BIG_ENDIAN; - surface_desc.ddpfPixelFormat.dwRBitMask = - GUINT32_TO_BE (surface_desc.ddpfPixelFormat.dwRBitMask); - surface_desc.ddpfPixelFormat.dwGBitMask = - GUINT32_TO_BE (surface_desc.ddpfPixelFormat.dwGBitMask); - surface_desc.ddpfPixelFormat.dwBBitMask = - GUINT32_TO_BE (surface_desc.ddpfPixelFormat.dwBBitMask); - if (surface_desc.ddpfPixelFormat.dwRGBBitCount == 24) { - surface_desc.ddpfPixelFormat.dwRBitMask >>= 8; - surface_desc.ddpfPixelFormat.dwGBitMask >>= 8; - surface_desc.ddpfPixelFormat.dwBBitMask >>= 8; - } - } - - format_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, surface_desc.ddpfPixelFormat.dwRGBBitCount, - "depth", G_TYPE_INT, depth, - "endianness", G_TYPE_INT, endianness, - "red_mask", G_TYPE_INT, surface_desc.ddpfPixelFormat.dwRBitMask, - "green_mask", G_TYPE_INT, surface_desc.ddpfPixelFormat.dwGBitMask, - "blue_mask", G_TYPE_INT, surface_desc.ddpfPixelFormat.dwBBitMask, NULL); - + format_caps = + gst_directdraw_sink_create_caps_from_surfacedesc (&surface_desc); if (format_caps) { gst_caps_append (ddrawsink->caps, format_caps); } @@ -1356,6 +1538,9 @@ gst_directdraw_sink_get_ddrawcaps (GstDirectDrawSink * 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 = @@ -1376,7 +1561,8 @@ gst_directdraw_sink_get_ddrawcaps (GstDirectDrawSink * ddrawsink) ("No supported caps found."), (NULL)); return NULL; } - //GST_CAT_INFO_OBJECT (directdrawsink_debug, ddrawsink, "returning caps %s", gst_caps_to_string (ddrawsink->caps)); + + /*GST_CAT_INFO_OBJECT (directdrawsink_debug, ddrawsink, "returning caps %s", gst_caps_to_string (ddrawsink->caps)); */ return ddrawsink->caps; } @@ -1418,7 +1604,15 @@ gst_directdraw_sink_surface_create (GstDirectDrawSink * ddrawsink, "failed getting pixel format from caps %" GST_PTR_FORMAT, caps); } - if (ddrawsink->ddraw_object) { + /* 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 */ @@ -1518,6 +1712,29 @@ no_sink: 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) { diff --git a/sys/directdraw/gstdirectdrawsink.h b/sys/directdraw/gstdirectdrawsink.h index 3bd55dd3..68a2a14b 100644 --- a/sys/directdraw/gstdirectdrawsink.h +++ b/sys/directdraw/gstdirectdrawsink.h @@ -120,6 +120,15 @@ struct _GstDirectDrawSink /* TRUE when directdraw objects are setup */ gboolean setup; + + /* TRUE if the hardware support 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 need when hardware doesn't support fourcc blit and the bit deph + * of the current display mode changes. + */ + gboolean must_recreate_offscreen; }; struct _GstDirectDrawSinkClass -- cgit v1.2.1 From 0ebea33d76aa7591609e7315e364fb9a76081937 Mon Sep 17 00:00:00 2001 From: Thomas Vander Stichele Date: Sun, 29 Apr 2007 13:56:18 +0000 Subject: [MOVED FROM GOOD] 80 char police Original commit message from CVS: 80 char police --- sys/directdraw/gstdirectdrawsink.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'sys') diff --git a/sys/directdraw/gstdirectdrawsink.c b/sys/directdraw/gstdirectdrawsink.c index ab778c84..ecff6343 100644 --- a/sys/directdraw/gstdirectdrawsink.c +++ b/sys/directdraw/gstdirectdrawsink.c @@ -30,9 +30,9 @@ * * * - * 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. + * 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. * @@ -95,7 +95,7 @@ static gboolean gst_directdraw_sink_check_offscreen_surface (GstDirectDrawSink * static GstCaps *gst_directdraw_sink_get_ddrawcaps (GstDirectDrawSink * ddrawsink); static GstCaps - *gst_directdraw_sink_create_caps_from_surfacedesc (LPDDSURFACEDESC2 desc); + * 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); -- cgit v1.2.1 From 032eeebb754035bb0e954314aefb74edf638e28e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Tue, 15 May 2007 17:22:58 +0000 Subject: [MOVED FROM GOOD] Add DIRECTDRAW_CFLAGS and DIRECTSOUND_CFLAGS to Makefile.am; save and restore the various flags in the directdraw/dir... Original commit message from CVS: * configure.ac: * sys/directdraw/Makefile.am: * sys/directsound/Makefile.am: Add DIRECTDRAW_CFLAGS and DIRECTSOUND_CFLAGS to Makefile.am; save and restore the various flags in the directdraw/directsound detection section. Apparently improves cross-compiling for win32 with mingw32 under some circumstances (#437539). --- sys/directdraw/Makefile.am | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sys') diff --git a/sys/directdraw/Makefile.am b/sys/directdraw/Makefile.am index 999f026e..3fa5e85f 100644 --- a/sys/directdraw/Makefile.am +++ b/sys/directdraw/Makefile.am @@ -2,8 +2,8 @@ plugin_LTLIBRARIES = libgstdirectdrawsink.la libgstdirectdrawsink_la_SOURCES = gstdirectdrawsink.c gstdirectdrawplugin.c libgstdirectdrawsink_la_CFLAGS = $(GST_CFLAGS) $(GST_BASE_CFLAGS) \ - $(GST_PLUGINS_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) +libgstdirectdrawsink_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) $(DIRECTDRAW_LDFLAGS) -- cgit v1.2.1 From b7476655fbb340f90162623d31b87353c19cb311 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Sun, 20 May 2007 14:59:46 +0000 Subject: [MOVED FROM GOOD] sys/directdraw/gstdirectdrawsink.c: Bunch of small fixes: remove static function that doesn't exist; declare another ... Original commit message from CVS: * sys/directdraw/gstdirectdrawsink.c: (gst_ddrawsurface_finalize), (gst_directdraw_sink_buffer_alloc), (gst_directdraw_sink_get_ddrawcaps), (gst_directdraw_sink_surface_create): Bunch of small fixes: remove static function that doesn't exist; declare another one that does; printf format fix; use right macro when specifying debug category; remove a bunch of unused variables; #if 0 out an unused chunk of code (partially fixes #439914). --- sys/directdraw/gstdirectdrawsink.c | 117 ++++++++++++++++++------------------- 1 file changed, 58 insertions(+), 59 deletions(-) (limited to 'sys') diff --git a/sys/directdraw/gstdirectdrawsink.c b/sys/directdraw/gstdirectdrawsink.c index ecff6343..2ad0cb68 100644 --- a/sys/directdraw/gstdirectdrawsink.c +++ b/sys/directdraw/gstdirectdrawsink.c @@ -99,8 +99,7 @@ static GstCaps static void gst_directdraw_sink_cleanup (GstDirectDrawSink * ddrawsink); static void gst_directdraw_sink_bufferpool_clear (GstDirectDrawSink * ddrawsink); -static void gst_directdraw_sink_ddraw_put (GstDirectDrawSink * ddrawsink, - GstDDrawSurface * surface); +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, @@ -203,7 +202,7 @@ gst_directdraw_sink_init_interfaces (GType type) } /* Subclass of GstBuffer which manages buffer_pool surfaces lifetime */ -static void gst_ddrawsurface_finalize (GstDDrawSurface * surface); +static void gst_ddrawsurface_finalize (GstMiniObject * mini_object); static void gst_ddrawsurface_init (GstDDrawSurface * surface, gpointer g_class) @@ -250,11 +249,12 @@ gst_ddrawsurface_get_type (void) } static void -gst_ddrawsurface_finalize (GstDDrawSurface * surface) +gst_ddrawsurface_finalize (GstMiniObject * mini_object) { GstDirectDrawSink *ddrawsink = NULL; + GstDDrawSurface *surface; - g_return_if_fail (surface != NULL); + surface = (GstDDrawSurface *) mini_object; ddrawsink = surface->ddrawsink; if (!ddrawsink) @@ -288,7 +288,7 @@ gst_ddrawsurface_finalize (GstDDrawSurface * surface) return; no_sink: - GST_WARNING (directdrawsink_debug, "no sink found"); + GST_CAT_WARNING (directdrawsink_debug, "no sink found"); return; } @@ -597,7 +597,7 @@ gst_directdraw_sink_buffer_alloc (GstBaseSink * bsink, guint64 offset, hres = IDirectDraw7_GetDisplayMode (ddrawsink->ddraw_object, &surface_desc); if (hres != DD_OK) { GST_CAT_DEBUG_OBJECT (directdrawsink_debug, ddrawsink, - "Can't get current display mode (error=%d)", hres); + "Can't get current display mode (error=%ld)", (glong) hres); return GST_FLOW_ERROR; } @@ -1486,9 +1486,6 @@ static GstCaps * gst_directdraw_sink_get_ddrawcaps (GstDirectDrawSink * ddrawsink) { HRESULT hRes = S_OK; - DWORD dwFourccCodeIndex = 0; - LPDWORD pdwFourccCodes = NULL; - DWORD dwNbFourccCodes = 0; DDCAPS ddcaps_hardware; DDCAPS ddcaps_emulation; GstCaps *format_caps = NULL; @@ -1611,62 +1608,64 @@ gst_directdraw_sink_surface_create (GstDirectDrawSink * ddrawsink, * 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 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; - } + /* 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)); - /* 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; + hRes = IDirectDraw7_CreateSurface (ddrawsink->ddraw_object, &surf_desc, + &surface->surface, NULL); + if (hRes != DD_OK) { + goto surface_pitch_bad; + } - 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); + /* 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; - /*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; + if (surf_lock_desc.lPitch != pitch) { GST_CAT_INFO_OBJECT (directdrawsink_debug, ddrawsink, - "allocating a surface of %d bytes (stride=%ld)\n", size, - surf_lock_desc.lPitch); - } else { + "DDraw stride/pitch %ld isn't as expected value %d, let's continue allocating a system memory buffer.", + surf_lock_desc.lPitch, pitch); - surface_pitch_bad: - 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); + /*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); + +#else + +surface_pitch_bad: + 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); -- cgit v1.2.1 From 4c32422297fba581dc4c79f8bcfe412b604e6347 Mon Sep 17 00:00:00 2001 From: Vincent Torri Date: Thu, 24 May 2007 08:35:23 +0000 Subject: [MOVED FROM GOOD] sys/directdraw/gstdirectdrawsink.*: Fix more warnings when compiling with MingW (#439914). Original commit message from CVS: Patch by: Vincent Torri * sys/directdraw/gstdirectdrawsink.c: (gst_directdraw_sink_buffer_alloc), (gst_directdraw_sink_show_frame), (gst_directdraw_sink_check_primary_surface), (gst_directdraw_sink_check_offscreen_surface), (EnumModesCallback2), (gst_directdraw_sink_get_ddrawcaps), (gst_directdraw_sink_surface_create): * sys/directdraw/gstdirectdrawsink.h: Fix more warnings when compiling with MingW (#439914). --- sys/directdraw/gstdirectdrawsink.c | 47 ++++++++++++++++++++++++++------------ sys/directdraw/gstdirectdrawsink.h | 2 +- 2 files changed, 34 insertions(+), 15 deletions(-) (limited to 'sys') diff --git a/sys/directdraw/gstdirectdrawsink.c b/sys/directdraw/gstdirectdrawsink.c index 2ad0cb68..300bfe07 100644 --- a/sys/directdraw/gstdirectdrawsink.c +++ b/sys/directdraw/gstdirectdrawsink.c @@ -585,6 +585,7 @@ gst_directdraw_sink_buffer_alloc (GstBaseSink * bsink, guint64 offset, guint depth; HRESULT hres; DDSURFACEDESC2 surface_desc; + DDSURFACEDESC2 *sd; GstStructure *structure = NULL; structure = gst_caps_get_structure (caps, 0); @@ -593,8 +594,11 @@ gst_directdraw_sink_buffer_alloc (GstBaseSink * bsink, guint64 offset, "Can't get depth from buffer_alloc caps"); return GST_FLOW_ERROR; } - surface_desc.dwSize = sizeof (DDSURFACEDESC); - hres = IDirectDraw7_GetDisplayMode (ddrawsink->ddraw_object, &surface_desc); + 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); @@ -744,14 +748,16 @@ gst_directdraw_sink_show_frame (GstBaseSink * bsink, GstBuffer * buf) 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, - &surf_desc, DDLOCK_WAIT, 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", @@ -1284,6 +1290,7 @@ 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) { @@ -1320,7 +1327,9 @@ gst_directdraw_sink_check_primary_surface (GstDirectDrawSink * ddrawsink) dd_surface_desc.dwSize = sizeof (dd_surface_desc); dd_surface_desc.dwFlags = DDSD_CAPS; dd_surface_desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; - hres = IDirectDraw7_CreateSurface (ddrawsink->ddraw_object, &dd_surface_desc, + 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, @@ -1342,6 +1351,7 @@ 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 */ @@ -1380,7 +1390,9 @@ gst_directdraw_sink_check_offscreen_surface (GstDirectDrawSink * ddrawsink) sizeof (DDPIXELFORMAT)); dd_surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; - hres = IDirectDraw7_CreateSurface (ddrawsink->ddraw_object, &dd_surface_desc, + 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, @@ -1412,25 +1424,26 @@ gst_directdraw_sink_get_depth (LPDDPIXELFORMAT lpddpfPixelFormat) } HRESULT WINAPI -EnumModesCallback2 (LPDDSURFACEDESC2 lpDDSurfaceDesc, LPVOID lpContext) +EnumModesCallback2 (LPDDSURFACEDESC lpDDSurfaceDesc, LPVOID lpContext) { GstDirectDrawSink *ddrawsink = (GstDirectDrawSink *) lpContext; GstCaps *format_caps = NULL; + LPDDSURFACEDESC2 sd; if (!ddrawsink || !lpDDSurfaceDesc) return DDENUMRET_CANCEL; - if ((lpDDSurfaceDesc->dwFlags & DDSD_PIXELFORMAT) != DDSD_PIXELFORMAT) { + 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 ((lpDDSurfaceDesc->ddpfPixelFormat.dwFlags & DDPF_RGB) != DDPF_RGB) + if ((sd->ddpfPixelFormat.dwFlags & DDPF_RGB) != DDPF_RGB) return DDENUMRET_OK; - format_caps = - gst_directdraw_sink_create_caps_from_surfacedesc (lpDDSurfaceDesc); + format_caps = gst_directdraw_sink_create_caps_from_surfacedesc (sd); if (format_caps) { gst_caps_append (ddrawsink->caps, format_caps); @@ -1503,6 +1516,7 @@ gst_directdraw_sink_get_ddrawcaps (GstDirectDrawSink * ddrawsink) /* 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. " @@ -1511,8 +1525,11 @@ gst_directdraw_sink_get_ddrawcaps (GstDirectDrawSink * ddrawsink) /* save blit caps */ ddrawsink->can_blit_between_colorspace = FALSE; - surface_desc.dwSize = sizeof (DDSURFACEDESC); - hRes = IDirectDraw7_GetDisplayMode (ddrawsink->ddraw_object, &surface_desc); + 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", @@ -1572,7 +1589,10 @@ gst_directdraw_sink_surface_create (GstDirectDrawSink * ddrawsink, 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); @@ -1655,9 +1675,8 @@ lock: "allocating a surface of %d bytes (stride=%ld)\n", size, surf_lock_desc.lPitch); -#else - 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; diff --git a/sys/directdraw/gstdirectdrawsink.h b/sys/directdraw/gstdirectdrawsink.h index 68a2a14b..0026eb35 100644 --- a/sys/directdraw/gstdirectdrawsink.h +++ b/sys/directdraw/gstdirectdrawsink.h @@ -136,7 +136,7 @@ struct _GstDirectDrawSinkClass GstVideoSinkClass parent_class; }; -GType gst_direct_drawsink_get_type (void); +GType gst_directdraw_sink_get_type (void); G_END_DECLS #endif /* __GST_DIRECTDRAWSINK_H__ */ -- cgit v1.2.1 From 7e0f619ef2ba9fe40df099716bf5652df069cc87 Mon Sep 17 00:00:00 2001 From: Jan Schmidt Date: Fri, 8 Jun 2007 16:31:15 +0000 Subject: [MOVED FROM GOOD] Rename the keep-aspect-ratio property to force-aspect-ratio to make it consistent with xvimagesink and ximagesink. Original commit message from CVS: * docs/plugins/gst-plugins-bad-plugins.args: * sys/directdraw/gstdirectdrawsink.c: (gst_directdraw_sink_class_init): Rename the keep-aspect-ratio property to force-aspect-ratio to make it consistent with xvimagesink and ximagesink. --- sys/directdraw/gstdirectdrawsink.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'sys') diff --git a/sys/directdraw/gstdirectdrawsink.c b/sys/directdraw/gstdirectdrawsink.c index 300bfe07..5eff741c 100644 --- a/sys/directdraw/gstdirectdrawsink.c +++ b/sys/directdraw/gstdirectdrawsink.c @@ -342,8 +342,9 @@ gst_directdraw_sink_class_init (GstDirectDrawSinkClass * klass) /* install properties */ /* setup aspect ratio mode */ g_object_class_install_property (G_OBJECT_CLASS (klass), - PROP_KEEP_ASPECT_RATIO, g_param_spec_boolean ("keep-aspect-ratio", - "keep-aspect-ratio", "keep the aspect ratio or not", FALSE, + 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)); } -- cgit v1.2.1 From 958dc325050cc5683e3ad21489568997737a3a53 Mon Sep 17 00:00:00 2001 From: Jan Schmidt Date: Thu, 14 Jun 2007 12:14:24 +0000 Subject: [MOVED FROM GOOD] Make sure to dist everything needed for win32 builds. Original commit message from CVS: * configure.ac: * sys/Makefile.am: * sys/directdraw/Makefile.am: * sys/directsound/Makefile.am: * sys/waveform/Makefile.am: Make sure to dist everything needed for win32 builds. --- sys/directdraw/Makefile.am | 2 ++ 1 file changed, 2 insertions(+) (limited to 'sys') diff --git a/sys/directdraw/Makefile.am b/sys/directdraw/Makefile.am index 3fa5e85f..dddaf189 100644 --- a/sys/directdraw/Makefile.am +++ b/sys/directdraw/Makefile.am @@ -7,3 +7,5 @@ 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) + +noinst_HEADERS= gstdirectdrawsink.h -- cgit v1.2.1 From ca3a85c8338c9624a00fadddf8e9f59358e1931b Mon Sep 17 00:00:00 2001 From: Thomas Vander Stichele Date: Sat, 22 Sep 2007 08:12:57 +0000 Subject: [MOVED FROM GOOD] fix header and comments Original commit message from CVS: fix header and comments --- sys/directdraw/gstdirectdrawsink.c | 47 ++++++++++++++++++-------------------- sys/directdraw/gstdirectdrawsink.h | 15 ++++++------ 2 files changed, 29 insertions(+), 33 deletions(-) (limited to 'sys') diff --git a/sys/directdraw/gstdirectdrawsink.c b/sys/directdraw/gstdirectdrawsink.c index 5eff741c..65c3df23 100644 --- a/sys/directdraw/gstdirectdrawsink.c +++ b/sys/directdraw/gstdirectdrawsink.c @@ -1,29 +1,26 @@ /* GStreamer -* Copyright (C) 2005 Sebastien Moutte -* Copyright (C) 2007 Pioneers of the Inevitable -* -* Based on directfb video sink -* gstdirectdrawsink.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 -* -*/ + * Copyright (C) 2005 Sebastien Moutte + * Copyright (C) 2007 Pioneers of the Inevitable + * + * 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 diff --git a/sys/directdraw/gstdirectdrawsink.h b/sys/directdraw/gstdirectdrawsink.h index 0026eb35..9cb5f788 100644 --- a/sys/directdraw/gstdirectdrawsink.h +++ b/sys/directdraw/gstdirectdrawsink.h @@ -1,9 +1,7 @@ /* GStreamer - * Copyright (C) 2005 Sebastien Moutte + * Copyright (C) 2005 Sebastien Moutte * Copyright (C) 2007 Pioneers of the Inevitable * - * gstdirectdrawsink.h: - * * 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 @@ -24,7 +22,6 @@ * */ - #ifndef __GST_DIRECTDRAWSINK_H__ #define __GST_DIRECTDRAWSINK_H__ @@ -38,6 +35,7 @@ #include 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)) @@ -118,14 +116,14 @@ struct _GstDirectDrawSink /* thread processing our default window messages */ GThread *window_thread; - /* TRUE when directdraw objects are setup */ + /* TRUE when directdraw object is set up */ gboolean setup; - /* TRUE if the hardware support blitting from one colorspace to another */ + /* 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 need when hardware doesn't support fourcc blit and the bit deph + /* 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; @@ -139,4 +137,5 @@ struct _GstDirectDrawSinkClass GType gst_directdraw_sink_get_type (void); G_END_DECLS + #endif /* __GST_DIRECTDRAWSINK_H__ */ -- cgit v1.2.1 From 1e8cd75ae9e35c1951d0572f00dc8574f5c65611 Mon Sep 17 00:00:00 2001 From: Julien Moutte Date: Sat, 5 Jan 2008 21:20:08 +0000 Subject: [MOVED FROM GOOD] sys/directdraw/gstdirectdrawsink.c: Make sure we create our internal window only when we need it. That will give a ch... Original commit message from CVS: 2008-01-05 Julien Moutte * sys/directdraw/gstdirectdrawsink.c: (gst_directdraw_sink_set_window_id), (gst_directdraw_sink_set_caps), (gst_directdraw_sink_change_state), (gst_directdraw_sink_buffer_alloc), (gst_directdraw_sink_draw_borders), (gst_directdraw_sink_show_frame), (gst_directdraw_sink_setup_ddraw), (gst_directdraw_sink_window_thread), (gst_directdraw_sink_get_ddrawcaps), (gst_directdraw_sink_surface_create): Make sure we create our internal window only when we need it. That will give a chance to the application to get the prepare-xwindow-id bus message. Draw black borders when keeping aspect ratio. Handle the case where our rendering window disappears (closed or errors) like other sinks do. Various 80 columns fixes, improve state change order. That element could need some more love. --- sys/directdraw/gstdirectdrawsink.c | 181 +++++++++++++++++++++++++++++-------- 1 file changed, 143 insertions(+), 38 deletions(-) (limited to 'sys') diff --git a/sys/directdraw/gstdirectdrawsink.c b/sys/directdraw/gstdirectdrawsink.c index 65c3df23..78406d27 100644 --- a/sys/directdraw/gstdirectdrawsink.c +++ b/sys/directdraw/gstdirectdrawsink.c @@ -146,13 +146,24 @@ 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) + 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) { @@ -161,6 +172,9 @@ gst_directdraw_sink_set_window_id (GstXOverlay * overlay, ULONG window_id) 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 @@ -476,6 +490,11 @@ gst_directdraw_sink_set_caps (GstBaseSink * bsink, GstCaps * caps) 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, @@ -499,26 +518,28 @@ static GstStateChangeReturn gst_directdraw_sink_change_state (GstElement * element, GstStateChange transition) { - GstDirectDrawSink *ddrawsink = GST_DIRECTDRAW_SINK (element);; + GstDirectDrawSink *ddrawsink = GST_DIRECTDRAW_SINK (element); + GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS; switch (transition) { case GST_STATE_CHANGE_NULL_TO_READY: - if (ddrawsink->video_window == NULL) - if (!gst_directdraw_sink_create_default_window (ddrawsink)) - return GST_STATE_CHANGE_FAILURE; - - if (!gst_directdraw_sink_setup_ddraw (ddrawsink)) - return GST_STATE_CHANGE_FAILURE; + if (!gst_directdraw_sink_setup_ddraw (ddrawsink)) { + ret = GST_STATE_CHANGE_FAILURE; + goto beach; + } - if (!(ddrawsink->caps = gst_directdraw_sink_get_ddrawcaps (ddrawsink))) - return GST_STATE_CHANGE_FAILURE; - break; - case GST_STATE_CHANGE_READY_TO_PAUSED: - break; - case GST_STATE_CHANGE_PAUSED_TO_PLAYING: + if (!(ddrawsink->caps = gst_directdraw_sink_get_ddrawcaps (ddrawsink))) { + ret = GST_STATE_CHANGE_FAILURE; + goto beach; + } break; - case GST_STATE_CHANGE_PLAYING_TO_PAUSED: + 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; @@ -531,9 +552,12 @@ gst_directdraw_sink_change_state (GstElement * element, if (ddrawsink->setup) gst_directdraw_sink_cleanup (ddrawsink); break; + default: + break; } - return GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); +beach: + return ret; } static GstFlowReturn @@ -547,7 +571,7 @@ gst_directdraw_sink_buffer_alloc (GstBaseSink * bsink, guint64 offset, gboolean buffercaps_unref = FALSE; GST_CAT_INFO_OBJECT (directdrawsink_debug, ddrawsink, - "a buffer of %d bytes was requested", size); + "a buffer of %u bytes was requested", size); g_mutex_lock (ddrawsink->pool_lock); @@ -687,6 +711,63 @@ gst_directdraw_sink_buffer_alloc (GstBaseSink * bsink, guint64 offset, 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) { @@ -711,6 +792,15 @@ gst_directdraw_sink_show_frame (GstBaseSink * bsink, GstBuffer * buf) 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); @@ -725,7 +815,9 @@ gst_directdraw_sink_show_frame (GstBaseSink * bsink, GstBuffer * buf) 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); @@ -780,17 +872,18 @@ gst_directdraw_sink_show_frame (GstBaseSink * bsink, GstBuffer * buf) return GST_FLOW_ERROR; } - /* blit to primary surface ( Blt will scale the video the dest rect surface if needed */ + /* 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) + 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 */ + /* 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); @@ -802,7 +895,7 @@ gst_directdraw_sink_show_frame (GstBaseSink * bsink, GstBuffer * buf) /* blit to our primary surface */ hRes = IDirectDrawSurface7_Blt (ddrawsink->primary_surface, &destsurf_rect, surface->surface, NULL, DDBLT_WAIT, NULL); - if (hRes != DD_OK) + 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)); @@ -1158,8 +1251,8 @@ 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 */ + /* 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) { @@ -1171,7 +1264,7 @@ gst_directdraw_sink_setup_ddraw (GstDirectDrawSink * ddrawsink) /* set cooperative level */ hRes = IDirectDraw7_SetCooperativeLevel (ddrawsink->ddraw_object, - ddrawsink->video_window, DDSCL_NORMAL); + NULL, DDSCL_NORMAL); if (hRes != DD_OK) { GST_ELEMENT_ERROR (ddrawsink, RESOURCE, WRITE, ("Failed to set the set the cooperative level error=%s", @@ -1182,10 +1275,6 @@ gst_directdraw_sink_setup_ddraw (GstDirectDrawSink * ddrawsink) /* setup the clipper object */ hRes = IDirectDraw7_CreateClipper (ddrawsink->ddraw_object, 0, &ddrawsink->clipper, NULL); - if (hRes == DD_OK) { - hRes = IDirectDrawClipper_SetHWnd (ddrawsink->clipper, 0, - ddrawsink->video_window); - } /* create our primary surface */ if (!gst_directdraw_sink_check_primary_surface (ddrawsink)) @@ -1236,6 +1325,9 @@ gst_directdraw_sink_window_thread (GstDirectDrawSink * ddrawsink) if (ddrawsink->video_window == NULL) return FALSE; + /* Set the clipper on that window */ + IDirectDrawClipper_SetHWnd (ddrawsink->clipper, 0, ddrawsink->video_window); + /* signal application we create a window */ gst_x_overlay_got_xwindow_id (GST_X_OVERLAY (ddrawsink), (gulong) ddrawsink->video_window); @@ -1246,8 +1338,18 @@ gst_directdraw_sink_window_thread (GstDirectDrawSink * ddrawsink) while (1) { MSG msg; - if (!GetMessage (&msg, ddrawsink->video_window, 0, 0)) + if (GetMessage (&msg, ddrawsink->video_window, 0, 0) <= 0) { + 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); + } break; + } DispatchMessage (&msg); } @@ -1511,7 +1613,8 @@ gst_directdraw_sink_get_ddrawcaps (GstDirectDrawSink * ddrawsink) 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 */ + /* 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; @@ -1574,7 +1677,8 @@ gst_directdraw_sink_get_ddrawcaps (GstDirectDrawSink * ddrawsink) return NULL; } - /*GST_CAT_INFO_OBJECT (directdrawsink_debug, ddrawsink, "returning caps %s", gst_caps_to_string (ddrawsink->caps)); */ + /*GST_CAT_INFO_OBJECT (directdrawsink_debug, ddrawsink, "returning caps %s", + * gst_caps_to_string (ddrawsink->caps)); */ return ddrawsink->caps; } @@ -1619,12 +1723,13 @@ gst_directdraw_sink_surface_create (GstDirectDrawSink * 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. + /* 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) {*/ -- cgit v1.2.1 From c67d72290784cf6a62b81ace93a24ac9494885a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Mon, 7 Jan 2008 16:41:00 +0000 Subject: [MOVED FROM GOOD] sys/directdraw/gstdirectdrawsink.c: FALSE is not a gpointer. Original commit message from CVS: * sys/directdraw/gstdirectdrawsink.c: (gst_directdraw_sink_window_thread): FALSE is not a gpointer. --- sys/directdraw/gstdirectdrawsink.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sys') diff --git a/sys/directdraw/gstdirectdrawsink.c b/sys/directdraw/gstdirectdrawsink.c index 78406d27..9a028287 100644 --- a/sys/directdraw/gstdirectdrawsink.c +++ b/sys/directdraw/gstdirectdrawsink.c @@ -1323,12 +1323,12 @@ gst_directdraw_sink_window_thread (GstDirectDrawSink * ddrawsink) WS_OVERLAPPEDWINDOW | WS_SIZEBOX, 0, 0, 640, 480, NULL, NULL, WndClass.hInstance, NULL); if (ddrawsink->video_window == NULL) - return FALSE; + return NULL; /* Set the clipper on that window */ IDirectDrawClipper_SetHWnd (ddrawsink->clipper, 0, ddrawsink->video_window); - /* signal application we create a window */ + /* signal application we created a window */ gst_x_overlay_got_xwindow_id (GST_X_OVERLAY (ddrawsink), (gulong) ddrawsink->video_window); -- cgit v1.2.1 From e7a9a0ef4b000a9aaf57f1bcd4ca2de3a22a96ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Tue, 12 Feb 2008 12:22:48 +0000 Subject: [MOVED FROM GOOD] sys/directdraw/gstdirectdrawsink.c: Properly chain up finalize functions. Fixes bug #515980. Original commit message from CVS: * sys/directdraw/gstdirectdrawsink.c: (gst_ddrawsurface_class_init), (gst_ddrawsurface_finalize), (gst_directdraw_sink_finalize): Properly chain up finalize functions. Fixes bug #515980. --- sys/directdraw/gstdirectdrawsink.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'sys') diff --git a/sys/directdraw/gstdirectdrawsink.c b/sys/directdraw/gstdirectdrawsink.c index 9a028287..1dd334c2 100644 --- a/sys/directdraw/gstdirectdrawsink.c +++ b/sys/directdraw/gstdirectdrawsink.c @@ -214,6 +214,7 @@ gst_directdraw_sink_init_interfaces (GType type) /* 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) @@ -232,6 +233,8 @@ 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); } @@ -283,7 +286,7 @@ gst_ddrawsurface_finalize (GstMiniObject * mini_object) 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, @@ -296,10 +299,12 @@ gst_ddrawsurface_finalize (GstMiniObject * mini_object) 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; } @@ -407,6 +412,8 @@ gst_directdraw_sink_finalize (GObject * object) if (ddrawsink->setup) { gst_directdraw_sink_cleanup (ddrawsink); } + + G_OBJECT_CLASS (parent_class)->finalize (object); } static void -- cgit v1.2.1 From edaeddd5d1fe2c84019de2a509a604eca74a0c5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ole=20Andr=C3=A9=20Vadla=20Ravn=C3=A5s?= Date: Wed, 7 May 2008 13:48:28 +0000 Subject: [MOVED FROM GOOD] sys/directdraw/gstdirectdrawsink.c Original commit message from CVS: * sys/directdraw/gstdirectdrawsink.c (gst_directdraw_sink_buffer_alloc): Clear the flags on recycled buffers from buffer_alloc. Partially fixes #520885. --- sys/directdraw/gstdirectdrawsink.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'sys') diff --git a/sys/directdraw/gstdirectdrawsink.c b/sys/directdraw/gstdirectdrawsink.c index 1dd334c2..a8fe4eff 100644 --- a/sys/directdraw/gstdirectdrawsink.c +++ b/sys/directdraw/gstdirectdrawsink.c @@ -572,6 +572,8 @@ 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; @@ -580,6 +582,14 @@ gst_directdraw_sink_buffer_alloc (GstBaseSink * bsink, guint64 offset, 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 */ @@ -591,8 +601,8 @@ gst_directdraw_sink_buffer_alloc (GstBaseSink * bsink, guint64 offset, ddrawsink->buffer_pool); /* If the surface is invalid for our need, destroy */ - if ((surface->width != ddrawsink->video_width) || - (surface->height != ddrawsink->video_height) || + 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)) @@ -615,9 +625,7 @@ gst_directdraw_sink_buffer_alloc (GstBaseSink * bsink, guint64 offset, HRESULT hres; DDSURFACEDESC2 surface_desc; DDSURFACEDESC2 *sd; - GstStructure *structure = NULL; - structure = gst_caps_get_structure (caps, 0); if (!gst_structure_get_int (structure, "depth", &depth)) { GST_CAT_DEBUG_OBJECT (directdrawsink_debug, ddrawsink, "Can't get depth from buffer_alloc caps"); @@ -673,7 +681,7 @@ gst_directdraw_sink_buffer_alloc (GstBaseSink * bsink, guint64 offset, buffer_caps = copy_caps; buffercaps_unref = TRUE; /* update buffer size needed to store video frames according to new caps */ - size = ddrawsink->video_width * ddrawsink->video_height * (bpp / 8); + size = width * height * (bpp / 8); /* update our member pixel format */ gst_ddrawvideosink_get_format_from_caps (ddrawsink, buffer_caps, -- cgit v1.2.1 From 1aa90c3ce12b56aa7a1c2a5cb7087a60b72c84a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ole=20Andr=C3=A9=20Vadla=20Ravn=C3=A5s?= Date: Wed, 7 May 2008 14:39:45 +0000 Subject: [MOVED FROM GOOD] sys/directdraw/gstdirectdrawsink.c Original commit message from CVS: * sys/directdraw/gstdirectdrawsink.c (gst_directdraw_sink_buffer_alloc): Reverting previous commit, it had it all mixed up, was for a different patch (major automation screw-up). Sorry! --- sys/directdraw/gstdirectdrawsink.c | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) (limited to 'sys') diff --git a/sys/directdraw/gstdirectdrawsink.c b/sys/directdraw/gstdirectdrawsink.c index a8fe4eff..1dd334c2 100644 --- a/sys/directdraw/gstdirectdrawsink.c +++ b/sys/directdraw/gstdirectdrawsink.c @@ -572,8 +572,6 @@ 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; @@ -582,14 +580,6 @@ gst_directdraw_sink_buffer_alloc (GstBaseSink * bsink, guint64 offset, 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 */ @@ -601,8 +591,8 @@ gst_directdraw_sink_buffer_alloc (GstBaseSink * bsink, guint64 offset, ddrawsink->buffer_pool); /* If the surface is invalid for our need, destroy */ - if ((surface->width != width) || - (surface->height != height) || + if ((surface->width != ddrawsink->video_width) || + (surface->height != ddrawsink->video_height) || (memcmp (&surface->dd_pixel_format, &ddrawsink->dd_pixel_format, sizeof (DDPIXELFORMAT)) || !gst_directdraw_sink_surface_check (ddrawsink, surface)) @@ -625,7 +615,9 @@ gst_directdraw_sink_buffer_alloc (GstBaseSink * bsink, guint64 offset, HRESULT hres; DDSURFACEDESC2 surface_desc; DDSURFACEDESC2 *sd; + GstStructure *structure = NULL; + structure = gst_caps_get_structure (caps, 0); if (!gst_structure_get_int (structure, "depth", &depth)) { GST_CAT_DEBUG_OBJECT (directdrawsink_debug, ddrawsink, "Can't get depth from buffer_alloc caps"); @@ -681,7 +673,7 @@ gst_directdraw_sink_buffer_alloc (GstBaseSink * bsink, guint64 offset, buffer_caps = copy_caps; buffercaps_unref = TRUE; /* update buffer size needed to store video frames according to new caps */ - size = width * height * (bpp / 8); + size = ddrawsink->video_width * ddrawsink->video_height * (bpp / 8); /* update our member pixel format */ gst_ddrawvideosink_get_format_from_caps (ddrawsink, buffer_caps, -- cgit v1.2.1 From 44a5658faaa9e32e260dfb4d6d85fe8e0982fd69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ole=20Andr=C3=A9=20Vadla=20Ravn=C3=A5s?= Date: Wed, 7 May 2008 14:43:39 +0000 Subject: [MOVED FROM GOOD] sys/directdraw/gstdirectdrawsink.c Original commit message from CVS: * sys/directdraw/gstdirectdrawsink.c (gst_directdraw_sink_buffer_alloc): Clear the flags on recycled buffers from buffer_alloc. Partially fixes #520885. The right fix this time. --- sys/directdraw/gstdirectdrawsink.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sys') diff --git a/sys/directdraw/gstdirectdrawsink.c b/sys/directdraw/gstdirectdrawsink.c index 1dd334c2..a39e0335 100644 --- a/sys/directdraw/gstdirectdrawsink.c +++ b/sys/directdraw/gstdirectdrawsink.c @@ -705,6 +705,7 @@ gst_directdraw_sink_buffer_alloc (GstBaseSink * bsink, guint64 offset, /* 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); } -- cgit v1.2.1 From e2886ac7c9b90ecf6d5e87c0e78451e98a8ea636 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ole=20Andr=C3=A9=20Vadla=20Ravn=C3=A5s?= Date: Wed, 7 May 2008 14:56:22 +0000 Subject: [MOVED FROM GOOD] sys/directdraw/gstdirectdrawsink.c Original commit message from CVS: * sys/directdraw/gstdirectdrawsink.c (gst_directdraw_sink_buffer_alloc): Make it so that gst_directdraw_sink_buffer_alloc uses the right width/height. Especially when looking through the pool of buffers, make sure that the width/height of caps is used instead of the already negotiated dimensions. For example if a buffer with different caps is requested, i.e. higher resolution, the caller would get a buffer with the old dimensions and thus corrupt the heap. --- sys/directdraw/gstdirectdrawsink.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'sys') diff --git a/sys/directdraw/gstdirectdrawsink.c b/sys/directdraw/gstdirectdrawsink.c index a39e0335..9d34cf22 100644 --- a/sys/directdraw/gstdirectdrawsink.c +++ b/sys/directdraw/gstdirectdrawsink.c @@ -572,6 +572,8 @@ 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; @@ -580,6 +582,14 @@ gst_directdraw_sink_buffer_alloc (GstBaseSink * bsink, guint64 offset, 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 */ @@ -591,8 +601,8 @@ gst_directdraw_sink_buffer_alloc (GstBaseSink * bsink, guint64 offset, ddrawsink->buffer_pool); /* If the surface is invalid for our need, destroy */ - if ((surface->width != ddrawsink->video_width) || - (surface->height != ddrawsink->video_height) || + 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)) @@ -615,9 +625,7 @@ gst_directdraw_sink_buffer_alloc (GstBaseSink * bsink, guint64 offset, HRESULT hres; DDSURFACEDESC2 surface_desc; DDSURFACEDESC2 *sd; - GstStructure *structure = NULL; - structure = gst_caps_get_structure (caps, 0); if (!gst_structure_get_int (structure, "depth", &depth)) { GST_CAT_DEBUG_OBJECT (directdrawsink_debug, ddrawsink, "Can't get depth from buffer_alloc caps"); @@ -673,7 +681,7 @@ gst_directdraw_sink_buffer_alloc (GstBaseSink * bsink, guint64 offset, buffer_caps = copy_caps; buffercaps_unref = TRUE; /* update buffer size needed to store video frames according to new caps */ - size = ddrawsink->video_width * ddrawsink->video_height * (bpp / 8); + size = width * height * (bpp / 8); /* update our member pixel format */ gst_ddrawvideosink_get_format_from_caps (ddrawsink, buffer_caps, -- cgit v1.2.1 From b4633a6930097eb3e48334d67ee62d4ef9ab0a5f Mon Sep 17 00:00:00 2001 From: Haakon Sporsheim Date: Wed, 7 May 2008 15:09:10 +0000 Subject: [MOVED FROM GOOD] sys/directdraw/gstdirectdrawsink.c (gst_directdraw_sink_set_caps): Fixed mid stream resolution change bug, the offscr... Original commit message from CVS: patch by: Haakon Sporsheim * sys/directdraw/gstdirectdrawsink.c (gst_directdraw_sink_set_caps): Fixed mid stream resolution change bug, the offscreen surface is now released when set_caps is called. Partially fixes #520885. --- sys/directdraw/gstdirectdrawsink.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'sys') diff --git a/sys/directdraw/gstdirectdrawsink.c b/sys/directdraw/gstdirectdrawsink.c index 9d34cf22..d049c575 100644 --- a/sys/directdraw/gstdirectdrawsink.c +++ b/sys/directdraw/gstdirectdrawsink.c @@ -510,6 +510,12 @@ gst_directdraw_sink_set_caps (GstBaseSink * bsink, GstCaps * caps) (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) { -- cgit v1.2.1 From 4e309644e82531028d0dace0715f1803e6bfdaf6 Mon Sep 17 00:00:00 2001 From: Haakon Sporsheim Date: Wed, 7 May 2008 15:19:47 +0000 Subject: [MOVED FROM GOOD] sys/directdraw/gstdirectdrawsink.c (gst_directdraw_sink_show_frame, Original commit message from CVS: patch by: Haakon Sporsheim * sys/directdraw/gstdirectdrawsink.c (gst_directdraw_sink_show_frame, WndProc, gst_directdraw_sink_window_thread): Improved Windows message loop and fixed window destruction issue. When the window which DirectDraw is rendering to is destroyed, the render/show_frame function will return GST_FLOW_ERROR. Partially fixes #520885. --- sys/directdraw/gstdirectdrawsink.c | 42 +++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 19 deletions(-) (limited to 'sys') diff --git a/sys/directdraw/gstdirectdrawsink.c b/sys/directdraw/gstdirectdrawsink.c index d049c575..a0df1c57 100644 --- a/sys/directdraw/gstdirectdrawsink.c +++ b/sys/directdraw/gstdirectdrawsink.c @@ -810,8 +810,14 @@ gst_directdraw_sink_show_frame (GstBaseSink * bsink, GstBuffer * buf) /* use last buffer */ buf = ddrawsink->last_buffer; } - if (buf == NULL) + + 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); @@ -1314,13 +1320,13 @@ WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) switch (message) { case WM_ERASEBKGND: return TRUE; - case WM_DESTROY: - PostQuitMessage (0); - break; case WM_CLOSE: DestroyWindow (hWnd); + case WM_DESTROY: + PostQuitMessage (0); return 0; } + return DefWindowProc (hWnd, message, wParam, lParam); } @@ -1328,6 +1334,7 @@ static gpointer gst_directdraw_sink_window_thread (GstDirectDrawSink * ddrawsink) { WNDCLASS WndClass; + MSG msg; memset (&WndClass, 0, sizeof (WNDCLASS)); WndClass.style = CS_HREDRAW | CS_VREDRAW; @@ -1357,24 +1364,21 @@ gst_directdraw_sink_window_thread (GstDirectDrawSink * ddrawsink) ReleaseSemaphore (ddrawsink->window_created_signal, 1, NULL); /* start message loop processing our default window messages */ - while (1) { - MSG msg; - - if (GetMessage (&msg, ddrawsink->video_window, 0, 0) <= 0) { - 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); - } - break; - } + 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; } -- cgit v1.2.1 From 0a7b74558542bdc3ed6ef354576b0b9fa3bd9471 Mon Sep 17 00:00:00 2001 From: Haakon Sporsheim Date: Wed, 7 May 2008 15:28:06 +0000 Subject: [MOVED FROM GOOD] sys/directdraw/gstdirectdrawsink.c (gst_directdraw_sink_show_frame): Added checking of surface lost case after an uns... Original commit message from CVS: patch by: Haakon Sporsheim * sys/directdraw/gstdirectdrawsink.c (gst_directdraw_sink_show_frame): Added checking of surface lost case after an unsuccessful IDirectDrawSurface7_Lock() call. If surface is lost, return GST_FLOW_OK. --- sys/directdraw/gstdirectdrawsink.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'sys') diff --git a/sys/directdraw/gstdirectdrawsink.c b/sys/directdraw/gstdirectdrawsink.c index a0df1c57..b5a93225 100644 --- a/sys/directdraw/gstdirectdrawsink.c +++ b/sys/directdraw/gstdirectdrawsink.c @@ -880,7 +880,11 @@ gst_directdraw_sink_show_frame (GstBaseSink * bsink, GstBuffer * buf) GST_CAT_WARNING_OBJECT (directdrawsink_debug, ddrawsink, "gst_directdraw_sink_show_frame failed locking surface %s", DDErrorString (hRes)); - return GST_FLOW_ERROR; + + 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 */ -- cgit v1.2.1 From 934179d813b2e7096eb0aa4fc2fdd9e557765ef5 Mon Sep 17 00:00:00 2001 From: Haakon Sporsheim Date: Wed, 7 May 2008 15:33:52 +0000 Subject: [MOVED FROM GOOD] sys/directdraw/gstdirectdrawsink.c (gst_directdraw_sink_setup_ddraw): Do IDirectDrawClipper_SetHWnd() if the window I... Original commit message from CVS: patch by: Haakon Sporsheim * sys/directdraw/gstdirectdrawsink.c (gst_directdraw_sink_setup_ddraw): Do IDirectDrawClipper_SetHWnd() if the window ID has already been set after creating the clipper. --- sys/directdraw/gstdirectdrawsink.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'sys') diff --git a/sys/directdraw/gstdirectdrawsink.c b/sys/directdraw/gstdirectdrawsink.c index b5a93225..d0a318b7 100644 --- a/sys/directdraw/gstdirectdrawsink.c +++ b/sys/directdraw/gstdirectdrawsink.c @@ -1308,6 +1308,9 @@ gst_directdraw_sink_setup_ddraw (GstDirectDrawSink * ddrawsink) 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; -- cgit v1.2.1 From c99b497b4fc6f9b87e4836de64eb211f67670b82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ole=20Andr=C3=A9=20Vadla=20Ravn=C3=A5s?= Date: Thu, 21 Aug 2008 15:28:09 +0000 Subject: [MOVED FROM GOOD] sys/directdraw/gstdirectdrawsink.c: Fix buffer ref leak. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Original commit message from CVS: Patch by: Ole André Vadla Ravnås * sys/directdraw/gstdirectdrawsink.c: (gst_directdraw_sink_show_frame): Fix buffer ref leak. --- sys/directdraw/gstdirectdrawsink.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'sys') diff --git a/sys/directdraw/gstdirectdrawsink.c b/sys/directdraw/gstdirectdrawsink.c index d0a318b7..18d6178e 100644 --- a/sys/directdraw/gstdirectdrawsink.c +++ b/sys/directdraw/gstdirectdrawsink.c @@ -800,12 +800,10 @@ gst_directdraw_sink_show_frame (GstBaseSink * bsink, GstBuffer * buf) if (buf) { /* save a reference to the input buffer */ - if (ddrawsink->last_buffer != buf) { - if (ddrawsink->last_buffer) { - gst_buffer_unref (ddrawsink->last_buffer); - } - } - ddrawsink->last_buffer = gst_buffer_ref (buf); + 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; -- cgit v1.2.1 From 88fb052f4fc83579310fef2857c68a54ddd9fca4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ole=20Andr=C3=A9=20Vadla=20Ravn=C3=A5s?= Date: Thu, 21 Aug 2008 21:56:19 +0000 Subject: [MOVED FROM GOOD] sys/directdraw/gstdirectdrawsink.c (gst_directdraw_sink_buffer_alloc, gst_directdraw_sink_bufferpool_clear): Original commit message from CVS: * sys/directdraw/gstdirectdrawsink.c (gst_directdraw_sink_buffer_alloc, gst_directdraw_sink_bufferpool_clear): Fix two more buffer ref leaks. --- sys/directdraw/gstdirectdrawsink.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'sys') diff --git a/sys/directdraw/gstdirectdrawsink.c b/sys/directdraw/gstdirectdrawsink.c index 18d6178e..caa28005 100644 --- a/sys/directdraw/gstdirectdrawsink.c +++ b/sys/directdraw/gstdirectdrawsink.c @@ -614,6 +614,7 @@ gst_directdraw_sink_buffer_alloc (GstBaseSink * bsink, guint64 offset, !gst_directdraw_sink_surface_check (ddrawsink, surface)) ) { gst_directdraw_sink_surface_destroy (ddrawsink, surface); + gst_buffer_unref (surface); surface = NULL; } else { /* We found a suitable surface */ @@ -1897,6 +1898,7 @@ gst_directdraw_sink_bufferpool_clear (GstDirectDrawSink * ddrawsink) ddrawsink->buffer_pool = g_slist_delete_link (ddrawsink->buffer_pool, ddrawsink->buffer_pool); gst_directdraw_sink_surface_destroy (ddrawsink, surface); + gst_buffer_unref (surface); } g_mutex_unlock (ddrawsink->pool_lock); } -- cgit v1.2.1 From 9d4bfe34dbde8410a06fce62efe6d76c88a94266 Mon Sep 17 00:00:00 2001 From: Stefan Kost Date: Tue, 4 Nov 2008 12:28:34 +0000 Subject: [MOVED FROM GOOD] Don't install static libs for plugins. Fixes #550851 for -good. Original commit message from CVS: * ext/aalib/Makefile.am: * ext/annodex/Makefile.am: * ext/cairo/Makefile.am: * ext/dv/Makefile.am: * ext/esd/Makefile.am: * ext/flac/Makefile.am: * ext/gconf/Makefile.am: * ext/gdk_pixbuf/Makefile.am: * ext/hal/Makefile.am: * ext/jpeg/Makefile.am: * ext/ladspa/Makefile.am: * ext/libcaca/Makefile.am: * ext/libmng/Makefile.am: * ext/libpng/Makefile.am: * ext/mikmod/Makefile.am: * ext/pulse/Makefile.am: * ext/raw1394/Makefile.am: * ext/shout2/Makefile.am: * ext/soup/Makefile.am: * ext/speex/Makefile.am: * ext/taglib/Makefile.am: * ext/wavpack/Makefile.am: * gst/alpha/Makefile.am: * gst/apetag/Makefile.am: * gst/audiofx/Makefile.am: * gst/auparse/Makefile.am: * gst/autodetect/Makefile.am: * gst/avi/Makefile.am: * gst/cutter/Makefile.am: * gst/debug/Makefile.am: * gst/effectv/Makefile.am: * gst/equalizer/Makefile.am: * gst/flx/Makefile.am: * gst/goom/Makefile.am: * gst/goom2k1/Makefile.am: * gst/icydemux/Makefile.am: * gst/id3demux/Makefile.am: * gst/interleave/Makefile.am: * gst/law/Makefile.am: * gst/level/Makefile.am: * gst/matroska/Makefile.am: * gst/median/Makefile.am: * gst/monoscope/Makefile.am: * gst/multifile/Makefile.am: * gst/multipart/Makefile.am: * gst/oldcore/Makefile.am: * gst/qtdemux/Makefile.am: * gst/replaygain/Makefile.am: * gst/rtp/Makefile.am: * gst/rtsp/Makefile.am: * gst/smpte/Makefile.am: * gst/spectrum/Makefile.am: * gst/udp/Makefile.am: * gst/videobox/Makefile.am: * gst/videocrop/Makefile.am: * gst/videofilter/Makefile.am: * gst/videomixer/Makefile.am: * gst/wavenc/Makefile.am: * gst/wavparse/Makefile.am: * sys/directdraw/Makefile.am: * sys/directsound/Makefile.am: * sys/oss/Makefile.am: * sys/osxaudio/Makefile.am: * sys/osxvideo/Makefile.am: * sys/sunaudio/Makefile.am: * sys/v4l2/Makefile.am: * sys/waveform/Makefile.am: * sys/ximage/Makefile.am: Don't install static libs for plugins. Fixes #550851 for -good. --- sys/directdraw/Makefile.am | 1 + 1 file changed, 1 insertion(+) (limited to 'sys') diff --git a/sys/directdraw/Makefile.am b/sys/directdraw/Makefile.am index dddaf189..647d58ac 100644 --- a/sys/directdraw/Makefile.am +++ b/sys/directdraw/Makefile.am @@ -7,5 +7,6 @@ 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 -- cgit v1.2.1 From 88e98b2298b338d0e342af8846a5f73d690831d0 Mon Sep 17 00:00:00 2001 From: Stefan Kost Date: Thu, 29 Jan 2009 10:10:08 +0200 Subject: [MOVED FROM GOOD] Update and add documentation for platform specific plugins (sys). Link to properties. Correct titles for examples. Fix examples. --- sys/directdraw/gstdirectdrawsink.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) (limited to 'sys') diff --git a/sys/directdraw/gstdirectdrawsink.c b/sys/directdraw/gstdirectdrawsink.c index caa28005..26babd90 100644 --- a/sys/directdraw/gstdirectdrawsink.c +++ b/sys/directdraw/gstdirectdrawsink.c @@ -25,21 +25,17 @@ /** * 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 + * 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. - * - * Examples - * - * Here is a simple pipeline to test the sink : - * + * + * + * Example pipelines + * |[ * gst-launch-0.10 -v videotestsrc ! directdrawsink - * - * + * ]| a simple pipeline to test the sink * */ -- cgit v1.2.1 From 3aafd4f9c35922b01f30c278007eca40ed224544 Mon Sep 17 00:00:00 2001 From: Stefan Kost Date: Thu, 29 Jan 2009 11:07:59 +0200 Subject: [MOVED FROM GOOD] Remove version numbers from a few gst-launch examples. The majority of the examples doe not use -0.10 and this will also help us to maintain the docs. --- sys/directdraw/gstdirectdrawsink.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sys') diff --git a/sys/directdraw/gstdirectdrawsink.c b/sys/directdraw/gstdirectdrawsink.c index 26babd90..a128b317 100644 --- a/sys/directdraw/gstdirectdrawsink.c +++ b/sys/directdraw/gstdirectdrawsink.c @@ -34,7 +34,7 @@ * * Example pipelines * |[ - * gst-launch-0.10 -v videotestsrc ! directdrawsink + * gst-launch -v videotestsrc ! directdrawsink * ]| a simple pipeline to test the sink * */ -- cgit v1.2.1 From 770c18986da43fde4b1257b50440c78cba4aade4 Mon Sep 17 00:00:00 2001 From: LRN Date: Fri, 27 Feb 2009 20:40:31 +0100 Subject: [MOVED FROM GOOD] directdrawsink: Fix type mismatches Fixes bug #573343. --- sys/directdraw/gstdirectdrawsink.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'sys') diff --git a/sys/directdraw/gstdirectdrawsink.c b/sys/directdraw/gstdirectdrawsink.c index a128b317..144f6595 100644 --- a/sys/directdraw/gstdirectdrawsink.c +++ b/sys/directdraw/gstdirectdrawsink.c @@ -610,7 +610,7 @@ gst_directdraw_sink_buffer_alloc (GstBaseSink * bsink, guint64 offset, !gst_directdraw_sink_surface_check (ddrawsink, surface)) ) { gst_directdraw_sink_surface_destroy (ddrawsink, surface); - gst_buffer_unref (surface); + gst_buffer_unref (GST_BUFFER_CAST (surface)); surface = NULL; } else { /* We found a suitable surface */ @@ -629,7 +629,7 @@ gst_directdraw_sink_buffer_alloc (GstBaseSink * bsink, guint64 offset, DDSURFACEDESC2 surface_desc; DDSURFACEDESC2 *sd; - if (!gst_structure_get_int (structure, "depth", &depth)) { + 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; @@ -663,7 +663,7 @@ gst_directdraw_sink_buffer_alloc (GstBaseSink * bsink, guint64 offset, gint bpp, endianness, red_mask, green_mask, blue_mask; /* get new display mode properties */ - gst_structure_get_int (display_structure, "depth", &depth); + 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); @@ -997,7 +997,7 @@ gst_ddrawvideosink_get_format_from_caps (GstDirectDrawSink * ddrawsink, pPixelFormat->dwBBitMask = GUINT32_TO_BE (pPixelFormat->dwBBitMask); } } else if (gst_structure_has_name (structure, "video/x-raw-yuv")) { - gint fourcc; + guint32 fourcc; pPixelFormat->dwFlags = DDPF_FOURCC; ret &= gst_structure_get_fourcc (structure, "format", &fourcc); @@ -1894,7 +1894,7 @@ gst_directdraw_sink_bufferpool_clear (GstDirectDrawSink * ddrawsink) ddrawsink->buffer_pool = g_slist_delete_link (ddrawsink->buffer_pool, ddrawsink->buffer_pool); gst_directdraw_sink_surface_destroy (ddrawsink, surface); - gst_buffer_unref (surface); + gst_buffer_unref (GST_BUFFER_CAST (surface)); } g_mutex_unlock (ddrawsink->pool_lock); } -- cgit v1.2.1 From 3a05abd2b1e7813fe54d8d54ca1643e4f576f889 Mon Sep 17 00:00:00 2001 From: Jan Schmidt Date: Sat, 16 May 2009 01:14:23 +0100 Subject: Moved 'directdraw' from -good to -bad --- sys/Makefile.am | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'sys') diff --git a/sys/Makefile.am b/sys/Makefile.am index e6212c65..161f3339 100644 --- a/sys/Makefile.am +++ b/sys/Makefile.am @@ -22,6 +22,12 @@ endif # CDROM_DIR= # endif +if USE_DIRECTDRAW +DIRECTDRAW_DIR=directdraw +else +DIRECTDRAW_DIR= +endif + if USE_FBDEV FBDEV_DIR=fbdev else @@ -64,8 +70,8 @@ else ACM_DIR= endif -SUBDIRS = $(ACM_DIR) $(DVB_DIR) $(FBDEV_DIR) $(OSS4_DIR) $(OSX_VIDEO_DIR) $(QT_DIR) $(VCD_DIR) $(WININET_DIR) +SUBDIRS = $(ACM_DIR) $(DIRECTDRAW_DIR) $(DVB_DIR) $(FBDEV_DIR) $(OSS4_DIR) $(OSX_VIDEO_DIR) $(QT_DIR) $(VCD_DIR) $(WININET_DIR) -DIST_SUBDIRS = acmenc acmmp3dec dvb fbdev dshowdecwrapper dshowsrcwrapper dshowvideosink \ +DIST_SUBDIRS = acmenc acmmp3dec directdraw dvb fbdev dshowdecwrapper dshowsrcwrapper dshowvideosink \ oss4 osxvideo qtwrapper vcd wasapi wininet winks winscreencap -- cgit v1.2.1