[vlc-devel] [PATCH 1/5] Make opengl.c handle movie rotations.
Matthias Keiser
matthias at tristan-inc.com
Sun Mar 16 22:16:16 CET 2014
Am 15.03.2014 um 09:33 schrieb Rémi Denis-Courmont <remi at remlab.net>:
> Le vendredi 14 mars 2014, 01:00:07 Matthias Keiser a écrit :
>> ---
>> modules/video_output/opengl.c | 102
>> ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 98
>> insertions(+), 4 deletions(-)
>
> Trying with 90 degrees rotation...
>
> With the NVIDIA driver, I still get an immediate segmentation fault. With the
> Mesa R300 driver, the picture is corrupted, partly rotated, partly not.
Ok, this is awkward because I can't reproduce it myself, but if we are lucky this fixes it:
---
modules/video_output/opengl.c | 104 ++++++++++++++++++++++++++++++++++++++++--
1 file changed, 99 insertions(+), 5 deletions(-)
diff --git a/modules/video_output/opengl.c b/modules/video_output/opengl.c
index 33db19d..4359474 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;
@@ -221,12 +224,13 @@ static void BuildVertexShader(vout_display_opengl_t *vgl,
PRECISION
"varying vec4 TexCoord0,TexCoord1, TexCoord2;"
"attribute vec4 MultiTexCoord0,MultiTexCoord1,MultiTexCoord2;"
- "attribute vec4 VertexPosition;"
+ "attribute vec2 VertexPosition;"
+ "uniform mat4 RotationMatrix;"
"void main() {"
" TexCoord0 = MultiTexCoord0;"
" TexCoord1 = MultiTexCoord1;"
" TexCoord2 = MultiTexCoord2;"
- " gl_Position = VertexPosition;"
+ " gl_Position = RotationMatrix * vec4(VertexPosition, 0.0, 1.0);"
"}";
*shader = vgl->CreateShader(GL_VERTEX_SHADER);
@@ -432,6 +436,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 +463,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 +953,76 @@ int vout_display_opengl_Prepare(vout_display_opengl_t *vgl,
return VLC_SUCCESS;
}
+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
+};
+
+static void orientationTransformMatrix(float matrix[static 16], video_orientation_t orientation) {
+
+ memcpy(matrix, identity, sizeof(identity));
+
+ const int k_cos_pi = -1;
+ const int k_cos_pi_2 = 0;
+ const int k_cos_n_pi_2 = 0;
+
+ const int k_sin_pi = 0;
+ const int k_sin_pi_2 = 1;
+ const int k_sin_n_pi_2 = -1;
+
+ bool rotate = false;
+ int cos = 0, sin = 0;
+
+ switch (orientation) {
+
+ case ORIENT_ROTATED_90:
+ cos = k_cos_pi_2;
+ sin = k_sin_pi_2;
+ rotate = true;
+ break;
+ case ORIENT_ROTATED_180:
+ cos = k_cos_pi;
+ sin = k_sin_pi;
+ rotate = true;
+ break;
+ case ORIENT_ROTATED_270:
+ cos = k_cos_n_pi_2;
+ sin = k_sin_n_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] = cos;
+ matrix[0 * 4 + 1] = -sin;
+ matrix[1 * 4 + 0] = sin;
+ matrix[1 * 4 + 1] = cos;
+ }
+}
+
#ifdef SUPPORTS_FIXED_PIPELINE
static void DrawWithoutShaders(vout_display_opengl_t *vgl,
float *left, float *top, float *right, float *bottom)
@@ -965,6 +1041,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 +1066,9 @@ static void DrawWithoutShaders(vout_display_opengl_t *vgl,
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
glDisable(vgl->tex_target);
+
+ glPopMatrix();
+
}
#endif
@@ -1035,6 +1121,11 @@ static void DrawWithShaders(vout_display_opengl_t *vgl,
vgl->EnableVertexAttribArray(vgl->GetAttribLocation(vgl->program[program], "VertexPosition"));
vgl->VertexAttribPointer(vgl->GetAttribLocation(vgl->program[program], "VertexPosition"), 2, GL_FLOAT, 0, 0, vertexCoord);
+ 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 +1229,9 @@ 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);
+ //Subpictures have the correct orientation:
+ vgl->EnableVertexAttribArray(vgl->GetUniformLocation(vgl->program[1], "RotationMatrix"));
+ vgl->UniformMatrix4fv(vgl->GetUniformLocation(vgl->program[1], "RotationMatrix"), 1, GL_FALSE, identity);
#endif
} else {
#ifdef SUPPORTS_FIXED_PIPELINE
--
1.8.3.4 (Apple Git-47)
More information about the vlc-devel
mailing list