[vlc-commits] [Git][videolan/vlc][master] 21 commits: opengl: filters: add vlc_gl_filters_Replace()
Steve Lhomme (@robUx4)
gitlab at videolan.org
Tue Jan 14 09:07:09 UTC 2025
Steve Lhomme pushed to branch master at VideoLAN / VLC
Commits:
820be6c4 by Alexandre Janniaux at 2025-01-14T08:40:43+00:00
opengl: filters: add vlc_gl_filters_Replace()
The function allows replacing a filter from the existing vlc_gl_filter
chain. The main target is replacing the final renderer but it could work
with any (current non-blend) filter which needs to have its shaders
updated.
- - - - -
5227011a by Alexandre Janniaux at 2025-01-14T08:40:43+00:00
opengl: vout helper: store viewpoint for UpdateFormat
Future changes will re-create the renderer module and the viewpoint will
be lost after that. It's already doing that when updating the format, so
store it to restore the viewpoint during re-creation of the renderer.
- - - - -
3836aa64 by Alexandre Janniaux at 2025-01-14T08:40:43+00:00
opengl: display: remove now redundant SetViewpoint call
The vout_helper code will restore the viewpoint when the renderer is
created again, so the display doesn't need to restore it manually
anymore.
- - - - -
46389b9d by Alexandre Janniaux at 2025-01-14T08:40:43+00:00
VLCSampleBufferDisplay: use designated initializer
- - - - -
daa9c1f7 by Alexandre Janniaux at 2025-01-14T08:40:43+00:00
vlc_vout_display: add projection field and control
Even though the source provides a (source) projection, this new
parameters provides a way to specify how the projection should be
rendered on-screen. The current goal is not to provide projection
filtering (eg. changing from cubemap to equirectangular) but mostly to
be able to enforce a rectangular projection rendering and avoid the
mapping to 3D objects on the display.
- - - - -
4018a540 by Alexandre Janniaux at 2025-01-14T08:40:43+00:00
opengl: display: reindent control
- - - - -
2070bfb3 by Alexandre Janniaux at 2025-01-14T08:40:43+00:00
libvlc-module: add projection-mode variable
Here, projection-mode designates the _source_ projection mode that gets
overriden. Having EQUIRECTANGULAR there means that the source should be
interpreted as an EQUIRECTANGULAR-ly mapped video buffer, which should
be mapped to the sphere, and not that the source video should be
transformed into an equirectangular frame.
- - - - -
d7ae2e6f by Alexandre Janniaux at 2025-01-14T08:40:43+00:00
opengl: renderer: handle specific projection mode
This adds a way for the renderer to override the source projection from
the creation of the renderer module. Restarting the filter allows to
change the projection by changing this parameter in the configuration
chain beforehand.
- - - - -
8e08af74 by Alexandre Janniaux at 2025-01-14T08:40:43+00:00
opengl: vout_helper: store renderer as a filter
The filter provides access to the .sys pointer as well as the private
implementation from the core, whereas vlc_gl_renderer only references
the .sys pointer. Interacting with the filter in the filter engine
(vlc_gl_filters object) requires access to the vlc_gl_filter object
itself so store it instead of the vlc_gl_renderer.
- - - - -
dca1931f by Alexandre Janniaux at 2025-01-14T08:40:43+00:00
opengl: vout helper: provide functions to override projection
Like for update_format, the viewpoint needs to be restored given that
the renderer module is restarted.
- - - - -
e23b5271 by Alexandre Janniaux at 2025-01-14T08:40:43+00:00
caopengllayer: handle source projection change
The viewpoint and viewport informations need to be reset after
restarting the renderer because they will get lost with the re-creation
of the renderer filter.
- - - - -
680e0786 by Alexandre Janniaux at 2025-01-14T08:40:43+00:00
opengl: display: handle source projection change
The viewpoint and viewport informations need to be reset after
restarting the renderer because they will get lost with the re-creation
of the renderer filter.
- - - - -
977862c7 by Alexandre Janniaux at 2025-01-14T08:40:43+00:00
direct3d11: add projection_mode change support
- - - - -
123f15dc by Alexandre Janniaux at 2025-01-14T08:40:43+00:00
video_output: display: add controls to setup projection
- - - - -
d520ede5 by Alexandre Janniaux at 2025-01-14T08:40:43+00:00
video_output: add method to change projection
This provides the vout_thread_t -> vout_display control indirection
function, to change the source projection mode.
- - - - -
3f653e0b by Alexandre Janniaux at 2025-01-14T08:40:43+00:00
vout_intf: setup callback to change source projection
This will allow the hotkeys to change the projection mode when requested
by the user.
- - - - -
dfca890f by Alexandre Janniaux at 2025-01-14T08:40:43+00:00
vlc_actions: add toggle projection mode
This will provides hotkey support for changing projection in the next
patches.
- - - - -
9c30ff9e by Alexandre Janniaux at 2025-01-14T08:40:43+00:00
hotkeys: handle projection toggle
- - - - -
f785d0af by Alexandre Janniaux at 2025-01-14T08:40:43+00:00
libvlc-module: create action for changing projection
- - - - -
79e34456 by Alexandre Janniaux at 2025-01-14T08:40:43+00:00
actions: handle toggle projection action
- - - - -
9e5e5ca6 by Alexandre Janniaux at 2025-01-14T08:40:43+00:00
libvlc: media_player: add projection-mode API
- - - - -
24 changed files:
- include/vlc/libvlc_media_player.h
- include/vlc_actions.h
- include/vlc_vout_display.h
- lib/libvlc.sym
- lib/media_player.c
- lib/video.c
- modules/control/hotkeys.c
- modules/video_output/apple/VLCSampleBufferDisplay.m
- modules/video_output/caopengllayer.m
- modules/video_output/opengl/display.c
- modules/video_output/opengl/filters.c
- modules/video_output/opengl/filters.h
- 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
- modules/video_output/win32/direct3d11.cpp
- src/libvlc-module.c
- src/misc/actions.c
- src/video_output/display.c
- src/video_output/video_output.c
- src/video_output/vout_internal.h
- src/video_output/vout_intf.c
- src/video_output/vout_wrapper.h
Changes:
=====================================
include/vlc/libvlc_media_player.h
=====================================
@@ -7,6 +7,7 @@
* Jean-Paul Saman <jpsaman at videolan.org>
* Pierre d'Herbemont <pdherbemont at videolan.org>
* Maxime Chapelet <umxprime at videolabs dot io>
+ * Alexandre Janniaux <ajanni at videolabs.io>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
@@ -2432,6 +2433,29 @@ LIBVLC_API float libvlc_video_get_adjust_float( libvlc_media_player_t *p_mi,
*/
LIBVLC_API void libvlc_video_set_adjust_float( libvlc_media_player_t *p_mi,
unsigned option, float value );
+/**
+ * Change the projection mode used for rendering the source.
+ *
+ * This changes how the source is mapped to the output w.r.t. 360 playback.
+ *
+ * \param p_mi libvlc media player instance
+ * \param projection_mode the considered projection mode for the source
+ * \version LibVLC 4.0.0 and later.
+ */
+LIBVLC_API void
+libvlc_video_set_projection_mode(libvlc_media_player_t *player,
+ libvlc_video_projection_t projection_mode);
+
+/**
+ * Remove previously set projection mode.
+ *
+ * Remove the effects from previous call to libvlc_video_set_projection_mode.
+ *
+ * \param p_mi libvlc media player instance
+ * \version LibVLC 4.0.0 and later.
+ */
+LIBVLC_API void
+libvlc_video_unset_projection_mode(libvlc_media_player_t *player);
/** @} video */
=====================================
include/vlc_actions.h
=====================================
@@ -262,6 +262,8 @@ typedef enum vlc_action_id {
/* Combo Actions */
ACTIONID_COMBO_VOL_FOV_DOWN,
ACTIONID_COMBO_VOL_FOV_UP,
+
+ ACTIONID_PROJECTION_TOGGLE,
} vlc_action_id_t;
/**
=====================================
include/vlc_vout_display.h
=====================================
@@ -119,6 +119,10 @@ typedef struct vout_display_cfg {
struct vlc_window *window; /**< Window */
struct vout_display_placement display; /**< Display placement properties */
vlc_icc_profile_t *icc_profile; /**< Currently active ICC profile */
+ /** Final source projection requested for display. */
+ video_projection_mode_t projection;
+
+ /** Initial viewpoint when projection != PROJECTION_MODE_RECTANGULAR */
vlc_viewpoint_t viewpoint;
} vout_display_cfg_t;
@@ -323,6 +327,18 @@ struct vlc_display_operations
*/
int (*update_format)(vout_display_t *, const video_format_t *fmt,
vlc_video_context *ctx);
+
+ /**
+ * Set the source projection used by the display.
+ *
+ * May be NULL.
+ *
+ * \param display the display to change projection for
+ * \param projection the new projection mode considered for the source
+ * \return VLC_SUCCESS on succes, another value if changing projection failed
+ */
+ int (*change_source_projection)(vout_display_t *display,
+ video_projection_mode_t projection);
};
/**
@@ -492,6 +508,13 @@ static inline bool vout_display_cfg_IsWindowed(const vout_display_cfg_t *cfg)
return cfg->window->type != VLC_WINDOW_TYPE_DUMMY;
}
+static inline int vout_display_ChangeProjection(vout_display_t *vd, video_projection_mode_t projection)
+{
+ if (vd->ops->change_source_projection == NULL)
+ return VLC_ENOTSUP;
+ return vd->ops->change_source_projection(vd, projection);
+}
+
/**
* Computes the default display size given the source and
* the display configuration.
=====================================
lib/libvlc.sym
=====================================
@@ -267,6 +267,8 @@ libvlc_video_set_logo_string
libvlc_video_set_marquee_int
libvlc_video_set_marquee_string
libvlc_video_set_mouse_input
+libvlc_video_set_projection_mode
+libvlc_video_unset_projection_mode
libvlc_video_set_scale
libvlc_video_set_spu_delay
libvlc_video_set_spu_text_scale
=====================================
lib/media_player.c
=====================================
@@ -695,6 +695,7 @@ libvlc_media_player_new( libvlc_instance_t *instance )
var_Create (mp, "crop", VLC_VAR_STRING);
var_Create (mp, "deinterlace", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT);
var_Create (mp, "deinterlace-mode", VLC_VAR_STRING | VLC_VAR_DOINHERIT);
+ var_Create (mp, "projection-mode", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT);
var_Create (mp, "vbi-page", VLC_VAR_INTEGER);
var_SetInteger (mp, "vbi-page", 100);
=====================================
lib/video.c
=====================================
@@ -8,6 +8,7 @@
* Filippo Carone <littlejohn at videolan.org>
* Jean-Paul Saman <jpsaman _at_ m2x _dot_ nl>
* Damien Fouilleul <damienf a_t videolan dot org>
+ * Alexandre Janniaux <ajanni at videolabs.io>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
@@ -863,3 +864,34 @@ float libvlc_video_get_adjust_float( libvlc_media_player_t *p_mi,
{
return get_float( p_mi, "adjust", adjust_option_bynumber(option) );
}
+
+void libvlc_video_unset_projection_mode(libvlc_media_player_t *player)
+{
+ var_SetInteger(player, "projection-mode", -1);
+
+ /* Apply to current video outputs (if any) */
+ size_t n;
+ vout_thread_t **pp_vouts = GetVouts(player, &n);
+ for (size_t i = 0; i < n; i++)
+ {
+ var_SetInteger(pp_vouts[i], "projection-mode", -1);
+ vout_Release(pp_vouts[i]);
+ }
+ free (pp_vouts);
+}
+
+void libvlc_video_set_projection_mode(libvlc_media_player_t *player,
+ libvlc_video_projection_t projection_mode)
+{
+ var_SetInteger(player, "projection-mode", projection_mode);
+
+ /* Apply to current video outputs (if any) */
+ size_t n;
+ vout_thread_t **pp_vouts = GetVouts(player, &n);
+ for (size_t i = 0; i < n; i++)
+ {
+ var_SetInteger(pp_vouts[i], "projection-mode", projection_mode);
+ vout_Release(pp_vouts[i]);
+ }
+ free (pp_vouts);
+}
=====================================
modules/control/hotkeys.c
=====================================
@@ -915,6 +915,12 @@ VOUT_ACTION_HANDLER(SubtitleDisplay)
}
}
+VOUT_ACTION_HANDLER(Projection)
+{
+ (void)intf; (void)action_id;
+ var_ToggleBool(vout, "override-projection");
+}
+
/****************
* action table *
****************/
@@ -993,6 +999,7 @@ static struct vlc_action const actions[] =
VLC_ACTION_VOUT(TOGGLE_AUTOSCALE, ZOOM_DOUBLE, Zoom)
VLC_ACTION_VOUT(DEINTERLACE, DEINTERLACE_MODE, Deinterlace)
VLC_ACTION_VOUT(SUBPOS_DOWN, SUBTITLE_TEXT_SCALE_UP, SubtitleDisplay)
+ VLC_ACTION_VOUT(PROJECTION_TOGGLE, PROJECTION_TOGGLE, Projection)
/* null action */
{ .type = NULL_ACTION }
=====================================
modules/video_output/apple/VLCSampleBufferDisplay.m
=====================================
@@ -1132,7 +1132,10 @@ static int Open (vout_display_t *vd,
vd->sys = (__bridge_retained void*)sys;
static const struct vlc_display_operations ops = {
- Close, Prepare, Display, Control, NULL, NULL, NULL,
+ .close = Close,
+ .prepare = Prepare,
+ .display = Display,
+ .control = Control,
};
vd->ops = &ops;
=====================================
modules/video_output/caopengllayer.m
=====================================
@@ -6,6 +6,7 @@
* Authors: David Fuhrmann <david dot fuhrmann at googlemail dot com>
* Felix Paul Kühne <fkuehne at videolan dot org>
* Pierre d'Herbemont <pdherbemont at videolan dot org>
+ * Alexandre Janniaux <ajanni at videolabs.io>
*
* Some of the code is based on mpv's video_layer.swift by "der richter"
*
@@ -109,6 +110,9 @@ typedef struct vout_display_sys_t {
vout_display_place_t place;
vout_display_cfg_t cfg;
+ bool change_projection;
+ video_projection_mode_t projection;
+ vlc_viewpoint_t viewpoint;
} vout_display_sys_t;
#pragma mark -
@@ -235,11 +239,20 @@ static int SetViewpoint(vout_display_t *vd, const vlc_viewpoint_t *vp)
if (vlc_gl_MakeCurrent(sys->gl) != VLC_SUCCESS)
return VLC_EGENERIC;
+ sys->viewpoint = *vp;
int ret = vout_display_opengl_SetViewpoint(sys->vgl, vp);
vlc_gl_ReleaseCurrent(sys->gl);
return ret;
}
+static int ChangeSourceProjection(vout_display_t *vd, video_projection_mode_t projection)
+{
+ vout_display_sys_t *sys = vd->sys;
+ sys->projection = projection;
+ sys->change_projection = true;
+ return VLC_SUCCESS;
+}
+
/**
* Flush the OpenGL context
* In case of double-buffering swaps the back buffer with the front buffer.
@@ -352,6 +365,15 @@ static void PictureRender (vout_display_t *vd, picture_t *pic,
if (vlc_gl_MakeCurrent(sys->gl) == VLC_SUCCESS)
{
+ if (sys->change_projection)
+ {
+ vout_display_opengl_ChangeProjection(sys->vgl, sys->projection);
+ vout_display_opengl_Viewport(sys->vgl, sys->place.x, sys->place.y,
+ sys->place.width, sys->place.height);
+ vout_display_opengl_SetOutputSize(sys->vgl, sys->cfg.display.width, sys->cfg.display.height);
+
+ sys->change_projection = false;
+ }
vout_display_opengl_Prepare(sys->vgl, pic, subpicture);
vlc_gl_ReleaseCurrent(sys->gl);
@@ -446,6 +468,8 @@ static int Open (vout_display_t *vd,
vd->sys = sys = calloc(1, sizeof(*sys));
if (sys == NULL)
return VLC_ENOMEM;
+ sys->projection = vd->cfg->projection;
+ sys->change_projection = false;
id container = (__bridge id)vd->cfg->window->handle.nsobject;
if (!container) {
@@ -516,6 +540,7 @@ static int Open (vout_display_t *vd,
return VLC_EGENERIC;
}
+ sys->viewpoint = vd->cfg->viewpoint;
sys->vgl = vout_display_opengl_New(fmt, &spu_chromas, sys->gl,
&vd->cfg->viewpoint, context);
vlc_gl_ReleaseCurrent(sys->gl);
@@ -534,6 +559,7 @@ static int Open (vout_display_t *vd,
.display = PictureDisplay,
.control = Control,
.set_viewpoint = SetViewpoint,
+ .change_source_projection = ChangeSourceProjection,
};
vd->ops = &ops;
=====================================
modules/video_output/opengl/display.c
=====================================
@@ -78,6 +78,7 @@ typedef struct vout_display_sys_t
vout_display_place_t place;
bool place_changed;
bool is_dirty;
+ bool restart_renderer;
struct {
PFNGLFLUSHPROC Flush;
@@ -116,26 +117,11 @@ UpdateFormat(vout_display_t *vd, const video_format_t *fmt,
/* Force to recompute the viewport on next picture */
sys->place_changed = true;
- /* Restore viewpoint */
- int vp_ret = vout_display_opengl_SetViewpoint(sys->vgl, &sys->viewpoint);
- /* The viewpoint previously applied is necessarily valid */
- assert(vp_ret == VLC_SUCCESS);
- (void) vp_ret;
-
vlc_gl_ReleaseCurrent(sys->gl);
return ret;
}
-static const struct vlc_display_operations ops = {
- .close = Close,
- .prepare = PictureRender,
- .display = PictureDisplay,
- .control = Control,
- .set_viewpoint = SetViewpoint,
- .update_format = UpdateFormat,
-};
-
static void PlacePicture(vout_display_t *vd, vout_display_place_t *place,
struct vout_display_placement dp)
{
@@ -173,6 +159,31 @@ static void PlacePicture(vout_display_t *vd, vout_display_place_t *place,
video_format_Clean(&source);
}
+static void UpdateConfig(vout_display_t *vd)
+{
+ vout_display_sys_t *sys = vd->sys;
+ PlacePicture(vd, &sys->place, vd->cfg->display);
+ sys->place_changed = true;
+}
+
+static int ChangeSourceProjection(vout_display_t *vd, video_projection_mode_t projection)
+{
+ vout_display_sys_t *sys = vd->sys;
+ UpdateConfig(vd);
+ sys->restart_renderer = true;
+ return VLC_SUCCESS;
+}
+
+static const struct vlc_display_operations ops = {
+ .close = Close,
+ .prepare = PictureRender,
+ .display = PictureDisplay,
+ .control = Control,
+ .set_viewpoint = SetViewpoint,
+ .update_format = UpdateFormat,
+ .change_source_projection = ChangeSourceProjection,
+};
+
/**
* Allocates a surface and an OpenGL context for video output.
*/
@@ -287,8 +298,12 @@ static void PictureRender (vout_display_t *vd, picture_t *pic,
if (vlc_gl_MakeCurrent (sys->gl) == VLC_SUCCESS)
{
- vout_display_opengl_Prepare (sys->vgl, pic, subpicture);
- sys->vt.Flush();
+ if (sys->restart_renderer)
+ {
+ vout_display_opengl_ChangeProjection(sys->vgl, vd->cfg->projection);
+ sys->restart_renderer = false;
+ }
+
if (sys->place_changed)
{
vout_display_opengl_SetOutputSize(sys->vgl, vd->cfg->display.width,
@@ -297,7 +312,10 @@ static void PictureRender (vout_display_t *vd, picture_t *pic,
sys->place.width, sys->place.height);
sys->place_changed = false;
}
+
+ vout_display_opengl_Prepare (sys->vgl, pic, subpicture);
vout_display_opengl_Display(sys->vgl);
+
sys->vt.Flush();
vlc_gl_ReleaseCurrent (sys->gl);
sys->is_dirty = true;
@@ -321,21 +339,24 @@ static int Control (vout_display_t *vd, int query)
switch (query)
{
- case VOUT_DISPLAY_CHANGE_DISPLAY_SIZE:
- vlc_gl_Resize (sys->gl, vd->cfg->display.width, vd->cfg->display.height);
- // fallthrough
- case VOUT_DISPLAY_CHANGE_SOURCE_ASPECT:
- case VOUT_DISPLAY_CHANGE_SOURCE_CROP:
- case VOUT_DISPLAY_CHANGE_SOURCE_PLACE:
- {
- struct vout_display_placement dp = vd->cfg->display;
-
- PlacePicture(vd, &sys->place, dp);
- sys->place_changed = true;
- return VLC_SUCCESS;
- }
- default:
- msg_Err (vd, "Unknown request %d", query);
+ case VOUT_DISPLAY_CHANGE_DISPLAY_SIZE:
+ UpdateConfig(vd);
+ vlc_gl_Resize (sys->gl, vd->cfg->display.width, vd->cfg->display.height);
+ // fallthrough
+ case VOUT_DISPLAY_CHANGE_SOURCE_ASPECT:
+ case VOUT_DISPLAY_CHANGE_SOURCE_CROP:
+ case VOUT_DISPLAY_CHANGE_SOURCE_PLACE:
+ {
+ struct vout_display_placement dp = vd->cfg->display;
+
+ PlacePicture(vd, &sys->place, dp);
+ sys->place_changed = true;
+ UpdateConfig(vd);
+ return VLC_SUCCESS;
+ }
+
+ default:
+ msg_Err (vd, "Unknown request %d", query);
}
return VLC_EGENERIC;
}
=====================================
modules/video_output/opengl/filters.c
=====================================
@@ -4,6 +4,8 @@
* Copyright (C) 2020 VLC authors and VideoLAN
* Copyright (C) 2020 Videolabs
*
+ * Authors: Alexandre Janniaux <ajanni at videolabs.io>
+ *
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
@@ -206,6 +208,84 @@ vlc_gl_filters_Delete(struct vlc_gl_filters *filters)
free(filters);
}
+static struct vlc_gl_filter_priv *
+vlc_gl_filters_CreateNewFilter(struct vlc_gl_filters *filters,
+ struct vlc_gl_filter_priv *prev_filter,
+ const char *name,
+ const config_chain_t *config)
+{
+ struct vlc_gl_filter *filter = vlc_gl_filter_New(filters->gl, filters->api);
+ if (!filter)
+ return NULL;
+ filter->gl = filters->gl;
+
+ struct vlc_gl_filter_priv *priv = vlc_gl_filter_PRIV(filter);
+ vlc_list_init(&priv->blend_subfilters);
+
+ struct vlc_gl_tex_size size_in;
+ struct vlc_gl_format *glfmt = &priv->glfmt_in;
+
+ if (!prev_filter)
+ {
+ size_in.width = filters->interop->fmt_out.i_visible_width;
+ size_in.height = filters->interop->fmt_out.i_visible_height;
+
+ assert(filters->importer);
+ *glfmt = filters->importer->glfmt;
+ }
+ else
+ {
+ size_in = prev_filter->size_out;
+
+ /* If the previous filter operated on planes, then its output chroma is
+ * the same as its input chroma. Otherwise, it's RGBA. */
+ vlc_fourcc_t chroma = prev_filter->filter.config.filter_planes
+ ? prev_filter->glfmt_in.fmt.i_chroma
+ : VLC_CODEC_RGBA;
+
+ video_format_t *fmt = &glfmt->fmt;
+ video_format_Init(fmt, chroma);
+ fmt->i_width = fmt->i_visible_width = prev_filter->size_out.width;
+ fmt->i_height = fmt->i_visible_height = prev_filter->size_out.height;
+
+ glfmt->tex_target = GL_TEXTURE_2D;
+ glfmt->tex_count = prev_filter->plane_count;
+
+ size_t size = glfmt->tex_count * sizeof(GLsizei);
+ memcpy(glfmt->tex_widths, prev_filter->plane_widths, size);
+ memcpy(glfmt->tex_heights, prev_filter->plane_heights, size);
+ }
+
+ /* By default, the output size is the same as the input size. The filter
+ * may change it during its Open(). */
+ priv->size_out = size_in;
+
+ int ret = vlc_gl_filter_LoadModule(filters->gl, name, filter, config,
+ glfmt, &priv->size_out);
+ if (ret != VLC_SUCCESS)
+ {
+ /* Creation failed, do not call close() */
+ msg_Err(filters->gl, "Could not load OpenGL filter '%s'", name);
+ filter->ops = NULL;
+ vlc_gl_filter_Delete(filter);
+ return NULL;
+ }
+
+ /* A blend filter may not change its output size. */
+ assert(!filter->config.blend
+ || (priv->size_out.width == size_in.width
+ && priv->size_out.height == size_in.height));
+
+ /* A filter operating on planes may not blend. */
+ assert(!filter->config.filter_planes || !filter->config.blend);
+
+ /* A filter operating on planes may not use anti-aliasing. */
+ assert(!filter->config.filter_planes || !filter->config.msaa_level);
+ vlc_gl_filter_InitPlaneSizes(filter);
+
+ return priv;
+}
+
struct vlc_gl_filter *
vlc_gl_filters_Append(struct vlc_gl_filters *filters, const char *name,
const config_chain_t *config)
@@ -313,6 +393,36 @@ vlc_gl_filters_Append(struct vlc_gl_filters *filters, const char *name,
return filter;
}
+struct vlc_gl_filter *
+vlc_gl_filters_Replace(struct vlc_gl_filters *filters, struct vlc_gl_filter *old_filter,
+ const char *name, const config_chain_t *config)
+{
+ struct vlc_gl_filter_priv *old_priv = vlc_gl_filter_PRIV(old_filter);
+ struct vlc_gl_filter *prev_filter = NULL;
+ struct vlc_gl_filter_priv *priv_prev = vlc_gl_filter_PRIV(prev_filter);
+
+ struct vlc_gl_filter_priv *new_filter = vlc_gl_filters_CreateNewFilter(filters, priv_prev, name, config);
+ if (new_filter == NULL)
+ return NULL;
+
+ assert(!new_filter->filter.config.blend && !old_filter->config.blend);
+ vlc_gl_filter_InitPlaneSizes(old_filter);
+
+ /* Move previous subfilter to the new filter */
+ struct vlc_gl_filter_priv *subfilter;
+ vlc_list_foreach(subfilter, &old_priv->blend_subfilters, node)
+ {
+ vlc_list_remove(&subfilter->node);
+ vlc_list_append(&subfilter->node, &new_filter->blend_subfilters);
+ }
+
+ /* Append to the main filter list */
+ vlc_list_replace(&old_priv->node, &new_filter->node);
+ vlc_gl_filter_Delete(old_filter);
+
+ return &new_filter->filter;
+}
+
int
vlc_gl_filters_InitFramebuffers(struct vlc_gl_filters *filters)
{
=====================================
modules/video_output/opengl/filters.h
=====================================
@@ -68,6 +68,12 @@ struct vlc_gl_filter *
vlc_gl_filters_Append(struct vlc_gl_filters *filters, const char *name,
const config_chain_t *config);
+struct vlc_gl_filter *
+vlc_gl_filters_Replace(struct vlc_gl_filters *filters,
+ struct vlc_gl_filter *filter,
+ const char *name,
+ const config_chain_t *config);
+
/**
* Init the framebuffers for the appended filters.
*
=====================================
modules/video_output/opengl/renderer.c
=====================================
@@ -38,6 +38,7 @@
#include <vlc_es.h>
#include <vlc_picture.h>
#include <vlc_opengl_filter.h>
+#include <vlc_configuration.h>
#include "gl_util.h"
#include "vout_helper.h"
@@ -356,8 +357,7 @@ vlc_gl_renderer_SetViewpoint(struct vlc_gl_renderer *renderer,
UpdateFOVy(renderer);
UpdateZ(renderer);
}
- const video_format_t *fmt = &renderer->sampler->glfmt.fmt;
- getViewpointMatrixes(renderer, fmt->projection_mode);
+ getViewpointMatrixes(renderer, renderer->projection_mode);
return VLC_SUCCESS;
}
@@ -377,8 +377,7 @@ vlc_gl_renderer_SetOutputSize(struct vlc_gl_renderer *renderer, unsigned width,
UpdateFOVy(renderer);
UpdateZ(renderer);
- const video_format_t *fmt = &renderer->sampler->glfmt.fmt;
- getViewpointMatrixes(renderer, fmt->projection_mode);
+ getViewpointMatrixes(renderer, renderer->projection_mode);
}
static int
@@ -675,7 +674,7 @@ static int SetupCoords(struct vlc_gl_renderer *renderer,
unsigned nbVertices, nbIndices;
int i_ret;
- switch (fmt->projection_mode)
+ switch (renderer->projection_mode)
{
case PROJECTION_MODE_RECTANGULAR:
i_ret = BuildRectangle(&vertexCoord, &textureCoord, &nbVertices,
@@ -797,9 +796,11 @@ vlc_gl_renderer_Open(struct vlc_gl_filter *filter,
const struct vlc_gl_format *glfmt,
struct vlc_gl_tex_size *size_out)
{
- (void) config;
(void) size_out;
+ const char * const options[] = { "projection-mode", NULL };
+ config_ChainParse(filter, "", options, config);
+
const opengl_vtable_t *vt = &filter->api->vt;
struct vlc_gl_sampler *sampler =
@@ -828,6 +829,18 @@ vlc_gl_renderer_Open(struct vlc_gl_filter *filter,
renderer->vt = vt;
renderer->dump_shaders = var_InheritInteger(filter, "verbose") >= 4;
+ int projection_mode = var_InheritInteger(filter, "projection-mode");
+ switch (projection_mode)
+ {
+ case PROJECTION_MODE_RECTANGULAR:
+ renderer->projection_mode = projection_mode;
+ break;
+ default:
+ case -1:
+ renderer->projection_mode = sampler->glfmt.fmt.projection_mode;
+ break;
+ }
+
int ret = opengl_link_program(filter);
if (ret != VLC_SUCCESS)
{
=====================================
modules/video_output/opengl/renderer.h
=====================================
@@ -101,6 +101,9 @@ struct vlc_gl_renderer
* f_sar = (float) target_width / target_height */
unsigned target_width;
unsigned target_height;
+
+ /* Projection mode for the input data */
+ video_projection_mode_t projection_mode;
};
vlc_gl_filter_open_fn vlc_gl_renderer_Open;
=====================================
modules/video_output/opengl/vout_helper.c
=====================================
@@ -10,6 +10,7 @@
* Adrien Maglo <magsoft at videolan dot org>
* Felix Paul Kühne <fkuehne at videolan dot org>
* Pierre d'Herbemont <pdherbemont at videolan dot org>
+ * Alexandre Janniaux <ajanni at videolabs.io>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
@@ -55,11 +56,15 @@ struct vout_display_opengl_t {
struct vlc_gl_interop *interop;
struct vlc_gl_renderer *renderer; /**< weak reference */
+ struct vlc_gl_filter *renderer_filter; /**< weak reference */
struct vlc_gl_filters *filters;
struct vlc_gl_interop *sub_interop;
struct vlc_gl_sub_renderer *sub_renderer;
+
+ vlc_viewpoint_t viewpoint;
+ video_projection_mode_t projection;
};
static const vlc_fourcc_t gl_subpicture_chromas[] = {
@@ -99,7 +104,7 @@ ResizeFormatToGLMaxTexSize(video_format_t *fmt, unsigned int max_tex_size)
static struct vlc_gl_filters *
CreateFilters(vlc_gl_t *gl, const struct vlc_gl_api *api,
struct vlc_gl_interop *interop,
- struct vlc_gl_renderer **out_renderer)
+ struct vlc_gl_filter **out_renderer)
{
struct vlc_gl_filters *filters = vlc_gl_filters_New(gl, api, interop, gl->orientation);
if (!filters)
@@ -166,7 +171,7 @@ CreateFilters(vlc_gl_t *gl, const struct vlc_gl_api *api,
/* The renderer is a special filter: we need its concrete instance to
* forward SetViewpoint() */
- *out_renderer = renderer_filter->sys;
+ *out_renderer = renderer_filter;
return filters;
@@ -175,6 +180,41 @@ error:
return NULL;
}
+int vout_display_opengl_ChangeProjection(vout_display_opengl_t *vgl,
+ video_projection_mode_t projection)
+{
+ const config_chain_t chain = {
+ .psz_name = strdup("projection-mode"),
+ .psz_value = strdup(projection == PROJECTION_MODE_RECTANGULAR ? "0" : "-1"),
+ };
+
+ 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);
+ if (new_renderer == NULL)
+ {
+ msg_Err(vgl->gl, "Could not re-create renderer filter for projection mode %d",
+ (int)projection);
+ return VLC_EGENERIC;
+ }
+
+ int ret = vlc_gl_filters_InitFramebuffers(vgl->filters);
+ if (ret != VLC_SUCCESS)
+ {
+ msg_Err(vgl->gl, "Could not init filters framebuffers");
+ return VLC_EGENERIC;
+ }
+
+ vgl->renderer_filter = new_renderer;
+ vgl->renderer = new_renderer->sys;
+
+ vlc_gl_renderer_SetViewpoint(vgl->renderer, &vgl->viewpoint);
+
+ msg_Dbg(vgl->gl, "Changed to projection mode %d", projection);
+ 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,
@@ -221,12 +261,13 @@ vout_display_opengl_t *vout_display_opengl_New(video_format_t *fmt,
}
GL_ASSERT_NOERROR(vt);
- vgl->filters = CreateFilters(gl, api, vgl->interop, &vgl->renderer);
+ vgl->filters = CreateFilters(gl, api, vgl->interop, &vgl->renderer_filter);
if (!vgl->filters)
{
msg_Err(gl, "Could not create filters");
goto delete_interop;
}
+ vgl->renderer = vgl->renderer_filter->sys;
GL_ASSERT_NOERROR(vt);
vgl->sub_interop = vlc_gl_interop_NewForSubpictures(gl);
@@ -247,6 +288,7 @@ vout_display_opengl_t *vout_display_opengl_New(video_format_t *fmt,
GL_ASSERT_NOERROR(vt);
+ vlc_viewpoint_init(&vgl->viewpoint);
if (fmt->projection_mode != PROJECTION_MODE_RECTANGULAR
&& vout_display_opengl_SetViewpoint(vgl, viewpoint) != VLC_SUCCESS)
msg_Err(gl, "Could not set viewpoint");
@@ -304,7 +346,7 @@ int vout_display_opengl_UpdateFormat(vout_display_opengl_t *vgl,
return VLC_EGENERIC;
}
- struct vlc_gl_renderer *renderer;
+ struct vlc_gl_filter *renderer;
struct vlc_gl_filters *filters = CreateFilters(gl, api, interop, &renderer);
if (!filters)
{
@@ -319,7 +361,10 @@ int vout_display_opengl_UpdateFormat(vout_display_opengl_t *vgl,
vgl->interop = interop;
vgl->filters = filters;
- vgl->renderer = renderer;
+ vgl->renderer = renderer->sys;
+ vgl->renderer_filter = renderer;
+
+ vlc_gl_renderer_SetViewpoint(vgl->renderer, &vgl->viewpoint);
return VLC_SUCCESS;
}
@@ -348,7 +393,10 @@ void vout_display_opengl_Delete(vout_display_opengl_t *vgl)
int vout_display_opengl_SetViewpoint(vout_display_opengl_t *vgl,
const vlc_viewpoint_t *p_vp)
{
- return vlc_gl_renderer_SetViewpoint(vgl->renderer, p_vp);
+ int ret = vlc_gl_renderer_SetViewpoint(vgl->renderer, p_vp);
+ if (ret == VLC_SUCCESS)
+ vgl->viewpoint = *p_vp;
+ return ret;
}
void vout_display_opengl_SetOutputSize(vout_display_opengl_t *vgl,
=====================================
modules/video_output/opengl/vout_helper.h
=====================================
@@ -87,4 +87,7 @@ int vout_display_opengl_UpdateFormat(vout_display_opengl_t *vgl,
const video_format_t *fmt,
vlc_video_context *vctx);
+int vout_display_opengl_ChangeProjection(vout_display_opengl_t *vgl,
+ video_projection_mode_t projection);
+
#endif
=====================================
modules/video_output/win32/direct3d11.cpp
=====================================
@@ -5,6 +5,7 @@
*
* Authors: Martell Malone <martellmalone at gmail.com>
* Steve Lhomme <robux4 at gmail.com>
+ * Alexandre Janniaux <ajanni at videolabs.io>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
@@ -144,7 +145,7 @@ typedef struct vout_display_sys_t
ComPtr<ID3D11VideoProcessorOutputView> outputView;
} old_feature;
-
+ video_projection_mode_t projection_mode;
d3d11_vertex_shader_t projectionVShader = {};
d3d11_vertex_shader_t flatVShader = {};
@@ -493,6 +494,13 @@ error:
msg_Dbg(vd, "failed to create the tone mapper, using default HDR mode");
}
+static int ChangeSourceProjection(vout_display_t *vd, video_projection_mode_t projection)
+{
+ vout_display_sys_t *sys = static_cast<vout_display_sys_t *>(vd->sys);
+ sys->projection_mode = projection;
+ return Direct3D11CreateFormatResources(vd, vd->source);
+}
+
static const auto ops = []{
struct vlc_display_operations ops {};
ops.close = Close;
@@ -500,6 +508,7 @@ static const auto ops = []{
ops.display = Display;
ops.control = Control;
ops.set_viewpoint = SetViewpoint;
+ ops.change_source_projection = ChangeSourceProjection;
return ops;
}();
@@ -542,6 +551,7 @@ static int Open(vout_display_t *vd,
dev_sys = sys->local_d3d_dev;
}
sys->d3d_dev = &dev_sys->d3d_dev;
+ sys->projection_mode = vd->cfg->projection;
InitTonemapProcessor(vd, vd->source);
@@ -554,7 +564,7 @@ static int Open(vout_display_t *vd,
if (vd->cfg->window->type == VLC_WINDOW_TYPE_HWND)
{
if (CommonWindowInit(vd, &sys->area,
- vd->source->projection_mode != PROJECTION_MODE_RECTANGULAR))
+ sys->projection_mode != PROJECTION_MODE_RECTANGULAR))
goto error;
}
@@ -890,7 +900,7 @@ static void PreparePicture(vout_display_t *vd, picture_t *picture,
renderSrc = p_sys->renderSrc;
}
D3D11_RenderQuad(sys->d3d_dev, &sys->picQuad,
- vd->source->projection_mode == PROJECTION_MODE_RECTANGULAR ? &sys->flatVShader : &sys->projectionVShader,
+ sys->projection_mode == PROJECTION_MODE_RECTANGULAR ? &sys->flatVShader : &sys->projectionVShader,
renderSrc, SelectRenderPlane, sys);
if (subpicture) {
@@ -1421,7 +1431,7 @@ static int Direct3D11CreateFormatResources(vout_display_t *vd, const video_forma
return VLC_EGENERIC;
}
- if (D3D11_AllocateQuad(vd, sys->d3d_dev, sys->picQuad.quad_fmt.projection_mode, &sys->picQuad) != VLC_SUCCESS)
+ if (D3D11_AllocateQuad(vd, sys->d3d_dev, sys->projection_mode, &sys->picQuad) != VLC_SUCCESS)
{
msg_Err(vd, "Could not allocate quad buffers.");
return VLC_EGENERIC;
@@ -1440,8 +1450,8 @@ static int Direct3D11CreateFormatResources(vout_display_t *vd, const video_forma
return VLC_EGENERIC;
}
- if ( vd->source->projection_mode == PROJECTION_MODE_EQUIRECTANGULAR ||
- vd->source->projection_mode == PROJECTION_MODE_CUBEMAP_LAYOUT_STANDARD )
+ if ( sys->projection_mode == PROJECTION_MODE_EQUIRECTANGULAR ||
+ sys->projection_mode == PROJECTION_MODE_CUBEMAP_LAYOUT_STANDARD )
D3D11_UpdateViewpoint( vd, sys->d3d_dev, &sys->picQuad, &vd->cfg->viewpoint,
(float) vd->cfg->display.width / vd->cfg->display.height );
=====================================
src/libvlc-module.c
=====================================
@@ -336,6 +336,10 @@ static const char *const ppsz_align_descriptions[] =
#define FULLSCREEN_LONGTEXT N_( \
"Start video in fullscreen mode" )
+#define PROJECTION_MODE_TEXT N_("360 videos projection mode")
+#define PROJECTION_MODE_LONGTEXT N_( \
+ "Change the 360 video projection mode.")
+
#define VIDEO_ON_TOP_TEXT N_("Always on top")
#define VIDEO_ON_TOP_LONGTEXT N_( \
"Always place the video window on top of other windows." )
@@ -1645,6 +1649,9 @@ vlc_module_begin ()
add_bool( "fullscreen", false, FULLSCREEN_TEXT, FULLSCREEN_LONGTEXT )
change_short('f')
change_safe ()
+ add_integer("projection-mode", -1, PROJECTION_MODE_TEXT, PROJECTION_MODE_LONGTEXT)
+ change_volatile ()
+ change_safe ()
add_bool( "embedded-video", true, EMBEDDED_TEXT, EMBEDDED_LONGTEXT )
add_bool( "xlib", true, "", "" )
change_private ()
@@ -2290,6 +2297,7 @@ vlc_module_begin ()
# define KEY_RATE_SLOWER_FINE NULL
# define KEY_NEXT "Command+Right"
# define KEY_PREV "Command+Left"
+# define KEY_PROJECTION_TOGGLE NULL
# define KEY_STOP "Command+."
# define KEY_POSITION "t"
# define KEY_JUMP_MEXTRASHORT "Command+Ctrl+Left"
@@ -2423,6 +2431,7 @@ vlc_module_begin ()
# define KEY_PREV "p\tMedia Prev Track"
# define KEY_STOP "s\tMedia Stop"
#endif
+# define KEY_PROJECTION_TOGGLE NULL
# define KEY_POSITION "t"
# define KEY_JUMP_MEXTRASHORT "Shift+Left"
# define KEY_JUMP_PEXTRASHORT "Shift+Right"
@@ -2563,6 +2572,7 @@ vlc_module_begin ()
RATE_SLOWER_FINE_KEY_TEXT, RATE_SLOWER_FINE_KEY_LONGTEXT)
add_key("key-next", KEY_NEXT, NEXT_KEY_TEXT, NEXT_KEY_LONGTEXT)
add_key("key-prev", KEY_PREV, PREV_KEY_TEXT, PREV_KEY_LONGTEXT)
+ add_key("key-projection-toggle", KEY_PROJECTION_TOGGLE, "", "")
add_key("key-stop", KEY_STOP, STOP_KEY_TEXT, STOP_KEY_LONGTEXT)
add_key("key-position", KEY_POSITION, POSITION_KEY_TEXT,
POSITION_KEY_LONGTEXT)
=====================================
src/misc/actions.c
=====================================
@@ -340,6 +340,7 @@ static const struct name2action
{ "prev", ACTIONID_PREV, },
{ "program-sid-next", ACTIONID_PROGRAM_SID_NEXT, },
{ "program-sid-prev", ACTIONID_PROGRAM_SID_PREV, },
+ { "projection-toggle", ACTIONID_PROJECTION_TOGGLE, },
{ "quit", ACTIONID_QUIT, },
{ "random", ACTIONID_RANDOM, },
{ "rate-faster-fine", ACTIONID_RATE_FASTER_FINE, },
=====================================
src/video_output/display.c
=====================================
@@ -762,6 +762,14 @@ int vout_SetDisplayFormat(vout_display_t *vd, const video_format_t *fmt,
return VLC_SUCCESS;
}
+void vout_SetDisplayProjection(vout_display_t *vd,
+ video_projection_mode_t projection)
+{
+ vout_display_priv_t *osys = container_of(vd, vout_display_priv_t, display);
+ osys->cfg.projection = projection;
+ vout_display_ChangeProjection(vd, projection);
+}
+
vout_display_t *vout_display_New(vlc_object_t *parent,
const video_format_t *source,
vlc_video_context *vctx,
=====================================
src/video_output/video_output.c
=====================================
@@ -119,6 +119,7 @@ typedef struct vout_thread_sys_t
bool is_interlaced;
picture_t *decoded; // decoded picture before passed through chain_static
picture_t *current;
+ video_projection_mode_t projection;
} displayed;
struct {
@@ -677,6 +678,50 @@ void vout_ChangeIccProfile(vout_thread_t *vout,
vlc_queuedmutex_unlock(&sys->display_lock);
}
+void vout_ToggleProjection(vout_thread_t *vout, bool enabled)
+{
+ vout_thread_sys_t *sys = VOUT_THREAD_TO_SYS(vout);
+ assert(!sys->dummy);
+
+ video_projection_mode_t projection;
+ if (sys->displayed.projection != PROJECTION_MODE_RECTANGULAR && !enabled)
+ projection = PROJECTION_MODE_RECTANGULAR;
+ else if (sys->original.projection_mode != PROJECTION_MODE_RECTANGULAR && enabled)
+ projection = sys->original.projection_mode;
+ else return;
+
+ vlc_queuedmutex_lock(&sys->display_lock);
+ if (sys->display != NULL)
+ vout_SetDisplayProjection(sys->display, projection);
+ vlc_queuedmutex_unlock(&sys->display_lock);
+
+}
+
+void vout_ResetProjection(vout_thread_t *vout)
+{
+ vout_thread_sys_t *sys = VOUT_THREAD_TO_SYS(vout);
+ assert(!sys->dummy);
+
+ msg_Dbg(vout, "resetting projection_mode to %d", sys->original.projection_mode);
+ vout_ChangeProjection(vout, sys->original.projection_mode);
+}
+
+void vout_ChangeProjection(vout_thread_t *vout,
+ video_projection_mode_t projection)
+{
+ vout_thread_sys_t *sys = VOUT_THREAD_TO_SYS(vout);
+ assert(!sys->dummy);
+
+ /* Use vout_ResetProjection instead. */
+ assert((int)projection != -1);
+ msg_Dbg(vout, "setting projection_mode to %d", projection);
+
+ vlc_queuedmutex_lock(&sys->display_lock);
+ if (sys->display != NULL)
+ vout_SetDisplayProjection(sys->display, projection);
+ vlc_queuedmutex_unlock(&sys->display_lock);
+}
+
/* */
static void VoutGetDisplayCfg(vout_thread_sys_t *p_vout, const video_format_t *fmt, vout_display_cfg_t *cfg)
{
@@ -1814,6 +1859,12 @@ static int vout_Start(vout_thread_sys_t *vout, vlc_video_context *vctx, const vo
dcfg.display.width = sys->window_width;
dcfg.display.height = sys->window_height;
+ int projection = var_InheritInteger(&vout->obj, "projection-mode");
+ if (projection == -1)
+ dcfg.projection = sys->original.projection_mode;
+ else if (projection >= 0)
+ dcfg.projection = (video_projection_mode_t)projection;
+
sys->private_pool =
picture_pool_NewFromFormat(&sys->original, FILTER_POOL_SIZE);
if (sys->private_pool == NULL) {
@@ -2306,6 +2357,7 @@ int vout_Request(const vout_configuration_t *cfg, vlc_video_context *vctx, input
vlc_mutex_lock(&sys->window_lock);
video_format_Clean(&sys->original);
sys->original = original;
+ sys->displayed.projection = original.projection_mode;
vout_InitSource(vout);
if (EnableWindowLocked(vout, &original) != 0)
=====================================
src/video_output/vout_internal.h
=====================================
@@ -161,6 +161,9 @@ void vout_ControlChangeSubFilters(vout_thread_t *, const char *);
void vout_ChangeSpuChannelMargin(vout_thread_t *, enum vlc_vout_order order, int);
void vout_ChangeViewpoint( vout_thread_t *, const vlc_viewpoint_t *);
void vout_ChangeIccProfile(vout_thread_t *, vlc_icc_profile_t *);
+void vout_ChangeProjection(vout_thread_t *, video_projection_mode_t projection);
+void vout_ToggleProjection(vout_thread_t *, bool enabled);
+void vout_ResetProjection(vout_thread_t *);
void vout_FilterMouse(vout_thread_t *vout, vlc_mouse_t *mouse);
=====================================
src/video_output/vout_intf.c
=====================================
@@ -83,6 +83,12 @@ static int SecondarySubMarginCallback( vlc_object_t *, char const *,
static int ViewpointCallback( vlc_object_t *, char const *,
vlc_value_t, vlc_value_t, void * );
+static int OverrideProjectionCallback( vlc_object_t *, char const *,
+ vlc_value_t, vlc_value_t, void * );
+
+static int ChangeProjectionCallback( vlc_object_t *, char const *,
+ vlc_value_t, vlc_value_t, void * );
+
/*****************************************************************************
* vout_IntfInit: called during the vout creation to initialise misc things.
*****************************************************************************/
@@ -328,6 +334,11 @@ void vout_CreateVars( vout_thread_t *p_vout )
/* SPU in full window */
var_Create( p_vout, "spu-fill", VLC_VAR_BOOL | VLC_VAR_DOINHERIT
| VLC_VAR_ISCOMMAND );
+
+ var_Create(p_vout, "override-projection", VLC_VAR_BOOL);
+ var_SetBool(p_vout, "override-projection", false);
+
+ var_Create(p_vout, "projection-mode", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT);
}
void vout_IntfInit( vout_thread_t *p_vout )
@@ -350,6 +361,8 @@ void vout_IntfInit( vout_thread_t *p_vout )
var_AddCallback( p_vout, "sub-filter", SubFilterCallback, NULL );
var_AddCallback( p_vout, "sub-margin", SubMarginCallback, NULL );
var_AddCallback( p_vout, "viewpoint", ViewpointCallback, NULL );
+ var_AddCallback( p_vout, "override-projection", OverrideProjectionCallback, NULL );
+ var_AddCallback( p_vout, "projection-mode", ChangeProjectionCallback, NULL );
}
void vout_IntfReinit( vout_thread_t *p_vout )
@@ -364,6 +377,8 @@ void vout_IntfReinit( vout_thread_t *p_vout )
cause unwanted OSD on vout start. Filter out it there. */
var_TriggerCallback( p_vout, "sub-margin" );
var_TriggerCallback( p_vout, "secondary-sub-margin" );
+
+ var_TriggerCallback( p_vout, "projection-mode" );
}
void vout_IntfDeinit(vlc_object_t *obj)
@@ -387,6 +402,8 @@ void vout_IntfDeinit(vlc_object_t *obj)
var_DelCallback(obj, "zoom", ZoomCallback, NULL);
var_DelCallback(obj, "fit", FitCallback, NULL);
var_DelCallback(obj, "autoscale", AutoScaleCallback, NULL);
+ var_DelCallback(obj, "override-projection", OverrideProjectionCallback, NULL);
+ var_DelCallback(obj, "projection-mode", ChangeProjectionCallback, NULL);
}
/*****************************************************************************
@@ -614,6 +631,48 @@ static int FitCallback( vlc_object_t *obj, char const *name,
return VLC_SUCCESS;
}
+static int OverrideProjectionCallback( vlc_object_t *obj, char const *name,
+ vlc_value_t prev, vlc_value_t cur, void *data )
+{
+ VLC_UNUSED(name); VLC_UNUSED(prev); VLC_UNUSED(data);
+ vout_thread_t *vout = (vout_thread_t *)obj;
+
+ vout_OSDMessage(vout, VOUT_SPU_CHANNEL_OSD, "Projection: %s", cur.b_bool ? "disabled" : "enabled");
+ vout_ToggleProjection(vout, !cur.b_bool);
+ return VLC_SUCCESS;
+}
+
+static int ChangeProjectionCallback( vlc_object_t *obj, char const *name,
+ vlc_value_t prev, vlc_value_t cur, void *data )
+{
+ VLC_UNUSED(name); VLC_UNUSED(prev); VLC_UNUSED(data);
+ vout_thread_t *vout = (vout_thread_t *)obj;
+
+ const char *projection;
+ switch(cur.i_int)
+ {
+ case -1: projection = "source"; break;
+ case PROJECTION_MODE_RECTANGULAR: projection = "rectangular"; break;
+ case PROJECTION_MODE_EQUIRECTANGULAR: projection = "equirectangular"; break;
+ case PROJECTION_MODE_CUBEMAP_LAYOUT_STANDARD: projection = "cubemap (standard)"; break;
+ default: projection = "unknown"; break;
+ }
+
+ vout_OSDMessage(vout, VOUT_SPU_CHANNEL_OSD, "Projection: %s", projection);
+ if (cur.i_int == -1)
+ {
+ vout_ResetProjection(vout);
+ return VLC_SUCCESS;
+ }
+ else if (cur.i_int < 0 || cur.i_int > (int)PROJECTION_MODE_CUBEMAP_LAYOUT_STANDARD)
+ {
+ return VLC_EGENERIC;
+ }
+
+ vout_ChangeProjection(vout, cur.i_int);
+ return VLC_SUCCESS;
+}
+
static int ZoomCallback( vlc_object_t *obj, char const *name,
vlc_value_t prev, vlc_value_t cur, void *data )
{
=====================================
src/video_output/vout_wrapper.h
=====================================
@@ -42,6 +42,7 @@ int vout_SetDisplayFormat(vout_display_t *, const video_format_t *fmt,
/* The owner/caller is responsible for managing the lifetime of this ICC
* profile and always updating the display state to a consistent value */
void vout_SetDisplayIccProfile(vout_display_t *, const vlc_icc_profile_t *);
+void vout_SetDisplayProjection(vout_display_t *, video_projection_mode_t);
#endif /* LIBVLC_VOUT_WRAPPER_H */
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/7b43acff4f2c342d51a604ae29e34c078e5d188e...9e5e5ca6125de7b086f12c6cacb99d9a493106b1
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/7b43acff4f2c342d51a604ae29e34c078e5d188e...9e5e5ca6125de7b086f12c6cacb99d9a493106b1
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