|
|
|
@@ -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 */ |
|
|
|
|