[vlc-devel] [PATCH 11/15] core: add an option to set the projection mode

Steve Lhomme robux4 at videolabs.io
Mon Nov 7 10:52:00 CET 2016


--
fix older patch with proper value initialization

opengl: reset the viewpoint values when changing the projection mode

replaces https://patches.videolan.org/patch/14436/
* reorder the ch_viewpoint so that the initial viewpoint is used properly
  on startup
* remove unused projection modes
* rename projection_mode to vout_projection_mode_t
* rename PROJECTION_XXX to VOUT_PROJECTION_XXX

replaces https://patches.videolan.org/patch/14917/
* document VOUT_DISPLAY_CHANGE_PROJECTION
* enum layout
---
 include/vlc_vout.h               |  7 +++++++
 include/vlc_vout_display.h       |  6 ++++++
 include/vlc_vout_wrapper.h       |  1 +
 src/libvlc-module.c              | 13 +++++++++++++
 src/video_output/control.h       |  1 +
 src/video_output/display.c       | 28 +++++++++++++++++++++++++++-
 src/video_output/video_output.c  | 15 +++++++++++++++
 src/video_output/vout_internal.h |  1 +
 src/video_output/vout_intf.c     | 34 ++++++++++++++++++++++++++++++++++
 9 files changed, 105 insertions(+), 1 deletion(-)

diff --git a/include/vlc_vout.h b/include/vlc_vout.h
index 57afacc..5537f63 100644
--- a/include/vlc_vout.h
+++ b/include/vlc_vout.h
@@ -82,6 +82,13 @@ struct vout_thread_t {
 #define VOUT_ALIGN_BOTTOM       0x0008
 #define VOUT_ALIGN_VMASK        0x000C
 
+typedef enum {
+    VOUT_PROJECTION_AUTO,
+    VOUT_PROJECTION_FLAT,
+    VOUT_PROJECTION_SPHERE,
+    VOUT_PROJECTION_CUBEMAP,
+} vout_projection_mode_t;
+
 struct vlc_viewpoint_t {
     float yaw;   /* yaw in radians */
     float pitch; /* pitch in radians */
diff --git a/include/vlc_vout_display.h b/include/vlc_vout_display.h
index e1efe00..f83f15b 100644
--- a/include/vlc_vout_display.h
+++ b/include/vlc_vout_display.h
@@ -118,6 +118,8 @@ typedef struct {
 
     vlc_viewpoint_t viewpoint;
 
+    vout_projection_mode_t projection;
+
 } vout_display_cfg_t;
 
 /**
@@ -182,6 +184,10 @@ enum {
     /* Ask the module to acknowledge/refuse VR/360° viewing direction after
      * being requested externally */
     VOUT_DISPLAY_CHANGE_VIEWPOINT,   /* const vout_display_cfg_t *p_cfg */
+
+    /* Ask the module to acknowledge/refuse a different type of viewing
+     * projection like spherical after being requested externally. */
+    VOUT_DISPLAY_CHANGE_PROJECTION, /* const vout_display_cfg_t *p_cfg */
 };
 
 /**
diff --git a/include/vlc_vout_wrapper.h b/include/vlc_vout_wrapper.h
index 2ba4fc6..f6edb94 100644
--- a/include/vlc_vout_wrapper.h
+++ b/include/vlc_vout_wrapper.h
@@ -95,6 +95,7 @@ void vout_SetDisplayCrop(vout_display_t *, unsigned num, unsigned den,
                          unsigned left, unsigned top, int right, int bottom);
 void vout_GetDisplayViewpoint(vout_display_t *, vlc_viewpoint_t *p_viewpoint);
 void vout_SetDisplayViewpoint(vout_display_t *, const vlc_viewpoint_t *p_viewpoint);
+void vout_SetDisplayProjection(vout_display_t *, vout_projection_mode_t);
 
 #endif /* VLC_VOUT_WRAPPER_H */
 
diff --git a/src/libvlc-module.c b/src/libvlc-module.c
index 05b171d..0908aae 100644
--- a/src/libvlc-module.c
+++ b/src/libvlc-module.c
@@ -449,6 +449,17 @@ static const char *const ppsz_pos_descriptions[] =
     "video, in radians." )
 
 
+#define PROJECTION_TEXT N_("Projection")
+#define PROJECTION_LONGTEXT N_( \
+    "Change the way the video is displayed.")
+static const int pi_projection_values[] = { 0, 1, 2, 3 };
+static const char *const ppsz_projection_descriptions[] =
+{ N_("Automatic"),
+  N_("Flat/2D"),
+  N_("360° Sphere"),
+  N_("360° Cubemap"),
+};
+
 #define AUTOSCALE_TEXT N_("Video Auto Scaling")
 #define AUTOSCALE_LONGTEXT N_( \
     "Let the video scale to fit a given window or fullscreen.")
@@ -1614,6 +1625,8 @@ vlc_module_begin ()
     add_float( "viewpoint-roll", 0.,
                 VIEWPOINT_ROLL_TEXT, VIEWPOINT_ROLL_LONGTEXT, false )
         change_safe ()
+    add_integer( "projection", 0, PROJECTION_TEXT, PROJECTION_LONGTEXT, false )
+        change_integer_list( pi_projection_values, ppsz_projection_descriptions )
     add_bool( "autoscale", true, AUTOSCALE_TEXT, AUTOSCALE_LONGTEXT, false )
         change_safe ()
     add_obsolete_float( "scale" ) /* since 3.0.0 */
diff --git a/src/video_output/control.h b/src/video_output/control.h
index add2246..a020d22 100644
--- a/src/video_output/control.h
+++ b/src/video_output/control.h
@@ -59,6 +59,7 @@ enum {
     VOUT_CONTROL_CROP_RATIO,            /* pair */
     VOUT_CONTROL_CROP_WINDOW,           /* window */
     VOUT_CONTROL_VIEWPOINT,             /* viewpoint */
+    VOUT_CONTROL_PROJECTION,            /* integer */
 };
 
 typedef struct {
diff --git a/src/video_output/display.c b/src/video_output/display.c
index 4716755..f6b8e43 100644
--- a/src/video_output/display.c
+++ b/src/video_output/display.c
@@ -377,6 +377,9 @@ struct vout_display_owner_sys_t {
     vlc_viewpoint_t viewpoint;
     vlc_mutex_t viewpoint_lock;
 
+    bool ch_projection;
+    vout_projection_mode_t proj_mode;
+
     /* */
     video_format_t source;
     filter_chain_t *filters;
@@ -855,7 +858,8 @@ bool vout_ManageDisplay(vout_display_t *vd, bool allow_reset_pictures)
 #endif
             !osys->ch_sar &&
             !osys->ch_crop &&
-            !osys->ch_viewpoint) {
+            !osys->ch_viewpoint &&
+            !osys->ch_projection) {
 
             if (!osys->cfg.is_fullscreen && osys->fit_window != 0) {
                 VoutDisplayFitWindow(vd, osys->fit_window == -1);
@@ -1039,6 +1043,18 @@ bool vout_ManageDisplay(vout_display_t *vd, bool allow_reset_pictures)
             osys->crop.den    = crop_den;
             osys->ch_crop = false;
         }
+        if (osys->ch_projection) {
+            vout_display_cfg_t cfg = osys->cfg;
+
+            cfg.projection = osys->proj_mode;
+
+            if (vout_display_Control(vd, VOUT_DISPLAY_CHANGE_PROJECTION, &cfg)) {
+                msg_Err(vd, "Failed to change Projection");
+                osys->proj_mode = osys->cfg.projection;
+            }
+            osys->cfg.projection = osys->proj_mode;
+            osys->ch_projection = false;
+        }
         if (osys->ch_viewpoint) {
             vout_display_cfg_t cfg = osys->cfg;
 
@@ -1236,6 +1252,16 @@ void vout_SetDisplayViewpoint(vout_display_t *vd, const vlc_viewpoint_t *p_viewp
     vlc_mutex_unlock(&osys->viewpoint_lock);
 }
 
+void vout_SetDisplayProjection(vout_display_t *vd, vout_projection_mode_t proj)
+{
+    vout_display_owner_sys_t *osys = vd->owner.sys;
+
+    if (osys->proj_mode != proj) {
+        osys->proj_mode = proj;
+        osys->ch_projection = true;
+    }
+}
+
 static vout_display_t *DisplayNew(vout_thread_t *vout,
                                   const video_format_t *source,
                                   const vout_display_state_t *state,
diff --git a/src/video_output/video_output.c b/src/video_output/video_output.c
index 9a97767..f3614d2 100644
--- a/src/video_output/video_output.c
+++ b/src/video_output/video_output.c
@@ -553,6 +553,11 @@ void vout_SetViewpoint(vout_thread_t *vout, const vlc_viewpoint_t *p_viewpoint)
 
     vout_control_Push(&vout->p->control, &cmd);
 }
+void vout_ControlChangeProjection(vout_thread_t *vout, vout_projection_mode_t proj)
+{
+    vout_control_PushInteger(&vout->p->control, VOUT_CONTROL_PROJECTION,
+                             proj);
+}
 
 /* */
 static void VoutGetDisplayCfg(vout_thread_t *vout, vout_display_cfg_t *cfg, const char *title)
@@ -560,6 +565,7 @@ static void VoutGetDisplayCfg(vout_thread_t *vout, vout_display_cfg_t *cfg, cons
     /* Load configuration */
     cfg->is_fullscreen = var_CreateGetBool(vout, "fullscreen")
                          || var_InheritBool(vout, "video-wallpaper");
+    cfg->projection = var_CreateGetInteger(vout, "projection");
     cfg->viewpoint.yaw   = 0.0f;
     cfg->viewpoint.pitch = 0.0f;
     cfg->viewpoint.roll  = 0.0f;
@@ -1311,6 +1317,12 @@ static void ThreadExecuteViewpoint(vout_thread_t *vout, const vlc_viewpoint_t *p
     vout_SetDisplayViewpoint(vout->p->display.vd, p_viewpoint);
 }
 
+static void ThreadExecuteProjection(vout_thread_t *vout, vout_projection_mode_t proj)
+{
+    msg_Dbg(vout, "ThreadExecuteProjection %d", proj);
+    vout_SetDisplayProjection(vout->p->display.vd, proj);
+}
+
 static int ThreadStart(vout_thread_t *vout, vout_display_state_t *state)
 {
     vlc_mouse_Init(&vout->p->mouse);
@@ -1573,6 +1585,9 @@ static int ThreadControl(vout_thread_t *vout, vout_control_cmd_t cmd)
     case VOUT_CONTROL_VIEWPOINT:
         ThreadExecuteViewpoint(vout, &cmd.u.viewpoint);
         break;
+    case VOUT_CONTROL_PROJECTION:
+        ThreadExecuteProjection(vout, (vout_projection_mode_t) cmd.u.integer);
+        break;
     default:
         break;
     }
diff --git a/src/video_output/vout_internal.h b/src/video_output/vout_internal.h
index 4d63fbf..5ef1435 100644
--- a/src/video_output/vout_internal.h
+++ b/src/video_output/vout_internal.h
@@ -141,6 +141,7 @@ void vout_ControlChangeSampleAspectRatio(vout_thread_t *, unsigned num, unsigned
 void vout_ControlChangeCropRatio(vout_thread_t *, unsigned num, unsigned den);
 void vout_ControlChangeCropWindow(vout_thread_t *, int x, int y, int width, int height);
 void vout_ControlChangeCropBorder(vout_thread_t *, int left, int top, int right, int bottom);
+void vout_ControlChangeProjection(vout_thread_t *vout, vout_projection_mode_t projection);
 void vout_ControlChangeFilters(vout_thread_t *, const char *);
 void vout_ControlChangeSubSources(vout_thread_t *, const char *);
 void vout_ControlChangeSubFilters(vout_thread_t *, const char *);
diff --git a/src/video_output/vout_intf.c b/src/video_output/vout_intf.c
index fe6c36b..e18d3e6 100644
--- a/src/video_output/vout_intf.c
+++ b/src/video_output/vout_intf.c
@@ -124,6 +124,17 @@ static const struct
     { "5:4", "5:4" },
 };
 
+static const struct
+{
+    vout_projection_mode_t value;
+    char psz_label[20];
+} p_projection_values[] = {
+    { VOUT_PROJECTION_AUTO, N_("Automatic Selection") },
+    { VOUT_PROJECTION_FLAT, N_("Flat/2D") },
+    { VOUT_PROJECTION_SPHERE, N_("360° Sphere") },
+    { VOUT_PROJECTION_CUBEMAP, N_("360° Cubemap") },
+};
+
 static void AddCustomRatios( vout_thread_t *p_vout, const char *psz_var,
                              char *psz_list )
 {
@@ -147,6 +158,14 @@ static void AddCustomRatios( vout_thread_t *p_vout, const char *psz_var,
     }
 }
 
+static int ProjectionCallback(vlc_object_t *obj, char const *cmd,
+                              vlc_value_t oldval, vlc_value_t newval, void *data)
+{
+    vout_ControlChangeProjection((vout_thread_t *)obj, (vout_projection_mode_t) newval.i_int);
+    VLC_UNUSED(cmd); VLC_UNUSED(oldval); VLC_UNUSED(data);
+    return VLC_SUCCESS;
+}
+
 void vout_IntfInit( vout_thread_t *p_vout )
 {
     vlc_value_t val, text;
@@ -258,6 +277,20 @@ void vout_IntfInit( vout_thread_t *p_vout )
     var_Create( p_vout, "viewpoint", VLC_VAR_ADDRESS | VLC_VAR_DOINHERIT );
     var_AddCallback( p_vout, "viewpoint", ViewpointCallback, NULL );
 
+    var_Create( p_vout, "projection", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT
+                | VLC_VAR_ISCOMMAND );
+    text.psz_string = _("Projection");
+    var_Change( p_vout, "projection", VLC_VAR_SETTEXT, &text, NULL );
+
+    for( size_t i = 0; i < ARRAY_SIZE(p_projection_values); i++ )
+    {
+        val.i_int = p_projection_values[i].value;
+        text.psz_string = _( p_projection_values[i].psz_label );
+        var_Change( p_vout, "projection", VLC_VAR_ADDCHOICE, &val, &text );
+    }
+
+    var_AddCallback( p_vout, "projection", ProjectionCallback, NULL );
+
     /* Add a variable to indicate if the window should be below all others */
     var_Create( p_vout, "video-wallpaper", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
     var_AddCallback( p_vout, "video-wallpaper", WallPaperCallback,
@@ -316,6 +349,7 @@ void vout_IntfReinit( vout_thread_t *p_vout )
     var_TriggerCallback( p_vout, "crop" );
     var_TriggerCallback( p_vout, "aspect-ratio" );
     var_TriggerCallback( p_vout, "viewpoint" );
+    var_TriggerCallback( p_vout, "projection" );
 
     var_TriggerCallback( p_vout, "video-on-top" );
     var_TriggerCallback( p_vout, "video-wallpaper" );
-- 
2.10.1



More information about the vlc-devel mailing list