summaryrefslogtreecommitdiffstats
path: root/libavformat/rtsp.c
diff options
context:
space:
mode:
authorFabrice Bellard <fabrice@bellard.org>2003-07-15 16:57:35 +0000
committerFabrice Bellard <fabrice@bellard.org>2003-07-15 16:57:35 +0000
commitb689213642724e46b03ab78246c43d7d397c9a09 (patch)
tree23b4c142c00497dfbb5da7645e978a8c98c3b11b /libavformat/rtsp.c
parentaa35ccb8e1df62bfb25ec07ad12e0755feac74d2 (diff)
downloadffmpeg-streaming-b689213642724e46b03ab78246c43d7d397c9a09.zip
ffmpeg-streaming-b689213642724e46b03ab78246c43d7d397c9a09.tar.gz
fixed RTP/TCP client support
Originally committed as revision 2045 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavformat/rtsp.c')
-rw-r--r--libavformat/rtsp.c76
1 files changed, 50 insertions, 26 deletions
diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
index e6108cc..601f20d 100644
--- a/libavformat/rtsp.c
+++ b/libavformat/rtsp.c
@@ -29,10 +29,12 @@
#endif
//#define DEBUG
+//#define DEBUG_RTP_TCP
typedef struct RTSPState {
URLContext *rtsp_hd; /* RTSP TCP connexion handle */
- ByteIOContext rtsp_gb;
+ /* XXX: currently we use unbuffered input */
+ // ByteIOContext rtsp_gb;
int seq; /* RTSP command sequence number */
char session_id[512];
enum RTSPProtocol protocol;
@@ -55,7 +57,12 @@ int rtsp_abort_req = 0;
/* XXX: currently, the only way to change the protocols consists in
changing this variable */
+#if 1
int rtsp_default_protocols = (1 << RTSP_PROTOCOL_RTP_TCP) | (1 << RTSP_PROTOCOL_RTP_UDP) | (1 << RTSP_PROTOCOL_RTP_UDP_MULTICAST);
+#else
+/* try it if a proxy is used */
+int rtsp_default_protocols = (1 << RTSP_PROTOCOL_RTP_TCP);
+#endif
/* if non zero, then set a range for RTP ports */
int rtsp_rtp_port_min = 0;
@@ -365,7 +372,7 @@ static int sdp_parse(AVFormatContext *s, const char *content)
p++;
/* get the content */
q = buf;
- while (*p != '\n' && *p != '\0') {
+ while (*p != '\n' && *p != '\r' && *p != '\0') {
if ((q - buf) < sizeof(buf) - 1)
*q++ = *p;
p++;
@@ -427,10 +434,11 @@ static void rtsp_parse_transport(RTSPHeader *reply, const char *p)
get_word_sep(profile, sizeof(profile), "/;,", &p);
lower_transport[0] = '\0';
if (*p == '/') {
+ p++;
get_word_sep(lower_transport, sizeof(lower_transport),
";,", &p);
}
- if (!strcmp(lower_transport, "TCP"))
+ if (!strcasecmp(lower_transport, "TCP"))
th->protocol = RTSP_PROTOCOL_RTP_TCP;
else
th->protocol = RTSP_PROTOCOL_RTP_UDP;
@@ -526,13 +534,13 @@ static void rtsp_send_cmd(AVFormatContext *s,
rt->seq++;
pstrcpy(buf, sizeof(buf), cmd);
- snprintf(buf1, sizeof(buf1), "CSeq: %d\n", rt->seq);
+ snprintf(buf1, sizeof(buf1), "CSeq: %d\r\n", rt->seq);
pstrcat(buf, sizeof(buf), buf1);
if (rt->session_id[0] != '\0' && !strstr(cmd, "\nIf-Match:")) {
- snprintf(buf1, sizeof(buf1), "Session: %s\n", rt->session_id);
+ snprintf(buf1, sizeof(buf1), "Session: %s\r\n", rt->session_id);
pstrcat(buf, sizeof(buf), buf1);
}
- pstrcat(buf, sizeof(buf), "\n");
+ pstrcat(buf, sizeof(buf), "\r\n");
#ifdef DEBUG
printf("Sending:\n%s--\n", buf);
#endif
@@ -626,8 +634,8 @@ static int rtsp_read_header(AVFormatContext *s,
/* describe the stream */
snprintf(cmd, sizeof(cmd),
- "DESCRIBE %s RTSP/1.0\n"
- "Accept: application/sdp\n",
+ "DESCRIBE %s RTSP/1.0\r\n"
+ "Accept: application/sdp\r\n",
s->filename);
rtsp_send_cmd(s, cmd, reply, &content);
if (!content) {
@@ -708,10 +716,9 @@ static int rtsp_read_header(AVFormatContext *s,
sizeof(transport) - strlen(transport) - 1,
"RTP/AVP/UDP;multicast");
}
-
snprintf(cmd, sizeof(cmd),
- "SETUP %s RTSP/1.0\n"
- "Transport: %s\n",
+ "SETUP %s RTSP/1.0\r\n"
+ "Transport: %s\r\n",
rtsp_st->control_url, transport);
rtsp_send_cmd(s, cmd, reply, NULL);
if (reply->status_code != RTSP_STATUS_OK ||
@@ -794,7 +801,8 @@ static int rtsp_read_header(AVFormatContext *s,
/* start playing */
snprintf(cmd, sizeof(cmd),
- "PLAY %s RTSP/1.0\n",
+ "PLAY %s RTSP/1.0\r\n"
+ "Range: npt=0-\r\n",
s->filename);
rtsp_send_cmd(s, cmd, reply, NULL);
if (reply->status_code != RTSP_STATUS_OK) {
@@ -802,6 +810,7 @@ static int rtsp_read_header(AVFormatContext *s,
goto fail;
}
+#if 0
/* open TCP with bufferized input */
if (rt->protocol == RTSP_PROTOCOL_RTP_TCP) {
if (url_fdopen(&rt->rtsp_gb, rt->rtsp_hd) < 0) {
@@ -809,6 +818,7 @@ static int rtsp_read_header(AVFormatContext *s,
goto fail;
}
}
+#endif
return 0;
fail:
@@ -830,33 +840,46 @@ static int tcp_read_packet(AVFormatContext *s,
AVPacket *pkt)
{
RTSPState *rt = s->priv_data;
- ByteIOContext *rtsp_gb = &rt->rtsp_gb;
- int c, id, len, i, ret;
+ int id, len, i, ret;
AVStream *st;
RTSPStream *rtsp_st;
- char buf[RTP_MAX_PACKET_LENGTH];
+ uint8_t buf[RTP_MAX_PACKET_LENGTH];
+#ifdef DEBUG_RTP_TCP
+ printf("tcp_read_packet:\n");
+#endif
redo:
for(;;) {
- c = url_fgetc(rtsp_gb);
- if (c == URL_EOF)
+ ret = url_read(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)
return AVERROR_IO;
- if (c == '$')
+ if (buf[0] == '$')
break;
}
- id = get_byte(rtsp_gb);
- len = get_be16(rtsp_gb);
+ ret = url_read(rt->rtsp_hd, buf, 3);
+ if (ret != 3)
+ return AVERROR_IO;
+ id = buf[0];
+ len = (buf[1] << 8) | buf[2];
+#ifdef DEBUG_RTP_TCP
+ printf("id=%d len=%d\n", id, len);
+#endif
if (len > RTP_MAX_PACKET_LENGTH || len < 12)
goto redo;
/* get the data */
- get_buffer(rtsp_gb, buf, len);
-
+ ret = url_read(rt->rtsp_hd, buf, len);
+ if (ret != len)
+ return AVERROR_IO;
+
/* find the matching stream */
for(i = 0; i < s->nb_streams; i++) {
st = s->streams[i];
rtsp_st = st->priv_data;
- if (i >= rtsp_st->interleaved_min &&
- i <= rtsp_st->interleaved_max)
+ if (id >= rtsp_st->interleaved_min &&
+ id <= rtsp_st->interleaved_max)
goto found;
}
goto redo;
@@ -945,13 +968,14 @@ static int rtsp_read_close(AVFormatContext *s)
int i;
char cmd[1024];
+#if 0
/* NOTE: it is valid to flush the buffer here */
if (rt->protocol == RTSP_PROTOCOL_RTP_TCP) {
url_fclose(&rt->rtsp_gb);
}
-
+#endif
snprintf(cmd, sizeof(cmd),
- "TEARDOWN %s RTSP/1.0\n",
+ "TEARDOWN %s RTSP/1.0\r\n",
s->filename);
rtsp_send_cmd(s, cmd, reply, NULL);
OpenPOWER on IntegriCloud