diff --git a/ffplay.c b/ffplay.c
index 1bc8192db00abf91106625e3606a644f054fc320..d62d99da6fe1c4f859108144bcf965c9e9936c2b 100644
--- a/ffplay.c
+++ b/ffplay.c
@@ -73,6 +73,7 @@ typedef struct VideoState {
     int no_background;
     int abort_request;
     int paused;
+    int last_paused;
     AVFormatContext *ic;
     int dtg_active_format;
 
@@ -1041,6 +1042,14 @@ static void stream_component_close(VideoState *is, int stream_index)
     }
 }
 
+/* since we have only one decoding thread, we can use a global
+   variable instead of a thread local variable */
+static VideoState *global_video_state;
+
+static int decode_interrupt_cb(void)
+{
+    return (global_video_state && global_video_state->abort_request);
+}
 
 /* this thread gets the stream from the disk or the network */
 static int decode_thread(void *arg)
@@ -1055,6 +1064,9 @@ static int decode_thread(void *arg)
     is->video_stream = -1;
     is->audio_stream = -1;
 
+    global_video_state = is;
+    url_set_interrupt_cb(decode_interrupt_cb);
+
     err = av_open_input_file(&ic, is->filename, NULL, 0, NULL);
     if (err < 0)
         return 0;
@@ -1101,6 +1113,22 @@ static int decode_thread(void *arg)
     for(;;) {
         if (is->abort_request)
             break;
+        if (is->paused != is->last_paused) {
+            is->last_paused = is->paused;
+            if (ic->iformat == &rtsp_demux) {
+                if (is->paused)
+                    rtsp_pause(ic);
+                else
+                    rtsp_resume(ic);
+            }
+        }
+        if (is->paused && ic->iformat == &rtsp_demux) {
+            /* wait 10 ms to avoid trying to get another packet */
+            /* XXX: horrible */
+            SDL_Delay(10);
+            continue;
+        }
+
         /* if the queue are full, no need to read more */
         if (is->audioq.size > MAX_AUDIOQ_SIZE ||
             is->videoq.size > MAX_VIDEOQ_SIZE) {
@@ -1126,6 +1154,9 @@ static int decode_thread(void *arg)
     }
 
  fail:
+    /* disable interrupting */
+    global_video_state = NULL;
+
     /* close each stream */
     if (is->audio_stream >= 0)
         stream_component_close(is, is->audio_stream);
@@ -1134,6 +1165,8 @@ static int decode_thread(void *arg)
 
     av_close_input_file(is->ic);
     is->ic = NULL; /* safety */
+    url_set_interrupt_cb(NULL);
+
     return 0;
 }
 
@@ -1315,6 +1348,12 @@ static void opt_format(const char *arg)
     }
 }
 
+void opt_rtp_tcp(void)
+{
+    /* only tcp protocol */
+    rtsp_default_protocols = (1 << RTSP_PROTOCOL_RTP_TCP);
+}
+
 const OptionDef options[] = {
     { "h", 0, {(void*)show_help}, "show help" },
     { "x", HAS_ARG, {(void*)opt_width}, "force displayed width", "width" },
@@ -1324,6 +1363,7 @@ const OptionDef options[] = {
     { "nodisp", OPT_BOOL, {(void*)&display_disable}, "disable graphical display" },
     { "f", HAS_ARG, {(void*)opt_format}, "force format", "fmt" },
     { "stats", OPT_BOOL | OPT_EXPERT, {(void*)&show_status}, "show status", "" },
+    { "rtp_tcp", OPT_EXPERT, {(void*)&opt_rtp_tcp}, "force RTP/TCP protocol usage", "" },
     { NULL, },
 };