Revision 4f40ec05

View differences:

libavformat/rtsp.c
1291 1291
    int port, err, tcp_fd;
1292 1292
    RTSPMessageHeader reply1 = {0}, *reply = &reply1;
1293 1293
    int lower_transport_mask = 0;
1294
    char real_challenge[64];
1294
    char real_challenge[64] = "";
1295 1295
    struct sockaddr_storage peer;
1296 1296
    socklen_t peer_len = sizeof(peer);
1297 1297

  
......
1515 1515
        }
1516 1516
    } while (err);
1517 1517

  
1518
    rt->lower_transport_mask = lower_transport_mask;
1519
    av_strlcpy(rt->real_challenge, real_challenge, sizeof(rt->real_challenge));
1518 1520
    rt->state = RTSP_STATE_IDLE;
1519 1521
    rt->seek_timestamp = 0; /* default is to start stream at position zero */
1520 1522
    return 0;
libavformat/rtsp.h
248 248
     * of RTSPMessageHeader->real_challenge */
249 249
    enum RTSPServerType server_type;
250 250

  
251
    /** the "RealChallenge1:" field from the server */
252
    char real_challenge[64];
253

  
251 254
    /** plaintext authorization line (username:password) */
252 255
    char auth[128];
253 256

  
......
313 316
    /** Filter incoming UDP packets - receive packets only from the right
314 317
     * source address and port. */
315 318
    int filter_source;
319

  
320
    /**
321
     * A mask with all requested transport methods
322
     */
323
    int lower_transport_mask;
324

  
325
    /**
326
     * The number of returned packets
327
     */
328
    uint64_t packets;
316 329
} RTSPState;
317 330

  
318 331
/**
libavformat/rtspdec.c
229 229
    *prtsp_st = rtsp_st;
230 230
    return len;
231 231
}
232

  
233
static int resetup_tcp(AVFormatContext *s)
234
{
235
    RTSPState *rt = s->priv_data;
236
    char host[1024];
237
    int port;
238

  
239
    av_url_split(NULL, 0, NULL, 0, host, sizeof(host), &port, NULL, 0,
240
                 s->filename);
241
    ff_rtsp_undo_setup(s);
242
    return ff_rtsp_make_setup_request(s, host, port, RTSP_LOWER_TRANSPORT_TCP,
243
                                      rt->real_challenge);
244
}
245

  
232 246
static int rtsp_read_packet(AVFormatContext *s, AVPacket *pkt)
233 247
{
234 248
    RTSPState *rt = s->priv_data;
......
236 250
    RTSPMessageHeader reply1, *reply = &reply1;
237 251
    char cmd[1024];
238 252

  
253
retry:
239 254
    if (rt->server_type == RTSP_SERVER_REAL) {
240 255
        int i;
241 256

  
......
295 310
    }
296 311

  
297 312
    ret = ff_rtsp_fetch_packet(s, pkt);
298
    if (ret < 0)
313
    if (ret < 0) {
314
        if (ret == FF_NETERROR(ETIMEDOUT) && !rt->packets) {
315
            if (rt->lower_transport == RTSP_LOWER_TRANSPORT_UDP &&
316
                rt->lower_transport_mask & (1 << RTSP_LOWER_TRANSPORT_TCP)) {
317
                RTSPMessageHeader reply1, *reply = &reply1;
318
                av_log(s, AV_LOG_WARNING, "UDP timeout, retrying with TCP\n");
319
                if (rtsp_read_pause(s) != 0)
320
                    return -1;
321
                // TEARDOWN is required on Real-RTSP, but might make
322
                // other servers close the connection.
323
                if (rt->server_type == RTSP_SERVER_REAL)
324
                    ff_rtsp_send_cmd(s, "TEARDOWN", rt->control_uri, NULL,
325
                                     reply, NULL);
326
                rt->session_id[0] = '\0';
327
                if (resetup_tcp(s) == 0) {
328
                    rt->state = RTSP_STATE_IDLE;
329
                    rt->need_subscription = 1;
330
                    if (rtsp_read_play(s) != 0)
331
                        return -1;
332
                    goto retry;
333
                }
334
            }
335
        }
299 336
        return ret;
337
    }
338
    rt->packets++;
300 339

  
301 340
    /* send dummy request to keep TCP connection alive */
302 341
    if ((av_gettime() - rt->last_cmd_time) / 1000000 >= rt->timeout / 2) {

Also available in: Unified diff