Mercurial > libavformat.hg
changeset 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 | 81f64d590675 |
files | rtsp.c |
diffstat | 1 files changed, 56 insertions(+), 15 deletions(-) [+] |
line wrap: on
line diff
--- a/rtsp.c Wed Jan 07 14:45:13 2009 +0000 +++ b/rtsp.c Wed Jan 07 14:48:17 2009 +0000 @@ -75,6 +75,8 @@ char last_reply[2048]; /* XXX: allocate ? */ void *cur_tx; int need_subscription; + enum AVDiscard real_setup_cache[MAX_STREAMS]; + char last_subscription[1024]; } RTSPState; typedef struct RTSPStream { @@ -1352,27 +1354,66 @@ int ret, len; uint8_t buf[RTP_MAX_PACKET_LENGTH]; - if (rt->server_type == RTSP_SERVER_REAL && rt->need_subscription) { + if (rt->server_type == RTSP_SERVER_REAL) { int i; RTSPHeader reply1, *reply = &reply1; + enum AVDiscard cache[MAX_STREAMS]; char cmd[1024]; - snprintf(cmd, sizeof(cmd), - "SET_PARAMETER %s RTSP/1.0\r\n" - "Subscribe: ", - s->filename); - for (i = 0; i < rt->nb_rtsp_streams; i++) { - if (i != 0) av_strlcat(cmd, ",", sizeof(cmd)); - ff_rdt_subscribe_rule(cmd, sizeof(cmd), i, 0); + for (i = 0; i < s->nb_streams; i++) + cache[i] = s->streams[i]->discard; + + if (!rt->need_subscription) { + if (memcmp (cache, rt->real_setup_cache, + sizeof(enum AVDiscard) * s->nb_streams)) { + av_strlcatf(cmd, sizeof(cmd), + "SET_PARAMETER %s RTSP/1.0\r\n" + "Unsubscribe: %s\r\n", + s->filename, rt->last_subscription); + rtsp_send_cmd(s, cmd, reply, NULL); + if (reply->status_code != RTSP_STATUS_OK) + return AVERROR_INVALIDDATA; + rt->need_subscription = 1; + } } - av_strlcat(cmd, "\r\n", sizeof(cmd)); - rtsp_send_cmd(s, cmd, reply, NULL); - if (reply->status_code != RTSP_STATUS_OK) - return AVERROR_INVALIDDATA; - rt->need_subscription = 0; + + if (rt->need_subscription) { + int r, rule_nr, first = 1; + + memcpy(rt->real_setup_cache, cache, + sizeof(enum AVDiscard) * s->nb_streams); + rt->last_subscription[0] = 0; - if (rt->state == RTSP_STATE_PLAYING) - rtsp_read_play (s); + snprintf(cmd, sizeof(cmd), + "SET_PARAMETER %s RTSP/1.0\r\n" + "Subscribe: ", + s->filename); + for (i = 0; i < rt->nb_rtsp_streams; i++) { + rule_nr = 0; + for (r = 0; r < s->nb_streams; r++) { + if (s->streams[r]->priv_data == rt->rtsp_streams[i]) { + if (s->streams[r]->discard != AVDISCARD_ALL) { + if (!first) + av_strlcat(rt->last_subscription, ",", + sizeof(rt->last_subscription)); + ff_rdt_subscribe_rule( + rt->last_subscription, + sizeof(rt->last_subscription), i, rule_nr); + first = 0; + } + rule_nr++; + } + } + } + av_strlcatf(cmd, sizeof(cmd), "%s\r\n", rt->last_subscription); + rtsp_send_cmd(s, cmd, reply, NULL); + if (reply->status_code != RTSP_STATUS_OK) + return AVERROR_INVALIDDATA; + rt->need_subscription = 0; + + if (rt->state == RTSP_STATE_PLAYING) + rtsp_read_play (s); + } } /* get next frames from the same RTP packet */