[vlc-devel] [PATCH 08/16] aout: handle viewpoint change

Thomas Guillem thomas at gllm.fr
Fri Jul 7 16:02:54 CEST 2017


---
 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 647cb3bafd..6b2d490440 100644
--- a/include/vlc_aout.h
+++ b/include/vlc_aout.h
@@ -353,6 +353,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, video_format_t *p_fmt );
 
diff --git a/include/vlc_filter.h b/include/vlc_filter.h
index a0b6bb2945..a5098df403 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 8516d4cd40..5480f01a29 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 <vlc_atomic.h>
+# include <vlc_vout.h> /* for vlc_viewpoint_t */
 
 /* Max input rate factor (1/4 -> 4) */
 # define AOUT_MAX_INPUT_RATE (4)
@@ -69,6 +70,13 @@ typedef struct
 
     struct
     {
+        atomic_bool update;
+        vlc_mutex_t lock;
+        vlc_viewpoint_t value;
+    } vp;
+
+    struct
+    {
         mtime_t end; /**< Last seen PTS */
         unsigned resamp_start_drift; /**< Resampler drift absolute value */
         int resamp_type; /**< Resampler mode (FIXME: redundant / resampling) */
@@ -155,4 +163,7 @@ static inline void aout_InputRequestRestart(audio_output_t *aout)
 /* 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 54d58fe818..e868112684 100644
--- a/src/audio_output/dec.c
+++ b/src/audio_output/dec.c
@@ -125,6 +125,7 @@ error:
 
     atomic_init (&owner->buffers_lost, 0);
     atomic_init (&owner->buffers_played, 0);
+    atomic_init (&owner->vp.update, false);
     return 0;
 }
 
@@ -390,6 +391,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;
@@ -462,3 +470,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 661bfb78a6..25d1fdd47f 100644
--- a/src/audio_output/filters.c
+++ b/src/audio_output/filters.c
@@ -299,6 +299,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
 
@@ -671,3 +678,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 59d2cb121d..becec9c4b4 100644
--- a/src/audio_output/output.c
+++ b/src/audio_output/output.c
@@ -171,6 +171,15 @@ static int FilterCallback (vlc_object_t *obj, const char *var,
     return VLC_SUCCESS;
 }
 
+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.
@@ -189,6 +198,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;
@@ -290,6 +300,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");
@@ -333,6 +345,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);
@@ -358,6 +371,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
-- 
2.11.0



More information about the vlc-devel mailing list