[vlc-devel] [PATCH 10/15] libvlc: add the API needed to set/get the viewpoint in 360° videos
Filip Roséen
filip at atch.se
Fri Nov 4 18:47:29 CET 2016
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"*.
> +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?
> + }
> + 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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/vlc-devel/attachments/20161104/1a7e7460/attachment-0001.html>
More information about the vlc-devel
mailing list