提交 7e726132 编写于 作者: R Ronald S. Bultje

Allow (and parse) incoming server messages (notices) interleaved with TCP

data packets or in addition to UDP data packets, over the RTSP/TCP connection.
See discussion in [PATCH] rtsp.c: read TCP server notifications/messages"
thread on mailinglist.

Originally committed as revision 18121 to svn://svn.ffmpeg.org/ffmpeg/trunk
上级 9c610b76
......@@ -744,15 +744,36 @@ static void rtsp_skip_packet(AVFormatContext *s)
}
}
static void
/**
* Read a RTSP message from the server, or prepare to read data
* packets if we're reading data interleaved over the TCP/RTSP
* connection as well.
*
* @param s RTSP demuxer context
* @param reply pointer where the RTSP message header will be stored
* @param content_ptr pointer where the RTSP message body, if any, will
* be stored (length is in \p reply)
* @param return_on_interleaved_data whether the function may return if we
* encounter a data marker ('$'), which precedes data
* packets over interleaved TCP/RTSP connections. If this
* is set, this function will return 1 after encountering
* a '$'. If it is not set, the function will skip any
* data packets (if they are encountered), until a reply
* has been fully parsed. If no more data is available
* without parsing a reply, it will return an error.
*
* @returns 1 if a data packets is ready to be received, -1 on error,
* and 0 on success.
*/
static int
rtsp_read_reply (AVFormatContext *s, RTSPMessageHeader *reply,
unsigned char **content_ptr)
unsigned char **content_ptr, int return_on_interleaved_data)
{
RTSPState *rt = s->priv_data;
char buf[4096], buf1[1024], *q;
unsigned char ch;
const char *p;
int content_length, line_count = 0;
int ret, content_length, line_count = 0;
unsigned char *content = NULL;
memset(reply, 0, sizeof(*reply));
......@@ -762,12 +783,19 @@ rtsp_read_reply (AVFormatContext *s, RTSPMessageHeader *reply,
for(;;) {
q = buf;
for(;;) {
if (url_readbuf(rt->rtsp_hd, &ch, 1) != 1)
break;
ret = url_readbuf(rt->rtsp_hd, &ch, 1);
#ifdef DEBUG_RTP_TCP
printf("ret=%d c=%02x [%c]\n", ret, ch, ch);
#endif
if (ret != 1)
return -1;
if (ch == '\n')
break;
if (ch == '$') {
/* XXX: only parse it if first char on line ? */
if (return_on_interleaved_data) {
return 1;
} else
rtsp_skip_packet(s);
} else if (ch != '\r') {
if ((q - buf) < sizeof(buf) - 1)
......@@ -809,6 +837,8 @@ rtsp_read_reply (AVFormatContext *s, RTSPMessageHeader *reply,
*content_ptr = content;
else
av_free(content);
return 0;
}
static void rtsp_send_cmd(AVFormatContext *s,
......@@ -832,7 +862,7 @@ static void rtsp_send_cmd(AVFormatContext *s,
#endif
url_write(rt->rtsp_hd, buf, strlen(buf));
rtsp_read_reply(s, reply, content_ptr);
rtsp_read_reply(s, reply, content_ptr, 0);
}
......@@ -1277,14 +1307,14 @@ static int tcp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st,
#endif
redo:
for(;;) {
ret = url_readbuf(rt->rtsp_hd, buf, 1);
#ifdef DEBUG_RTP_TCP
printf("ret=%d c=%02x [%c]\n", ret, buf[0], buf[0]);
#endif
if (ret != 1)
RTSPMessageHeader reply;
ret = rtsp_read_reply(s, &reply, NULL, 1);
if (ret == -1)
return -1;
if (buf[0] == '$')
if (ret == 1) /* received '$' */
break;
/* XXX: parse message */
}
ret = url_readbuf(rt->rtsp_hd, buf, 3);
if (ret != 3)
......@@ -1323,14 +1353,15 @@ static int udp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st,
RTSPState *rt = s->priv_data;
RTSPStream *rtsp_st;
fd_set rfds;
int fd, fd_max, n, i, ret;
int fd, fd_max, n, i, ret, tcp_fd;
struct timeval tv;
for(;;) {
if (url_interrupt_cb())
return AVERROR(EINTR);
FD_ZERO(&rfds);
fd_max = -1;
tcp_fd = fd_max = url_get_file_handle(rt->rtsp_hd);
FD_SET(tcp_fd, &rfds);
for(i = 0; i < rt->nb_rtsp_streams; i++) {
rtsp_st = rt->rtsp_streams[i];
if (rtsp_st->rtp_handle) {
......@@ -1359,6 +1390,12 @@ static int udp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st,
}
}
}
if (FD_ISSET(tcp_fd, &rfds)) {
RTSPMessageHeader reply;
rtsp_read_reply(s, &reply, NULL, 0);
/* XXX: parse message */
}
}
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册