/* GStreamer SDL plugin
 * Copyright (C) 2001-2002 Ronald Bultje <rbultje@ronald.bitfreak.net>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

/* let's not forget to mention that all this was based on aasink ;-) */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <signal.h>
#include <string.h>
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#include <stdlib.h>

#include <gst/glib-compat-private.h>
#include <gst/interfaces/xoverlay.h>
#include <gst/interfaces/navigation.h>

#include "sdlvideosink.h"

GST_DEBUG_CATEGORY_EXTERN (sdl_debug);
#define GST_CAT_DEFAULT sdl_debug

/* These macros are adapted from videotestsrc.c 
 *  and/or gst-plugins/gst/games/gstvideoimage.c */
#define I420_Y_ROWSTRIDE(width) (GST_ROUND_UP_4(width))
#define I420_U_ROWSTRIDE(width) (GST_ROUND_UP_8(width)/2)
#define I420_V_ROWSTRIDE(width) ((GST_ROUND_UP_8(I420_Y_ROWSTRIDE(width)))/2)

#define I420_Y_OFFSET(w,h) (0)
#define I420_U_OFFSET(w,h) (I420_Y_OFFSET(w,h)+(I420_Y_ROWSTRIDE(w)*GST_ROUND_UP_2(h)))
#define I420_V_OFFSET(w,h) (I420_U_OFFSET(w,h)+(I420_U_ROWSTRIDE(w)*GST_ROUND_UP_2(h)/2))

#define I420_SIZE(w,h)     (I420_V_OFFSET(w,h)+(I420_V_ROWSTRIDE(w)*GST_ROUND_UP_2(h)/2))


enum
{
  PROP_0,
  PROP_FULLSCREEN
};

static void gst_sdlvideosink_interface_init (GstImplementsInterfaceClass *
    klass);
static gboolean gst_sdlvideosink_supported (GstImplementsInterface * iface,
    GType type);

static void gst_sdlvideosink_xoverlay_init (GstXOverlayClass * klass);
static void gst_sdlvideosink_xoverlay_set_window_handle
    (GstXOverlay * overlay, guintptr parent);

static gboolean gst_sdlvideosink_lock (GstSDLVideoSink * sdl);
static void gst_sdlvideosink_unlock (GstSDLVideoSink * sdl);

static gboolean gst_sdlvideosink_initsdl (GstSDLVideoSink * sdl);
static void gst_sdlvideosink_deinitsdl (GstSDLVideoSink * sdl);

static gboolean gst_sdlvideosink_create (GstSDLVideoSink * sdl);
static void gst_sdlvideosink_destroy (GstSDLVideoSink * sdl);

static gboolean gst_sdlvideosink_setcaps (GstBaseSink * bsink, GstCaps * caps);

static GstFlowReturn gst_sdlvideosink_show_frame (GstBaseSink * bsink,
    GstBuffer * buff);

static void gst_sdlvideosink_set_property (GObject * object,
    guint prop_id, const GValue * value, GParamSpec * pspec);
static void gst_sdlvideosink_get_property (GObject * object,
    guint prop_id, GValue * value, GParamSpec * pspec);
static GstStateChangeReturn
gst_sdlvideosink_change_state (GstElement * element, GstStateChange transition);

static void gst_sdlvideosink_navigation_init (GstNavigationInterface * iface);

static void gst_sdlv_process_events (GstSDLVideoSink * sdlvideosink);

static GstPadTemplate *sink_template;

static void
_do_init (GType type)
{
  static const GInterfaceInfo iface_info = {
    (GInterfaceInitFunc) gst_sdlvideosink_interface_init,
    NULL,
    NULL,
  };
  static const GInterfaceInfo xoverlay_info = {
    (GInterfaceInitFunc) gst_sdlvideosink_xoverlay_init,
    NULL,
    NULL,
  };
  static const GInterfaceInfo navigation_info = {
    (GInterfaceInitFunc) gst_sdlvideosink_navigation_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);
  g_type_add_interface_static (type, GST_TYPE_NAVIGATION, &navigation_info);

}

GST_BOILERPLATE_FULL (GstSDLVideoSink, gst_sdlvideosink, GstVideoSink,
    GST_TYPE_VIDEO_SINK, _do_init);

static void
gst_sdlvideosink_base_init (gpointer g_class)
{
  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
  GstCaps *capslist;
  gint i;
  guint32 formats[] = {
    GST_MAKE_FOURCC ('I', '4', '2', '0'),
    GST_MAKE_FOURCC ('Y', 'V', '1', '2'),
    GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'),
    GST_MAKE_FOURCC ('Y', 'V', 'Y', 'U'),
    GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y')
  };

  /* make a list of all available caps */
  capslist = gst_caps_new_empty ();
  for (i = 0; i < G_N_ELEMENTS (formats); i++) {
    gst_caps_append_structure (capslist,
        gst_structure_new ("video/x-raw-yuv",
            "format", GST_TYPE_FOURCC, formats[i],
            "width", GST_TYPE_INT_RANGE, 1, G_MAXINT,
            "height", GST_TYPE_INT_RANGE, 1, G_MAXINT,
            "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, 100, 1, NULL));
  }

  sink_template = gst_pad_template_new ("sink",
      GST_PAD_SINK, GST_PAD_ALWAYS, capslist);

  gst_element_class_add_pad_template (element_class, sink_template);
  gst_element_class_set_static_metadata (element_class, "SDL video sink",
      "Sink/Video", "An SDL-based videosink",
      "Ronald Bultje <rbultje@ronald.bitfreak.net>, "
      "Edgard Lima <edgard.lima@indt.org.br>, "
      "Jan Schmidt <thaytan@mad.scientist.com>");
}

static void
gst_sdlvideosink_finalize (GObject * obj)
{
  g_mutex_free (GST_SDLVIDEOSINK (obj)->lock);

  G_OBJECT_CLASS (parent_class)->finalize (obj);
}

static void
gst_sdlvideosink_get_times (GstBaseSink * basesink, GstBuffer * buffer,
    GstClockTime * start, GstClockTime * end)
{
  GstSDLVideoSink *sdlvideosink = GST_SDLVIDEOSINK (basesink);
  GstClockTime timestamp, duration;

  timestamp = GST_BUFFER_TIMESTAMP (buffer);
  if (GST_CLOCK_TIME_IS_VALID (timestamp)) {
    *start = timestamp;
    duration = GST_BUFFER_DURATION (buffer);
    if (GST_CLOCK_TIME_IS_VALID (duration)) {
      *end = timestamp + duration;
    } else {
      if (sdlvideosink->framerate_n > 0) {
        *end = timestamp +
            gst_util_uint64_scale_int (GST_SECOND, sdlvideosink->framerate_d,
            sdlvideosink->framerate_n);
      }
    }
  }
}

static void
gst_sdlvideosink_class_init (GstSDLVideoSinkClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *gstelement_class;
  GstBaseSinkClass *gstvs_class;

  gobject_class = (GObjectClass *) klass;
  gstelement_class = (GstElementClass *) klass;
  gstvs_class = (GstBaseSinkClass *) klass;

  parent_class = g_type_class_peek_parent (klass);

  gobject_class->set_property = gst_sdlvideosink_set_property;
  gobject_class->get_property = gst_sdlvideosink_get_property;

  gobject_class->finalize = gst_sdlvideosink_finalize;

  gstelement_class->change_state =
      GST_DEBUG_FUNCPTR (gst_sdlvideosink_change_state);

  gstvs_class->set_caps = GST_DEBUG_FUNCPTR (gst_sdlvideosink_setcaps);
  gstvs_class->get_times = GST_DEBUG_FUNCPTR (gst_sdlvideosink_get_times);
  gstvs_class->preroll = GST_DEBUG_FUNCPTR (gst_sdlvideosink_show_frame);
  gstvs_class->render = GST_DEBUG_FUNCPTR (gst_sdlvideosink_show_frame);

  g_object_class_install_property (gobject_class, PROP_FULLSCREEN,
      g_param_spec_boolean ("fullscreen", "Fullscreen",
          "If true it will be Full screen", FALSE,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  /*gstvs_class->set_video_out = gst_sdlvideosink_set_video_out;
     gstvs_class->push_ui_event = gst_sdlvideosink_push_ui_event;
     gstvs_class->set_geometry = gst_sdlvideosink_set_geometry; */
}

#if 0
/* FIXME */
static GstBuffer *
gst_sdlvideosink_buffer_new (GstBufferPool * pool,
    gint64 location, guint size, gpointer user_data)
{
  GstSDLVideoSink *sdlvideosink = GST_SDLVIDEOSINK (user_data);
  GstBuffer *buffer;

  if (!sdlvideosink->overlay)
    return NULL;

  if (!gst_sdlvideosink_lock (sdlvideosink)) {
    return NULL;
  }

  /* this protects the buffer from being written over multiple times */
  g_mutex_lock (sdlvideosink->lock);

  buffer = gst_buffer_new ();
  GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_DONTFREE);
  GST_BUFFER_DATA (buffer) = sdlvideosink->overlay->pixels[0];
  if (sdlvideosink->format == SDL_YV12_OVERLAY ||
      sdlvideosink->format == SDL_IYUV_OVERLAY) {
    GST_BUFFER_SIZE (buffer) =
        sdlvideosink->width * sdlvideosink->height * 3 / 2;
  } else {
    GST_BUFFER_SIZE (buffer) = sdlvideosink->width * sdlvideosink->height * 2;
  }
  GST_BUFFER_MAXSIZE (buffer) = GST_BUFFER_SIZE (buffer);

  return buffer;
}

static void
gst_sdlvideosink_buffer_free (GstBufferPool * pool,
    GstBuffer * buffer, gpointer user_data)
{
  GstSDLVideoSink *sdlvideosink = GST_SDLVIDEOSINK (user_data);

  g_mutex_unlock (sdlvideosink->lock);
  gst_sdlvideosink_unlock (sdlvideosink);

  gst_buffer_default_free (buffer);
}


static GstBufferPool *
gst_sdlvideosink_get_bufferpool (GstPad * pad)
{
  GstSDLVideoSink *sdlvideosink = GST_SDLVIDEOSINK (gst_pad_get_parent (pad));

  if (sdlvideosink->overlay)
    return sdlvideosink->bufferpool;

  return NULL;
}
#endif

static void
gst_sdlvideosink_init (GstSDLVideoSink * sdlvideosink,
    GstSDLVideoSinkClass * g_class)
{

  sdlvideosink->width = -1;
  sdlvideosink->height = -1;
  sdlvideosink->framerate_n = 0;
  sdlvideosink->framerate_d = 1;
  sdlvideosink->full_screen = FALSE;

  sdlvideosink->overlay = NULL;
  sdlvideosink->screen = NULL;

  sdlvideosink->xwindow_id = 0;

  //sdlvideosink->capslist = capslist;

  sdlvideosink->init = FALSE;

  sdlvideosink->event_thread = NULL;
  sdlvideosink->running = FALSE;

  sdlvideosink->lock = g_mutex_new ();
}

static void
gst_sdlvideosink_interface_init (GstImplementsInterfaceClass * klass)
{
  klass->supported = gst_sdlvideosink_supported;
}

static gboolean
gst_sdlvideosink_supported (GstImplementsInterface * interface,
    GType iface_type)
{
  GstSDLVideoSink *sdlvideosink = GST_SDLVIDEOSINK (interface);
  gboolean result = FALSE;

  /* check SDL for whether it was compiled against X, FB, etc. */
  if (iface_type == GST_TYPE_X_OVERLAY) {
    gchar tmp[4];

    if (!sdlvideosink->init) {
      g_mutex_lock (sdlvideosink->lock);
      SDL_Init (SDL_INIT_VIDEO);

      /* True if the video driver is X11 */
      result = (strcmp ("x11", SDL_VideoDriverName (tmp, 4)) == 0);
      SDL_QuitSubSystem (SDL_INIT_VIDEO);
      g_mutex_unlock (sdlvideosink->lock);
    } else
      result = sdlvideosink->is_xwindows;
  } else if (iface_type == GST_TYPE_NAVIGATION)
    result = TRUE;

  return result;
}

/* SDL Video sink and X overlay: 
 *
 * SDL supports creating an Xv window/overlay within an existing X window
 * through the horrible mechanism of setting the WINDOWID environment
 * variable.
 * It will then display the x overlay within that window, but not at the
 * full window size. Instead, we need to explicitly tell SDL the size.
 *
 * Unfortunately, the XOverlay interface in GStreamer doesn't supply
 * that information. The only way to get it would be to do what X[v]imagesink
 * does and retrieve it using X11 calls, and linking to Xlib. That would
 * defeat the whole purpose of using the SDL abstraction and plugin entirely
 * however. 
 *
 * I have no nice solution to this problem for you, dear readers.
 */
static void
gst_sdlvideosink_xoverlay_init (GstXOverlayClass * klass)
{
  klass->set_window_handle = gst_sdlvideosink_xoverlay_set_window_handle;
}

static void
gst_sdlvideosink_xoverlay_set_window_handle (GstXOverlay * overlay,
    guintptr handle)
{
  GstSDLVideoSink *sdlvideosink = GST_SDLVIDEOSINK (overlay);
  unsigned long parent = (unsigned long) handle;

  if (sdlvideosink->xwindow_id == parent)
    return;

  sdlvideosink->xwindow_id = parent;

  /* are we running yet? */
  if (sdlvideosink->init) {
    gboolean negotiated;

    g_mutex_lock (sdlvideosink->lock);

    negotiated = (sdlvideosink->overlay != NULL);

    if (negotiated)
      gst_sdlvideosink_destroy (sdlvideosink);

    /* Call initsdl to set the WINDOWID env var urk */
    gst_sdlvideosink_initsdl (sdlvideosink);

    if (negotiated)
      gst_sdlvideosink_create (sdlvideosink);

    g_mutex_unlock (sdlvideosink->lock);
  }
}

static guint32
gst_sdlvideosink_get_sdl_from_fourcc (GstSDLVideoSink * sdlvideosink,
    guint32 code)
{
  switch (code) {
      /* Note: SDL_IYUV_OVERLAY does not always work for I420 */
    case GST_MAKE_FOURCC ('I', '4', '2', '0'):
      return SDL_YV12_OVERLAY;
    case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
      return SDL_YV12_OVERLAY;
    case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
      return SDL_YUY2_OVERLAY;
    case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
      return SDL_UYVY_OVERLAY;
    case GST_MAKE_FOURCC ('Y', 'V', 'Y', 'U'):
      return SDL_YVYU_OVERLAY;
    default:
      return 0;
  }
}

static gboolean
gst_sdlvideosink_lock (GstSDLVideoSink * sdlvideosink)
{
  /* assure that we've got a screen */
  if (!sdlvideosink->screen || !sdlvideosink->overlay)
    goto no_setup;

  /* Lock SDL/yuv-overlay */
  if (SDL_MUSTLOCK (sdlvideosink->screen)) {
    if (SDL_LockSurface (sdlvideosink->screen) < 0)
      goto could_not_lock;
  }
  if (SDL_LockYUVOverlay (sdlvideosink->overlay) < 0)
    goto lock_yuv;

  return TRUE;

  /* ERRORS */
no_setup:
  {
    GST_ELEMENT_ERROR (sdlvideosink, LIBRARY, TOO_LAZY, (NULL),
        ("Tried to lock screen without being set-up"));
    return FALSE;
  }
could_not_lock:
  {
    GST_ELEMENT_ERROR (sdlvideosink, LIBRARY, TOO_LAZY, (NULL),
        ("SDL: couldn't lock the SDL video window: %s", SDL_GetError ()));
    return FALSE;
  }
lock_yuv:
  {
    GST_ELEMENT_ERROR (sdlvideosink, LIBRARY, TOO_LAZY, (NULL),
        ("SDL: couldn\'t lock the SDL YUV overlay: %s", SDL_GetError ()));
    return FALSE;
  }
}


static void
gst_sdlvideosink_unlock (GstSDLVideoSink * sdlvideosink)
{
  /* Unlock SDL_overlay */
  SDL_UnlockYUVOverlay (sdlvideosink->overlay);
  if (SDL_MUSTLOCK (sdlvideosink->screen))
    SDL_UnlockSurface (sdlvideosink->screen);
}

/* Must be called with ->lock held */
static void
gst_sdlvideosink_deinitsdl (GstSDLVideoSink * sdlvideosink)
{
  if (sdlvideosink->init) {
    sdlvideosink->running = FALSE;
    if (sdlvideosink->event_thread) {
      g_mutex_unlock (sdlvideosink->lock);
      g_thread_join (sdlvideosink->event_thread);
      g_mutex_lock (sdlvideosink->lock);
      sdlvideosink->event_thread = NULL;
    }

    SDL_QuitSubSystem (SDL_INIT_VIDEO);
    sdlvideosink->init = FALSE;

  }
}

/* Process pending events. Call with ->lock held */
static void
gst_sdlv_process_events (GstSDLVideoSink * sdlvideosink)
{
  SDL_Event event;
  int numevents;
  char *keysym = NULL;

  do {
    SDL_PumpEvents ();
    numevents = SDL_PeepEvents (&event, 1, SDL_GETEVENT,
        SDL_KEYDOWNMASK | SDL_KEYUPMASK |
        SDL_MOUSEMOTIONMASK | SDL_MOUSEBUTTONDOWNMASK |
        SDL_MOUSEBUTTONUPMASK | SDL_QUITMASK | SDL_VIDEORESIZEMASK);

    if (numevents > 0 && (event.type == SDL_KEYUP || event.type == SDL_KEYDOWN)) {
      keysym = SDL_GetKeyName (event.key.keysym.sym);
    }

    if (numevents > 0) {
      g_mutex_unlock (sdlvideosink->lock);
      switch (event.type) {
        case SDL_MOUSEMOTION:
          gst_navigation_send_mouse_event (GST_NAVIGATION (sdlvideosink),
              "mouse-move", 0, event.motion.x, event.motion.y);
          break;
        case SDL_MOUSEBUTTONDOWN:
          gst_navigation_send_mouse_event (GST_NAVIGATION (sdlvideosink),
              "mouse-button-press",
              event.button.button, event.button.x, event.button.y);
          break;
        case SDL_MOUSEBUTTONUP:
          gst_navigation_send_mouse_event (GST_NAVIGATION (sdlvideosink),
              "mouse-button-release",
              event.button.button, event.button.x, event.button.y);
          break;
        case SDL_KEYUP:
          GST_DEBUG ("key press event %s !",
              SDL_GetKeyName (event.key.keysym.sym));
          gst_navigation_send_key_event (GST_NAVIGATION (sdlvideosink),
              "key-release", keysym);
          break;
        case SDL_KEYDOWN:
          if (SDLK_ESCAPE != event.key.keysym.sym) {
            GST_DEBUG ("key press event %s !",
                SDL_GetKeyName (event.key.keysym.sym));
            gst_navigation_send_key_event (GST_NAVIGATION (sdlvideosink),
                "key-press", keysym);
            break;
          } else {
            /* fall through */
          }
        case SDL_QUIT:
          sdlvideosink->running = FALSE;
          GST_ELEMENT_ERROR (sdlvideosink, RESOURCE, OPEN_WRITE,
              ("Video output device is gone."),
              ("We were running fullscreen and user "
                  "pressed the ESC key, stopping playback."));
          break;
        case SDL_VIDEORESIZE:
          /* create a SDL window of the size requested by the user */
          g_mutex_lock (sdlvideosink->lock);
          GST_VIDEO_SINK_WIDTH (sdlvideosink) = event.resize.w;
          GST_VIDEO_SINK_HEIGHT (sdlvideosink) = event.resize.h;
          gst_sdlvideosink_create (sdlvideosink);
          g_mutex_unlock (sdlvideosink->lock);
          break;
      }
      g_mutex_lock (sdlvideosink->lock);
    }
  } while (numevents > 0);
}

static gpointer
gst_sdlvideosink_event_thread (GstSDLVideoSink * sdlvideosink)
{
  g_mutex_lock (sdlvideosink->lock);
  while (sdlvideosink->running) {
    gst_sdlv_process_events (sdlvideosink);

    /* Done events, sleep for 50 ms */
    g_mutex_unlock (sdlvideosink->lock);
    g_usleep (50000);
    g_mutex_lock (sdlvideosink->lock);
  }
  g_mutex_unlock (sdlvideosink->lock);

  return NULL;
}

/* Must be called with the SDL lock held */
static gboolean
gst_sdlvideosink_initsdl (GstSDLVideoSink * sdlvideosink)
{
  gst_sdlvideosink_deinitsdl (sdlvideosink);

  if (sdlvideosink->is_xwindows && !sdlvideosink->xwindow_id) {
    g_mutex_unlock (sdlvideosink->lock);
    gst_x_overlay_prepare_xwindow_id (GST_X_OVERLAY (sdlvideosink));
    g_mutex_lock (sdlvideosink->lock);
  }

  if (!sdlvideosink->xwindow_id) {
    g_unsetenv ("SDL_WINDOWID");
  } else {
    char SDL_hack[32];

    sprintf (SDL_hack, "%lu", sdlvideosink->xwindow_id);
    g_setenv ("SDL_WINDOWID", SDL_hack, 1);
  }

  /* Initialize the SDL library */
  if (SDL_Init (SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE) < 0)
    goto init_failed;

  sdlvideosink->init = TRUE;

  sdlvideosink->running = TRUE;
  sdlvideosink->event_thread =
      g_thread_create ((GThreadFunc) gst_sdlvideosink_event_thread,
      sdlvideosink, TRUE, NULL);

  return TRUE;

  /* ERRORS */
init_failed:
  {
    GST_ELEMENT_ERROR (sdlvideosink, LIBRARY, INIT, (NULL),
        ("Couldn't initialize SDL: %s", SDL_GetError ()));
    return FALSE;
  }
}

/* Must be called with the sdl lock held */
static void
gst_sdlvideosink_destroy (GstSDLVideoSink * sdlvideosink)
{
  if (sdlvideosink->overlay) {
    SDL_FreeYUVOverlay (sdlvideosink->overlay);
    sdlvideosink->overlay = NULL;
  }

  if (sdlvideosink->screen) {
    SDL_FreeSurface (sdlvideosink->screen);
    sdlvideosink->screen = NULL;
  }
  sdlvideosink->xwindow_id = 0;
}

/* Must be called with the sdl lock held */
static gboolean
gst_sdlvideosink_create (GstSDLVideoSink * sdlvideosink)
{
  if (GST_VIDEO_SINK_HEIGHT (sdlvideosink) <= 0)
    GST_VIDEO_SINK_HEIGHT (sdlvideosink) = sdlvideosink->height;
  if (GST_VIDEO_SINK_WIDTH (sdlvideosink) <= 0)
    GST_VIDEO_SINK_WIDTH (sdlvideosink) = sdlvideosink->width;

  gst_sdlvideosink_destroy (sdlvideosink);

  if (sdlvideosink->is_xwindows && !sdlvideosink->xwindow_id) {
    g_mutex_unlock (sdlvideosink->lock);
    gst_x_overlay_prepare_xwindow_id (GST_X_OVERLAY (sdlvideosink));
    g_mutex_lock (sdlvideosink->lock);
  }

  /* create a SDL window of the size requested by the user */
  if (sdlvideosink->full_screen) {
    sdlvideosink->screen =
        SDL_SetVideoMode (GST_VIDEO_SINK_WIDTH (sdlvideosink),
        GST_VIDEO_SINK_HEIGHT (sdlvideosink), 0,
        SDL_SWSURFACE | SDL_FULLSCREEN);
  } else {
    sdlvideosink->screen =
        SDL_SetVideoMode (GST_VIDEO_SINK_WIDTH (sdlvideosink),
        GST_VIDEO_SINK_HEIGHT (sdlvideosink), 0, SDL_HWSURFACE | SDL_RESIZABLE);
  }
  if (sdlvideosink->screen == NULL)
    goto no_screen;

  /* create a new YUV overlay */
  sdlvideosink->overlay = SDL_CreateYUVOverlay (sdlvideosink->width,
      sdlvideosink->height, sdlvideosink->format, sdlvideosink->screen);
  if (sdlvideosink->overlay == NULL)
    goto no_overlay;


  GST_DEBUG ("Using a %dx%d %dbpp SDL screen with a %dx%d \'%"
      GST_FOURCC_FORMAT "\' YUV overlay", GST_VIDEO_SINK_WIDTH (sdlvideosink),
      GST_VIDEO_SINK_HEIGHT (sdlvideosink),
      sdlvideosink->screen->format->BitsPerPixel, sdlvideosink->width,
      sdlvideosink->height, GST_FOURCC_ARGS (sdlvideosink->format));

  sdlvideosink->rect.x = 0;
  sdlvideosink->rect.y = 0;
  sdlvideosink->rect.w = GST_VIDEO_SINK_WIDTH (sdlvideosink);
  sdlvideosink->rect.h = GST_VIDEO_SINK_HEIGHT (sdlvideosink);

  /*SDL_DisplayYUVOverlay (sdlvideosink->overlay, &(sdlvideosink->rect)); */

  GST_DEBUG ("sdlvideosink: setting %08x (%" GST_FOURCC_FORMAT ")",
      sdlvideosink->format, GST_FOURCC_ARGS (sdlvideosink->format));

  return TRUE;

  /* ERRORS */
no_screen:
  {
    GST_ELEMENT_ERROR (sdlvideosink, LIBRARY, TOO_LAZY, (NULL),
        ("SDL: Couldn't set %dx%d: %s", GST_VIDEO_SINK_WIDTH (sdlvideosink),
            GST_VIDEO_SINK_HEIGHT (sdlvideosink), SDL_GetError ()));
    return FALSE;
  }
no_overlay:
  {
    GST_ELEMENT_ERROR (sdlvideosink, LIBRARY, TOO_LAZY, (NULL),
        ("SDL: Couldn't create SDL YUV overlay (%dx%d \'%" GST_FOURCC_FORMAT
            "\'): %s", sdlvideosink->width, sdlvideosink->height,
            GST_FOURCC_ARGS (sdlvideosink->format), SDL_GetError ()));
    return FALSE;
  }
}

static gboolean
gst_sdlvideosink_setcaps (GstBaseSink * bsink, GstCaps * vscapslist)
{
  GstSDLVideoSink *sdlvideosink;
  GstStructure *structure;
  gboolean res = TRUE;

  sdlvideosink = GST_SDLVIDEOSINK (bsink);

  structure = gst_caps_get_structure (vscapslist, 0);
  gst_structure_get_fourcc (structure, "format", &sdlvideosink->fourcc);
  sdlvideosink->format =
      gst_sdlvideosink_get_sdl_from_fourcc (sdlvideosink, sdlvideosink->fourcc);
  gst_structure_get_int (structure, "width", &sdlvideosink->width);
  gst_structure_get_int (structure, "height", &sdlvideosink->height);
  gst_structure_get_fraction (structure, "framerate",
      &sdlvideosink->framerate_n, &sdlvideosink->framerate_d);

  g_mutex_lock (sdlvideosink->lock);
  if (!sdlvideosink->format || !gst_sdlvideosink_create (sdlvideosink))
    res = FALSE;
  g_mutex_unlock (sdlvideosink->lock);

  return res;
}


static GstFlowReturn
gst_sdlvideosink_show_frame (GstBaseSink * bsink, GstBuffer * buf)
{

  GstSDLVideoSink *sdlvideosink;

  sdlvideosink = GST_SDLVIDEOSINK (bsink);

  g_mutex_lock (sdlvideosink->lock);
  if (!sdlvideosink->init ||
      !sdlvideosink->overlay || !sdlvideosink->overlay->pixels)
    goto not_init;

  /* if (GST_BUFFER_DATA (buf) != sdlvideosink->overlay->pixels[0]) */
  if (TRUE) {
    guint8 *out;
    gint l;

    if (!gst_sdlvideosink_lock (sdlvideosink))
      goto cannot_lock;

    /* buf->yuv - FIXME: bufferpool! */
    if (sdlvideosink->format == SDL_YV12_OVERLAY) {
      guint8 *y, *u, *v;

      switch (sdlvideosink->fourcc) {
        case GST_MAKE_FOURCC ('I', '4', '2', '0'):
          y = GST_BUFFER_DATA (buf);
          /* I420 is YV12 with switched colour planes and different offsets */
          v = y + I420_U_OFFSET (sdlvideosink->width, sdlvideosink->height);
          u = y + I420_V_OFFSET (sdlvideosink->width, sdlvideosink->height);
          break;
        case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
          y = GST_BUFFER_DATA (buf);
          u = y + I420_U_OFFSET (sdlvideosink->width, sdlvideosink->height);
          v = y + I420_V_OFFSET (sdlvideosink->width, sdlvideosink->height);
          break;
        default:
          gst_sdlvideosink_unlock (sdlvideosink);
          g_mutex_unlock (sdlvideosink->lock);
          g_return_val_if_reached (GST_FLOW_ERROR);
      }

      /* Y Plane */
      out = sdlvideosink->overlay->pixels[0];
      for (l = 0; l < sdlvideosink->height; l++) {
        memcpy (out, y, I420_Y_ROWSTRIDE (sdlvideosink->width));
        out += sdlvideosink->overlay->pitches[0];
        y += I420_Y_ROWSTRIDE (sdlvideosink->width);
      }

      /* U plane */
      out = sdlvideosink->overlay->pixels[1];
      for (l = 0; l < (sdlvideosink->height / 2); l++) {
        memcpy (out, u, I420_U_ROWSTRIDE (sdlvideosink->width));
        out += sdlvideosink->overlay->pitches[1];
        u += I420_U_ROWSTRIDE (sdlvideosink->width);
      }

      /* V plane */
      out = sdlvideosink->overlay->pixels[2];
      for (l = 0; l < (sdlvideosink->height / 2); l++) {
        memcpy (out, v, I420_V_ROWSTRIDE (sdlvideosink->width));
        out += sdlvideosink->overlay->pitches[2];
        v += I420_V_ROWSTRIDE (sdlvideosink->width);
      }
    } else {
      guint8 *in = GST_BUFFER_DATA (buf);
      gint in_stride = sdlvideosink->width * 2;

      out = sdlvideosink->overlay->pixels[0];

      for (l = 0; l < sdlvideosink->height; l++) {
        memcpy (out, in, in_stride);
        out += sdlvideosink->overlay->pitches[0];
        in += in_stride;
      }
    }
    gst_sdlvideosink_unlock (sdlvideosink);
  }

  /* Show, baby, show! */
  SDL_DisplayYUVOverlay (sdlvideosink->overlay, &(sdlvideosink->rect));

  /* Handle any resize */
  gst_sdlv_process_events (sdlvideosink);

  g_mutex_unlock (sdlvideosink->lock);

  return GST_FLOW_OK;

  /* ERRORS */
not_init:
  {
    GST_ELEMENT_ERROR (sdlvideosink, CORE, NEGOTIATION, (NULL),
        ("not negotiated."));
    g_mutex_unlock (sdlvideosink->lock);
    return GST_FLOW_NOT_NEGOTIATED;
  }
cannot_lock:
  {
    /* lock function posted detailed message */
    g_mutex_unlock (sdlvideosink->lock);
    return GST_FLOW_ERROR;
  }
}


static void
gst_sdlvideosink_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstSDLVideoSink *sdlvideosink;

  sdlvideosink = GST_SDLVIDEOSINK (object);

  switch (prop_id) {
    case PROP_FULLSCREEN:
      sdlvideosink->full_screen = g_value_get_boolean (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}


static void
gst_sdlvideosink_get_property (GObject * object, guint prop_id, GValue * value,
    GParamSpec * pspec)
{
  GstSDLVideoSink *sdlvideosink;

  sdlvideosink = GST_SDLVIDEOSINK (object);

  switch (prop_id) {
    case PROP_FULLSCREEN:
      g_value_set_boolean (value, sdlvideosink->full_screen);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}


static GstStateChangeReturn
gst_sdlvideosink_change_state (GstElement * element, GstStateChange transition)
{
  GstSDLVideoSink *sdlvideosink;
  GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;

  g_return_val_if_fail (GST_IS_SDLVIDEOSINK (element),
      GST_STATE_CHANGE_FAILURE);
  sdlvideosink = GST_SDLVIDEOSINK (element);

  switch (transition) {
    case GST_STATE_CHANGE_NULL_TO_READY:
      sdlvideosink->is_xwindows = GST_IS_X_OVERLAY (sdlvideosink);
      g_mutex_lock (sdlvideosink->lock);
      if (!gst_sdlvideosink_initsdl (sdlvideosink)) {
        g_mutex_unlock (sdlvideosink->lock);
        goto init_failed;
      }
      GST_OBJECT_FLAG_SET (sdlvideosink, GST_SDLVIDEOSINK_OPEN);
      g_mutex_unlock (sdlvideosink->lock);
      break;
    default:                   /* do nothing */
      break;
  }

  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);

  switch (transition) {
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      sdlvideosink->framerate_n = 0;
      sdlvideosink->framerate_d = 1;
      g_mutex_lock (sdlvideosink->lock);
      gst_sdlvideosink_destroy (sdlvideosink);
      g_mutex_unlock (sdlvideosink->lock);
      break;
    case GST_STATE_CHANGE_READY_TO_NULL:
      g_mutex_lock (sdlvideosink->lock);
      gst_sdlvideosink_deinitsdl (sdlvideosink);
      GST_OBJECT_FLAG_UNSET (sdlvideosink, GST_SDLVIDEOSINK_OPEN);
      g_mutex_unlock (sdlvideosink->lock);
      break;
    default:                   /* do nothing */
      break;
  }
  return ret;

init_failed:
  {
    /* method posted detailed error message */
    GST_DEBUG_OBJECT (sdlvideosink, "init failed");
    return GST_STATE_CHANGE_FAILURE;
  }
}


static void
gst_sdlvideosink_navigation_send_event (GstNavigation * navigation,
    GstStructure * structure)
{
  GstSDLVideoSink *sdlvideosink = GST_SDLVIDEOSINK (navigation);
  GstEvent *event;
  GstVideoRectangle dst = { 0, };
  GstVideoRectangle src = { 0, };
  GstVideoRectangle result;
  double x, y, old_x, old_y;
  GstPad *pad = NULL;

  src.w = GST_VIDEO_SINK_WIDTH (sdlvideosink);
  src.h = GST_VIDEO_SINK_HEIGHT (sdlvideosink);
  dst.w = sdlvideosink->width;
  dst.h = sdlvideosink->height;
  gst_video_sink_center_rect (src, dst, &result, FALSE);

  event = gst_event_new_navigation (structure);

  /* Our coordinates can be wrong here if we centered the video */

  /* Converting pointer coordinates to the non scaled geometry */
  if (gst_structure_get_double (structure, "pointer_x", &old_x)) {
    x = old_x;

    if (x >= result.x && x <= (result.x + result.w)) {
      x -= result.x;
      x *= sdlvideosink->width;
      x /= result.w;
    } else {
      x = 0;
    }
    GST_DEBUG_OBJECT (sdlvideosink, "translated navigation event x "
        "coordinate from %f to %f", old_x, x);
    gst_structure_set (structure, "pointer_x", G_TYPE_DOUBLE, x, NULL);
  }
  if (gst_structure_get_double (structure, "pointer_y", &old_y)) {
    y = old_y;

    if (y >= result.y && y <= (result.y + result.h)) {
      y -= result.y;
      y *= sdlvideosink->height;
      y /= result.h;
    } else {
      y = 0;
    }
    GST_DEBUG_OBJECT (sdlvideosink, "translated navigation event y "
        "coordinate from %f to %f", old_y, y);
    gst_structure_set (structure, "pointer_y", G_TYPE_DOUBLE, y, NULL);
  }

  pad = gst_pad_get_peer (GST_VIDEO_SINK_PAD (sdlvideosink));

  if (GST_IS_PAD (pad) && GST_IS_EVENT (event)) {
    gst_pad_send_event (pad, event);

    gst_object_unref (pad);
  }
}

static void
gst_sdlvideosink_navigation_init (GstNavigationInterface * iface)
{
  iface->send_event = gst_sdlvideosink_navigation_send_event;
}
