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

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

#include "dshowvideosink.h"
#include "dshowvideofakesrc.h"

#include <gst/video/video.h>
#include <gst/video/videooverlay.h>
#include <gst/video/navigation.h>

#include "windows.h"

#define WM_GRAPH_NOTIFY WM_APP + 1 /* Private message */

GST_DEBUG_CATEGORY (dshowvideosink_debug);
#define GST_CAT_DEFAULT dshowvideosink_debug

static GstCaps * gst_directshow_media_type_to_caps (AM_MEDIA_TYPE *mediatype);
static gboolean gst_caps_to_directshow_media_type (GstDshowVideoSink * sink,
  GstCaps *caps, AM_MEDIA_TYPE *mediatype);

/* TODO: Support RGB! */
static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS (
        "video/x-raw,"
        "width = (int) [ 1, MAX ],"
        "height = (int) [ 1, MAX ],"
        "framerate = (fraction) [ 0, MAX ]," 
        "format = {(string)YUY2, (string)UYVY, (string)YV12 }")
    );

static void gst_dshowvideosink_init_interfaces (GType type);

static void gst_dshowvideosink_videooverlay_init (GstVideoOverlayInterface *iface);
static void
gst_dshowvideosink_navigation_interface_init (GstNavigationInterface * iface);

#define gst_dshowvideosink_parent_class parent_class
G_DEFINE_TYPE_WITH_CODE (GstDshowVideoSink, gst_dshowvideosink,
                         GST_TYPE_VIDEO_SINK,
                         G_IMPLEMENT_INTERFACE (GST_TYPE_VIDEO_OVERLAY, gst_dshowvideosink_videooverlay_init);
                         G_IMPLEMENT_INTERFACE (GST_TYPE_NAVIGATION, gst_dshowvideosink_navigation_interface_init))

enum
{
  PROP_0,
  PROP_KEEP_ASPECT_RATIO,
  PROP_FULL_SCREEN,
  PROP_RENDERER
};

/* GObject methods */
static void gst_dshowvideosink_finalize (GObject * gobject);
static void gst_dshowvideosink_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_dshowvideosink_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);

/* GstElement methods */
static GstStateChangeReturn gst_dshowvideosink_change_state (GstElement * element, GstStateChange transition);

/* GstBaseSink methods */
static gboolean gst_dshowvideosink_start (GstBaseSink * bsink);
static gboolean gst_dshowvideosink_stop (GstBaseSink * bsink);
static gboolean gst_dshowvideosink_unlock (GstBaseSink * bsink);
static gboolean gst_dshowvideosink_unlock_stop (GstBaseSink * bsink);
static gboolean gst_dshowvideosink_set_caps (GstBaseSink * bsink, GstCaps * caps);
static GstCaps *gst_dshowvideosink_get_caps (GstBaseSink * bsink, GstCaps * filter);
static GstFlowReturn gst_dshowvideosink_show_frame (GstVideoSink *sink, GstBuffer *buffer);
static void gst_dshowvideosink_set_window_for_renderer (GstDshowVideoSink *sink);

/* COM initialization/uninitialization thread */
static void gst_dshowvideosink_com_thread (GstDshowVideoSink * sink);
/* TODO: event, preroll, buffer_alloc? 
 * buffer_alloc won't generally be all that useful because the renderers require a 
 * different stride to GStreamer's implicit values. 
 */

static void
gst_dshowvideosink_set_window_handle (GstVideoOverlay * overlay, guintptr window_id)

{
  GstDshowVideoSink *sink = GST_DSHOWVIDEOSINK (overlay);
  HWND previous_window = sink->window_id;
  HWND videowindow = (HWND)window_id;

  if (videowindow == sink->window_id) {
    GST_DEBUG_OBJECT (sink, "Window already set");
    return;
  }

  sink->window_id = videowindow;

  /* Update window if we're already playing. */
  if (sink->connected && sink->filter_media_event) {
    HRESULT hres;

    if (sink->is_new_window) {
      /* If we created a new window */
      SendMessage (previous_window, WM_CLOSE, NULL, NULL);
      sink->is_new_window = FALSE;
      sink->window_closed = FALSE;
    } else {
      /* Return control of application window */
      SetWindowLongPtr (previous_window, GWLP_WNDPROC, (LONG_PTR)sink->prevWndProc);
      SetWindowPos (previous_window, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
    }

    gst_dshowvideosink_set_window_for_renderer (sink);

    hres = sink->filter_media_event->SetNotifyWindow ((OAHWND)sink->window_id, WM_GRAPH_NOTIFY, 0);
    GST_DEBUG_OBJECT (sink, "SetNotifyWindow(%p) returned %x", sink->window_id, hres);
  }
}

static void
gst_dshowvideosink_expose (GstVideoOverlay * overlay)
{
  GstDshowVideoSink *sink = GST_DSHOWVIDEOSINK (overlay);

  if (sink->renderersupport) {
    sink->renderersupport->PaintWindow ();
  }
}

static void
gst_dshowvideosink_videooverlay_init (GstVideoOverlayInterface * iface)
{
  iface->set_window_handle = gst_dshowvideosink_set_window_handle;
  iface->expose = gst_dshowvideosink_expose;
}

static void
gst_dshowvideosink_navigation_send_event (GstNavigation * navigation,
    GstStructure * structure)
{
  GstDshowVideoSink *sink = GST_DSHOWVIDEOSINK (navigation);
  GstEvent *event = NULL;
  GstPad *pad = NULL;

  event = gst_event_new_navigation (structure);

  /* FXIME: handle aspect ratio. */

  pad = gst_pad_get_peer (GST_VIDEO_SINK_PAD (sink));

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

    gst_object_unref (pad);
  }
}

static void
gst_dshowvideosink_navigation_interface_init (GstNavigationInterface * iface)
{
  /* FIXME: navigation interface partially implemented.
   * Need to call gst_navigation_send_mouse_event and
   * gst_navigation_send_key_event like in directdrawsink.
   */
  iface->send_event = gst_dshowvideosink_navigation_send_event;
}

static void
gst_dshowvideosink_class_init (GstDshowVideoSinkClass * klass)
{
  GObjectClass *o_class;
  GstElementClass *e_class;
  GstBaseSinkClass *bs_class;
  GstVideoSinkClass *vs_class;

  o_class = (GObjectClass *) klass;
  e_class = (GstElementClass *) klass;
  bs_class = (GstBaseSinkClass *) klass;
  vs_class = (GstVideoSinkClass *) klass;

  o_class->finalize = gst_dshowvideosink_finalize;
  o_class->set_property = gst_dshowvideosink_set_property;
  o_class->get_property = gst_dshowvideosink_get_property;

  gst_element_class_set_static_metadata (e_class, "DirectShow video sink",
      "Sink/Video", "Display data using a DirectShow video renderer",
      "Pioneers of the Inevitable <songbird@songbirdnest.com>, " \
      "FLUENDO S.A. <support@fluendo.com>");

  gst_element_class_add_pad_template (e_class,
      gst_static_pad_template_get (&sink_template));

  e_class->change_state = GST_DEBUG_FUNCPTR (gst_dshowvideosink_change_state);

  bs_class->get_caps = GST_DEBUG_FUNCPTR (gst_dshowvideosink_get_caps);
  bs_class->set_caps = GST_DEBUG_FUNCPTR (gst_dshowvideosink_set_caps);
  bs_class->start = GST_DEBUG_FUNCPTR (gst_dshowvideosink_start);
  bs_class->stop = GST_DEBUG_FUNCPTR (gst_dshowvideosink_stop);
  bs_class->unlock = GST_DEBUG_FUNCPTR (gst_dshowvideosink_unlock);
  bs_class->unlock_stop =
      GST_DEBUG_FUNCPTR (gst_dshowvideosink_unlock_stop);

  vs_class->show_frame = GST_DEBUG_FUNCPTR (gst_dshowvideosink_show_frame);

  /* Add properties */
  g_object_class_install_property (G_OBJECT_CLASS (klass),
      PROP_KEEP_ASPECT_RATIO, g_param_spec_boolean ("force-aspect-ratio",
          "Force aspect ratio",
          "When enabled, scaling will respect original aspect ratio", TRUE,
          (GParamFlags)G_PARAM_READWRITE));
  g_object_class_install_property (G_OBJECT_CLASS (klass),
      PROP_FULL_SCREEN, g_param_spec_boolean ("fullscreen",
          "Full screen mode",
          "Use full-screen mode (not available when using XOverlay)", FALSE,
          (GParamFlags)G_PARAM_READWRITE));

  g_object_class_install_property (G_OBJECT_CLASS (klass),
      PROP_RENDERER, g_param_spec_string ("renderer", "Renderer", 
      "Force usage of specific DirectShow renderer (EVR, VMR9 or VMR7)",
      NULL, (GParamFlags)G_PARAM_READWRITE));
}

static void
gst_dshowvideosink_clear (GstDshowVideoSink *sink)
{
  sink->renderersupport = NULL;
  sink->fakesrc = NULL;
  sink->filter_graph = NULL;
  sink->filter_media_event = NULL;

  sink->keep_aspect_ratio = FALSE;
  sink->full_screen = FALSE;

  sink->window_closed = FALSE;
  sink->window_id = NULL;
  sink->is_new_window = FALSE;

  sink->connected = FALSE;
  sink->graph_running = FALSE;
}

static void
gst_dshowvideosink_init (GstDshowVideoSink * sink)
{
  gst_dshowvideosink_clear (sink);

  g_mutex_init (&sink->graph_lock);
  g_mutex_init (&sink->com_init_lock);
  g_mutex_init (&sink->com_deinit_lock);
  g_cond_init (&sink->com_initialized);
  g_cond_init (&sink->com_uninitialize);
  g_cond_init (&sink->com_uninitialized);

  g_mutex_lock (&sink->com_init_lock);

  /* create the COM initialization thread */
  g_thread_new ("gstdshowvideosinkcomthread", (GThreadFunc)gst_dshowvideosink_com_thread, sink);

  /* wait until the COM thread signals that COM has been initialized */
  g_cond_wait (&sink->com_initialized, &sink->com_init_lock);
  g_mutex_unlock (&sink->com_init_lock);
}

static void
gst_dshowvideosink_finalize (GObject * gobject)
{
  GstDshowVideoSink *sink = GST_DSHOWVIDEOSINK (gobject);

  if (sink->preferredrenderer)
    g_free (sink->preferredrenderer);

  /* signal the COM thread that it sould uninitialize COM */
  if (sink->comInitialized) {
    g_mutex_lock (&sink->com_deinit_lock);
    g_cond_signal (&sink->com_uninitialize);
    g_cond_wait (&sink->com_uninitialized, &sink->com_deinit_lock);
    g_mutex_unlock (&sink->com_deinit_lock);
  }

  g_mutex_clear (&sink->com_init_lock);
  g_mutex_clear (&sink->com_deinit_lock);
  g_cond_clear (&sink->com_initialized);
  g_cond_clear (&sink->com_uninitialize);
  g_cond_clear (&sink->com_uninitialized);

  g_mutex_clear (&sink->graph_lock);

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

static void
gst_dshowvideosink_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstDshowVideoSink *sink = GST_DSHOWVIDEOSINK (object);

  switch (prop_id) {
    case PROP_RENDERER:
      if (sink->preferredrenderer)
        g_free (sink->preferredrenderer);

      sink->preferredrenderer = g_value_dup_string (value);
      break;
    case PROP_KEEP_ASPECT_RATIO:
      sink->keep_aspect_ratio = g_value_get_boolean (value);
      if (sink->renderersupport)
        sink->renderersupport->SetAspectRatioMode();
      break;
    case PROP_FULL_SCREEN:
      sink->full_screen = g_value_get_boolean (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_dshowvideosink_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstDshowVideoSink *sink = GST_DSHOWVIDEOSINK (object);

  switch (prop_id) {
    case PROP_RENDERER:
      g_value_take_string (value, sink->preferredrenderer);
      break;
    case PROP_KEEP_ASPECT_RATIO:
      g_value_set_boolean (value, sink->keep_aspect_ratio);
      break;
    case PROP_FULL_SCREEN:
      g_value_set_boolean (value, sink->full_screen);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_dshowvideosink_com_thread (GstDshowVideoSink * sink)
{
  HRESULT res;

  g_mutex_lock (&sink->com_init_lock);

  /* Initialize COM with a MTA for this process. This thread will
   * be the first one to enter the apartement and the last one to leave
   * it, unitializing COM properly */

  res = CoInitializeEx (0, COINIT_MULTITHREADED);
  if (res == S_FALSE)
    GST_WARNING_OBJECT (sink, "COM has been already initialized in the same process");
  else if (res == RPC_E_CHANGED_MODE)
    GST_WARNING_OBJECT (sink, "The concurrency model of COM has changed.");
  else
    GST_INFO_OBJECT (sink, "COM intialized succesfully");

  sink->comInitialized = TRUE;

  /* Signal other threads waiting on this condition that COM was initialized */
  g_cond_signal (&sink->com_initialized);

  g_mutex_unlock (&sink->com_init_lock);

  /* Wait until the unitialize condition is met to leave the COM apartement */
  g_mutex_lock (&sink->com_deinit_lock);
  g_cond_wait (&sink->com_uninitialize, &sink->com_deinit_lock);

  CoUninitialize ();
  GST_INFO_OBJECT (sink, "COM unintialized succesfully");
  sink->comInitialized = FALSE;
  g_cond_signal (&sink->com_uninitialized);
  g_mutex_unlock (&sink->com_deinit_lock);
}

static GstCaps *
gst_dshowvideosink_get_caps (GstBaseSink * basesink, GstCaps * filter)
{
  GstDshowVideoSink *sink = GST_DSHOWVIDEOSINK (basesink);
  GstCaps *ret = NULL;

  return ret;
}

static void dump_available_media_types (IPin *pin)
{
  /* Enumerate all media types on this pin, output info about them */
  IEnumMediaTypes *enumerator = NULL;
  AM_MEDIA_TYPE *type;
  GstCaps *caps;
  int i = 0;

  GST_INFO ("Enumerating media types on pin %p", pin);

  pin->EnumMediaTypes (&enumerator);

  while (enumerator->Next (1, &type, NULL) == S_OK) {
    i++;
    caps = gst_directshow_media_type_to_caps (type);

    if (caps) {
      gchar *str = gst_caps_to_string (caps);
      GST_INFO ("Type %d: converted to caps \"%s\"", i, str);
      g_free (str);

      gst_caps_unref (caps);
    }
    else
      GST_INFO ("Failed to convert type to GstCaps");

    DeleteMediaType (type);
  }
  GST_INFO ("Enumeration complete");

  enumerator->Release();
}

static void
dump_all_pin_media_types (IBaseFilter *filter)
{
  IEnumPins *enumpins = NULL;
  IPin *pin = NULL;
  HRESULT hres; 

  hres = filter->EnumPins (&enumpins);
  if (FAILED(hres)) {
    GST_WARNING ("Cannot enumerate pins on filter");
    return;
  }

  GST_INFO ("Enumerating pins on filter %p", filter);
  while (enumpins->Next (1, &pin, NULL) == S_OK)
  {
    IMemInputPin *meminputpin;
    PIN_DIRECTION pindir;
    hres = pin->QueryDirection (&pindir);

    GST_INFO ("Found a pin with direction: %s", (pindir == PINDIR_INPUT)? "input": "output");
    dump_available_media_types (pin);

    hres = pin->QueryInterface (
            IID_IMemInputPin, (void **) &meminputpin);
    if (hres == S_OK) {
      GST_INFO ("Pin is a MemInputPin (push mode): %p", meminputpin);
      meminputpin->Release();
    }
    else
      GST_INFO ("Pin is not a MemInputPin (pull mode?): %p", pin);

    pin->Release();
  }
  enumpins->Release();
}

gboolean 
gst_dshow_get_pin_from_filter (IBaseFilter *filter, PIN_DIRECTION pindir, IPin **pin)
{
  gboolean ret = FALSE;
  IEnumPins *enumpins = NULL;
  IPin *pintmp = NULL;
  HRESULT hres; 
  *pin = NULL;

  hres = filter->EnumPins (&enumpins);
  if (FAILED(hres)) {
    return ret;
  }

  while (enumpins->Next (1, &pintmp, NULL) == S_OK)
  {
    PIN_DIRECTION pindirtmp;
    hres = pintmp->QueryDirection (&pindirtmp);
    if (hres == S_OK && pindir == pindirtmp) {
      *pin = pintmp;
      ret = TRUE;
      break;
    }
    pintmp->Release ();
  }
  enumpins->Release ();

  return ret;
}

static void 
gst_dshowvideosink_handle_event (GstDshowVideoSink *sink)
{
  if (sink->filter_media_event) {
    long evCode;
    LONG_PTR param1, param2;
    while (SUCCEEDED (sink->filter_media_event->GetEvent(&evCode, &param1, &param2, 0)))
    {
      GST_INFO_OBJECT (sink, "Received DirectShow graph event code 0x%x", evCode);
      sink->filter_media_event->FreeEventParams(evCode, param1, param2);
    }
  }
}

/* WNDPROC for application-supplied windows */
LRESULT APIENTRY WndProcHook (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
  /* Handle certain actions specially on the window passed to us.
   * Then forward back to the original window.
   */
  GstDshowVideoSink *sink = (GstDshowVideoSink *)GetProp (hWnd, (LPCSTR)"GstDShowVideoSink");
  g_assert (sink != NULL);

  switch (message) {
    case WM_GRAPH_NOTIFY:
      gst_dshowvideosink_handle_event (sink);
      return 0;
    case WM_PAINT:
      sink->renderersupport->PaintWindow ();
      break;
    case WM_MOVE:
    case WM_SIZE:
      sink->renderersupport->MoveWindow ();
      break;
    case WM_DISPLAYCHANGE:
      sink->renderersupport->DisplayModeChanged();
      break;
    case WM_ERASEBKGND:
      /* DirectShow docs recommend ignoring this message to avoid flicker */
      return TRUE;
    case WM_CLOSE:
      sink->window_closed = TRUE;
  }
  return CallWindowProc (sink->prevWndProc, hWnd, message, wParam, lParam);
}

/* WndProc for our default window, if the application didn't supply one */
LRESULT APIENTRY 
WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
  GstDshowVideoSink *sink = (GstDshowVideoSink *)GetWindowLongPtr (hWnd, GWLP_USERDATA);

  if (!sink) {
    /* I think these happen before we have a chance to set our userdata pointer */
    GST_DEBUG ("No sink!");
    return DefWindowProc (hWnd, message, wParam, lParam);
  }

  //GST_DEBUG_OBJECT (sink, "Got a window message for %x, %x", hWnd, message);

  switch (message) {
    case WM_GRAPH_NOTIFY:
      GST_LOG_OBJECT (sink, "GRAPH_NOTIFY WINDOW MESSAGE");
      gst_dshowvideosink_handle_event (sink);
      return 0;
    case WM_PAINT:
      sink->renderersupport->PaintWindow ();
      break;
    case WM_MOVE:
    case WM_SIZE:
      sink->renderersupport->MoveWindow ();
      break;
    case WM_DISPLAYCHANGE:
      sink->renderersupport->DisplayModeChanged();
      break;
    case WM_ERASEBKGND:
      /* DirectShow docs recommend ignoring this message */
      return TRUE;
    case WM_CLOSE:
      sink->renderersupport->DestroyWindow ();
      sink->window_closed = TRUE;
      PostQuitMessage (WM_QUIT);
      return 0;
  }

  return DefWindowProc (hWnd, message, wParam, lParam);
}

static gpointer
gst_dshowvideosink_window_thread (GstDshowVideoSink * sink)
{
  WNDCLASS WndClass;
  int width, height;
  int offx, offy;
  DWORD exstyle, style;

  memset (&WndClass, 0, sizeof (WNDCLASS));
  WndClass.style = CS_HREDRAW | CS_VREDRAW;
  WndClass.hInstance = GetModuleHandle (NULL);
  WndClass.lpszClassName = (LPCSTR)"GST-DShowSink";
  WndClass.hbrBackground = (HBRUSH) GetStockObject (BLACK_BRUSH);
  WndClass.cbClsExtra = 0;
  WndClass.cbWndExtra = 0;
  WndClass.lpfnWndProc = WndProc;
  WndClass.hCursor = LoadCursor (NULL, IDC_ARROW);
  RegisterClass (&WndClass);

  if (sink->full_screen) {
    /* This doesn't seem to work, it returns the wrong values! But when we
     * later use ShowWindow to show it maximized, it goes to full-screen
     * anyway. TODO: Figure out why. */
    width = GetSystemMetrics (SM_CXFULLSCREEN);
    height = GetSystemMetrics (SM_CYFULLSCREEN);
    offx = 0;
    offy = 0;

    style = WS_POPUP; /* No window decorations */
    exstyle = 0;
  }
  else {
    /* By default, create a normal top-level window, the size 
     * of the video.
     */
    RECT rect;
    AM_MEDIA_TYPE pmt = (AM_MEDIA_TYPE)sink->mediatype;
    VIDEOINFOHEADER *vi = (VIDEOINFOHEADER *)pmt.pbFormat;

    if (vi == NULL)
    {
        GST_ELEMENT_ERROR (sink, RESOURCE, NOT_FOUND, ("Unknown media format"), (NULL));
        return NULL;
    }

    /* rcTarget is the aspect-ratio-corrected size of the video. */
    width = vi->rcTarget.right + GetSystemMetrics (SM_CXSIZEFRAME) * 2;
    height = vi->rcTarget.bottom + GetSystemMetrics (SM_CYCAPTION) +
        (GetSystemMetrics (SM_CYSIZEFRAME) * 2);

    SystemParametersInfo (SPI_GETWORKAREA, NULL, &rect, 0);
    int screenwidth = rect.right - rect.left;
    int screenheight = rect.bottom - rect.top;
    offx = rect.left;
    offy = rect.top;

    /* Make it fit into the screen without changing the
     * aspect ratio. */
    if (width > screenwidth) {
      double ratio = (double)screenwidth/(double)width;
      width = screenwidth;
      height = (int)(height * ratio);
    }
    if (height > screenheight) {
      double ratio = (double)screenheight/(double)height;
      height = screenheight;
      width = (int)(width * ratio);
    }

    style = WS_OVERLAPPEDWINDOW; /* Normal top-level window */
    exstyle = 0;
  }

  HWND video_window = CreateWindowEx (exstyle, (LPCSTR)"GST-DShowSink",
      (LPCSTR)"GStreamer DirectShow sink default window",
      style, offx, offy, width, height, NULL, NULL,
      WndClass.hInstance, NULL);
  if (video_window == NULL) {
    GST_ERROR_OBJECT (sink, "Failed to create window!");
    return NULL;
  }

  sink->is_new_window = TRUE;

  SetWindowLongPtr (video_window, GWLP_USERDATA, (LONG_PTR)sink);

  sink->window_id = video_window;

  /* signal application we created a window */
  gst_video_overlay_got_window_handle (GST_VIDEO_OVERLAY (sink),
      (gulong)video_window);

  /* Set the renderer's clipping window */
  if (!sink->renderersupport->SetRendererWindow (video_window)) {
    GST_WARNING_OBJECT (sink, "Failed to set video clipping window on filter %p", sink->renderersupport);
  }

  /* Now show the window, as appropriate */
  if (sink->full_screen) {
    ShowWindow (video_window, SW_SHOWMAXIMIZED);
    ShowCursor (FALSE);
  }
  else
    ShowWindow (video_window, SW_SHOWNORMAL);

  /* Trigger the initial paint of the window */
  UpdateWindow (video_window);

  ReleaseSemaphore (sink->window_created_signal, 1, NULL);

  /* start message loop processing our default window messages */
  while (1) {
    MSG msg;

    if (GetMessage (&msg, video_window, 0, 0) <= 0) {
      GST_LOG_OBJECT (sink, "our window received WM_QUIT or error.");
      break;
    }
    DispatchMessage (&msg);
  }

  return NULL;
}

static gboolean
gst_dshowvideosink_create_default_window (GstDshowVideoSink * sink)
{
  sink->window_created_signal = CreateSemaphore (NULL, 0, 1, NULL);
  if (sink->window_created_signal == NULL)
    goto failed;

  sink -> window_thread = g_thread_new ("windowthread",
                                        (GThreadFunc) gst_dshowvideosink_window_thread,
                                        sink);

  /* wait maximum 10 seconds for window to be created */
  if (WaitForSingleObject (sink->window_created_signal,
          10000) != WAIT_OBJECT_0)
    goto failed;

  CloseHandle (sink->window_created_signal);
  return TRUE;

failed:
  CloseHandle (sink->window_created_signal);
  GST_ELEMENT_ERROR (sink, RESOURCE, WRITE,
      ("Error creating our default window"), (NULL));

  return FALSE;
}

static void gst_dshowvideosink_set_window_for_renderer (GstDshowVideoSink *sink)
{
  WNDPROC prevWndProc = (WNDPROC)GetWindowLongPtr (sink->window_id, GWLP_WNDPROC);
  if (prevWndProc == WndProcHook) {
    /* The WndProc already points to our hook. Something has gone wrong
     * somewhere else and this safety net prevents an infinite recursion */
    return;
  }

  /* Application has requested a specific window ID */
  sink->prevWndProc = (WNDPROC) SetWindowLongPtr (sink->window_id, GWLP_WNDPROC, (LONG_PTR)WndProcHook);
  GST_DEBUG_OBJECT (sink, "Set wndproc to %p from %p", WndProcHook, sink->prevWndProc);
  SetProp (sink->window_id, (LPCSTR)"GstDShowVideoSink", sink);
  /* This causes the new WNDPROC to become active */
  SetWindowPos (sink->window_id, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);

  if (!sink->renderersupport->SetRendererWindow (sink->window_id)) {
    GST_WARNING_OBJECT (sink, "Failed to set HWND %x on renderer", sink->window_id);
    return;
  }
  sink->is_new_window = FALSE;

  /* This tells the renderer where the window is located, needed to 
   * start drawing in the right place.  */
  sink->renderersupport->MoveWindow();
  GST_INFO_OBJECT (sink, "Set renderer window to %x", sink->window_id);
}

static void
gst_dshowvideosink_prepare_window (GstDshowVideoSink *sink)
{
  HRESULT hres;

  /* Give the app a last chance to supply a window id */
  if (!sink->window_id) {
    gst_video_overlay_prepare_window_handle (GST_VIDEO_OVERLAY (sink));
  }

  /* If the app supplied one, use it. Otherwise, go ahead
   * and create (and use) our own window */
  if (sink->window_id) {
    gst_dshowvideosink_set_window_for_renderer (sink);
  }
  else {
    gst_dshowvideosink_create_default_window (sink);
  }

  if (sink->filter_media_event) {
    sink->filter_media_event->Release();
    sink->filter_media_event = NULL;
  }

  hres = sink->filter_graph->QueryInterface(
          IID_IMediaEventEx, (void **) &sink->filter_media_event);

  if (FAILED (hres)) {
    GST_WARNING_OBJECT (sink, "Failed to get IMediaEventEx");
  }
  else {
    hres = sink->filter_media_event->SetNotifyWindow ((OAHWND)sink->window_id,
            WM_GRAPH_NOTIFY, 0);
    GST_DEBUG_OBJECT (sink, "SetNotifyWindow(%p) returned %x", sink->window_id, hres);
  }
}

static gboolean
gst_dshowvideosink_connect_graph (GstDshowVideoSink *sink)
{
  HRESULT hres;
  IPin *srcpin;
  IPin *sinkpin;

  GST_INFO_OBJECT (sink, "Connecting DirectShow pins");

  srcpin = sink->fakesrc->GetOutputPin();

  gst_dshow_get_pin_from_filter (sink->renderersupport->GetFilter(), PINDIR_INPUT, 
      &sinkpin);
  if (!sinkpin) {
    GST_WARNING_OBJECT (sink, "Cannot get input pin from Renderer");
    return FALSE;
  }

  /* Be warned that this call WILL deadlock unless you call it from
   * the main thread. Thus, we call this from the state change, not from
   * setcaps (which happens in a streaming thread).
   */
  hres = sink->filter_graph->ConnectDirect (
           srcpin, sinkpin, NULL);
  if (FAILED (hres)) {
    GST_WARNING_OBJECT (sink, "Could not connect pins: %x", hres);
    sinkpin->Release();
    return FALSE;
  }
  sinkpin->Release();
  return TRUE;
}

static GstStateChangeReturn
gst_dshowvideosink_start_graph (GstDshowVideoSink *sink)
{
  IMediaControl *control = NULL;
  HRESULT hres;
  GstStateChangeReturn ret;

  GST_DEBUG_OBJECT (sink, "Connecting and starting DirectShow graph");

  hres = sink->filter_graph->QueryInterface(
          IID_IMediaControl, (void **) &control);

  if (FAILED (hres)) {
    GST_WARNING_OBJECT (sink, "Failed to get IMediaControl interface");
    ret = GST_STATE_CHANGE_FAILURE;
    goto done;
  }

  GST_INFO_OBJECT (sink, "Running DirectShow graph");
  hres = control->Run();
  if (FAILED (hres)) {
    GST_ERROR_OBJECT (sink,
        "Failed to run the directshow graph (error=%x)", hres);
    ret = GST_STATE_CHANGE_FAILURE;
    goto done;
  }
  
  GST_DEBUG_OBJECT (sink, "DirectShow graph is now running");
  ret = GST_STATE_CHANGE_SUCCESS;

done:
  if (control)
    control->Release();

  return ret;
}
static GstStateChangeReturn
gst_dshowvideosink_pause_graph (GstDshowVideoSink *sink)
{
  IMediaControl *control = NULL;
  GstStateChangeReturn ret;
  HRESULT hres;

  hres = sink->filter_graph->QueryInterface(
          IID_IMediaControl, (void **) &control);
  if (FAILED (hres)) {
    GST_WARNING_OBJECT (sink, "Failed to get IMediaControl interface");
    ret = GST_STATE_CHANGE_FAILURE;
    goto done;
  }

  GST_INFO_OBJECT (sink, "Pausing DirectShow graph");
  hres = control->Pause();
  if (FAILED (hres)) {
    GST_WARNING_OBJECT (sink,
        "Can't pause the directshow graph (error=%x)", hres);
    ret = GST_STATE_CHANGE_FAILURE;
    goto done;
  }

  ret = GST_STATE_CHANGE_SUCCESS;

done:
  if (control)
    control->Release();

  return ret;
}

static GstStateChangeReturn
gst_dshowvideosink_stop_graph (GstDshowVideoSink *sink)
{
  IMediaControl *control = NULL;
  GstStateChangeReturn ret;
  HRESULT hres;
  IPin *sinkpin;

  hres = sink->filter_graph->QueryInterface(
          IID_IMediaControl, (void **) &control);
  if (FAILED (hres)) {
    GST_WARNING_OBJECT (sink, "Failed to get IMediaControl interface");
    ret = GST_STATE_CHANGE_FAILURE;
    goto done;
  }

  GST_INFO_OBJECT (sink, "Stopping DirectShow graph");
  hres = control->Stop();
  if (FAILED (hres)) {
    GST_WARNING_OBJECT (sink,
        "Can't stop the directshow graph (error=%x)", hres);
    ret = GST_STATE_CHANGE_FAILURE;
    goto done;
  }

  sink->filter_graph->Disconnect(sink->fakesrc->GetOutputPin());

  gst_dshow_get_pin_from_filter (sink->renderersupport->GetFilter(), PINDIR_INPUT, 
      &sinkpin);
  sink->filter_graph->Disconnect(sinkpin);
  sinkpin->Release();

  GST_DEBUG_OBJECT (sink, "DirectShow graph has stopped");

  if (sink->window_id) {
    /* Return control of application window */
    SetWindowLongPtr (sink->window_id, GWLP_WNDPROC, (LONG_PTR)sink->prevWndProc);
    RemoveProp (sink->window_id, (LPCSTR)"GstDShowVideoSink");
    SetWindowPos (sink->window_id, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
    sink->prevWndProc = NULL;
  }
  sink->connected = FALSE;

  ret = GST_STATE_CHANGE_SUCCESS;

done:
  if (control)
    control->Release();

  return ret;
}

static GstStateChangeReturn
gst_dshowvideosink_change_state (GstElement * element, GstStateChange transition)
{
  GstDshowVideoSink *sink = GST_DSHOWVIDEOSINK (element);
  GstStateChangeReturn ret, rettmp;

  switch (transition) {
    case GST_STATE_CHANGE_NULL_TO_READY:
      break;
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      break;
    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
      ret = gst_dshowvideosink_start_graph (sink);
      if (ret == GST_STATE_CHANGE_FAILURE)
        return ret;
      sink->graph_running = TRUE;
      break;
  }

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

  switch (transition) {
    case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
      GST_DSHOWVIDEOSINK_GRAPH_LOCK(sink);
      rettmp = gst_dshowvideosink_pause_graph (sink);
      if (rettmp == GST_STATE_CHANGE_FAILURE)
        ret = rettmp;
      sink->graph_running = FALSE;
      GST_DSHOWVIDEOSINK_GRAPH_UNLOCK(sink);
      break;
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      GST_DSHOWVIDEOSINK_GRAPH_LOCK(sink);
      rettmp = gst_dshowvideosink_stop_graph (sink);
      if (rettmp == GST_STATE_CHANGE_FAILURE)
        ret = rettmp;
      sink->graph_running = FALSE;
      GST_DSHOWVIDEOSINK_GRAPH_UNLOCK(sink);
      break;
    case GST_STATE_CHANGE_READY_TO_NULL:
      gst_dshowvideosink_clear (sink);
      break;
  }

  return ret;
}

class EVRSupport : public RendererSupport
{
private:
  GstDshowVideoSink *sink;
  IBaseFilter *filter;
  IMFGetService *service;
  IMFVideoDisplayControl *control;
  HWND video_window;

public:
  EVRSupport (GstDshowVideoSink *sink) : 
      sink(sink),
      filter(NULL),
      service(NULL),
      control(NULL)
  {
  }

  ~EVRSupport() {
    if (control)
      control->Release();
    if (service)
      service->Release();
    if (filter)
      filter->Release();
  }

  const char *GetName() {
    return "EnhancedVideoRenderer";
  }

  IBaseFilter *GetFilter() {
    return filter;
  }

  gboolean CheckOS () {
    OSVERSIONINFO info;
    info.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
    GetVersionEx (&info);

    if (info.dwMajorVersion < 6) {
      return false;
    }
    else {
      return true;
    }
  }

  gboolean Configure() {
    HRESULT hres;

    if (!this->CheckOS ()) {
      GST_DEBUG_OBJECT (sink, "Windows Vista is required at least for EVR to work");
      return FALSE;
    }

    hres = CoCreateInstance (CLSID_EnhancedVideoRenderer, NULL, CLSCTX_INPROC,
        IID_IBaseFilter, (LPVOID *) &filter);
    GST_DEBUG_OBJECT (sink, "cocreateinstance returned %d", hres);
    if (FAILED (hres)) {
      GST_ERROR_OBJECT (sink, 
          "Can't create an instance of renderer (error=%x)",
          hres);
      return FALSE;
    }

    hres = filter->QueryInterface (IID_IMFGetService,
          (void **) &service);
    if (FAILED (hres)) {
      GST_WARNING_OBJECT (sink, "EVR service interface missing: %x", hres);
      return FALSE;
    }

    hres = service->GetService (MR_VIDEO_RENDER_SERVICE, 
          IID_IMFVideoDisplayControl, (void **) &control);
    if (FAILED (hres)) {
      GST_WARNING_OBJECT (sink, "EVR control service missing: %x", hres);
      return FALSE;
    }

    SetAspectRatioMode();
    return TRUE;
  }

  void SetAspectRatioMode() {
    if (sink->keep_aspect_ratio) {
      control->SetAspectRatioMode(MFVideoARMode_PreservePicture);
    }
    else {
      control->SetAspectRatioMode(MFVideoARMode_None);
    }
  }

  gboolean SetRendererWindow(HWND window) {
    video_window = window;
    HRESULT hres = control->SetVideoWindow (video_window);
    if (FAILED (hres)) {
      GST_WARNING_OBJECT (sink, "Failed to set video clipping window on filter %p: %x", filter, hres);
      return FALSE;
    }
    return TRUE;
  }

  void PaintWindow()
  {
    HRESULT hr;
    PAINTSTRUCT ps;
    HDC         hdc;
    RECT        rcClient;

    GetClientRect(video_window, &rcClient);
    hdc = BeginPaint(video_window, &ps);

    hr = control->RepaintVideo();

    EndPaint(video_window, &ps);
  }

  void MoveWindow()
  {
    HRESULT hr;
    RECT rect;

    // Track the movement of the container window and resize as needed
    GetClientRect(video_window, &rect);
    hr = control->SetVideoPosition(NULL, &rect);
  }

  void DisplayModeChanged() {
  }

  void DestroyWindow() {
    ::DestroyWindow (video_window);
  }
};

class VMR9Support : public RendererSupport
{
private:
  GstDshowVideoSink *sink;
  IBaseFilter *filter;
  IVMRWindowlessControl9 *control;
  IVMRFilterConfig9 *config;
  HWND video_window;

public:
  VMR9Support (GstDshowVideoSink *sink) : 
      sink(sink), 
      filter(NULL),
      control(NULL),
      config(NULL)
  {
  }

  ~VMR9Support() {
    if (control)
      control->Release();
    if (config)
      config->Release();
    if (filter)
      filter->Release();
  }

  const char *GetName() {
    return "VideoMixingRenderer9";
  }

  IBaseFilter *GetFilter() {
    return filter;
  }

  gboolean Configure() {
    HRESULT hres;

    hres = CoCreateInstance (CLSID_VideoMixingRenderer9, NULL, CLSCTX_INPROC,
        IID_IBaseFilter, (LPVOID *) &filter);
    if (FAILED (hres)) {
      GST_ERROR_OBJECT (sink, 
          "Can't create an instance of renderer (error=%x)",
          hres);
      return FALSE;
    }

    hres = filter->QueryInterface (
          IID_IVMRFilterConfig9, (void **) &config);
    if (FAILED (hres)) {
      GST_WARNING_OBJECT (sink, "VMR9 filter config interface missing: %x", hres);
      return FALSE;
    }

    hres = config->SetRenderingMode (VMR9Mode_Windowless);
    if (FAILED (hres)) {
      GST_WARNING_OBJECT (sink, "VMR9 couldn't be set to windowless mode: %x", hres);
      return FALSE;
    }
    else {
      GST_DEBUG_OBJECT (sink, "Set VMR9 (%p) to windowless mode!", filter);
    }

    /* We can't QI to this until _after_ we've been set to windowless mode. 
     * Apparently this is against the rules in COM, but that's how it is... */
    hres = filter->QueryInterface (
          IID_IVMRWindowlessControl9, (void **) &control);
    if (FAILED (hres)) {
      GST_WARNING_OBJECT (sink, "VMR9 windowless control interface missing: %x", hres);
      return FALSE;
    }

    SetAspectRatioMode();
    return TRUE;
  }

  void SetAspectRatioMode() {
    if (sink->keep_aspect_ratio) {
      control->SetAspectRatioMode(VMR9ARMode_LetterBox);
    }
    else {
      control->SetAspectRatioMode(VMR9ARMode_None);
    }
  }

  gboolean SetRendererWindow(HWND window) {
    video_window = window;
    HRESULT hres = control->SetVideoClippingWindow (video_window);
    if (FAILED (hres)) {
      GST_WARNING_OBJECT (sink, "Failed to set video clipping window on filter %p: %x", filter, hres);
      return FALSE;
    }
    return TRUE;
  }

  void PaintWindow()
  {
    HRESULT hr;
    PAINTSTRUCT ps;
    HDC         hdc;
    RECT        rcClient;

    GetClientRect(video_window, &rcClient);
    hdc = BeginPaint(video_window, &ps);

    hr = control->RepaintVideo(video_window, hdc);

    EndPaint(video_window, &ps);
  }

  void MoveWindow()
  {
    HRESULT hr;
    RECT rect;

    // Track the movement of the container window and resize as needed
    GetClientRect(video_window, &rect);
    hr = control->SetVideoPosition(NULL, &rect);
  }

  void DisplayModeChanged() {
    control->DisplayModeChanged();
  }

  void DestroyWindow() {
    ::DestroyWindow (video_window);
  }
};

class VMR7Support : public RendererSupport
{
private:
  GstDshowVideoSink *sink;
  IBaseFilter *filter;
  IVMRWindowlessControl *control;
  IVMRFilterConfig *config;
  HWND video_window;

public:
  VMR7Support (GstDshowVideoSink *sink) : 
      sink(sink), 
      filter(NULL),
      control(NULL),
      config(NULL)
  {
  }

  ~VMR7Support() {
    if (control)
      control->Release();
    if (config)
      config->Release();
    if (filter)
      filter->Release();
  }

  const char *GetName() {
    return "VideoMixingRenderer";
  }

  IBaseFilter *GetFilter() {
    return filter;
  }

  gboolean Configure() {
    HRESULT hres;

    hres = CoCreateInstance (CLSID_VideoMixingRenderer, NULL, CLSCTX_INPROC,
        IID_IBaseFilter, (LPVOID *) &filter);
    if (FAILED (hres)) {
      GST_ERROR_OBJECT (sink, 
          "Can't create an instance of renderer (error=%x)",
          hres);
      return FALSE;
    }

    hres = filter->QueryInterface (
          IID_IVMRFilterConfig, (void **) &config);
    if (FAILED (hres)) {
      GST_WARNING_OBJECT (sink, "VMR filter config interface missing: %x", hres);
      return FALSE;
    }

    hres = config->SetRenderingMode (VMRMode_Windowless);
    if (FAILED (hres)) {
      GST_WARNING_OBJECT (sink, "VMR couldn't be set to windowless mode: %x", hres);
      return FALSE;
    }
    else {
      GST_DEBUG_OBJECT (sink, "Set VMR (%p) to windowless mode!", filter);
    }

    hres = filter->QueryInterface (
          IID_IVMRWindowlessControl, (void **) &control);
    if (FAILED (hres)) {
      GST_WARNING_OBJECT (sink, "VMR windowless control interface missing: %x", hres);
      return FALSE;
    }

    SetAspectRatioMode();
    return TRUE;
  }

  void SetAspectRatioMode() {
    if (sink->keep_aspect_ratio) {
      control->SetAspectRatioMode(VMR_ARMODE_LETTER_BOX);
    }
    else {
      control->SetAspectRatioMode(VMR_ARMODE_NONE);
    }
  }

  gboolean SetRendererWindow(HWND window) {
    video_window = window;
    HRESULT hres = control->SetVideoClippingWindow (video_window);
    if (FAILED (hres)) {
      GST_WARNING_OBJECT (sink, "Failed to set video clipping window on filter %p: %x", filter, hres);
      return FALSE;
    }
    return TRUE;
  }

  void PaintWindow()
  {
    HRESULT hr;
    PAINTSTRUCT ps;
    HDC         hdc;
    RECT        rcClient;

    GetClientRect(video_window, &rcClient);
    hdc = BeginPaint(video_window, &ps);

    hr = control->RepaintVideo(video_window, hdc);

    EndPaint(video_window, &ps);
  }

  void MoveWindow()
  {
    HRESULT hr;
    RECT rect;

    // Track the movement of the container window and resize as needed
    GetClientRect(video_window, &rect);
    hr = control->SetVideoPosition(NULL, &rect);
  }

  void DisplayModeChanged() {
    control->DisplayModeChanged();
  }

  void DestroyWindow() {
    ::DestroyWindow (video_window);
  }
};

static gboolean 
gst_dshowvideosink_create_renderer (GstDshowVideoSink *sink) 
{
  GST_DEBUG_OBJECT (sink, "Trying to create renderer '%s'", "EVR");

  RendererSupport *support = NULL;

  if (sink->preferredrenderer) {
    if (!strcmp (sink->preferredrenderer, "EVR")) {
      GST_INFO_OBJECT (sink, "Forcing use of EVR");
      support = new EVRSupport (sink);
    }
    else if (!strcmp (sink->preferredrenderer, "VMR9")) {
      GST_INFO_OBJECT (sink, "Forcing use of VMR9");
      support = new VMR9Support (sink);
    }
    else if (!strcmp (sink->preferredrenderer, "VMR")) {
      GST_INFO_OBJECT (sink, "Forcing use of VMR");
      support = new VMR7Support (sink);
    }
    else {
      GST_ERROR_OBJECT (sink, "Unknown sink type '%s'", sink->preferredrenderer);
      return FALSE;
    }

    if (!support->Configure()) {
      GST_ERROR_OBJECT (sink, "Couldn't configure selected renderer");
      delete support;
      return FALSE;
    }
    goto done;
  }

  support = new EVRSupport (sink);
  if (!support->Configure ()) {
    GST_INFO_OBJECT (sink, "Failed to configure EVR, trying VMR9");
    delete support;
    support = new VMR9Support (sink);
    if (!support->Configure()) {
      GST_INFO_OBJECT (sink, "Failed to configure VMR9, trying VMR7");
      delete support;
      support = new VMR7Support (sink);
      if (!support->Configure()) {
        GST_ERROR_OBJECT (sink, "Failed to configure VMR9 or VMR7");
        delete support;
        return FALSE;
      }
    }
  }

done:
  sink->renderersupport = support;
  return TRUE;
}

static gboolean
gst_dshowvideosink_build_filtergraph (GstDshowVideoSink *sink)
{
  HRESULT hres;

  /* Build our DirectShow FilterGraph, looking like: 
   *
   *    [ fakesrc ] -> [ sink filter ]
   *
   * so we can feed data in through the fakesrc.
   *
   * The sink filter can be one of our supported filters: VMR9 (VMR7?, EMR?)
   */

  hres = CoCreateInstance (CLSID_FilterGraph, NULL, CLSCTX_INPROC,
      IID_IFilterGraph, (LPVOID *) & sink->filter_graph);
  if (FAILED (hres)) {
    GST_ERROR_OBJECT (sink, 
          "Can't create an instance of the dshow graph manager (error=%x)", hres);
    goto error;
  }

  sink->fakesrc = new VideoFakeSrc();

  IBaseFilter *filter;
  hres = sink->fakesrc->QueryInterface (
          IID_IBaseFilter, (void **) &filter);
  if (FAILED (hres)) {
    GST_ERROR_OBJECT (sink, "Could not QI fakesrc to IBaseFilter");
    goto error;
  }

  hres = sink->filter_graph->AddFilter (filter, L"fakesrc");
  if (FAILED (hres)) {
    GST_ERROR_OBJECT (sink,
        "Can't add our fakesrc filter to the graph (error=%x)", hres);
    goto error;
  }

  if (!gst_dshowvideosink_create_renderer (sink)) {
    GST_ERROR_OBJECT (sink, "Could not create a video renderer");
    goto error;
  }

  /* dump_all_pin_media_types (sink->renderer); */

  hres =
      sink->filter_graph->AddFilter (sink->renderersupport->GetFilter(),
      L"renderer");
  if (FAILED (hres)) {
    GST_ERROR_OBJECT (sink, 
          "Can't add renderer to the graph (error=%x)", hres);
    goto error;
  }

  return TRUE;

error:
  if (sink->fakesrc) {
    sink->fakesrc->Release();
    sink->fakesrc = NULL;
  }

  if (sink->filter_graph) {
    sink->filter_graph->Release();
    sink->filter_graph = NULL;
  }

  if (sink->filter_media_event) {
    sink->filter_media_event->Release();
    sink->filter_media_event = NULL;
  }

  return FALSE;
}

static gboolean
gst_dshowvideosink_start (GstBaseSink * bsink)
{
  HRESULT hres = S_FALSE;
  GstDshowVideoSink *sink = GST_DSHOWVIDEOSINK (bsink);

  /* Just build the filtergraph; we don't link or otherwise configure it yet */
  return gst_dshowvideosink_build_filtergraph (sink);
}

static gboolean
gst_dshowvideosink_set_caps (GstBaseSink * bsink, GstCaps * caps)
{
  GstDshowVideoSink *sink = GST_DSHOWVIDEOSINK (bsink);

  if (sink->connected) {
      IPin *sinkpin;
      sink->filter_graph->Disconnect(sink->fakesrc->GetOutputPin());
      gst_dshow_get_pin_from_filter (sink->renderersupport->GetFilter(), PINDIR_INPUT, 
          &sinkpin);
      sink->filter_graph->Disconnect(sinkpin);
      sinkpin->Release();
  }

  if (!gst_caps_to_directshow_media_type (sink, caps, &sink->mediatype)) {
    GST_WARNING_OBJECT (sink, "Cannot convert caps to AM_MEDIA_TYPE, rejecting");
    return FALSE;
  }

  GST_DEBUG_OBJECT (sink, "Configuring output pin media type");
  /* Now we have an AM_MEDIA_TYPE describing what we're going to send.
   * We set this on our DirectShow fakesrc's output pin. 
   */
  sink->fakesrc->GetOutputPin()->SetMediaType (&sink->mediatype);
  GST_DEBUG_OBJECT (sink, "Configured output pin media type");

  /* We have configured the ouput pin media type.
  * So, create a window (or start using an application-supplied
  * one, then connect the graph */
  gst_dshowvideosink_prepare_window (sink);
  if (!gst_dshowvideosink_connect_graph (sink)) {
    GST_ELEMENT_ERROR (sink, CORE, NEGOTIATION,
          ("Failed to initialize DirectShow graph with the input caps"), (NULL));
    return FALSE;
  }
  sink->connected = TRUE;

  return TRUE;
}

static gboolean
gst_dshowvideosink_stop (GstBaseSink * bsink)
{
  IPin *input_pin = NULL, *output_pin = NULL;
  HRESULT hres = S_FALSE;
  GstDshowVideoSink *sink = GST_DSHOWVIDEOSINK (bsink);

  if (!sink->filter_graph) {
    GST_WARNING_OBJECT (sink, "Cannot destroy filter graph; it doesn't exist");
    return TRUE;
  }
  
  /* If we created a new window, send the close message and wait until 
   * it's closed in the window thread */
  if (sink->is_new_window) {
    SendMessage (sink->window_id, WM_CLOSE, NULL, NULL);
    while (!sink->window_closed);
    sink->is_new_window = FALSE;
  }

  /* Release the renderer */
  if (sink->renderersupport) {
    delete sink->renderersupport;
    sink->renderersupport = NULL;
  }

  /* Release our dshow fakesrc */
  if (sink->fakesrc) {
    sink->fakesrc->Release();
    sink->fakesrc = NULL;
  }

  /* Release the filter graph manager */
  if (sink->filter_graph) {
    sink->filter_graph->Release();
    sink->filter_graph = NULL;
  }

  if (sink->filter_media_event) {
    sink->filter_media_event->Release();
    sink->filter_media_event = NULL;
  }

  return TRUE;
}

static GstFlowReturn
gst_dshowvideosink_show_frame (GstVideoSink *vsink, GstBuffer *buffer)
{
  GstDshowVideoSink *sink = GST_DSHOWVIDEOSINK (vsink);
  GstFlowReturn ret;
  GstStateChangeReturn retst;

  if (sink->window_closed) {
    GST_ELEMENT_ERROR (sink, RESOURCE, NOT_FOUND, ("Output window was closed"), (NULL));
    return GST_FLOW_ERROR;
  }

  GST_DEBUG_OBJECT (sink, "Pushing buffer through fakesrc->renderer");
  GST_DSHOWVIDEOSINK_GRAPH_LOCK(sink);
  if (!sink->graph_running){
    retst = gst_dshowvideosink_start_graph(sink);
    if (retst == GST_STATE_CHANGE_FAILURE)
      return GST_FLOW_FLUSHING;
  }
  ret = sink->fakesrc->GetOutputPin()->PushBuffer (buffer);
  if (!sink->graph_running){
    retst = gst_dshowvideosink_pause_graph(sink);
    if (retst == GST_STATE_CHANGE_FAILURE)
      return GST_FLOW_FLUSHING;
  }
  GST_DSHOWVIDEOSINK_GRAPH_UNLOCK(sink);
  GST_DEBUG_OBJECT (sink, "Done pushing buffer through fakesrc->renderer: %s", gst_flow_get_name(ret));

  return ret;
}

/* TODO: How can we implement these? Figure that out... */
static gboolean
gst_dshowvideosink_unlock (GstBaseSink * bsink)
{
  GstDshowVideoSink *sink = GST_DSHOWVIDEOSINK (bsink);

  return TRUE;
}

static gboolean
gst_dshowvideosink_unlock_stop (GstBaseSink * bsink)
{
  GstDshowVideoSink *sink = GST_DSHOWVIDEOSINK (bsink);

  return TRUE;
}

/* TODO: Move all of this into generic code? */

/* Helpers to format GUIDs the same way we find them in the source */
#define GUID_FORMAT "{%.8x, %.4x, %.4x, { %.2x, %.2x, %.2x, %.2x, %.2x, %.2x, %.2x, %.2x }}"
#define GUID_ARGS(guid) \
    guid.Data1, guid.Data2, guid.Data3, \
    guid.Data4[0], guid.Data4[1], guid.Data4[3], guid.Data4[4], \
    guid.Data4[5], guid.Data4[6], guid.Data4[7], guid.Data4[8]

static GstCaps *
audio_media_type_to_caps (AM_MEDIA_TYPE *mediatype)
{
  return NULL;
}

static GstCaps *
video_media_type_to_caps (AM_MEDIA_TYPE *mediatype)
{
  GstCaps *caps = NULL;

  /* TODO: Add  RGB types. */
  if (IsEqualGUID (mediatype->subtype, MEDIASUBTYPE_YUY2))
    caps = gst_caps_new_simple ("video/x-raw",
            "format", GST_TYPE_VIDEO_FORMAT, GST_VIDEO_FORMAT_YUY2, NULL);
  else if (IsEqualGUID (mediatype->subtype, MEDIASUBTYPE_UYVY))
    caps = gst_caps_new_simple ("video/x-raw",
            "format", GST_TYPE_VIDEO_FORMAT, GST_VIDEO_FORMAT_UYVY, NULL);
  else if (IsEqualGUID (mediatype->subtype, MEDIASUBTYPE_YV12))
    caps = gst_caps_new_simple ("video/x-raw",
            "format", GST_TYPE_VIDEO_FORMAT, GST_VIDEO_FORMAT_YV12, NULL);

  if (!caps) {
    GST_DEBUG ("No subtype known; cannot continue");
    return NULL;
  }

  if (IsEqualGUID (mediatype->formattype, FORMAT_VideoInfo) &&
          mediatype->cbFormat >= sizeof(VIDEOINFOHEADER))
  {
    VIDEOINFOHEADER *vh = (VIDEOINFOHEADER *)mediatype->pbFormat;

	/* TODO: Set PAR here. Based on difference between source and target RECTs? 
     *       Do we want framerate? Based on AvgTimePerFrame? */
    gst_caps_set_simple (caps, 
            "width", G_TYPE_INT, vh->bmiHeader.biWidth,
            "height", G_TYPE_INT, vh->bmiHeader.biHeight,
			NULL);
  }

  return caps;
}


/* Create a GstCaps object representing the same media type as
 * this AM_MEDIA_TYPE.
 *
 * Returns NULL if no corresponding GStreamer type is known.
 *
 * May modify mediatype.
 */
static GstCaps *
gst_directshow_media_type_to_caps (AM_MEDIA_TYPE *mediatype)
{
  GstCaps *caps = NULL;

  if (IsEqualGUID (mediatype->majortype, MEDIATYPE_Video))
    caps = video_media_type_to_caps (mediatype);
  else if (IsEqualGUID (mediatype->majortype, MEDIATYPE_Audio))
    caps = audio_media_type_to_caps (mediatype);
  else {
    GST_DEBUG ("Non audio/video media types not yet " \
        "recognised, please add me: " GUID_FORMAT,
        GUID_ARGS(mediatype->majortype));
  }

  if (caps) {
    gchar *capsstring = gst_caps_to_string (caps);
    GST_DEBUG ("Converted AM_MEDIA_TYPE to \"%s\"", capsstring);
    g_free (capsstring);
  }
  else {
    GST_WARNING ("Failed to convert AM_MEDIA_TYPE to caps");
  }

  return caps;
}

/* Fill in a DirectShow AM_MEDIA_TYPE structure representing the same media
 * type as this GstCaps object.
 *
 * Returns FALSE if no corresponding type is known.
 *
 * Only operates on simple (single structure) caps.
 */
static gboolean
gst_caps_to_directshow_media_type (GstDshowVideoSink * sink, GstCaps *caps,
    AM_MEDIA_TYPE *mediatype)
{
  GstVideoInfo info;
  int width, height;
  int bpp;

  gst_video_info_init (&info);
  if (!gst_video_info_from_caps (&info, caps))
  {
    GST_WARNING_OBJECT (sink, "Couldn't parse caps");
      return FALSE;
  }
  memset (mediatype, 0, sizeof (AM_MEDIA_TYPE));

  if (GST_VIDEO_FORMAT_INFO_IS_YUV (info.finfo))
  {
    guint32 fourcc;
    GST_VIDEO_SINK_WIDTH (sink) = info.width;
    GST_VIDEO_SINK_HEIGHT (sink) = info.height;
    width = info.width;
    height = info.height;
    mediatype->majortype = MEDIATYPE_Video;

    switch (GST_VIDEO_INFO_FORMAT (&info))
    {
        case GST_VIDEO_FORMAT_YUY2:
          mediatype->subtype = MEDIASUBTYPE_YUY2;
          fourcc = GST_MAKE_FOURCC ('Y', 'U', 'Y', '2');
          bpp = 16;
          break;
        case GST_VIDEO_FORMAT_UYVY:
          mediatype->subtype = MEDIASUBTYPE_UYVY;
          fourcc = GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y');
          bpp = 16;
          break;
        case GST_VIDEO_FORMAT_YV12:
          mediatype->subtype = MEDIASUBTYPE_YV12;
          fourcc = GST_MAKE_FOURCC ('Y', 'V', '1', '2');
          bpp = 12;
          break;
        default:
          GST_WARNING_OBJECT (sink, "Couldn't parse caps");
          return FALSE;
    }

    mediatype->bFixedSizeSamples = TRUE; /* Always true for raw video */
    mediatype->bTemporalCompression = FALSE; /* Likewise, always false */

    {
      int par_n, par_d;
      VIDEOINFOHEADER *vi = (VIDEOINFOHEADER *)CoTaskMemAlloc (sizeof (VIDEOINFOHEADER));
      memset (vi, 0, sizeof (VIDEOINFOHEADER));

      mediatype->formattype = FORMAT_VideoInfo;
      mediatype->cbFormat = sizeof (VIDEOINFOHEADER);
      mediatype->pbFormat = (BYTE *)vi;

      mediatype->lSampleSize = width * height * bpp / 8;

      GST_INFO_OBJECT (sink, "Set mediatype format: size %d, sample size %d",
          mediatype->cbFormat, mediatype->lSampleSize);

      vi->rcSource.top = 0;
      vi->rcSource.left = 0;
      vi->rcSource.bottom = height;
      vi->rcSource.right = width;

      vi->rcTarget.top = 0;
      vi->rcTarget.left = 0;
      if (sink->keep_aspect_ratio) {
        par_n = GST_VIDEO_INFO_PAR_N (&info);
        par_d = GST_VIDEO_INFO_PAR_D (&info);
        /* To handle non-square pixels, we set the target rectangle to a 
         * different size than the source rectangle.
         * There might be a better way, but this seems to work. */
        vi->rcTarget.bottom = height;
        vi->rcTarget.right = width * par_n / par_d;
        GST_DEBUG_OBJECT (sink, "Got PAR: set target right to %d from width %d",
            vi->rcTarget.right, width);
      }
      else {
        vi->rcTarget.bottom = height;
        vi->rcTarget.right = width;
      }

      vi->bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
      vi->bmiHeader.biWidth = width;
      vi->bmiHeader.biHeight = -height; /* Required to be negative. */
      vi->bmiHeader.biPlanes = 1; /* Required to be 1 */
      vi->bmiHeader.biBitCount = bpp;
      vi->bmiHeader.biCompression = fourcc;
      vi->bmiHeader.biSizeImage = width * height * bpp / 8;

      /* We can safely zero these; they don't matter for our uses */
      vi->bmiHeader.biXPelsPerMeter = 0;
      vi->bmiHeader.biYPelsPerMeter = 0;
      vi->bmiHeader.biClrUsed = 0;
      vi->bmiHeader.biClrImportant = 0;
    }

    GST_DEBUG_OBJECT (sink, "Successfully built AM_MEDIA_TYPE from caps");
    return TRUE;
  }

  GST_WARNING_OBJECT (sink, "Failed to convert caps, not a known caps type");
  /* Only YUV supported so far */

  return FALSE;
}

/* Plugin entry point */
extern "C" static gboolean
plugin_init (GstPlugin * plugin)
{
  /* PRIMARY: this is the best videosink to use on windows */
  if (!gst_element_register (plugin, "dshowvideosink",
          GST_RANK_SECONDARY, GST_TYPE_DSHOWVIDEOSINK))
    return FALSE;

  return TRUE;
}

extern "C" GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
    GST_VERSION_MINOR,
    dshowsinkwrapper,
    "DirectShow sink wrapper plugin",
    plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
