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)