[vlc-devel] [PATCH 6/7] Support for rotated MP4 Movies (bug #2882)

Matthias Keiser matthias at tristan-inc.com
Mon Feb 17 01:35:38 CET 2014


---
 modules/video_output/opengl.c | 94 +++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 90 insertions(+), 4 deletions(-)

diff --git a/modules/video_output/opengl.c b/modules/video_output/opengl.c
index 33db19d..93e5578 100644
--- a/modules/video_output/opengl.c
+++ b/modules/video_output/opengl.c
@@ -35,6 +35,7 @@
 #include <vlc_opengl.h>
 
 #include "opengl.h"
+#include "math.h"
 
 #ifndef GL_CLAMP_TO_EDGE
 # define GL_CLAMP_TO_EDGE 0x812F
@@ -49,6 +50,7 @@
 #   define PFNGLGETATTRIBLOCATIONPROC        typeof(glGetAttribLocation)*
 #   define PFNGLVERTEXATTRIBPOINTERPROC      typeof(glVertexAttribPointer)*
 #   define PFNGLENABLEVERTEXATTRIBARRAYPROC  typeof(glEnableVertexAttribArray)*
+#   define PFNGLUNIFORMMATRIX4FVPROC         typeof(glUniformMatrix4fv)*
 #   define PFNGLUNIFORM4FVPROC               typeof(glUniform4fv)*
 #   define PFNGLUNIFORM4FPROC                typeof(glUniform4f)*
 #   define PFNGLUNIFORM1IPROC                typeof(glUniform1i)*
@@ -146,9 +148,10 @@ struct vout_display_opengl_t {
     PFNGLVERTEXATTRIBPOINTERPROC     VertexAttribPointer;
     PFNGLENABLEVERTEXATTRIBARRAYPROC EnableVertexAttribArray;
 
-    PFNGLUNIFORM4FVPROC   Uniform4fv;
-    PFNGLUNIFORM4FPROC    Uniform4f;
-    PFNGLUNIFORM1IPROC    Uniform1i;
+    PFNGLUNIFORMMATRIX4FVPROC   UniformMatrix4fv;
+    PFNGLUNIFORM4FVPROC         Uniform4fv;
+    PFNGLUNIFORM4FPROC          Uniform4f;
+    PFNGLUNIFORM1IPROC          Uniform1i;
 
     /* Shader command */
     PFNGLCREATESHADERPROC CreateShader;
@@ -222,11 +225,13 @@ static void BuildVertexShader(vout_display_opengl_t *vgl,
         "varying vec4 TexCoord0,TexCoord1, TexCoord2;"
         "attribute vec4 MultiTexCoord0,MultiTexCoord1,MultiTexCoord2;"
         "attribute vec4 VertexPosition;"
+        "uniform float zRotation;"
+        "uniform mat4 RotationMatrix = mat4(1.0);" //Initialize to identity transform.
         "void main() {"
         " TexCoord0 = MultiTexCoord0;"
         " TexCoord1 = MultiTexCoord1;"
         " TexCoord2 = MultiTexCoord2;"
-        " gl_Position = VertexPosition;"
+        " gl_Position = vec4(RotationMatrix * VertexPosition);"
         "}";
 
     *shader = vgl->CreateShader(GL_VERTEX_SHADER);
@@ -432,6 +437,7 @@ vout_display_opengl_t *vout_display_opengl_New(video_format_t *fmt,
     vgl->GetAttribLocation  = glGetAttribLocation;
     vgl->VertexAttribPointer= glVertexAttribPointer;
     vgl->EnableVertexAttribArray = glEnableVertexAttribArray;
+    vgl->UniformMatrix4fv = glUniformMatrix4fv;
     vgl->Uniform4fv    = glUniform4fv;
     vgl->Uniform4f     = glUniform4f;
     vgl->Uniform1i     = glUniform1i;
@@ -458,6 +464,7 @@ vout_display_opengl_t *vout_display_opengl_New(video_format_t *fmt,
     vgl->GetAttribLocation  = (PFNGLGETATTRIBLOCATIONPROC)vlc_gl_GetProcAddress(vgl->gl, "glGetAttribLocation");
     vgl->VertexAttribPointer= (PFNGLVERTEXATTRIBPOINTERPROC)vlc_gl_GetProcAddress(vgl->gl, "glVertexAttribPointer");
     vgl->EnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)vlc_gl_GetProcAddress(vgl->gl, "glEnableVertexAttribArray");
+    vgl->UniformMatrix4fv   = (PFNGLUNIFORMMATRIX4FVPROC)vlc_gl_GetProcAddress(vgl->gl,"glUniformMatrix4fv");
     vgl->Uniform4fv    = (PFNGLUNIFORM4FVPROC)vlc_gl_GetProcAddress(vgl->gl,"glUniform4fv");
     vgl->Uniform4f     = (PFNGLUNIFORM4FPROC)vlc_gl_GetProcAddress(vgl->gl,"glUniform4f");
     vgl->Uniform1i     = (PFNGLUNIFORM1IPROC)vlc_gl_GetProcAddress(vgl->gl,"glUniform1i");
@@ -947,6 +954,65 @@ int vout_display_opengl_Prepare(vout_display_opengl_t *vgl,
     return VLC_SUCCESS;
 }
 
+static void orientationTransformMatrix(float matrix[static 16], video_orientation_t orientation) {
+
+    static const float identity[] = {
+        1.0f, 0.0f, 0.0f, 0.0f,
+        0.0f, 1.0f, 0.0f, 0.0f,
+        0.0f, 0.0f, 1.0f, 0.0f,
+        0.0f, 0.0f, 0.0f, 1.0f
+    };
+
+    memcpy(matrix, identity, sizeof(identity));
+
+    float angle = 0.0;
+    bool rotate = false;
+
+    switch (orientation) {
+
+        case ORIENT_ROTATED_90:
+            angle = M_PI_2;
+            rotate = true;
+            break;
+        case ORIENT_ROTATED_180:
+            angle = M_PI;
+            rotate = true;
+            break;
+        case ORIENT_ROTATED_270:
+            angle = -M_PI_2;
+            rotate = true;
+            break;
+        case ORIENT_HFLIPPED:
+            matrix[0 * 4 + 0] = -1;
+            break;
+        case ORIENT_VFLIPPED:
+            matrix[1 * 4 + 1] = -1;
+            break;
+        case ORIENT_TRANSPOSED:
+            matrix[0 * 4 + 0] = 0;
+            matrix[0 * 4 + 1] = -1;
+            matrix[1 * 4 + 0] = -1;
+            matrix[1 * 4 + 1] = 0;
+            break;
+        case ORIENT_ANTI_TRANSPOSED:
+            matrix[0 * 4 + 0] = 0;
+            matrix[0 * 4 + 1] = 1;
+            matrix[1 * 4 + 0] = 1;
+            matrix[1 * 4 + 1] = 0;
+            break;
+        default:
+            break;
+    }
+
+    if(rotate) {
+
+        matrix[0 * 4 + 0] = cosf(angle);
+        matrix[0 * 4 + 1] = -sinf(angle);
+        matrix[1 * 4 + 0] = sinf(angle);
+        matrix[1 * 4 + 1] = cosf(angle);
+    }
+}
+
 #ifdef SUPPORTS_FIXED_PIPELINE
 static void DrawWithoutShaders(vout_display_opengl_t *vgl,
                                float *left, float *top, float *right, float *bottom)
@@ -965,6 +1031,13 @@ static void DrawWithoutShaders(vout_display_opengl_t *vgl,
         right[0], top[0]
     };
 
+    float transformMatrix[16];
+    orientationTransformMatrix(transformMatrix, vgl->fmt.orientation);
+
+    glPushMatrix();
+    glMatrixMode(GL_MODELVIEW);
+    glLoadMatrixf(transformMatrix);
+
     glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
     glEnable(vgl->tex_target);
     glActiveTexture(GL_TEXTURE0 + 0);
@@ -983,6 +1056,9 @@ static void DrawWithoutShaders(vout_display_opengl_t *vgl,
     glDisableClientState(GL_TEXTURE_COORD_ARRAY);
     glDisableClientState(GL_VERTEX_ARRAY);
     glDisable(vgl->tex_target);
+
+    glPopMatrix();
+
 }
 #endif
 
@@ -1030,11 +1106,20 @@ static void DrawWithShaders(vout_display_opengl_t *vgl,
         vgl->EnableVertexAttribArray(vgl->GetAttribLocation(vgl->program[program], attribute));
         vgl->VertexAttribPointer(vgl->GetAttribLocation(vgl->program[program], attribute), 2, GL_FLOAT, 0, 0, textureCoord);
     }
+
     glActiveTexture(GL_TEXTURE0 + 0);
     glClientActiveTexture(GL_TEXTURE0 + 0);
     vgl->EnableVertexAttribArray(vgl->GetAttribLocation(vgl->program[program], "VertexPosition"));
     vgl->VertexAttribPointer(vgl->GetAttribLocation(vgl->program[program], "VertexPosition"), 2, GL_FLOAT, 0, 0, vertexCoord);
 
+    if (vgl->fmt.orientation != ORIENT_NORMAL) {
+
+        float transformMatrix[16];
+        orientationTransformMatrix(transformMatrix, vgl->fmt.orientation);
+        vgl->EnableVertexAttribArray(vgl->GetUniformLocation(vgl->program[program], "RotationMatrix"));
+        vgl->UniformMatrix4fv(vgl->GetUniformLocation(vgl->program[program], "RotationMatrix"), 1, GL_FALSE, transformMatrix);
+    }
+
     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
 }
 #endif
@@ -1138,6 +1223,7 @@ int vout_display_opengl_Display(vout_display_opengl_t *vgl,
             vgl->VertexAttribPointer(vgl->GetAttribLocation(vgl->program[1], "MultiTexCoord0"), 2, GL_FLOAT, 0, 0, textureCoord);
             vgl->EnableVertexAttribArray(vgl->GetAttribLocation(vgl->program[1], "VertexPosition"));
             vgl->VertexAttribPointer(vgl->GetAttribLocation(vgl->program[1], "VertexPosition"), 2, GL_FLOAT, 0, 0, vertexCoord);
+            /* We don't have to set "RotationMatrix" here, because subtitles have the correct orientation and size. */
 #endif
         } else {
 #ifdef SUPPORTS_FIXED_PIPELINE
-- 
1.8.3.4 (Apple Git-47)





More information about the vlc-devel mailing list