[vlc-devel] [PATCH 03/10] libvlc: add the API needed to set/get the viewpoint in 360° videos

Rémi Denis-Courmont remi at remlab.net
Fri Sep 16 21:07:21 CEST 2016


Le vendredi 16 septembre 2016, 18:00:29 Steve Lhomme a écrit :
> --
> replaces https://patches.videolan.org/patch/14420/
> * redo the API so that the structure is allocated and released via the API
> * add missing libvlc.sym changes
> * add API tests
> * media_player variables are not inherited
> 
> replaces https://patches.videolan.org/patch/14457/
> * warn the user the structure must be allocated with get_viewpoint()
> * get_viewpoint() returns the allocated structure directly
> * use libvlc_free instead of a release function
> * move the structure so it's in a libvlc video doc
> 
> replaces https://patches.videolan.org/patch/14468/
> * use an API entry to allocate the structure
> * get/set individually on the vout number, if no vout set the local variable
> that will be inherited when vout(s) will be created
> * get/set return error values and set an error string
> 
> replaces https://patches.videolan.org/patch/14475/
> * use msleep instead of sleep to wait for the vout
> * use vlc_viewpoint rather than "viepoint"
> ---
>  include/vlc/libvlc_media_player.h |  61 ++++++++++++++++++++
>  lib/libvlc.sym                    |   3 +
>  lib/media_player.c                |   1 +
>  lib/video.c                       | 114
> ++++++++++++++++++++++++++++++++++++++ test/libvlc/media_player.c        | 
> 64 +++++++++++++++++++++
>  5 files changed, 243 insertions(+)
> 
> diff --git a/include/vlc/libvlc_media_player.h
> b/include/vlc/libvlc_media_player.h index 2718a33..2dbfda6 100644
> --- a/include/vlc/libvlc_media_player.h
> +++ b/include/vlc/libvlc_media_player.h
> @@ -1127,6 +1127,67 @@ LIBVLC_API char *libvlc_video_get_aspect_ratio(
> libvlc_media_player_t *p_mi ); LIBVLC_API void
> libvlc_video_set_aspect_ratio( libvlc_media_player_t *p_mi, const char
> *psz_aspect );
> 
>  /**
> + * Viewpoint for video outputs
> + *
> + * \warning allocate using libvlc_video_new_viewpoint()
> + */
> +typedef struct libvlc_video_viewpoint_t
> +{
> +    float f_yaw;   /**< view point yaw in degrees ]-180;180] */
> +    float f_pitch; /**< view point pitch in degrees ]-180;180] */
> +    float f_roll;  /**< view point roll in degrees ]-180;180] */
> +} libvlc_video_viewpoint_t;
> +
> +/**
> + * Create a video viewpoint structure.
> + *
> + * \version LibVLC 3.0.0 and later
> + *
> + * \return video viewpoint or NULL
> + *         (the result must be released with free() or libvlc_free()).
> + */
> +LIBVLC_API libvlc_video_viewpoint_t *libvlc_video_new_viewpoint();
> +
> +/**
> + * Get current video viewpoint.
> + *
> + * \version LibVLC 3.0.0 and later
> + *
> + * \param p_mi the media player
> + * \param num number of video output (typically 0 for the first/only one)
> + * \param p_viewpoint video viewpoint allocated via
> libvlc_video_new_viewpoint() + *                    that will be filled
> with the vout value if it is found + *                    or the default
> value for the media player
> + * \return 1 if the structure was filled, 0 if the vout number doesn't
> match + * \warning the call is synchronous and may not return the value
> just set with + *          libvlc_video_set_viewpoint().
> + *
> + * \libvlc_return_bool
> + */
> +LIBVLC_API int libvlc_video_get_viewpoint( libvlc_media_player_t *p_mi,
> +                                           unsigned num,
> +                                           libvlc_video_viewpoint_t
> *p_viewpoint ); +
> +/**
> + * Set new video viewpoint information.
> + *
> + * \version LibVLC 3.0.0 and later
> + *
> + * \param p_mi the media player
> + * \param num number of video output (typically 0 for the first/only one)
> + * \param p_viewpoint new video viewpoint allocated via
> libvlc_video_new_viewpoint() + *                    or NULL to reset to
> default.
> + * \return -1 if an error was detected, 0 otherwise.
> + *
> + * \note if no file is playing the value is set on the media player.
> + * \note if the vout number doesn't match any vout, the value is discarded.
> + * \note the values are set asynchronously, all at once.
> + */
> +LIBVLC_API int libvlc_video_set_viewpoint( libvlc_media_player_t *p_mi,
> +                                            unsigned num,
> +                                            const libvlc_video_viewpoint_t
> *p_viewpoint ); +
> +/**
>   * Get current video subtitle.
>   *
>   * \param p_mi the media player
> diff --git a/lib/libvlc.sym b/lib/libvlc.sym
> index 733a4dd..1074d7d 100644
> --- a/lib/libvlc.sym
> +++ b/lib/libvlc.sym
> @@ -271,6 +271,9 @@ libvlc_video_set_subtitle_file
>  libvlc_video_set_teletext
>  libvlc_video_set_track
>  libvlc_video_take_snapshot
> +libvlc_video_new_viewpoint
> +libvlc_video_get_viewpoint
> +libvlc_video_set_viewpoint
>  libvlc_vlm_add_broadcast
>  libvlc_vlm_add_vod
>  libvlc_vlm_add_input
> diff --git a/lib/media_player.c b/lib/media_player.c
> index 69d3523..4d5b35c 100644
> --- a/lib/media_player.c
> +++ b/lib/media_player.c
> @@ -640,6 +640,7 @@ libvlc_media_player_new( libvlc_instance_t *instance )
>      var_Create (mp, "zoom", VLC_VAR_FLOAT | VLC_VAR_DOINHERIT);
>      var_Create (mp, "aspect-ratio", VLC_VAR_STRING);
>      var_Create (mp, "crop", VLC_VAR_STRING);
> +    var_Create (mp, "viewpoint", VLC_VAR_STRING | VLC_VAR_DOINHERIT);
>      var_Create (mp, "deinterlace", VLC_VAR_INTEGER);
>      var_Create (mp, "deinterlace-mode", VLC_VAR_STRING);
> 
> diff --git a/lib/video.c b/lib/video.c
> index b2c9b34..f0ea58f 100644
> --- a/lib/video.c
> +++ b/lib/video.c
> @@ -281,6 +281,120 @@ void libvlc_video_set_aspect_ratio(
> libvlc_media_player_t *p_mi, free (pp_vouts);
>  }
> 
> +libvlc_video_viewpoint_t *libvlc_video_new_viewpoint()
> +{
> +    return calloc(1, sizeof(libvlc_video_viewpoint_t));
> +}
> +
> +int libvlc_video_get_viewpoint( libvlc_media_player_t *p_mi, unsigned num,
> +                                libvlc_video_viewpoint_t *p_viewpoint )
> +{
> +    if (p_viewpoint == NULL)
> +    {
> +        libvlc_printerr("output pointer is NULL");
> +        return 0;
> +    }

assert() or ignore it. This is undefined behaviour.

> +
> +    vout_thread_t *p_vout = NULL;
> +    size_t n;
> +    vout_thread_t **pp_vouts = GetVouts (p_mi, &n);
> +    if (pp_vouts == NULL)
> +    {
> +        /* no vout, read the p_mi value */
> +        char *psz_viewpoint = var_GetNonEmptyString( p_mi, "viewpoint" );
> +        if ( psz_viewpoint == NULL ||
> +             sscanf( psz_viewpoint, "%f:%f:%f",
> +                     &p_viewpoint->f_yaw, &p_viewpoint->f_pitch,
> &p_viewpoint->f_roll) != 3) {
> +            p_viewpoint->f_yaw =
> p_viewpoint->f_pitch = p_viewpoint->f_roll = 0.0f;
> +        }
> +    }
> +    else if (num >= n)
> +    {
> +        /* unknown vout, read nothing */
> +        for (size_t i = 0; i < n; i++)
> +            vlc_object_release (pp_vouts[i]);
> +        free (pp_vouts);
> +        libvlc_printerr("unknown vout number %d", num);
> +        return 0;
> +    }
> +    else
> +    {
> +        /* read the value from the specified vout */
> +        p_vout = pp_vouts[num];
> +        for (size_t i = 0; i < n; i++)
> +        {
> +            if (i != num)
> +                vlc_object_release (pp_vouts[i]);
> +        }
> +        free (pp_vouts);
> +
> +        vlc_viewpoint viewpoint;
> +        vout_GetViewpoint( p_vout, &viewpoint );
> +        vlc_object_release (p_vout);
> +
> +        p_viewpoint->f_yaw   = viewpoint.f_yaw;
> +        p_viewpoint->f_pitch = viewpoint.f_pitch;
> +        p_viewpoint->f_roll  = viewpoint.f_roll;
> +    }
> +
> +    return 1;
> +}
> +
> +int libvlc_video_set_viewpoint( libvlc_media_player_t *p_mi,
> +                                 unsigned num,
> +                                 const libvlc_video_viewpoint_t
> *p_viewpoint ) +{
> +    vout_thread_t *p_vout = NULL;
> +    size_t n;
> +    vout_thread_t **pp_vouts = GetVouts (p_mi, &n);
> +    if (pp_vouts == NULL)
> +    {
> +        /* no vout, set the mi value */
> +        char psz_viewpoint[4 * 13];
> +        if (p_viewpoint == NULL)
> +            psz_viewpoint[0] = '\0';
> +        else
> +            sprintf( psz_viewpoint, "%.7f:%.7f:%.7f",
> +                     p_viewpoint->f_yaw, p_viewpoint->f_pitch,
> p_viewpoint->f_roll  ); +        int err = var_SetString (p_mi,
> "viewpoint", psz_viewpoint); +        if (err != VLC_SUCCESS)
> +        {
> +            libvlc_printerr("failed to set the viewpoint (%d)", err);
> +            return -1;
> +        }
> +    }
> +    else if (num >= n)
> +    {
> +        /* unknown vout, write nothing */
> +        for (size_t i = 0; i < n; i++)
> +            vlc_object_release (pp_vouts[i]);
> +        free (pp_vouts);
> +        libvlc_printerr("unknown vout number %d", num);
> +        return -1;
> +    }
> +    else
> +    {
> +        /* write the value from the specified vout */
> +        p_vout = pp_vouts[num];
> +        for (size_t i = 0; i < n; i++)
> +        {
> +            if (i != num)
> +                vlc_object_release (pp_vouts[i]);
> +        }
> +        free (pp_vouts);
> +
> +        vlc_viewpoint viewpoint = {
> +            .f_yaw   =   p_viewpoint->f_yaw,
> +            .f_pitch =   p_viewpoint->f_pitch,
> +            .f_roll  =   p_viewpoint->f_roll,
> +        };
> +        vout_SetViewpoint(p_vout, &viewpoint);
> +        vlc_object_release (p_vout);
> +    }
> +
> +    return 0;
> +}
> +
>  int libvlc_video_get_spu( libvlc_media_player_t *p_mi )
>  {
>      input_thread_t *p_input_thread = libvlc_get_input_thread( p_mi );
> diff --git a/test/libvlc/media_player.c b/test/libvlc/media_player.c
> index f3198b5..9e83dc6 100644
> --- a/test/libvlc/media_player.c
> +++ b/test/libvlc/media_player.c
> @@ -23,6 +23,9 @@
> 
>  #include "test.h"
> 
> +#include <vlc_common.h>
> +#include <vlc_threads.h> /* for msleep */
> +
>  static void wait_playing(libvlc_media_player_t *mp)
>  {
>      libvlc_state_t state;
> @@ -190,6 +193,66 @@ static void test_media_player_pause_stop(const char**
> argv, int argc) libvlc_release (vlc);
>  }
> 
> +static void test_media_player_viewpoint(const char** argv, int argc)
> +{
> +    libvlc_instance_t *vlc;
> +    libvlc_media_t *md;
> +    libvlc_media_player_t *mi;
> +    const char * file = test_default_video;
> +
> +    log ("Testing viewpoint for %s\n", file);
> +
> +    vlc = libvlc_new (argc, argv);
> +    assert (vlc != NULL);
> +
> +    md = libvlc_media_new_path (vlc, file);
> +    assert (md != NULL);
> +
> +    mi = libvlc_media_player_new_from_media (md);
> +    assert (mi != NULL);
> +
> +    libvlc_media_release (md);
> +
> +    libvlc_video_viewpoint_t *p_viewpoint = libvlc_video_new_viewpoint();
> +    assert(p_viewpoint != NULL);
> +
> +    /* test without the file loaded */
> +    assert(libvlc_video_get_viewpoint(mi, 0, p_viewpoint));
> +    assert(libvlc_video_get_viewpoint(mi, 16, p_viewpoint));
> +
> +    p_viewpoint->f_yaw = 1.57f;
> +    assert(!libvlc_video_set_viewpoint(mi, 0, p_viewpoint));
> +    libvlc_free(p_viewpoint);
> +    p_viewpoint = libvlc_video_new_viewpoint();
> +    assert(p_viewpoint != NULL);
> +
> +    assert(libvlc_video_get_viewpoint(mi, 0, p_viewpoint));
> +    assert(p_viewpoint->f_yaw == 1.57f);
> +
> +    libvlc_media_player_play (mi);
> +    log ("Waiting for playing\n");
> +    wait_playing (mi);
> +
> +    while ( libvlc_media_player_has_vout(mi) == 0 )
> +        msleep( CLOCK_FREQ / 5 );
> +    log ("Vout found\n");
> +
> +    assert(!libvlc_video_get_viewpoint(mi, 16, p_viewpoint));
> +    assert(libvlc_video_get_viewpoint(mi, 0, p_viewpoint));
> +
> +    p_viewpoint->f_yaw = 0.57f;
> +    assert(!libvlc_video_set_viewpoint(mi, 0, p_viewpoint));
> +
> +    assert(libvlc_video_get_viewpoint(mi, 0, p_viewpoint));
> +    assert(p_viewpoint->f_yaw == 0.57f);
> +
> +    assert(!libvlc_video_get_viewpoint(mi,
> libvlc_media_player_has_vout(mi), p_viewpoint)); +   
> libvlc_free(p_viewpoint);
> +
> +    libvlc_media_player_stop (mi);
> +    libvlc_media_player_release (mi);
> +    libvlc_release (vlc);
> +}
> 
>  int main (void)
>  {
> @@ -198,6 +261,7 @@ int main (void)
>      test_media_player_set_media (test_defaults_args, test_defaults_nargs);
>      test_media_player_play_stop (test_defaults_args, test_defaults_nargs);
>      test_media_player_pause_stop (test_defaults_args, test_defaults_nargs);
> +    test_media_player_viewpoint (test_defaults_args, test_defaults_nargs);
> 
>      return 0;
>  }
> _______________________________________________
> vlc-devel mailing list
> To unsubscribe or modify your subscription options:
> https://mailman.videolan.org/listinfo/vlc-devel

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



More information about the vlc-devel mailing list