📄 input.c
字号:
* 3. Some delay in the output stage, causing a loss of lip * synchronization * Solution : resample the buffer to avoid a scratch. */ mtime_t drift = p_buffer->start_date - start_date; p_input->i_resamp_start_date = mdate(); p_input->i_resamp_start_drift = (int)drift; if ( drift > 0 ) p_input->i_resampling_type = AOUT_RESAMPLING_DOWN; else p_input->i_resampling_type = AOUT_RESAMPLING_UP; msg_Warn( p_aout, "buffer is %"PRId64" %s, triggering %ssampling", drift > 0 ? drift : -drift, drift > 0 ? "in advance" : "late", drift > 0 ? "down" : "up"); } if ( p_input->i_resampling_type != AOUT_RESAMPLING_NONE ) { /* Resampling has been triggered previously (because of dates * mismatch). We want the resampling to happen progressively so * it isn't too audible to the listener. */ if( p_input->i_resampling_type == AOUT_RESAMPLING_UP ) { p_input->pp_resamplers[0]->input.i_rate += 2; /* Hz */ } else { p_input->pp_resamplers[0]->input.i_rate -= 2; /* Hz */ } /* Check if everything is back to normal, in which case we can stop the * resampling */ unsigned int i_nominal_rate = (p_input->pp_resamplers[0] == p_input->p_playback_rate_filter) ? INPUT_RATE_DEFAULT * p_input->input.i_rate / i_input_rate : p_input->input.i_rate; if( p_input->pp_resamplers[0]->input.i_rate == i_nominal_rate ) { p_input->i_resampling_type = AOUT_RESAMPLING_NONE; msg_Warn( p_aout, "resampling stopped after %"PRIi64" usec " "(drift: %"PRIi64")", mdate() - p_input->i_resamp_start_date, p_buffer->start_date - start_date); } else if( abs( (int)(p_buffer->start_date - start_date) ) < abs( p_input->i_resamp_start_drift ) / 2 ) { /* if we reduced the drift from half, then it is time to switch * back the resampling direction. */ if( p_input->i_resampling_type == AOUT_RESAMPLING_UP ) p_input->i_resampling_type = AOUT_RESAMPLING_DOWN; else p_input->i_resampling_type = AOUT_RESAMPLING_UP; p_input->i_resamp_start_drift = 0; } else if( p_input->i_resamp_start_drift && ( abs( (int)(p_buffer->start_date - start_date) ) > abs( p_input->i_resamp_start_drift ) * 3 / 2 ) ) { /* If the drift is increasing and not decreasing, than something * is bad. We'd better stop the resampling right now. */ msg_Warn( p_aout, "timing screwed, stopping resampling" ); inputResamplingStop( p_input ); } }#ifndef AOUT_PROCESS_BEFORE_CHEKS /* Actually run the resampler now. */ if ( p_input->i_nb_resamplers > 0 ) { aout_FiltersPlay( p_aout, p_input->pp_resamplers, p_input->i_nb_resamplers, &p_buffer ); } if( p_buffer->i_nb_samples <= 0 ) { aout_BufferFree( p_buffer ); return 0; }#endif /* Adding the start date will be managed by aout_FifoPush(). */ p_buffer->end_date = start_date + (p_buffer->end_date - p_buffer->start_date); p_buffer->start_date = start_date; aout_lock_input_fifos( p_aout ); aout_FifoPush( p_aout, &p_input->fifo, p_buffer ); aout_unlock_input_fifos( p_aout ); return 0;}/***************************************************************************** * static functions *****************************************************************************/static void inputFailure( aout_instance_t * p_aout, aout_input_t * p_input, const char * psz_error_message ){ /* error message */ msg_Err( p_aout, "%s", psz_error_message ); /* clean up */ aout_FiltersDestroyPipeline( p_aout, p_input->pp_filters, p_input->i_nb_filters ); aout_FiltersDestroyPipeline( p_aout, p_input->pp_resamplers, p_input->i_nb_resamplers ); aout_FifoDestroy( p_aout, &p_input->fifo ); var_Destroy( p_aout, "visual" ); var_Destroy( p_aout, "equalizer" ); var_Destroy( p_aout, "audio-filter" ); var_Destroy( p_aout, "audio-visual" ); var_Destroy( p_aout, "audio-replay-gain-mode" ); var_Destroy( p_aout, "audio-replay-gain-default" ); var_Destroy( p_aout, "audio-replay-gain-preamp" ); var_Destroy( p_aout, "audio-replay-gain-peak-protection" ); /* error flag */ p_input->b_error = 1;}static void inputDrop( aout_instance_t *p_aout, aout_input_t *p_input, aout_buffer_t *p_buffer ){ aout_BufferFree( p_buffer ); if( !p_input->p_input_thread ) return; vlc_mutex_lock( &p_input->p_input_thread->p->counters.counters_lock); stats_UpdateInteger( p_aout, p_input->p_input_thread->p->counters.p_lost_abuffers, 1, NULL ); vlc_mutex_unlock( &p_input->p_input_thread->p->counters.counters_lock);}static void inputResamplingStop( aout_input_t *p_input ){ p_input->i_resampling_type = AOUT_RESAMPLING_NONE; if( p_input->i_nb_resamplers != 0 ) { p_input->pp_resamplers[0]->input.i_rate = ( p_input->pp_resamplers[0] == p_input->p_playback_rate_filter ) ? INPUT_RATE_DEFAULT * p_input->input.i_rate / p_input->i_last_input_rate : p_input->input.i_rate; p_input->pp_resamplers[0]->b_continuity = false; }}static int ChangeFiltersString( aout_instance_t * p_aout, const char* psz_variable, const char *psz_name, bool b_add ){ return AoutChangeFilterString( VLC_OBJECT(p_aout), p_aout, psz_variable, psz_name, b_add ) ? 1 : 0;}static int VisualizationCallback( vlc_object_t *p_this, char const *psz_cmd, vlc_value_t oldval, vlc_value_t newval, void *p_data ){ aout_instance_t *p_aout = (aout_instance_t *)p_this; char *psz_mode = newval.psz_string; vlc_value_t val; (void)psz_cmd; (void)oldval; (void)p_data; if( !psz_mode || !*psz_mode ) { ChangeFiltersString( p_aout, "audio-visual", "goom", false ); ChangeFiltersString( p_aout, "audio-visual", "visual", false ); ChangeFiltersString( p_aout, "audio-visual", "galaktos", false ); } else { if( !strcmp( "goom", psz_mode ) ) { ChangeFiltersString( p_aout, "audio-visual", "visual", false ); ChangeFiltersString( p_aout, "audio-visual", "goom", true ); ChangeFiltersString( p_aout, "audio-visual", "galaktos", false); } else if( !strcmp( "galaktos", psz_mode ) ) { ChangeFiltersString( p_aout, "audio-visual", "visual", false ); ChangeFiltersString( p_aout, "audio-visual", "goom", false ); ChangeFiltersString( p_aout, "audio-visual", "galaktos", true ); } else { val.psz_string = psz_mode; var_Create( p_aout, "effect-list", VLC_VAR_STRING ); var_Set( p_aout, "effect-list", val ); ChangeFiltersString( p_aout, "audio-visual", "goom", false ); ChangeFiltersString( p_aout, "audio-visual", "visual", true ); ChangeFiltersString( p_aout, "audio-visual", "galaktos", false); } } /* That sucks */ AoutInputsMarkToRestart( p_aout ); return VLC_SUCCESS;}static int EqualizerCallback( vlc_object_t *p_this, char const *psz_cmd, vlc_value_t oldval, vlc_value_t newval, void *p_data ){ aout_instance_t *p_aout = (aout_instance_t *)p_this; char *psz_mode = newval.psz_string; vlc_value_t val; int i_ret; (void)psz_cmd; (void)oldval; (void)p_data; if( !psz_mode || !*psz_mode ) { i_ret = ChangeFiltersString( p_aout, "audio-filter", "equalizer", false ); } else { val.psz_string = psz_mode; var_Create( p_aout, "equalizer-preset", VLC_VAR_STRING ); var_Set( p_aout, "equalizer-preset", val ); i_ret = ChangeFiltersString( p_aout, "audio-filter", "equalizer", true ); } /* That sucks */ if( i_ret == 1 ) AoutInputsMarkToRestart( p_aout ); return VLC_SUCCESS;}static int ReplayGainCallback( vlc_object_t *p_this, char const *psz_cmd, vlc_value_t oldval, vlc_value_t newval, void *p_data ){ VLC_UNUSED(psz_cmd); VLC_UNUSED(oldval); VLC_UNUSED(newval); VLC_UNUSED(p_data); aout_instance_t *p_aout = (aout_instance_t *)p_this; int i; aout_lock_mixer( p_aout ); for( i = 0; i < p_aout->i_nb_inputs; i++ ) ReplayGainSelect( p_aout, p_aout->pp_inputs[i] ); /* Restart the mixer (a trivial mixer may be in use) */ aout_MixerMultiplierSet( p_aout, p_aout->mixer.f_multiplier ); aout_unlock_mixer( p_aout ); return VLC_SUCCESS;}static void ReplayGainSelect( aout_instance_t *p_aout, aout_input_t *p_input ){ char *psz_replay_gain = var_GetNonEmptyString( p_aout, "audio-replay-gain-mode" ); int i_mode; int i_use; float f_gain; p_input->f_multiplier = 1.0; if( !psz_replay_gain ) return; /* Find select mode */ if( !strcmp( psz_replay_gain, "track" ) ) i_mode = AUDIO_REPLAY_GAIN_TRACK; else if( !strcmp( psz_replay_gain, "album" ) ) i_mode = AUDIO_REPLAY_GAIN_ALBUM; else i_mode = AUDIO_REPLAY_GAIN_MAX; /* If the select mode is not available, prefer the other one */ i_use = i_mode; if( i_use != AUDIO_REPLAY_GAIN_MAX && !p_input->replay_gain.pb_gain[i_use] ) { for( i_use = 0; i_use < AUDIO_REPLAY_GAIN_MAX; i_use++ ) { if( p_input->replay_gain.pb_gain[i_use] ) break; } } /* */ if( i_use != AUDIO_REPLAY_GAIN_MAX ) f_gain = p_input->replay_gain.pf_gain[i_use] + var_GetFloat( p_aout, "audio-replay-gain-preamp" ); else if( i_mode != AUDIO_REPLAY_GAIN_MAX ) f_gain = var_GetFloat( p_aout, "audio-replay-gain-default" ); else f_gain = 0.0; p_input->f_multiplier = pow( 10.0, f_gain / 20.0 ); /* */ if( p_input->replay_gain.pb_peak[i_use] && var_GetBool( p_aout, "audio-replay-gain-peak-protection" ) && p_input->replay_gain.pf_peak[i_use] * p_input->f_multiplier > 1.0 ) { p_input->f_multiplier = 1.0f / p_input->replay_gain.pf_peak[i_use]; } free( psz_replay_gain );}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -