summaryrefslogtreecommitdiff
path: root/libavformat/rtsp.c
diff options
context:
space:
mode:
authorRonald S. Bultje <rsbultje@gmail.com>2009-01-07 14:48:17 +0000
committerRonald S. Bultje <rsbultje@gmail.com>2009-01-07 14:48:17 +0000
commit572c6a3814c7f08e9dca0cceaeb19265fcc57a6e (patch)
treea4d09f314e9967cb2f03b54c95b47fa9735cc8ed /libavformat/rtsp.c
parent7c68a17754ca1a42baccf8b90704a073f4514ece (diff)
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. Originally committed as revision 16469 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavformat/rtsp.c')
-rw-r--r--libavformat/rtsp.c71
1 files changed, 56 insertions, 15 deletions
diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
index 1e874ed5e1..f0c6e1b3ab 100644
--- a/libavformat/rtsp.c
+++ b/libavformat/rtsp.c
@@ -75,6 +75,8 @@ typedef struct RTSPState {
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 @@ static int rtsp_read_packet(AVFormatContext *s,
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->state == RTSP_STATE_PLAYING)
- rtsp_read_play (s);
+ 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;
+
+ 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 */