diff -uNr vlc-trunk-orig/include/vlc_demux.h vlc-trunk-modified/include/vlc_demux.h
--- vlc-trunk-orig/include/vlc_demux.h	2007-11-19 15:03:23.000000000 +0000
+++ vlc-trunk-modified/include/vlc_demux.h	2007-11-20 12:50:17.000000000 +0000
@@ -127,7 +127,10 @@
     DEMUX_CAN_PAUSE,            /* arg1= vlc_bool_t*    cannot fail */
     DEMUX_CAN_CONTROL_PACE,     /* arg1= vlc_bool_t*    cannot fail */
     DEMUX_GET_PTS_DELAY,        /* arg1= int64_t*       cannot fail */
-    DEMUX_SET_PAUSE_STATE       /* arg1= vlc_bool_t     can fail */
+    DEMUX_SET_PAUSE_STATE,      /* arg1= vlc_bool_t     can fail */
+    DEMUX_HAS_SCALE_TRICKPLAY,  /* arg1= vlc_bool_t     cannot fail */
+    DEMUX_GET_SCALE,            /* arg1= int            cannot fail */
+    DEMUX_SET_SCALE             /* arg1= int, arg2= vlc_bool_t can fail */
 };
 
 VLC_EXPORT( int,       demux2_vaControlHelper, ( stream_t *, int64_t i_start, int64_t i_end, int i_bitrate, int i_align, int i_query, va_list args ) );
diff -uNr vlc-trunk-orig/modules/control/rc.c vlc-trunk-modified/modules/control/rc.c
--- vlc-trunk-orig/modules/control/rc.c	2007-11-19 15:02:51.000000000 +0000
+++ vlc-trunk-modified/modules/control/rc.c	2007-11-20 12:50:17.000000000 +0000
@@ -1072,15 +1072,61 @@
     }
     else if ( !strcmp( psz_cmd, "fastforward" ) )
     {
-        val.i_int = config_GetInt( p_intf, "key-jump+extrashort" );
-        var_Set( p_intf->p_libvlc, "key-pressed", val );
+        if( config_GetInt( p_intf, "rtsp-scaled-trickplay" ) == 0 
+            && config_GetInt( p_intf, "rtsp-kasenna") == 0 )
+        {
+            val.i_int = config_GetInt( p_intf, "key-jump+extrashort" );
+            var_Set( p_intf->p_libvlc, "key-pressed", val );
+        }
+        else
+        {
+            if( strlen( newval.psz_string ) > 0 )
+            {
+                val.i_int = atoi( newval.psz_string );
+                val.f_float = (float)val.i_int;
+            }
+            else
+            {
+                /* If the user didn't ask for a scale factor then use this
+                 * define as an indicator that we want to use the next scale
+                 * available.
+                 */
+                val.i_int = INPUT_RATE_MAX;
+                val.f_float = (float)INPUT_RATE_MAX;
+            }
+            var_Set( p_input, "rate", val);
+        }
         vlc_object_release( p_input );
         return VLC_SUCCESS;
     }
     else if ( !strcmp( psz_cmd, "rewind" ) )
     {
-        val.i_int = config_GetInt( p_intf, "key-jump-extrashort" );
-        var_Set( p_intf->p_libvlc, "key-pressed", val );
+        if( config_GetInt( p_intf, "rtsp-scaled-trickplay" ) == 0 
+            && config_GetInt( p_intf, "rtsp-kasenna") == 0 )
+        {
+            val.i_int = config_GetInt( p_intf, "key-jump-extrashort" );
+            var_Set( p_intf->p_libvlc, "key-pressed", val );
+        }
+        else
+        {
+            if( strlen( newval.psz_string ) > 0 )
+            {
+                val.i_int = atoi( newval.psz_string );
+                if( val.i_int > 0 )
+                    val.i_int *= -1; 
+                val.f_float = (float)val.i_int;
+            }
+            else
+            {
+                /* If the user didn't ask for a scale factor then use this
+                 * define as an indicator that we want to use the next scale
+                 * available.
+                 */
+                val.i_int = INPUT_RATE_MIN;
+                val.f_float = (float)INPUT_RATE_MIN;
+            }
+            var_Set( p_input, "rate", val);
+        }
         vlc_object_release( p_input );
         return VLC_SUCCESS;
     }
diff -uNr vlc-trunk-orig/modules/demux/live555.cpp vlc-trunk-modified/modules/demux/live555.cpp
--- vlc-trunk-orig/modules/demux/live555.cpp	2007-11-20 12:47:54.000000000 +0000
+++ vlc-trunk-modified/modules/demux/live555.cpp	2007-11-20 12:50:36.000000000 +0000
@@ -28,6 +28,7 @@
  *****************************************************************************/
 
 #include <vlc/vlc.h>
+#include <vlc_input.h>
 
 #include <vlc_demux.h>
 #include <vlc_interface.h>
@@ -67,6 +68,15 @@
     "dialect of RTSP. When you set this parameter, VLC will try this dialect "\
     "for communication. In this mode you cannot connect to normal RTSP servers." )
 
+#define SCALE_TEXT N_("RTSP Scaled trickplay")
+#define SCALE_LONGTEXT N_("RTSP servers can scale the rate of play " \
+    "when delivering a stream. Implementation of scale changes depends on the" \
+    "server and media type. For video, a server may, for example, deliver " \
+    "only key frames or selected key frames. For audio, it may time-scale the" \
+    "audio while preserving pitch or, less desirably, deliver fragments of " \
+    "audio.")
+
+
 #define USER_TEXT N_("RTSP user name")
 #define USER_LONGTEXT N_("Allows you to modify the user name that will " \
     "be used for authenticating the connection.")
@@ -107,10 +117,13 @@
                     CACHING_TEXT, CACHING_LONGTEXT, VLC_TRUE );
         add_bool(   "rtsp-kasenna", VLC_FALSE, NULL, KASENNA_TEXT,
                     KASENNA_LONGTEXT, VLC_TRUE );
+        add_bool(   "rtsp-scaled-trickplay", VLC_FALSE, NULL, SCALE_TEXT,
+                    SCALE_LONGTEXT, VLC_TRUE );
         add_string( "rtsp-user", NULL, NULL, USER_TEXT,
                     USER_LONGTEXT, VLC_TRUE );
         add_string( "rtsp-pwd", NULL, NULL, PASS_TEXT,
                     PASS_LONGTEXT, VLC_TRUE );
+
 vlc_module_end();
 
 
@@ -1140,6 +1153,9 @@
     int64_t *pi64;
     double  *pf, f;
     vlc_bool_t *pb, b_bool;
+    float f_scale;
+
+    f = f_scale = 0.0;
 
     switch( i_query )
     {
@@ -1247,9 +1263,13 @@
 
         case DEMUX_SET_PAUSE_STATE:
         {
-            double d_npt = (double) p_sys->i_npt / I64C(1000000);
+            double d_npt;
             int i;
 
+            d_npt = 0.0;
+            if( var_CreateGetBool( p_demux, "rtsp-kasenna" ) == VLC_FALSE )
+                d_npt = (double) p_sys->i_npt / I64C(1000000);
+
             b_bool = (vlc_bool_t)va_arg( args, vlc_bool_t );
             if( p_sys->rtsp == NULL )
                 return VLC_EGENERIC;
@@ -1321,6 +1341,78 @@
             pi64 = (int64_t*)va_arg( args, int64_t * );
             *pi64 = (int64_t)var_GetInteger( p_demux, "rtsp-caching" ) * 1000;
             return VLC_SUCCESS;
+        case DEMUX_HAS_SCALE_TRICKPLAY:
+            pb = (vlc_bool_t*)va_arg( args, vlc_bool_t * );
+            if( p_sys->rtsp && ( var_CreateGetBool( p_demux, "rtsp-kasenna" )
+                    || var_CreateGetBool( p_demux, "rtsp-scaled-trickplay" ) ) )
+                *pb = VLC_TRUE;
+            else
+                *pb = VLC_FALSE;
+            return VLC_SUCCESS;
+        case DEMUX_SET_SCALE:
+            f_scale = (double)va_arg( args, double );
+            if( (int)f_scale == INPUT_RATE_MAX 
+                || (int)f_scale == INPUT_RATE_MIN )
+            {
+                /* Double the current scale if none specified */
+                if( p_sys->ms != NULL )
+                {
+                    if( (int)f_scale == INPUT_RATE_MIN )
+                    {
+                        /* Need a negative value for rewind */
+                        if( (int)p_sys->ms->scale() > 0 )
+                        { 
+                            /* Default Scale (1.0) set to negative for rewind
+                             * And doubled for increased speed
+                             * ((1.0 * 2) * -1) == -2.0 */
+                            f_scale = -2.0; 
+                        } 
+                        else /* double the existing <1.0 scale */
+                        {
+                            f_scale = p_sys->ms->scale() * 2;
+                        }
+                    }
+                    else
+                    {
+                        f_scale = p_sys->ms->scale() * 2;
+                    }
+                }
+                else /* f_scale == INPUT_RATE_MAX */
+                    f_scale = 1.0;
+            }
+            else if( (int)f_scale == INPUT_RATE_DEFAULT || (int)f_scale == 0 )
+            {
+                f_scale = 1.0;
+            }
+
+            /* Passing -1 for the start and end time will mean liveMedia won't
+             * create a Range: section for the RTSP message. The server should 
+             * pick up from the current position */
+            if( !p_sys->rtsp->playMediaSession( *p_sys->ms, -1, -1, f_scale ) )
+            {
+                msg_Err( p_demux, "PLAY with Scale %0.2f failed %s", f_scale, 
+                         p_sys->env->getResultMsg() );
+                return VLC_EGENERIC;
+            }
+            /* ReSync the stream */
+            p_sys->i_npt_start = 0;
+            p_sys->i_pcr = 0;
+            es_out_Control( p_demux->out, ES_OUT_RESET_PCR );
+            
+            return VLC_SUCCESS;
+
+        case DEMUX_GET_SCALE:
+            pf = (double*)va_arg( args, double* );
+            if( p_sys->i_npt_length > 0 )
+            {
+                *pf = (double)( p_sys->ms->scale() );
+            }
+            else
+            {
+                *pf = 1.0;
+            }
+            return VLC_SUCCESS;
+
 
         default:
             return VLC_EGENERIC;
diff -uNr vlc-trunk-orig/src/input/input.c vlc-trunk-modified/src/input/input.c
--- vlc-trunk-orig/src/input/input.c	2007-11-19 15:02:38.000000000 +0000
+++ vlc-trunk-modified/src/input/input.c	2007-11-20 12:50:17.000000000 +0000
@@ -1673,82 +1673,104 @@
         case INPUT_CONTROL_SET_RATE_SLOWER:
         case INPUT_CONTROL_SET_RATE_FASTER:
         {
-            int i_rate;
+            int i_rate, i_ret;
+            vlc_bool_t b_scale_trickplay = VLC_FALSE;
 
-            if( i_type == INPUT_CONTROL_SET_RATE )
-            {
-                i_rate = val.i_int;
+            /* Check to see if the Demux allows us to use Scale Trickplay */
+            i_ret = demux2_Control( p_input->p->input.p_demux,
+                                    DEMUX_HAS_SCALE_TRICKPLAY,
+                                    &b_scale_trickplay);
+            if( i_ret == VLC_SUCCESS && b_scale_trickplay == VLC_TRUE )
+            {
+                double scale = val.f_float;
+                msg_Dbg( p_input, "Setting Scale to %0.2f", scale );
+                demux2_Control( p_input->p->input.p_demux, 
+                                DEMUX_SET_SCALE, scale );
+                msg_Dbg( p_input, "Verifying Scale...");
+                /* Now, readback the value actually used by the server, as
+                 * as it may not support the scale we've specified
+                 */
+                demux2_Control( p_input->p->input.p_demux, 
+                                DEMUX_GET_SCALE, &scale );
+                msg_Dbg( p_input, "Scale is set to %0.2f", scale );
             }
             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_error = INT_MAX;
-                i_idx = -1;
-                for( i = 0; ppi_factor[i][0] != 0; i++ )
+                if( i_type == INPUT_CONTROL_SET_RATE )
+                {
+                    i_rate = val.i_int;
+                }
+                else
                 {
-                    const int i_test_r = INPUT_RATE_DEFAULT * ppi_factor[i][0] / ppi_factor[i][1];
-                    const int i_test_e = abs(p_input->p->i_rate - i_test_r);
-                    if( i_test_e < i_error )
+                    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_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(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 )
                     {
-                        i_idx = i;
-                        i_error = i_test_e;
+                        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;
                     }
                 }
-                assert( i_idx >= 0 && ppi_factor[i_idx][0] != 0 );
 
-                if( i_type == INPUT_CONTROL_SET_RATE_SLOWER )
+                if( i_rate < INPUT_RATE_MIN )
                 {
-                    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;
+                    msg_Dbg( p_input, "cannot set rate faster" );
+                    i_rate = INPUT_RATE_MIN;
                 }
-                else
+                else if( i_rate > INPUT_RATE_MAX )
                 {
-                    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;
+                    msg_Dbg( p_input, "cannot set rate slower" );
+                    i_rate = INPUT_RATE_MAX;
                 }
-            }
-
-            if( i_rate < INPUT_RATE_MIN )
-            {
-                msg_Dbg( p_input, "cannot set rate faster" );
-                i_rate = INPUT_RATE_MIN;
-            }
-            else if( i_rate > INPUT_RATE_MAX )
-            {
-                msg_Dbg( p_input, "cannot set rate slower" );
-                i_rate = INPUT_RATE_MAX;
-            }
-            if( i_rate != INPUT_RATE_DEFAULT &&
-                ( !p_input->b_can_pace_control ||
-                  ( p_input->p->p_sout && !p_input->p->b_out_pace_control ) ) )
-            {
-                msg_Dbg( p_input, "cannot change rate" );
-                i_rate = INPUT_RATE_DEFAULT;
-            }
-            if( i_rate != p_input->p->i_rate )
-            {
-                val.i_int = i_rate;
-                var_Change( p_input, "rate", VLC_VAR_SETVALUE, &val, NULL );
+                if( i_rate != INPUT_RATE_DEFAULT &&
+                    ( !p_input->b_can_pace_control ||
+                      ( p_input->p->p_sout && !p_input->p->b_out_pace_control ) ) )
+                {
+                    msg_Dbg( p_input, "cannot change rate" );
+                    i_rate = INPUT_RATE_DEFAULT;
+                }
+                if( i_rate != p_input->p->i_rate )
+                {
+                    val.i_int = i_rate;
+                    var_Change( p_input, "rate", VLC_VAR_SETVALUE, &val, NULL );
 
-                p_input->p->i_rate  = i_rate;
+                    p_input->p->i_rate  = i_rate;
 
-                input_EsOutChangeRate( p_input->p->p_es_out );
+                    input_EsOutChangeRate( p_input->p->p_es_out );
 
-                b_force_update = VLC_TRUE;
+                    b_force_update = VLC_TRUE;
+                }
             }
             break;
         }
