/* 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);

  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:
      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)
