[vlc-devel] [RFC 2/7] opengl: support rendering subpictures in display dimensions

Salah-Eddin Shaban salah at videolan.org
Mon Feb 19 11:43:05 CET 2018


---
 modules/video_output/caopengllayer.m      |  2 +-
 modules/video_output/ios.m                |  2 +-
 modules/video_output/macosx.m             | 15 +++++----
 modules/video_output/opengl/converter.h   |  1 +
 modules/video_output/opengl/display.c     | 15 +++++----
 modules/video_output/opengl/vout_helper.c | 56 ++++++++++++++++++++++---------
 modules/video_output/opengl/vout_helper.h |  2 +-
 modules/video_output/win32/common.c       |  8 +++--
 modules/video_output/win32/glwin32.c      |  3 +-
 9 files changed, 70 insertions(+), 34 deletions(-)

diff --git a/modules/video_output/caopengllayer.m b/modules/video_output/caopengllayer.m
index a8cffadb61..817215a091 100644
--- a/modules/video_output/caopengllayer.m
+++ b/modules/video_output/caopengllayer.m
@@ -495,7 +495,7 @@ static void *OurGetProcAddress (vlc_gl_t *gl, const char *name)
                                  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 655381a8b0..74302c4118 100644
--- a/modules/video_output/ios.m
+++ b/modules/video_output/ios.m
@@ -358,7 +358,7 @@ static void PictureDisplay(vout_display_t *vd, picture_t *pic, subpicture_t *sub
     @synchronized (sys->glESView) {
         if (vlc_gl_MakeCurrent(sys->gl) == VLC_SUCCESS)
         {
-            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 0ab61fc52b..40e10e3105 100644
--- a/modules/video_output/macosx.m
+++ b/modules/video_output/macosx.m
@@ -239,6 +239,7 @@ static int Open (vlc_object_t *this)
         vout_display_info_t info = vd->info;
         info.has_pictures_invalid = false;
         info.subpicture_chromas = subpicture_chromas;
+        info.constrained_spu = false;
 
         /* Setup vout_display_t once everything is fine */
         vd->info = info;
@@ -339,7 +340,7 @@ static void PictureDisplay (vout_display_t *vd, picture_t *pic, subpicture_t *su
     [sys->glView setVoutFlushing:YES];
     if (vlc_gl_MakeCurrent(sys->gl) == VLC_SUCCESS)
     {
-        vout_display_opengl_Display (sys->vgl, &vd->source);
+        vout_display_opengl_Display (sys->vgl, vd);
         vlc_gl_ReleaseCurrent(sys->gl);
     }
     [sys->glView setVoutFlushing:NO];
@@ -396,15 +397,15 @@ static int Control (vout_display_t *vd, int query, va_list ap)
 
                 if (vlc_gl_MakeCurrent (sys->gl) != VLC_SUCCESS)
                     return VLC_EGENERIC;
-                vout_display_opengl_SetWindowAspectRatio(sys->vgl, (float)place.width / place.height);
+                vout_display_opengl_SetWindowAspectRatio(sys->vgl, (float)bounds.size.width / bounds.size.height);
 
                 /* For resize, we call glViewport in reshape and not here.
                  This has the positive side effect that we avoid erratic sizing as we animate every resize. */
                 if (query != VOUT_DISPLAY_CHANGE_DISPLAY_SIZE)
                     // x / y are top left corner, but we need the lower left one
-                    vout_display_opengl_Viewport(sys->vgl, place.x,
-                                                 cfg_tmp.display.height - (place.y + place.height),
-                                                 place.width, place.height);
+                    vout_display_opengl_Viewport(sys->vgl, 0,
+                                                 0,
+                                                 bounds.size.width, bounds.size.height);
                 vlc_gl_ReleaseCurrent (sys->gl);
 
                 return VLC_SUCCESS;
@@ -630,7 +631,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);
 }
@@ -660,7 +661,7 @@ static void OpenglSwap (vlc_gl_t *gl)
 
     if ([self lockgl]) {
         // x / y are top left corner, but we need the lower left one
-        glViewport (place.x, bounds.size.height - (place.y + place.height), place.width, place.height);
+        glViewport (0, 0, bounds.size.width, bounds.size.height);
 
         @synchronized(self) {
             // This may be cleared before -drawRect is being called,
diff --git a/modules/video_output/opengl/converter.h b/modules/video_output/opengl/converter.h
index 470758e876..52a8bcd385 100644
--- a/modules/video_output/opengl/converter.h
+++ b/modules/video_output/opengl/converter.h
@@ -25,6 +25,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 */
diff --git a/modules/video_output/opengl/display.c b/modules/video_output/opengl/display.c
index b3bafa15c6..5ba231e8e2 100644
--- a/modules/video_output/opengl/display.c
+++ b/modules/video_output/opengl/display.c
@@ -151,6 +151,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.constrained_spu = false;
     vd->pool = Pool;
     vd->prepare = PictureRender;
     vd->display = PictureDisplay;
@@ -217,7 +218,7 @@ static void PictureDisplay (vout_display_t *vd, picture_t *pic, subpicture_t *su
 
     if (vlc_gl_MakeCurrent (sys->gl) == VLC_SUCCESS)
     {
-        vout_display_opengl_Display (sys->vgl, &vd->source);
+        vout_display_opengl_Display (sys->vgl, vd);
         vlc_gl_ReleaseCurrent (sys->gl);
     }
 
@@ -252,11 +253,12 @@ static int Control (vout_display_t *vd, int query, va_list ap)
             c.align.vertical = VOUT_DISPLAY_ALIGN_TOP;
 
         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);
         if (vlc_gl_MakeCurrent (sys->gl) != VLC_SUCCESS)
             return VLC_EGENERIC;
-        vout_display_opengl_SetWindowAspectRatio(sys->vgl, (float)place.width / place.height);
-        vout_display_opengl_Viewport(sys->vgl, place.x, place.y, place.width, place.height);
+        vout_display_opengl_SetWindowAspectRatio(sys->vgl,
+                (float)c.display.width / c.display.height);
+        vout_display_opengl_Viewport(sys->vgl, 0, 0, c.display.width, c.display.height);
         vlc_gl_ReleaseCurrent (sys->gl);
         return VLC_SUCCESS;
       }
@@ -270,8 +272,9 @@ static int Control (vout_display_t *vd, int query, va_list ap)
         vout_display_PlacePicture (&place, &vd->source, cfg, false);
         if (vlc_gl_MakeCurrent (sys->gl) != VLC_SUCCESS)
             return VLC_EGENERIC;
-        vout_display_opengl_SetWindowAspectRatio(sys->vgl, (float)place.width / place.height);
-        vout_display_opengl_Viewport(sys->vgl, place.x, place.y, place.width, place.height);
+        vout_display_opengl_SetWindowAspectRatio(sys->vgl,
+                (float)cfg->display.width / cfg->display.height);
+        vout_display_opengl_Viewport(sys->vgl, 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 56f5be7bc3..db0bc406ed 100644
--- a/modules/video_output/opengl/vout_helper.c
+++ b/modules/video_output/opengl/vout_helper.c
@@ -158,6 +158,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;
 
@@ -1236,8 +1239,10 @@ 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;
 
@@ -1322,8 +1327,10 @@ 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;
 
@@ -1446,7 +1453,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;
@@ -1468,11 +1476,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));
@@ -1502,7 +1521,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;
@@ -1515,13 +1535,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,
@@ -1529,7 +1549,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;
@@ -1652,7 +1672,7 @@ static void TextureCropForStereo(vout_display_opengl_t *vgl,
 }
 
 int vout_display_opengl_Display(vout_display_opengl_t *vgl,
-                                const video_format_t *source)
+                                const vout_display_t *vd)
 {
     GL_ASSERT_NOERROR();
 
@@ -1663,7 +1683,11 @@ int vout_display_opengl_Display(vout_display_opengl_t *vgl,
 
     vgl->vt.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)
@@ -1698,10 +1722,12 @@ int vout_display_opengl_Display(vout_display_opengl_t *vgl,
         }
 
         TextureCropForStereo(vgl, left, top, right, bottom);
-        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 bd4126c632..7cff4a2dfd 100644
--- a/modules/video_output/opengl/vout_helper.h
+++ b/modules/video_output/opengl/vout_helper.h
@@ -231,6 +231,6 @@ void vout_display_opengl_Viewport(vout_display_opengl_t *vgl, int x, int y,
 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/common.c b/modules/video_output/win32/common.c
index 611554f9bc..391fb7e798 100644
--- a/modules/video_output/win32/common.c
+++ b/modules/video_output/win32/common.c
@@ -185,16 +185,20 @@ void UpdateRects(vout_display_t *vd,
     place_cfg.display.width = rect.right;
     place_cfg.display.height = rect.bottom;
 
+    vout_display_place_t place;
 #if (defined(MODULE_NAME_IS_glwin32))
     /* Reverse vertical alignment as the GL tex are Y inverted */
     if (place_cfg.align.vertical == VOUT_DISPLAY_ALIGN_TOP)
         place_cfg.align.vertical = VOUT_DISPLAY_ALIGN_BOTTOM;
     else if (place_cfg.align.vertical == VOUT_DISPLAY_ALIGN_BOTTOM)
         place_cfg.align.vertical = VOUT_DISPLAY_ALIGN_TOP;
-#endif
 
-    vout_display_place_t place;
+    place.x = place.y = 0;
+    place.width = rect.right;
+    place.height = rect.bottom;
+#else
     vout_display_PlacePicture(&place, source, &place_cfg, false);
+#endif
 
 #if !VLC_WINSTORE_APP
     EventThreadUpdateSourceAndPlace(sys->event, source, &place);
diff --git a/modules/video_output/win32/glwin32.c b/modules/video_output/win32/glwin32.c
index 2d3debff6b..0590703021 100644
--- a/modules/video_output/win32/glwin32.c
+++ b/modules/video_output/win32/glwin32.c
@@ -162,6 +162,7 @@ static int Open(vlc_object_t *object)
     vd->display = Display;
     vd->control = Control;
     vd->manage  = Manage;
+    vd->info.constrained_spu = false;
 
     return VLC_SUCCESS;
 
@@ -227,7 +228,7 @@ static void Display(vout_display_t *vd, picture_t *picture, subpicture_t *subpic
 
     if (vlc_gl_MakeCurrent (sys->gl) == VLC_SUCCESS)
     {
-        vout_display_opengl_Display (sys->vgl, &vd->source);
+        vout_display_opengl_Display (sys->vgl, vd);
         vlc_gl_ReleaseCurrent (sys->gl);
     }
 
-- 
2.13.6



More information about the vlc-devel mailing list