[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