From 426710c117852ea743e48d171240f0b4767ad2df Mon Sep 17 00:00:00 2001 From: Thomas Guillem Date: Tue, 29 Nov 2016 18:35:46 +0100 Subject: [PATCH] aout: handle viewpoint change via audio filters --- include/vlc_aout.h | 1 + include/vlc_filter.h | 15 +++++++++++++++ src/audio_output/aout_internal.h | 11 +++++++++++ src/audio_output/dec.c | 19 +++++++++++++++++++ src/audio_output/filters.c | 13 +++++++++++++ src/audio_output/output.c | 14 ++++++++++++++ src/libvlccore.sym | 1 + 7 files changed, 74 insertions(+) diff --git a/include/vlc_aout.h b/include/vlc_aout.h index c352634120..3693c0e921 100644 --- a/include/vlc_aout.h +++ b/include/vlc_aout.h @@ -388,6 +388,7 @@ VLC_API bool aout_FiltersAdjustResampling(aout_filters_t *, int); VLC_API block_t *aout_FiltersPlay(aout_filters_t *, block_t *, int rate); VLC_API block_t *aout_FiltersDrain(aout_filters_t *); VLC_API void aout_FiltersFlush(aout_filters_t *); +VLC_API void aout_FiltersChangeViewpoint(aout_filters_t *, const vlc_viewpoint_t *vp); VLC_API vout_thread_t * aout_filter_RequestVout( filter_t *, vout_thread_t *p_vout, const video_format_t *p_fmt ); diff --git a/include/vlc_filter.h b/include/vlc_filter.h index d26cad53a9..5b376b4bd0 100644 --- a/include/vlc_filter.h +++ b/include/vlc_filter.h @@ -118,6 +118,14 @@ struct filter_t */ void (*pf_flush)( filter_t * ); + /** Change viewpoint + * + * Pass a new viewpoint to audio filters. Filters like the spatialaudio one + * used for Ambisonics rendering will change its output according to this + * viewpoint. + */ + void (*pf_change_viewpoint)( filter_t *, const vlc_viewpoint_t * ); + union { /** Filter mouse state (video filter). @@ -171,6 +179,13 @@ static inline void filter_Flush( filter_t *p_filter ) p_filter->pf_flush( p_filter ); } +static inline void filter_ChangeViewpoint( filter_t *p_filter, + const vlc_viewpoint_t *vp) +{ + if( p_filter->pf_change_viewpoint != NULL ) + p_filter->pf_change_viewpoint( p_filter, vp ); +} + /** * This function will drain, then flush an audio filter. */ diff --git a/src/audio_output/aout_internal.h b/src/audio_output/aout_internal.h index 831307b965..c90eb6a44d 100644 --- a/src/audio_output/aout_internal.h +++ b/src/audio_output/aout_internal.h @@ -25,6 +25,7 @@ # define LIBVLC_AOUT_INTERNAL_H 1 # include +# include /* for vlc_viewpoint_t */ /* Max input rate factor (1/4 -> 4) */ # define AOUT_MAX_INPUT_RATE (4) @@ -67,6 +68,13 @@ typedef struct unsigned count; } dev; + struct + { + atomic_bool update; + vlc_mutex_t lock; + vlc_viewpoint_t value; + } vp; + struct { mtime_t end; /**< Last seen PTS */ @@ -170,4 +178,7 @@ static inline void aout_SetWavePhysicalChannels(audio_sample_format_t *fmt) /* From filters.c */ bool aout_FiltersCanResample (aout_filters_t *filters); +void aout_ChangeViewpoint(audio_output_t *aout, + const vlc_viewpoint_t *p_viewpoint); + #endif /* !LIBVLC_AOUT_INTERNAL_H */ diff --git a/src/audio_output/dec.c b/src/audio_output/dec.c index 58ede03c51..4e71a0904c 100644 --- a/src/audio_output/dec.c +++ b/src/audio_output/dec.c @@ -112,6 +112,7 @@ error: atomic_init (&owner->buffers_lost, 0); atomic_init (&owner->buffers_played, 0); + atomic_init (&owner->vp.update, false); return 0; } @@ -384,6 +385,13 @@ int aout_DecPlay (audio_output_t *aout, block_t *block, int input_rate) if (block->i_flags & BLOCK_FLAG_DISCONTINUITY) owner->sync.discontinuity = true; + if (atomic_exchange(&owner->vp.update, false)) + { + vlc_mutex_lock (&owner->vp.lock); + aout_FiltersChangeViewpoint (owner->filters, &owner->vp.value); + vlc_mutex_unlock (&owner->vp.lock); + } + block = aout_FiltersPlay (owner->filters, block, input_rate); if (block == NULL) goto lost; @@ -456,3 +464,14 @@ void aout_DecFlush (audio_output_t *aout, bool wait) } aout_OutputUnlock (aout); } + +void aout_ChangeViewpoint(audio_output_t *aout, + const vlc_viewpoint_t *p_viewpoint) +{ + aout_owner_t *owner = aout_owner (aout); + + vlc_mutex_lock (&owner->vp.lock); + owner->vp.value = *p_viewpoint; + atomic_store(&owner->vp.update, true); + vlc_mutex_unlock (&owner->vp.lock); +} diff --git a/src/audio_output/filters.c b/src/audio_output/filters.c index 04b13dd8bd..155f5b5134 100644 --- a/src/audio_output/filters.c +++ b/src/audio_output/filters.c @@ -327,6 +327,13 @@ static void aout_FiltersPipelineFlush(filter_t *const *filters, filter_Flush (filters[i]); } +static void aout_FiltersPipelineChangeViewpoint(filter_t *const *filters, + unsigned count, + const vlc_viewpoint_t *vp) +{ + for (unsigned i = 0; i < count; i++) + filter_ChangeViewpoint (filters[i], vp); +} #define AOUT_MAX_FILTERS 10 @@ -760,3 +767,9 @@ void aout_FiltersFlush (aout_filters_t *filters) if (filters->resampler != NULL) aout_FiltersPipelineFlush (&filters->resampler, 1); } + +void aout_FiltersChangeViewpoint (aout_filters_t *filters, + const vlc_viewpoint_t *vp) +{ + aout_FiltersPipelineChangeViewpoint (filters->tab, filters->count, vp); +} diff --git a/src/audio_output/output.c b/src/audio_output/output.c index eb79479a8b..a4d234fd83 100644 --- a/src/audio_output/output.c +++ b/src/audio_output/output.c @@ -181,6 +181,15 @@ static int StereoModeCallback (vlc_object_t *obj, const char *varname, return 0; } +static int ViewpointCallback (vlc_object_t *obj, const char *var, + vlc_value_t prev, vlc_value_t cur, void *data) +{ + if( cur.p_address != NULL ) + aout_ChangeViewpoint((audio_output_t *)obj, cur.p_address ); + (void) var; (void) data; (void) prev; + return VLC_SUCCESS; +} + #undef aout_New /** * Creates an audio output object and initializes an output module. @@ -199,6 +208,7 @@ audio_output_t *aout_New (vlc_object_t *parent) vlc_mutex_init (&owner->lock); vlc_mutex_init (&owner->req.lock); vlc_mutex_init (&owner->dev.lock); + vlc_mutex_init (&owner->vp.lock); owner->req.device = (char *)unset_str; owner->req.volume = -1.f; owner->req.mute = -1; @@ -300,6 +310,8 @@ audio_output_t *aout_New (vlc_object_t *parent) text.psz_string = _("Audio filters"); var_Change (aout, "audio-filter", VLC_VAR_SETTEXT, &text, NULL); + var_Create (aout, "viewpoint", VLC_VAR_ADDRESS | VLC_VAR_DOINHERIT); + var_AddCallback (aout, "viewpoint", ViewpointCallback, NULL); var_Create (aout, "audio-visual", VLC_VAR_STRING | VLC_VAR_DOINHERIT); text.psz_string = _("Audio visualizations"); @@ -350,6 +362,7 @@ void aout_Destroy (audio_output_t *aout) aout->device_select = NULL; aout_OutputUnlock (aout); + var_DelCallback (aout, "viewpoint", ViewpointCallback, NULL); var_DelCallback (aout, "audio-filter", FilterCallback, NULL); var_DelCallback (aout, "device", var_CopyDevice, aout->obj.parent); var_DelCallback (aout, "mute", var_Copy, aout->obj.parent); @@ -376,6 +389,7 @@ static void aout_Destructor (vlc_object_t *obj) } assert (owner->req.device == unset_str); + vlc_mutex_destroy (&owner->vp.lock); vlc_mutex_destroy (&owner->req.lock); vlc_mutex_destroy (&owner->lock); } diff --git a/src/libvlccore.sym b/src/libvlccore.sym index 93c56d3749..d8649afe1b 100644 --- a/src/libvlccore.sym +++ b/src/libvlccore.sym @@ -23,6 +23,7 @@ aout_DeviceGet aout_DeviceSet aout_DevicesList aout_FiltersNew +aout_FiltersChangeViewpoint aout_FiltersDelete aout_FiltersDrain aout_FiltersFlush