Mercurial > libavformat.hg
changeset 172:9a0ab557b159 libavformat
fixed RTP/TCP client support
author | bellard |
---|---|
date | Tue, 15 Jul 2003 16:57:35 +0000 |
parents | fe5fc579b4de |
children | 38f64fabb24b |
files | rtsp.c utils.c |
diffstat | 2 files changed, 68 insertions(+), 31 deletions(-) [+] |
line wrap: on
line diff
--- a/rtsp.c Tue Jul 15 13:35:20 2003 +0000 +++ b/rtsp.c Tue Jul 15 16:57:35 2003 +0000 @@ -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 @@ /* 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 @@ 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 @@ 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 @@ 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 @@ /* 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 @@ 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 @@ /* 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 @@ 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 @@ goto fail; } } +#endif return 0; fail: @@ -830,33 +840,46 @@ 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 @@ 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);
--- a/utils.c Tue Jul 15 13:35:20 2003 +0000 +++ b/utils.c Tue Jul 15 16:57:35 2003 +0000 @@ -312,7 +312,7 @@ AVFormatParameters *ap) { AVFormatContext *ic = NULL; - int err; + int err, must_open_file; char buf[PROBE_BUF_SIZE]; AVProbeData probe_data, *pd = &probe_data; @@ -331,7 +331,15 @@ fmt = av_probe_input_format(pd, 0); } - if (!fmt || !(fmt->flags & AVFMT_NOFILE)) { + /* do not open file if the format does not need it. XXX: specific + hack needed to handle RTSP/TCP */ + must_open_file = 1; + if ((fmt->flags & AVFMT_NOFILE) || + (fmt == &rtp_demux && !strcmp(filename, "null"))) { + must_open_file = 0; + } + + if (!fmt || must_open_file) { /* if no file needed do not try to open one */ if (url_fopen(&ic->pb, filename, URL_RDONLY) < 0) { err = AVERROR_IO; @@ -397,7 +405,7 @@ *ic_ptr = ic; return 0; fail1: - if (!fmt || !(fmt->flags & AVFMT_NOFILE)) { + if (!fmt || must_open_file) { url_fclose(&ic->pb); } fail: @@ -664,7 +672,7 @@ */ void av_close_input_file(AVFormatContext *s) { - int i; + int i, must_open_file; if (s->iformat->read_close) s->iformat->read_close(s); @@ -682,7 +690,12 @@ } s->packet_buffer = NULL; } - if (!(s->iformat->flags & AVFMT_NOFILE)) { + must_open_file = 1; + if ((s->iformat->flags & AVFMT_NOFILE) || + (s->iformat == &rtp_demux && !strcmp(s->filename, "null"))) { + must_open_file = 0; + } + if (must_open_file) { url_fclose(&s->pb); } av_freep(&s->priv_data);