static gboolean
gst_mfx_window_wayland_resize (GstMfxWindow * window, guint width, guint height)
{
  GstMfxWindowWaylandPrivate *const priv =
      GST_MFX_WINDOW_WAYLAND_GET_PRIVATE (window);
  GstMfxDisplayWaylandPrivate *const priv_display =
      GST_MFX_DISPLAY_WAYLAND_GET_PRIVATE (GST_MFX_WINDOW_DISPLAY (window));

  GST_DEBUG ("resize window, new size %ux%u", width, height);

  GST_MFX_DISPLAY_LOCK (GST_MFX_WINDOW_DISPLAY (window));

#ifdef USE_WESTON_4_0
  if (priv->wp_viewport)
    wp_viewport_set_destination (priv->wp_viewport, width, height);
#else
  if (priv->viewport)
    wl_viewport_set_destination (priv->viewport, width, height);
#endif

  wl_surface_damage (priv->surface, 0, 0, width, height);
  wl_surface_commit (priv->surface);

  if (priv->opaque_region)
    wl_region_destroy (priv->opaque_region);

  priv->opaque_region = wl_compositor_create_region (priv_display->compositor);
  wl_region_add (priv->opaque_region, 0, 0, width, height);

  GST_MFX_DISPLAY_UNLOCK (GST_MFX_WINDOW_DISPLAY (window));

  return TRUE;
}
static gboolean
gst_mfx_window_wayland_set_fullscreen (GstMfxWindow * window,
    gboolean fullscreen)
{
  GstMfxWindowWaylandPrivate *const priv =
      GST_MFX_WINDOW_WAYLAND_GET_PRIVATE (window);

  if (!priv->is_shown) {
    priv->fullscreen_on_show = fullscreen;
    return TRUE;
  }

  if (!fullscreen)
    wl_shell_surface_set_toplevel (priv->shell_surface);
  else {
#ifdef USE_WESTON_4_0
    if (priv->wp_viewport)
      wp_viewport_set_destination (priv->wp_viewport,
	window->width, window->height);
#else
    wl_shell_surface_set_fullscreen (priv->shell_surface,
        WL_SHELL_SURFACE_FULLSCREEN_METHOD_SCALE, 0, NULL);
#endif
  }

  return TRUE;
}
Beispiel #3
0
void
gst_wl_window_set_render_rectangle (GstWlWindow * window, gint x, gint y,
    gint w, gint h)
{
  g_return_if_fail (window != NULL);

  window->render_rectangle.x = x;
  window->render_rectangle.y = y;
  window->render_rectangle.w = w;
  window->render_rectangle.h = h;

  /* position the area inside the parent - needs a parent commit to apply */
  if (window->area_subsurface)
    wl_subsurface_set_position (window->area_subsurface, x, y);

  /* change the size of the area */
  if (window->area_viewport)
    wp_viewport_set_destination (window->area_viewport, w, h);

  gst_wl_window_update_borders (window);

  if (window->video_width != 0) {
    wl_subsurface_set_sync (window->video_subsurface);
    gst_wl_window_resize_video_surface (window, TRUE);
  }

  wl_surface_damage (window->area_surface_wrapper, 0, 0, w, h);
  wl_surface_commit (window->area_surface_wrapper);

  if (window->video_width != 0)
    wl_subsurface_set_desync (window->video_subsurface);
}
Beispiel #4
0
static void
gst_wl_window_resize_video_surface (GstWlWindow * window, gboolean commit)
{
  GstVideoRectangle src = { 0, };
  GstVideoRectangle dst = { 0, };
  GstVideoRectangle res;

  /* center the video_subsurface inside area_subsurface */
  src.w = window->video_width;
  src.h = window->video_height;
  dst.w = window->render_rectangle.w;
  dst.h = window->render_rectangle.h;

  if (window->video_viewport) {
    gst_video_sink_center_rect (src, dst, &res, TRUE);
    wp_viewport_set_destination (window->video_viewport, res.w, res.h);
  } else {
    gst_video_sink_center_rect (src, dst, &res, FALSE);
  }

  wl_subsurface_set_position (window->video_subsurface, res.x, res.y);

  if (commit) {
    wl_surface_damage (window->video_surface_wrapper, 0, 0, res.w, res.h);
    wl_surface_commit (window->video_surface_wrapper);
  }

  if (gst_wl_window_is_toplevel (window)) {
    struct wl_region *region;

    region = wl_compositor_create_region (window->display->compositor);
    wl_region_add (region, 0, 0, window->render_rectangle.w,
        window->render_rectangle.h);
    wl_surface_set_input_region (window->area_surface, region);
    wl_region_destroy (region);
  }

  /* this is saved for use in wl_surface_damage */
  window->video_rectangle = res;
}
static gboolean
gst_mfx_window_wayland_render (GstMfxWindow * window,
    GstMfxSurface * surface,
    const GstMfxRectangle * src_rect, const GstMfxRectangle * dst_rect)
{
  GstMfxWindowWaylandPrivate *const priv =
      GST_MFX_WINDOW_WAYLAND_GET_PRIVATE (window);
  GstMfxDisplayWaylandPrivate *const display_priv =
      GST_MFX_DISPLAY_WAYLAND_GET_PRIVATE (GST_MFX_WINDOW_DISPLAY (window));
  struct wl_display *const display =
      GST_MFX_DISPLAY_HANDLE (GST_MFX_WINDOW_DISPLAY (window));
  GstMfxPrimeBufferProxy *buffer_proxy;
  struct wl_buffer *buffer;
  FrameState *frame;
  guintptr fd = 0;
  guint32 drm_format = 0;
  gint offsets[3] = { 0 }, pitches[3] = { 0 }, num_planes = 0, i = 0;
  VaapiImage *vaapi_image;

  buffer_proxy = gst_mfx_prime_buffer_proxy_new_from_surface (surface);
  if (!buffer_proxy)
    return FALSE;

  fd = GST_MFX_PRIME_BUFFER_PROXY_HANDLE (buffer_proxy);
  vaapi_image = gst_mfx_prime_buffer_proxy_get_vaapi_image (buffer_proxy);
  num_planes = vaapi_image_get_plane_count (vaapi_image);

  if ((dst_rect->height != src_rect->height)
      || (dst_rect->width != src_rect->width)) {
#ifdef USE_WESTON_4_0
    if (priv->wp_viewport) {
      wp_viewport_set_destination (priv->wp_viewport,
          dst_rect->width, dst_rect->height);
    }
#else
    if (priv->viewport) {
      wl_viewport_set_destination (priv->viewport,
          dst_rect->width, dst_rect->height);
    }
#endif
  }

  for (i = 0; i < num_planes; i++) {
    offsets[i] = vaapi_image_get_offset (vaapi_image, i);
    pitches[i] = vaapi_image_get_pitch (vaapi_image, i);
  }

  if (GST_VIDEO_FORMAT_NV12 == vaapi_image_get_format (vaapi_image)) {
    drm_format = WL_DRM_FORMAT_NV12;
  } else if (GST_VIDEO_FORMAT_BGRA == vaapi_image_get_format (vaapi_image)) {
    drm_format = WL_DRM_FORMAT_ARGB8888;
  }

  if (!drm_format)
    goto error;

  if (!display_priv->drm)
    goto error;

  GST_MFX_DISPLAY_LOCK (GST_MFX_WINDOW_DISPLAY (window));
  buffer =
      wl_drm_create_prime_buffer (display_priv->drm, fd,
          src_rect->width, src_rect->height, drm_format,
          offsets[0], pitches[0],
          offsets[1], pitches[1],
          offsets[2], pitches[2]);
  GST_MFX_DISPLAY_UNLOCK (GST_MFX_WINDOW_DISPLAY (window));
  if (!buffer) {
    GST_ERROR ("No wl_buffer created\n");
    goto error;
  }

  frame = frame_state_new (window);
  if (!frame)
    goto error;

  g_atomic_pointer_set (&priv->last_frame, frame);
  g_atomic_int_inc (&priv->num_frames_pending);

  GST_MFX_DISPLAY_LOCK (GST_MFX_WINDOW_DISPLAY (window));
  wl_surface_attach (priv->surface, buffer, 0, 0);

  wl_surface_damage (priv->surface, 0, 0, dst_rect->width, dst_rect->height);

  if (priv->opaque_region) {
    wl_surface_set_opaque_region (priv->surface, priv->opaque_region);
    wl_region_destroy (priv->opaque_region);
    priv->opaque_region = NULL;
  }
  wl_proxy_set_queue ((struct wl_proxy *) buffer, priv->event_queue);
  wl_buffer_add_listener (buffer, &frame_buffer_listener, frame);

  frame->callback = wl_surface_frame (priv->surface);
  wl_callback_add_listener (frame->callback, &frame_callback_listener, frame);

  wl_surface_commit (priv->surface);
  wl_display_flush (display);

  GST_MFX_DISPLAY_UNLOCK (GST_MFX_WINDOW_DISPLAY (window));

  vaapi_image_unref (vaapi_image);
  gst_mfx_prime_buffer_proxy_unref (buffer_proxy);

  return TRUE;
error:
  {
    vaapi_image_unref (vaapi_image);
    gst_mfx_prime_buffer_proxy_unref (buffer_proxy);
    return FALSE;
  }
}
Beispiel #6
0
static int Control(vout_display_t *vd, int query, va_list ap)
{
    vout_display_sys_t *sys = vd->sys;

    switch (query)
    {
        case VOUT_DISPLAY_RESET_PICTURES:
        {
            const vout_display_cfg_t *cfg = va_arg(ap, const vout_display_cfg_t *);
            video_format_t *fmt = va_arg(ap, video_format_t *);
            vout_display_place_t place;
            video_format_t src;
            assert(sys->viewport == NULL);

            vout_display_PlacePicture(&place, &vd->source, cfg);
            video_format_ApplyRotation(&src, &vd->source);

            fmt->i_width  = src.i_width * place.width
                                        / src.i_visible_width;
            fmt->i_height = src.i_height * place.height
                                         / src.i_visible_height;
            fmt->i_visible_width  = place.width;
            fmt->i_visible_height = place.height;
            fmt->i_x_offset = src.i_x_offset * place.width
                                             / src.i_visible_width;
            fmt->i_y_offset = src.i_y_offset * place.height
                                             / src.i_visible_height;
            break;
        }

        case VOUT_DISPLAY_CHANGE_DISPLAY_SIZE:
        case VOUT_DISPLAY_CHANGE_DISPLAY_FILLED:
        case VOUT_DISPLAY_CHANGE_ZOOM:
        case VOUT_DISPLAY_CHANGE_SOURCE_ASPECT:
        case VOUT_DISPLAY_CHANGE_SOURCE_CROP:
        {
            const vout_display_cfg_t *cfg = va_arg(ap, const vout_display_cfg_t *);
            sys->display_width = cfg->display.width;
            sys->display_height = cfg->display.height;

            if (sys->viewport != NULL)
            {
                video_format_t fmt;
                vout_display_place_t place;

                video_format_ApplyRotation(&fmt, &vd->source);
                vout_display_PlacePicture(&place, &vd->source, cfg);

                wp_viewport_set_source(sys->viewport,
                                wl_fixed_from_int(fmt.i_x_offset),
                                wl_fixed_from_int(fmt.i_y_offset),
                                wl_fixed_from_int(fmt.i_visible_width),
                                wl_fixed_from_int(fmt.i_visible_height));
                wp_viewport_set_destination(sys->viewport,
                                            place.width, place.height);
            }
            else
                return VLC_EGENERIC;
            break;
        }
        default:
             msg_Err(vd, "unknown request %d", query);
             return VLC_EGENERIC;
    }
    return VLC_SUCCESS;
}