[vlc-commits] Implemented subpicture direct rendering in opengl.
Laurent Aimar
git at videolan.org
Mon May 30 22:28:18 CEST 2011
vlc | branch: master | Laurent Aimar <fenrir at videolan.org> | Mon May 30 21:55:43 2011 +0200| [0a5dcfefe87ade9c9f903ada0ab4df5ccbfcb205] | committer: Laurent Aimar
Implemented subpicture direct rendering in opengl.
It is enabled only on linux/win32 when opengl ES is not used and when
non power of 2 textures are supported.
Only RGBA colorspace is supported for the subpicture.
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=0a5dcfefe87ade9c9f903ada0ab4df5ccbfcb205
---
modules/video_output/opengl.c | 112 +++++++++++++++++++++++++++++++++++++++++
1 files changed, 112 insertions(+), 0 deletions(-)
diff --git a/modules/video_output/opengl.c b/modules/video_output/opengl.c
index 26cd383..4900395 100644
--- a/modules/video_output/opengl.c
+++ b/modules/video_output/opengl.c
@@ -30,6 +30,7 @@
#include <vlc_common.h>
#include <vlc_picture_pool.h>
+#include <vlc_subpicture.h>
#include <vlc_opengl.h>
#include "opengl.h"
@@ -73,6 +74,26 @@
# define VLCGL_PICTURE_MAX 128
#endif
+static const vlc_fourcc_t gl_subpicture_chromas[] = {
+ VLC_CODEC_RGBA,
+ 0
+};
+
+typedef struct {
+ GLuint texture;
+ unsigned format;
+ unsigned type;
+ unsigned width;
+ unsigned height;
+
+ float alpha;
+
+ float top;
+ float left;
+ float bottom;
+ float right;
+} gl_region_t;
+
struct vout_display_opengl_t {
vlc_gl_t *gl;
@@ -88,6 +109,10 @@ struct vout_display_opengl_t {
GLuint texture[VLCGL_TEXTURE_COUNT][PICTURE_PLANE_MAX];
+ int region_count;
+ gl_region_t *region;
+
+
picture_pool_t *pool;
GLuint program;
@@ -334,11 +359,17 @@ vout_display_opengl_t *vout_display_opengl_New(video_format_t *fmt,
for (int j = 0; j < PICTURE_PLANE_MAX; j++)
vgl->texture[i][j] = 0;
}
+ vgl->region_count = 0;
+ vgl->region = NULL;
vgl->pool = NULL;
*fmt = vgl->fmt;
if (subpicture_chromas) {
*subpicture_chromas = NULL;
+#if !defined(MACOS_OPENGL) && !USE_OPENGL_ES
+ if (supports_npot)
+ *subpicture_chromas = gl_subpicture_chromas;
+#endif
}
return vgl;
}
@@ -532,6 +563,54 @@ int vout_display_opengl_Prepare(vout_display_opengl_t *vgl,
}
#endif
+ for (int i = 0; i < vgl->region_count; i++) {
+ glDeleteTextures(1, &vgl->region[i].texture);
+ }
+ free(vgl->region);
+ vgl->region_count = 0;
+ vgl->region = NULL;
+
+ if (subpicture) {
+
+ int count = 0;
+ for (subpicture_region_t *r = subpicture->p_region; r; r = r->p_next)
+ count++;
+
+ vgl->region_count = count;
+ vgl->region = calloc(count, sizeof(*vgl->region));
+
+ if (vgl->chroma->plane_count > 1)
+ vgl->ActiveTextureARB(GL_TEXTURE0_ARB + 0);
+ int i = 0;
+ for (subpicture_region_t *r = subpicture->p_region; r; r = r->p_next, i++) {
+ gl_region_t *glr = &vgl->region[i];
+
+ glr->format = GL_RGBA;
+ glr->type = GL_UNSIGNED_BYTE;
+ glr->width = r->fmt.i_visible_width;
+ glr->height = r->fmt.i_visible_height;
+ glr->alpha = (float)subpicture->i_alpha * r->i_alpha / 255 / 255;
+ glr->left = 2.0 * (r->i_x ) / subpicture->i_original_picture_width - 1.0;
+ glr->top = -2.0 * (r->i_y ) / subpicture->i_original_picture_height + 1.0;
+ glr->right = 2.0 * (r->i_x + r->fmt.i_visible_width ) / subpicture->i_original_picture_width - 1.0;
+ glr->bottom = -2.0 * (r->i_y + r->fmt.i_visible_height) / subpicture->i_original_picture_height + 1.0;
+
+ glGenTextures(1, &glr->texture);
+ glBindTexture(GL_TEXTURE_2D, glr->texture);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_PRIORITY, 1.0);
+ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ /* TODO set GL_UNPACK_ALIGNMENT */
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, r->p_picture->p->i_pitch / r->p_picture->p->i_pixel_pitch);
+ glTexImage2D(GL_TEXTURE_2D, 0, glr->format,
+ glr->width, glr->height, 0, glr->format, glr->type,
+ r->p_picture->p->p_pixels);
+ }
+ }
+
vlc_gl_Unlock(vgl->gl);
VLC_UNUSED(subpicture);
return VLC_SUCCESS;
@@ -639,6 +718,39 @@ int vout_display_opengl_Display(vout_display_opengl_t *vgl,
else
glDisable(vgl->tex_target);
+#if !USE_OPENGL_ES
+ if (vgl->chroma->plane_count > 1)
+ vgl->ActiveTextureARB(GL_TEXTURE0_ARB + 0);
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ for (int i = 0; i < vgl->region_count; i++) {
+ gl_region_t *glr = &vgl->region[i];
+
+ glBindTexture(GL_TEXTURE_2D, glr->texture);
+
+ glBegin(GL_POLYGON);
+
+ glColor4f(1.0, 1.0, 1.0, glr->alpha);
+
+ glTexCoord2f(0.0, 0.0);
+ glVertex2f(glr->left, glr->top);
+
+ glTexCoord2f(1.0, 0.0);
+ glVertex2f(glr->right, glr->top);
+
+ glTexCoord2f(1.0, 1.0);
+ glVertex2f(glr->right, glr->bottom);
+
+ glTexCoord2f(0.0, 1.0);
+ glVertex2f(glr->left, glr->bottom);
+
+ glEnd();
+ }
+ glDisable(GL_BLEND);
+ glDisable(GL_TEXTURE_2D);
+#endif
+
vlc_gl_Swap(vgl->gl);
vlc_gl_Unlock(vgl->gl);
More information about the vlc-commits
mailing list