struct in_addr sdp_ip;
int ttl;
-#ifdef DEBUG
- printf("sdp: %c='%s'\n", letter, buf);
-#endif
+ dprintf(s, "sdp: %c='%s'\n", letter, buf);
p = buf;
if (s1->skip_media && letter != 'm')
} else if (av_stristart(p, "Server:", &p)) {
skip_spaces(&p);
av_strlcpy(reply->server, p, sizeof(reply->server));
+ } else if (av_stristart(p, "Notice:", &p) ||
+ av_stristart(p, "X-Notice:", &p)) {
+ reply->notice = strtol(p, NULL, 10);
}
}
-static int url_readbuf(URLContext *h, unsigned char *buf, int size)
-{
- int ret, len;
-
- len = 0;
- while (len < size) {
- ret = url_read(h, buf+len, size-len);
- if (ret < 1)
- return ret;
- len += ret;
- }
- return len;
-}
-
/* skip a RTP/TCP interleaved packet */
static void rtsp_skip_packet(AVFormatContext *s)
{
int ret, len, len1;
uint8_t buf[1024];
- ret = url_readbuf(rt->rtsp_hd, buf, 3);
+ ret = url_read_complete(rt->rtsp_hd, buf, 3);
if (ret != 3)
return;
len = AV_RB16(buf + 1);
-#ifdef DEBUG
- printf("skipping RTP packet len=%d\n", len);
-#endif
+
+ dprintf(s, "skipping RTP packet len=%d\n", len);
+
/* skip payload */
while (len > 0) {
len1 = len;
if (len1 > sizeof(buf))
len1 = sizeof(buf);
- ret = url_readbuf(rt->rtsp_hd, buf, len1);
+ ret = url_read_complete(rt->rtsp_hd, buf, len1);
if (ret != len1)
return;
len -= len1;
for(;;) {
q = buf;
for(;;) {
- ret = url_readbuf(rt->rtsp_hd, &ch, 1);
+ ret = url_read_complete(rt->rtsp_hd, &ch, 1);
#ifdef DEBUG_RTP_TCP
- printf("ret=%d c=%02x [%c]\n", ret, ch, ch);
+ dprintf(s, "ret=%d c=%02x [%c]\n", ret, ch, ch);
#endif
if (ret != 1)
return -1;
}
}
*q = '\0';
-#ifdef DEBUG
- printf("line='%s'\n", buf);
-#endif
+
+ dprintf(s, "line='%s'\n", buf);
+
/* test if last line */
if (buf[0] == '\0')
break;
if (content_length > 0) {
/* leave some room for a trailing '\0' (useful for simple parsing) */
content = av_malloc(content_length + 1);
- (void)url_readbuf(rt->rtsp_hd, content, content_length);
+ (void)url_read_complete(rt->rtsp_hd, content, content_length);
content[content_length] = '\0';
}
if (content_ptr)
else
av_free(content);
+ /* EOS */
+ if (reply->notice == 2101 /* End-of-Stream Reached */ ||
+ reply->notice == 2104 /* Start-of-Stream Reached */ ||
+ reply->notice == 2306 /* Continuous Feed Terminated */)
+ rt->state = RTSP_STATE_IDLE;
+ else if (reply->notice >= 4400 && reply->notice < 5500)
+ return AVERROR(EIO); /* data or server error */
+ else if (reply->notice == 2401 /* Ticket Expired */ ||
+ (reply->notice >= 5500 && reply->notice < 5600) /* end of term */ )
+ return AVERROR(EPERM);
+
return 0;
}
av_strlcat(buf, buf1, sizeof(buf));
}
av_strlcat(buf, "\r\n", sizeof(buf));
-#ifdef DEBUG
- printf("Sending:\n%s--\n", buf);
-#endif
+
+ dprintf(s, "Sending:\n%s--\n", buf);
+
url_write(rt->rtsp_hd, buf, strlen(buf));
rt->last_cmd_time = av_gettime();
}
RTSPStream *rtsp_st;
#ifdef DEBUG_RTP_TCP
- printf("tcp_read_packet:\n");
+ dprintf(s, "tcp_read_packet:\n");
#endif
redo:
for(;;) {
if (ret == 1) /* received '$' */
break;
/* XXX: parse message */
+ if (rt->state != RTSP_STATE_PLAYING)
+ return 0;
}
- ret = url_readbuf(rt->rtsp_hd, buf, 3);
+ ret = url_read_complete(rt->rtsp_hd, buf, 3);
if (ret != 3)
return -1;
id = buf[0];
len = AV_RB16(buf + 1);
#ifdef DEBUG_RTP_TCP
- printf("id=%d len=%d\n", id, len);
+ dprintf(s, "id=%d len=%d\n", id, len);
#endif
if (len > buf_size || len < 12)
goto redo;
/* get the data */
- ret = url_readbuf(rt->rtsp_hd, buf, len);
+ ret = url_read_complete(rt->rtsp_hd, buf, len);
if (ret != len)
return -1;
if (rt->transport == RTSP_TRANSPORT_RDT &&
if (url_interrupt_cb())
return AVERROR(EINTR);
FD_ZERO(&rfds);
- tcp_fd = fd_max = url_get_file_handle(rt->rtsp_hd);
- FD_SET(tcp_fd, &rfds);
+ if (rt->rtsp_hd) {
+ tcp_fd = fd_max = url_get_file_handle(rt->rtsp_hd);
+ FD_SET(tcp_fd, &rfds);
+ } else {
+ fd_max = 0;
+ tcp_fd = -1;
+ }
for(i = 0; i < rt->nb_rtsp_streams; i++) {
rtsp_st = rt->rtsp_streams[i];
if (rtsp_st->rtp_handle) {
rtsp_read_reply(s, &reply, NULL, 0);
/* XXX: parse message */
+ if (rt->state != RTSP_STATE_PLAYING)
+ return 0;
}
}
}
}
if (len < 0)
return len;
+ if (len == 0)
+ return AVERROR_EOF;
if (rt->transport == RTSP_TRANSPORT_RDT)
ret = ff_rdt_parse_packet(rtsp_st->transport_priv, pkt, buf, len);
else
case RTSP_STATE_IDLE:
break;
case RTSP_STATE_PLAYING:
+ if (rtsp_read_pause(s) != 0)
+ return -1;
+ rt->state = RTSP_STATE_SEEKING;
if (rtsp_read_play(s) != 0)
return -1;
break;