コード例 #1
0
static void
window_resize (GstGLWindowDispmanxEGL * window_egl, guint width, guint height)
{
  GST_DEBUG ("resizing window from %ux%u to %ux%u",
      window_egl->native.width, window_egl->native.height, width, height);

  if (window_egl->display) {
    VC_RECT_T dst_rect;
    VC_RECT_T src_rect;
    GstVideoRectangle src, dst, res;
    DISPMANX_UPDATE_HANDLE_T dispman_update;
    VC_DISPMANX_ALPHA_T alpha =
        { DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS, 255, 0 };

    /* Center width*height frame inside dp_width*dp_height */
    src.w = width;
    src.h = height;
    src.x = src.y = 0;
    dst.w = window_egl->dp_width;
    dst.h = window_egl->dp_height;
    dst.x = dst.y = 0;
    gst_video_sink_center_rect (src, dst, &res, FALSE);

    dst_rect.x = res.x;
    dst_rect.y = res.y;
    dst_rect.width = res.w;
    dst_rect.height = res.h;

    src_rect.x = 0;
    src_rect.y = 0;
    src_rect.width = width << 16;
    src_rect.height = height << 16;

    dispman_update = vc_dispmanx_update_start (0);

    if (window_egl->native.element) {
      vc_dispmanx_element_change_attributes (dispman_update,
          window_egl->native.element, 0x00000110, 0, 0, &dst_rect, &src_rect, 0,
          0);
    } else {
      window_egl->native.element = vc_dispmanx_element_add (dispman_update,
          window_egl->display, 0, &dst_rect, 0, &src_rect,
          DISPMANX_PROTECTION_NONE, &alpha, 0, 0);
    }

    vc_dispmanx_update_submit_sync (dispman_update);

    if (GST_GL_WINDOW (window_egl)->resize)
      GST_GL_WINDOW (window_egl)->
          resize (GST_GL_WINDOW (window_egl)->resize_data, width, height);
  }

  window_egl->native.width = width;
  window_egl->native.height = height;
}
コード例 #2
0
/**
 * gst_gl_window_new:
 * @display: a #GstGLDisplay
 *
 * Returns: (transfer full): a new #GstGLWindow using @display's connection
 */
GstGLWindow *
gst_gl_window_new (GstGLDisplay * display)
{
  GstGLWindow *window = NULL;
  const gchar *user_choice;
  static volatile gsize _init = 0;

  g_return_val_if_fail (display != NULL, NULL);

  if (g_once_init_enter (&_init)) {
    GST_DEBUG_CATEGORY_INIT (gst_gl_window_debug, "glwindow", 0,
        "glwindow element");
    g_once_init_leave (&_init, 1);
  }

  user_choice = g_getenv ("GST_GL_WINDOW");
  GST_INFO ("creating a window, user choice:%s", user_choice);

#if GST_GL_HAVE_WINDOW_COCOA
  if (!window && (!user_choice || g_strstr_len (user_choice, 5, "cocoa")))
    window = GST_GL_WINDOW (gst_gl_window_cocoa_new ());
#endif
#if GST_GL_HAVE_WINDOW_X11
  if (!window && (!user_choice || g_strstr_len (user_choice, 3, "x11")))
    window = GST_GL_WINDOW (gst_gl_window_x11_new (display));
#endif
#if GST_GL_HAVE_WINDOW_WIN32
  if (!window && (!user_choice || g_strstr_len (user_choice, 5, "win32")))
    window = GST_GL_WINDOW (gst_gl_window_win32_new ());
#endif
#if GST_GL_HAVE_WINDOW_WAYLAND
  if (!window && (!user_choice || g_strstr_len (user_choice, 7, "wayland")))
    window = GST_GL_WINDOW (gst_gl_window_wayland_egl_new ());
#endif
#if GST_GL_HAVE_WINDOW_DISPMANX
  if (!window && (!user_choice || g_strstr_len (user_choice, 8, "dispmanx")))
    window = GST_GL_WINDOW (gst_gl_window_dispmanx_egl_new ());
#endif
#if GST_GL_HAVE_WINDOW_ANDROID
  if (!window && (!user_choice || g_strstr_len (user_choice, 7, "android")))
    window = GST_GL_WINDOW (gst_gl_window_android_egl_new ());
#endif
#if GST_GL_HAVE_WINDOW_EAGL
  if (!window && (!user_choice || g_strstr_len (user_choice, 4, "eagl")))
    window = GST_GL_WINDOW (gst_gl_window_eagl_new ());
#endif
  if (!window) {
    /* subclass returned a NULL window */
    GST_WARNING ("Could not create window. user specified %s, creating dummy"
        " window", user_choice ? user_choice : "(null)");

    window = GST_GL_WINDOW (gst_gl_dummy_window_new ());
  }

  window->display = gst_object_ref (display);

  return window;
}
コード例 #3
0
ファイル: gstglwindow.c プロジェクト: fanc999/gst-plugins-bad
static void
gst_gl_window_finalize (GObject * object)
{
  GstGLWindow *window = GST_GL_WINDOW (object);
  GstGLWindowPrivate *priv = window->priv;

  GST_INFO ("quit navigation loop");
  if (window->priv->navigation_loop) {
    g_main_loop_quit (window->priv->navigation_loop);
    /* wait until navigation thread finished */
    g_thread_join (window->priv->navigation_thread);
    window->priv->navigation_thread = NULL;
  }

  if (priv->loop)
    g_main_loop_unref (priv->loop);

  if (priv->main_context)
    g_main_context_unref (priv->main_context);

  g_weak_ref_clear (&window->context_ref);

  g_mutex_clear (&window->lock);
  g_mutex_clear (&window->priv->nav_lock);
  g_cond_clear (&window->priv->nav_create_cond);
  g_mutex_clear (&window->priv->sync_message_lock);
  g_cond_clear (&window->priv->sync_message_cond);
  gst_object_unref (window->display);

  G_OBJECT_CLASS (gst_gl_window_parent_class)->finalize (object);
}
コード例 #4
0
static void
draw_cb (gpointer data)
{
  GstGLWindowAndroidEGL *window_egl = data;
  GstGLWindow *window = GST_GL_WINDOW (window_egl);
  GstGLContext *context = gst_gl_window_get_context (window);
  GstGLContextEGL *context_egl = GST_GL_CONTEXT_EGL (context);
  GstGLContextClass *context_class = GST_GL_CONTEXT_GET_CLASS (context);

  if (context_egl->egl_surface) {
    gint width, height;

    if (eglQuerySurface (context_egl->egl_display,
            context_egl->egl_surface, EGL_WIDTH, &width) &&
        eglQuerySurface (context_egl->egl_display,
            context_egl->egl_surface, EGL_HEIGHT, &height)
        && (width != window_egl->window_width
            || height != window_egl->window_height)) {
      window_egl->window_width = width;
      window_egl->window_height = height;

      if (window->resize)
        window->resize (window->resize_data, width, height);
    }
  }

  if (window->draw)
    window->draw (window->draw_data);

  context_class->swap_buffers (context);

  gst_object_unref (context);
}
コード例 #5
0
static void
draw_cb (gpointer data)
{
  GstGLWindowWaylandEGL *window_egl = data;
  GstGLWindow *window = GST_GL_WINDOW (window_egl);
  GstGLContext *context = gst_gl_window_get_context (window);
  GstGLContextClass *context_class = GST_GL_CONTEXT_GET_CLASS (context);

  create_surfaces (window_egl);

  if (window_egl->window.subsurface)
    wl_subsurface_set_desync (window_egl->window.subsurface);

  if (window->queue_resize) {
    guint width, height;

    gst_gl_window_get_surface_dimensions (window, &width, &height);
    gst_gl_window_resize (window, width, height);
  }

  if (window->draw)
    window->draw (window->draw_data);

  context_class->swap_buffers (context);

  if (window_egl->window.subsurface)
    wl_subsurface_set_desync (window_egl->window.subsurface);

  gst_object_unref (context);
}
コード例 #6
0
static void
gst_gl_window_finalize (GObject * object)
{
  GstGLWindow *window = GST_GL_WINDOW (object);

  g_weak_ref_clear (&window->context_ref);

  g_mutex_clear (&window->lock);
  gst_object_unref (window->display);

  G_OBJECT_CLASS (gst_gl_window_parent_class)->finalize (object);
}
コード例 #7
0
ファイル: gstglwindow.c プロジェクト: fanc999/gst-plugins-bad
static gboolean
gst_gl_window_key_event_cb (gpointer data)
{
  KeyEventData *key_data = data;

  GST_DEBUG
      ("%s called data struct %p window %p key %s event %s ",
      __func__, key_data, key_data->window, key_data->key_str,
      key_data->event_type);

  gst_gl_window_send_key_event (GST_GL_WINDOW (key_data->window),
      key_data->event_type, key_data->key_str);

  return G_SOURCE_REMOVE;
}
コード例 #8
0
static void
draw_cb (gpointer data)
{
  GstGLWindowWaylandEGL *window_egl = data;
  GstGLWindow *window = GST_GL_WINDOW (window_egl);
  GstGLContext *context = gst_gl_window_get_context (window);
  GstGLContextClass *context_class = GST_GL_CONTEXT_GET_CLASS (context);

  if (window->draw)
    window->draw (window->draw_data);

  context_class->swap_buffers (context);

  gst_object_unref (context);
}
コード例 #9
0
ファイル: gstglwindow.c プロジェクト: fanc999/gst-plugins-bad
static gboolean
gst_gl_window_mouse_event_cb (gpointer data)
{
  MouseEventData *mouse_data = data;

  GST_DEBUG ("%s called data struct %p mouse event %s button %d at %g, %g",
      __func__, mouse_data, mouse_data->event_type, mouse_data->button,
      mouse_data->posx, mouse_data->posy);

  gst_gl_window_send_mouse_event (GST_GL_WINDOW (mouse_data->window),
      mouse_data->event_type, mouse_data->button, mouse_data->posx,
      mouse_data->posy);

  return G_SOURCE_REMOVE;
}
コード例 #10
0
static void
draw_cb (gpointer data)
{
  struct draw *draw_data = data;
  GstGLDummyWindow *dummy = draw_data->window;
  GstGLWindow *window = GST_GL_WINDOW (dummy);
  GstGLContext *context = gst_gl_window_get_context (window);
  GstGLContextClass *context_class = GST_GL_CONTEXT_GET_CLASS (context);

  if (window->draw)
    window->draw (window->draw_data);

  context_class->swap_buffers (context);

  gst_object_unref (context);
}
コード例 #11
0
static void
window_resize (GstGLWindowWaylandEGL * window_egl, guint width, guint height)
{
  GstGLWindow *window = GST_GL_WINDOW (window_egl);

  GST_DEBUG ("resizing window from %ux%u to %ux%u",
      window_egl->window.window_width, window_egl->window.window_height, width,
      height);

  if (window_egl->window.native) {
    wl_egl_window_resize (window_egl->window.native, width, height, 0, 0);
  }

  gst_gl_window_resize (window, width, height);

  window_egl->window.window_width = width;
  window_egl->window.window_height = height;
}
コード例 #12
0
GstGLContext *
gst_gl_context_gpu_process_new (GstGLDisplay * display,
    GstGLAPI gl_api, GstGLProcAddrFunc proc_addr)
{
  GstGLContext *context = NULL;
  GstGLContextGPUProcess *gpu_context = NULL;
  GstGLContextClass *context_class = NULL;
  GstGLWindow *window = NULL;
  GError *error = NULL;
  g_return_val_if_fail ((gst_gl_display_get_gl_api (display) & gl_api) !=
      GST_GL_API_NONE, NULL);

  gpu_context = g_object_new (GST_GL_TYPE_CONTEXT_GPU_PROCESS, NULL);
  gpu_context->priv->gl_api = gl_api;

  context = GST_GL_CONTEXT (gpu_context);

  context->display = display;
  gst_gl_display_add_context (display, context);

  context_class = GST_GL_CONTEXT_GET_CLASS (context);

  context_class->get_current_context = NULL;
  context_class->get_proc_address = GST_DEBUG_FUNCPTR (proc_addr);

  gst_gl_context_activate (context, TRUE);
  gst_gl_context_fill_info (context, &error);

  if (error) {
    GST_ERROR_OBJECT (context, "Failed to create gpu process context: %s",
        error->message);
    g_error_free (error);
    gst_object_unref (context);
    return NULL;
  }

  window = GST_GL_WINDOW (gst_gl_window_gpu_process_new (display));
  gst_gl_context_set_window (context, window);
  GST_GL_WINDOW_GET_CLASS (window)->open (window, NULL);
  gst_object_unref (window);

  return context;
}
コード例 #13
0
ファイル: gstglwindow.c プロジェクト: luisbg/gst-plugins-bad
static void
gst_gl_window_finalize (GObject * object)
{
  GstGLWindow *window = GST_GL_WINDOW (object);
  GstGLWindowPrivate *priv = window->priv;

  if (priv->loop)
    g_main_loop_unref (priv->loop);

  if (priv->main_context)
    g_main_context_unref (priv->main_context);

  g_weak_ref_clear (&window->context_ref);

  g_mutex_clear (&window->lock);
  g_mutex_clear (&window->priv->sync_message_lock);
  g_cond_clear (&window->priv->sync_message_cond);
  gst_object_unref (window->display);

  G_OBJECT_CLASS (gst_gl_window_parent_class)->finalize (object);
}
コード例 #14
0
static void
gst_gl_window_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstGLWindow *window;
  GstGLWindowPrivate *priv;

  g_return_if_fail (GST_GL_IS_WINDOW (object));

  window = GST_GL_WINDOW (object);

  priv = window->priv;

  switch (prop_id) {
    case ARG_DISPLAY:
      g_value_set_string (value, priv->display_name);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}
コード例 #15
0
ファイル: gstglwindow.c プロジェクト: luisbg/gst-plugins-bad
static void
draw_cb (gpointer data)
{
  GstGLWindow *window = GST_GL_WINDOW (data);
  GstGLContext *context = gst_gl_window_get_context (window);
  GstGLContextClass *context_class = GST_GL_CONTEXT_GET_CLASS (context);

  if (window->queue_resize) {
    guint width, height;

    gst_gl_window_get_surface_dimensions (window, &width, &height);
    gst_gl_window_resize (window, width, height);
  }

  if (window->draw)
    window->draw (window->draw_data);

  if (context_class->swap_buffers)
    context_class->swap_buffers (context);

  gst_object_unref (context);
}
コード例 #16
0
static void
draw_cb (gpointer data)
{
  GstGLWindowDispmanxEGL *window_egl = data;
  GstGLWindow *window = GST_GL_WINDOW (window_egl);
  GstGLContext *context = gst_gl_window_get_context (window);
  GstGLContextClass *context_class = GST_GL_CONTEXT_GET_CLASS (context);

  if (window_egl->native.width != window_egl->preferred_width
      || window_egl->native.height != window_egl->preferred_height) {
    GST_DEBUG ("dimensions don't match, attempting resize");
    window_resize (window_egl, window_egl->preferred_width,
        window_egl->preferred_height);
  }

  if (window->draw)
    window->draw (window->draw_data);

  context_class->swap_buffers (context);

  gst_object_unref (context);
}
コード例 #17
0
ファイル: gstglwindow.c プロジェクト: fanc999/gst-plugins-bad
/**
 * gst_gl_window_new:
 * @display: a #GstGLDisplay
 *
 * Returns: (transfer full): a new #GstGLWindow using @display's connection
 *
 * Since: 1.4
 */
GstGLWindow *
gst_gl_window_new (GstGLDisplay * display)
{
  GstGLWindow *window = NULL;
  const gchar *user_choice;

  g_return_val_if_fail (display != NULL, NULL);

  _init_debug ();

  user_choice = g_getenv ("GST_GL_WINDOW");
  GST_INFO ("creating a window, user choice:%s", user_choice);

#if GST_GL_HAVE_WINDOW_COCOA
  if (!window && (!user_choice || g_strstr_len (user_choice, 5, "cocoa")))
    window = GST_GL_WINDOW (gst_gl_window_cocoa_new (display));
#endif
#if GST_GL_HAVE_WINDOW_X11
  if (!window && (!user_choice || g_strstr_len (user_choice, 3, "x11")))
    window = GST_GL_WINDOW (gst_gl_window_x11_new (display));
#endif
#if GST_GL_HAVE_WINDOW_WIN32
  if (!window && (!user_choice || g_strstr_len (user_choice, 5, "win32")))
    window = GST_GL_WINDOW (gst_gl_window_win32_new (display));
#endif
#if GST_GL_HAVE_WINDOW_WAYLAND
  if (!window && (!user_choice || g_strstr_len (user_choice, 7, "wayland")))
    window = GST_GL_WINDOW (gst_gl_window_wayland_egl_new (display));
#endif
#if GST_GL_HAVE_WINDOW_DISPMANX
  if (!window && (!user_choice || g_strstr_len (user_choice, 8, "dispmanx")))
    window = GST_GL_WINDOW (gst_gl_window_dispmanx_egl_new (display));
#endif
#if GST_GL_HAVE_WINDOW_ANDROID
  if (!window && (!user_choice || g_strstr_len (user_choice, 7, "android")))
    window = GST_GL_WINDOW (gst_gl_window_android_egl_new (display));
#endif
#if GST_GL_HAVE_WINDOW_EAGL
  if (!window && (!user_choice || g_strstr_len (user_choice, 4, "eagl")))
    window = GST_GL_WINDOW (gst_gl_window_eagl_new (display));
#endif
  if (!window) {
    /* subclass returned a NULL window */
    GST_WARNING ("Could not create window. user specified %s, creating dummy"
        " window", user_choice ? user_choice : "(null)");

    window = GST_GL_WINDOW (gst_gl_dummy_window_new ());
  }

  window->display = gst_object_ref (display);

  g_mutex_lock (&window->priv->nav_lock);
  window->priv->navigation_thread = g_thread_new ("gstglnavigation",
      (GThreadFunc) gst_gl_window_navigation_thread, window);

  while (!window->priv->nav_alive)
    g_cond_wait (&window->priv->nav_create_cond, &window->priv->nav_lock);
  g_mutex_unlock (&window->priv->nav_lock);

  return window;
}
コード例 #18
0
static void
create_surfaces (GstGLWindowWaylandEGL * window_egl)
{
  GstGLDisplayWayland *display =
      GST_GL_DISPLAY_WAYLAND (GST_GL_WINDOW (window_egl)->display);
  gint width, height;

  if (!window_egl->window.surface) {
    window_egl->window.surface =
        wl_compositor_create_surface (display->compositor);
    if (window_egl->window.queue)
      wl_proxy_set_queue ((struct wl_proxy *) window_egl->window.surface,
          window_egl->window.queue);
  }

  if (window_egl->window.foreign_surface) {
    /* (re)parent */
    if (!display->subcompositor) {
      GST_ERROR_OBJECT (window_egl,
          "Wayland server does not support subsurfaces");
      window_egl->window.foreign_surface = NULL;
      goto shell_window;
    }

    if (!window_egl->window.subsurface) {
      window_egl->window.subsurface =
          wl_subcompositor_get_subsurface (display->subcompositor,
          window_egl->window.surface, window_egl->window.foreign_surface);
      if (window_egl->window.queue)
        wl_proxy_set_queue ((struct wl_proxy *) window_egl->window.subsurface,
            window_egl->window.queue);

      wl_subsurface_set_position (window_egl->window.subsurface,
          window_egl->window.window_x, window_egl->window.window_y);
      wl_subsurface_set_desync (window_egl->window.subsurface);
    }
  } else {
  shell_window:
    if (!window_egl->window.shell_surface) {
      window_egl->window.shell_surface =
          wl_shell_get_shell_surface (display->shell,
          window_egl->window.surface);
      if (window_egl->window.queue)
        wl_proxy_set_queue ((struct wl_proxy *) window_egl->window.
            shell_surface, window_egl->window.queue);

      wl_shell_surface_add_listener (window_egl->window.shell_surface,
          &shell_surface_listener, window_egl);

      wl_shell_surface_set_title (window_egl->window.shell_surface,
          "OpenGL Renderer");
      wl_shell_surface_set_toplevel (window_egl->window.shell_surface);
    }
  }

  if (window_egl->window.window_width > 0)
    width = window_egl->window.window_width;
  else
    width = 320;
  window_egl->window.window_width = width;

  if (window_egl->window.window_height > 0)
    height = window_egl->window.window_height;
  else
    height = 240;
  window_egl->window.window_height = height;

  if (!window_egl->window.native) {
    gst_gl_window_resize (GST_GL_WINDOW (window_egl), width, height);

    window_egl->window.native =
        wl_egl_window_create (window_egl->window.surface, width, height);
    if (window_egl->window.queue)
      wl_proxy_set_queue ((struct wl_proxy *) window_egl->window.native,
          window_egl->window.queue);
  }
}
コード例 #19
0
/* Must be called in the gl thread */
static void
gst_gl_window_finalize (GObject * object)
{
  GstGLWindow *window = GST_GL_WINDOW (object);
  GstGLWindowPrivate *priv = window->priv;
  XEvent event;
  Bool ret = TRUE;

  g_mutex_lock (priv->x_lock);

  priv->parent = 0;

  XUnmapWindow (priv->device, priv->internal_win_id);

  ret =
      eglMakeCurrent (priv->device, EGL_NO_SURFACE, EGL_NO_SURFACE,
      EGL_NO_CONTEXT);
  if (!ret)
    g_debug ("failed to release opengl context\n");

  eglDestroyContext (priv->device, priv->gl_context);

  eglTerminate (priv->device);

  XFree (priv->visual_info);

  XReparentWindow (priv->device, priv->internal_win_id, priv->root, 0, 0);

  XDestroyWindow (priv->device, priv->internal_win_id);

  XSync (priv->device, FALSE);

  while (XPending (priv->device))
    XNextEvent (priv->device, &event);

  XSetCloseDownMode (priv->device, DestroyAll);

  /*XAddToSaveSet (display, w)
     Display *display;
     Window w; */

  //FIXME: it seems it causes destroy all created windows, even by other display connection:
  //This is case in: gst-launch-0.10 videotestsrc ! tee name=t t. ! queue ! glimagesink t. ! queue ! glimagesink
  //When the first window is closed and so its display is closed by the following line, then the other Window managed by the
  //other glimagesink, is not useable and so each opengl call causes a segmentation fault.
  //Maybe the solution is to use: XAddToSaveSet
  //The following line is commented to avoid the disagreement explained before.
  //XCloseDisplay (priv->device);

  g_debug ("display receiver closed\n");

  XCloseDisplay (priv->disp_send);

  g_debug ("display sender closed\n");

  if (priv->cond_send_message) {
    g_cond_free (priv->cond_send_message);
    priv->cond_send_message = NULL;
  }

  g_mutex_unlock (priv->x_lock);

  if (priv->x_lock) {
    g_mutex_free (priv->x_lock);
    priv->x_lock = NULL;
  }

  G_OBJECT_CLASS (gst_gl_window_parent_class)->finalize (object);
}
コード例 #20
0
LRESULT CALLBACK
window_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
  GstGLWindowWin32 *window_win32;
  LRESULT ret = 0;

  if (uMsg == WM_CREATE) {
    window_win32 =
        GST_GL_WINDOW_WIN32 (((LPCREATESTRUCT) lParam)->lpCreateParams);

    GST_TRACE ("WM_CREATE");

    window_win32->device = GetDC (hWnd);
    /* Do this, otherwise we hang on exit. We can still use it (due to the
     * CS_OWNDC flag in the WindowClass) after we have Released.
     */
    ReleaseDC (hWnd, window_win32->device);

    SetProp (hWnd, "gl_window", window_win32);
  } else if (GetProp (hWnd, "gl_window")) {
    GstGLWindow *window;
    GstGLContext *context;
    GstGLContextClass *context_class;

    window_win32 = GST_GL_WINDOW_WIN32 (GetProp (hWnd, "gl_window"));
    window = GST_GL_WINDOW (window_win32);
    context = gst_gl_window_get_context (window);
    context_class = GST_GL_CONTEXT_GET_CLASS (context);

    g_assert (window_win32->internal_win_id == hWnd);

    switch (uMsg) {
      case WM_SIZE:
      {
        if (window->resize) {
          window->resize (window->resize_data, LOWORD (lParam),
              HIWORD (lParam));
        }
        break;
      }
      case WM_PAINT:
      {
        if (window->draw) {
          PAINTSTRUCT ps;
          BeginPaint (hWnd, &ps);
          window->draw (window->draw_data);
          context_class->swap_buffers (context);
          EndPaint (hWnd, &ps);
        }
        break;
      }
      case WM_CLOSE:
      {
        ShowWindowAsync (window_win32->internal_win_id, SW_HIDE);

        GST_TRACE ("WM_CLOSE");

        if (window->close)
          window->close (window->close_data);
        break;
      }
      case WM_CAPTURECHANGED:
      {
        GST_DEBUG ("WM_CAPTURECHANGED");
        if (window->draw)
          window->draw (window->draw_data);
        break;
      }
      case WM_ERASEBKGND:
      {
        ret = TRUE;
        break;
      }
      default:
      {
        /* transmit messages to the parrent (ex: mouse/keyboard input) */
        HWND parent_id = window_win32->parent_win_id;
        if (parent_id)
          PostMessage (parent_id, uMsg, wParam, lParam);
        ret = DefWindowProc (hWnd, uMsg, wParam, lParam);
      }
    }

    gst_object_unref (context);
  } else {
    ret = DefWindowProc (hWnd, uMsg, wParam, lParam);
  }

  return ret;
}
コード例 #21
0
static void
window_resize (GstGLWindowDispmanxEGL * window_egl, guint width, guint height,
    gboolean visible)
{
  GstGLWindow *window = GST_GL_WINDOW (window_egl);

  GST_DEBUG ("resizing %s window from %ux%u to %ux%u",
      visible ? "visible" : "invisible", window_egl->native.width,
      window_egl->native.height, width, height);

  if (window_egl->display) {
    VC_RECT_T dst_rect;
    VC_RECT_T src_rect;
    GstVideoRectangle src, res;
    DISPMANX_UPDATE_HANDLE_T dispman_update;
    uint32_t opacity = visible ? 255 : 0;
    VC_DISPMANX_ALPHA_T alpha =
        { DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS, opacity, 0 };

    src.w = width;
    src.h = height;
    src.x = src.y = 0;

    /* If there is no render rectangle, center the width*height frame
     *  inside dp_width*dp_height */
    if (window_egl->render_rect.w <= 0 || window_egl->render_rect.h <= 0) {
      GstVideoRectangle dst;
      dst.w = window_egl->dp_width;
      dst.h = window_egl->dp_height;
      dst.x = dst.y = 0;
      gst_video_sink_center_rect (src, dst, &res, FALSE);
    } else {
      gst_video_sink_center_rect (src, window_egl->render_rect, &res, FALSE);
    }

    dst_rect.x = res.x;
    dst_rect.y = res.y;
    dst_rect.width = res.w;
    dst_rect.height = res.h;

    src_rect.x = 0;
    src_rect.y = 0;
    src_rect.width = width << 16;
    src_rect.height = height << 16;

    dispman_update = vc_dispmanx_update_start (0);

    if (window_egl->native.element) {
      uint32_t change_flags =
          ELEMENT_CHANGE_OPACITY | ELEMENT_CHANGE_DEST_RECT |
          ELEMENT_CHANGE_SRC_RECT;
      vc_dispmanx_element_change_attributes (dispman_update,
          window_egl->native.element, change_flags, 0, opacity, &dst_rect,
          &src_rect, 0, 0);
    } else {
      window_egl->native.element = vc_dispmanx_element_add (dispman_update,
          window_egl->display, 0, &dst_rect, 0, &src_rect,
          DISPMANX_PROTECTION_NONE, &alpha, 0, 0);
    }

    vc_dispmanx_update_submit_sync (dispman_update);

    gst_gl_window_resize (window, width, height);
  }

  window_egl->native.width = width;
  window_egl->native.height = height;
}
LRESULT CALLBACK
window_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
  GstGLWindowWin32 *window_win32;
  if (uMsg == WM_CREATE) {
    window_win32 =
        GST_GL_WINDOW_WIN32 (((LPCREATESTRUCT) lParam)->lpCreateParams);

    GST_TRACE ("WM_CREATE");

    window_win32->device = GetDC (hWnd);
    /* Do this, otherwise we hang on exit. We can still use it (due to the
     * CS_OWNDC flag in the WindowClass) after we have Released.
     */
    ReleaseDC (hWnd, window_win32->device);

    SetProp (hWnd, "gl_window", window_win32);
    return 0;
  } else if (GetProp (hWnd, "gl_window")) {
    GstGLWindow *window;
    GstGLContext *context;
    GstGLContextClass *context_class;

    window_win32 = GST_GL_WINDOW_WIN32 (GetProp (hWnd, "gl_window"));
    window = GST_GL_WINDOW (window_win32);
    context = gst_gl_window_get_context (window);
    context_class = GST_GL_CONTEXT_GET_CLASS (context);

    g_assert (window_win32->internal_win_id == hWnd);

    switch (uMsg) {
      case WM_SIZE:
      {
        if (window->resize) {
          window->resize (window->resize_data, LOWORD (lParam),
              HIWORD (lParam));
        }
        break;
      }
      case WM_PAINT:
      {
        if (window->draw) {
          PAINTSTRUCT ps;
          BeginPaint (hWnd, &ps);
          window->draw (window->draw_data);
          context_class->swap_buffers (context);
          EndPaint (hWnd, &ps);
        }
        break;
      }
      case WM_CLOSE:
      {
        ShowWindowAsync (window_win32->internal_win_id, SW_HIDE);

        GST_TRACE ("WM_CLOSE");

        if (window->close)
          window->close (window->close_data);
        break;
      }
      case WM_GST_GL_WINDOW_QUIT:
      {
        HWND parent_id = 0;

        GST_TRACE ("WM_GST_GL_WINDOW_QUIT");

        parent_id = window_win32->parent_win_id;
        if (parent_id) {
          WNDPROC parent_proc = GetProp (parent_id, "gl_window_parent_proc");

          g_assert (parent_proc);

          SetWindowLongPtr (parent_id, GWLP_WNDPROC, (LONG_PTR) parent_proc);
          SetParent (hWnd, NULL);

          RemoveProp (parent_id, "gl_window_parent_proc");
        }

        window_win32->is_closed = TRUE;
        RemoveProp (hWnd, "gl_window");

        if (window_win32->internal_win_id) {
          if (!DestroyWindow (window_win32->internal_win_id))
            GST_WARNING ("failed to destroy window %" G_GUINTPTR_FORMAT
                ", 0x%x", (guintptr) hWnd, (unsigned int) GetLastError ());
        }

        PostQuitMessage (0);
        break;
      }
      case WM_CAPTURECHANGED:
      {
        GST_DEBUG ("WM_CAPTURECHANGED");
        if (window->draw)
          window->draw (window->draw_data);
        break;
      }
      case WM_GST_GL_WINDOW_CUSTOM:
      {
        if (!window_win32->is_closed) {
          GstGLMessage *message = (GstGLMessage *) wParam;
          _run_message (message);
        }
        break;
      }
      case WM_ERASEBKGND:
        return TRUE;
      default:
      {
        /* transmit messages to the parrent (ex: mouse/keyboard input) */
        HWND parent_id = window_win32->parent_win_id;
        if (parent_id)
          PostMessage (parent_id, uMsg, wParam, lParam);
        return DefWindowProc (hWnd, uMsg, wParam, lParam);
      }
    }

    gst_object_unref (context);

    return 0;
  } else {
    return DefWindowProc (hWnd, uMsg, wParam, lParam);
  }
}