Browse code

rtsp: Allow requesting of filtering of source packets

If filtered, only packets from the right source address and port
are received.

To test, play back e.g. some mpeg4 video RTSP stream (where the
video stream is the first stream in the presentation) over UDP.
While receiving this stream, send another stream to the same port:
ffmpeg -re -i <whatever> -vcodec mpeg4 -an -f rtp
rtp://127.0.0.1:5000?localport=1234
Normally, the RTSP playback reports lots of errors at this point.

If the RTSP stream has the ?filter_src option enabled, these
interferring packets are ignored.

Originally committed as revision 26246 to svn://svn.ffmpeg.org/ffmpeg/trunk

Martin Storsjö authored on 2011/01/07 00:22:58
Showing 3 changed files
... ...
@@ -251,6 +251,9 @@ Use UDP multicast as lower transport protocol.
251 251
 @item http
252 252
 Use HTTP tunneling as lower transport protocol, which is useful for
253 253
 passing proxies.
254
+
255
+@item filter_src
256
+Accept packets only from negotiated peer address and port.
254 257
 @end table
255 258
 
256 259
 Multiple lower transport protocols may be specified, in that case they are
... ...
@@ -1186,16 +1186,18 @@ static int make_setup_request(AVFormatContext *s, const char *host, int port,
1186 1186
             break;
1187 1187
 
1188 1188
         case RTSP_LOWER_TRANSPORT_UDP: {
1189
-            char url[1024];
1189
+            char url[1024], options[30] = "";
1190 1190
 
1191
+            if (rt->filter_source)
1192
+                av_strlcpy(options, "?connect=1", sizeof(options));
1191 1193
             /* Use source address if specified */
1192 1194
             if (reply->transports[0].source[0]) {
1193 1195
                 ff_url_join(url, sizeof(url), "rtp", NULL,
1194 1196
                             reply->transports[0].source,
1195
-                            reply->transports[0].server_port_min, NULL);
1197
+                            reply->transports[0].server_port_min, options);
1196 1198
             } else {
1197 1199
                 ff_url_join(url, sizeof(url), "rtp", NULL, host,
1198
-                            reply->transports[0].server_port_min, NULL);
1200
+                            reply->transports[0].server_port_min, options);
1199 1201
             }
1200 1202
             if (!(rt->server_type == RTSP_SERVER_WMS && i > 1) &&
1201 1203
                 rtp_set_remote_url(rtsp_st->rtp_handle, url) < 0) {
... ...
@@ -1315,6 +1317,8 @@ redirect:
1315 1315
             } else if(!strcmp(option, "http")) {
1316 1316
                 lower_transport_mask |= (1<< RTSP_LOWER_TRANSPORT_TCP);
1317 1317
                 rt->control_transport = RTSP_MODE_TUNNEL;
1318
+            } else if (!strcmp(option, "filter_src")) {
1319
+                rt->filter_source = 1;
1318 1320
             } else {
1319 1321
                 /* Write options back into the buffer, using memmove instead
1320 1322
                  * of strcpy since the strings may overlap. */
... ...
@@ -309,6 +309,10 @@ typedef struct RTSPState {
309 309
 
310 310
     /** Reusable buffer for receiving packets */
311 311
     uint8_t* recvbuf;
312
+
313
+    /** Filter incoming UDP packets - receive packets only from the right
314
+     * source address and port. */
315
+    int filter_source;
312 316
 } RTSPState;
313 317
 
314 318
 /**