[vlc-devel] [RFC 1/1] opengl: subtitles outside the video

Salah-Eddin Shaban salah at videolan.org
Fri Mar 3 13:29:56 CET 2017


---
 modules/video_output/caopengllayer.m      |  2 +-
 modules/video_output/ios.m                |  2 +-
 modules/video_output/macosx.m             |  4 +--
 modules/video_output/opengl/display.c     | 15 ++++----
 modules/video_output/opengl/vout_helper.c | 58 +++++++++++++++++++++++--------
 modules/video_output/opengl/vout_helper.h |  3 +-
 modules/video_output/win32/glwin32.c      |  2 +-
 7 files changed, 59 insertions(+), 27 deletions(-)

diff --git a/modules/video_output/caopengllayer.m b/modules/video_output/caopengllayer.m
index ed77118..f3f3016 100644
--- a/modules/video_output/caopengllayer.m
+++ b/modules/video_output/caopengllayer.m
@@ -548,7 +548,7 @@ static void *OurGetProcAddress (vlc_gl_t *gl, const char *name)
     glViewport (sys->place.x, bounds.size.height - (sys->place.y + sys->place.height), sys->place.width, sys->place.height);
 
     // flush is also done by this method, no need to call super
-    vout_display_opengl_Display (sys->vgl, &_voutDisplay->source);
+    vout_display_opengl_Display (sys->vgl, _voutDisplay);
     sys->b_frame_available = NO;
 }
 
diff --git a/modules/video_output/ios.m b/modules/video_output/ios.m
index 7777c2c..ca51976 100644
--- a/modules/video_output/ios.m
+++ b/modules/video_output/ios.m
@@ -364,7 +364,7 @@ static void PictureDisplay(vout_display_t *vd, picture_t *pic, subpicture_t *sub
     @synchronized (sys->glESView) {
         if (likely([sys->glESView isAppActive])) {
             vlc_gl_MakeCurrent(sys->gl);
-            vout_display_opengl_Display(sys->vgl, &vd->source);
+            vout_display_opengl_Display(sys->vgl, vd);
             vlc_gl_ReleaseCurrent(sys->gl);
         }
     }
diff --git a/modules/video_output/macosx.m b/modules/video_output/macosx.m
index 03086fa..8a051c2 100644
--- a/modules/video_output/macosx.m
+++ b/modules/video_output/macosx.m
@@ -397,7 +397,7 @@ static void PictureDisplay (vout_display_t *vd, picture_t *pic, subpicture_t *su
     vout_display_sys_t *sys = vd->sys;
     [sys->glView setVoutFlushing:YES];
     vlc_gl_MakeCurrent(sys->gl);
-    vout_display_opengl_Display (sys->vgl, &vd->source);
+    vout_display_opengl_Display (sys->vgl, vd);
     vlc_gl_ReleaseCurrent(sys->gl);
     [sys->glView setVoutFlushing:NO];
     picture_Release (pic);
@@ -697,7 +697,7 @@ static void OpenglSwap (vlc_gl_t *gl)
 
     if (hasFirstFrame)
         // This will lock gl.
-        vout_display_opengl_Display (vd->sys->vgl, &vd->source);
+        vout_display_opengl_Display (vd->sys->vgl, vd);
     else
         glClear (GL_COLOR_BUFFER_BIT);
 }
diff --git a/modules/video_output/opengl/display.c b/modules/video_output/opengl/display.c
index 281ed71..24f6bc6 100644
--- a/modules/video_output/opengl/display.c
+++ b/modules/video_output/opengl/display.c
@@ -125,6 +125,7 @@ static int Open (vlc_object_t *obj)
     vd->sys = sys;
     vd->info.has_pictures_invalid = false;
     vd->info.subpicture_chromas = spu_chromas;
+    vd->info.scale_spu_to_display = true;
     vd->pool = Pool;
     vd->prepare = PictureRender;
     vd->display = PictureDisplay;
@@ -190,7 +191,7 @@ static void PictureDisplay (vout_display_t *vd, picture_t *pic, subpicture_t *su
     vout_display_sys_t *sys = vd->sys;
 
     vlc_gl_MakeCurrent (sys->gl);
-    vout_display_opengl_Display (sys->vgl, &vd->source);
+    vout_display_opengl_Display (sys->vgl, vd);
     vlc_gl_ReleaseCurrent (sys->gl);
 
     picture_Release (pic);
@@ -220,10 +221,11 @@ static int Control (vout_display_t *vd, int query, va_list ap)
         vout_display_place_t place;
 
         vout_display_PlacePicture (&place, src, c, false);
-        vlc_gl_Resize (sys->gl, place.width, place.height);
+        vlc_gl_Resize (sys->gl, c->display.width, c->display.height);
         vlc_gl_MakeCurrent (sys->gl);
-        vout_display_opengl_SetWindowAspectRatio(sys->vgl, (float)place.width / place.height);
-        glViewport (place.x, place.y, place.width, place.height);
+        vout_display_opengl_SetWindowAspectRatio(sys->vgl,
+                (float)c->display.width / c->display.height);
+        glViewport (0, 0, c->display.width, c->display.height);
         vlc_gl_ReleaseCurrent (sys->gl);
         return VLC_SUCCESS;
       }
@@ -237,8 +239,9 @@ static int Control (vout_display_t *vd, int query, va_list ap)
 
         vout_display_PlacePicture (&place, src, cfg, false);
         vlc_gl_MakeCurrent (sys->gl);
-        vout_display_opengl_SetWindowAspectRatio(sys->vgl, (float)place.width / place.height);
-        glViewport (place.x, place.y, place.width, place.height);
+        vout_display_opengl_SetWindowAspectRatio(sys->vgl,
+                (float)cfg->display.width / cfg->display.height);
+        glViewport (0, 0, cfg->display.width, cfg->display.height);
         vlc_gl_ReleaseCurrent (sys->gl);
         return VLC_SUCCESS;
       }
diff --git a/modules/video_output/opengl/vout_helper.c b/modules/video_output/opengl/vout_helper.c
index 39c2eb7..cd46d30 100644
--- a/modules/video_output/opengl/vout_helper.c
+++ b/modules/video_output/opengl/vout_helper.c
@@ -141,6 +141,9 @@ struct vout_display_opengl_t {
         unsigned int i_visible_height;
     } last_source;
 
+    unsigned int i_last_display_width;
+    unsigned int i_last_display_height;
+
     /* Non-power-of-2 texture size support */
     bool supports_npot;
 
@@ -1032,8 +1035,11 @@ static int BuildSphere(unsigned nbPlanes,
                         GLfloat **vertexCoord, GLfloat **textureCoord, unsigned *nbVertices,
                         GLushort **indices, unsigned *nbIndices,
                         const float *left, const float *top,
-                        const float *right, const float *bottom)
+                        const float *right, const float *bottom,
+                        const vout_display_t *vd)
 {
+    VLC_UNUSED(vd);
+
     unsigned nbLatBands = 128;
     unsigned nbLonBands = 128;
 
@@ -1118,8 +1124,11 @@ static int BuildCube(unsigned nbPlanes,
                      GLfloat **vertexCoord, GLfloat **textureCoord, unsigned *nbVertices,
                      GLushort **indices, unsigned *nbIndices,
                      const float *left, const float *top,
-                     const float *right, const float *bottom)
+                     const float *right, const float *bottom,
+                     const vout_display_t *vd)
 {
+    VLC_UNUSED(vd);
+
     *nbVertices = 4 * 6;
     *nbIndices = 6 * 6;
 
@@ -1242,7 +1251,8 @@ static int BuildRectangle(unsigned nbPlanes,
                           GLfloat **vertexCoord, GLfloat **textureCoord, unsigned *nbVertices,
                           GLushort **indices, unsigned *nbIndices,
                           const float *left, const float *top,
-                          const float *right, const float *bottom)
+                          const float *right, const float *bottom,
+                          const vout_display_t *vd)
 {
     *nbVertices = 4;
     *nbIndices = 6;
@@ -1264,11 +1274,22 @@ static int BuildRectangle(unsigned nbPlanes,
         return VLC_ENOMEM;
     }
 
-    static const GLfloat coord[] = {
-       -1.0,    1.0,    -1.0f,
-       -1.0,    -1.0,   -1.0f,
-       1.0,     1.0,    -1.0f,
-       1.0,     -1.0,   -1.0f
+    vout_display_place_t place;
+    vout_display_PlacePicture (&place, &vd->source, vd->cfg, false);
+
+    /* map place coordinates to the range -1..+1 */
+    GLfloat v_left, v_right, v_top, v_bottom;
+
+    v_left = (GLfloat) place.x * 2.0 / (GLfloat) vd->cfg->display.width - 1;
+    v_right = v_left + (GLfloat) place.width * 2.0 / (GLfloat) vd->cfg->display.width;
+    v_top = (GLfloat) place.y * 2.0 / (GLfloat) vd->cfg->display.height - 1;
+    v_bottom = v_top + (GLfloat) place.height * 2.0 / (GLfloat) vd->cfg->display.height;
+
+    GLfloat coord[] = {
+       v_left,    v_bottom,  -1.0f,
+       v_left,    v_top,     -1.0f,
+       v_right,   v_bottom,  -1.0f,
+       v_right,   v_top,     -1.0f
     };
 
     memcpy(*vertexCoord, coord, *nbVertices * 3 * sizeof(GLfloat));
@@ -1298,7 +1319,8 @@ static int BuildRectangle(unsigned nbPlanes,
 
 static int SetupCoords(vout_display_opengl_t *vgl,
                        const float *left, const float *top,
-                       const float *right, const float *bottom)
+                       const float *right, const float *bottom,
+                       const vout_display_t *vd)
 {
     GLfloat *vertexCoord, *textureCoord;
     GLushort *indices;
@@ -1311,13 +1333,13 @@ static int SetupCoords(vout_display_opengl_t *vgl,
         i_ret = BuildRectangle(vgl->prgm->tc.tex_count,
                                &vertexCoord, &textureCoord, &nbVertices,
                                &indices, &nbIndices,
-                               left, top, right, bottom);
+                               left, top, right, bottom, vd);
         break;
     case PROJECTION_MODE_EQUIRECTANGULAR:
         i_ret = BuildSphere(vgl->prgm->tc.tex_count,
                             &vertexCoord, &textureCoord, &nbVertices,
                             &indices, &nbIndices,
-                            left, top, right, bottom);
+                            left, top, right, bottom, vd);
         break;
     case PROJECTION_MODE_CUBEMAP_LAYOUT_STANDARD:
         i_ret = BuildCube(vgl->prgm->tc.tex_count,
@@ -1325,7 +1347,7 @@ static int SetupCoords(vout_display_opengl_t *vgl,
                           (float)vgl->fmt.i_cubemap_padding / vgl->fmt.i_height,
                           &vertexCoord, &textureCoord, &nbVertices,
                           &indices, &nbIndices,
-                          left, top, right, bottom);
+                          left, top, right, bottom, vd);
         break;
     default:
         i_ret = VLC_EGENERIC;
@@ -1400,7 +1422,7 @@ static void DrawWithShaders(vout_display_opengl_t *vgl, struct prgm *prgm)
 }
 
 int vout_display_opengl_Display(vout_display_opengl_t *vgl,
-                                const video_format_t *source)
+                                const vout_display_t *vd)
 {
     /* Why drawing here and not in Render()? Because this way, the
        OpenGL providers can call vout_display_opengl_Display to force redraw.
@@ -1409,7 +1431,11 @@ int vout_display_opengl_Display(vout_display_opengl_t *vgl,
 
     vgl->api.UseProgram(vgl->prgm->id);
 
-    if (source->i_x_offset != vgl->last_source.i_x_offset
+    const video_format_t *source = &vd->source;
+
+    if (vd->cfg->display.width != vgl->i_last_display_width
+     || vd->cfg->display.height != vgl->i_last_display_height
+     || source->i_x_offset != vgl->last_source.i_x_offset
      || source->i_y_offset != vgl->last_source.i_y_offset
      || source->i_visible_width != vgl->last_source.i_visible_width
      || source->i_visible_height != vgl->last_source.i_visible_height)
@@ -1443,10 +1469,12 @@ int vout_display_opengl_Display(vout_display_opengl_t *vgl,
             bottom[j] = (source->i_y_offset + source->i_visible_height) * scale_h;
         }
 
-        int ret = SetupCoords(vgl, left, top, right, bottom);
+        int ret = SetupCoords(vgl, left, top, right, bottom, vd);
         if (ret != VLC_SUCCESS)
             return ret;
 
+        vgl->i_last_display_width = vd->cfg->display.width;
+        vgl->i_last_display_height = vd->cfg->display.height;
         vgl->last_source.i_x_offset = source->i_x_offset;
         vgl->last_source.i_y_offset = source->i_y_offset;
         vgl->last_source.i_visible_width = source->i_visible_width;
diff --git a/modules/video_output/opengl/vout_helper.h b/modules/video_output/opengl/vout_helper.h
index bb72699..f23544c 100644
--- a/modules/video_output/opengl/vout_helper.h
+++ b/modules/video_output/opengl/vout_helper.h
@@ -32,6 +32,7 @@
 #include <vlc_common.h>
 #include <vlc_picture_pool.h>
 #include <vlc_opengl.h>
+#include <vlc_vout_display.h>
 
 /* if USE_OPENGL_ES2 is defined, OpenGL ES version 2 will be used, otherwise
  * normal OpenGL will be used */
@@ -94,6 +95,6 @@ void vout_display_opengl_SetWindowAspectRatio(vout_display_opengl_t *vgl,
 int vout_display_opengl_Prepare(vout_display_opengl_t *vgl,
                                 picture_t *picture, subpicture_t *subpicture);
 int vout_display_opengl_Display(vout_display_opengl_t *vgl,
-                                const video_format_t *source);
+                                const vout_display_t *vd);
 
 #endif
diff --git a/modules/video_output/win32/glwin32.c b/modules/video_output/win32/glwin32.c
index 4b94a28..8d76ad1 100644
--- a/modules/video_output/win32/glwin32.c
+++ b/modules/video_output/win32/glwin32.c
@@ -312,7 +312,7 @@ static void Display(vout_display_t *vd, picture_t *picture, subpicture_t *subpic
 {
     vout_display_sys_t *sys = vd->sys;
 
-    vout_display_opengl_Display(sys->vgl, &vd->source);
+    vout_display_opengl_Display(sys->vgl, vd);
 
     picture_Release(picture);
     if (subpicture)
-- 
2.6.6



More information about the vlc-devel mailing list