X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Faudio_output%2Foutput.c;h=7fdb531f6afc5463f32db74945e8fca573e6d696;hb=87908cfda5514937773e9fe18dd82ead0499f9da;hp=44c818cbce06b6adfbaaa95990b82d86f3ece8d1;hpb=cfca8bcd6d718662c18d6ccb8a44d6b90305b997;p=vlc diff --git a/src/audio_output/output.c b/src/audio_output/output.c index 44c818cbce..7fdb531f6a 100644 --- a/src/audio_output/output.c +++ b/src/audio_output/output.c @@ -28,6 +28,8 @@ # include "config.h" #endif +#include + #include #include #include @@ -48,7 +50,7 @@ int aout_OutputNew( audio_output_t *p_aout, { aout_owner_t *owner = aout_owner (p_aout); - vlc_assert_locked( &p_aout->lock ); + aout_assert_locked( p_aout ); p_aout->format = *p_format; /* Retrieve user defaults. */ @@ -161,9 +163,6 @@ int aout_OutputNew( audio_output_t *p_aout, aout_FormatPrepare( &p_aout->format ); aout_FormatPrint( p_aout, "output", &p_aout->format ); - /* Prepare FIFO. */ - aout_PacketInit (p_aout, &owner->packet, p_aout->i_nb_samples); - /* Choose the mixer format. */ owner->mixer_format = p_aout->format; if (AOUT_FMT_NON_LINEAR(&p_aout->format)) @@ -209,7 +208,7 @@ void aout_OutputDelete( audio_output_t * p_aout ) { aout_owner_t *owner = aout_owner (p_aout); - vlc_assert_locked( &p_aout->lock ); + aout_assert_locked( p_aout ); if (owner->module == NULL) return; @@ -218,7 +217,6 @@ void aout_OutputDelete( audio_output_t * p_aout ) aout_VolumeNoneInit( p_aout ); /* clear volume callback */ owner->module = NULL; aout_FiltersDestroyPipeline (owner->filters, owner->nb_filters); - aout_PacketDestroy (p_aout); } /***************************************************************************** @@ -230,7 +228,7 @@ void aout_OutputPlay (audio_output_t *aout, block_t *block) { aout_owner_t *owner = aout_owner (aout); - vlc_assert_locked (&aout->lock); + aout_assert_locked (aout); aout_FiltersPlay (owner->filters, owner->nb_filters, &block); if (block == NULL) @@ -251,7 +249,7 @@ void aout_OutputPlay (audio_output_t *aout, block_t *block) */ void aout_OutputPause( audio_output_t *aout, bool pause, mtime_t date ) { - vlc_assert_locked( &aout->lock ); + aout_assert_locked( aout ); if( aout->pf_pause != NULL ) aout->pf_pause( aout, pause, date ); } @@ -264,7 +262,7 @@ void aout_OutputPause( audio_output_t *aout, bool pause, mtime_t date ) */ void aout_OutputFlush( audio_output_t *aout, bool wait ) { - vlc_assert_locked( &aout->lock ); + aout_assert_locked( aout ); if( aout->pf_flush != NULL ) aout->pf_flush( aout, wait ); @@ -291,8 +289,10 @@ void aout_VolumeNoneInit (audio_output_t *aout) { /* aout_New() -safely- calls this function without the lock, before any * other thread knows of this audio output instance. - vlc_assert_locked (&aout->lock); */ + aout_assert_locked (aout); */ aout->pf_volume_set = aout_VolumeNoneSet; + var_Destroy (aout, "volume"); + var_Destroy (aout, "mute"); } /** @@ -302,7 +302,7 @@ static int aout_VolumeSoftSet (audio_output_t *aout, float volume, bool mute) { aout_owner_t *owner = aout_owner (aout); - vlc_assert_locked (&aout->lock); + aout_assert_locked (aout); /* Cubic mapping from software volume to amplification factor. * This provides a good tradeoff between low and high volume ranges. @@ -330,7 +330,7 @@ void aout_VolumeSoftInit (audio_output_t *aout) audio_volume_t volume = var_InheritInteger (aout, "volume"); bool mute = var_InheritBool (aout, "mute"); - vlc_assert_locked (&aout->lock); + aout_assert_locked (aout); aout->pf_volume_set = aout_VolumeSoftSet; aout_VolumeSoftSet (aout, volume / (float)AOUT_VOLUME_DEFAULT, mute); } @@ -342,8 +342,10 @@ void aout_VolumeSoftInit (audio_output_t *aout) */ void aout_VolumeHardInit (audio_output_t *aout, aout_volume_cb setter) { - vlc_assert_locked (&aout->lock); + aout_assert_locked (aout); aout->pf_volume_set = setter; + var_Create (aout, "volume", VLC_VAR_INTEGER|VLC_VAR_DOINHERIT); + var_Create (aout, "mute", VLC_VAR_BOOL|VLC_VAR_DOINHERIT); } /** @@ -352,17 +354,21 @@ void aout_VolumeHardInit (audio_output_t *aout, aout_volume_cb setter) * @param setter volume setter callback * @param volume current custom volume * @param mute current mute flag - * @note Audio output plugins that cannot apply the volume - * should call this function during activation. + * + * @warning The caller (i.e. the audio output plug-in) is responsible for + * interlocking and synchronizing call to this function and to the + * audio_output_t.pf_volume_set callback. This ensures that VLC gets correct + * volume information (possibly with a latency). */ void aout_VolumeHardSet (audio_output_t *aout, float volume, bool mute) { -#warning FIXME - /* REVISIT: This is tricky. We cannot acquire the volume lock as this gets - * called from the audio output (it would cause a lock inversion). - * We also should not override the input manager volume, but only the - * volume of the current audio output... FIXME */ - msg_Err (aout, "%s(%f, %u)", __func__, volume, (unsigned)mute); + audio_volume_t vol = lroundf (volume * (float)AOUT_VOLUME_DEFAULT); + + /* We cannot acquire the volume lock as this gets called from the audio + * output plug-in (it would cause a lock inversion). */ + var_SetInteger (aout, "volume", vol); + var_SetBool (aout, "mute", mute); + var_TriggerCallback (aout, "intf-change"); } @@ -370,14 +376,14 @@ void aout_VolumeHardSet (audio_output_t *aout, float volume, bool mute) static inline aout_packet_t *aout_packet (audio_output_t *aout) { - aout_owner_t *owner = aout_owner (aout); - return &owner->packet; + return (aout_packet_t *)(aout->sys); } void aout_PacketInit (audio_output_t *aout, aout_packet_t *p, unsigned samples) { assert (p == aout_packet (aout)); + vlc_mutex_init (&p->lock); aout_FifoInit (aout, &p->partial, aout->format.i_rate); aout_FifoInit (aout, &p->fifo, aout->format.i_rate); p->pause_date = VLC_TS_INVALID; @@ -391,6 +397,7 @@ void aout_PacketDestroy (audio_output_t *aout) aout_FifoDestroy (&p->partial); aout_FifoDestroy (&p->fifo); + vlc_mutex_destroy (&p->lock); } static block_t *aout_OutputSlice (audio_output_t *); @@ -399,9 +406,11 @@ void aout_PacketPlay (audio_output_t *aout, block_t *block) { aout_packet_t *p = aout_packet (aout); + vlc_mutex_lock (&p->lock); aout_FifoPush (&p->partial, block); while ((block = aout_OutputSlice (aout)) != NULL) aout_FifoPush (&p->fifo, block); + vlc_mutex_unlock (&p->lock); } void aout_PacketPause (audio_output_t *aout, bool pause, mtime_t date) @@ -420,8 +429,10 @@ void aout_PacketPause (audio_output_t *aout, bool pause, mtime_t date) mtime_t duration = date - p->pause_date; p->pause_date = VLC_TS_INVALID; + vlc_mutex_lock (&p->lock); aout_FifoMoveDates (&p->partial, duration); aout_FifoMoveDates (&p->fifo, duration); + vlc_mutex_unlock (&p->lock); } } @@ -429,8 +440,11 @@ void aout_PacketFlush (audio_output_t *aout, bool drain) { aout_packet_t *p = aout_packet (aout); + vlc_mutex_lock (&p->lock); aout_FifoReset (&p->partial); aout_FifoReset (&p->fifo); + vlc_mutex_unlock (&p->lock); + (void) drain; /* TODO */ } @@ -444,12 +458,10 @@ static block_t *aout_OutputSlice (audio_output_t *p_aout) { aout_packet_t *p = aout_packet (p_aout); aout_fifo_t *p_fifo = &p->partial; - const unsigned samples = p_aout->i_nb_samples; - /* FIXME: Remove this silly constraint. Just pass buffers as they come to - * "smart" audio outputs. */ + const unsigned samples = p->samples; assert( samples > 0 ); - vlc_assert_locked( &p_aout->lock ); + vlc_assert_locked( &p->lock ); /* Retrieve the date of the next buffer. */ date_t exact_start_date = p->fifo.end_date; @@ -601,10 +613,12 @@ aout_buffer_t * aout_OutputNextBuffer( audio_output_t * p_aout, { aout_packet_t *p = aout_packet (p_aout); aout_fifo_t *p_fifo = &p->fifo; - aout_buffer_t * p_buffer; + aout_buffer_t *p_buffer = NULL; mtime_t now = mdate(); - aout_lock( p_aout ); + vlc_mutex_lock( &p->lock ); + if( p->pause_date != VLC_TS_INVALID ) + goto out; /* Drop the audio sample if the audio output is really late. * In the case of b_can_sleek, we don't use a resampler so we need to be @@ -660,8 +674,9 @@ aout_buffer_t * aout_OutputNextBuffer( audio_output_t * p_aout, aout_FifoMoveDates (&p->partial, delta); aout_FifoMoveDates (p_fifo, delta); +#warning FIXME: feed back to input for resampling!!! } out: - aout_unlock( p_aout ); + vlc_mutex_unlock( &p->lock ); return p_buffer; }