X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Faudio_output%2Faout_internal.h;h=f8ebd79ae2a767c2be53909466ec39e96773f0b7;hb=c48875b31615603d9d2daaa1a1daf161a83e1f2a;hp=968805e7c14f0911e2d848077b54045c316a1b53;hpb=13700a227ef6c45cd19d6c9b068726a41b03f285;p=vlc diff --git a/src/audio_output/aout_internal.h b/src/audio_output/aout_internal.h index 968805e7c1..f8ebd79ae2 100644 --- a/src/audio_output/aout_internal.h +++ b/src/audio_output/aout_internal.h @@ -24,10 +24,14 @@ #ifndef LIBVLC_AOUT_INTERNAL_H # define LIBVLC_AOUT_INTERNAL_H 1 -# include +/* Max input rate factor (1/4 -> 4) */ +# define AOUT_MAX_INPUT_RATE (4) -aout_buffer_t *aout_BufferAlloc(aout_alloc_t *allocation, mtime_t microseconds, - aout_buffer_t *old_buffer); +enum { + AOUT_RESAMPLING_NONE=0, + AOUT_RESAMPLING_UP, + AOUT_RESAMPLING_DOWN +}; typedef struct { @@ -38,20 +42,14 @@ typedef struct struct filter_owner_sys_t { - aout_instance_t *p_aout; + audio_output_t *p_aout; aout_input_t *p_input; }; -block_t *aout_FilterBufferNew( filter_t *, int ); - /** an input stream for the audio output */ struct aout_input_t { - /* When this lock is taken, the pipeline cannot be changed by a - * third-party. */ - vlc_mutex_t lock; - - audio_sample_format_t input; + unsigned samplerate; /**< Input sample rate */ /* pre-filters */ filter_t * pp_filters[AOUT_MAX_FILTERS]; @@ -66,88 +64,147 @@ struct aout_input_t mtime_t i_resamp_start_date; int i_resamp_start_drift; - /* Mixer information */ - audio_replay_gain_t replay_gain; - - /* If b_restart == 1, the input pipeline will be re-created. */ - bool b_restart; - - /* If b_error == 1, there is no input pipeline. */ - bool b_error; - /* last rate from input */ int i_last_input_rate; /* */ int i_buffer_lost; - /* */ - bool b_paused; - mtime_t i_pause_date; - /* */ bool b_recycle_vout; aout_request_vout_t request_vout; +}; - /* */ - aout_mixer_input_t mixer; - }; +typedef struct +{ + vlc_mutex_t lock; + module_t *module; /**< Output plugin (or NULL if inactive) */ + aout_input_t *input; + + struct + { + date_t date; + } sync; + + struct + { + vlc_mutex_t lock; + float multiplier; /**< Software volume amplification multiplier */ + struct audio_mixer *mixer; /**< Software volume plugin */ + } volume; + + struct + { + vlc_atomic_t multiplier; + audio_replay_gain_t data; + } gain; + + audio_sample_format_t mixer_format; + audio_sample_format_t input_format; + + /* Filters between mixer and output */ + filter_t *filters[AOUT_MAX_FILTERS]; + int nb_filters; + + vlc_atomic_t restart; +} 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; +} /**************************************************************************** * Prototypes *****************************************************************************/ /* From input.c : */ -int aout_InputNew( aout_instance_t * p_aout, aout_input_t * p_input, const aout_request_vout_t * ); -int aout_InputDelete( aout_instance_t * p_aout, aout_input_t * p_input ); -int aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input, - aout_buffer_t * p_buffer, int i_input_rate ); -void aout_InputCheckAndRestart( aout_instance_t * p_aout, aout_input_t * p_input ); -bool aout_InputIsEmpty( aout_instance_t * p_aout, aout_input_t * p_input ); +aout_input_t *aout_InputNew(audio_output_t *, const audio_sample_format_t *, + const audio_sample_format_t *, + const aout_request_vout_t *); +int aout_InputDelete( audio_output_t * p_aout, aout_input_t * p_input ); +block_t *aout_InputPlay( audio_output_t *p_aout, aout_input_t *p_input, + block_t *p_buffer, int i_input_rate, date_t * ); /* From filters.c : */ -int aout_FiltersCreatePipeline ( aout_instance_t * p_aout, filter_t ** pp_filters, int * pi_nb_filters, const audio_sample_format_t * p_input_format, const audio_sample_format_t * p_output_format ); -void aout_FiltersDestroyPipeline ( aout_instance_t * p_aout, filter_t ** pp_filters, int i_nb_filters ); -void aout_FiltersPlay ( filter_t ** pp_filters, unsigned i_nb_filters, aout_buffer_t ** pp_input_buffer ); -void aout_FiltersHintBuffers( aout_instance_t * p_aout, filter_t ** pp_filters, int i_nb_filters, aout_alloc_t * p_first_alloc ); +int aout_FiltersCreatePipeline( vlc_object_t *, filter_t **, int *, + const audio_sample_format_t *, const audio_sample_format_t * ); +#define aout_FiltersCreatePipeline(o, pv, pc, inf, outf) \ + aout_FiltersCreatePipeline(VLC_OBJECT(o), pv, pc, inf, outf) +void aout_FiltersDestroyPipeline( filter_t *const *, unsigned ); +void aout_FiltersPlay( filter_t *const *, unsigned, aout_buffer_t ** ); /* From mixer.c : */ -int aout_MixerNew( aout_instance_t * p_aout ); -void aout_MixerDelete( aout_instance_t * p_aout ); -void aout_MixerRun( aout_instance_t * p_aout ); -int aout_MixerMultiplierSet( aout_instance_t * p_aout, float f_multiplier ); +struct audio_mixer *aout_MixerNew(vlc_object_t *, vlc_fourcc_t); +#define aout_MixerNew(o, f) aout_MixerNew(VLC_OBJECT(o), f) +void aout_MixerDelete(struct audio_mixer *); +void aout_MixerRun(struct audio_mixer *, block_t *, float); +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)); +} + /* From output.c : */ -int aout_OutputNew( aout_instance_t * p_aout, - audio_sample_format_t * p_format ); -void aout_OutputPlay( aout_instance_t * p_aout, aout_buffer_t * p_buffer ); -void aout_OutputDelete( aout_instance_t * p_aout ); +int aout_OutputNew( audio_output_t * p_aout, + const audio_sample_format_t * p_format ); +void aout_OutputPlay( audio_output_t * p_aout, aout_buffer_t * p_buffer ); +void aout_OutputPause( audio_output_t * p_aout, bool, mtime_t ); +void aout_OutputFlush( audio_output_t * p_aout, bool ); +void aout_OutputDelete( audio_output_t * p_aout ); /* From common.c : */ -#define aout_New(a) __aout_New(VLC_OBJECT(a)) -/* Release with vlc_object_release() */ -aout_instance_t * __aout_New ( vlc_object_t * ); - -void aout_FifoInit( aout_instance_t *, aout_fifo_t *, uint32_t ); -mtime_t aout_FifoNextStart( aout_instance_t *, aout_fifo_t * ); -void aout_FifoPush( aout_instance_t *, aout_fifo_t *, aout_buffer_t * ); -void aout_FifoSet( aout_instance_t *, aout_fifo_t *, mtime_t ); -void aout_FifoMoveDates( aout_instance_t *, aout_fifo_t *, mtime_t ); -void aout_FifoDestroy( aout_instance_t * p_aout, aout_fifo_t * p_fifo ); -void aout_FormatsPrint( aout_instance_t * p_aout, const char * psz_text, const audio_sample_format_t * p_format1, const audio_sample_format_t * p_format2 ); -bool aout_ChangeFilterString( vlc_object_t *, aout_instance_t *, const char *psz_variable, const char *psz_name, bool b_add ); +audio_output_t *aout_New (vlc_object_t *); +#define aout_New(a) aout_New(VLC_OBJECT(a)) +void aout_Destroy (audio_output_t *); + +void aout_FifoInit( vlc_object_t *, aout_fifo_t *, uint32_t ); +mtime_t aout_FifoFirstDate( const aout_fifo_t * ) VLC_USED; +#define aout_FifoInit(o, f, r) aout_FifoInit(VLC_OBJECT(o), f, r) +void aout_FifoPush( aout_fifo_t *, aout_buffer_t * ); +aout_buffer_t *aout_FifoPop( aout_fifo_t * p_fifo ) VLC_USED; +void aout_FifoReset( aout_fifo_t * ); +void aout_FifoMoveDates( aout_fifo_t *, mtime_t ); +void aout_FifoDestroy( aout_fifo_t * p_fifo ); +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) +bool aout_ChangeFilterString( vlc_object_t *manager, vlc_object_t *aout, + const char *var, const char *name, bool b_add ); /* From dec.c */ -aout_input_t *aout_DecNew( aout_instance_t *, audio_sample_format_t *, - const audio_replay_gain_t *, const aout_request_vout_t * ); -int aout_DecDelete ( aout_instance_t *, aout_input_t * ); -aout_buffer_t * aout_DecNewBuffer( aout_input_t *, size_t ); -void aout_DecDeleteBuffer( aout_instance_t *, aout_input_t *, aout_buffer_t * ); -int aout_DecPlay( aout_instance_t *, aout_input_t *, aout_buffer_t *, int i_input_rate ); -int aout_DecGetResetLost( aout_instance_t *, aout_input_t * ); -void aout_DecChangePause( aout_instance_t *, aout_input_t *, bool b_paused, mtime_t i_date ); -void aout_DecFlush( aout_instance_t *, aout_input_t * ); +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 *); + +void aout_InputRequestRestart(audio_output_t *); +void aout_RequestRestart(audio_output_t *); +void aout_Shutdown (audio_output_t *); /* Audio output locking */ @@ -159,95 +216,43 @@ void aout_DecFlush( aout_instance_t *, aout_input_t * ); #ifdef AOUT_DEBUG enum { - MIXER_LOCK=1, - INPUT_LOCK=2, - INPUT_FIFO_LOCK=4, - OUTPUT_FIFO_LOCK=8, - VOLUME_VARS_LOCK=16 + OUTPUT_LOCK=1, + VOLUME_LOCK=2, }; -void aout_lock (unsigned); -void aout_unlock (unsigned); +void aout_lock_check (unsigned); +void aout_unlock_check (unsigned); #else -# define aout_lock( i ) (void)0 -# define aout_unlock( i ) (void)0 +# define aout_lock_check( i ) (void)0 +# define aout_unlock_check( i ) (void)0 #endif -static inline void aout_lock_mixer( aout_instance_t *p_aout ) +static inline void aout_lock( audio_output_t *p_aout ) { - aout_lock( MIXER_LOCK ); - vlc_mutex_lock( &p_aout->mixer_lock ); + aout_lock_check( OUTPUT_LOCK ); + vlc_mutex_lock( &aout_owner(p_aout)->lock ); } -static inline void aout_unlock_mixer( aout_instance_t *p_aout ) +static inline void aout_unlock( audio_output_t *p_aout ) { - aout_unlock( MIXER_LOCK ); - vlc_mutex_unlock( &p_aout->mixer_lock ); + aout_unlock_check( OUTPUT_LOCK ); + vlc_mutex_unlock( &aout_owner(p_aout)->lock ); } -static inline void aout_lock_input_fifos( aout_instance_t *p_aout ) +static inline void aout_lock_volume( audio_output_t *p_aout ) { - aout_lock( INPUT_FIFO_LOCK ); - vlc_mutex_lock( &p_aout->input_fifos_lock ); + aout_lock_check( VOLUME_LOCK ); + vlc_mutex_lock( &aout_owner(p_aout)->volume.lock ); } -static inline void aout_unlock_input_fifos( aout_instance_t *p_aout ) +static inline void aout_unlock_volume( audio_output_t *p_aout ) { - aout_unlock( INPUT_FIFO_LOCK ); - vlc_mutex_unlock( &p_aout->input_fifos_lock ); + aout_unlock_check( VOLUME_LOCK ); + vlc_mutex_unlock( &aout_owner(p_aout)->volume.lock ); } -static inline void aout_lock_output_fifo( aout_instance_t *p_aout ) -{ - aout_lock( OUTPUT_FIFO_LOCK ); - vlc_mutex_lock( &p_aout->output_fifo_lock ); -} - -static inline void aout_unlock_output_fifo( aout_instance_t *p_aout ) -{ - aout_unlock( OUTPUT_FIFO_LOCK ); - vlc_mutex_unlock( &p_aout->output_fifo_lock ); -} - -static inline void aout_lock_input( aout_instance_t *p_aout, aout_input_t * p_input ) -{ - (void)p_aout; - aout_lock( INPUT_LOCK ); - vlc_mutex_lock( &p_input->lock ); -} - -static inline void aout_unlock_input( aout_instance_t *p_aout, aout_input_t * p_input ) -{ - (void)p_aout; - aout_unlock( INPUT_LOCK ); - vlc_mutex_unlock( &p_input->lock ); -} - -static inline void aout_lock_volume( aout_instance_t *p_aout ) -{ - aout_lock( VOLUME_VARS_LOCK ); - vlc_mutex_lock( &p_aout->volume_vars_lock ); -} - -static inline void aout_unlock_volume( aout_instance_t *p_aout ) -{ - aout_unlock( VOLUME_VARS_LOCK ); - vlc_mutex_unlock( &p_aout->volume_vars_lock ); -} - -/* Helpers */ - -/** - * This function will safely mark aout input to be restarted as soon as - * possible to take configuration changes into account */ -static inline void AoutInputsMarkToRestart( aout_instance_t *p_aout ) -{ - int i; - aout_lock_mixer( p_aout ); - for( i = 0; i < p_aout->i_nb_inputs; i++ ) - p_aout->pp_inputs[i]->b_restart = true; - aout_unlock_mixer( p_aout ); -} +#define aout_assert_locked( aout ) \ + vlc_assert_locked( &aout_owner(aout)->lock ) #endif /* !LIBVLC_AOUT_INTERNAL_H */