[vlc-commits] core: add viewpoint to change the yaw/pitch/roll/fow/ zoom view during playback

Steve Lhomme git at videolan.org
Tue Nov 15 18:14:00 CET 2016


vlc | branch: master | Steve Lhomme <robux4 at videolabs.io> | Thu Nov 10 18:24:17 2016 +0100| [335c16ab44753ec66244109e3f40b4ffe2242da9] | committer: Thomas Guillem

core: add viewpoint to change the yaw/pitch/roll/fow/zoom view during playback

These changes allow for us to change the viewpoint for a given vout, which is
the foundation required in order to play, and navigate, the contents of 360
videos.

Five new arguments has been added so that a user can decide where to start
playing within the 360 globe.

Signed-off-by: Thomas Guillem <thomas at gllm.fr>

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=335c16ab44753ec66244109e3f40b4ffe2242da9
---

 include/vlc_common.h             |  1 +
 include/vlc_vout.h               | 17 +++++++++++++++++
 include/vlc_vout_display.h       |  6 ++++++
 include/vlc_vout_wrapper.h       |  1 +
 src/video_output/control.h       |  2 ++
 src/video_output/display.c       | 34 +++++++++++++++++++++++++++++++++-
 src/video_output/video_output.c  | 23 +++++++++++++++++++++++
 src/video_output/vout_internal.h |  1 +
 src/video_output/vout_intf.c     | 17 +++++++++++++++++
 9 files changed, 101 insertions(+), 1 deletion(-)

diff --git a/include/vlc_common.h b/include/vlc_common.h
index a9683d6..0b1db73 100644
--- a/include/vlc_common.h
+++ b/include/vlc_common.h
@@ -249,6 +249,7 @@ typedef audio_format_t audio_sample_format_t;
 
 /* Video */
 typedef struct vout_thread_t vout_thread_t;
+typedef struct vlc_viewpoint_t vlc_viewpoint_t;
 
 typedef video_format_t video_frame_format_t;
 typedef struct picture_t picture_t;
diff --git a/include/vlc_vout.h b/include/vlc_vout.h
index 600cb56..fcf7ff4 100644
--- a/include/vlc_vout.h
+++ b/include/vlc_vout.h
@@ -82,6 +82,23 @@ struct vout_thread_t {
 #define VOUT_ALIGN_BOTTOM       0x0008
 #define VOUT_ALIGN_VMASK        0x000C
 
+/**
+ * Viewpoints
+ */
+struct vlc_viewpoint_t {
+    float yaw;   /* yaw in degrees */
+    float pitch; /* pitch in degrees */
+    float roll;  /* roll in degrees */
+    float fov;   /* field of view in degrees */
+    float zoom;  /* zoom factor, default to 0 */
+};
+
+static inline void vlc_viewpoint_init( vlc_viewpoint_t *p_vp )
+{
+    p_vp->yaw = p_vp->pitch = p_vp->roll = p_vp->zoom = 0.0f;
+    p_vp->fov = DEFAULT_FIELD_OF_VIEW_DEGREES;
+}
+
 /*****************************************************************************
  * Prototypes
  *****************************************************************************/
diff --git a/include/vlc_vout_display.h b/include/vlc_vout_display.h
index 817f770..04a265a 100644
--- a/include/vlc_vout_display.h
+++ b/include/vlc_vout_display.h
@@ -30,6 +30,7 @@
 #include <vlc_subpicture.h>
 #include <vlc_keys.h>
 #include <vlc_mouse.h>
+#include <vlc_vout.h>
 #include <vlc_vout_window.h>
 
 /**
@@ -115,6 +116,7 @@ typedef struct {
         int den;
     } zoom;
 
+    vlc_viewpoint_t viewpoint;
 } vout_display_cfg_t;
 
 /**
@@ -175,6 +177,10 @@ enum {
      * The cropping requested is stored by video_format_t::i_x/y_offset and
      * video_format_t::i_visible_width/height */
     VOUT_DISPLAY_CHANGE_SOURCE_CROP,   /* const video_format_t *p_source */
+
+    /* 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 */
 };
 
 /**
diff --git a/include/vlc_vout_wrapper.h b/include/vlc_vout_wrapper.h
index 419bfc8..ce019a8 100644
--- a/include/vlc_vout_wrapper.h
+++ b/include/vlc_vout_wrapper.h
@@ -93,6 +93,7 @@ void vout_SetDisplayZoom(vout_display_t *, unsigned num, unsigned den);
 void vout_SetDisplayAspect(vout_display_t *, unsigned num, unsigned den);
 void vout_SetDisplayCrop(vout_display_t *, unsigned num, unsigned den,
                          unsigned left, unsigned top, int right, int bottom);
+void vout_SetDisplayViewpoint(vout_display_t *, const vlc_viewpoint_t *);
 
 #endif /* VLC_VOUT_WRAPPER_H */
 
diff --git a/src/video_output/control.h b/src/video_output/control.h
index eff9aa1..9fdfd85 100644
--- a/src/video_output/control.h
+++ b/src/video_output/control.h
@@ -58,6 +58,7 @@ enum {
     VOUT_CONTROL_CROP_BORDER,           /* border */
     VOUT_CONTROL_CROP_RATIO,            /* pair */
     VOUT_CONTROL_CROP_WINDOW,           /* window */
+    VOUT_CONTROL_VIEWPOINT,             /* viewpoint */
 };
 
 typedef struct {
@@ -95,6 +96,7 @@ typedef struct {
         } window;
         const vout_configuration_t *cfg;
         subpicture_t *subpicture;
+        vlc_viewpoint_t viewpoint;
     } u;
 } vout_control_cmd_t;
 
diff --git a/src/video_output/display.c b/src/video_output/display.c
index ecf661a..b3fce3c 100644
--- a/src/video_output/display.c
+++ b/src/video_output/display.c
@@ -373,6 +373,9 @@ struct vout_display_owner_sys_t {
         unsigned den;
     } crop;
 
+    bool ch_viewpoint;
+    vlc_viewpoint_t viewpoint;
+
     /* */
     video_format_t source;
     filter_chain_t *filters;
@@ -850,7 +853,8 @@ bool vout_ManageDisplay(vout_display_t *vd, bool allow_reset_pictures)
             !ch_wm_state &&
 #endif
             !osys->ch_sar &&
-            !osys->ch_crop) {
+            !osys->ch_crop &&
+            !osys->ch_viewpoint) {
 
             if (!osys->cfg.is_fullscreen && osys->fit_window != 0) {
                 VoutDisplayFitWindow(vd, osys->fit_window == -1);
@@ -1034,6 +1038,18 @@ bool vout_ManageDisplay(vout_display_t *vd, bool allow_reset_pictures)
             osys->crop.den    = crop_den;
             osys->ch_crop = false;
         }
+        if (osys->ch_viewpoint) {
+            vout_display_cfg_t cfg = osys->cfg;
+
+            cfg.viewpoint = osys->viewpoint;
+
+            if (vout_display_Control(vd, VOUT_DISPLAY_CHANGE_VIEWPOINT, &cfg)) {
+                msg_Err(vd, "Failed to change Viewpoint");
+                osys->viewpoint = osys->cfg.viewpoint;
+            }
+            osys->cfg.viewpoint = osys->viewpoint;
+            osys->ch_viewpoint  = false;
+        }
 
         /* */
         if (reset_pictures) {
@@ -1193,6 +1209,22 @@ void vout_SetDisplayCrop(vout_display_t *vd,
     }
 }
 
+void vout_SetDisplayViewpoint(vout_display_t *vd,
+                              const vlc_viewpoint_t *p_viewpoint)
+{
+    vout_display_owner_sys_t *osys = vd->owner.sys;
+
+    if (osys->viewpoint.yaw   != p_viewpoint->yaw ||
+        osys->viewpoint.pitch != p_viewpoint->pitch ||
+        osys->viewpoint.roll  != p_viewpoint->roll ||
+        osys->viewpoint.zoom  != p_viewpoint->zoom ||
+        osys->viewpoint.fov   != p_viewpoint->fov) {
+        osys->viewpoint = *p_viewpoint;
+
+        osys->ch_viewpoint = 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 7994bec..1fd9e68 100644
--- a/src/video_output/video_output.c
+++ b/src/video_output/video_output.c
@@ -540,12 +540,26 @@ void vout_ControlChangeSubMargin(vout_thread_t *vout, int margin)
                              margin);
 }
 
+void vout_ControlChangeViewpoint(vout_thread_t *vout,
+                                 const vlc_viewpoint_t *p_viewpoint)
+{
+    vout_control_cmd_t cmd;
+    vout_control_cmd_Init(&cmd, VOUT_CONTROL_VIEWPOINT);
+    cmd.u.viewpoint = *p_viewpoint;
+    vout_control_Push(&vout->p->control, &cmd);
+}
+
 /* */
 static void VoutGetDisplayCfg(vout_thread_t *vout, vout_display_cfg_t *cfg, const char *title)
 {
     /* Load configuration */
     cfg->is_fullscreen = var_CreateGetBool(vout, "fullscreen")
                          || var_InheritBool(vout, "video-wallpaper");
+    const vlc_viewpoint_t *p_viewpoint = var_InheritAddress(vout, "viewpoint");
+    if (p_viewpoint != NULL)
+        cfg->viewpoint = *p_viewpoint;
+    else
+        vlc_viewpoint_init(&cfg->viewpoint);
     cfg->display.title = title;
     const int display_width = var_CreateGetInteger(vout, "width");
     const int display_height = var_CreateGetInteger(vout, "height");
@@ -1289,6 +1303,12 @@ static void ThreadExecuteCropRatio(vout_thread_t *vout,
                         0, 0, 0, 0);
 }
 
+static void ThreadExecuteViewpoint(vout_thread_t *vout,
+                                   const vlc_viewpoint_t *p_viewpoint)
+{
+    vout_SetDisplayViewpoint(vout->p->display.vd, p_viewpoint);
+}
+
 static int ThreadStart(vout_thread_t *vout, vout_display_state_t *state)
 {
     vlc_mouse_Init(&vout->p->mouse);
@@ -1548,6 +1568,9 @@ static int ThreadControl(vout_thread_t *vout, vout_control_cmd_t cmd)
                 cmd.u.border.left,  cmd.u.border.top,
                 cmd.u.border.right, cmd.u.border.bottom);
         break;
+    case VOUT_CONTROL_VIEWPOINT:
+        ThreadExecuteViewpoint(vout, &cmd.u.viewpoint);
+        break;
     default:
         break;
     }
diff --git a/src/video_output/vout_internal.h b/src/video_output/vout_internal.h
index 4d63fbf..fec54f3 100644
--- a/src/video_output/vout_internal.h
+++ b/src/video_output/vout_internal.h
@@ -145,6 +145,7 @@ void vout_ControlChangeFilters(vout_thread_t *, const char *);
 void vout_ControlChangeSubSources(vout_thread_t *, const char *);
 void vout_ControlChangeSubFilters(vout_thread_t *, const char *);
 void vout_ControlChangeSubMargin(vout_thread_t *, int);
+void vout_ControlChangeViewpoint( vout_thread_t *, const vlc_viewpoint_t *);
 
 /* */
 void vout_IntfInit( vout_thread_t * );
diff --git a/src/video_output/vout_intf.c b/src/video_output/vout_intf.c
index 11240c8..1aa78be 100644
--- a/src/video_output/vout_intf.c
+++ b/src/video_output/vout_intf.c
@@ -73,6 +73,8 @@ static int SubFilterCallback( vlc_object_t *, char const *,
                               vlc_value_t, vlc_value_t, void * );
 static int SubMarginCallback( vlc_object_t *, char const *,
                               vlc_value_t, vlc_value_t, void * );
+static int ViewpointCallback( vlc_object_t *, char const *,
+                              vlc_value_t, vlc_value_t, void * );
 
 /*****************************************************************************
  * vout_IntfInit: called during the vout creation to initialise misc things.
@@ -301,6 +303,10 @@ void vout_IntfInit( vout_thread_t *p_vout )
     var_Create( p_vout, "mouse-moved", VLC_VAR_COORDS );
     var_Create( p_vout, "mouse-clicked", VLC_VAR_COORDS );
 
+    /* Viewpoint */
+    var_Create( p_vout, "viewpoint", VLC_VAR_ADDRESS  | VLC_VAR_DOINHERIT );
+    var_AddCallback( p_vout, "viewpoint", ViewpointCallback, NULL );
+
     vout_IntfReinit( p_vout );
 }
 
@@ -317,6 +323,7 @@ void vout_IntfReinit( vout_thread_t *p_vout )
     var_TriggerCallback( p_vout, "sub-source" );
     var_TriggerCallback( p_vout, "sub-filter" );
     var_TriggerCallback( p_vout, "sub-margin" );
+    var_TriggerCallback( p_vout, "viewpoint" );
 }
 
 /*****************************************************************************
@@ -692,3 +699,13 @@ static int SubMarginCallback( vlc_object_t *p_this, char const *psz_cmd,
     return VLC_SUCCESS;
 }
 
+static int ViewpointCallback( vlc_object_t *p_this, char const *psz_cmd,
+                              vlc_value_t oldval, vlc_value_t newval, void *p_data)
+{
+    vout_thread_t *p_vout = (vout_thread_t *)p_this;
+    VLC_UNUSED(psz_cmd); VLC_UNUSED(oldval); VLC_UNUSED(p_data);
+
+    if( newval.p_address != NULL )
+        vout_ControlChangeViewpoint( p_vout, newval.p_address );
+    return VLC_SUCCESS;
+}



More information about the vlc-commits mailing list