1 /*****************************************************************************
2 * dec.c : audio output API towards decoders
3 *****************************************************************************
4 * Copyright (C) 2002-2019 VLC authors, VideoLAN and Videolabs SAS
6 * Authors: Christophe Massiot <massiot@via.ecp.fr>
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU Lesser General Public License as published by
10 * the Free Software Foundation; either version 2.1 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program; if not, write to the Free Software Foundation,
20 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
21 *****************************************************************************/
23 /*****************************************************************************
25 *****************************************************************************/
34 #include <vlc_common.h>
37 #include "aout_internal.h"
38 #include "clock/clock.h"
41 static void aout_Drain(audio_output_t
*aout
)
48 if (aout_TimeGet(aout
, &delay
) == 0)
49 vlc_tick_sleep(delay
);
54 * Creates an audio output
56 int aout_DecNew(audio_output_t
*p_aout
, const audio_sample_format_t
*p_format
,
57 int profile
, vlc_clock_t
*clock
,
58 const audio_replay_gain_t
*p_replay_gain
)
63 if( p_format
->i_bitspersample
> 0 )
65 /* Sanitize audio format, input need to have a valid physical channels
66 * layout or a valid number of channels. */
67 int i_map_channels
= aout_FormatNbChannels( p_format
);
68 if( ( i_map_channels
== 0 && p_format
->i_channels
== 0 )
69 || i_map_channels
> AOUT_CHAN_MAX
|| p_format
->i_channels
> INPUT_CHAN_MAX
)
71 msg_Err( p_aout
, "invalid audio channels count" );
76 if( p_format
->i_rate
> 384000 )
78 msg_Err( p_aout
, "excessive audio sample frequency (%u)",
82 if( p_format
->i_rate
< 4000 )
84 msg_Err( p_aout
, "too low audio sample frequency (%u)",
89 aout_owner_t
*owner
= aout_owner(p_aout
);
91 /* Create the audio output stream */
93 owner
->volume
= aout_volume_New (p_aout
, p_replay_gain
);
95 atomic_store_explicit(&owner
->restart
, 0, memory_order_relaxed
);
96 owner
->input_profile
= profile
;
97 owner
->filter_format
= owner
->mixer_format
= owner
->input_format
= *p_format
;
99 owner
->sync
.clock
= clock
;
101 owner
->filters
= NULL
;
102 owner
->filters_cfg
= AOUT_FILTERS_CFG_INIT
;
103 if (aout_OutputNew (p_aout
))
105 aout_volume_SetFormat (owner
->volume
, owner
->mixer_format
.i_format
);
107 vlc_audio_meter_Reset(&owner
->meter
, &owner
->mixer_format
);
109 if (!owner
->bitexact
)
111 /* Create the audio filtering "input" pipeline */
112 owner
->filters
= aout_FiltersNewWithClock(VLC_OBJECT(p_aout
), clock
,
113 &owner
->filter_format
,
114 &owner
->mixer_format
,
115 &owner
->filters_cfg
);
116 if (owner
->filters
== NULL
)
118 aout_OutputDelete (p_aout
);
119 vlc_audio_meter_Reset(&owner
->meter
, NULL
);
122 aout_volume_Delete (owner
->volume
);
123 owner
->volume
= NULL
;
128 owner
->sync
.rate
= 1.f
;
129 owner
->sync
.resamp_type
= AOUT_RESAMPLING_NONE
;
130 owner
->sync
.discontinuity
= true;
131 owner
->original_pts
= VLC_TICK_INVALID
;
132 owner
->sync
.delay
= owner
->sync
.request_delay
= 0;
134 atomic_init (&owner
->buffers_lost
, 0);
135 atomic_init (&owner
->buffers_played
, 0);
136 atomic_store_explicit(&owner
->vp
.update
, true, memory_order_relaxed
);
141 * Stops all plugins involved in the audio output.
143 void aout_DecDelete (audio_output_t
*aout
)
145 aout_owner_t
*owner
= aout_owner (aout
);
147 if (owner
->mixer_format
.i_format
)
151 aout_FiltersDelete (aout
, owner
->filters
);
152 aout_OutputDelete (aout
);
154 aout_volume_Delete (owner
->volume
);
155 owner
->volume
= NULL
;
158 static int aout_CheckReady (audio_output_t
*aout
)
160 aout_owner_t
*owner
= aout_owner (aout
);
161 int status
= AOUT_DEC_SUCCESS
;
163 int restart
= atomic_exchange_explicit(&owner
->restart
, 0,
164 memory_order_acquire
);
165 if (unlikely(restart
))
169 aout_FiltersDelete (aout
, owner
->filters
);
170 owner
->filters
= NULL
;
173 if (restart
& AOUT_RESTART_OUTPUT
)
174 { /* Reinitializes the output */
175 msg_Dbg (aout
, "restarting output...");
176 if (owner
->mixer_format
.i_format
)
177 aout_OutputDelete (aout
);
178 owner
->filter_format
= owner
->mixer_format
= owner
->input_format
;
179 owner
->filters_cfg
= AOUT_FILTERS_CFG_INIT
;
180 if (aout_OutputNew (aout
))
181 owner
->mixer_format
.i_format
= 0;
182 aout_volume_SetFormat (owner
->volume
,
183 owner
->mixer_format
.i_format
);
185 /* Notify the decoder that the aout changed in order to try a new
186 * suitable codec (like an HDMI audio format). However, keep the
187 * same codec if the aout was restarted because of a stereo-mode
188 * change from the user. */
189 if (restart
== AOUT_RESTART_OUTPUT
)
190 status
= AOUT_DEC_CHANGED
;
193 msg_Dbg (aout
, "restarting filters...");
194 owner
->sync
.resamp_type
= AOUT_RESAMPLING_NONE
;
196 if (owner
->mixer_format
.i_format
&& !owner
->bitexact
)
198 owner
->filters
= aout_FiltersNewWithClock(VLC_OBJECT(aout
),
200 &owner
->filter_format
,
201 &owner
->mixer_format
,
202 &owner
->filters_cfg
);
203 if (owner
->filters
== NULL
)
205 aout_OutputDelete (aout
);
206 owner
->mixer_format
.i_format
= 0;
208 aout_FiltersSetClockDelay(owner
->filters
, owner
->sync
.delay
);
211 vlc_audio_meter_Reset(&owner
->meter
,
212 owner
->mixer_format
.i_format
? &owner
->mixer_format
: NULL
);
214 /* TODO: This would be a good time to call clean up any video output
215 * left over by an audio visualization:
216 input_resource_TerminatVout(MAGIC HERE); */
218 return (owner
->mixer_format
.i_format
) ? status
: AOUT_DEC_FAILED
;
222 * Marks the audio output for restart, to update any parameter of the output
223 * plug-in (e.g. output device or channel mapping).
225 void aout_RequestRestart (audio_output_t
*aout
, unsigned mode
)
227 aout_owner_t
*owner
= aout_owner (aout
);
228 atomic_fetch_or_explicit(&owner
->restart
, mode
, memory_order_release
);
229 msg_Dbg (aout
, "restart requested (%u)", mode
);
236 static void aout_StopResampling (audio_output_t
*aout
)
238 aout_owner_t
*owner
= aout_owner (aout
);
239 assert(owner
->filters
);
241 owner
->sync
.resamp_type
= AOUT_RESAMPLING_NONE
;
242 aout_FiltersAdjustResampling (owner
->filters
, 0);
245 static void aout_DecSynchronize(audio_output_t
*aout
, vlc_tick_t system_now
,
247 static void aout_DecSilence (audio_output_t
*aout
, vlc_tick_t length
, vlc_tick_t pts
)
249 aout_owner_t
*owner
= aout_owner (aout
);
250 const audio_sample_format_t
*fmt
= &owner
->mixer_format
;
251 size_t frames
= samples_from_vlc_tick(length
, fmt
->i_rate
);
253 block_t
*block
= block_Alloc (frames
* fmt
->i_bytes_per_frame
254 / fmt
->i_frame_length
);
255 if (unlikely(block
== NULL
))
258 msg_Dbg (aout
, "inserting %zu zeroes / %"PRId64
"ms", frames
, MS_FROM_VLC_TICK(length
));
259 memset (block
->p_buffer
, 0, block
->i_buffer
);
260 block
->i_nb_samples
= frames
;
263 block
->i_length
= length
;
265 const vlc_tick_t system_now
= vlc_tick_now();
266 const vlc_tick_t system_pts
=
267 vlc_clock_ConvertToSystem(owner
->sync
.clock
, system_now
, pts
,
269 aout
->play(aout
, block
, system_pts
);
272 static void aout_DecSynchronize(audio_output_t
*aout
, vlc_tick_t system_now
,
276 * Depending on the drift between the actual and intended playback times,
277 * the audio core may ignore the drift, trigger upsampling or downsampling,
278 * insert silence or even discard samples.
279 * Future VLC versions may instead adjust the input rate.
281 * The audio output plugin is responsible for estimating its actual
282 * playback time, or rather the estimated time when the next sample will
283 * be played. (The actual playback time is always the current time, that is
284 * to say vlc_tick_now(). It is not an useful statistic.)
286 * Most audio output plugins can estimate the delay until playback of
287 * the next sample to be written to the buffer, or equally the time until
288 * all samples in the buffer will have been played. Then:
289 * pts = vlc_tick_now() + delay
291 aout_owner_t
*owner
= aout_owner (aout
);
294 if (aout_TimeGet(aout
, &delay
) != 0)
295 return; /* nothing can be done if timing is unknown */
297 if (owner
->sync
.discontinuity
)
299 /* Chicken-egg situation for most aout modules that can't be started
300 * deferred (all except PulseAudio). These modules will start to play
301 * data immediately and ignore the given play_date (that take the clock
302 * jitter into account). We don't want to let aout_RequestRetiming()
303 * handle the first silence (from the "Early audio output" case) since
304 * this function will first update the clock without taking the jitter
305 * into account. Therefore, we manually insert silence that correspond
306 * to the clock jitter value before updating the clock.
308 vlc_tick_t play_date
=
309 vlc_clock_ConvertToSystem(owner
->sync
.clock
, system_now
+ delay
,
310 dec_pts
, owner
->sync
.rate
);
311 vlc_tick_t jitter
= play_date
- system_now
;
314 aout_DecSilence (aout
, jitter
, dec_pts
- delay
);
315 if (aout_TimeGet(aout
, &delay
) != 0)
320 aout_RequestRetiming(aout
, system_now
+ delay
, dec_pts
);
323 void aout_RequestRetiming(audio_output_t
*aout
, vlc_tick_t system_ts
,
326 aout_owner_t
*owner
= aout_owner (aout
);
327 float rate
= owner
->sync
.rate
;
329 vlc_clock_Update(owner
->sync
.clock
, system_ts
, audio_ts
, rate
);
331 if (unlikely(drift
== INT64_MAX
) || owner
->bitexact
)
332 return; /* cf. INT64_MAX comment in aout_DecPlay() */
334 /* Following calculations expect an opposite drift. Indeed,
335 * vlc_clock_Update() returns a positive relative time, corresponding to
336 * the time when audio_ts is expected to be played (in the future when not
340 /* Late audio output.
341 * This can happen due to insufficient caching, scheduling jitter
342 * or bug in the decoder. Ideally, the output would seek backward. But that
343 * is not portable, not supported by some hardware and often unsafe/buggy
344 * where supported. The other alternative is to flush the buffers
346 if (drift
> (owner
->sync
.discontinuity
? 0
347 : lroundf(+3 * AOUT_MAX_PTS_DELAY
/ rate
)))
349 if (!owner
->sync
.discontinuity
)
350 msg_Warn (aout
, "playback way too late (%"PRId64
"): "
351 "flushing buffers", drift
);
353 msg_Dbg (aout
, "playback too late (%"PRId64
"): "
354 "flushing buffers", drift
);
356 aout_StopResampling (aout
);
358 return; /* nothing can be done if timing is unknown */
361 /* Early audio output.
362 * This is rare except at startup when the buffers are still empty. */
363 if (drift
< (owner
->sync
.discontinuity
? 0
364 : lroundf(-3 * AOUT_MAX_PTS_ADVANCE
/ rate
)))
366 if (!owner
->sync
.discontinuity
)
367 msg_Warn (aout
, "playback way too early (%"PRId64
"): "
368 "playing silence", drift
);
369 aout_DecSilence (aout
, -drift
, audio_ts
);
371 aout_StopResampling (aout
);
372 owner
->sync
.discontinuity
= true;
376 if (!aout_FiltersCanResample(owner
->filters
))
380 if (drift
> +AOUT_MAX_PTS_DELAY
381 && owner
->sync
.resamp_type
!= AOUT_RESAMPLING_UP
)
383 msg_Warn (aout
, "playback too late (%"PRId64
"): up-sampling",
385 owner
->sync
.resamp_type
= AOUT_RESAMPLING_UP
;
386 owner
->sync
.resamp_start_drift
= +drift
;
388 if (drift
< -AOUT_MAX_PTS_ADVANCE
389 && owner
->sync
.resamp_type
!= AOUT_RESAMPLING_DOWN
)
391 msg_Warn (aout
, "playback too early (%"PRId64
"): down-sampling",
393 owner
->sync
.resamp_type
= AOUT_RESAMPLING_DOWN
;
394 owner
->sync
.resamp_start_drift
= -drift
;
397 if (owner
->sync
.resamp_type
== AOUT_RESAMPLING_NONE
)
398 return; /* Everything is fine. Nothing to do. */
400 if (llabs (drift
) > 2 * owner
->sync
.resamp_start_drift
)
401 { /* If the drift is ever increasing, then something is seriously wrong.
402 * Cease resampling and hope for the best. */
403 msg_Warn (aout
, "timing screwed (drift: %"PRId64
" us): "
404 "stopping resampling", drift
);
405 aout_StopResampling (aout
);
409 /* Resampling has been triggered earlier. This checks if it needs to be
410 * increased or decreased. Resampling rate changes must be kept slow for
411 * the comfort of listeners. */
412 int adj
= (owner
->sync
.resamp_type
== AOUT_RESAMPLING_UP
) ? +2 : -2;
414 if (2 * llabs (drift
) <= owner
->sync
.resamp_start_drift
)
415 /* If the drift has been reduced from more than half its initial
416 * value, then it is time to switch back the resampling direction. */
419 if (!aout_FiltersAdjustResampling (owner
->filters
, adj
))
420 { /* Everything is back to normal: stop resampling. */
421 owner
->sync
.resamp_type
= AOUT_RESAMPLING_NONE
;
422 msg_Dbg (aout
, "resampling stopped (drift: %"PRId64
" us)", drift
);
426 /*****************************************************************************
427 * aout_DecPlay : filter & mix the decoded buffer
428 *****************************************************************************/
429 int aout_DecPlay(audio_output_t
*aout
, block_t
*block
)
431 aout_owner_t
*owner
= aout_owner (aout
);
433 assert (block
->i_pts
!= VLC_TICK_INVALID
);
435 block
->i_length
= vlc_tick_from_samples( block
->i_nb_samples
,
436 owner
->input_format
.i_rate
);
438 int ret
= aout_CheckReady (aout
);
439 if (unlikely(ret
== AOUT_DEC_FAILED
))
440 goto drop
; /* Pipeline is unrecoverably broken :-( */
442 if (block
->i_flags
& BLOCK_FLAG_DISCONTINUITY
)
444 owner
->sync
.discontinuity
= true;
445 owner
->original_pts
= VLC_TICK_INVALID
;
448 if (owner
->original_pts
== VLC_TICK_INVALID
)
450 /* Use the original PTS for synchronization and as a play date of the
451 * aout module. This PTS need to be saved here in order to use the PTS
452 * of the first block that has been filtered. Indeed, aout filters may
453 * need more than one block to output a new one. */
454 owner
->original_pts
= block
->i_pts
;
459 if (atomic_load_explicit(&owner
->vp
.update
, memory_order_relaxed
))
461 vlc_mutex_lock (&owner
->vp
.lock
);
462 aout_FiltersChangeViewpoint (owner
->filters
, &owner
->vp
.value
);
463 atomic_store_explicit(&owner
->vp
.update
, false, memory_order_relaxed
);
464 vlc_mutex_unlock (&owner
->vp
.lock
);
467 block
= aout_FiltersPlay(owner
->filters
, block
, owner
->sync
.rate
);
472 const vlc_tick_t original_pts
= owner
->original_pts
;
473 owner
->original_pts
= VLC_TICK_INVALID
;
475 /* Software volume */
476 aout_volume_Amplify (owner
->volume
, block
);
479 if (owner
->sync
.request_delay
!= owner
->sync
.delay
)
481 owner
->sync
.delay
= owner
->sync
.request_delay
;
482 vlc_tick_t delta
= vlc_clock_SetDelay(owner
->sync
.clock
, owner
->sync
.delay
);
484 aout_FiltersSetClockDelay(owner
->filters
, owner
->sync
.delay
);
486 aout_DecSilence (aout
, delta
, block
->i_pts
);
489 /* Drift correction */
490 vlc_tick_t system_now
= vlc_tick_now();
491 aout_DecSynchronize(aout
, system_now
, original_pts
);
493 vlc_tick_t play_date
=
494 vlc_clock_ConvertToSystem(owner
->sync
.clock
, system_now
, original_pts
,
496 if (unlikely(play_date
== INT64_MAX
))
498 /* The clock is paused but not the output, play the audio anyway since
499 * we can't delay audio playback from here. */
500 play_date
= system_now
;
504 vlc_audio_meter_Process(&owner
->meter
, block
, play_date
);
507 owner
->sync
.discontinuity
= false;
508 aout
->play(aout
, block
, play_date
);
510 atomic_fetch_add_explicit(&owner
->buffers_played
, 1, memory_order_relaxed
);
513 owner
->sync
.discontinuity
= true;
514 owner
->original_pts
= VLC_TICK_INVALID
;
515 block_Release (block
);
516 atomic_fetch_add_explicit(&owner
->buffers_lost
, 1, memory_order_relaxed
);
520 void aout_DecGetResetStats(audio_output_t
*aout
, unsigned *restrict lost
,
521 unsigned *restrict played
)
523 aout_owner_t
*owner
= aout_owner (aout
);
525 *lost
= atomic_exchange_explicit(&owner
->buffers_lost
, 0,
526 memory_order_relaxed
);
527 *played
= atomic_exchange_explicit(&owner
->buffers_played
, 0,
528 memory_order_relaxed
);
531 void aout_DecChangePause (audio_output_t
*aout
, bool paused
, vlc_tick_t date
)
533 aout_owner_t
*owner
= aout_owner (aout
);
535 if (owner
->mixer_format
.i_format
)
537 if (aout
->pause
!= NULL
)
538 aout
->pause(aout
, paused
, date
);
544 void aout_DecChangeRate(audio_output_t
*aout
, float rate
)
546 aout_owner_t
*owner
= aout_owner(aout
);
548 owner
->sync
.rate
= rate
;
551 void aout_DecChangeDelay(audio_output_t
*aout
, vlc_tick_t delay
)
553 aout_owner_t
*owner
= aout_owner(aout
);
555 owner
->sync
.request_delay
= delay
;
558 void aout_DecFlush(audio_output_t
*aout
)
560 aout_owner_t
*owner
= aout_owner (aout
);
562 if (owner
->mixer_format
.i_format
)
564 vlc_audio_meter_Flush(&owner
->meter
);
567 aout_FiltersFlush (owner
->filters
);
570 vlc_clock_Reset(owner
->sync
.clock
);
572 aout_FiltersResetClock(owner
->filters
);
574 if (owner
->sync
.delay
> 0)
576 /* Also reset the delay in case of a positive delay. This will
577 * trigger a silence playback before the next play. Consequently,
578 * the first play date won't be (delay + dejitter) but only
579 * dejitter. This will allow the aout to update the master clock
582 vlc_clock_SetDelay(owner
->sync
.clock
, 0);
584 aout_FiltersSetClockDelay(owner
->filters
, 0);
585 owner
->sync
.request_delay
= owner
->sync
.delay
;
586 owner
->sync
.delay
= 0;
589 owner
->sync
.discontinuity
= true;
590 owner
->original_pts
= VLC_TICK_INVALID
;
593 void aout_DecDrain(audio_output_t
*aout
)
595 aout_owner_t
*owner
= aout_owner (aout
);
597 if (!owner
->mixer_format
.i_format
)
602 block_t
*block
= aout_FiltersDrain (owner
->filters
);
604 aout
->play(aout
, block
, vlc_tick_now());
609 vlc_clock_Reset(owner
->sync
.clock
);
611 aout_FiltersResetClock(owner
->filters
);
613 owner
->sync
.discontinuity
= true;
614 owner
->original_pts
= VLC_TICK_INVALID
;