[vlc-devel] [PATCH] Fix for H264 seek without jerks and fast forward at 2x and 4x speedin case VOD RTSP streaming

Murali Manohar murali.manohar123 at gmail.com
Thu Jan 30 19:13:35 CET 2014


---
 include/vlc_vlm.h                 |    7 ++
 include/vlc_vod.h                 |   19 ++++
 modules/codec/avcodec/avcodec.c   |    2 +-
 modules/codec/avcodec/video.c     |   65 +++++++++++++-
 modules/demux/avformat/demux.c    |   41 ++++++++-
 modules/demux/live555.cpp         |    7 +-
 modules/demux/mpeg/h264.c         |   18 ++++
 modules/misc/rtsp.c               |   54 ++++++++++++
 modules/packetizer/h264.c         |   41 ++++++++-
 modules/stream_out/rtp.h          |    9 ++
 modules/stream_out/rtpfmt.c       |   46 ++++++++++
 modules/stream_out/rtsp.c         |  114 +++++++++++++++++++++++-
 modules/stream_out/vod.c          |  172 +++++++++++++++++++++++++++++++++++++
 src/input/decoder.c               |   46 +++++++++-
 src/input/demux.c                 |   20 +++++
 src/input/es_out.c                |   44 +++++++++-
 src/input/input.c                 |   62 ++++++++++++-
 src/input/stream.c                |   89 ++++++++++++++++++-
 src/input/stream_demux.c          |   29 +++++++
 src/input/vlm.c                   |   62 ++++++++++++-
 src/misc/variables.c              |   12 +++
 src/stream_output/stream_output.c |   25 ++++++
 src/video_output/video_output.c   |    9 +-
 23 files changed, 971 insertions(+), 22 deletions(-)

diff --git a/include/vlc_vlm.h b/include/vlc_vlm.h
index 12a0eda..3ab2232 100644
--- a/include/vlc_vlm.h
+++ b/include/vlc_vlm.h
@@ -155,6 +155,13 @@ enum vlm_query_e
     VLM_GET_MEDIA_INSTANCE_POSITION,    /* arg1=int64_t id, arg2=const char *psz_instance_name arg3=double *   */
     /* Set instance position ([0.0 .. 1.0]) */
     VLM_SET_MEDIA_INSTANCE_POSITION,    /* arg1=int64_t id, arg2=const char *psz_instance_name arg3=double     */
+// mmnk - fix for rate speed control
+// mmnk-START
+#if 1
+    /* Set instance rate */
+    VLM_SET_MEDIA_INSTANCE_RATE,        /* arg1=int64_t id, arg2=const char *psz_instance_name arg3=int     */
+#endif 
+// mmnk-END
 
     /* Schedule control */
     VLM_CLEAR_SCHEDULES,                /* no arg */
diff --git a/include/vlc_vod.h b/include/vlc_vod.h
index 2f09433..46d4366 100644
--- a/include/vlc_vod.h
+++ b/include/vlc_vod.h
@@ -36,6 +36,8 @@
  * @{
  */
 
+#define FAST_REWIND_USING_SEEK
+
 struct vod_t
 {
     VLC_COMMON_MEMBERS
@@ -50,6 +52,17 @@ struct vod_t
     /* Owner properties */
     int (*pf_media_control) ( void *, vod_media_t *, const char *, int, va_list );
     void *p_data;
+
+// mmnk-START: Fix for fast rewind
+#ifdef FAST_REWIND_USING_SEEK
+    vod_media_t   *p_media;
+    int           i_start;
+    int           i_rwd_rate;
+    int           i_rwd_thrd_exist;
+    vlc_thread_t  thread;
+    const char    p_psz_session[48];
+#endif //FAST_REWIND_USING_SEEK
+// mmnk-END: Fix for fast rewind
 };
 
 static inline int vod_MediaControl( vod_t *p_vod, vod_media_t *p_media,
@@ -75,6 +88,12 @@ enum vod_query_e
     VOD_MEDIA_SEEK,         /* arg1= double         res=    */
     VOD_MEDIA_REWIND,       /* arg1= double         res=    */
     VOD_MEDIA_FORWARD,      /* arg1= double         res=    */
+// mmnk - fix for rate speed control
+// mmnk-START
+#if 1
+    VOD_MEDIA_RATE,         /* arg1= int            res=    */
+#endif 
+// mmnk-END
 };
 
 /**
diff --git a/modules/codec/avcodec/avcodec.c b/modules/codec/avcodec/avcodec.c
index cd811e9..62d9e91 100644
--- a/modules/codec/avcodec/avcodec.c
+++ b/modules/codec/avcodec/avcodec.c
@@ -128,6 +128,7 @@ vlc_module_begin ()
     add_integer( "ffmpeg-debug", 0, DEBUG_TEXT, DEBUG_LONGTEXT,
                  true )
     add_string( "ffmpeg-codec", NULL, CODEC_TEXT, CODEC_LONGTEXT, true )
+
 #if defined(HAVE_AVCODEC_VAAPI) || defined(HAVE_AVCODEC_DXVA2)
     add_bool( "ffmpeg-hw", false, HW_TEXT, HW_LONGTEXT, false )
 #endif
@@ -135,7 +136,6 @@ vlc_module_begin ()
     add_integer( "ffmpeg-threads", 0, THREADS_TEXT, THREADS_LONGTEXT, true );
 #endif
 
-
 #ifdef ENABLE_SOUT
     /* encoder submodule */
     add_submodule ()
diff --git a/modules/codec/avcodec/video.c b/modules/codec/avcodec/video.c
index 3fccbbf..97f5df5 100644
--- a/modules/codec/avcodec/video.c
+++ b/modules/codec/avcodec/video.c
@@ -493,8 +493,12 @@ picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block )
         return NULL;
     }
 
+#if 1 //mmnk    
     if( p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) )
     {
+
+        //msg_Err( p_dec, "mmnk - test - 1\n" );
+
         p_sys->i_pts = VLC_TS_INVALID; /* To make sure we recover properly */
 
         p_sys->i_late_frames = 0;
@@ -505,9 +509,11 @@ picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block )
         block_Release( p_block );
         return NULL;
     }
+#endif
 
     if( p_block->i_flags & BLOCK_FLAG_PREROLL )
     {
+	//msg_Err( p_dec, "mmnk - test - 2\n" );
         /* Do not care about late frames when prerolling
          * TODO avoid decoding of non reference frame
          * (ie all B except for H264 where it depends only on nal_ref_idc) */
@@ -517,6 +523,9 @@ picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block )
     if( !p_dec->b_pace_control && (p_sys->i_late_frames > 0) &&
         (mdate() - p_sys->i_late_frames_start > INT64_C(5000000)) )
     {
+// mmnk-START-Fix
+// Avoid drop and skip to remove jerk in straming video play
+#if 0 //mmnk
         if( p_sys->i_pts > VLC_TS_INVALID )
         {
             msg_Err( p_dec, "more than 5 seconds of late video -> "
@@ -526,6 +535,8 @@ picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block )
         block_Release( p_block );
         p_sys->i_late_frames--;
         return NULL;
+#endif
+// mmnk-END-Fix
     }
 
     /* A good idea could be to decode all I pictures and see for the other */
@@ -533,31 +544,54 @@ picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block )
         p_sys->b_hurry_up &&
         (p_sys->i_late_frames > 4) )
     {
+	//msg_Err( p_dec, "late frames more than 4 ");
+// mmnk-START-Fix
+// Avoid drop and skip to remove jerk in straming video play
+#if 0 //mmnk
         b_drawpicture = 0;
         if( p_sys->i_late_frames < 12 )
         {
             p_context->skip_frame =
                     (p_sys->i_skip_frame <= AVDISCARD_NONREF) ?
                     AVDISCARD_NONREF : p_sys->i_skip_frame;
+	    //msg_Err( p_dec, "late frames more than 4: p_context->skip_frame = %d", p_context->skip_frame);
         }
         else
         {
+	    //msg_Err( p_dec, "late frames more than 12 ");	
             /* picture too late, won't decode
              * but break picture until a new I, and for mpeg4 ...*/
             p_sys->i_late_frames--; /* needed else it will never be decrease */
             block_Release( p_block );
             return NULL;
         }
+#endif
+// mmnk-END-Fix
     }
+// mmnk-START-Fix
+// Avoid drop and skip to remove jerk in straming video play
+#if 0 //mmnk
     else
     {
         if( p_sys->b_hurry_up )
+	{
+	    //msg_Err( p_dec, "p_sys->b_hurry_up");
             p_context->skip_frame = p_sys->i_skip_frame;
-        if( !(p_block->i_flags & BLOCK_FLAG_PREROLL) )
+	}     
+	if( !(p_block->i_flags & BLOCK_FLAG_PREROLL) )
+        {
+	    //msg_Err( p_dec, "b_drawpicture = 1");
             b_drawpicture = 1;
+        }
         else
+        {
             b_drawpicture = 0;
+        }
     }
+#else
+    b_drawpicture = 1;
+#endif
+// mmnk-END-Fix
 
     if( p_context->width <= 0 || p_context->height <= 0 )
     {
@@ -635,18 +669,26 @@ picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block )
         wait_mt( p_sys );
 
         if( p_sys->b_flush )
+        {
+	    //msg_Err( p_dec, "mmnk - test - 3\n" );
             p_sys->b_first_frame = true;
+	}
 
         if( p_block->i_buffer <= 0 )
             p_sys->b_flush = false;
 
         if( i_used < 0 )
         {
+#if 1 //mmnk
+	    //msg_Err( p_dec, "mmnk - test - 4\n" );
             if( b_drawpicture )
                 msg_Warn( p_dec, "cannot decode one frame (%zu bytes)",
                           p_block->i_buffer );
             block_Release( p_block );
             return NULL;
+#else
+	    i_used = 0;
+#endif
         }
         else if( i_used > p_block->i_buffer ||
                  p_context->thread_count > 1 )
@@ -658,12 +700,15 @@ picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block )
         p_block->i_buffer -= i_used;
         p_block->p_buffer += i_used;
 
+#if 1 //mmnk
         /* Nothing to display */
         if( !b_gotpicture )
         {
+	    //msg_Err( p_dec, "mmnk - test - 5\n" );
             if( i_used == 0 ) break;
             continue;
         }
+#endif
 
         /* Sanity check (seems to be needed for some streams) */
         if( p_sys->p_ff_pic->pict_type == AV_PICTURE_TYPE_B)
@@ -673,10 +718,14 @@ picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block )
 
         /* Compute the PTS */
         mtime_t i_pts = VLC_TS_INVALID;
+#if 1 //mmnk
         if( p_sys->p_ff_pic->reordered_opaque != INT64_MIN )
+#endif
         {
             mtime_t i_ts = p_sys->p_ff_pic->reordered_opaque >> 1;
             bool    b_dts = p_sys->p_ff_pic->reordered_opaque & 1;
+
+#if 1 //mmnk
             if( b_dts )
             {
                 if( !p_context->has_b_frames ||
@@ -695,12 +744,16 @@ picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block )
                 }
             }
             else
+#endif
             {
                 i_pts = i_ts;
             }
         }
         if( i_pts <= VLC_TS_INVALID )
+        {
+	    //msg_Err( p_dec, "mmnk - test - 6\n" );
             i_pts = p_sys->i_pts;
+	}
 
         /* Interpolate the next PTS */
         if( i_pts > VLC_TS_INVALID )
@@ -734,19 +787,24 @@ picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block )
         if( !(p_block->i_flags & BLOCK_FLAG_PREROLL) )
             i_display_date = decoder_GetDisplayDate( p_dec, i_pts );
 
+#if 1 //mmnk
         if( i_display_date > 0 && i_display_date <= mdate() )
         {
+	    //msg_Err( p_dec, "mmnk - test - 7\n" );
             p_sys->i_late_frames++;
             if( p_sys->i_late_frames == 1 )
                 p_sys->i_late_frames_start = mdate();
         }
         else
+#endif
         {
             p_sys->i_late_frames = 0;
         }
 
+#if 1 //mmnk
         if( !b_drawpicture || ( !p_sys->p_va && !p_sys->p_ff_pic->linesize[0] ) )
             continue;
+#endif 
 
         if( !p_sys->p_ff_pic->opaque )
         {
@@ -754,6 +812,7 @@ picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block )
             p_pic = ffmpeg_NewPictBuf( p_dec, p_context );
             if( !p_pic )
             {
+   		//msg_Err( p_dec, "mmnk - test - 8\n" );
                 block_Release( p_block );
                 return NULL;
             }
@@ -784,7 +843,9 @@ picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block )
         }
 
         /* Send decoded frame to vout */
+#if 1 //mmnk
         if( i_pts > VLC_TS_INVALID)
+#endif
         {
             p_pic->date = i_pts;
 
@@ -819,10 +880,12 @@ picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block )
 
             return p_pic;
         }
+#if 1 //mmnk
         else
         {
             decoder_DeletePicture( p_dec, p_pic );
         }
+#endif
     }
 
     block_Release( p_block );
diff --git a/modules/demux/avformat/demux.c b/modules/demux/avformat/demux.c
index cf6aae2..d39371c 100644
--- a/modules/demux/avformat/demux.c
+++ b/modules/demux/avformat/demux.c
@@ -62,6 +62,8 @@
 #   define HAVE_AVUTIL_CODEC_ATTACHMENT 1
 #endif
 
+#define ENABLE_MMNK_DEBUG_LOGS
+
 /*****************************************************************************
  * demux_sys_t: demux descriptor
  *****************************************************************************/
@@ -799,7 +801,11 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
             return VLC_SUCCESS;
 
         case DEMUX_SET_POSITION:
-            f = (double) va_arg( args, double );
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+	    fprintf(stderr, "\nmmnk - DEMUX_SET_POSITION-1\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS            
+
+	    f = (double) va_arg( args, double );
             i64 = p_sys->ic->duration * f + i_start_time;
 
             msg_Warn( p_demux, "DEMUX_SET_POSITION: %"PRId64, i64 );
@@ -812,14 +818,26 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
                 int64_t i_size = stream_Size( p_demux->s );
                 i64 = (i_size * f);
 
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+	    	fprintf(stderr, "\nmmnk - DEMUX_SET_POSITION-2\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS
+
                 msg_Warn( p_demux, "DEMUX_SET_BYTE_POSITION: %"PRId64, i64 );
                 if( av_seek_frame( p_sys->ic, -1, i64, AVSEEK_FLAG_BYTE ) < 0 )
-                    return VLC_EGENERIC;
+                {
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+		    	fprintf(stderr, "\nmmnk - DEMUX_SET_POSITION-3\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS                    
+			return VLC_EGENERIC;
+                }
 
                 ResetTime( p_demux, -1 );
             }
             else
             {
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+	    	fprintf(stderr, "\nmmnk - DEMUX_SET_POSITION-4\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS                    
                 ResetTime( p_demux, i64 - i_start_time );
             }
             return VLC_SUCCESS;
@@ -842,10 +860,17 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
             i64 = (int64_t)va_arg( args, int64_t );
             i64 = i64 *AV_TIME_BASE / 1000000 + i_start_time;
 
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+            fprintf(stderr, "\nmmnk - DEMUX_SET_TIME-1\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS                    
+
             msg_Warn( p_demux, "DEMUX_SET_TIME: %"PRId64, i64 );
 
             if( av_seek_frame( p_sys->ic, -1, i64, AVSEEK_FLAG_BACKWARD ) < 0 )
             {
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+	        fprintf(stderr, "\nmmnk - DEMUX_SET_TIME-2\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS                    
                 return VLC_EGENERIC;
             }
             ResetTime( p_demux, i64 - i_start_time );
@@ -941,8 +966,17 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
         case DEMUX_SET_SEEKPOINT:
         {
             const int i_seekpoint = (int)va_arg( args, int );
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+            fprintf(stderr, "\nmmnk - DEMUX_SET_SEEKPOINT-1\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS                    
+
             if( !p_sys->p_title )
+            {
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+                fprintf(stderr, "\nmmnk - DEMUX_SET_SEEKPOINT-2\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS                    
                 return VLC_EGENERIC;
+            }
 
             i64 = p_sys->p_title->seekpoint[i_seekpoint]->i_time_offset *
                   AV_TIME_BASE / 1000000 + i_start_time;
@@ -951,6 +985,9 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
 
             if( av_seek_frame( p_sys->ic, -1, i64, AVSEEK_FLAG_BACKWARD ) < 0 )
             {
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+                fprintf(stderr, "\nmmnk - DEMUX_SET_SEEKPOINT-3\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS                    
                 return VLC_EGENERIC;
             }
             ResetTime( p_demux, i64 - i_start_time );
diff --git a/modules/demux/live555.cpp b/modules/demux/live555.cpp
index f8f040d..1491438 100644
--- a/modules/demux/live555.cpp
+++ b/modules/demux/live555.cpp
@@ -1345,7 +1345,9 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
                     p_sys->f_seek_request = time;
                     return VLC_SUCCESS;
                 }
-
+// mmnk-START-Fix
+// mmnk - May not required to pause before play
+#if 1 // mmnk
                 p_sys->rtsp->sendPauseCommand( *p_sys->ms, default_live555_callback );
 
                 if( !wait_Live555_response( p_demux ) )
@@ -1354,7 +1356,8 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
                         p_sys->env->getResultMsg() );
                     return VLC_EGENERIC;
                 }
-
+#endif // mmnk
+// mmnk-END-Fix
                 p_sys->rtsp->sendPlayCommand( *p_sys->ms, default_live555_callback, time, -1, 1 );
 
                 if( !wait_Live555_response( p_demux ) )
diff --git a/modules/demux/mpeg/h264.c b/modules/demux/mpeg/h264.c
index b467235..ef7cce0 100644
--- a/modules/demux/mpeg/h264.c
+++ b/modules/demux/mpeg/h264.c
@@ -34,6 +34,8 @@
 #include <vlc_demux.h>
 #include <vlc_codec.h>
 
+//#define ENABLE_MMNK_DEBUG_LOGS
+
 /*****************************************************************************
  * Module descriptor
  *****************************************************************************/
@@ -142,8 +144,15 @@ static int Demux( demux_t *p_demux)
     demux_sys_t *p_sys = p_demux->p_sys;
     block_t *p_block_in, *p_block_out;
 
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+    fprintf(stderr, "\nmmnk - Demux-1\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS   
+
     if( ( p_block_in = stream_Block( p_demux->s, H264_PACKET_SIZE ) ) == NULL )
     {
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+    fprintf(stderr, "\nmmnk - Demux-2\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS   
         return 0;
     }
 
@@ -153,14 +162,23 @@ static int Demux( demux_t *p_demux)
 
     while( (p_block_out = p_sys->p_packetizer->pf_packetize( p_sys->p_packetizer, &p_block_in )) )
     {
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+    fprintf(stderr, "\nmmnk - Demux-3\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS   
         while( p_block_out )
         {
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+    fprintf(stderr, "\nmmnk - Demux-4\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS   
             block_t *p_next = p_block_out->p_next;
 
             p_block_out->p_next = NULL;
 
             if( p_sys->p_es == NULL )
             {
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+    fprintf(stderr, "\nmmnk - Demux-5\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS   
                 p_sys->p_packetizer->fmt_out.b_packetized = true;
                 p_sys->p_es = es_out_Add( p_demux->out, &p_sys->p_packetizer->fmt_out);
             }
diff --git a/modules/misc/rtsp.c b/modules/misc/rtsp.c
index 37d8758..d6c3f72 100644
--- a/modules/misc/rtsp.c
+++ b/modules/misc/rtsp.c
@@ -193,6 +193,12 @@ typedef enum
     RTSP_CMD_TYPE_SEEK,
     RTSP_CMD_TYPE_REWIND,
     RTSP_CMD_TYPE_FORWARD,
+// mmnk - fix for rate speed control
+// mmnk-START
+#if 1
+    RTSP_CMD_TYPE_SCALE,
+#endif 
+// mmnk-END
 
     RTSP_CMD_TYPE_ADD,
     RTSP_CMD_TYPE_DEL,
@@ -840,6 +846,17 @@ static void* CommandThread( void *obj )
             vod_MediaControl( p_vod, p_media, cmd.psz_session,
                               VOD_MEDIA_FORWARD, cmd.f_arg );
             break;
+// mmnk - fix for rate speed control
+// mmnk-START
+#if 1
+        case RTSP_CMD_TYPE_SCALE:
+	    fprintf(stderr, "\nmmnk - rtsp.c changes - case RTSP_CMD_TYPE_SCALE \n");
+	
+            vod_MediaControl( p_vod, p_media, cmd.psz_session,
+                              VOD_MEDIA_RATE, (int)cmd.f_arg );
+            break;
+#endif 
+// mmnk-END
 
         default:
             break;
@@ -939,6 +956,12 @@ static int RtspCallback( httpd_callback_sys_t *p_args, httpd_client_t *cl,
     const char *psz_cseq = NULL;
     rtsp_client_t *p_rtsp;
     int i_cseq = 0;
+// mmnk - fix for rate speed control
+// mmnk-START
+#if 1
+    double f_scale = 0;
+#endif 
+// mmnk-END
 
     if( answer == NULL || query == NULL ) return VLC_SUCCESS;
 
@@ -1104,14 +1127,26 @@ static int RtspCallback( httpd_callback_sys_t *p_args, httpd_client_t *cl,
                     CommandPush( p_vod, RTSP_CMD_TYPE_SEEK, p_media,
                                  psz_session, i_time, 0.0, NULL );
                 }
+// mmnk - fix for rate speed control
+// mmnk-START
+#if 0
                 else if( psz_scale )
                 {
                     double f_scale = 0.0;
+#else
+                else if( psz_scale && psz_scale[0] != '-' ) /* TODO handle negative values */
+                {
+#endif
+// mmnk-END
                     char *end;
+		    fprintf(stderr, "\nmmnk - rtsp.c changes - else if( psz_scale && psz_scale[0]... \n");
 
                     f_scale = us_strtod( psz_scale, &end );
                     if( end > psz_scale )
                     {
+// mmnk - fix for rate speed control
+// mmnk-START
+#if 0
                         f_scale = (f_scale * 30.0);
                         if( psz_scale[0] == '-' ) /* rewind */
                         {
@@ -1126,6 +1161,16 @@ static int RtspCallback( httpd_callback_sys_t *p_args, httpd_client_t *cl,
                             CommandPush( p_vod, RTSP_CMD_TYPE_FORWARD, p_media,
                                          psz_session, 0, f_scale, NULL );
                         }
+#else
+                        //Convert RTSP rate (multiple of 1) to VLC rate
+                        double f_vlc_scale = ( 1.0 / f_scale ) * INPUT_RATE_DEFAULT;
+                        msg_Dbg( p_vod, "trickplay request: %s",
+                                 psz_scale );
+                        CommandPush( p_vod, RTSP_CMD_TYPE_SCALE, p_media,
+                                    psz_session, 0, f_vlc_scale, NULL );
+		        fprintf(stderr, "\nmmnk - rtsp.c changes - if( end > psz_scale )... \n");
+#endif
+// mmnk-END
                     }
                 }
                 /* unpause, in case it's paused */
@@ -1249,6 +1294,15 @@ static int RtspCallback( httpd_callback_sys_t *p_args, httpd_client_t *cl,
     psz_cseq ? i_cseq = atoi( psz_cseq ) : 0;
     httpd_MsgAdd( answer, "CSeq", "%d", i_cseq );
     httpd_MsgAdd( answer, "Cache-Control", "%s", "no-cache" );
+// mmnk - fix for rate speed control
+// mmnk-START
+#if 1
+    fprintf(stderr, "\nmmnk - rtsp.c changes - if( f_scale != 0 )... \n");
+
+    if( f_scale != 0 )
+        httpd_MsgAdd( answer, "Scale", "%f", f_scale );
+#endif 
+// mmnk-END
 
     if( psz_session )
     {
diff --git a/modules/packetizer/h264.c b/modules/packetizer/h264.c
index a680454..4bf865b 100644
--- a/modules/packetizer/h264.c
+++ b/modules/packetizer/h264.c
@@ -44,6 +44,8 @@
 #include "../codec/cc.h"
 #include "packetizer_helper.h"
 
+//#define ENABLE_MMNK_DEBUG_LOGS
+
 /*****************************************************************************
  * Module descriptor
  *****************************************************************************/
@@ -405,7 +407,9 @@ static void Close( vlc_object_t *p_this )
 static block_t *Packetize( decoder_t *p_dec, block_t **pp_block )
 {
     decoder_sys_t *p_sys = p_dec->p_sys;
-
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+            //fprintf(stderr, "\nmmnk - Packetize-1\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS  
     return packetizer_Packetize( &p_sys->packetizer, pp_block );
 }
 
@@ -421,10 +425,22 @@ static block_t *PacketizeAVC1( decoder_t *p_dec, block_t **pp_block )
     block_t       *p_ret = NULL;
     uint8_t       *p;
 
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+            //fprintf(stderr, "\nmmnk - PacketizeAVC1-1\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS  
+
     if( !pp_block || !*pp_block )
-        return NULL;
+    {
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+            //fprintf(stderr, "\nmmnk - PacketizeAVC1-2\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS          
+	return NULL;
+    }
     if( (*pp_block)->i_flags&(BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) )
     {
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+            fprintf(stderr, "\nmmnk - PacketizeAVC1-3\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS          
         block_Release( *pp_block );
         return NULL;
     }
@@ -447,14 +463,21 @@ static block_t *PacketizeAVC1( decoder_t *p_dec, block_t **pp_block )
         if( i_size <= 0 ||
             i_size > ( p_block->p_buffer + p_block->i_buffer - p ) )
         {
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+            fprintf(stderr, "\nmmnk - PacketizeAVC1-4\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS          
             msg_Err( p_dec, "Broken frame : size %d is too big", i_size );
             break;
         }
 
         block_t *p_part = CreateAnnexbNAL( p_dec, p, i_size );
         if( !p_part )
+        {
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+            fprintf(stderr, "\nmmnk - PacketizeAVC1-5\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS          
             break;
-
+        }
         p_part->i_dts = p_block->i_dts;
         p_part->i_pts = p_block->i_pts;
 
@@ -463,10 +486,22 @@ static block_t *PacketizeAVC1( decoder_t *p_dec, block_t **pp_block )
         {
             block_ChainAppend( &p_ret, p_pic );
         }
+        else
+        {
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+            fprintf(stderr, "\nmmnk - PacketizeAVC1-6\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS          
+        }
+
         p += i_size;
     }
     block_Release( p_block );
 
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+	if (p_ret == NULL)
+            fprintf(stderr, "\nmmnk - PacketizeAVC1-6-p_ret=%x\n", p_ret);	
+#endif // ENABLE_MMNK_DEBUG_LOGS       
+
     return p_ret;
 }
 
diff --git a/modules/stream_out/rtp.h b/modules/stream_out/rtp.h
index adb37b2..daca484 100644
--- a/modules/stream_out/rtp.h
+++ b/modules/stream_out/rtp.h
@@ -98,6 +98,15 @@ int vod_check_range(vod_media_t *p_media, const char *psz_session,
 void vod_play(vod_media_t *p_media, const char *psz_session,
               int64_t *start, int64_t end);
 void vod_pause(vod_media_t *p_media, const char *psz_session, int64_t *npt);
+
+// mmnk - fix for rate speed control
+// mmnk-START
+#if 1
+void vod_setrate(vod_media_t *p_media, const char *psz_session, float rate);
+int vod_getlength(vod_media_t *p_media);
+#endif
+// mmnk-END
+
 void vod_stop(vod_media_t *p_media, const char *psz_session);
 
 const char *vod_get_mux(const vod_media_t *p_media);
diff --git a/modules/stream_out/rtpfmt.c b/modules/stream_out/rtpfmt.c
index 79ae441..a182474 100644
--- a/modules/stream_out/rtpfmt.c
+++ b/modules/stream_out/rtpfmt.c
@@ -56,6 +56,8 @@ static int rtp_packetize_xiph (sout_stream_id_t *, block_t *);
 
 #define XIPH_IDENT (0)
 
+//#define ENABLE_MMNK_DEBUG_LOGS
+
 /* Helpers common to xiph codecs (vorbis and theora) */
 
 static int rtp_xiph_pack_headers(size_t room, void *p_extra, size_t i_extra,
@@ -1059,8 +1061,17 @@ rtp_packetize_h264_nal( sout_stream_id_t *id,
     int i_nal_hdr;
     int i_nal_type;
 
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+    fprintf(stderr, "\nmmnk - rtp_packetize_h264_nal - entry\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS 
+
     if( i_data < 5 )
+    {
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+    fprintf(stderr, "\nmmnk - rtp_packetize_h264_nal - 0\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS 
         return VLC_SUCCESS;
+    }
 
     i_nal_hdr = p_data[3];
     i_nal_type = i_nal_hdr&0x1f;
@@ -1072,6 +1083,10 @@ rtp_packetize_h264_nal( sout_stream_id_t *id,
     /* */
     if( i_data <= i_max )
     {
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+       fprintf(stderr, "\nmmnk - rtp_packetize_h264_nal - 1\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS 
+
         /* Single NAL unit packet */
         block_t *out = block_Alloc( 12 + i_data );
         out->i_dts    = i_dts;
@@ -1091,6 +1106,10 @@ rtp_packetize_h264_nal( sout_stream_id_t *id,
         const int i_count = ( i_data-1 + i_max-2 - 1 ) / (i_max-2);
         int i;
 
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+       fprintf(stderr, "\nmmnk - rtp_packetize_h264_nal - 2\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS 
+
         p_data++;
         i_data--;
 
@@ -1101,6 +1120,10 @@ rtp_packetize_h264_nal( sout_stream_id_t *id,
             out->i_dts    = i_dts + i * i_length / i_count;
             out->i_length = i_length / i_count;
 
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+            fprintf(stderr, "\nmmnk - rtp_packetize_h264_nal - 3\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS 
+
             /* */
             rtp_packetize_common( id, out, (b_last && i_payload == i_data),
                                     i_pts );
@@ -1118,6 +1141,9 @@ rtp_packetize_h264_nal( sout_stream_id_t *id,
             p_data += i_payload;
         }
     }
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+    fprintf(stderr, "\nmmnk - rtp_packetize_h264_nal - exit\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS 
     return VLC_SUCCESS;
 }
 
@@ -1126,8 +1152,15 @@ static int rtp_packetize_h264( sout_stream_id_t *id, block_t *in )
     const uint8_t *p_buffer = in->p_buffer;
     int i_buffer = in->i_buffer;
 
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+    fprintf(stderr, "\nmmnk - rtp_packetize_h264 - entry\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS 
+
     while( i_buffer > 4 && ( p_buffer[0] != 0 || p_buffer[1] != 0 || p_buffer[2] != 1 ) )
     {
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+    fprintf(stderr, "\nmmnk - rtp_packetize_h264 - 1A\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS 
         i_buffer--;
         p_buffer++;
     }
@@ -1139,11 +1172,19 @@ static int rtp_packetize_h264( sout_stream_id_t *id, block_t *in )
         int i_size = i_buffer;
         int i_skip = i_buffer;
 
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+        fprintf(stderr, "\nmmnk - rtp_packetize_h264 - 1B\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS 
+
         /* search nal end */
         for( i_offset = 4; i_offset+2 < i_buffer ; i_offset++)
         {
             if( p_buffer[i_offset] == 0 && p_buffer[i_offset+1] == 0 && p_buffer[i_offset+2] == 1 )
             {
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+                fprintf(stderr, "\nmmnk - rtp_packetize_h264 - 2\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS 
+
                 /* we found another startcode */
                 i_size = i_offset - ( p_buffer[i_offset-1] == 0 ? 1 : 0);
                 i_skip = i_offset;
@@ -1158,6 +1199,11 @@ static int rtp_packetize_h264( sout_stream_id_t *id, block_t *in )
         i_buffer -= i_skip;
         p_buffer += i_skip;
     }
+
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+    fprintf(stderr, "\nmmnk - rtp_packetize_h264 - exit\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS 
+
     return VLC_SUCCESS;
 }
 
diff --git a/modules/stream_out/rtsp.c b/modules/stream_out/rtsp.c
index 2f9569a..56fe354 100644
--- a/modules/stream_out/rtsp.c
+++ b/modules/stream_out/rtsp.c
@@ -34,6 +34,14 @@
 #include <vlc_common.h>
 #include <vlc_sout.h>
 
+// mmnk - fix for rate speed control
+// mmnk-START
+#if 1
+#include <vlc_input.h>
+#include <vlc_vod.h>
+#endif
+// mmnk-END
+
 #include <vlc_httpd.h>
 #include <vlc_url.h>
 #include <vlc_charset.h>
@@ -54,6 +62,8 @@
 
 #include "rtp.h"
 
+//#define ENABLE_MMNK_DEBUG_LOGS
+
 typedef struct rtsp_session_t rtsp_session_t;
 
 struct rtsp_stream_t
@@ -944,10 +954,14 @@ static int RtspHandler( rtsp_stream_t *rtsp, rtsp_stream_id_t *id,
             psz_session = httpd_MsgGet( query, "Session" );
             int64_t start = -1, end = -1, npt;
             const char *range = httpd_MsgGet (query, "Range");
+
+	    //fprintf(stderr, "\nmmnk - HTTPD_MSG_PLAY-1 - range = %s\n", range);
+
             if (range != NULL)
             {
                 if (strncmp (range, "npt=", 4))
                 {
+		    //fprintf(stderr, "\nmmnk - HTTPD_MSG_PLAY-1 - answer->i_status = 501\n");
                     answer->i_status = 501;
                     break;
                 }
@@ -959,6 +973,7 @@ static int RtspHandler( rtsp_stream_t *rtsp, rtsp_stream_id_t *id,
 
                 if (end >= 0 && end < start)
                 {
+		    //fprintf(stderr, "\nmmnk - HTTPD_MSG_PLAY-1 - answer->i_status = 457\n");
                     answer->i_status = 457;
                     break;
                 }
@@ -968,6 +983,7 @@ static int RtspHandler( rtsp_stream_t *rtsp, rtsp_stream_id_t *id,
                     if (vod_check_range(rtsp->vod_media, psz_session,
                                         start, end) != VLC_SUCCESS)
                     {
+			//fprintf(stderr, "\nmmnk - HTTPD_MSG_PLAY-2 - answer->i_status = 457\n");
                         answer->i_status = 457;
                         break;
                     }
@@ -976,6 +992,7 @@ static int RtspHandler( rtsp_stream_t *rtsp, rtsp_stream_id_t *id,
                  * that already started */
                 else if (start > 0 || end >= 0)
                 {
+		    //fprintf(stderr, "\nmmnk - HTTPD_MSG_PLAY-1 - answer->i_status = 456\n");
                     answer->i_status = 456;
                     break;
                 }
@@ -990,6 +1007,8 @@ static int RtspHandler( rtsp_stream_t *rtsp, rtsp_stream_id_t *id,
                 size_t infolen = 0;
                 RtspClientAlive(ses);
 
+		//fprintf(stderr, "\nmmnk - HTTPD_MSG_PLAY-3 \n");
+
                 sout_stream_id_t *sout_id = NULL;
                 if (vod)
                 {
@@ -999,42 +1018,63 @@ static int RtspHandler( rtsp_stream_t *rtsp, rtsp_stream_id_t *id,
                     {
                         sout_id = ses->trackv[i].sout_id;
                         if (sout_id != NULL)
+			{
+			    //fprintf(stderr, "\nmmnk - HTTPD_MSG_PLAY-4 \n");
                             break;
+			}
                     }
                 }
                 int64_t ts = rtp_get_ts(vod ? NULL : (sout_stream_t *)owner,
                                         sout_id, rtsp->vod_media, psz_session,
                                         vod ? NULL : &npt);
 
+		//fprintf(stderr, "\nmmnk - HTTPD_MSG_PLAY-4 - ts = %ld \n", ts);
+		//fprintf(stderr, "\nmmnk - HTTPD_MSG_PLAY-4 - ses->trackc = %d \n", ses->trackc);
+
                 for( int i = 0; i < ses->trackc; i++ )
                 {
                     rtsp_strack_t *tr = ses->trackv + i;
+
+		    //fprintf(stderr, "\nmmnk - HTTPD_MSG_PLAY-5 \n");
+
                     if( ( id == NULL ) || ( tr->id == id ) )
                     {
                         if (tr->setup_fd == -1)
+			{
+			    //fprintf(stderr, "\nmmnk - HTTPD_MSG_PLAY-6 \n");
                             /* Track not SETUP */
                             continue;
+			}
 
                         uint16_t seq;
                         if( tr->rtp_fd == -1 )
                         {
+			    //fprintf(stderr, "\nmmnk - HTTPD_MSG_PLAY-7 \n");
+
                             /* Track not PLAYing yet */
                             if (tr->sout_id == NULL)
+			    {
+				//fprintf(stderr, "\nmmnk - HTTPD_MSG_PLAY-8 \n");
                                 /* Instance not running yet (VoD) */
                                 seq = tr->seq_init;
+			    }
                             else
                             {
                                 /* Instance running, add a sink to it */
                                 tr->rtp_fd = dup_socket(tr->setup_fd);
                                 if (tr->rtp_fd == -1)
+				{
+				    //fprintf(stderr, "\nmmnk - HTTPD_MSG_PLAY-8a \n");
                                     continue;
-
+				}
                                 rtp_add_sink( tr->sout_id, tr->rtp_fd,
                                               false, &seq );
                             }
                         }
                         else
                         {
+			    //fprintf(stderr, "\nmmnk - HTTPD_MSG_PLAY-7a -  tr->sout_id = %d\n",  tr->sout_id);
+
                             /* Track already playing */
                             assert( tr->sout_id != NULL );
                             seq = rtp_get_seq( tr->sout_id );
@@ -1055,6 +1095,9 @@ static int RtspHandler( rtsp_stream_t *rtsp, rtsp_stream_id_t *id,
             }
             vlc_mutex_unlock( &rtsp->lock );
 
+// mmnk - fix for rate speed control
+// mmnk-START
+#if 0
             if (ses != NULL)
             {
                 if (vod)
@@ -1067,9 +1110,72 @@ static int RtspHandler( rtsp_stream_t *rtsp, rtsp_stream_id_t *id,
                 httpd_MsgAdd( answer, "Range", "npt=%f-", f_npt );
             }
 
-            if( httpd_MsgGet( query, "Scale" ) != NULL )
-                httpd_MsgAdd( answer, "Scale", "1." );
-            break;
+	    const char *psz_scale = httpd_MsgGet( query, "Scale" );
+	    if( psz_scale != NULL )
+	    {
+		httpd_MsgAdd( answer, "Scale", "1." );
+	    }
+#else   
+            if (ses != NULL)
+            {
+                if (vod)
+		{
+			const char *psz_scale = httpd_MsgGet( query, "Scale" );
+			if( psz_scale != NULL )
+			{
+		                char *end_t;
+			        double f_scale = us_strtod(psz_scale, &end_t);
+				double f_vlc_scale; 
+			        
+				// Set scale to integer 
+				f_scale = (int)f_scale;
+
+				// Use scale = 3 as rewind
+				if(f_scale == 3.0)
+				{	
+					f_scale = -1.0;
+					//psz_scale = "-1.0";
+					psz_scale = "1.0";
+				}
+
+				// Set max and min limit
+				if(f_scale > 4.0)
+				{	
+					f_scale = 4.0;
+					psz_scale = "4.0";
+				}
+				if(f_scale < 1.0 && f_scale != -1.0)
+				{	
+					f_scale = 1.0;
+					psz_scale = "1.0";
+				}
+
+				f_vlc_scale = f_scale;
+			
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+				fprintf(stderr, "\nmmnk - f_scale = %f \n", f_scale);	
+				fprintf(stderr, "\nmmnk - f_vlc_scale = %f \n", f_vlc_scale);	
+				fprintf(stderr, "\nmmnk - psz_scale = %s\n", psz_scale);	
+#endif // ENABLE_MMNK_DEBUG_LOGS
+
+				//vod_MediaControl(rtsp->vod_media->p_vod, rtsp->vod_media, psz_session,
+		                //      VOD_MEDIA_RATE, (int)f_vlc_scale );			
+				vod_setrate(rtsp->vod_media, psz_session, (float)f_vlc_scale*1000);
+
+				httpd_MsgAdd( answer, "Scale", psz_scale );
+			}
+
+			vod_play(rtsp->vod_media, psz_session, &start, end);
+		        npt = start;
+		}
+
+	        double f_npt = (double) npt / CLOCK_FREQ;
+	        httpd_MsgAdd( answer, "Range", "npt=%f-", f_npt );
+            }
+#endif
+// mmnk-END
+            
+	    break;
         }
 
         case HTTPD_MSG_PAUSE:
diff --git a/modules/stream_out/vod.c b/modules/stream_out/vod.c
index dd611d5..c39caa2 100644
--- a/modules/stream_out/vod.c
+++ b/modules/stream_out/vod.c
@@ -45,6 +45,8 @@
 
 #include "rtp.h"
 
+//#define ENABLE_MMNK_DEBUG_LOGS
+
 /*****************************************************************************
  * Exported prototypes
  *****************************************************************************/
@@ -160,6 +162,13 @@ int OpenVoD( vlc_object_t *p_this )
         goto error;
     }
 
+// mmnk-START: Fix for fast rewind
+#ifdef FAST_REWIND_USING_SEEK
+    p_vod->i_rwd_rate = 0;
+    p_vod->i_rwd_thrd_exist = 0;
+#endif // FAST_REWIND_USING_SEEK
+// mmnk-END: Fix for fast rewind
+
     return VLC_SUCCESS;
 
 error:
@@ -184,6 +193,21 @@ void CloseVoD( vlc_object_t * p_this )
     vlc_cancel( p_sys->thread );
     vlc_join( p_sys->thread, NULL );
 
+// mmnk-START: Fix for fast rewind
+#ifdef FAST_REWIND_USING_SEEK
+    if(p_vod->i_rwd_thrd_exist == 1)
+    {
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+	fprintf(stderr, "\nmmnk - FAST_REWIND thread kill in close VOD\n");		
+#endif // ENABLE_MMNK_DEBUG_LOGS    	
+	vlc_cancel( p_vod->thread );
+	vlc_join( p_vod->thread, NULL );
+        p_vod->i_rwd_thrd_exist = 0;
+        p_vod->i_rwd_rate = 0;
+    }
+#endif // FAST_REWIND_USING_SEEK
+// mmnk-END: Fix for fast rewind
+
     while( block_FifoCount( p_sys->p_fifo_cmd ) > 0 )
     {
         rtsp_cmd_t cmd;
@@ -472,6 +496,45 @@ int vod_check_range(vod_media_t *p_media, const char *psz_session,
     return VLC_SUCCESS;
 }
 
+// mmnk-START: Fix for fast rewind
+#ifdef FAST_REWIND_USING_SEEK
+static void* FastRwdThread( void *obj )
+{
+    vod_t    *p_vod = (vod_t *)obj;
+    int64_t  moviepos, moviepos_t;
+    float    rspeed;
+    int      sleept=100;
+    
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+    fprintf(stderr, "\nmmnk - FastRwdThread entry\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS    	
+
+    moviepos_t = moviepos = p_vod->i_start;
+    rspeed   = p_vod->i_rwd_rate * -1;
+    
+    vod_MediaControl(p_vod, p_vod->p_media, &p_vod->p_psz_session[0], VOD_MEDIA_PAUSE, &moviepos);
+
+    do { 
+	usleep (sleept*1000); /* Let it play a bit */
+	vod_MediaControl(p_vod, p_vod->p_media, &p_vod->p_psz_session[0], VOD_MEDIA_PLAY, "vod", &moviepos_t);
+        vod_MediaControl(p_vod, p_vod->p_media, &p_vod->p_psz_session[0], VOD_MEDIA_PAUSE, &moviepos_t);
+	moviepos_t = moviepos = moviepos - (sleept*rspeed*1000);
+//#ifdef ENABLE_MMNK_DEBUG_LOGS
+	fprintf(stderr, "\nmmnk - moviepos = %ld\n", moviepos);	
+//#endif // ENABLE_MMNK_DEBUG_LOGS    	
+    } while(moviepos > 0);
+
+    vod_setrate(p_vod->p_media, &p_vod->p_psz_session[0], 1000.0);
+    p_vod->i_rwd_rate = 0;
+    p_vod->i_rwd_thrd_exist = 0;
+
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+    fprintf(stderr, "\nmmnk - FastRwdThread exit\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS    	
+}
+#endif // FAST_REWIND_USING_SEEK
+// mmnk-END: Fix for fast rewind
+
 /* TODO: add support in the VLM for queueing proper PLAY requests with
  * start and end times, fetch whether the input is seekable... and then
  * clean this up */
@@ -481,19 +544,128 @@ void vod_play(vod_media_t *p_media, const char *psz_session,
     if (vod_check_range(p_media, psz_session, *start, end) != VLC_SUCCESS)
         return;
 
+// mmnk-START: Fix for fast rewind
+#ifdef FAST_REWIND_USING_SEEK
+    if(p_media->p_vod->i_rwd_thrd_exist == 1)
+    {
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+	fprintf(stderr, "\nmmnk - FAST_REWIND thread kill in play\n");		
+#endif // ENABLE_MMNK_DEBUG_LOGS    	
+	vlc_cancel( p_media->p_vod->thread );
+	vlc_join( p_media->p_vod->thread, NULL );
+        //vod_setrate(p_media, psz_session, 1000.0);
+        p_media->p_vod->i_rwd_thrd_exist = 0;
+    }
+#endif // FAST_REWIND_USING_SEEK
+// mmnk-END: Fix for fast rewind
+
     /* We're passing the #vod{} sout chain here */
     vod_MediaControl(p_media->p_vod, p_media, psz_session,
                      VOD_MEDIA_PLAY, "vod", start);
+
+// mmnk-START: Fix for fast rewind
+#ifdef FAST_REWIND_USING_SEEK
+    if(p_media->p_vod->i_rwd_rate < 0 && p_media->p_vod->i_rwd_thrd_exist == 0)
+    {
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+	fprintf(stderr, "\nmmnk - FAST_REWIND_USING_SEEK - 1\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS    	
+        p_media->p_vod->p_media = p_media;
+        strcpy(&p_media->p_vod->p_psz_session[0], psz_session);
+        p_media->p_vod->i_start = *start;
+    	vlc_clone( &p_media->p_vod->thread, FastRwdThread, p_media->p_vod, VLC_THREAD_PRIORITY_LOW );
+        p_media->p_vod->i_rwd_thrd_exist = 1;
+    }
+#endif // FAST_REWIND_USING_SEEK
+// mmnk-END: Fix for fast rewind
 }
 
 void vod_pause(vod_media_t *p_media, const char *psz_session, int64_t *npt)
 {
+// mmnk-START: Fix for fast rewind
+#ifdef FAST_REWIND_USING_SEEK    
+    if(p_media->p_vod->i_rwd_thrd_exist == 1)
+    {
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+	fprintf(stderr, "\nmmnk - FAST_REWIND thread kill in pause\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS    	
+	vlc_cancel( p_media->p_vod->thread );
+	vlc_join( p_media->p_vod->thread, NULL );
+        vod_setrate(p_media, psz_session, 1000.0);
+        p_media->p_vod->i_rwd_thrd_exist = 0;
+        p_media->p_vod->i_rwd_rate = 0;
+    }
+#endif // FAST_REWIND_USING_SEEK
+// mmnk-END: Fix for fast rewind
+
     vod_MediaControl(p_media->p_vod, p_media, psz_session,
                      VOD_MEDIA_PAUSE, npt);
 }
 
+// mmnk - fix for rate speed control
+// mmnk-START
+#if 1
+void vod_setrate(vod_media_t *p_media, const char *psz_session, float rate)
+{
+// mmnk-START: Fix for fast rewind
+#ifdef FAST_REWIND_USING_SEEK
+    if(rate > 0)
+    {	
+	    if(p_media->p_vod->i_rwd_thrd_exist == 1)
+	    {
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+		fprintf(stderr, "\nmmnk - FAST_REWIND thread kill in set rate\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS    	
+		vlc_cancel( p_media->p_vod->thread );
+		vlc_join( p_media->p_vod->thread, NULL );
+		//vod_setrate(p_media, psz_session, 1000.0);
+		p_media->p_vod->i_rwd_thrd_exist = 0;
+		p_media->p_vod->i_rwd_rate = 0;
+	   }
+
+    	vod_MediaControl(p_media->p_vod, p_media, psz_session, VOD_MEDIA_RATE, (int)rate);
+        p_media->p_vod->i_rwd_rate = 0;
+    }
+    else
+    {	
+	p_media->p_vod->i_rwd_rate = rate/1000;
+    }
+
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+    fprintf(stderr, "\nmmnk - p_media->p_vod->i_rwd_rate = %d \n", p_media->p_vod->i_rwd_rate);	
+#endif // ENABLE_MMNK_DEBUG_LOGS    	
+
+#else // FAST_REWIND_USING_SEEK
+    vod_MediaControl(p_media->p_vod, p_media, psz_session, VOD_MEDIA_RATE, (int)rate);
+#endif // FAST_REWIND_USING_SEEK
+// mmnk-END: Fix for fast rewind
+}
+
+int vod_getlength(vod_media_t *p_media)
+{
+    return p_media->i_length;
+}
+#endif
+// mmnk-END
+
 void vod_stop(vod_media_t *p_media, const char *psz_session)
 {
+// mmnk-START: Fix for fast rewind
+#ifdef FAST_REWIND_USING_SEEK    
+    if(p_media->p_vod->i_rwd_thrd_exist == 1)
+    {
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+	fprintf(stderr, "\nmmnk - FAST_REWIND thread kill in stop\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS    	
+	vlc_cancel( p_media->p_vod->thread );
+	vlc_join( p_media->p_vod->thread, NULL );
+        vod_setrate(p_media, psz_session, 1000.0);
+        p_media->p_vod->i_rwd_thrd_exist = 0;
+        p_media->p_vod->i_rwd_rate = 0;
+    }
+#endif // FAST_REWIND_USING_SEEK
+// mmnk-END: Fix for fast rewind
+
     CommandPush(p_media->p_vod, RTSP_CMD_TYPE_STOP, p_media, psz_session);
 }
 
diff --git a/src/input/decoder.c b/src/input/decoder.c
index 10298b0..f536961 100644
--- a/src/input/decoder.c
+++ b/src/input/decoder.c
@@ -53,6 +53,8 @@
 
 #include "../video_output/vout_control.h"
 
+//#define ENABLE_MMNK_DEBUG_LOGS
+
 static decoder_t *CreateDecoder( vlc_object_t *, input_thread_t *,
                                  es_format_t *, bool, input_resource_t *,
                                  sout_instance_t *p_sout );
@@ -386,12 +388,20 @@ void input_DecoderDecode( decoder_t *p_dec, block_t *p_block, bool b_do_pace )
 
     if( b_do_pace )
     {
-        /* The fifo is not consummed when buffering and so will
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+                fprintf(stderr, "\nmmnk - input_DecoderDecode-1\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS         
+       /* The fifo is not consummed when buffering and so will
          * deadlock vlc.
          * There is no need to lock as b_buffering is never modify
          * inside decoder thread. */
         if( !p_owner->b_buffering )
+        {
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+                fprintf(stderr, "\nmmnk - input_DecoderDecode-2\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS         
             block_FifoPace( p_owner->p_fifo, 10, SIZE_MAX );
+        }
     }
 #ifdef __arm__
     else if( block_FifoSize( p_owner->p_fifo ) > 50*1024*1024 /* 50 MiB */ )
@@ -399,6 +409,9 @@ void input_DecoderDecode( decoder_t *p_dec, block_t *p_block, bool b_do_pace )
     else if( block_FifoSize( p_owner->p_fifo ) > 400*1024*1024 /* 400 MiB, ie ~ 50mb/s for 60s */ )
 #endif
     {
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+                fprintf(stderr, "\nmmnk - input_DecoderDecode-3\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS         
         /* FIXME: ideally we would check the time amount of data
          * in the FIFO instead of its size. */
         msg_Warn( p_dec, "decoder/packetizer fifo full (data not "
@@ -406,6 +419,9 @@ void input_DecoderDecode( decoder_t *p_dec, block_t *p_block, bool b_do_pace )
         block_FifoEmpty( p_owner->p_fifo );
     }
 
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+                fprintf(stderr, "\nmmnk - input_DecoderDecode-4\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS         
     block_FifoPut( p_owner->p_fifo, p_block );
 }
 
@@ -1687,6 +1703,9 @@ static void DecoderPlaySout( decoder_t *p_dec, block_t *p_sout_block,
 
         if( p_owner->b_buffering )
         {
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+            fprintf(stderr, "\nmmnk - DecoderPlaySout-1\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS   
             vlc_mutex_unlock( &p_owner->lock );
             return;
         }
@@ -1711,12 +1730,28 @@ static void DecoderPlaySout( decoder_t *p_dec, block_t *p_sout_block,
         vlc_mutex_unlock( &p_owner->lock );
 
         if( !b_reject )
+        {
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+            fprintf(stderr, "\nmmnk - DecoderPlaySout-2\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS   
             sout_InputSendBuffer( p_owner->p_sout_input, p_sout_block ); // FIXME --VLC_TS_INVALID inspect stream_output/*
+        }   
         else
-            block_Release( p_sout_block );
+        {
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+            fprintf(stderr, "\nmmnk - DecoderPlaySout-3\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS   
+    	    block_Release( p_sout_block );
+        }
 
         if( !b_has_more )
+        {
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+            fprintf(stderr, "\nmmnk - DecoderPlaySout-4\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS   
             break;
+        }
+        
         vlc_mutex_lock( &p_owner->lock );
         if( !p_owner->buffer.p_block )
         {
@@ -1814,12 +1849,19 @@ static void DecoderProcessSout( decoder_t *p_dec, block_t *p_block )
 
             if( p_owner->p_sout_input == NULL )
             {
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+            fprintf(stderr, "\nmmnk - DecoderProcessSout-1\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS   
+
                 msg_Err( p_dec, "cannot create packetizer output (%4.4s)",
                          (char *)&p_owner->sout.i_codec );
                 p_dec->b_error = true;
 
                 while( p_sout_block )
                 {
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+            fprintf(stderr, "\nmmnk - DecoderProcessSout-2\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS   
                     block_t *p_next = p_sout_block->p_next;
                     block_Release( p_sout_block );
                     p_sout_block = p_next;
diff --git a/src/input/demux.c b/src/input/demux.c
index e44df63..40cb5c3 100644
--- a/src/input/demux.c
+++ b/src/input/demux.c
@@ -32,6 +32,8 @@
 #include <vlc_url.h>
 #include <vlc_modules.h>
 
+//#define ENABLE_MMNK_DEBUG_LOGS
+
 static bool SkipID3Tag( demux_t * );
 static bool SkipAPETag( demux_t *p_demux );
 
@@ -283,13 +285,22 @@ int demux_vaControlHelper( stream_t *s,
 
 
         case DEMUX_SET_POSITION:
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+            fprintf(stderr, "\nmmnk - DEMUX_SET_POSITION-1\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS   
             f = (double)va_arg( args, double );
             if( i_start < i_end && f >= 0.0 && f <= 1.0 )
             {
                 int64_t i_block = (f * ( i_end - i_start )) / i_align;
 
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+                fprintf(stderr, "\nmmnk - DEMUX_SET_POSITION-2\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS   
                 if( stream_Seek( s, i_start + i_block * i_align ) )
                 {
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+                    fprintf(stderr, "\nmmnk - DEMUX_SET_POSITION-3\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS   
                     return VLC_EGENERIC;
                 }
                 return VLC_SUCCESS;
@@ -297,12 +308,21 @@ int demux_vaControlHelper( stream_t *s,
             return VLC_EGENERIC;
 
         case DEMUX_SET_TIME:
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+            fprintf(stderr, "\nmmnk - DEMUX_SET_TIME-1\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS   
             i64 = (int64_t)va_arg( args, int64_t );
             if( i_bitrate > 0 && i64 >= 0 )
             {
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+                fprintf(stderr, "\nmmnk - DEMUX_SET_TIME-2\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS   
                 int64_t i_block = i64 * i_bitrate / INT64_C(8000000) / i_align;
                 if( stream_Seek( s, i_start + i_block * i_align ) )
                 {
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+                    fprintf(stderr, "\nmmnk - DEMUX_SET_TIME-3\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS   
                     return VLC_EGENERIC;
                 }
                 return VLC_SUCCESS;
diff --git a/src/input/es_out.c b/src/input/es_out.c
index 9ae8b36..e473147 100644
--- a/src/input/es_out.c
+++ b/src/input/es_out.c
@@ -53,6 +53,8 @@
 /* FIXME we should find a better way than including that */
 #include "../text/iso-639_def.h"
 
+//#define ENABLE_MMNK_DEBUG_LOGS
+
 /*****************************************************************************
  * Local prototypes
  *****************************************************************************/
@@ -1922,6 +1924,10 @@ static int EsOutSend( es_out_t *out, es_out_id_t *es, block_t *p_block )
     input_thread_t *p_input = p_sys->p_input;
     int i_total = 0;
 
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+    //fprintf(stderr, "\nmmnk - EsOutSend-1\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS 
+
     if( libvlc_stats( p_input ) )
     {
         vlc_mutex_lock( &p_input->p->counters.counters_lock );
@@ -1933,12 +1939,18 @@ static int EsOutSend( es_out_t *out, es_out_id_t *es, block_t *p_block )
         /* Update number of corrupted data packats */
         if( p_block->i_flags & BLOCK_FLAG_CORRUPTED )
         {
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+    fprintf(stderr, "\nmmnk - EsOutSend-1A\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS 
             stats_UpdateInteger( p_input, p_input->p->counters.p_demux_corrupted,
                                  1, NULL );
         }
         /* Update number of discontinuities */
         if( p_block->i_flags & BLOCK_FLAG_DISCONTINUITY )
         {
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+    fprintf(stderr, "\nmmnk - EsOutSend-1B\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS 
             stats_UpdateInteger( p_input, p_input->p->counters.p_demux_discontinuity,
                                  1, NULL );
         }
@@ -1951,11 +1963,26 @@ static int EsOutSend( es_out_t *out, es_out_id_t *es, block_t *p_block )
     if( p_sys->i_preroll_end >= 0 )
     {
         int64_t i_date = p_block->i_pts;
+
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+    fprintf(stderr, "\nmmnk - EsOutSend-2\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS 
+
         if( p_block->i_pts <= VLC_TS_INVALID )
+        {
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+    fprintf(stderr, "\nmmnk - EsOutSend-3\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS 
             i_date = p_block->i_dts;
+        }
 
         if( i_date < p_sys->i_preroll_end )
+        {
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+    fprintf(stderr, "\nmmnk - EsOutSend-4\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS 
             p_block->i_flags |= BLOCK_FLAG_PREROLL;
+        } 
     }
 
     if( !es->p_dec )
@@ -1972,12 +1999,18 @@ static int EsOutSend( es_out_t *out, es_out_id_t *es, block_t *p_block )
         if( p_input->p->p_sout->i_out_pace_nocontrol > 0 &&
             p_input->p->b_out_pace_control )
         {
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+    fprintf(stderr, "\nmmnk - EsOutSend-5\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS 
             msg_Dbg( p_input, "switching to sync mode" );
             p_input->p->b_out_pace_control = false;
         }
         else if( p_input->p->p_sout->i_out_pace_nocontrol <= 0 &&
                  !p_input->p->b_out_pace_control )
         {
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+    fprintf(stderr, "\nmmnk - EsOutSend-6\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS 
             msg_Dbg( p_input, "switching to async mode" );
             p_input->p->b_out_pace_control = true;
         }
@@ -2358,10 +2391,14 @@ static int EsOutControlLocked( es_out_t *out, int i_query, va_list args )
 
                     /* Force a rebufferization when we are too late */
 
+// mmnk-START-Fix
+// Avoid reset remove jerk in straming video play
+#if 0 // mmnk
                     /* It is not really good, as we throw away already buffered data
                      * TODO have a mean to correctly reenter bufferization */
                     es_out_Control( out, ES_OUT_RESET_PCR );
-
+#endif // mmnk
+// mmnk-END-Fix
                     es_out_SetJitter( out, i_pts_delay_base, i_pts_delay - i_pts_delay_base, p_sys->i_cr_average );
                 }
             }
@@ -2369,8 +2406,13 @@ static int EsOutControlLocked( es_out_t *out, int i_query, va_list args )
         }
 
         case ES_OUT_RESET_PCR:
+// mmnk-START-Fix
+// Avoid reset remove jerk in straming video play
+#if 0 // mmnk
             msg_Err( p_sys->p_input, "ES_OUT_RESET_PCR called" );
             EsOutChangePosition( out );
+#endif // mmnk
+// mmnk-END-Fix
             return VLC_SUCCESS;
 
         case ES_OUT_SET_GROUP:
diff --git a/src/input/input.c b/src/input/input.c
index f649bd8..dd3161b 100644
--- a/src/input/input.c
+++ b/src/input/input.c
@@ -59,6 +59,8 @@
 #   include <sys/stat.h>
 #endif
 
+//#define ENABLE_MMNK_DEBUG_LOGS
+
 /*****************************************************************************
  * Local prototypes
  *****************************************************************************/
@@ -1844,20 +1846,64 @@ static bool Control( input_thread_t *p_input,
                 }
             }
 
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+	    fprintf(stderr, "\nmmnk - input.c - i_rate = %d\n", i_rate);	
+	    fprintf(stderr, "\nmmnk - input.c - p_input->p->i_rate = %d\n", p_input->p->i_rate);	
+	    fprintf(stderr, "\nmmnk - input.c - p_input->p->b_can_rate_control = %d\n", p_input->p->b_can_rate_control);	
+	    fprintf(stderr, "\nmmnk - input.c - p_input->p->input.b_rescale_ts = %d\n", p_input->p->input.b_rescale_ts);	
+	    fprintf(stderr, "\nmmnk - input.c - p_input->p->b_can_pace_control = %d\n", p_input->p->b_can_pace_control);	
+#endif // ENABLE_MMNK_DEBUG_LOGS
+
             if( i_rate != INPUT_RATE_DEFAULT &&
+// mmnk - fix for rate speed control
+// mmnk-START
+#if 0
                 ( ( !p_input->p->b_can_rate_control && !p_input->p->input.b_rescale_ts ) ||
                   ( p_input->p->p_sout && !p_input->p->b_out_pace_control ) ) )
+#else
+		( !p_input->p->b_can_rate_control && !p_input->p->input.b_rescale_ts ) )
+#endif 
+// mmnk-END
             {
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+	        fprintf(stderr, "\nmmnk - cannot change rate\n");
+#endif // ENABLE_MMNK_DEBUG_LOGS
                 msg_Dbg( p_input, "cannot change rate" );
                 i_rate = INPUT_RATE_DEFAULT;
             }
+
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+	    fprintf(stderr, "\nmmnk - input.c - before if( i_rate != p_input->p->i_rate && ...\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS
+
             if( i_rate != p_input->p->i_rate &&
-                !p_input->p->b_can_pace_control && p_input->p->b_can_rate_control )
+// mmnk - fix for rate speed control
+// mmnk-START
+#if 0
+                  !p_input->p->b_can_pace_control && p_input->p->b_can_rate_control )
+#else
+                  p_input->p->b_can_rate_control )
+#endif 
+// mmnk-END
             {
                 int i_ret;
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+	        fprintf(stderr, "\nmmnk - input.c - after if( i_rate != p_input->p->i_rate && ...\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS
                 if( p_input->p->input.p_access )
                 {
+// mmnk - fix for rate speed control
+// mmnk-START
+#if 0
                     i_ret = VLC_EGENERIC;
+#else
+		    i_ret = VLC_SUCCESS;
+#endif 
+// mmnk-END
+
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+		    fprintf(stderr, "\nmmnk - input.c -  if( p_input->p->input.p_access )...\n");
+#endif // ENABLE_MMNK_DEBUG_LOGS
                 }
                 else
                 {
@@ -1866,17 +1912,31 @@ static bool Control( input_thread_t *p_input,
 
                     i_ret = demux_Control( p_input->p->input.p_demux,
                                             DEMUX_SET_RATE, &i_rate );
+
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+		    fprintf(stderr, "\nmmnk - input.c -  i_ret = demux_Control... i_ret = %d\n", i_ret);
+#endif // ENABLE_MMNK_DEBUG_LOGS
                 }
                 if( i_ret )
                 {
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+		    fprintf(stderr, "\nmmnk - input.c - ACCESS/DEMUX_SET_RATE failed\n");
+#endif // ENABLE_MMNK_DEBUG_LOGS
                     msg_Warn( p_input, "ACCESS/DEMUX_SET_RATE failed" );
                     i_rate = p_input->p->i_rate;
                 }
             }
 
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+            fprintf(stderr, "\nmmnk - input.c - before if( i_rate != p_input->p->i_rate ) ...\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS
             /* */
             if( i_rate != p_input->p->i_rate )
             {
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+	        fprintf(stderr, "\nmmnk - input.c - after if( i_rate != p_input->p->i_rate ) ...\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS
+
                 p_input->p->i_rate = i_rate;
                 input_SendEventRate( p_input, i_rate );
 
diff --git a/src/input/stream.c b/src/input/stream.c
index 1800195..789936f 100644
--- a/src/input/stream.c
+++ b/src/input/stream.c
@@ -39,6 +39,8 @@
 
 #include "input_internal.h"
 
+//#define ENABLE_MMNK_DEBUG_LOGS
+
 // #define STREAM_DEBUG 1
 
 /* TODO:
@@ -598,12 +600,21 @@ static int AStreamControl( stream_t *s, int i_query, va_list args )
             break;
 
         case STREAM_SET_POSITION:
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+            //fprintf(stderr, "\nmmnk - STREAM_SET_POSITION-1\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS 
             i_64 = va_arg( args, uint64_t );
             switch( p_sys->method )
             {
             case STREAM_METHOD_BLOCK:
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+                fprintf(stderr, "\nmmnk - STREAM_SET_POSITION-2\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS 
                 return AStreamSeekBlock( s, i_64 );
             case STREAM_METHOD_STREAM:
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+                //fprintf(stderr, "\nmmnk - STREAM_SET_POSITION-3\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS 
                 return AStreamSeekStream( s, i_64 );
             default:
                 assert(0);
@@ -865,14 +876,25 @@ static int AStreamSeekBlock( stream_t *s, uint64_t i_pos )
         return VLC_SUCCESS;
     }
 
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+    fprintf(stderr, "\nmmnk - AStreamSeekBlock-1\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS 
+
     /* We may need to seek or to read data */
     if( i_offset < 0 )
     {
         bool b_aseek;
         access_Control( p_access, ACCESS_CAN_SEEK, &b_aseek );
 
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+        fprintf(stderr, "\nmmnk - AStreamSeekBlock-2\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS 
+
         if( !b_aseek )
         {
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+            fprintf(stderr, "\nmmnk - AStreamSeekBlock-3\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS 
             msg_Err( s, "backward seeking impossible (access not seekable)" );
             return VLC_EGENERIC;
         }
@@ -886,6 +908,9 @@ static int AStreamSeekBlock( stream_t *s, uint64_t i_pos )
         access_Control( p_access, ACCESS_CAN_SEEK, &b_aseek );
         access_Control( p_access, ACCESS_CAN_FASTSEEK, &b_aseekfast );
 
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+        fprintf(stderr, "\nmmnk - AStreamSeekBlock-4\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS 
         if( !b_aseek )
         {
             b_seek = false;
@@ -897,6 +922,9 @@ static int AStreamSeekBlock( stream_t *s, uint64_t i_pos )
         {
             int64_t i_skip = i_offset - p_sys->block.i_size;
 
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+        fprintf(stderr, "\nmmnk - AStreamSeekBlock-5\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS 
             /* Avg bytes per packets */
             int i_avg = p_sys->stat.i_bytes / p_sys->stat.i_read_count;
             /* TODO compute a seek cost instead of fixed threshold */
@@ -916,6 +944,11 @@ static int AStreamSeekBlock( stream_t *s, uint64_t i_pos )
     if( b_seek )
     {
         int64_t i_start, i_end;
+
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+        fprintf(stderr, "\nmmnk - AStreamSeekBlock-6\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS 
+
         /* Do the access seek */
         i_start = mdate();
         if( ASeek( s, i_pos ) ) return VLC_EGENERIC;
@@ -1126,8 +1159,17 @@ static int AStreamSeekStream( stream_t *s, uint64_t i_pos )
     stream_track_t *p_current = &p_sys->stream.tk[p_sys->stream.i_tk];
     access_t *p_access = p_sys->p_access;
 
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+    //fprintf(stderr, "\nmmnk - AStreamSeekStream-1\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS 
+
     if( p_current->i_start >= p_current->i_end  && i_pos >= p_current->i_end )
+    {
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+        fprintf(stderr, "\nmmnk - AStreamSeekStream-1A\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS 
         return 0; /* EOF */
+    }
 
 #ifdef STREAM_DEBUG
     msg_Dbg( s, "AStreamSeekStream: to %"PRId64" pos=%"PRId64
@@ -1140,14 +1182,25 @@ static int AStreamSeekStream( stream_t *s, uint64_t i_pos )
 
     bool   b_aseek;
     access_Control( p_access, ACCESS_CAN_SEEK, &b_aseek );
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+    //fprintf(stderr, "\nmmnk - AStreamSeekStream-1B-b_aseek = %d\n", b_aseek);	
+#endif // ENABLE_MMNK_DEBUG_LOGS
+ 
     if( !b_aseek && i_pos < p_current->i_start )
     {
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+        fprintf(stderr, "\nmmnk - AStreamSeekStream-2\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS 
+
         msg_Warn( s, "AStreamSeekStream: can't seek" );
         return VLC_EGENERIC;
     }
 
     bool   b_afastseek;
     access_Control( p_access, ACCESS_CAN_FASTSEEK, &b_afastseek );
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+    //fprintf(stderr, "\nmmnk - AStreamSeekStream-1B-b_afastseek = %d\n", b_afastseek);	
+#endif // ENABLE_MMNK_DEBUG_LOGS 
 
     /* FIXME compute seek cost (instead of static 'stupid' value) */
     uint64_t i_skip_threshold;
@@ -1177,8 +1230,12 @@ static int AStreamSeekStream( stream_t *s, uint64_t i_pos )
             stream_track_t *t = &p_sys->stream.tk[i];
 
             if( t->i_start > i_pos || i_pos > t->i_end )
+            {
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+                //fprintf(stderr, "\nmmnk - AStreamSeekStream-3\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS 
                 continue;
-
+            }
             if( !tk || tk->i_end < t->i_end )
             {
                 tk = t;
@@ -1220,7 +1277,13 @@ static int AStreamSeekStream( stream_t *s, uint64_t i_pos )
              * TODO it is stupid to seek now, it would be better to delay it
              */
             if( ASeek( s, tk->i_end ) )
+            {
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+                fprintf(stderr, "\nmmnk - AStreamSeekStream-4\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS 
+
                 return VLC_EGENERIC;
+            }
         }
         else if( i_pos > tk->i_end )
         {
@@ -1229,8 +1292,13 @@ static int AStreamSeekStream( stream_t *s, uint64_t i_pos )
             {
                 const int i_read_max = __MIN( 10 * STREAM_READ_ATONCE, i_skip );
                 if( AStreamReadNoSeekStream( s, NULL, i_read_max ) != i_read_max )
-                    return VLC_EGENERIC;
-                i_skip -= i_read_max;
+                {
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+                        fprintf(stderr, "\nmmnk - AStreamSeekStream-5\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS 
+                	return VLC_EGENERIC;
+		}                
+		i_skip -= i_read_max;
             }
         }
     }
@@ -1239,9 +1307,19 @@ static int AStreamSeekStream( stream_t *s, uint64_t i_pos )
 #ifdef STREAM_DEBUG
         msg_Err( s, "AStreamSeekStream: hard seek" );
 #endif
+
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+        //fprintf(stderr, "\nmmnk - AStreamSeekStream-5A\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS 
+
         /* Nothing good, seek and choose oldest segment */
         if( ASeek( s, i_pos ) )
+        {
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+            fprintf(stderr, "\nmmnk - AStreamSeekStream-6\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS 
             return VLC_EGENERIC;
+        }
 
         tk->i_start = i_pos;
         tk->i_end   = i_pos;
@@ -1261,7 +1339,12 @@ static int AStreamSeekStream( stream_t *s, uint64_t i_pos )
             p_sys->stream.i_used = STREAM_READ_ATONCE / 2;
 
         if( AStreamRefillStream( s ) && i_pos == tk->i_end )
+        {
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+            fprintf(stderr, "\nmmnk - AStreamSeekStream-7\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS 
             return VLC_EGENERIC;
+        }
     }
     return VLC_SUCCESS;
 }
diff --git a/src/input/stream_demux.c b/src/input/stream_demux.c
index adb134b..7b26b84 100644
--- a/src/input/stream_demux.c
+++ b/src/input/stream_demux.c
@@ -30,6 +30,8 @@
 #include <libvlc.h>
 #include <vlc_codec.h>
 
+//#define ENABLE_MMNK_DEBUG_LOGS
+
 /****************************************************************************
  * stream_Demux*: create a demuxer for an outpout stream (allow demuxer chain)
  ****************************************************************************/
@@ -143,6 +145,10 @@ static int DStreamRead( stream_t *s, void *p_read, unsigned int i_read )
     uint8_t *p_out = p_read;
     int i_out = 0;
 
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+    fprintf(stderr, "\nmmnk - DStreamRead-1\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS    
+
     //msg_Dbg( s, "DStreamRead: wanted %d bytes", i_read );
 
     while( vlc_object_alive( s ) && !s->b_error && i_read )
@@ -150,11 +156,18 @@ static int DStreamRead( stream_t *s, void *p_read, unsigned int i_read )
         block_t *p_block = p_sys->p_block;
         int i_copy;
 
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+        fprintf(stderr, "\nmmnk - DStreamRead-2\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS    
+
         if( !p_block )
         {
             p_block = block_FifoGet( p_sys->p_fifo );
             if( !p_block ) s->b_error = 1;
             p_sys->p_block = p_block;
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+            fprintf(stderr, "\nmmnk - DStreamRead-3\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS         
         }
 
         if( p_block && i_read )
@@ -248,15 +261,31 @@ static int DStreamControl( stream_t *s, int i_query, va_list args )
         case STREAM_SET_POSITION:
         {
             uint64_t i64 = va_arg( args, uint64_t );
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+            fprintf(stderr, "\nmmnk - stream_demux - STREAM_SET_POSITION-1\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS 
             if( i64 < p_sys->i_pos )
+            {
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+                fprintf(stderr, "\nmmnk - stream_demux - STREAM_SET_POSITION-2\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS 
                 return VLC_EGENERIC;
+            }
 
             uint64_t i_skip = i64 - p_sys->i_pos;
             while( i_skip > 0 )
             {
                 int i_read = DStreamRead( s, NULL, __MIN(i_skip, INT_MAX) );
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+                fprintf(stderr, "\nmmnk - stream_demux - STREAM_SET_POSITION-3\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS 
                 if( i_read <= 0 )
+                {
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+                    fprintf(stderr, "\nmmnk - stream_demux - STREAM_SET_POSITION-4\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS 
                     return VLC_EGENERIC;
+                }
                 i_skip -= i_read;
             }
             return VLC_SUCCESS;
diff --git a/src/input/vlm.c b/src/input/vlm.c
index 4dce5ec..1d6cb74 100644
--- a/src/input/vlm.c
+++ b/src/input/vlm.c
@@ -63,6 +63,8 @@
 #include "../stream_output/stream_output.h"
 #include "../libvlc.h"
 
+//#define ENABLE_MMNK_DEBUG_LOGS
+
 /*****************************************************************************
  * Local prototypes.
  *****************************************************************************/
@@ -395,6 +397,20 @@ static int vlm_MediaVodControl( void *p_private, vod_media_t *p_vod_media,
         i_ret = vlm_ControlInternal( vlm, VLM_SET_MEDIA_INSTANCE_POSITION, id, psz_id, d_position );
         break;
     }
+// mmnk - fix for rate speed control
+// mmnk-START
+#if 1
+    case VOD_MEDIA_RATE:
+    {
+        int i_scale = (int)va_arg( args, int );
+        i_ret = vlm_ControlInternal( vlm, VLM_SET_MEDIA_INSTANCE_RATE, id, psz_id, i_scale );
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+	fprintf(stderr, "\nmmnk - vlm.c changes - case VOD_MEDIA_RATE... \n");
+#endif // ENABLE_MMNK_DEBUG_LOGS
+        break;
+    }
+#endif 
+// mmnk-END
 
     default:
         i_ret = VLC_EGENERIC;
@@ -1142,6 +1158,36 @@ static int vlm_ControlMediaInstanceSetTimePosition( vlm_t *p_vlm, int64_t id, co
     return VLC_EGENERIC;
 }
 
+// mmnk - fix for rate speed control
+// mmnk-START
+#if 1
+static int vlm_ControlMediaInstanceSetRate( vlm_t *p_vlm, int64_t id, const char *psz_id, int i_rate )
+{
+    vlm_media_sys_t *p_media = vlm_ControlMediaGetById( p_vlm, id );
+    vlm_media_instance_sys_t *p_instance;
+
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+    fprintf(stderr, "\nmmnk - vlm.c changes - caseint vlm_ControlMediaInstanceSetRate... \n");
+#endif // ENABLE_MMNK_DEBUG_LOGS
+
+    if( !p_media )
+        return VLC_EGENERIC;
+
+    p_instance = vlm_ControlMediaInstanceGetByName( p_media, psz_id );
+    if( !p_instance || !p_instance->p_input )
+        return VLC_EGENERIC;
+
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+    fprintf(stderr, "\nmmnk - Old rate float = %f \n",  var_GetFloat( p_instance->p_input, "rate" ));	
+    //fprintf(stderr, "\nmmnk - Old rate integer = %d \n",  var_GetInteger( p_instance->p_input, "rate" ));	
+#endif // ENABLE_MMNK_DEBUG_LOGS
+
+    //return var_SetInteger( p_instance->p_input, "rate", i_rate );
+    return var_SetFloat( p_instance->p_input, "rate", (float)i_rate/1000 );	
+}
+#endif 
+// mmnk-END
+
 static int vlm_ControlMediaInstanceGets( vlm_t *p_vlm, int64_t id, vlm_media_instance_t ***ppp_idsc, int *pi_instance )
 {
     vlm_media_sys_t *p_media = vlm_ControlMediaGetById( p_vlm, id );
@@ -1168,7 +1214,7 @@ static int vlm_ControlMediaInstanceGets( vlm_t *p_vlm, int64_t id, vlm_media_ins
             if( var_GetInteger( p_instance->p_input, "state" ) == PAUSE_S )
                 p_idsc->b_paused = true;
             p_idsc->i_rate = INPUT_RATE_DEFAULT
-                             / var_GetFloat( p_instance->p_input, "rate" );
+                             / var_GetFloat( p_instance->p_input, "rate" );	    
         }
 
         TAB_APPEND( i_idsc, pp_idsc, p_idsc );
@@ -1311,6 +1357,20 @@ static int vlm_vaControlInternal( vlm_t *p_vlm, int i_query, va_list args )
         d_double = (double)va_arg( args, double );
         return vlm_ControlMediaInstanceSetTimePosition( p_vlm, id, psz_id, -1, d_double );
 
+// mmnk - fix for rate speed control
+// mmnk-START
+#if 1
+    case VLM_SET_MEDIA_INSTANCE_RATE:
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+	fprintf(stderr, "\nmmnk - vlm.c changes - case VLM_SET_MEDIA_INSTANCE_RATE:... \n");
+#endif // ENABLE_MMNK_DEBUG_LOGS
+        id = (int64_t)va_arg( args, int64_t );
+        psz_id = (const char*)va_arg( args, const char* );
+        i_int = (int)va_arg( args, int );
+        return vlm_ControlMediaInstanceSetRate( p_vlm, id, psz_id, i_int );
+#endif 
+// mmnk-END
+
     case VLM_CLEAR_SCHEDULES:
         return vlm_ControlScheduleClear( p_vlm );
 
diff --git a/src/misc/variables.c b/src/misc/variables.c
index bcbce8d..494ad67 100644
--- a/src/misc/variables.c
+++ b/src/misc/variables.c
@@ -739,8 +739,20 @@ int var_SetChecked( vlc_object_t *p_this, const char *psz_name,
         return VLC_ENOVAR;
     }
 
+// mmnk - fix for rate speed control
+// mmnk-START
+#if 1
     assert( expected_type == 0 ||
             (p_var->i_type & VLC_VAR_CLASS) == expected_type );
+#else
+    //fprintf(stderr, "\nmmnk - expected_type = %d \n", expected_type);	
+    //fprintf(stderr, "\nmmnk - p_var->i_type = %d \n", p_var->i_type);	
+    //fprintf(stderr, "\nmmnk - val = %d \n", val);		
+    //assert( expected_type == 0 ||
+    //        (p_var->i_type & VLC_VAR_CLASS) == expected_type );
+#endif
+// mmnk-END
+
 #ifndef NDEBUG
         /* Alert if the type is VLC_VAR_VOID */
         if( ( p_var->i_type & VLC_VAR_TYPE ) == VLC_VAR_VOID )
diff --git a/src/stream_output/stream_output.c b/src/stream_output/stream_output.c
index 9587cf7..d2b3ab5 100644
--- a/src/stream_output/stream_output.c
+++ b/src/stream_output/stream_output.c
@@ -50,6 +50,8 @@
 
 #include "input/input_interface.h"
 
+//#define ENABLE_MMNK_DEBUG_LOGS
+
 #define VLC_CODEC_NULL VLC_FOURCC( 'n', 'u', 'l', 'l' )
 
 #undef DEBUG_BUFFER
@@ -223,6 +225,10 @@ int sout_InputSendBuffer( sout_packetizer_input_t *p_input,
     sout_instance_t     *p_sout = p_input->p_sout;
     int                 i_ret;
 
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+    //fprintf(stderr, "\nmmnk - sout_InputSendBuffer-1\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS 
+
     if( p_input->p_fmt->i_codec == VLC_CODEC_NULL )
     {
         block_Release( p_buffer );
@@ -231,6 +237,9 @@ int sout_InputSendBuffer( sout_packetizer_input_t *p_input,
 
     if( p_buffer->i_dts <= VLC_TS_INVALID )
     {
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+    fprintf(stderr, "\nmmnk - sout_InputSendBuffer-2\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS 
         msg_Warn( p_sout, "trying to send non-dated packet to stream output!");
         block_Release( p_buffer );
         return VLC_SUCCESS;
@@ -528,8 +537,15 @@ void sout_MuxSendBuffer( sout_mux_t *p_mux, sout_input_t *p_input,
 {
     block_FifoPut( p_input->p_fifo, p_buffer );
 
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+    fprintf(stderr, "\nmmnk - sout_MuxSendBuffer-1\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS 
+
     if( p_mux->p_sout->i_out_pace_nocontrol )
     {
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+    fprintf(stderr, "\nmmnk - sout_MuxSendBuffer-2\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS 
         mtime_t current_date = mdate();
         if ( current_date > p_buffer->i_dts )
             msg_Warn( p_mux, "late buffer for mux input (%"PRId64")",
@@ -540,13 +556,22 @@ void sout_MuxSendBuffer( sout_mux_t *p_mux, sout_input_t *p_input,
     {
         const int64_t i_caching = var_GetInteger( p_mux->p_sout, "sout-mux-caching" ) * INT64_C(1000);
 
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+    fprintf(stderr, "\nmmnk - sout_MuxSendBuffer-3\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS 
+
         if( p_mux->i_add_stream_start < 0 )
             p_mux->i_add_stream_start = p_buffer->i_dts;
 
         /* Wait until we have enought data before muxing */
         if( p_mux->i_add_stream_start < 0 ||
             p_buffer->i_dts < p_mux->i_add_stream_start + i_caching )
+        {
+#ifdef ENABLE_MMNK_DEBUG_LOGS
+    fprintf(stderr, "\nmmnk - sout_MuxSendBuffer-4\n");	
+#endif // ENABLE_MMNK_DEBUG_LOGS 
             return;
+        }
         p_mux->b_waiting_stream = false;
     }
     p_mux->pf_mux( p_mux );
diff --git a/src/video_output/video_output.c b/src/video_output/video_output.c
index a8e4e24..673e319 100644
--- a/src/video_output/video_output.c
+++ b/src/video_output/video_output.c
@@ -832,7 +832,14 @@ static int ThreadDisplayPreparePicture(vout_thread_t *vout, bool reuse, bool is_
             if (is_late_dropped && decoded && !decoded->b_force) {
                 const mtime_t predicted = mdate() + 0; /* TODO improve */
                 const mtime_t late = predicted - decoded->date;
-                if (late > VOUT_DISPLAY_LATE_THRESHOLD) {
+// mmnk - FIX-Start
+// Fix to allow late frame to display and avoid jerky play in streaming cases
+#if 0
+		if (late > VOUT_DISPLAY_LATE_THRESHOLD) {
+#else
+                if(0){
+#endif
+// mmnk  - FIX-End
                     msg_Warn(vout, "picture is too late to be displayed (missing %d ms)", (int)(late/1000));
                     picture_Release(decoded);
                     lost_count++;
-- 
1.7.9.5




More information about the vlc-devel mailing list