vlc_aout.h 18.6 KB
Newer Older
1
/*****************************************************************************
2
 * vlc_aout.h : audio output interface
3
 *****************************************************************************
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
4
 * Copyright (C) 2002-2011 VLC authors and VideoLAN
5
 *
6
 * Authors: Christophe Massiot <massiot@via.ecp.fr>
7
 *
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
8 9 10
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or
11
 * (at your option) any later version.
12
 *
13 14
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
15 16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
17
 *
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
18 19 20
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
21
 *****************************************************************************/
22

23 24
#ifndef VLC_AOUT_H
#define VLC_AOUT_H 1
25

26 27
#include <assert.h>

28
/**
29 30 31
 * \defgroup audio_output Audio output
 * \ingroup output
 * @{
32
 * \file
33
 * Audio output modules interface
34 35
 */

36 37
/* Buffers which arrive in advance of more than AOUT_MAX_ADVANCE_TIME
 * will be considered as bogus and be trashed */
38
#define AOUT_MAX_ADVANCE_TIME           (AOUT_MAX_PREPARE_TIME + CLOCK_FREQ)
39 40 41

/* Buffers which arrive in advance of more than AOUT_MAX_PREPARE_TIME
 * will cause the calling thread to sleep */
42
#define AOUT_MAX_PREPARE_TIME           (2 * CLOCK_FREQ)
43 44 45

/* Buffers which arrive after pts - AOUT_MIN_PREPARE_TIME will be trashed
 * to avoid too heavy resampling */
46
#define AOUT_MIN_PREPARE_TIME           AOUT_MAX_PTS_ADVANCE
47

48 49 50 51 52 53 54 55
/* Tolerance values from EBU Recommendation 37 */
/** Maximum advance of actual audio playback time to coded PTS,
 * above which downsampling will be performed */
#define AOUT_MAX_PTS_ADVANCE            (CLOCK_FREQ / 25)

/** Maximum delay of actual audio playback time from coded PTS,
 * above which upsampling will be performed */
#define AOUT_MAX_PTS_DELAY              (3 * CLOCK_FREQ / 50)
56 57 58

/* Max acceptable resampling (in %) */
#define AOUT_MAX_RESAMPLING             10
59

60
#include "vlc_es.h"
Michel Kaempf's avatar
Michel Kaempf committed
61

62
#define AOUT_FMTS_IDENTICAL( p_first, p_second ) (                          \
63
    ((p_first)->i_format == (p_second)->i_format)                           \
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
64
      && AOUT_FMTS_SIMILAR(p_first, p_second) )
65

66 67 68
/* Check if i_rate == i_rate and i_channels == i_channels */
#define AOUT_FMTS_SIMILAR( p_first, p_second ) (                            \
    ((p_first)->i_rate == (p_second)->i_rate)                               \
69
      && ((p_first)->channel_type == (p_second)->channel_type)            \
70
      && ((p_first)->i_physical_channels == (p_second)->i_physical_channels)\
71
      && ((p_first)->i_chan_mode == (p_second)->i_chan_mode) )
72

73 74 75
#define AOUT_FMT_LINEAR( p_format ) \
    (aout_BitsPerSample((p_format)->i_format) != 0)

76 77
#define VLC_CODEC_SPDIFL VLC_FOURCC('s','p','d','i')
#define VLC_CODEC_SPDIFB VLC_FOURCC('s','p','d','b')
78

79
#define AOUT_FMT_SPDIF( p_format ) \
80 81
    ( ((p_format)->i_format == VLC_CODEC_SPDIFL)       \
       || ((p_format)->i_format == VLC_CODEC_SPDIFB)   \
82
       || ((p_format)->i_format == VLC_CODEC_A52)      \
83
       || ((p_format)->i_format == VLC_CODEC_DTS) )
84

85 86
#define AOUT_FMT_HDMI( p_format )                   \
    ( (p_format)->i_format == VLC_CODEC_EAC3        \
87 88
    ||(p_format)->i_format == VLC_CODEC_TRUEHD      \
    ||(p_format)->i_format == VLC_CODEC_MLP         \
89 90
    )

91
/* Values used for the audio-channels object variable */
92
#define AOUT_VAR_CHAN_UNSET         0 /* must be zero */
Gildas Bazin's avatar
Gildas Bazin committed
93 94 95 96 97
#define AOUT_VAR_CHAN_STEREO        1
#define AOUT_VAR_CHAN_RSTEREO       2
#define AOUT_VAR_CHAN_LEFT          3
#define AOUT_VAR_CHAN_RIGHT         4
#define AOUT_VAR_CHAN_DOLBYS        5
98
#define AOUT_VAR_CHAN_HEADPHONES    6
99
#define AOUT_VAR_CHAN_MONO          7
100

101
/*****************************************************************************
102
 * Main audio output structures
103
 *****************************************************************************/
104

Christophe Massiot's avatar
Christophe Massiot committed
105 106
/* Size of a frame for S/PDIF output. */
#define AOUT_SPDIF_SIZE 6144
107

108
/* Number of samples in an A/52 frame. */
109
#define A52_FRAME_NB 1536
110

111
/* FIXME to remove once aout.h is cleaned a bit more */
112
#include <vlc_block.h>
113

114 115 116 117 118 119 120 121 122 123
struct vlc_audio_output_events {
    void (*volume_report)(audio_output_t *, float);
    void (*mute_report)(audio_output_t *, bool);
    void (*policy_report)(audio_output_t *, bool);
    void (*device_report)(audio_output_t *, const char *);
    void (*hotplug_report)(audio_output_t *, const char *, const char *);
    void (*restart_request)(audio_output_t *, unsigned);
    int (*gain_request)(audio_output_t *, float);
};

124 125 126 127 128 129 130 131 132 133 134 135 136
/** Audio output object
 *
 * The audio output object is the abstraction for rendering decoded
 * (or pass-through) audio samples. In addition to playing samples,
 * the abstraction exposes controls for pause/resume, flush/drain,
 * changing the volume or mut flag, and listing and changing output device.
 *
 * An audio output can be in one of three different states:
 * stopped, playing or paused.
 * The audio output is always created in stopped state and is always destroyed
 * in that state also. It is moved from stopped to playing state by start(),
 * and from playing or paused states back to stopped state by stop().
 **/
137
struct audio_output
138
{
139
    struct vlc_common_members obj;
140

141
    void *sys; /**< Private data for callbacks */
142 143 144

    int (*start)(audio_output_t *, audio_sample_format_t *fmt);
    /**< Starts a new stream (mandatory, cannot be NULL).
145 146 147 148 149
      *
      * This callback changes the audio output from stopped to playing state
      * (if succesful). After the callback returns, time_get(), play(),
      * pause(), flush() and eventually stop() callbacks may be called.
      *
150 151 152
      * \param fmt input stream sample format upon entry,
      *            output stream sample format upon return [IN/OUT]
      * \return VLC_SUCCESS on success, non-zero on failure
153 154 155 156 157
      *
      * \note This callback can only be called while the audio output is in
      * stopped state. There can be only one stream per audio output at a time.
      *
      * \note This callbacks needs not be reentrant.
158
      */
159

160 161
    void (*stop)(audio_output_t *);
    /**< Stops the existing stream (optional, may be NULL).
162 163 164 165 166
      *
      * This callback terminates the current audio stream,
      * and returns the audio output to stopped state.
      *
      * \note This callback needs not be reentrant.
167
      */
168

169
    int (*time_get)(audio_output_t *, mtime_t *delay);
170 171 172 173 174 175 176 177 178 179
    /**< Estimates playback buffer latency (mandatory, cannot be NULL).
      *
      * This callback computes an estimation of the delay until the current
      * tail of the audio output buffer would be rendered. This is essential
      * for (lip) synchronization and long term drift between the audio output
      * clock and the media upstream clock (if any).
      *
      * If the audio output clock is exactly synchronized with the system
      * monotonic clock (i.e. mdate()), then aout_TimeGetDefault() can
      * implement this callback.
180
      *
181 182
      * \param delay pointer to the delay until the next sample to be written
      *              to the playback buffer is rendered [OUT]
183
      * \return 0 on success, non-zero on failure or lack of data
184 185
      *
      * \note This callback cannot be called in stopped state.
186
      */
187

188
    void (*play)(audio_output_t *, block_t *block, mtime_t date);
189
    /**< Queues a block of samples for playback (mandatory, cannot be NULL).
190
      *
191 192
      * \param block block of audio samples
      * \param date intended system time to render the first sample
193 194
      *
      * \note This callback cannot be called in stopped state.
195
      */
196

197
    void (*pause)( audio_output_t *, bool pause, mtime_t date);
198 199 200 201 202 203 204 205 206
    /**< Pauses or resumes playback (mandatory, cannot be NULL).
      *
      * This callback pauses or resumes audio playback as quickly as possible.
      * When pausing, it is desirable to stop producing sound immediately, but
      * retain already queued audio samples in the buffer to play when later
      * when resuming.
      *
      * If pausing is impossible, then aout_PauseDefault() can provide a
      * fallback implementation of this callback.
207
      *
208 209
      * \param pause pause if true, resume from pause if false
      * \param date timestamp when the pause or resume was requested
210 211
      *
      * \note This callback cannot be called in stopped state.
212
      */
213

214
    void (*flush)( audio_output_t *, bool wait);
215
    /**< Flushes or drains the playback buffers (mandatory, cannot be NULL).
216
      *
217 218
      * \param wait true to wait for playback of pending buffers (drain),
      *             false to discard pending buffers (flush)
219 220
      *
      * \note This callback cannot be called in stopped state.
221
      */
222

223 224
    int (*volume_set)(audio_output_t *, float volume);
    /**< Changes playback volume (optional, may be NULL).
225
      *
226
      * \param volume requested volume (0. = mute, 1. = nominal)
227
      *
228
      * \note The volume is always a positive number.
229
      *
230
      * \warning A stream may or may not have been started when called.
231 232 233 234
      * \warning This callback may be called concurrently with
      * time_get(), play(), pause() or flush().
      * It will however be protected against concurrent calls to
      * start(), stop(), volume_set(), mute_set() or device_select().
235
      */
236

237 238
    int (*mute_set)(audio_output_t *, bool mute);
    /**< Changes muting (optinal, may be NULL).
239
      *
240
      * \param mute true to mute, false to unmute
241
      * \warning The same constraints apply as with volume_set().
242
      */
243

244 245
    int (*device_select)(audio_output_t *, const char *id);
    /**< Selects an audio output device (optional, may be NULL).
246
      *
247 248
      * \param id nul-terminated device unique identifier.
      * \return 0 on success, non-zero on failure.
249 250
      *
      * \warning The same constraints apply as with volume_set().
251
      */
252 253 254 255 256 257 258

    struct {
        bool headphones; /**< Default to false, set it to true if the current
                              sink is using headphones */
    } current_sink_info;
    /**< Current sink informations set by the module from the start() function */

259
    const struct vlc_audio_output_events *events;
260 261
};

262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290
typedef enum
{
    AOUT_CHANIDX_DISABLE = -1,
    AOUT_CHANIDX_LEFT,
    AOUT_CHANIDX_RIGHT,
    AOUT_CHANIDX_MIDDLELEFT,
    AOUT_CHANIDX_MIDDLERIGHT,
    AOUT_CHANIDX_REARLEFT,
    AOUT_CHANIDX_REARRIGHT,
    AOUT_CHANIDX_REARCENTER,
    AOUT_CHANIDX_CENTER,
    AOUT_CHANIDX_LFE,
    AOUT_CHANIDX_MAX
} vlc_chan_order_idx_t;

static_assert(AOUT_CHANIDX_MAX == AOUT_CHAN_MAX, "channel count mismatch");

#define AOUT_CHAN_REMAP_INIT { \
    AOUT_CHANIDX_LEFT,  \
    AOUT_CHANIDX_RIGHT, \
    AOUT_CHANIDX_MIDDLELEFT, \
    AOUT_CHANIDX_MIDDLERIGHT, \
    AOUT_CHANIDX_REARLEFT, \
    AOUT_CHANIDX_REARRIGHT, \
    AOUT_CHANIDX_REARCENTER, \
    AOUT_CHANIDX_CENTER, \
    AOUT_CHANIDX_LFE, \
}

291
/**
292
 * It describes the audio channel order VLC expect.
293
 */
294
static const uint32_t pi_vlc_chan_order_wg4[] =
295 296 297 298 299 300 301
{
    AOUT_CHAN_LEFT, AOUT_CHAN_RIGHT,
    AOUT_CHAN_MIDDLELEFT, AOUT_CHAN_MIDDLERIGHT,
    AOUT_CHAN_REARLEFT, AOUT_CHAN_REARRIGHT, AOUT_CHAN_REARCENTER,
    AOUT_CHAN_CENTER, AOUT_CHAN_LFE, 0
};

302 303
#define AOUT_RESTART_FILTERS        0x1
#define AOUT_RESTART_OUTPUT         (AOUT_RESTART_FILTERS|0x2)
304
#define AOUT_RESTART_STEREOMODE     (AOUT_RESTART_OUTPUT|0x4)
305

306
/*****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
307
 * Prototypes
308
 *****************************************************************************/
309

310 311 312 313 314 315
/**
 * This function computes the reordering needed to go from pi_chan_order_in to
 * pi_chan_order_out.
 * If pi_chan_order_in or pi_chan_order_out is NULL, it will assume that vlc
 * internal (WG4) order is requested.
 */
316
VLC_API unsigned aout_CheckChannelReorder( const uint32_t *, const uint32_t *,
317
                                           uint32_t mask, uint8_t *table );
318
VLC_API void aout_ChannelReorder(void *, size_t, uint8_t, const uint8_t *, vlc_fourcc_t);
319

320 321 322
VLC_API void aout_Interleave(void *dst, const void *const *planes,
                             unsigned samples, unsigned channels,
                             vlc_fourcc_t fourcc);
323
VLC_API void aout_Deinterleave(void *dst, const void *src, unsigned samples,
324 325
                             unsigned channels, vlc_fourcc_t fourcc);

326
/**
David Fuhrmann's avatar
David Fuhrmann committed
327
 * This function will compute the extraction parameter into pi_selection to go
328 329 330 331 332 333 334 335 336 337 338 339 340 341
 * from i_channels with their type given by pi_order_src[] into the order
 * describe by pi_order_dst.
 * It will also set :
 * - *pi_channels as the number of channels that will be extracted which is
 * lower (in case of non understood channels type) or equal to i_channels.
 * - the layout of the channels (*pi_layout).
 *
 * It will return true if channel extraction is really needed, in which case
 * aout_ChannelExtract must be used
 *
 * XXX It must be used when the source may have channel type not understood
 * by VLC. In this case the channel type pi_order_src[] must be set to 0.
 * XXX It must also be used if multiple channels have the same type.
 */
342
VLC_API bool aout_CheckChannelExtraction( int *pi_selection, uint32_t *pi_layout, int *pi_channels, const uint32_t pi_order_dst[AOUT_CHAN_MAX], const uint32_t *pi_order_src, int i_channels );
343 344 345 346 347 348

/**
 * Do the actual channels extraction using the parameters created by
 * aout_CheckChannelExtraction.
 *
 * XXX this function does not work in place (p_dst and p_src must not overlap).
349
 * XXX Only 8, 16, 32, 64 bits per sample are supported.
350
 */
351
VLC_API void aout_ChannelExtract( void *p_dst, int i_dst_channels, const void *p_src, int i_src_channels, int i_sample_count, const int *pi_selection, int i_bits_per_sample );
352 353

/* */
354 355
static inline unsigned aout_FormatNbChannels(const audio_sample_format_t *fmt)
{
356
    return vlc_popcount(fmt->i_physical_channels);
357 358
}

359
VLC_API unsigned int aout_BitsPerSample( vlc_fourcc_t i_format ) VLC_USED;
360
VLC_API void aout_FormatPrepare( audio_sample_format_t * p_format );
361 362 363
VLC_API void aout_FormatPrint(vlc_object_t *, const char *,
                              const audio_sample_format_t *);
#define aout_FormatPrint(o, t, f) aout_FormatPrint(VLC_OBJECT(o), t, f)
364
VLC_API const char * aout_FormatPrintChannels( const audio_sample_format_t * ) VLC_USED;
365

366 367 368
#define AOUT_VOLUME_DEFAULT             256
#define AOUT_VOLUME_MAX                 512

369 370
VLC_API float aout_VolumeGet (audio_output_t *);
VLC_API int aout_VolumeSet (audio_output_t *, float);
371
VLC_API int aout_VolumeUpdate (audio_output_t *, int, float *);
372 373
VLC_API int aout_MuteGet (audio_output_t *);
VLC_API int aout_MuteSet (audio_output_t *, bool);
374 375 376
VLC_API char *aout_DeviceGet (audio_output_t *);
VLC_API int aout_DeviceSet (audio_output_t *, const char *);
VLC_API int aout_DevicesList (audio_output_t *, char ***, char ***);
377

378 379 380
/**
 * Report change of configured audio volume to the core and UI.
 */
381 382
static inline void aout_VolumeReport(audio_output_t *aout, float volume)
{
383
    aout->events->volume_report(aout, volume);
384 385
}

386 387 388
/**
 * Report change of muted flag to the core and UI.
 */
389
static inline void aout_MuteReport(audio_output_t *aout, bool mute)
390
{
391
    aout->events->mute_report(aout, mute);
392 393
}

394 395
/**
 * Report audio policy status.
396
 * \param cork true to request a cork, false to undo any pending cork.
397
 */
398 399
static inline void aout_PolicyReport(audio_output_t *aout, bool cork)
{
400
    aout->events->policy_report(aout, cork);
401 402
}

403 404 405 406 407
/**
 * Report change of output device.
 */
static inline void aout_DeviceReport(audio_output_t *aout, const char *id)
{
408
    aout->events->device_report(aout, id);
409 410
}

411 412 413 414 415 416 417 418
/**
 * Report a device hot-plug event.
 * @param id device ID
 * @param name human-readable device name (NULL for hot unplug)
 */
static inline void aout_HotplugReport(audio_output_t *aout,
                                      const char *id, const char *name)
{
419
    aout->events->hotplug_report(aout, id, name);
420 421
}

422 423 424 425 426
/**
 * Request a change of software audio amplification.
 * \param gain linear amplitude gain (must be positive)
 * \warning Values in excess 1.0 may cause overflow and distorsion.
 */
427
static inline int aout_GainRequest(audio_output_t *aout, float gain)
428
{
429
    return aout->events->gain_request(aout, gain);
430
}
431

432 433
static inline void aout_RestartRequest(audio_output_t *aout, unsigned mode)
{
434
    aout->events->restart_request(aout, mode);
435 436
}

437 438 439 440 441 442 443 444 445 446
/**
 * Default implementation for audio_output_t.time_get
 */
static inline int aout_TimeGetDefault(audio_output_t *aout,
                                      mtime_t *restrict delay)
{
    (void) aout; (void) delay;
    return -1;
}

447 448 449 450 451 452 453 454 455 456 457 458 459 460 461
/**
 * Default implementation for audio_output_t.pause
 *
 * \warning This default callback implementation is suboptimal as it will
 * discard some audio samples.
 * Do not use this unless there are really no possible better alternatives.
 */
static inline void aout_PauseDefault(audio_output_t *aout, bool paused,
                                     mtime_t date)
{
    if (paused && aout->flush != NULL)
        aout->flush(aout, false);
    (void) date;
}

462
/* Audio output filters */
463 464 465 466 467 468 469 470

typedef struct
{
    /**
     * If the remap order differs from the WG4 order, a remap audio filter will
     * be inserted to remap channels according to this array.
     */
    int remap[AOUT_CHANIDX_MAX];
471 472 473 474 475
    /**
     * If true, a filter will be inserted to add a headphones effect (like a
     * binauralizer audio filter).
     */
    bool headphones;
476 477 478 479
} aout_filters_cfg_t;

#define AOUT_FILTERS_CFG_INIT (aout_filters_cfg_t) \
    { .remap = AOUT_CHAN_REMAP_INIT, \
480
      .headphones = false, \
481 482
    };

483 484 485 486 487 488
typedef struct aout_filters aout_filters_t;
typedef struct aout_request_vout aout_request_vout_t;

VLC_API aout_filters_t *aout_FiltersNew(vlc_object_t *,
                                        const audio_sample_format_t *,
                                        const audio_sample_format_t *,
489
                                        const aout_request_vout_t *,
490
                                        const aout_filters_cfg_t *cfg) VLC_USED;
491 492
#define aout_FiltersNew(o,inf,outf,rv,remap) \
        aout_FiltersNew(VLC_OBJECT(o),inf,outf,rv,remap)
493 494 495 496
VLC_API void aout_FiltersDelete(vlc_object_t *, aout_filters_t *);
#define aout_FiltersDelete(o,f) \
        aout_FiltersDelete(VLC_OBJECT(o),f)
VLC_API bool aout_FiltersAdjustResampling(aout_filters_t *, int);
497
VLC_API block_t *aout_FiltersPlay(aout_filters_t *, block_t *, float rate);
498 499
VLC_API block_t *aout_FiltersDrain(aout_filters_t *);
VLC_API void     aout_FiltersFlush(aout_filters_t *);
500
VLC_API void     aout_FiltersChangeViewpoint(aout_filters_t *, const vlc_viewpoint_t *vp);
Clément Stenac's avatar
Clément Stenac committed
501

502
VLC_API vout_thread_t * aout_filter_RequestVout( filter_t *, vout_thread_t *p_vout, const video_format_t *p_fmt );
503

504 505
/** @} */

506
#endif /* VLC_AOUT_H */