[vlc-commits] direct3d11: handle the source orientation in flat projection
Steve Lhomme
git at videolan.org
Tue Jul 11 18:23:26 CEST 2017
vlc | branch: master | Steve Lhomme <robUx4 at videolabs.io> | Tue Jul 11 16:24:18 2017 +0200| [683051b044fbf8bd998d4d089f3426c23fdb0518] | committer: Jean-Baptiste Kempf
direct3d11: handle the source orientation in flat projection
Fixes #18477
Signed-off-by: Jean-Baptiste Kempf <jb at videolan.org>
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=683051b044fbf8bd998d4d089f3426c23fdb0518
---
modules/video_output/win32/direct3d11.c | 113 +++++++++++++++++++++++++++-----
1 file changed, 97 insertions(+), 16 deletions(-)
diff --git a/modules/video_output/win32/direct3d11.c b/modules/video_output/win32/direct3d11.c
index bf49b87e7e..9da636203f 100644
--- a/modules/video_output/win32/direct3d11.c
+++ b/modules/video_output/win32/direct3d11.c
@@ -228,7 +228,8 @@ static void Direct3D11DeleteRegions(int, picture_t **);
static int Direct3D11MapSubpicture(vout_display_t *, int *, picture_t ***, subpicture_t *);
static int SetupQuad(vout_display_t *, const video_format_t *, d3d_quad_t *,
- const d3d_format_t *, ID3D11PixelShader *, video_projection_mode_t);
+ const d3d_format_t *, ID3D11PixelShader *, video_projection_mode_t,
+ video_orientation_t);
static void ReleaseQuad(d3d_quad_t *);
static void UpdatePicQuadPosition(vout_display_t *);
@@ -775,7 +776,7 @@ static picture_pool_t *Pool(vout_display_t *vd, unsigned pool_size)
}
if (SetupQuad( vd, &surface_fmt, &sys->picQuad, sys->picQuadConfig, sys->picQuadPixelShader,
- surface_fmt.projection_mode) != VLC_SUCCESS) {
+ surface_fmt.projection_mode, vd->fmt.orientation ) != VLC_SUCCESS) {
msg_Err(vd, "Could not Create the main quad picture.");
return NULL;
}
@@ -2234,7 +2235,78 @@ static void Direct3D11DestroyPool(vout_display_t *vd)
sys->sys.pool = NULL;
}
-static void SetupQuadFlat(d3d_vertex_t *dst_data, const video_format_t *fmt, d3d_quad_t *quad, WORD *triangle_pos)
+/**
+ * Compute the vertex ordering needed to rotate the video. Without
+ * rotation, the vertices of the rectangle are defined in a clockwise
+ * order. This function computes a remapping of the coordinates to
+ * implement the rotation, given fixed texture coordinates.
+ * The unrotated order is the following:
+ * 0--1
+ * | |
+ * 3--2
+ * For a 180 degrees rotation it should like this:
+ * 2--3
+ * | |
+ * 1--0
+ * Vertex 0 should be assigned coordinates at index 2 from the
+ * unrotated order and so on, thus yielding order: 2 3 0 1.
+ */
+static void orientationVertexOrder(video_orientation_t orientation, int vertex_order[static 4])
+{
+ switch (orientation) {
+ case ORIENT_ROTATED_90:
+ vertex_order[0] = 3;
+ vertex_order[1] = 0;
+ vertex_order[2] = 1;
+ vertex_order[3] = 2;
+ break;
+ case ORIENT_ROTATED_270:
+ vertex_order[0] = 1;
+ vertex_order[1] = 2;
+ vertex_order[2] = 3;
+ vertex_order[3] = 0;
+ break;
+ case ORIENT_ROTATED_180:
+ vertex_order[0] = 2;
+ vertex_order[1] = 3;
+ vertex_order[2] = 0;
+ vertex_order[3] = 1;
+ break;
+ case ORIENT_TRANSPOSED:
+ vertex_order[0] = 2;
+ vertex_order[1] = 1;
+ vertex_order[2] = 0;
+ vertex_order[3] = 3;
+ break;
+ case ORIENT_HFLIPPED:
+ vertex_order[0] = 3;
+ vertex_order[1] = 2;
+ vertex_order[2] = 1;
+ vertex_order[3] = 0;
+ break;
+ case ORIENT_VFLIPPED:
+ vertex_order[0] = 1;
+ vertex_order[1] = 0;
+ vertex_order[2] = 3;
+ vertex_order[3] = 2;
+ break;
+ case ORIENT_ANTI_TRANSPOSED: /* transpose + vflip */
+ vertex_order[0] = 1;
+ vertex_order[1] = 2;
+ vertex_order[2] = 3;
+ vertex_order[3] = 0;
+ break;
+ default:
+ vertex_order[0] = 0;
+ vertex_order[1] = 1;
+ vertex_order[2] = 2;
+ vertex_order[3] = 3;
+ break;
+ }
+}
+
+static void SetupQuadFlat(d3d_vertex_t *dst_data, const video_format_t *fmt,
+ d3d_quad_t *quad, WORD *triangle_pos, video_orientation_t orientation)
{
unsigned int dst_width = fmt->i_visible_width;
unsigned int dst_height = fmt->i_visible_height;
@@ -2256,30 +2328,38 @@ static void SetupQuadFlat(d3d_vertex_t *dst_data, const video_format_t *fmt, d3d
float top = (float) (2*src_x + dst_height) / (float) dst_height;
float bottom = -(float) (2*src_height - dst_height - 2*src_y) / (float) dst_height;
+ const float vertices_coords[4][2] = {
+ { left, bottom },
+ { right, bottom },
+ { right, top },
+ { left, top },
+ };
+
+ /* Compute index remapping necessary to implement the rotation. */
+ int vertex_order[4];
+ orientationVertexOrder(orientation, vertex_order);
+
+ for (int i = 0; i < 4; ++i) {
+ dst_data[i].position.x = vertices_coords[vertex_order[i]][0];
+ dst_data[i].position.y = vertices_coords[vertex_order[i]][1];
+ }
+
// bottom left
- dst_data[0].position.x = left;
- dst_data[0].position.y = bottom;
dst_data[0].position.z = 0.0f;
dst_data[0].texture.x = 0.0f;
dst_data[0].texture.y = 1.0f;
// bottom right
- dst_data[1].position.x = right;
- dst_data[1].position.y = bottom;
dst_data[1].position.z = 0.0f;
dst_data[1].texture.x = 1.0f;
dst_data[1].texture.y = 1.0f;
// top right
- dst_data[2].position.x = right;
- dst_data[2].position.y = top;
dst_data[2].position.z = 0.0f;
dst_data[2].texture.x = 1.0f;
dst_data[2].texture.y = 0.0f;
// top left
- dst_data[3].position.x = left;
- dst_data[3].position.y = top;
dst_data[3].position.z = 0.0f;
dst_data[3].texture.x = 0.0f;
dst_data[3].texture.y = 0.0f;
@@ -2343,7 +2423,8 @@ static void SetupQuadSphere(d3d_vertex_t *dst_data, WORD *triangle_pos)
}
}
-static bool AllocQuadVertices(vout_display_t *vd, d3d_quad_t *quad, const video_format_t *fmt, video_projection_mode_t projection)
+static bool AllocQuadVertices(vout_display_t *vd, d3d_quad_t *quad, const video_format_t *fmt,
+ video_projection_mode_t projection, video_orientation_t orientation)
{
HRESULT hr;
D3D11_MAPPED_SUBRESOURCE mappedResource;
@@ -2410,7 +2491,7 @@ static bool AllocQuadVertices(vout_display_t *vd, d3d_quad_t *quad, const video_
WORD *triangle_pos = mappedResource.pData;
if ( projection == PROJECTION_MODE_RECTANGULAR )
- SetupQuadFlat(dst_data, fmt, quad, triangle_pos);
+ SetupQuadFlat(dst_data, fmt, quad, triangle_pos, orientation);
else
SetupQuadSphere(dst_data, triangle_pos);
@@ -2422,7 +2503,7 @@ static bool AllocQuadVertices(vout_display_t *vd, d3d_quad_t *quad, const video_
static int SetupQuad(vout_display_t *vd, const video_format_t *fmt, d3d_quad_t *quad,
const d3d_format_t *cfg, ID3D11PixelShader *d3dpixelShader,
- video_projection_mode_t projection)
+ video_projection_mode_t projection, video_orientation_t orientation)
{
vout_display_sys_t *sys = vd->sys;
HRESULT hr;
@@ -2568,7 +2649,7 @@ static int SetupQuad(vout_display_t *vd, const video_format_t *fmt, d3d_quad_t *
quad->picSys.context = sys->d3dcontext;
ID3D11DeviceContext_AddRef(quad->picSys.context);
- if (!AllocQuadVertices(vd, quad, fmt, projection))
+ if (!AllocQuadVertices(vd, quad, fmt, projection, orientation))
goto error;
quad->d3dpixelShader = d3dpixelShader;
@@ -2773,7 +2854,7 @@ static int Direct3D11MapSubpicture(vout_display_t *vd, int *subpicture_region_co
d3dquad->i_width = r->fmt.i_width;
d3dquad->i_height = r->fmt.i_height;
err = SetupQuad( vd, &r->fmt, d3dquad, sys->d3dregion_format, sys->pSPUPixelShader,
- PROJECTION_MODE_RECTANGULAR );
+ PROJECTION_MODE_RECTANGULAR, ORIENT_NORMAL );
if (err != VLC_SUCCESS) {
msg_Err(vd, "Failed to create %dx%d quad for OSD",
r->fmt.i_visible_width, r->fmt.i_visible_height);
More information about the vlc-commits
mailing list