aout: add "audio renderer" converters
[vlc.git] / src / audio_output / dec.c
1 /*****************************************************************************
2  * dec.c : audio output API towards decoders
3  *****************************************************************************
4  * Copyright (C) 2002-2007 VLC authors and VideoLAN
5  * $Id$
6  *
7  * Authors: Christophe Massiot <massiot@via.ecp.fr>
8  *
9  * This program is free software; you can redistribute it and/or modify it
10  * under the terms of the GNU Lesser General Public License as published by
11  * the Free Software Foundation; either version 2.1 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27 #ifdef HAVE_CONFIG_H
28 # include "config.h"
29 #endif
30
31 #include <assert.h>
32
33 #include <vlc_common.h>
34 #include <vlc_aout.h>
35 #include <vlc_input.h>
36
37 #include "aout_internal.h"
38 #include "libvlc.h"
39
40 /**
41  * Creates an audio output
42  */
43 int aout_DecNew( audio_output_t *p_aout,
44                  const audio_sample_format_t *p_format,
45                  const audio_replay_gain_t *p_replay_gain,
46                  const aout_request_vout_t *p_request_vout )
47 {
48
49     /* Sanitize audio format, input need to have a valid physical channels
50      * layout or a valid number of channels. */
51     int i_map_channels = aout_FormatNbChannels( p_format );
52     if( ( i_map_channels == 0 && p_format->i_channels == 0 )
53        || i_map_channels > AOUT_CHAN_MAX || p_format->i_channels > INPUT_CHAN_MAX )
54     {
55         msg_Err( p_aout, "invalid audio channels count" );
56         return -1;
57     }
58
59     if( p_format->i_rate > 352800 )
60     {
61         msg_Err( p_aout, "excessive audio sample frequency (%u)",
62                  p_format->i_rate );
63         return -1;
64     }
65     if( p_format->i_rate < 4000 )
66     {
67         msg_Err( p_aout, "too low audio sample frequency (%u)",
68                  p_format->i_rate );
69         return -1;
70     }
71
72     aout_owner_t *owner = aout_owner(p_aout);
73
74     /* TODO: reduce lock scope depending on decoder's real need */
75     aout_OutputLock (p_aout);
76
77     /* Create the audio output stream */
78     owner->volume = aout_volume_New (p_aout, p_replay_gain);
79
80     atomic_store (&owner->restart, 0);
81     owner->input_format = *p_format;
82     owner->mixer_format = owner->input_format;
83
84     if (p_format->channel_type == AUDIO_CHANNEL_TYPE_BITMAP
85      && i_map_channels == 0)
86     {
87         /* The output channel map is unknown, use the WAVE one. */
88         assert(owner->mixer_format.i_channels > 0);
89         aout_SetWavePhysicalChannels(&owner->mixer_format);
90     }
91     owner->request_vout = *p_request_vout;
92
93     var_Change (p_aout, "stereo-mode", VLC_VAR_SETVALUE,
94                 &(vlc_value_t) { .i_int = AOUT_VAR_CHAN_UNSET }, NULL);
95
96     int remap[] = AOUT_CHAN_REMAP_INIT;
97     if (aout_OutputNew (p_aout, &owner->mixer_format, remap))
98         goto error;
99     aout_volume_SetFormat (owner->volume, owner->mixer_format.i_format);
100
101     /* Create the audio filtering "input" pipeline */
102     memcpy(owner->remap, remap, sizeof(remap));
103     owner->filters = aout_FiltersNew (p_aout, p_format, &owner->mixer_format,
104                                       &owner->request_vout, owner->remap);
105     if (owner->filters == NULL)
106     {
107         aout_OutputDelete (p_aout);
108 error:
109         aout_volume_Delete (owner->volume);
110         owner->volume = NULL;
111         aout_OutputUnlock (p_aout);
112         return -1;
113     }
114
115
116     owner->sync.end = VLC_TS_INVALID;
117     owner->sync.resamp_type = AOUT_RESAMPLING_NONE;
118     owner->sync.discontinuity = true;
119     aout_OutputUnlock (p_aout);
120
121     atomic_init (&owner->buffers_lost, 0);
122     atomic_init (&owner->buffers_played, 0);
123     return 0;
124 }
125
126 /**
127  * Stops all plugins involved in the audio output.
128  */
129 void aout_DecDelete (audio_output_t *aout)
130 {
131     aout_owner_t *owner = aout_owner (aout);
132
133     aout_OutputLock (aout);
134     if (owner->mixer_format.i_format)
135     {
136         aout_FiltersDelete (aout, owner->filters);
137         aout_OutputDelete (aout);
138     }
139     aout_volume_Delete (owner->volume);
140     owner->volume = NULL;
141     aout_OutputUnlock (aout);
142 }
143
144 static int aout_CheckReady (audio_output_t *aout)
145 {
146     aout_owner_t *owner = aout_owner (aout);
147
148     int status = AOUT_DEC_SUCCESS;
149     int restart = atomic_exchange (&owner->restart, 0);
150     if (unlikely(restart))
151     {
152         if (owner->mixer_format.i_format)
153             aout_FiltersDelete (aout, owner->filters);
154
155         if (restart & AOUT_RESTART_OUTPUT)
156         {   /* Reinitializes the output */
157             msg_Dbg (aout, "restarting output...");
158             if (owner->mixer_format.i_format)
159                 aout_OutputDelete (aout);
160             owner->mixer_format = owner->input_format;
161             int remap[] = AOUT_CHAN_REMAP_INIT;
162             if (aout_OutputNew (aout, &owner->mixer_format, remap))
163                 owner->mixer_format.i_format = 0;
164             memcpy(owner->remap, remap, sizeof(remap));
165             aout_volume_SetFormat (owner->volume,
166                                    owner->mixer_format.i_format);
167
168             /* Notify the decoder that the aout changed in order to try a new
169              * suitable codec (like an HDMI audio format). However, keep the
170              * same codec if the aout was restarted because of a stereo-mode
171              * change from the user. */
172             if (!(restart & AOUT_RESTART_STEREOMODE))
173                 status = AOUT_DEC_CHANGED;
174         }
175
176         msg_Dbg (aout, "restarting filters...");
177         owner->sync.end = VLC_TS_INVALID;
178         owner->sync.resamp_type = AOUT_RESAMPLING_NONE;
179
180         if (owner->mixer_format.i_format)
181         {
182             owner->filters = aout_FiltersNew (aout, &owner->input_format,
183                                               &owner->mixer_format,
184                                               &owner->request_vout,
185                                               owner->remap);
186             if (owner->filters == NULL)
187             {
188                 aout_OutputDelete (aout);
189                 owner->mixer_format.i_format = 0;
190             }
191         }
192         /* TODO: This would be a good time to call clean up any video output
193          * left over by an audio visualization:
194         input_resource_TerminatVout(MAGIC HERE); */
195     }
196     return (owner->mixer_format.i_format) ? status : AOUT_DEC_FAILED;
197 }
198
199 /**
200  * Marks the audio output for restart, to update any parameter of the output
201  * plug-in (e.g. output device or channel mapping).
202  */
203 void aout_RequestRestart (audio_output_t *aout, unsigned mode)
204 {
205     aout_owner_t *owner = aout_owner (aout);
206     atomic_fetch_or (&owner->restart, mode);
207     msg_Dbg (aout, "restart requested (%u)", mode);
208 }
209
210 /*
211  * Buffer management
212  */
213
214 static void aout_StopResampling (audio_output_t *aout)
215 {
216     aout_owner_t *owner = aout_owner (aout);
217
218     owner->sync.resamp_type = AOUT_RESAMPLING_NONE;
219     aout_FiltersAdjustResampling (owner->filters, 0);
220 }
221
222 static void aout_DecSilence (audio_output_t *aout, mtime_t length, mtime_t pts)
223 {
224     aout_owner_t *owner = aout_owner (aout);
225     const audio_sample_format_t *fmt = &owner->mixer_format;
226     size_t frames = (fmt->i_rate * length) / CLOCK_FREQ;
227
228     block_t *block = block_Alloc (frames * fmt->i_bytes_per_frame
229                                   / fmt->i_frame_length);
230     if (unlikely(block == NULL))
231         return; /* uho! */
232
233     msg_Dbg (aout, "inserting %zu zeroes", frames);
234     memset (block->p_buffer, 0, block->i_buffer);
235     block->i_nb_samples = frames;
236     block->i_pts = pts;
237     block->i_dts = pts;
238     block->i_length = length;
239     aout_OutputPlay (aout, block);
240 }
241
242 static void aout_DecSynchronize (audio_output_t *aout, mtime_t dec_pts,
243                                  int input_rate)
244 {
245     aout_owner_t *owner = aout_owner (aout);
246     mtime_t drift;
247
248     /**
249      * Depending on the drift between the actual and intended playback times,
250      * the audio core may ignore the drift, trigger upsampling or downsampling,
251      * insert silence or even discard samples.
252      * Future VLC versions may instead adjust the input rate.
253      *
254      * The audio output plugin is responsible for estimating its actual
255      * playback time, or rather the estimated time when the next sample will
256      * be played. (The actual playback time is always the current time, that is
257      * to say mdate(). It is not an useful statistic.)
258      *
259      * Most audio output plugins can estimate the delay until playback of
260      * the next sample to be written to the buffer, or equally the time until
261      * all samples in the buffer will have been played. Then:
262      *    pts = mdate() + delay
263      */
264     if (aout_OutputTimeGet (aout, &drift) != 0)
265         return; /* nothing can be done if timing is unknown */
266     drift += mdate () - dec_pts;
267
268     /* Late audio output.
269      * This can happen due to insufficient caching, scheduling jitter
270      * or bug in the decoder. Ideally, the output would seek backward. But that
271      * is not portable, not supported by some hardware and often unsafe/buggy
272      * where supported. The other alternative is to flush the buffers
273      * completely. */
274     if (drift > (owner->sync.discontinuity ? 0
275                   : +3 * input_rate * AOUT_MAX_PTS_DELAY / INPUT_RATE_DEFAULT))
276     {
277         if (!owner->sync.discontinuity)
278             msg_Warn (aout, "playback way too late (%"PRId64"): "
279                       "flushing buffers", drift);
280         else
281             msg_Dbg (aout, "playback too late (%"PRId64"): "
282                      "flushing buffers", drift);
283         aout_OutputFlush (aout, false);
284
285         aout_StopResampling (aout);
286         owner->sync.end = VLC_TS_INVALID;
287         owner->sync.discontinuity = true;
288
289         /* Now the output might be too early... Recheck. */
290         if (aout_OutputTimeGet (aout, &drift) != 0)
291             return; /* nothing can be done if timing is unknown */
292         drift += mdate () - dec_pts;
293     }
294
295     /* Early audio output.
296      * This is rare except at startup when the buffers are still empty. */
297     if (drift < (owner->sync.discontinuity ? 0
298                 : -3 * input_rate * AOUT_MAX_PTS_ADVANCE / INPUT_RATE_DEFAULT))
299     {
300         if (!owner->sync.discontinuity)
301             msg_Warn (aout, "playback way too early (%"PRId64"): "
302                       "playing silence", drift);
303         aout_DecSilence (aout, -drift, dec_pts);
304
305         aout_StopResampling (aout);
306         owner->sync.discontinuity = true;
307         drift = 0;
308     }
309
310     if (!aout_FiltersCanResample(owner->filters))
311         return;
312
313     /* Resampling */
314     if (drift > +AOUT_MAX_PTS_DELAY
315      && owner->sync.resamp_type != AOUT_RESAMPLING_UP)
316     {
317         msg_Warn (aout, "playback too late (%"PRId64"): up-sampling",
318                   drift);
319         owner->sync.resamp_type = AOUT_RESAMPLING_UP;
320         owner->sync.resamp_start_drift = +drift;
321     }
322     if (drift < -AOUT_MAX_PTS_ADVANCE
323      && owner->sync.resamp_type != AOUT_RESAMPLING_DOWN)
324     {
325         msg_Warn (aout, "playback too early (%"PRId64"): down-sampling",
326                   drift);
327         owner->sync.resamp_type = AOUT_RESAMPLING_DOWN;
328         owner->sync.resamp_start_drift = -drift;
329     }
330
331     if (owner->sync.resamp_type == AOUT_RESAMPLING_NONE)
332         return; /* Everything is fine. Nothing to do. */
333
334     if (llabs (drift) > 2 * owner->sync.resamp_start_drift)
335     {   /* If the drift is ever increasing, then something is seriously wrong.
336          * Cease resampling and hope for the best. */
337         msg_Warn (aout, "timing screwed (drift: %"PRId64" us): "
338                   "stopping resampling", drift);
339         aout_StopResampling (aout);
340         return;
341     }
342
343     /* Resampling has been triggered earlier. This checks if it needs to be
344      * increased or decreased. Resampling rate changes must be kept slow for
345      * the comfort of listeners. */
346     int adj = (owner->sync.resamp_type == AOUT_RESAMPLING_UP) ? +2 : -2;
347
348     if (2 * llabs (drift) <= owner->sync.resamp_start_drift)
349         /* If the drift has been reduced from more than half its initial
350          * value, then it is time to switch back the resampling direction. */
351         adj *= -1;
352
353     if (!aout_FiltersAdjustResampling (owner->filters, adj))
354     {   /* Everything is back to normal: stop resampling. */
355         owner->sync.resamp_type = AOUT_RESAMPLING_NONE;
356         msg_Dbg (aout, "resampling stopped (drift: %"PRId64" us)", drift);
357     }
358 }
359
360 /*****************************************************************************
361  * aout_DecPlay : filter & mix the decoded buffer
362  *****************************************************************************/
363 int aout_DecPlay (audio_output_t *aout, block_t *block, int input_rate)
364 {
365     aout_owner_t *owner = aout_owner (aout);
366
367     assert (input_rate >= INPUT_RATE_DEFAULT / AOUT_MAX_INPUT_RATE);
368     assert (input_rate <= INPUT_RATE_DEFAULT * AOUT_MAX_INPUT_RATE);
369     assert (block->i_pts >= VLC_TS_0);
370
371     block->i_length = CLOCK_FREQ * block->i_nb_samples
372                                  / owner->input_format.i_rate;
373
374     aout_OutputLock (aout);
375     int ret = aout_CheckReady (aout);
376     if (unlikely(ret == AOUT_DEC_FAILED))
377         goto drop; /* Pipeline is unrecoverably broken :-( */
378
379     const mtime_t now = mdate (), advance = block->i_pts - now;
380     if (advance < -AOUT_MAX_PTS_DELAY)
381     {   /* Late buffer can be caused by bugs in the decoder, by scheduling
382          * latency spikes (excessive load, SIGSTOP, etc.) or if buffering is
383          * insufficient. We assume the PTS is wrong and play the buffer anyway:
384          * Hopefully video has encountered a similar PTS problem as audio. */
385         msg_Warn (aout, "buffer too late (%"PRId64" us): dropped", advance);
386         goto drop;
387     }
388     if (advance > AOUT_MAX_ADVANCE_TIME)
389     {   /* Early buffers can only be caused by bugs in the decoder. */
390         msg_Err (aout, "buffer too early (%"PRId64" us): dropped", advance);
391         goto drop;
392     }
393     if (block->i_flags & BLOCK_FLAG_DISCONTINUITY)
394         owner->sync.discontinuity = true;
395
396     block = aout_FiltersPlay (owner->filters, block, input_rate);
397     if (block == NULL)
398         goto lost;
399
400     /* Software volume */
401     aout_volume_Amplify (owner->volume, block);
402
403     /* Drift correction */
404     aout_DecSynchronize (aout, block->i_pts, input_rate);
405
406     /* Output */
407     owner->sync.end = block->i_pts + block->i_length + 1;
408     owner->sync.discontinuity = false;
409     aout_OutputPlay (aout, block);
410     atomic_fetch_add(&owner->buffers_played, 1);
411 out:
412     aout_OutputUnlock (aout);
413     return ret;
414 drop:
415     owner->sync.discontinuity = true;
416     block_Release (block);
417 lost:
418     atomic_fetch_add(&owner->buffers_lost, 1);
419     goto out;
420 }
421
422 void aout_DecGetResetStats(audio_output_t *aout, unsigned *restrict lost,
423                            unsigned *restrict played)
424 {
425     aout_owner_t *owner = aout_owner (aout);
426
427     *lost = atomic_exchange(&owner->buffers_lost, 0);
428     *played = atomic_exchange(&owner->buffers_played, 0);
429 }
430
431 void aout_DecChangePause (audio_output_t *aout, bool paused, mtime_t date)
432 {
433     aout_owner_t *owner = aout_owner (aout);
434
435     aout_OutputLock (aout);
436     if (owner->sync.end != VLC_TS_INVALID)
437     {
438         if (paused)
439             owner->sync.end -= date;
440         else
441             owner->sync.end += date;
442     }
443     if (owner->mixer_format.i_format)
444         aout_OutputPause (aout, paused, date);
445     aout_OutputUnlock (aout);
446 }
447
448 void aout_DecFlush (audio_output_t *aout, bool wait)
449 {
450     aout_owner_t *owner = aout_owner (aout);
451
452     aout_OutputLock (aout);
453     owner->sync.end = VLC_TS_INVALID;
454     if (owner->mixer_format.i_format)
455     {
456         if (wait)
457         {
458             block_t *block = aout_FiltersDrain (owner->filters);
459             if (block)
460                 aout_OutputPlay (aout, block);
461         }
462         else
463             aout_FiltersFlush (owner->filters);
464         aout_OutputFlush (aout, wait);
465     }
466     aout_OutputUnlock (aout);
467 }