Commit 572c6a38 authored by Ronald S. Bultje's avatar Ronald S. Bultje

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
parent 7c68a177
...@@ -75,6 +75,8 @@ typedef struct RTSPState { ...@@ -75,6 +75,8 @@ typedef struct RTSPState {
char last_reply[2048]; /* XXX: allocate ? */ char last_reply[2048]; /* XXX: allocate ? */
void *cur_tx; void *cur_tx;
int need_subscription; int need_subscription;
enum AVDiscard real_setup_cache[MAX_STREAMS];
char last_subscription[1024];
} RTSPState; } RTSPState;
typedef struct RTSPStream { typedef struct RTSPStream {
...@@ -1352,20 +1354,58 @@ static int rtsp_read_packet(AVFormatContext *s, ...@@ -1352,20 +1354,58 @@ static int rtsp_read_packet(AVFormatContext *s,
int ret, len; int ret, len;
uint8_t buf[RTP_MAX_PACKET_LENGTH]; 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; int i;
RTSPHeader reply1, *reply = &reply1; RTSPHeader reply1, *reply = &reply1;
enum AVDiscard cache[MAX_STREAMS];
char cmd[1024]; char cmd[1024];
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;
}
}
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), snprintf(cmd, sizeof(cmd),
"SET_PARAMETER %s RTSP/1.0\r\n" "SET_PARAMETER %s RTSP/1.0\r\n"
"Subscribe: ", "Subscribe: ",
s->filename); s->filename);
for (i = 0; i < rt->nb_rtsp_streams; i++) { for (i = 0; i < rt->nb_rtsp_streams; i++) {
if (i != 0) av_strlcat(cmd, ",", sizeof(cmd)); rule_nr = 0;
ff_rdt_subscribe_rule(cmd, sizeof(cmd), i, 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;
} }
av_strlcat(cmd, "\r\n", sizeof(cmd)); rule_nr++;
}
}
}
av_strlcatf(cmd, sizeof(cmd), "%s\r\n", rt->last_subscription);
rtsp_send_cmd(s, cmd, reply, NULL); rtsp_send_cmd(s, cmd, reply, NULL);
if (reply->status_code != RTSP_STATUS_OK) if (reply->status_code != RTSP_STATUS_OK)
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
...@@ -1374,6 +1414,7 @@ static int rtsp_read_packet(AVFormatContext *s, ...@@ -1374,6 +1414,7 @@ static int rtsp_read_packet(AVFormatContext *s,
if (rt->state == RTSP_STATE_PLAYING) if (rt->state == RTSP_STATE_PLAYING)
rtsp_read_play (s); rtsp_read_play (s);
} }
}
/* get next frames from the same RTP packet */ /* get next frames from the same RTP packet */
if (rt->cur_tx) { if (rt->cur_tx) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment