[vlc-devel] [PATCH 03/15] core: add viewpoint to change the yaw/pitch/roll view during playback

Rémi Denis-Courmont remi at remlab.net
Mon Nov 7 18:30:46 CET 2016


Le maanantaina 7. marraskuuta 2016, 10.51.52 EET Steve Lhomme a écrit :
> --
> * move the playlist viewpoint in playlist_private_t
> * less vlc_vout.h includes
> * removed text on the "viewpoint" variable
> 
> replaces https://patches.videolan.org/patch/14923/
> * forgot to remove playlist entries from libvlccore.sym
> 
> replaces https://patches.videolan.org/patch/14923/
> * use a different CLI parameter for each viewpoint parameter
> * drop the f_ prefix on vout float variables
> ---
>  include/vlc_common.h             |  1 +
>  include/vlc_vout.h               |  9 ++++++++
>  include/vlc_vout_display.h       |  7 ++++++
>  include/vlc_vout_wrapper.h       |  2 ++
>  src/libvlc-module.c              | 25 ++++++++++++++++++++
>  src/libvlccore.sym               |  2 ++
>  src/playlist/engine.c            |  8 +++++++
>  src/playlist/playlist_internal.h |  3 +++
>  src/video_output/control.h       |  2 ++
>  src/video_output/display.c       | 49
> +++++++++++++++++++++++++++++++++++++++- src/video_output/video_output.c  |
> 25 ++++++++++++++++++++
>  src/video_output/vout_intf.c     | 16 +++++++++++++
>  12 files changed, 148 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..57afacc 100644
> --- a/include/vlc_vout.h
> +++ b/include/vlc_vout.h
> @@ -82,6 +82,12 @@ struct vout_thread_t {
>  #define VOUT_ALIGN_BOTTOM       0x0008
>  #define VOUT_ALIGN_VMASK        0x000C
> 
> +struct vlc_viewpoint_t {
> +    float yaw;   /* yaw in radians */
> +    float pitch; /* pitch in radians */
> +    float roll;  /* roll in radians */
> +};
> +
>  /**************************************************************************
> *** * Prototypes
>  
> ***************************************************************************
> **/ @@ -156,6 +162,9 @@ VLC_API void vout_FlushSubpictureChannel(
> vout_thread_t *, int );
> 
>  VLC_API void vout_EnableFilter( vout_thread_t *, const char *,bool , bool 
> );
> 
> +VLC_API void vout_GetViewpoint( vout_thread_t *, vlc_viewpoint_t
> *p_viewpoint ); +VLC_API void vout_SetViewpoint( vout_thread_t *, const
> vlc_viewpoint_t *p_viewpoint ); +
>  /**@}*/
> 
>  #endif /* _VLC_VIDEO_H */
> diff --git a/include/vlc_vout_display.h b/include/vlc_vout_display.h
> index 817f770..e1efe00 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,8 @@ typedef struct {
>          int den;
>      } zoom;
> 
> +    vlc_viewpoint_t viewpoint;
> +
>  } vout_display_cfg_t;
> 
>  /**
> @@ -175,6 +178,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..2ba4fc6 100644
> --- a/include/vlc_vout_wrapper.h
> +++ b/include/vlc_vout_wrapper.h
> @@ -93,6 +93,8 @@ 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_GetDisplayViewpoint(vout_display_t *, vlc_viewpoint_t *p_viewpoint);
> +void vout_SetDisplayViewpoint(vout_display_t *, const vlc_viewpoint_t
> *p_viewpoint);
> 
>  #endif /* VLC_VOUT_WRAPPER_H */
> 
> diff --git a/src/libvlc-module.c b/src/libvlc-module.c
> index 035bcd2..05b171d 100644
> --- a/src/libvlc-module.c
> +++ b/src/libvlc-module.c
> @@ -433,6 +433,22 @@ static const char *const ppsz_pos_descriptions[] =
>      "aspect, or a float value (1.25, 1.3333, etc.) expressing pixel " \
>      "squareness.")
> 
> +#define VIEWPOINT_YAW_TEXT N_("Viewpoint Yaw")
> +#define VIEWPOINT_YAW_LONGTEXT N_( \
> +    "This forces the user viewpoint yaw (horizontal shift) for the
> displayed " \ +    "video, in radians." )
> +
> +#define VIEWPOINT_PITCH_TEXT N_("Viewpoint Pitch")
> +#define VIEWPOINT_PITCH_LONGTEXT N_( \
> +    "This forces the user viewpoint pitch (vertical shift) for the
> displayed " \ +    "video, in radians." )
> +
> +#define VIEWPOINT_ROLL_TEXT N_("Viewpoint Roll")
> +#define VIEWPOINT_ROLL_LONGTEXT N_( \
> +    "This forces the user viewpoint roll (head tilting) for the displayed "
> \ +    "video, in radians." )
> +
> +
>  #define AUTOSCALE_TEXT N_("Video Auto Scaling")
>  #define AUTOSCALE_LONGTEXT N_( \
>      "Let the video scale to fit a given window or fullscreen.")
> @@ -1589,6 +1605,15 @@ vlc_module_begin ()
>      add_string( "aspect-ratio", NULL,
>                  ASPECT_RATIO_TEXT, ASPECT_RATIO_LONGTEXT, false )
>          change_safe ()
> +    add_float( "viewpoint-yaw", 0.,
> +                VIEWPOINT_YAW_TEXT, VIEWPOINT_YAW_LONGTEXT, false )
> +        change_safe ()
> +    add_float( "viewpoint-pitch", 0.,
> +                VIEWPOINT_PITCH_TEXT, VIEWPOINT_PITCH_LONGTEXT, false )
> +        change_safe ()
> +    add_float( "viewpoint-roll", 0.,
> +                VIEWPOINT_ROLL_TEXT, VIEWPOINT_ROLL_LONGTEXT, false )
> +        change_safe ()
>      add_bool( "autoscale", true, AUTOSCALE_TEXT, AUTOSCALE_LONGTEXT, false
> ) change_safe ()
>      add_obsolete_float( "scale" ) /* since 3.0.0 */
> diff --git a/src/libvlccore.sym b/src/libvlccore.sym
> index 8bb2dac..59a6e56 100644
> --- a/src/libvlccore.sym
> +++ b/src/libvlccore.sym
> @@ -734,6 +734,8 @@ vout_window_Delete
>  vout_display_GetDefaultDisplaySize
>  vout_display_PlacePicture
>  vout_display_SendMouseMovedDisplayCoordinates
> +vout_GetViewpoint
> +vout_SetViewpoint
>  xml_Create
>  text_style_Copy
>  text_style_Create
> diff --git a/src/playlist/engine.c b/src/playlist/engine.c
> index 7c00a48..e840e9c 100644
> --- a/src/playlist/engine.c
> +++ b/src/playlist/engine.c
> @@ -479,6 +479,14 @@ static void VariablesInit( playlist_t *p_playlist )
>      var_Create( p_playlist, "mute", VLC_VAR_BOOL );
>      var_Create( p_playlist, "volume", VLC_VAR_FLOAT );
>      var_SetFloat( p_playlist, "volume", -1.f );
> +
> +    vlc_viewpoint_t *p_vp = &pl_priv(p_playlist)->viewpoint;
> +    p_vp->yaw   = var_InheritFloat( p_playlist, "viewpoint-yaw" );
> +    p_vp->pitch = var_InheritFloat( p_playlist, "viewpoint-pitch" );
> +    p_vp->roll  = var_InheritFloat( p_playlist, "viewpoint-roll" );
> +
> +    var_Create( p_playlist, "viewpoint", VLC_VAR_ADDRESS );
> +    var_SetAddress( p_playlist, "viewpoint", p_vp );
>  }
> 
>  playlist_item_t * playlist_CurrentPlayingItem( playlist_t * p_playlist )
> diff --git a/src/playlist/playlist_internal.h
> b/src/playlist/playlist_internal.h index d655dc3..faa7a14 100644
> --- a/src/playlist/playlist_internal.h
> +++ b/src/playlist/playlist_internal.h
> @@ -35,6 +35,7 @@
>   */
> 
>  #include "input/input_interface.h"
> +#include "vlc_vout.h"
>  #include <assert.h>
> 
>  #include "art.h"
> @@ -87,6 +88,8 @@ typedef struct playlist_private_t
> 
>      bool     b_tree; /**< Display as a tree */
>      bool     b_preparse; /**< Preparse items */
> +
> +    vlc_viewpoint_t  viewpoint; /**< playback viewpoint */
>  } playlist_private_t;
> 
>  #define pl_priv( pl ) ((playlist_private_t *)(pl))
> diff --git a/src/video_output/control.h b/src/video_output/control.h
> index eff9aa1..add2246 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 {
> @@ -93,6 +94,7 @@ typedef struct {
>              unsigned width;
>              unsigned height;
>          } window;
> +        vlc_viewpoint_t viewpoint;
>          const vout_configuration_t *cfg;
>          subpicture_t *subpicture;
>      } u;
> diff --git a/src/video_output/display.c b/src/video_output/display.c
> index ecf661a..4716755 100644
> --- a/src/video_output/display.c
> +++ b/src/video_output/display.c
> @@ -373,6 +373,10 @@ struct vout_display_owner_sys_t {
>          unsigned den;
>      } crop;
> 
> +    bool ch_viewpoint;
> +    vlc_viewpoint_t viewpoint;
> +    vlc_mutex_t viewpoint_lock;
> +
>      /* */
>      video_format_t source;
>      filter_chain_t *filters;
> @@ -850,7 +854,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 +1039,20 @@ 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;
> +
> +            vlc_mutex_lock(&osys->viewpoint_lock);
> +            cfg.viewpoint = osys->viewpoint;
> +
> +            if (vout_display_Control(vd, VOUT_DISPLAY_CHANGE_VIEWPOINT,
> &cfg)) { +                msg_Err(vd, "Failed to change Viewpoint");
> +                osys->viewpoint = cfg.viewpoint;
> +            }
> +            osys->cfg.viewpoint = osys->viewpoint;
> +            osys->ch_viewpoint  = false;
> +            vlc_mutex_unlock(&osys->viewpoint_lock);
> +        }
> 
>          /* */
>          if (reset_pictures) {
> @@ -1193,6 +1212,30 @@ void vout_SetDisplayCrop(vout_display_t *vd,
>      }
>  }
> 
> +void vout_GetDisplayViewpoint(vout_display_t *vd, vlc_viewpoint_t
> *p_viewpoint) +{
> +    vout_display_owner_sys_t *osys = vd->owner.sys;
> +
> +    vlc_mutex_lock(&osys->viewpoint_lock);
> +    *p_viewpoint = osys->viewpoint;
> +    vlc_mutex_unlock(&osys->viewpoint_lock);
> +}

I believe that there is a reason why there are no getters in this file: they 
simply make no sense. By the time the function returns, the mutex is already 
unlocked, and the obtained value is already meaningless.

Please, no.

> +
> +void vout_SetDisplayViewpoint(vout_display_t *vd, const vlc_viewpoint_t
> *p_viewpoint) +{
> +    vout_display_owner_sys_t *osys = vd->owner.sys;
> +
> +    vlc_mutex_lock(&osys->viewpoint_lock);
> +    if (osys->viewpoint.yaw   != p_viewpoint->yaw ||
> +        osys->viewpoint.pitch != p_viewpoint->pitch ||
> +        osys->viewpoint.roll  != p_viewpoint->roll) {
> +        osys->viewpoint = *p_viewpoint;
> +
> +        osys->ch_viewpoint = true;
> +    }
> +    vlc_mutex_unlock(&osys->viewpoint_lock);
> +}
> +
>  static vout_display_t *DisplayNew(vout_thread_t *vout,
>                                    const video_format_t *source,
>                                    const vout_display_state_t *state,
> @@ -1218,6 +1261,8 @@ static vout_display_t *DisplayNew(vout_thread_t *vout,
> 
>      vlc_mutex_init(&osys->lock);
> 
> +    vlc_mutex_init(&osys->viewpoint_lock);
> +
>      vlc_mouse_Init(&osys->mouse.state);
>      osys->mouse.last_moved = mdate();
>      osys->mouse.double_click_timeout = double_click_timeout;
> @@ -1289,6 +1334,7 @@ static vout_display_t *DisplayNew(vout_thread_t *vout,
> 
>      return p_display;
>  error:
> +    vlc_mutex_destroy(&osys->viewpoint_lock);
>      vlc_mutex_destroy(&osys->lock);
>      free(osys);
>      return NULL;
> @@ -1317,6 +1363,7 @@ void vout_DeleteDisplay(vout_display_t *vd,
> vout_display_state_t *state) vlc_join(osys->event.thread, NULL);
>          block_FifoRelease(osys->event.fifo);
>      }
> +    vlc_mutex_destroy(&osys->viewpoint_lock);
>      vlc_mutex_destroy(&osys->lock);
>      free(osys);
>  }
> diff --git a/src/video_output/video_output.c
> b/src/video_output/video_output.c index 7994bec..9a97767 100644
> --- a/src/video_output/video_output.c
> +++ b/src/video_output/video_output.c
> @@ -540,12 +540,29 @@ void vout_ControlChangeSubMargin(vout_thread_t *vout,
> int margin) margin);
>  }
> 
> +void vout_GetViewpoint( vout_thread_t *vout, vlc_viewpoint_t *p_viewpoint )
> +{
> +    vout_GetDisplayViewpoint(vout->p->display.vd, p_viewpoint);
> +}
> +
> +void vout_SetViewpoint(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");
> 
> +    cfg->viewpoint.yaw   = 0.0f;
> +    cfg->viewpoint.pitch = 0.0f;
> +    cfg->viewpoint.roll  = 0.0f;
>      cfg->display.title = title;
>      const int display_width = var_CreateGetInteger(vout, "width");
>      const int display_height = var_CreateGetInteger(vout, "height");
> @@ -1289,6 +1306,11 @@ 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 +1570,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_intf.c b/src/video_output/vout_intf.c
> index 11240c8..fe6c36b 100644
> --- a/src/video_output/vout_intf.c
> +++ b/src/video_output/vout_intf.c
> @@ -57,6 +57,8 @@ static int AutoScaleCallback( vlc_object_t *, char const
> *, vlc_value_t, vlc_value_t, void * ); static int ZoomCallback(
> 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 * );
>  static int AboveCallback( vlc_object_t *, char const *,
>                            vlc_value_t, vlc_value_t, void * );
>  static int WallPaperCallback( vlc_object_t *, char const *,
> @@ -252,6 +254,10 @@ void vout_IntfInit( vout_thread_t *p_vout )
>      var_Change( p_vout, "video-on-top", VLC_VAR_SETTEXT, &text, NULL );
>      var_AddCallback( p_vout, "video-on-top", AboveCallback, NULL );
> 
> +    /* Add a variable to indicate if the viewpoint to use to display the
> video */ +    var_Create( p_vout, "viewpoint", VLC_VAR_ADDRESS |
> VLC_VAR_DOINHERIT ); +    var_AddCallback( p_vout, "viewpoint",
> ViewpointCallback, 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, @@ -309,6
> +315,7 @@ void vout_IntfReinit( vout_thread_t *p_vout )
>      var_TriggerCallback( p_vout, "zoom" );
>      var_TriggerCallback( p_vout, "crop" );
>      var_TriggerCallback( p_vout, "aspect-ratio" );
> +    var_TriggerCallback( p_vout, "viewpoint" );
> 
>      var_TriggerCallback( p_vout, "video-on-top" );
>      var_TriggerCallback( p_vout, "video-wallpaper" );
> @@ -602,6 +609,15 @@ static int ZoomCallback( vlc_object_t *obj, char const
> *name, return VLC_SUCCESS;
>  }
> 
> +static int ViewpointCallback(vlc_object_t *obj, char const *cmd,
> +                             vlc_value_t oldval, vlc_value_t newval, void
> *data) +{
> +    vout_SetViewpoint((vout_thread_t *)obj, newval.p_address);
> +
> +    VLC_UNUSED(cmd); VLC_UNUSED(oldval); VLC_UNUSED(data);
> +    return VLC_SUCCESS;
> +}
> +
>  static int AboveCallback( vlc_object_t *obj, char const *name,
>                            vlc_value_t prev, vlc_value_t cur, void *data )
>  {


-- 
Rémi Denis-Courmont
http://www.remlab.net/



More information about the vlc-devel mailing list