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

Steve Lhomme robux4 at gmail.com
Sat Nov 5 08:55:35 CET 2016


On Fri, Nov 4, 2016 at 6:47 PM, Filip Roséen <filip at atch.se> wrote:
> On 2016-11-04 18:08, Steve Lhomme wrote:
>
>  --
>  replaces https://patches.videolan.org/patch/14608/
>  * only use vout 0 in libvlc_video_get_viewpoint()
>  * libvlc_video_get_viewpoint() returns 0 on success
>  ---
>   include/vlc/libvlc_media_player.h | 52 ++++++++++++++++++++++
>   lib/libvlc.sym                    |  3 ++
>   lib/media_player.c                | 10 +++++
>   lib/media_player_internal.h       |  2 +
>   lib/video.c                       | 49 ++++++++++++++++++++
>   test/Makefile.am                  |  2 +-
>   test/libvlc/media_player.c        | 94
> +++++++++++++++++++++++++++++++++++++++
>   7 files changed, 211 insertions(+), 1 deletion(-)
>
>  diff --git a/include/vlc/libvlc_media_player.h
> b/include/vlc/libvlc_media_player.h
>  index 9a73b4f..ebd83bd 100644
>  --- a/include/vlc/libvlc_media_player.h
>  +++ b/include/vlc/libvlc_media_player.h
>  @@ -1167,6 +1167,58 @@ 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 radians */
>  +    float f_pitch;         /**< view point pitch in radians */
>  +    float f_roll;          /**< view point roll in radians */
>  +} 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(void);
>  +
>  +/**
>  + * Get current video viewpoint.
>  + *
>  + * \version LibVLC 3.0.0 and later
>  + *
>  + * \param p_mi the media player
>  + * \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 an error was detected, 0 otherwise
>  + * \warning the call is synchronous and may not return the value used by
> the vout yet.
>  + */
>
> Not sure if the above accurately describes the semantics, it could perhaps
> be worded differently; “warning The result of this function may not reflect
> the value currently used by the vout as it might not have had time to react
> to a previous invocation of libvlc_video_set_viewpoint”.

Yes, that seems better.

>  +LIBVLC_API int libvlc_video_get_viewpoint( libvlc_media_player_t *p_mi,
>  +                                           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 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 the values are set asynchronously, it will be used by the next
> frame displayed.
>  + */
>  +LIBVLC_API int libvlc_video_set_viewpoint( libvlc_media_player_t *p_mi,
>  +                                           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 b994384..06868ff 100644
>  --- a/lib/libvlc.sym
>  +++ b/lib/libvlc.sym
>  @@ -283,6 +283,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 db08274..1109b83 100644
>  --- a/lib/media_player.c
>  +++ b/lib/media_player.c
>  @@ -719,6 +719,16 @@ libvlc_media_player_new( libvlc_instance_t *instance )
>       if( aout != NULL )
>           input_resource_PutAout(mp->input.p_resource, aout);
>
>  +    char *psz_viewpoint = var_InheritString(mp, "viewpoint" );
>  +    if ( psz_viewpoint == NULL ||
>  +         sscanf( psz_viewpoint, "%f:%f:%f",
>  +                 &mp->viewpoint.f_yaw, &mp->viewpoint.f_pitch,
> &mp->viewpoint.f_roll) != 3) {
>  +        mp->viewpoint.f_yaw = mp->viewpoint.f_pitch = mp->viewpoint.f_roll
> = 0.0f;
>
> Is it not appropriate to at least issue a diagnostic if the view-point
> parsing fails?

Yes.

>  +    }
>  +    free(psz_viewpoint);
>  +
>  +    var_Create (mp, "viewpoint", VLC_VAR_ADDRESS);
>  +    var_SetAddress( mp, "viewpoint", &mp->viewpoint );
>       vlc_mutex_init (&mp->input.lock);
>       mp->i_refcount = 1;
>       mp->p_event_manager = libvlc_event_manager_new(mp);
>  diff --git a/lib/media_player_internal.h b/lib/media_player_internal.h
>  index f5f101b..ceff6c8 100644
>  --- a/lib/media_player_internal.h
>  +++ b/lib/media_player_internal.h
>  @@ -32,6 +32,7 @@
>   #include <vlc/vlc.h>
>   #include <vlc/libvlc_media.h>
>   #include <vlc_input.h>
>  +#include <vlc_vout.h>
>
>   #include "../modules/audio_filter/equalizer_presets.h"
>
>  @@ -53,6 +54,7 @@ struct libvlc_media_player_t
>       libvlc_media_t * p_md; /* current media descriptor */
>       libvlc_event_manager_t * p_event_manager;
>       libvlc_state_t state;
>  +    vlc_viewpoint_t viewpoint; /* avoid parsing strings of floats at every
> get */
>   };
>
>   /* Media player - audio, video */
>  diff --git a/lib/video.c b/lib/video.c
>  index 1046fba..28a7338 100644
>  --- a/lib/video.c
>  +++ b/lib/video.c
>  @@ -282,6 +282,55 @@ void libvlc_video_set_aspect_ratio(
> libvlc_media_player_t *p_mi,
>       free (pp_vouts);
>   }
>
>  +libvlc_video_viewpoint_t *libvlc_video_new_viewpoint(void)
>  +{
>  +    return calloc(1, sizeof(libvlc_video_viewpoint_t));
>  +}
>  +
>  +int libvlc_video_get_viewpoint( libvlc_media_player_t *p_mi,
>  +                                libvlc_video_viewpoint_t *p_viewpoint )
>  +{
>  +    /* read the value from the first vout otherwise keep the local one */
>  +    vout_thread_t *p_vout = GetVout (p_mi, 0);
>  +    if (p_vout != NULL)
>  +    {
>  +        vout_GetViewpoint(p_vout, &p_mi->viewpoint);
>  +        vlc_object_release(p_vout);
>  +    }
>  +
>  +    p_viewpoint->f_yaw           = p_mi->viewpoint.f_yaw;
>  +    p_viewpoint->f_pitch         = p_mi->viewpoint.f_pitch;
>  +    p_viewpoint->f_roll          = p_mi->viewpoint.f_roll;
>
> Unnecessary whitespace above.
>
>  +    return VLC_SUCCESS;
>  +}
>  +
>  +int libvlc_video_set_viewpoint( libvlc_media_player_t *p_mi,
>  +                                const libvlc_video_viewpoint_t
> *p_viewpoint )
>  +{
>  +    size_t n;
>  +    if (p_viewpoint == NULL)
>  +    {
>  +        p_mi->viewpoint.f_yaw = p_mi->viewpoint.f_pitch =
> p_mi->viewpoint.f_roll = 0.0f;
>  +    }
>  +    else
>  +    {
>  +        p_mi->viewpoint.f_yaw   =  p_viewpoint->f_yaw;
>  +        p_mi->viewpoint.f_pitch =  p_viewpoint->f_pitch;
>  +        p_mi->viewpoint.f_roll  =  p_viewpoint->f_roll;
>  +    }
>  +
>  +    vout_thread_t **pp_vouts = GetVouts (p_mi, &n);
>  +    /* write the value from all used vouts */
>  +    for (size_t i = 0; i < n; i++)
>  +    {
>  +        vout_SetViewpoint(pp_vouts[i], &p_mi->viewpoint);
>  +        vlc_object_release (pp_vouts[i]);
>  +    }
>  +    free (pp_vouts);
>  +
>  +    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/Makefile.am b/test/Makefile.am
>  index e47430e..2c86751 100644
>  --- a/test/Makefile.am
>  +++ b/test/Makefile.am
>  @@ -83,7 +83,7 @@ test_libvlc_media_list_player_LDADD = $(LIBVLC)
>   test_libvlc_media_list_SOURCES = libvlc/media_list.c
>   test_libvlc_media_list_LDADD = $(LIBVLC)
>   test_libvlc_media_player_SOURCES = libvlc/media_player.c
>  -test_libvlc_media_player_LDADD = $(LIBVLC)
>  +test_libvlc_media_player_LDADD = $(LIBVLCCORE) $(LIBVLC)
>   test_libvlc_media_discoverer_SOURCES = libvlc/media_discoverer.c
>   test_libvlc_media_discoverer_LDADD = $(LIBVLC)
>   test_libvlc_renderer_discoverer_SOURCES = libvlc/renderer_discoverer.c
>  diff --git a/test/libvlc/media_player.c b/test/libvlc/media_player.c
>  index f3198b5..c44349a 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,96 @@ static void test_media_player_pause_stop(const char**
> argv, int argc)
>       libvlc_release (vlc);
>   }
>
>  +static void
>  +player_has_es(const struct libvlc_event_t *p_ev, void *p_data)
>  +{
>  +    (void) p_ev;
>  +    vlc_sem_t *p_sem = p_data;
>  +    vlc_sem_post(p_sem);
>  +}
>  +
>  +static void wait_done(void *p_data)
>  +{
>  +    vlc_sem_t *p_sem = p_data;
>  +    vlc_sem_post(p_sem);
>  +}
>  +
>  +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, p_viewpoint));
>  +
>  +    p_viewpoint->f_yaw = 1.57f;
>  +    assert(!libvlc_video_set_viewpoint(mi, p_viewpoint));
>  +    assert(p_viewpoint->f_yaw == 1.57f);
>  +
>  +    libvlc_free(p_viewpoint);
>  +    p_viewpoint = libvlc_video_new_viewpoint();
>  +    assert(p_viewpoint != NULL);
>  +
>  +    assert(!libvlc_video_get_viewpoint(mi, p_viewpoint));
>  +    assert(p_viewpoint->f_yaw == 1.57f);
>  +
>  +    libvlc_media_player_play (mi);
>  +
>  +    vlc_sem_t es_selected;
>  +    vlc_sem_init(&es_selected, 0);
>  +
>  +    libvlc_event_manager_t * em = libvlc_media_player_event_manager(mi);
>  +    int val = libvlc_event_attach(em, libvlc_MediaPlayerVout,
> player_has_es, &es_selected);
>  +    assert(val == 0);
>  +
>  +    log ("Waiting for Vout\n");
>  +    vlc_sem_wait(&es_selected);
>  +    log ("Vout found\n");
>  +
>  +    libvlc_event_detach(em, libvlc_MediaPlayerVout, player_has_es,
> &es_selected);
>  +
>  +    assert(!libvlc_video_get_viewpoint(mi, p_viewpoint));
>  +    assert(p_viewpoint->f_yaw == 1.57f);
>  +
>  +    p_viewpoint->f_yaw = 0.57f;
>  +    assert(!libvlc_video_set_viewpoint(mi, p_viewpoint));
>  +
>  +    /* let the value propagate */
>  +    vlc_timer_t done_timer;
>  +    int ret = vlc_timer_create( &done_timer, wait_done, &es_selected );
>  +    assert(!ret);
>  +    vlc_timer_schedule( done_timer, false, 1, CLOCK_FREQ / 5 );
>  +    vlc_sem_wait(&es_selected);
>  +    vlc_timer_destroy( done_timer );
>  +    vlc_sem_destroy(&es_selected);
>  +
>  +    assert(!libvlc_video_get_viewpoint(mi, p_viewpoint));
>  +    assert(p_viewpoint->f_yaw == 0.57f);
>  +
>  +    libvlc_free(p_viewpoint);
>  +
>  +    libvlc_media_player_stop (mi);
>  +    libvlc_media_player_release (mi);
>  +    libvlc_release (vlc);
>  +}
>
>   int main (void)
>   {
>  @@ -198,6 +291,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;
>   }
>  --
>  2.10.1
>
>
> _______________________________________________
> vlc-devel mailing list
> To unsubscribe or modify your subscription options:
> https://mailman.videolan.org/listinfo/vlc-devel


More information about the vlc-devel mailing list