[vlc-commits] [Git][videolan/vlc][master] 7 commits: vlc_vout: add a MAX value for stereoscopic enum
Alexandre Janniaux (@alexandre-janniaux)
gitlab at videolan.org
Wed Mar 26 10:47:08 UTC 2025
Alexandre Janniaux pushed to branch master at VideoLAN / VLC
Commits:
aed3d7bb by Alexandre Janniaux at 2025-03-26T10:32:14+00:00
vlc_vout: add a MAX value for stereoscopic enum
The MAX value allows checking whether the provided stereoscopic value is
valid or not.
- - - - -
93092b6c by Alexandre Janniaux at 2025-03-26T10:32:14+00:00
opengl: renderer: add support for video-stereo-mode
The video-stereo-mode is setup the same way I did the projection mode.
The client needs to restart the renderer to re-compile the shaders and
re-setup the variables for the mode, avoiding the need for a specific
API. This is justified by changing video-stereo-mode not happening at
each frame.
Note that projection_mode is temporarily enforced to
PROJECTION_MODE_RECTANGULAR whenever the multiview_mode is enforced to
another value than the source, to avoid trying to change the projection
from a texture containing the two eyes, leading to weird behaviour. This
happens when setting the SIDE_BY_SIDE stereoscopic mode which is made
for showing the two frames, but also in the STEREO stereoscopic mode
which is not yet supported in the module (need vlc-vr work).
- - - - -
0db936f2 by Alexandre Janniaux at 2025-03-26T10:32:14+00:00
opengl: vout helper: factor renderer restarting code
Create a dedicated function to restart the renderer given a set of
parameters. The function will also be used to change the
video-stereo-mode value in the renderer.
- - - - -
fb7d451d by Alexandre Janniaux at 2025-03-26T10:32:14+00:00
opengl: vout helper: store first projection state
The first projection state will be needed when changing the stereo-mode
in future commits.
- - - - -
37e222f6 by Alexandre Janniaux at 2025-03-26T10:32:14+00:00
opengl: vout helper: add support for changing video-stereo-mode
- - - - -
0902aed2 by Alexandre Janniaux at 2025-03-26T10:32:14+00:00
opengl: display: add support for set_stereo callback
Just like it's done for projection_mode, setup a state so that changing
the stereo mode can be asynchronously done when the rendering loop is
ready to provide the OpenGL context.
- - - - -
013a7c33 by Alexandre Janniaux at 2025-03-26T10:32:14+00:00
opengl: renderer: remove vout_helper.h include
- - - - -
6 changed files:
- include/vlc_vout.h
- modules/video_output/opengl/display.c
- modules/video_output/opengl/renderer.c
- modules/video_output/opengl/renderer.h
- modules/video_output/opengl/vout_helper.c
- modules/video_output/opengl/vout_helper.h
Changes:
=====================================
include/vlc_vout.h
=====================================
@@ -94,6 +94,7 @@ typedef enum vlc_stereoscopic_mode_t
VIDEO_STEREO_OUTPUT_LEFT_ONLY,
VIDEO_STEREO_OUTPUT_RIGHT_ONLY,
VIDEO_STEREO_OUTPUT_SIDE_BY_SIDE,
+#define VIDEO_STEREO_OUTPUT_MAX VIDEO_STEREO_OUTPUT_SIDE_BY_SIDE
} vlc_stereoscopic_mode_t;
/*****************************************************************************
=====================================
modules/video_output/opengl/display.c
=====================================
@@ -80,6 +80,11 @@ typedef struct vout_display_sys_t
bool is_dirty;
bool restart_renderer;
+ struct {
+ vlc_stereoscopic_mode_t mode;
+ bool changed;
+ } stereo;
+
struct {
PFNGLFLUSHPROC Flush;
} vt;
@@ -174,6 +179,15 @@ static int ChangeSourceProjection(vout_display_t *vd, video_projection_mode_t pr
return VLC_SUCCESS;
}
+static int SetStereoMode(vout_display_t *vd, vlc_stereoscopic_mode_t mode)
+{
+ vout_display_sys_t *sys = vd->sys;
+ UpdateConfig(vd);
+ sys->stereo.mode = mode;
+ sys->stereo.changed = true;
+ return VLC_SUCCESS;
+}
+
static const struct vlc_display_operations ops = {
.close = Close,
.prepare = PictureRender,
@@ -182,6 +196,7 @@ static const struct vlc_display_operations ops = {
.set_viewpoint = SetViewpoint,
.update_format = UpdateFormat,
.change_source_projection = ChangeSourceProjection,
+ .set_stereo = SetStereoMode,
};
/**
@@ -237,6 +252,7 @@ static int Open(vout_display_t *vd,
struct vout_display_placement dp = vd->cfg->display;
PlacePicture(vd, &sys->place, dp);
sys->place_changed = true;
+ sys->stereo.changed = false;
vlc_gl_Resize (sys->gl, vd->cfg->display.width, vd->cfg->display.height);
/* Initialize video display */
@@ -298,6 +314,12 @@ static void PictureRender (vout_display_t *vd, picture_t *pic,
if (vlc_gl_MakeCurrent (sys->gl) == VLC_SUCCESS)
{
+ if (sys->stereo.changed)
+ {
+ vout_display_opengl_ChangeStereoMode(sys->vgl, sys->stereo.mode);
+ sys->stereo.changed = false;
+ }
+
if (sys->restart_renderer)
{
vout_display_opengl_ChangeProjection(sys->vgl, vd->cfg->projection);
=====================================
modules/video_output/opengl/renderer.c
=====================================
@@ -41,7 +41,6 @@
#include <vlc_configuration.h>
#include "gl_util.h"
-#include "vout_helper.h"
#include "sampler.h"
#include "picture.h"
@@ -80,8 +79,9 @@ static void getProjectionMatrix(float sar, float fovy, GLfloat matrix[static 16]
static void getViewpointMatrixes(struct vlc_gl_renderer *renderer,
video_projection_mode_t projection_mode)
{
- if (projection_mode == PROJECTION_MODE_EQUIRECTANGULAR
+ if ((projection_mode == PROJECTION_MODE_EQUIRECTANGULAR
|| projection_mode == PROJECTION_MODE_CUBEMAP_LAYOUT_STANDARD)
+ && renderer->multiview_mode == renderer->sampler->glfmt.fmt.multiview_mode)
{
getProjectionMatrix(renderer->f_sar, renderer->f_fovy,
renderer->var.ProjectionMatrix);
@@ -104,6 +104,7 @@ static void getViewpointMatrixes(struct vlc_gl_renderer *renderer,
static void
InitStereoMatrix(GLfloat matrix_out[static 3*3],
+ vlc_stereoscopic_mode_t stereo_mode,
video_multiview_mode_t multiview_mode)
{
/*
@@ -112,10 +113,6 @@ InitStereoMatrix(GLfloat matrix_out[static 3*3],
*
* This 2D transformation is affine, so the matrix is 3x3 and applies to 3D
* vectors in the form (x, y, 1).
- *
- * Note that since for now, we always crop the left eye, in practice the
- * offset is always 0, so the transform is actually linear (a 2x2 matrix
- * would be sufficient).
*/
memcpy(matrix_out, MATRIX3_IDENTITY, sizeof(MATRIX3_IDENTITY));
@@ -123,6 +120,11 @@ InitStereoMatrix(GLfloat matrix_out[static 3*3],
#define COL(x) (x*3)
#define ROW(x) (x)
+ if (stereo_mode == VIDEO_STEREO_OUTPUT_SIDE_BY_SIDE)
+ return;
+ assert(stereo_mode == VIDEO_STEREO_OUTPUT_LEFT_ONLY ||
+ stereo_mode == VIDEO_STEREO_OUTPUT_RIGHT_ONLY);
+
switch (multiview_mode)
{
case MULTIVIEW_STEREO_SBS:
@@ -142,6 +144,8 @@ InitStereoMatrix(GLfloat matrix_out[static 3*3],
* \ 0 0 1 /
*/
matrix_out[COL(0) + ROW(0)] = 0.5;
+ if (stereo_mode == VIDEO_STEREO_OUTPUT_RIGHT_ONLY)
+ matrix_out[COL(2) + ROW(0)] = 0.5;
break;
case MULTIVIEW_STEREO_TB:
/*
@@ -165,6 +169,8 @@ InitStereoMatrix(GLfloat matrix_out[static 3*3],
* \ 0 0 1 /
*/
matrix_out[COL(1) + ROW(1)] = 0.5;
+ if (stereo_mode == VIDEO_STEREO_OUTPUT_RIGHT_ONLY)
+ matrix_out[COL(2) + ROW(1)] = 0.5;
break;
default:
break;
@@ -673,8 +679,12 @@ static int SetupCoords(struct vlc_gl_renderer *renderer,
GLushort *indices;
unsigned nbVertices, nbIndices;
+ video_projection_mode_t projection_mode = renderer->projection_mode;
+ if (renderer->multiview_mode != renderer->sampler->glfmt.fmt.multiview_mode)
+ projection_mode = PROJECTION_MODE_RECTANGULAR;
+
int i_ret;
- switch (renderer->projection_mode)
+ switch (projection_mode)
{
case PROJECTION_MODE_RECTANGULAR:
i_ret = BuildRectangle(&vertexCoord, &textureCoord, &nbVertices,
@@ -798,7 +808,7 @@ vlc_gl_renderer_Open(struct vlc_gl_filter *filter,
{
(void) size_out;
- const char * const options[] = { "projection-mode", NULL };
+ const char * const options[] = { "projection-mode", "video-stereo-mode", NULL };
config_ChainParse(filter, "", options, config);
const opengl_vtable_t *vt = &filter->api->vt;
@@ -844,6 +854,33 @@ vlc_gl_renderer_Open(struct vlc_gl_filter *filter,
break;
}
+ int stereo_mode = var_InheritInteger(filter, "video-stereo-mode");
+ if (stereo_mode > VIDEO_STEREO_OUTPUT_AUTO && stereo_mode <= VIDEO_STEREO_OUTPUT_MAX)
+ renderer->stereo_mode = stereo_mode;
+
+ if (sampler->glfmt.fmt.multiview_mode == MULTIVIEW_2D)
+ {
+ renderer->stereo_mode = VIDEO_STEREO_OUTPUT_SIDE_BY_SIDE;
+ renderer->multiview_mode = MULTIVIEW_2D;
+ }
+ else switch (stereo_mode)
+ {
+ case VIDEO_STEREO_OUTPUT_LEFT_ONLY:
+ case VIDEO_STEREO_OUTPUT_RIGHT_ONLY:
+ case VIDEO_STEREO_OUTPUT_AUTO:
+ /* multiview_mode != MULTIVIEW_2D */
+ renderer->multiview_mode = sampler->glfmt.fmt.multiview_mode;
+ if (stereo_mode == VIDEO_STEREO_OUTPUT_AUTO)
+ renderer->stereo_mode = VIDEO_STEREO_OUTPUT_LEFT_ONLY;
+ break;
+ case VIDEO_STEREO_OUTPUT_SIDE_BY_SIDE:
+ case VIDEO_STEREO_OUTPUT_STEREO: /* stereo mode is not supported yet */
+ default:
+ renderer->multiview_mode = MULTIVIEW_2D; /* Enforce the planar view */
+ renderer->stereo_mode = VIDEO_STEREO_OUTPUT_SIDE_BY_SIDE;
+ break;
+ }
+
int ret = opengl_link_program(filter);
if (ret != VLC_SUCCESS)
{
@@ -852,10 +889,9 @@ vlc_gl_renderer_Open(struct vlc_gl_filter *filter,
return ret;
}
- const video_format_t *fmt = &sampler->glfmt.fmt;
- InitStereoMatrix(renderer->var.StereoMatrix, fmt->multiview_mode);
+ InitStereoMatrix(renderer->var.StereoMatrix, renderer->stereo_mode, renderer->multiview_mode);
- getViewpointMatrixes(renderer, fmt->projection_mode);
+ getViewpointMatrixes(renderer, renderer->projection_mode);
vt->GenBuffers(1, &renderer->vertex_buffer_object);
vt->GenBuffers(1, &renderer->index_buffer_object);
=====================================
modules/video_output/opengl/renderer.h
=====================================
@@ -104,6 +104,8 @@ struct vlc_gl_renderer
/* Projection mode for the input data */
video_projection_mode_t projection_mode;
+ vlc_stereoscopic_mode_t stereo_mode;
+ video_multiview_mode_t multiview_mode;
};
vlc_gl_filter_open_fn vlc_gl_renderer_Open;
=====================================
modules/video_output/opengl/vout_helper.c
=====================================
@@ -65,6 +65,7 @@ struct vout_display_opengl_t {
vlc_viewpoint_t viewpoint;
video_projection_mode_t projection;
+ vlc_stereoscopic_mode_t stereo_mode;
};
static const vlc_fourcc_t gl_subpicture_chromas[] = {
@@ -180,22 +181,46 @@ error:
return NULL;
}
-int vout_display_opengl_ChangeProjection(vout_display_opengl_t *vgl,
- video_projection_mode_t projection)
+struct renderer_config
+{
+ video_projection_mode_t projection;
+ vlc_stereoscopic_mode_t stereo_mode;
+};
+
+static int RestartRenderer(vout_display_opengl_t *vgl,
+ const struct renderer_config *config)
{
- const config_chain_t chain = {
+ config_chain_t chain_projection = {
.psz_name = strdup("projection-mode"),
- .psz_value = strdup(projection == PROJECTION_MODE_RECTANGULAR ? "0" : "-1"),
+ .psz_value = strdup(config->projection == PROJECTION_MODE_RECTANGULAR ? "0" : "-1"),
+ };
+
+ config_chain_t chain_stereo = {
+ .psz_name = strdup("video-stereo-mode"),
+ .p_next = &chain_projection,
};
+ if (chain_projection.psz_name == NULL ||
+ chain_projection.psz_value == NULL ||
+ chain_stereo.psz_name == NULL ||
+ asprintf(&chain_stereo.psz_value, "%d", (int)config->stereo_mode) == -1)
+ {
+ free(chain_projection.psz_name);
+ free(chain_projection.psz_value);
+ free(chain_stereo.psz_name);
+ free(chain_stereo.psz_value);
+ return VLC_ENOMEM;
+ }
struct vlc_gl_filter *new_renderer =
- vlc_gl_filters_Replace(vgl->filters, vgl->renderer_filter, "renderer", &chain);
- free(chain.psz_name);
- free(chain.psz_value);
+ vlc_gl_filters_Replace(vgl->filters, vgl->renderer_filter, "renderer", &chain_stereo);
+ free(chain_projection.psz_name);
+ free(chain_projection.psz_value);
+ free(chain_stereo.psz_name);
+ free(chain_stereo.psz_value);
if (new_renderer == NULL)
{
- msg_Err(vgl->gl, "Could not re-create renderer filter for projection mode %d",
- (int)projection);
+ msg_Err(vgl->gl, "Could not re-create renderer filter for projection=%d stereo_mode=%d",
+ (int)config->projection, (int)config->stereo_mode);
return VLC_EGENERIC;
}
@@ -210,11 +235,41 @@ int vout_display_opengl_ChangeProjection(vout_display_opengl_t *vgl,
vgl->renderer = new_renderer->sys;
vlc_gl_renderer_SetViewpoint(vgl->renderer, &vgl->viewpoint);
+ return VLC_SUCCESS;
+}
+int vout_display_opengl_ChangeProjection(vout_display_opengl_t *vgl,
+ video_projection_mode_t projection)
+{
+ struct renderer_config config = {
+ .projection = projection,
+ .stereo_mode = vgl->stereo_mode,
+ };
+ int ret = RestartRenderer(vgl, &config);
+ if (ret != VLC_SUCCESS)
+ return ret;
+
+ vgl->projection = projection;
msg_Dbg(vgl->gl, "Changed to projection mode %d", projection);
return VLC_SUCCESS;
}
+int vout_display_opengl_ChangeStereoMode(vout_display_opengl_t *vgl,
+ vlc_stereoscopic_mode_t stereo_mode)
+{
+ struct renderer_config config = {
+ .projection = vgl->projection,
+ .stereo_mode = stereo_mode,
+ };
+ int ret = RestartRenderer(vgl, &config);
+ if (ret != VLC_SUCCESS)
+ return ret;
+
+ vgl->stereo_mode = stereo_mode;
+ msg_Dbg(vgl->gl, "Changed to stereo mode %d", stereo_mode);
+ return VLC_SUCCESS;
+}
+
vout_display_opengl_t *vout_display_opengl_New(video_format_t *fmt,
const vlc_fourcc_t **subpicture_chromas,
vlc_gl_t *gl,
@@ -293,6 +348,20 @@ vout_display_opengl_t *vout_display_opengl_New(video_format_t *fmt,
&& vout_display_opengl_SetViewpoint(vgl, viewpoint) != VLC_SUCCESS)
msg_Err(gl, "Could not set viewpoint");
+ int projection_mode = var_InheritInteger(gl, "projection-mode");
+ if (projection_mode == PROJECTION_MODE_RECTANGULAR ||
+ projection_mode == PROJECTION_MODE_EQUIRECTANGULAR ||
+ projection_mode == PROJECTION_MODE_CUBEMAP_LAYOUT_STANDARD)
+ vgl->projection = projection_mode;
+ else
+ vgl->projection = fmt->projection_mode;
+
+ int stereo_mode = var_InheritInteger(gl, "video-stereo-mode");
+ if (stereo_mode > 0 && stereo_mode <= VIDEO_STEREO_OUTPUT_MAX)
+ vgl->stereo_mode = stereo_mode;
+ else
+ vgl->stereo_mode = VIDEO_STEREO_OUTPUT_AUTO;
+
/* Forward to the core the changes to the input format requested by the
* interop */
video_format_Clean(fmt);
=====================================
modules/video_output/opengl/vout_helper.h
=====================================
@@ -90,4 +90,7 @@ int vout_display_opengl_UpdateFormat(vout_display_opengl_t *vgl,
int vout_display_opengl_ChangeProjection(vout_display_opengl_t *vgl,
video_projection_mode_t projection);
+int vout_display_opengl_ChangeStereoMode(vout_display_opengl_t *vgl,
+ vlc_stereoscopic_mode_t projection);
+
#endif
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/9cff68f0c37e42820b91b33d33f47827830c9b15...013a7c33605bc13aa269e182d81afe2ebe79e661
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/9cff68f0c37e42820b91b33d33f47827830c9b15...013a7c33605bc13aa269e182d81afe2ebe79e661
You're receiving this email because of your account on code.videolan.org.
VideoLAN code repository instance
More information about the vlc-commits
mailing list