static void SetBookmark ( intf_thread_t *, int );
static void DisplayPosition( intf_thread_t *, vout_thread_t *, input_thread_t * );
static void DisplayVolume ( intf_thread_t *, vout_thread_t *, audio_volume_t );
+static void DisplayRate ( input_thread_t *, float );
+static float AdjustRateFine( input_thread_t *, const int );
static void ClearChannels ( intf_thread_t *, vout_thread_t * );
/*****************************************************************************
vout_OSDMessage( VLC_OBJECT(p_input), DEFAULT_CHAN,
"%s", _("Next frame") );
}
+ else if( i_action == ACTIONID_RATE_NORMAL )
+ {
+ var_SetFloat( p_input, "rate", 1. );
+ vout_OSDMessage( VLC_OBJECT(p_input), DEFAULT_CHAN,
+ "%s", _("1.00x") );
+ }
else if( i_action == ACTIONID_FASTER )
{
var_TriggerCallback( p_input, "rate-faster" );
- vout_OSDMessage( VLC_OBJECT(p_input), DEFAULT_CHAN,
- "%s", _("Faster") );
+ DisplayRate( p_input, var_GetFloat( p_input, "rate" ) );
}
else if( i_action == ACTIONID_SLOWER )
{
var_TriggerCallback( p_input, "rate-slower" );
- vout_OSDMessage( VLC_OBJECT(p_input), DEFAULT_CHAN,
- "%s", _("Slower") );
- }
- else if( i_action == ACTIONID_RATE_NORMAL )
- {
- var_SetFloat( p_input, "rate", 1. );
- vout_OSDMessage( VLC_OBJECT(p_input), DEFAULT_CHAN,
- "%s", _("1.00x") );
+ DisplayRate( p_input, var_GetFloat( p_input, "rate" ) );
}
else if( i_action == ACTIONID_RATE_FASTER_FINE ||
i_action == ACTIONID_RATE_SLOWER_FINE )
{
- const double f_rate_min = (double)INPUT_RATE_DEFAULT / INPUT_RATE_MAX;
- const double f_rate_max = (double)INPUT_RATE_DEFAULT / INPUT_RATE_MIN;
- double f_rate = var_GetFloat( p_input, "rate" );
-
- int i_sign = f_rate < 0 ? -1 : 1;
const int i_dir = i_action == ACTIONID_RATE_FASTER_FINE ? 1 : -1;
+ float f_newrate = AdjustRateFine( p_input, i_dir );
- f_rate = floor( fabs(f_rate) / 0.1 + i_dir ) * 0.1;
- if( f_rate < f_rate_min )
- f_rate = f_rate_min;
- else if( f_rate > f_rate_max )
- f_rate = f_rate_max;
- f_rate *= i_sign;
-
- var_SetFloat( p_input, "rate", f_rate );
-
- char psz_msg[7+1];
- snprintf( psz_msg, sizeof(psz_msg), _("%.2fx"), f_rate );
- vout_OSDMessage( VLC_OBJECT(p_input), DEFAULT_CHAN, "%s", psz_msg );
+ var_SetFloat( p_input, "rate", f_newrate );
+ DisplayRate( p_input, f_newrate );
}
else if( i_action == ACTIONID_POSITION )
{
}
}
+static void DisplayRate( input_thread_t *p_input, float f_rate )
+{
+ vout_OSDMessage( VLC_OBJECT(p_input), DEFAULT_CHAN, _("Speed: %.2fx"), f_rate );
+}
+
+static float AdjustRateFine( input_thread_t *p_input, const int i_dir )
+{
+ const float f_rate_min = (float)INPUT_RATE_DEFAULT / INPUT_RATE_MAX;
+ const float f_rate_max = (float)INPUT_RATE_DEFAULT / INPUT_RATE_MIN;
+ float f_rate = var_GetFloat( p_input, "rate" );
+
+ int i_sign = f_rate < 0 ? -1 : 1;
+
+ f_rate = floor( fabs(f_rate) / 0.1 + i_dir ) * 0.1;
+
+ if( f_rate < f_rate_min )
+ f_rate = f_rate_min;
+ else if( f_rate > f_rate_max )
+ f_rate = f_rate_max;
+ f_rate *= i_sign;
+
+ return f_rate;
+}
+
static void ClearChannels( intf_thread_t *p_intf, vout_thread_t *p_vout )
{
int i;
break;
case INPUT_CONTROL_SET_RATE:
- case INPUT_CONTROL_SET_RATE_SLOWER:
- case INPUT_CONTROL_SET_RATE_FASTER:
{
- int i_rate;
- int i_rate_sign;
-
/* Get rate and direction */
- if( i_type == INPUT_CONTROL_SET_RATE )
- {
- i_rate = abs( val.i_int );
- i_rate_sign = val.i_int < 0 ? -1 : 1;
- }
- else
- {
- static const int ppi_factor[][2] = {
- {1,64}, {1,32}, {1,16}, {1,8}, {1,4}, {1,3}, {1,2}, {2,3},
- {1,1},
- {3,2}, {2,1}, {3,1}, {4,1}, {8,1}, {16,1}, {32,1}, {64,1},
- {0,0}
- };
- int i_error;
- int i_idx;
- int i;
-
- i_rate_sign = p_input->p->i_rate < 0 ? -1 : 1;
-
- i_error = INT_MAX;
- i_idx = -1;
- for( i = 0; ppi_factor[i][0] != 0; i++ )
- {
- const int i_test_r = INPUT_RATE_DEFAULT * ppi_factor[i][0] / ppi_factor[i][1];
- const int i_test_e = abs( abs( p_input->p->i_rate ) - i_test_r );
- if( i_test_e < i_error )
- {
- i_idx = i;
- i_error = i_test_e;
- }
- }
-
- assert( i_idx >= 0 && ppi_factor[i_idx][0] != 0 );
-
- if( i_type == INPUT_CONTROL_SET_RATE_SLOWER )
- {
- if( ppi_factor[i_idx+1][0] > 0 )
- i_rate = INPUT_RATE_DEFAULT * ppi_factor[i_idx+1][0] / ppi_factor[i_idx+1][1];
- else
- i_rate = INPUT_RATE_MAX+1;
- }
- else
- {
- assert( i_type == INPUT_CONTROL_SET_RATE_FASTER );
- if( i_idx > 0 )
- i_rate = INPUT_RATE_DEFAULT * ppi_factor[i_idx-1][0] / ppi_factor[i_idx-1][1];
- else
- i_rate = INPUT_RATE_MIN-1;
- }
- }
+ int i_rate = abs( val.i_int );
+ int i_rate_sign = val.i_int < 0 ? -1 : 1;
/* Check rate bound */
if( i_rate < INPUT_RATE_MIN )
INPUT_CONTROL_SET_STATE,
INPUT_CONTROL_SET_RATE,
- INPUT_CONTROL_SET_RATE_SLOWER,
- INPUT_CONTROL_SET_RATE_FASTER,
INPUT_CONTROL_SET_POSITION,
#endif
#include <vlc_common.h>
+#include <assert.h>
+#include <math.h>
#include <stdio.h>
#include <stdlib.h>
input_thread_t *p_input = (input_thread_t*)p_this;
VLC_UNUSED(oldval); VLC_UNUSED(p_data);
- /* Problem with this way: the "rate" variable is updated after the
- * input thread did the change */
+ static const int ppi_factor[][2] = {
+ {1,64}, {1,32}, {1,16}, {1,8}, {1,4}, {1,3}, {1,2}, {2,3},
+ {1,1},
+ {3,2}, {2,1}, {3,1}, {4,1}, {8,1}, {16,1}, {32,1}, {64,1},
+ {0,0}
+ };
+
+ int i;
+ int i_idx;
+ float f_rate = var_GetFloat( p_input, "rate" );
+ float f_sign = f_rate >= 0 ? +1. : -1.;
+ float f_error;
+
+ /* Determine the factor closest to the current rate */
+ f_error = 1E20;
+ i_idx = -1;
+ for( i = 0; ppi_factor[i][0] != 0; i++ )
+ {
+ const float f_test_r = (float)ppi_factor[i][0] / ppi_factor[i][1];
+ const float f_test_e = fabs( fabs( f_rate ) - f_test_r );
+ if( f_test_e < f_error )
+ {
+ i_idx = i;
+ f_error = f_test_e;
+ }
+ }
+
+ assert( i_idx >= 0 && ppi_factor[i_idx][0] != 0 );
+
+ float f_new_rate;
+ const float f_rate_min = (float)INPUT_RATE_DEFAULT / INPUT_RATE_MAX;
+ const float f_rate_max = (float)INPUT_RATE_DEFAULT / INPUT_RATE_MIN;
if( !strcmp( psz_cmd, "rate-slower" ) )
{
- input_ControlPush( p_input, INPUT_CONTROL_SET_RATE_SLOWER, NULL );
+ if( i_idx > 0 )
+ f_new_rate = (float)ppi_factor[i_idx-1][0] / ppi_factor[i_idx-1][1];
+ else
+ f_new_rate = f_rate_min;
+ f_new_rate *= f_sign;
+
+ var_SetFloat( p_input, "rate", f_new_rate );
}
else if( !strcmp( psz_cmd, "rate-faster" ) )
{
- input_ControlPush( p_input, INPUT_CONTROL_SET_RATE_FASTER, NULL );
+ if( ppi_factor[i_idx+1][0] > 0 )
+ f_new_rate = (float)ppi_factor[i_idx+1][0] / ppi_factor[i_idx+1][1];
+ else
+ f_new_rate = f_rate_max;
+ f_new_rate *= f_sign;
+
+ var_SetFloat( p_input, "rate", f_new_rate );
}
else
{
+ /* Problem with this way: the "rate" variable is updated after the
+ * input thread did the change */
newval.i_int = INPUT_RATE_DEFAULT / newval.f_float;
input_ControlPush( p_input, INPUT_CONTROL_SET_RATE, &newval );
}
+
return VLC_SUCCESS;
}