<html><head></head><body><div class="gmail_quote">Le 7 juillet 2017 17:03:01 GMT+03:00, Thomas Guillem <thomas@gllm.fr> a écrit :<blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
<pre class="k9mail">---<br /> modules/audio_output/pulse.c | 90 +++++++++++++++++++++++++++++++++++++++++++-<br /> 1 file changed, 89 insertions(+), 1 deletion(-)<br /><br />diff --git a/modules/audio_output/pulse.c b/modules/audio_output/pulse.c<br />index ac1254c8b9..ccec8df8f4 100644<br />--- a/modules/audio_output/pulse.c<br />+++ b/modules/audio_output/pulse.c<br />@@ -74,6 +74,10 @@ struct aout_sys_t<br />     pa_stream_flags_t flags_force; /**< Forced flags (stream must be NULL) */<br />     char *sink_force; /**< Forced sink name (stream must be NULL) */<br /> <br />+    vlc_fourcc_t fourcc;<br />+    uint8_t chans_table[AOUT_CHAN_MAX];<br />+    uint8_t chans_to_reorder;<br />+<br />     struct sink *sinks; /**< Locally-cached list of sinks */<br /> };<br /> <br />@@ -490,6 +494,11 @@ static void Play(audio_output_t *aout, block_t *block)<br />     aout_sys_t *sys = aout->sys;<br />     pa_stream *s = sys->stream;<br /> <br />+    if (sys->chans_to_reorder)<br />+        aout_ChannelReorder(block->p_buffer, block->i_buffer,<br />+                            sys->chans_to_reorder, sys->chans_table,<br />+                            sys->fourcc);<br />+<br />     const void *ptr = data_convert(&block);<br />     if (unlikely(ptr == NULL))<br />         return;<br />@@ -687,6 +696,36 @@ static const char *str_map(const char *key, const char *const table[][2],<br />      return (r != NULL) ? r[1] : NULL;<br /> }<br /> <br />+static int channel_map_pulse_to_vlc(pa_channel_position_t map)<br />+{<br />+    static_assert(AOUT_CHAN_MAX == 9, "Missing channels");<br />+<br />+    switch (map)<br />+    {<br />+        case PA_CHANNEL_POSITION_FRONT_LEFT:<br />+            return AOUT_CHAN_LEFT;<br />+        case PA_CHANNEL_POSITION_FRONT_RIGHT:<br />+            return AOUT_CHAN_RIGHT;<br />+        case PA_CHANNEL_POSITION_SIDE_LEFT:<br />+            return AOUT_CHAN_MIDDLELEFT;<br />+        case PA_CHANNEL_POSITION_SIDE_RIGHT:<br />+            return AOUT_CHAN_MIDDLERIGHT;<br />+        case PA_CHANNEL_POSITION_REAR_LEFT:<br />+            return AOUT_CHAN_REARLEFT;<br />+        case PA_CHANNEL_POSITION_REAR_RIGHT:<br />+            return AOUT_CHAN_REARRIGHT;<br />+        case PA_CHANNEL_POSITION_REAR_CENTER:<br />+            return AOUT_CHAN_REARCENTER;<br />+        case PA_CHANNEL_POSITION_LFE:<br />+            return AOUT_CHAN_LFE;<br />+        case PA_CHANNEL_POSITION_MONO:<br />+        case PA_CHANNEL_POSITION_FRONT_CENTER:<br />+            return AOUT_CHAN_CENTER;<br />+        default:<br />+            return 0;<br />+    }<br />+}<br />+<br /> /**<br />  * Create a PulseAudio playback stream, a.k.a. a sink input.<br />  */<br />@@ -804,6 +843,7 @@ static int Start(audio_output_t *aout, audio_sample_format_t *restrict fmt)<br /> <br />     if (encoding != PA_ENCODING_PCM)<br />     {<br />+        assert(fmt->channels_type == AUDIO_CHANNELS_TYPE_PHYSICAL);<br />         pa_format_info_set_channels(formatv, ss.channels);<br /> <br />         /* FIX flags are only permitted for PCM, and there is no way to pass<br />@@ -812,7 +852,7 @@ static int Start(audio_output_t *aout, audio_sample_format_t *restrict fmt)<br />                  | PA_STREAM_FIX_RATE<br />                  | PA_STREAM_FIX_CHANNELS);<br />     }<br />-    else<br />+    else if (fmt->channels_type == AUDIO_CHANNELS_TYPE_PHYSICAL)<br />     {<br />         /* Channel mapping (order defined in vlc_aout.h) */<br />         struct pa_channel_map map;<br />@@ -861,6 +901,19 @@ static int Start(audio_output_t *aout, audio_sample_format_t *restrict fmt)<br />         pa_format_info_set_channels(formatv, ss.channels);<br />         pa_format_info_set_channel_map(formatv, &map);<br />     }<br />+    else<br />+    {   /* AUDIO_CHANNELS_TYPE_AMBISONICS */<br />+        fmt->channels_type = AUDIO_CHANNELS_TYPE_PHYSICAL;<br />+<br />+        /* Use the channel layout of the sink and override the current one.<br />+         * This new layout be will used to configure the ambisonics filter. */<br />+        flags |= PA_STREAM_FIX_CHANNELS;<br />+<br />+        /* Setup low latency in order to quickly react to ambisonics filters<br />+         * viewpoint changes. */<br />+        flags |= PA_STREAM_ADJUST_LATENCY;<br />+        attr.tlength = pa_usec_to_bytes(2 * AOUT_MIN_PREPARE_TIME, &ss);<br />+    }<br /> <br />     /* Create a playback stream */<br />     pa_proplist *props = pa_proplist_new();<br />@@ -934,9 +987,44 @@ static int Start(audio_output_t *aout, audio_sample_format_t *restrict fmt)<br />         fmt->i_rate = spec->rate;<br />     }<br /> <br />+    if (flags & PA_STREAM_FIX_CHANNELS)<br />+    {<br />+        const pa_channel_map *map = pa_stream_get_channel_map(s);<br />+        assert(map != NULL);<br />+<br />+        const char *name = pa_channel_map_to_name(map);<br />+        msg_Info(aout, "using %s channel map", (name != NULL) ? name : "?");<br />+<br />+        uint8_t chans_out_count = 0;<br />+        uint32_t chans_out[AOUT_CHAN_MAX];<br />+        fmt->i_physical_channels = 0;<br />+        for (uint8_t i = 0; i < map->channels; ++i)<br />+        {<br />+            int vlcchan = channel_map_pulse_to_vlc(map->map[i]);<br />+            if (vlcchan != 0)<br />+            {<br />+                chans_out[chans_out_count++] = vlcchan;<br />+                assert(chans_out_count <= AOUT_CHAN_MAX);<br />+                fmt->i_physical_channels |= vlcchan;<br />+            }<br />+        }<br />+        if (chans_out_count != map->channels)<br />+            msg_Warn(aout, "%u channels won't be mapped",<br />+                     map->channels - chans_out_count);<br />+        fmt->i_original_channels = fmt->i_physical_channels;<br />+        aout_FormatPrepare(fmt);<br />+<br />+        sys->chans_to_reorder =<br />+            aout_CheckChannelReorder(NULL, chans_out, fmt->i_physical_channels,<br />+                                     sys->chans_table);<br />+    }<br />+    else<br />+        sys->chans_to_reorder = 0;<br />+<br />     stream_buffer_attr_cb(s, aout);<br />     stream_moved_cb(s, aout);<br />     pa_threaded_mainloop_unlock(sys->mainloop);<br />+    sys->fourcc = fmt->i_format;<br /> <br />     return VLC_SUCCESS;<br /> </pre></blockquote></div><br clear="all">Why do you impose the channel order here?!<br>
-- <br>
Rémi Denis-Courmont<br>
Typed on an inconvenient virtual keyboard</body></html>