From 5909a495a7c5a0556978b8b6cf7a8b9cc92360d9 Mon Sep 17 00:00:00 2001 From: Seungha Yang Date: Thu, 15 Aug 2019 16:20:26 +0900 Subject: [PATCH] d3d11videosink: Take into account pixel aspect ratio Fix unexpected cropping with non 1:1 pixel aspect-ratio. The actual buffer width/height should be passed to gst_d3d11_window_render(), instead of the calculated resolution. The width/height values are parameters for copying d3d11 video memory. Also, aspect-ratio should be considered on resize callback to decide render rectangle size. --- sys/d3d11/gstd3d11videosink.c | 8 +++++--- sys/d3d11/gstd3d11videosink.h | 2 ++ sys/d3d11/gstd3d11window.c | 20 ++++++++++++++++---- sys/d3d11/gstd3d11window.h | 5 +++++ 4 files changed, 28 insertions(+), 7 deletions(-) diff --git a/sys/d3d11/gstd3d11videosink.c b/sys/d3d11/gstd3d11videosink.c index 976c2fd69e..275295fe17 100644 --- a/sys/d3d11/gstd3d11videosink.c +++ b/sys/d3d11/gstd3d11videosink.c @@ -309,6 +309,8 @@ gst_d3d11_video_sink_set_caps (GstBaseSink * sink, GstCaps * caps) GST_DEBUG_OBJECT (self, "scaling to %dx%d", GST_VIDEO_SINK_WIDTH (self), GST_VIDEO_SINK_HEIGHT (self)); + self->video_width = video_width; + self->video_height = video_height; if (GST_VIDEO_SINK_WIDTH (self) <= 0 || GST_VIDEO_SINK_HEIGHT (self) <= 0) goto no_display_size; @@ -346,7 +348,7 @@ gst_d3d11_video_sink_set_caps (GstBaseSink * sink, GstCaps * caps) GST_OBJECT_UNLOCK (self); if (!gst_d3d11_window_prepare (self->window, GST_VIDEO_SINK_WIDTH (self), - GST_VIDEO_SINK_HEIGHT (self), self->dxgi_format, caps)) { + GST_VIDEO_SINK_HEIGHT (self), num, den, self->dxgi_format, caps)) { GST_ERROR_OBJECT (self, "cannot create swapchain"); return FALSE; } @@ -670,8 +672,8 @@ gst_d3d11_video_sink_show_frame (GstVideoSink * sink, GstBuffer * buf) rect.w = crop->width; rect.h = crop->height; } else { - rect.w = GST_VIDEO_SINK_WIDTH (self); - rect.h = GST_VIDEO_SINK_HEIGHT (self); + rect.w = self->video_width; + rect.h = self->video_height; } ret = gst_d3d11_window_render (self->window, texture, &rect); diff --git a/sys/d3d11/gstd3d11videosink.h b/sys/d3d11/gstd3d11videosink.h index 2fd81fc118..fa2f202b49 100644 --- a/sys/d3d11/gstd3d11videosink.h +++ b/sys/d3d11/gstd3d11videosink.h @@ -46,6 +46,8 @@ struct _GstD3D11VideoSink GstVideoSink sink; GstD3D11Device *device; GstD3D11Window *window; + gint video_width; + gint video_height; GstVideoInfo info; DXGI_FORMAT dxgi_format; diff --git a/sys/d3d11/gstd3d11window.c b/sys/d3d11/gstd3d11window.c index e34e47ccd6..3f4c54b0b0 100644 --- a/sys/d3d11/gstd3d11window.c +++ b/sys/d3d11/gstd3d11window.c @@ -137,6 +137,9 @@ gst_d3d11_window_init (GstD3D11Window * self) self->force_aspect_ratio = DEFAULT_FORCE_ASPECT_RATIO; self->enable_navigation_events = DEFAULT_ENABLE_NAVIGATION_EVENTS; + self->aspect_ratio_n = 1; + self->aspect_ratio_d = 1; + GST_TRACE_OBJECT (self, "Initialized"); } @@ -500,9 +503,12 @@ gst_d3d11_window_on_resize (GstD3D11Device * device, GstD3D11Window * window) if (width != window->surface_width || height != window->surface_height) { GstVideoRectangle src_rect, dst_rect; gdouble src_ratio, dst_ratio; + gdouble aspect_ratio = + (gdouble) window->aspect_ratio_n / (gdouble) window->aspect_ratio_d; src_ratio = (gdouble) width / height; - dst_ratio = (gdouble) window->surface_width / window->surface_height; + dst_ratio = + (gdouble) window->surface_width / window->surface_height * aspect_ratio; src_rect.x = 0; src_rect.y = 0; @@ -778,7 +784,8 @@ mastering_display_gst_to_dxgi (GstVideoMasteringDisplayInfo * m, gboolean gst_d3d11_window_prepare (GstD3D11Window * window, guint width, guint height, - DXGI_FORMAT format, GstCaps * caps) + guint aspect_ratio_n, guint aspect_ratio_d, DXGI_FORMAT format, + GstCaps * caps) { DXGI_SWAP_CHAIN_DESC desc = { 0, }; gboolean have_cll = FALSE; @@ -786,6 +793,8 @@ gst_d3d11_window_prepare (GstD3D11Window * window, guint width, guint height, gboolean hdr_api_available = FALSE; g_return_val_if_fail (GST_IS_D3D11_WINDOW (window), FALSE); + g_return_val_if_fail (aspect_ratio_n > 0, FALSE); + g_return_val_if_fail (aspect_ratio_d > 0, FALSE); GST_DEBUG_OBJECT (window, "Prepare window with %dx%d format %d", width, height, format); @@ -822,6 +831,9 @@ gst_d3d11_window_prepare (GstD3D11Window * window, guint width, guint height, } #endif + window->aspect_ratio_n = aspect_ratio_n; + window->aspect_ratio_d = aspect_ratio_d; + window->render_rect.x = 0; window->render_rect.y = 0; window->render_rect.w = width; @@ -847,8 +859,8 @@ gst_d3d11_window_prepare (GstD3D11Window * window, guint width, guint height, desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; #endif desc.OutputWindow = - window->external_win_id ? window-> - external_win_id : window->internal_win_id; + window->external_win_id ? window->external_win_id : window-> + internal_win_id; desc.Windowed = TRUE; desc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; diff --git a/sys/d3d11/gstd3d11window.h b/sys/d3d11/gstd3d11window.h index 3e39e7a873..6d25344625 100644 --- a/sys/d3d11/gstd3d11window.h +++ b/sys/d3d11/gstd3d11window.h @@ -62,6 +62,9 @@ struct _GstD3D11Window guint surface_width; guint surface_height; + guint aspect_ratio_n; + guint aspect_ratio_d; + gboolean visible; GSource *msg_source; @@ -113,6 +116,8 @@ void gst_d3d11_window_get_surface_dimensions (GstD3D11Window * window, gboolean gst_d3d11_window_prepare (GstD3D11Window * window, guint width, guint height, + guint aspect_ratio_n, + guint aspect_ratio_d, DXGI_FORMAT format, GstCaps * caps);