https://www.cnblogs.com/Icewine/p/8353709.html#一下载
https://code.videolan.org/videolan/VLCKit
VLCMediaPlayer.m地址
https://code.videolan.org/videolan/VLCKit/blob/master/Sources/VLCMediaPlayer.m
设置速度的c函数
https://code.videolan.org/videolan/vlc/blob/master/lib/media_player.c 1585行
int libvlc_media_player_set_rate( libvlc_media_player_t *p_mi, float rate )
{
vlc_player_t *player = p_mi->player;
vlc_player_Lock(player);
vlc_player_ChangeRate(player, rate);
vlc_player_Unlock(player);
return 0;
}
https://code.videolan.org/videolan/vlc/blob/master/src/input/player.c 2621行
void
vlc_player_ChangeRate(vlc_player_t *player, float rate)
{
struct vlc_player_input *input = vlc_player_get_input_locked(player);
if (rate == 0.0)
return;
/* Save rate accross inputs */
var_SetFloat(player, "rate", rate);
if (input)
{
input_ControlPushHelper(input->thread, INPUT_CONTROL_SET_RATE,
&(vlc_value_t) { .f_float = rate });
}
else
vlc_player_SendEvent(player, on_rate_changed, rate);
vlc_player_vout_OSDMessage(player, ("Speed: %.2fx"), rate);
}
https://code.videolan.org/videolan/vlc/blob/master/include/vlc_variables.h 330行
static inline int var_SetFloat( vlc_object_t *p_obj, const char *psz_name, float f )
{
vlc_value_t val;
val.f_float = f;
return var_SetChecked( p_obj, psz_name, VLC_VAR_FLOAT, val );
}
https://code.videolan.org/videolan/vlc/blob/master/src/misc/variables.c 673行
int (var_SetChecked)(vlc_object_t *p_this, const char *psz_name,
int expected_type, vlc_value_t val)
{
variable_t *p_var;
vlc_value_t oldval;
assert( p_this );
vlc_object_internals_t *p_priv = vlc_internals( p_this );
p_var = Lookup( p_this, psz_name );
if( p_var == NULL )
{
vlc_mutex_unlock( &p_priv->var_lock );
return VLC_ENOVAR;
}
assert( expected_type == 0 ||
(p_var->i_type & VLC_VAR_CLASS) == expected_type );
assert ((p_var->i_type & VLC_VAR_CLASS) != VLC_VAR_VOID);
WaitUnused( p_this, p_var );
/* Duplicate data if needed */
p_var->ops->pf_dup( &val );
/* Backup needed stuff */
oldval = p_var->val;
/* Check boundaries and list */
CheckValue( p_var, &val );
/* Set the variable */
p_var->val = val;
/* Deal with callbacks */
TriggerCallback( p_this, p_var, psz_name, oldval );
/* Free data if needed */
p_var->ops->pf_free( &oldval );
vlc_mutex_unlock( &p_priv->var_lock );
return VLC_SUCCESS;
}
/**
* Waits until the variable is inactive (i.e. not executing a callback)
*/
static void WaitUnused(vlc_object_t *obj, variable_t *var)
{
vlc_object_internals_t *priv = vlc_internals(obj);
mutex_cleanup_push(&priv->var_lock);
while (var->b_incallback)
vlc_cond_wait(&priv->var_wait, &priv->var_lock);
vlc_cleanup_pop();
}
static void TriggerCallback(vlc_object_t *obj, variable_t *var,
const char *name, vlc_value_t prev)
{
assert(obj != NULL);
callback_entry_t *entry = var->value_callbacks;
if (entry == NULL)
return;
vlc_object_internals_t *priv = vlc_internals(obj);
assert(!var->b_incallback);
var->b_incallback = true;
vlc_mutex_unlock(&priv->var_lock);
do
{
entry->pf_value_callback(obj, name, prev, var->val, entry->p_data);
entry = entry->next;
}
while (entry != NULL);
vlc_mutex_lock(&priv->var_lock);
var->b_incallback = false;
vlc_cond_broadcast(&priv->var_wait);
}