[vlc-devel] [PATCH] Direct3D: handle rotated movies.

Felix Abecassis felix.abecassis at gmail.com
Fri Mar 28 13:48:30 CET 2014


---
 modules/video_output/msw/direct3d.c |  103 +++++++++++++++++++++++++++++++----
 1 file changed, 92 insertions(+), 11 deletions(-)

diff --git a/modules/video_output/msw/direct3d.c b/modules/video_output/msw/direct3d.c
index 059c6d6..fc959fc 100644
--- a/modules/video_output/msw/direct3d.c
+++ b/modules/video_output/msw/direct3d.c
@@ -1316,31 +1316,112 @@ static void Direct3DDestroyShaders(vout_display_t *vd)
     sys->d3dx_shader = NULL;
 }
 
+/**
+ * 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] = 1;
+            vertex_order[1] = 2;
+            vertex_order[2] = 3;
+            vertex_order[3] = 0;
+            break;
+        case ORIENT_ROTATED_270:
+            vertex_order[0] = 3;
+            vertex_order[1] = 0;
+            vertex_order[2] = 1;
+            vertex_order[3] = 2;
+            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] = 0;
+            vertex_order[1] = 3;
+            vertex_order[2] = 2;
+            vertex_order[3] = 1;
+            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 Direct3DSetupVertices(CUSTOMVERTEX *vertices,
                                   const RECT src_full,
                                   const RECT src_crop,
                                   const RECT dst,
-                                  int alpha)
+                                  int alpha,
+                                  video_orientation_t orientation)
 {
     const float src_full_width  = src_full.right  - src_full.left;
     const float src_full_height = src_full.bottom - src_full.top;
-    vertices[0].x  = dst.left;
-    vertices[0].y  = dst.top;
+
+    /* Vertices of the dst rectangle in the unrotated (clockwise) order. */
+    const int vertices_coords[4][2] = {
+        { dst.left,  dst.top    },
+        { dst.right, dst.top    },
+        { dst.right, dst.bottom },
+        { dst.left,  dst.bottom },
+    };
+
+    /* Compute index remapping necessary to implement the rotation. */
+    int vertex_order[4];
+    orientationVertexOrder(orientation, vertex_order);
+
+    for (int i = 0; i < 4; ++i) {
+        vertices[i].x  = vertices_coords[vertex_order[i]][0];
+        vertices[i].y  = vertices_coords[vertex_order[i]][1];
+    }
+
     vertices[0].tu = src_crop.left / src_full_width;
     vertices[0].tv = src_crop.top  / src_full_height;
 
-    vertices[1].x  = dst.right;
-    vertices[1].y  = dst.top;
     vertices[1].tu = src_crop.right / src_full_width;
     vertices[1].tv = src_crop.top   / src_full_height;
 
-    vertices[2].x  = dst.right;
-    vertices[2].y  = dst.bottom;
     vertices[2].tu = src_crop.right  / src_full_width;
     vertices[2].tv = src_crop.bottom / src_full_height;
 
-    vertices[3].x  = dst.left;
-    vertices[3].y  = dst.bottom;
     vertices[3].tu = src_crop.left   / src_full_width;
     vertices[3].tv = src_crop.bottom / src_full_height;
 
@@ -1393,7 +1474,7 @@ static int Direct3DImportPicture(vout_display_t *vd,
     Direct3DSetupVertices(region->vertex,
                           vd->sys->rect_src,
                           vd->sys->rect_src_clipped,
-                          vd->sys->rect_dest_clipped, 255);
+                          vd->sys->rect_dest_clipped, 255, vd->fmt.orientation);
     return VLC_SUCCESS;
 }
 
@@ -1516,7 +1597,7 @@ static void Direct3DImportSubpicture(vout_display_t *vd,
         dst.bottom = dst.top  + scale_h * r->fmt.i_visible_height,
         Direct3DSetupVertices(d3dr->vertex,
                               src, src, dst,
-                              subpicture->i_alpha * r->i_alpha / 255);
+                              subpicture->i_alpha * r->i_alpha / 255, ORIENT_NORMAL);
     }
 }
 
-- 
1.7.10.4




More information about the vlc-devel mailing list