aout_internal.h 8.1 KB
Newer Older
Clément Stenac's avatar
Clément Stenac committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
/*****************************************************************************
 * aout_internal.h : internal defines for audio output
 *****************************************************************************
 * Copyright (C) 2002 the VideoLAN team
 * $Id$
 *
 * Authors: Christophe Massiot <massiot@via.ecp.fr>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU 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.
 *****************************************************************************/

24 25
#ifndef LIBVLC_AOUT_INTERNAL_H
# define LIBVLC_AOUT_INTERNAL_H 1
26

27 28 29 30 31 32 33 34 35
/* Max input rate factor (1/4 -> 4) */
# define AOUT_MAX_INPUT_RATE (4)

enum {
    AOUT_RESAMPLING_NONE=0,
    AOUT_RESAMPLING_UP,
    AOUT_RESAMPLING_DOWN
};

36 37 38 39 40 41 42
typedef struct
{
    struct vout_thread_t  *(*pf_request_vout)( void *, struct vout_thread_t *,
                                               video_format_t *, bool );
    void *p_private;
} aout_request_vout_t;

43
struct filter_owner_sys_t
44
{
45
    audio_output_t *p_aout;
46 47 48
    aout_input_t    *p_input;
};

49 50 51
/** an input stream for the audio output */
struct aout_input_t
{
52
    unsigned            samplerate; /**< Input sample rate */
53 54

    /* pre-filters */
55
    filter_t *              pp_filters[AOUT_MAX_FILTERS];
56 57
    int                     i_nb_filters;

58
    filter_t *              p_playback_rate_filter;
59 60

    /* resamplers */
61
    filter_t *              pp_resamplers[AOUT_MAX_FILTERS];
62 63 64 65 66 67 68 69 70 71 72 73 74 75
    int                     i_nb_resamplers;
    int                     i_resampling_type;
    mtime_t                 i_resamp_start_date;
    int                     i_resamp_start_drift;

    /* last rate from input */
    int               i_last_input_rate;

    /* */
    int               i_buffer_lost;

    /* */
    bool                b_recycle_vout;
    aout_request_vout_t request_vout;
76 77 78 79
};

typedef struct
{
80
    vlc_mutex_t lock;
81 82 83
    module_t *module; /**< Output plugin (or NULL if inactive) */
    aout_input_t *input;

84 85 86 87 88
    struct
    {
        date_t date;
    } sync;

89 90 91 92 93
    struct
    {
        vlc_mutex_t lock;
        float multiplier; /**< Software volume amplification multiplier */
        struct audio_mixer *mixer; /**< Software volume plugin */
94 95 96 97 98 99 100
    } volume;

    struct
    {
        vlc_atomic_t multiplier;
        audio_replay_gain_t data;
    } gain;
101 102

    audio_sample_format_t mixer_format;
103
    audio_sample_format_t input_format;
104 105 106 107

    /* Filters between mixer and output */
    filter_t *filters[AOUT_MAX_FILTERS];
    int       nb_filters;
108

109
    vlc_atomic_t restart;
110 111 112 113 114 115 116 117 118 119 120 121
} aout_owner_t;

typedef struct
{
    audio_output_t output;
    aout_owner_t   owner;
} aout_instance_t;

static inline aout_owner_t *aout_owner (audio_output_t *aout)
{
    return &((aout_instance_t *)aout)->owner;
}
122

Clément Stenac's avatar
Clément Stenac committed
123 124 125
/****************************************************************************
 * Prototypes
 *****************************************************************************/
126

Clément Stenac's avatar
Clément Stenac committed
127
/* From input.c : */
128 129 130
aout_input_t *aout_InputNew(audio_output_t *, const audio_sample_format_t *,
                            const audio_sample_format_t *,
                            const aout_request_vout_t *);
131
int aout_InputDelete( audio_output_t * p_aout, aout_input_t * p_input );
132
block_t *aout_InputPlay( audio_output_t *p_aout, aout_input_t *p_input,
133
                         block_t *p_buffer, int i_input_rate, date_t * );
Clément Stenac's avatar
Clément Stenac committed
134 135

/* From filters.c : */
136
int aout_FiltersCreatePipeline( vlc_object_t *, filter_t **, int *,
137
    const audio_sample_format_t *, const audio_sample_format_t * );
138 139
#define aout_FiltersCreatePipeline(o, pv, pc, inf, outf) \
        aout_FiltersCreatePipeline(VLC_OBJECT(o), pv, pc, inf, outf)
140 141
void aout_FiltersDestroyPipeline( filter_t *const *, unsigned );
void aout_FiltersPlay( filter_t *const *, unsigned, aout_buffer_t ** );
Clément Stenac's avatar
Clément Stenac committed
142 143

/* From mixer.c : */
144
struct audio_mixer *aout_MixerNew(vlc_object_t *, vlc_fourcc_t);
145
#define aout_MixerNew(o, f) aout_MixerNew(VLC_OBJECT(o), f)
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
146 147
void aout_MixerDelete(struct audio_mixer *);
void aout_MixerRun(struct audio_mixer *, block_t *, float);
148 149 150 151 152 153 154 155 156 157 158 159 160 161
float aout_ReplayGainSelect(vlc_object_t *, const char *,
                            const audio_replay_gain_t *);
#define aout_ReplayGainSelect(o, s, g) \
        aout_ReplayGainSelect(VLC_OBJECT(o), s, g)

static inline void aout_ReplayGainInit(audio_replay_gain_t *restrict d,
                                       const audio_replay_gain_t *restrict s)
{
    if (s != NULL)
        *d = *s;
    else
        memset (d, 0, sizeof (*d));
}

162

Clément Stenac's avatar
Clément Stenac committed
163
/* From output.c : */
164
int aout_OutputNew( audio_output_t * p_aout,
165
                    const audio_sample_format_t * p_format );
166 167
void aout_OutputPlay( audio_output_t * p_aout, aout_buffer_t * p_buffer );
void aout_OutputPause( audio_output_t * p_aout, bool, mtime_t );
168
void aout_OutputFlush( audio_output_t * p_aout, bool );
169
void aout_OutputDelete( audio_output_t * p_aout );
Clément Stenac's avatar
Clément Stenac committed
170 171 172


/* From common.c : */
173
audio_output_t *aout_New (vlc_object_t *);
174
#define aout_New(a) aout_New(VLC_OBJECT(a))
175
void aout_Destroy (audio_output_t *);
Clément Stenac's avatar
Clément Stenac committed
176

177
void aout_FifoInit( vlc_object_t *, aout_fifo_t *, uint32_t );
178
mtime_t aout_FifoFirstDate( const aout_fifo_t * ) VLC_USED;
179
#define aout_FifoInit(o, f, r) aout_FifoInit(VLC_OBJECT(o), f, r)
180 181
void aout_FifoPush( aout_fifo_t *, aout_buffer_t * );
aout_buffer_t *aout_FifoPop( aout_fifo_t * p_fifo ) VLC_USED;
182
void aout_FifoReset( aout_fifo_t * );
183 184
void aout_FifoMoveDates( aout_fifo_t *, mtime_t );
void aout_FifoDestroy( aout_fifo_t * p_fifo );
185 186 187 188 189
void aout_FormatsPrint(vlc_object_t *, const char *,
                       const audio_sample_format_t *,
                       const audio_sample_format_t *);
#define aout_FormatsPrint(o, t, a, b) \
        aout_FormatsPrint(VLC_OBJECT(o), t, a, b)
190 191
bool aout_ChangeFilterString( vlc_object_t *manager, vlc_object_t *aout,
                              const char *var, const char *name, bool b_add );
Clément Stenac's avatar
Clément Stenac committed
192 193

/* From dec.c */
194 195 196 197 198 199 200 201 202 203
int aout_DecNew(audio_output_t *, const audio_sample_format_t *,
                const audio_replay_gain_t *, const aout_request_vout_t *);
void aout_DecDelete(audio_output_t *);
block_t *aout_DecNewBuffer(audio_output_t *, size_t);
void aout_DecDeleteBuffer(audio_output_t *, block_t *);
int aout_DecPlay(audio_output_t *, block_t *, int i_input_rate);
int aout_DecGetResetLost(audio_output_t *);
void aout_DecChangePause(audio_output_t *, bool b_paused, mtime_t i_date);
void aout_DecFlush(audio_output_t *);
bool aout_DecIsEmpty(audio_output_t *);
Clément Stenac's avatar
Clément Stenac committed
204

205 206
void aout_InputRequestRestart(audio_output_t *);
void aout_RequestRestart(audio_output_t *);
207
void aout_Shutdown (audio_output_t *);
208

209 210 211 212 213 214 215 216 217 218
/* Audio output locking */

#if !defined (NDEBUG) \
 && defined __linux__ && (defined (__i386__) || defined (__x86_64__))
# define AOUT_DEBUG 1
#endif

#ifdef AOUT_DEBUG
enum
{
219 220
    OUTPUT_LOCK=1,
    VOLUME_LOCK=2,
221 222
};

223 224
void aout_lock_check (unsigned);
void aout_unlock_check (unsigned);
225 226

#else
227 228
# define aout_lock_check( i )   (void)0
# define aout_unlock_check( i ) (void)0
229
#endif
230

231
static inline void aout_lock( audio_output_t *p_aout )
232
{
233
    aout_lock_check( OUTPUT_LOCK );
234
    vlc_mutex_lock( &aout_owner(p_aout)->lock );
235 236
}

237
static inline void aout_unlock( audio_output_t *p_aout )
238
{
239
    aout_unlock_check( OUTPUT_LOCK );
240
    vlc_mutex_unlock( &aout_owner(p_aout)->lock );
241 242
}

243
static inline void aout_lock_volume( audio_output_t *p_aout )
244
{
245
    aout_lock_check( VOLUME_LOCK );
246
    vlc_mutex_lock( &aout_owner(p_aout)->volume.lock );
247 248
}

249
static inline void aout_unlock_volume( audio_output_t *p_aout )
250
{
251
    aout_unlock_check( VOLUME_LOCK );
252
    vlc_mutex_unlock( &aout_owner(p_aout)->volume.lock );
253
}
254

255 256 257
#define aout_assert_locked( aout ) \
        vlc_assert_locked( &aout_owner(aout)->lock )

258
#endif /* !LIBVLC_AOUT_INTERNAL_H */