Mercurial > libavformat.hg
comparison rtsp.c @ 4166:1dbda91eaebd libavformat
Allow subscription to any of the streams, not just the first, available in
this RTSP/RDT session. This basically implies full RDT support, including
stream selection in ffmpeg and multi-stream backupping in ffmpeg (by mapping
each stream to an output). See "[PATCH] RTSP/RDT: subscriptions" thread on
mailinglist.
author | rbultje |
---|---|
date | Wed, 07 Jan 2009 14:48:17 +0000 |
parents | 8b294ed0bd65 |
children | 0ebf63d12ea4 |
comparison
equal
deleted
inserted
replaced
4165:8b294ed0bd65 | 4166:1dbda91eaebd |
---|---|
73 enum RTSPLowerTransport lower_transport; | 73 enum RTSPLowerTransport lower_transport; |
74 enum RTSPServerType server_type; | 74 enum RTSPServerType server_type; |
75 char last_reply[2048]; /* XXX: allocate ? */ | 75 char last_reply[2048]; /* XXX: allocate ? */ |
76 void *cur_tx; | 76 void *cur_tx; |
77 int need_subscription; | 77 int need_subscription; |
78 enum AVDiscard real_setup_cache[MAX_STREAMS]; | |
79 char last_subscription[1024]; | |
78 } RTSPState; | 80 } RTSPState; |
79 | 81 |
80 typedef struct RTSPStream { | 82 typedef struct RTSPStream { |
81 URLContext *rtp_handle; /* RTP stream handle */ | 83 URLContext *rtp_handle; /* RTP stream handle */ |
82 void *tx_ctx; /* RTP/RDT parse context */ | 84 void *tx_ctx; /* RTP/RDT parse context */ |
1350 RTSPState *rt = s->priv_data; | 1352 RTSPState *rt = s->priv_data; |
1351 RTSPStream *rtsp_st; | 1353 RTSPStream *rtsp_st; |
1352 int ret, len; | 1354 int ret, len; |
1353 uint8_t buf[RTP_MAX_PACKET_LENGTH]; | 1355 uint8_t buf[RTP_MAX_PACKET_LENGTH]; |
1354 | 1356 |
1355 if (rt->server_type == RTSP_SERVER_REAL && rt->need_subscription) { | 1357 if (rt->server_type == RTSP_SERVER_REAL) { |
1356 int i; | 1358 int i; |
1357 RTSPHeader reply1, *reply = &reply1; | 1359 RTSPHeader reply1, *reply = &reply1; |
1360 enum AVDiscard cache[MAX_STREAMS]; | |
1358 char cmd[1024]; | 1361 char cmd[1024]; |
1359 | 1362 |
1360 snprintf(cmd, sizeof(cmd), | 1363 for (i = 0; i < s->nb_streams; i++) |
1361 "SET_PARAMETER %s RTSP/1.0\r\n" | 1364 cache[i] = s->streams[i]->discard; |
1362 "Subscribe: ", | 1365 |
1363 s->filename); | 1366 if (!rt->need_subscription) { |
1364 for (i = 0; i < rt->nb_rtsp_streams; i++) { | 1367 if (memcmp (cache, rt->real_setup_cache, |
1365 if (i != 0) av_strlcat(cmd, ",", sizeof(cmd)); | 1368 sizeof(enum AVDiscard) * s->nb_streams)) { |
1366 ff_rdt_subscribe_rule(cmd, sizeof(cmd), i, 0); | 1369 av_strlcatf(cmd, sizeof(cmd), |
1367 } | 1370 "SET_PARAMETER %s RTSP/1.0\r\n" |
1368 av_strlcat(cmd, "\r\n", sizeof(cmd)); | 1371 "Unsubscribe: %s\r\n", |
1369 rtsp_send_cmd(s, cmd, reply, NULL); | 1372 s->filename, rt->last_subscription); |
1370 if (reply->status_code != RTSP_STATUS_OK) | 1373 rtsp_send_cmd(s, cmd, reply, NULL); |
1371 return AVERROR_INVALIDDATA; | 1374 if (reply->status_code != RTSP_STATUS_OK) |
1372 rt->need_subscription = 0; | 1375 return AVERROR_INVALIDDATA; |
1373 | 1376 rt->need_subscription = 1; |
1374 if (rt->state == RTSP_STATE_PLAYING) | 1377 } |
1375 rtsp_read_play (s); | 1378 } |
1379 | |
1380 if (rt->need_subscription) { | |
1381 int r, rule_nr, first = 1; | |
1382 | |
1383 memcpy(rt->real_setup_cache, cache, | |
1384 sizeof(enum AVDiscard) * s->nb_streams); | |
1385 rt->last_subscription[0] = 0; | |
1386 | |
1387 snprintf(cmd, sizeof(cmd), | |
1388 "SET_PARAMETER %s RTSP/1.0\r\n" | |
1389 "Subscribe: ", | |
1390 s->filename); | |
1391 for (i = 0; i < rt->nb_rtsp_streams; i++) { | |
1392 rule_nr = 0; | |
1393 for (r = 0; r < s->nb_streams; r++) { | |
1394 if (s->streams[r]->priv_data == rt->rtsp_streams[i]) { | |
1395 if (s->streams[r]->discard != AVDISCARD_ALL) { | |
1396 if (!first) | |
1397 av_strlcat(rt->last_subscription, ",", | |
1398 sizeof(rt->last_subscription)); | |
1399 ff_rdt_subscribe_rule( | |
1400 rt->last_subscription, | |
1401 sizeof(rt->last_subscription), i, rule_nr); | |
1402 first = 0; | |
1403 } | |
1404 rule_nr++; | |
1405 } | |
1406 } | |
1407 } | |
1408 av_strlcatf(cmd, sizeof(cmd), "%s\r\n", rt->last_subscription); | |
1409 rtsp_send_cmd(s, cmd, reply, NULL); | |
1410 if (reply->status_code != RTSP_STATUS_OK) | |
1411 return AVERROR_INVALIDDATA; | |
1412 rt->need_subscription = 0; | |
1413 | |
1414 if (rt->state == RTSP_STATE_PLAYING) | |
1415 rtsp_read_play (s); | |
1416 } | |
1376 } | 1417 } |
1377 | 1418 |
1378 /* get next frames from the same RTP packet */ | 1419 /* get next frames from the same RTP packet */ |
1379 if (rt->cur_tx) { | 1420 if (rt->cur_tx) { |
1380 if (rt->transport == RTSP_TRANSPORT_RDT) | 1421 if (rt->transport == RTSP_TRANSPORT_RDT) |