3 * Copyright (c) 2002 Fabrice Bellard.
5 * This file is part of FFmpeg.
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 /* needed by inet_aton() */
25 #include "libavutil/avstring.h"
29 #include <unistd.h> /* for select() prototype */
34 #include "rtp_internal.h"
37 //#define DEBUG_RTP_TCP
39 enum RTSPClientState
{
45 typedef struct RTSPState
{
46 URLContext
*rtsp_hd
; /* RTSP TCP connexion handle */
48 struct RTSPStream
**rtsp_streams
;
50 enum RTSPClientState state
;
51 int64_t seek_timestamp
;
53 /* XXX: currently we use unbuffered input */
54 // ByteIOContext rtsp_gb;
55 int seq
; /* RTSP command sequence number */
57 enum RTSPProtocol protocol
;
58 char last_reply
[2048]; /* XXX: allocate ? */
59 RTPDemuxContext
*cur_rtp
;
62 typedef struct RTSPStream
{
63 URLContext
*rtp_handle
; /* RTP stream handle */
64 RTPDemuxContext
*rtp_ctx
; /* RTP parse context */
66 int stream_index
; /* corresponding stream index, if any. -1 if none (MPEG2TS case) */
67 int interleaved_min
, interleaved_max
; /* interleave ids, if TCP transport */
68 char control_url
[1024]; /* url for this stream (from SDP) */
70 int sdp_port
; /* port (from SDP content - not used in RTSP) */
71 struct in_addr sdp_ip
; /* IP address (from SDP content - not used in RTSP) */
72 int sdp_ttl
; /* IP TTL (from SDP content - not used in RTSP) */
73 int sdp_payload_type
; /* payload type - only used in SDP */
74 rtp_payload_data_t rtp_payload_data
; /* rtp payload parsing infos from SDP */
76 RTPDynamicProtocolHandler
*dynamic_handler
; ///< Only valid if it's a dynamic protocol. (This is the handler structure)
77 void *dynamic_protocol_context
; ///< Only valid if it's a dynamic protocol. (This is any private data associated with the dynamic protocol)
80 static int rtsp_read_play(AVFormatContext
*s
);
82 /* XXX: currently, the only way to change the protocols consists in
83 changing this variable */
85 #if LIBAVFORMAT_VERSION_INT < (53 << 16)
86 int rtsp_default_protocols
= (1 << RTSP_PROTOCOL_RTP_UDP
);
89 static int rtsp_probe(AVProbeData
*p
)
91 if (av_strstart(p
->filename
, "rtsp:", NULL
))
92 return AVPROBE_SCORE_MAX
;
96 static int redir_isspace(int c
)
98 return c
== ' ' || c
== '\t' || c
== '\n' || c
== '\r';
101 static void skip_spaces(const char **pp
)
105 while (redir_isspace(*p
))
110 static void get_word_sep(char *buf
, int buf_size
, const char *sep
,
121 while (!strchr(sep
, *p
) && *p
!= '\0') {
122 if ((q
- buf
) < buf_size
- 1)
131 static void get_word(char *buf
, int buf_size
, const char **pp
)
139 while (!redir_isspace(*p
) && *p
!= '\0') {
140 if ((q
- buf
) < buf_size
- 1)
149 /* parse the rtpmap description: <codec_name>/<clock_rate>[/<other
151 static int sdp_parse_rtpmap(AVCodecContext
*codec
, RTSPStream
*rtsp_st
, int payload_type
, const char *p
)
158 /* Loop into AVRtpDynamicPayloadTypes[] and AVRtpPayloadTypes[] and
159 see if we can handle this kind of payload */
160 get_word_sep(buf
, sizeof(buf
), "/", &p
);
161 if (payload_type
>= RTP_PT_PRIVATE
) {
162 RTPDynamicProtocolHandler
*handler
= RTPFirstDynamicPayloadHandler
;
164 if (!strcmp(buf
, handler
->enc_name
) && (codec
->codec_type
== handler
->codec_type
)) {
165 codec
->codec_id
= handler
->codec_id
;
166 rtsp_st
->dynamic_handler
= handler
;
168 rtsp_st
->dynamic_protocol_context
= handler
->open();
172 handler
= handler
->next
;
175 /* We are in a standard case ( from http://www.iana.org/assignments/rtp-parameters) */
176 /* search into AVRtpPayloadTypes[] */
177 codec
->codec_id
= ff_rtp_codec_id(buf
, codec
->codec_type
);
180 c
= avcodec_find_decoder(codec
->codec_id
);
184 c_name
= (char *)NULL
;
187 get_word_sep(buf
, sizeof(buf
), "/", &p
);
189 switch (codec
->codec_type
) {
190 case CODEC_TYPE_AUDIO
:
191 av_log(codec
, AV_LOG_DEBUG
, " audio codec set to : %s\n", c_name
);
192 codec
->sample_rate
= RTSP_DEFAULT_AUDIO_SAMPLERATE
;
193 codec
->channels
= RTSP_DEFAULT_NB_AUDIO_CHANNELS
;
195 codec
->sample_rate
= i
;
196 get_word_sep(buf
, sizeof(buf
), "/", &p
);
200 // TODO: there is a bug here; if it is a mono stream, and less than 22000Hz, faad upconverts to stereo and twice the
201 // frequency. No problem, but the sample rate is being set here by the sdp line. Upcoming patch forthcoming. (rdm)
203 av_log(codec
, AV_LOG_DEBUG
, " audio samplerate set to : %i\n", codec
->sample_rate
);
204 av_log(codec
, AV_LOG_DEBUG
, " audio channels set to : %i\n", codec
->channels
);
206 case CODEC_TYPE_VIDEO
:
207 av_log(codec
, AV_LOG_DEBUG
, " video codec set to : %s\n", c_name
);
218 /* return the length and optionnaly the data */
219 static int hex_to_data(uint8_t *data
, const char *p
)
229 c
= toupper((unsigned char)*p
++);
230 if (c
>= '0' && c
<= '9')
232 else if (c
>= 'A' && c
<= 'F')
247 static void sdp_parse_fmtp_config(AVCodecContext
*codec
, char *attr
, char *value
)
249 switch (codec
->codec_id
) {
252 if (!strcmp(attr
, "config")) {
253 /* decode the hexa encoded parameter */
254 int len
= hex_to_data(NULL
, value
);
255 codec
->extradata
= av_mallocz(len
+ FF_INPUT_BUFFER_PADDING_SIZE
);
256 if (!codec
->extradata
)
258 codec
->extradata_size
= len
;
259 hex_to_data(codec
->extradata
, value
);
268 typedef struct attrname_map
275 /* All known fmtp parmeters and the corresping RTPAttrTypeEnum */
276 #define ATTR_NAME_TYPE_INT 0
277 #define ATTR_NAME_TYPE_STR 1
278 static attrname_map_t attr_names
[]=
280 {"SizeLength", ATTR_NAME_TYPE_INT
, offsetof(rtp_payload_data_t
, sizelength
)},
281 {"IndexLength", ATTR_NAME_TYPE_INT
, offsetof(rtp_payload_data_t
, indexlength
)},
282 {"IndexDeltaLength", ATTR_NAME_TYPE_INT
, offsetof(rtp_payload_data_t
, indexdeltalength
)},
283 {"profile-level-id", ATTR_NAME_TYPE_INT
, offsetof(rtp_payload_data_t
, profile_level_id
)},
284 {"StreamType", ATTR_NAME_TYPE_INT
, offsetof(rtp_payload_data_t
, streamtype
)},
285 {"mode", ATTR_NAME_TYPE_STR
, offsetof(rtp_payload_data_t
, mode
)},
289 /** parse the attribute line from the fmtp a line of an sdp resonse. This is broken out as a function
290 * because it is used in rtp_h264.c, which is forthcoming.
292 int rtsp_next_attr_and_value(const char **p
, char *attr
, int attr_size
, char *value
, int value_size
)
297 get_word_sep(attr
, attr_size
, "=", p
);
300 get_word_sep(value
, value_size
, ";", p
);
308 /* parse a SDP line and save stream attributes */
309 static void sdp_parse_fmtp(AVStream
*st
, const char *p
)
315 RTSPStream
*rtsp_st
= st
->priv_data
;
316 AVCodecContext
*codec
= st
->codec
;
317 rtp_payload_data_t
*rtp_payload_data
= &rtsp_st
->rtp_payload_data
;
319 /* loop on each attribute */
320 while(rtsp_next_attr_and_value(&p
, attr
, sizeof(attr
), value
, sizeof(value
)))
322 /* grab the codec extra_data from the config parameter of the fmtp line */
323 sdp_parse_fmtp_config(codec
, attr
, value
);
324 /* Looking for a known attribute */
325 for (i
= 0; attr_names
[i
].str
; ++i
) {
326 if (!strcasecmp(attr
, attr_names
[i
].str
)) {
327 if (attr_names
[i
].type
== ATTR_NAME_TYPE_INT
)
328 *(int *)((char *)rtp_payload_data
+ attr_names
[i
].offset
) = atoi(value
);
329 else if (attr_names
[i
].type
== ATTR_NAME_TYPE_STR
)
330 *(char **)((char *)rtp_payload_data
+ attr_names
[i
].offset
) = av_strdup(value
);
336 /** Parse a string \p in the form of Range:npt=xx-xx, and determine the start
338 * Used for seeking in the rtp stream.
340 static void rtsp_parse_range_npt(const char *p
, int64_t *start
, int64_t *end
)
345 if (!av_stristart(p
, "npt=", &p
))
348 *start
= AV_NOPTS_VALUE
;
349 *end
= AV_NOPTS_VALUE
;
351 get_word_sep(buf
, sizeof(buf
), "-", &p
);
352 *start
= parse_date(buf
, 1);
355 get_word_sep(buf
, sizeof(buf
), "-", &p
);
356 *end
= parse_date(buf
, 1);
358 // av_log(NULL, AV_LOG_DEBUG, "Range Start: %lld\n", *start);
359 // av_log(NULL, AV_LOG_DEBUG, "Range End: %lld\n", *end);
362 typedef struct SDPParseState
{
364 struct in_addr default_ip
;
368 static void sdp_parse_line(AVFormatContext
*s
, SDPParseState
*s1
,
369 int letter
, const char *buf
)
371 RTSPState
*rt
= s
->priv_data
;
372 char buf1
[64], st_type
[64];
374 int codec_type
, payload_type
, i
;
377 struct in_addr sdp_ip
;
381 printf("sdp: %c='%s'\n", letter
, buf
);
387 get_word(buf1
, sizeof(buf1
), &p
);
388 if (strcmp(buf1
, "IN") != 0)
390 get_word(buf1
, sizeof(buf1
), &p
);
391 if (strcmp(buf1
, "IP4") != 0)
393 get_word_sep(buf1
, sizeof(buf1
), "/", &p
);
394 if (inet_aton(buf1
, &sdp_ip
) == 0)
399 get_word_sep(buf1
, sizeof(buf1
), "/", &p
);
402 if (s
->nb_streams
== 0) {
403 s1
->default_ip
= sdp_ip
;
404 s1
->default_ttl
= ttl
;
406 st
= s
->streams
[s
->nb_streams
- 1];
407 rtsp_st
= st
->priv_data
;
408 rtsp_st
->sdp_ip
= sdp_ip
;
409 rtsp_st
->sdp_ttl
= ttl
;
413 av_strlcpy(s
->title
, p
, sizeof(s
->title
));
416 if (s
->nb_streams
== 0) {
417 av_strlcpy(s
->comment
, p
, sizeof(s
->comment
));
423 get_word(st_type
, sizeof(st_type
), &p
);
424 if (!strcmp(st_type
, "audio")) {
425 codec_type
= CODEC_TYPE_AUDIO
;
426 } else if (!strcmp(st_type
, "video")) {
427 codec_type
= CODEC_TYPE_VIDEO
;
431 rtsp_st
= av_mallocz(sizeof(RTSPStream
));
434 rtsp_st
->stream_index
= -1;
435 dynarray_add(&rt
->rtsp_streams
, &rt
->nb_rtsp_streams
, rtsp_st
);
437 rtsp_st
->sdp_ip
= s1
->default_ip
;
438 rtsp_st
->sdp_ttl
= s1
->default_ttl
;
440 get_word(buf1
, sizeof(buf1
), &p
); /* port */
441 rtsp_st
->sdp_port
= atoi(buf1
);
443 get_word(buf1
, sizeof(buf1
), &p
); /* protocol (ignored) */
445 /* XXX: handle list of formats */
446 get_word(buf1
, sizeof(buf1
), &p
); /* format list */
447 rtsp_st
->sdp_payload_type
= atoi(buf1
);
449 if (!strcmp(ff_rtp_enc_name(rtsp_st
->sdp_payload_type
), "MP2T")) {
450 /* no corresponding stream */
452 st
= av_new_stream(s
, 0);
455 st
->priv_data
= rtsp_st
;
456 rtsp_st
->stream_index
= st
->index
;
457 st
->codec
->codec_type
= codec_type
;
458 if (rtsp_st
->sdp_payload_type
< RTP_PT_PRIVATE
) {
459 /* if standard payload type, we can find the codec right now */
460 rtp_get_codec_info(st
->codec
, rtsp_st
->sdp_payload_type
);
463 /* put a default control url */
464 av_strlcpy(rtsp_st
->control_url
, s
->filename
, sizeof(rtsp_st
->control_url
));
467 if (av_strstart(p
, "control:", &p
) && s
->nb_streams
> 0) {
469 /* get the control url */
470 st
= s
->streams
[s
->nb_streams
- 1];
471 rtsp_st
= st
->priv_data
;
473 /* XXX: may need to add full url resolution */
474 url_split(proto
, sizeof(proto
), NULL
, 0, NULL
, 0, NULL
, NULL
, 0, p
);
475 if (proto
[0] == '\0') {
476 /* relative control URL */
477 av_strlcat(rtsp_st
->control_url
, "/", sizeof(rtsp_st
->control_url
));
478 av_strlcat(rtsp_st
->control_url
, p
, sizeof(rtsp_st
->control_url
));
480 av_strlcpy(rtsp_st
->control_url
, p
, sizeof(rtsp_st
->control_url
));
482 } else if (av_strstart(p
, "rtpmap:", &p
)) {
483 /* NOTE: rtpmap is only supported AFTER the 'm=' tag */
484 get_word(buf1
, sizeof(buf1
), &p
);
485 payload_type
= atoi(buf1
);
486 for(i
= 0; i
< s
->nb_streams
;i
++) {
488 rtsp_st
= st
->priv_data
;
489 if (rtsp_st
->sdp_payload_type
== payload_type
) {
490 sdp_parse_rtpmap(st
->codec
, rtsp_st
, payload_type
, p
);
493 } else if (av_strstart(p
, "fmtp:", &p
)) {
494 /* NOTE: fmtp is only supported AFTER the 'a=rtpmap:xxx' tag */
495 get_word(buf1
, sizeof(buf1
), &p
);
496 payload_type
= atoi(buf1
);
497 for(i
= 0; i
< s
->nb_streams
;i
++) {
499 rtsp_st
= st
->priv_data
;
500 if (rtsp_st
->sdp_payload_type
== payload_type
) {
501 if(rtsp_st
->dynamic_handler
&& rtsp_st
->dynamic_handler
->parse_sdp_a_line
) {
502 if(!rtsp_st
->dynamic_handler
->parse_sdp_a_line(st
, rtsp_st
->dynamic_protocol_context
, buf
)) {
503 sdp_parse_fmtp(st
, p
);
506 sdp_parse_fmtp(st
, p
);
510 } else if(av_strstart(p
, "framesize:", &p
)) {
511 // let dynamic protocol handlers have a stab at the line.
512 get_word(buf1
, sizeof(buf1
), &p
);
513 payload_type
= atoi(buf1
);
514 for(i
= 0; i
< s
->nb_streams
;i
++) {
516 rtsp_st
= st
->priv_data
;
517 if (rtsp_st
->sdp_payload_type
== payload_type
) {
518 if(rtsp_st
->dynamic_handler
&& rtsp_st
->dynamic_handler
->parse_sdp_a_line
) {
519 rtsp_st
->dynamic_handler
->parse_sdp_a_line(st
, rtsp_st
->dynamic_protocol_context
, buf
);
523 } else if(av_strstart(p
, "range:", &p
)) {
526 // this is so that seeking on a streamed file can work.
527 rtsp_parse_range_npt(p
, &start
, &end
);
528 s
->start_time
= start
;
529 s
->duration
= (end
==AV_NOPTS_VALUE
)?AV_NOPTS_VALUE
:end
-start
; // AV_NOPTS_VALUE means live broadcast (and can't seek)
530 } else if (s
->nb_streams
> 0) {
531 rtsp_st
= s
->streams
[s
->nb_streams
- 1]->priv_data
;
532 if (rtsp_st
->dynamic_handler
&&
533 rtsp_st
->dynamic_handler
->parse_sdp_a_line
)
534 rtsp_st
->dynamic_handler
->parse_sdp_a_line(s
->streams
[s
->nb_streams
- 1],
535 rtsp_st
->dynamic_protocol_context
, buf
);
541 static int sdp_parse(AVFormatContext
*s
, const char *content
)
546 SDPParseState sdp_parse_state
, *s1
= &sdp_parse_state
;
548 memset(s1
, 0, sizeof(SDPParseState
));
559 /* get the content */
561 while (*p
!= '\n' && *p
!= '\r' && *p
!= '\0') {
562 if ((q
- buf
) < sizeof(buf
) - 1)
567 sdp_parse_line(s
, s1
, letter
, buf
);
569 while (*p
!= '\n' && *p
!= '\0')
577 static void rtsp_parse_range(int *min_ptr
, int *max_ptr
, const char **pp
)
584 v
= strtol(p
, (char **)&p
, 10);
588 v
= strtol(p
, (char **)&p
, 10);
597 /* XXX: only one transport specification is parsed */
598 static void rtsp_parse_transport(RTSPHeader
*reply
, const char *p
)
600 char transport_protocol
[16];
602 char lower_transport
[16];
604 RTSPTransportField
*th
;
607 reply
->nb_transports
= 0;
614 th
= &reply
->transports
[reply
->nb_transports
];
616 get_word_sep(transport_protocol
, sizeof(transport_protocol
),
620 if (!strcasecmp (transport_protocol
, "rtp")) {
621 get_word_sep(profile
, sizeof(profile
), "/;,", &p
);
622 lower_transport
[0] = '\0';
623 /* rtp/avp/<protocol> */
626 get_word_sep(lower_transport
, sizeof(lower_transport
),
629 } else if (!strcasecmp (transport_protocol
, "x-pn-tng")) {
630 /* x-pn-tng/<protocol> */
631 get_word_sep(lower_transport
, sizeof(lower_transport
), "/;,", &p
);
634 if (!strcasecmp(lower_transport
, "TCP"))
635 th
->protocol
= RTSP_PROTOCOL_RTP_TCP
;
637 th
->protocol
= RTSP_PROTOCOL_RTP_UDP
;
641 /* get each parameter */
642 while (*p
!= '\0' && *p
!= ',') {
643 get_word_sep(parameter
, sizeof(parameter
), "=;,", &p
);
644 if (!strcmp(parameter
, "port")) {
647 rtsp_parse_range(&th
->port_min
, &th
->port_max
, &p
);
649 } else if (!strcmp(parameter
, "client_port")) {
652 rtsp_parse_range(&th
->client_port_min
,
653 &th
->client_port_max
, &p
);
655 } else if (!strcmp(parameter
, "server_port")) {
658 rtsp_parse_range(&th
->server_port_min
,
659 &th
->server_port_max
, &p
);
661 } else if (!strcmp(parameter
, "interleaved")) {
664 rtsp_parse_range(&th
->interleaved_min
,
665 &th
->interleaved_max
, &p
);
667 } else if (!strcmp(parameter
, "multicast")) {
668 if (th
->protocol
== RTSP_PROTOCOL_RTP_UDP
)
669 th
->protocol
= RTSP_PROTOCOL_RTP_UDP_MULTICAST
;
670 } else if (!strcmp(parameter
, "ttl")) {
673 th
->ttl
= strtol(p
, (char **)&p
, 10);
675 } else if (!strcmp(parameter
, "destination")) {
676 struct in_addr ipaddr
;
680 get_word_sep(buf
, sizeof(buf
), ";,", &p
);
681 if (inet_aton(buf
, &ipaddr
))
682 th
->destination
= ntohl(ipaddr
.s_addr
);
685 while (*p
!= ';' && *p
!= '\0' && *p
!= ',')
693 reply
->nb_transports
++;
697 void rtsp_parse_line(RTSPHeader
*reply
, const char *buf
)
701 /* NOTE: we do case independent match for broken servers */
703 if (av_stristart(p
, "Session:", &p
)) {
704 get_word_sep(reply
->session_id
, sizeof(reply
->session_id
), ";", &p
);
705 } else if (av_stristart(p
, "Content-Length:", &p
)) {
706 reply
->content_length
= strtol(p
, NULL
, 10);
707 } else if (av_stristart(p
, "Transport:", &p
)) {
708 rtsp_parse_transport(reply
, p
);
709 } else if (av_stristart(p
, "CSeq:", &p
)) {
710 reply
->seq
= strtol(p
, NULL
, 10);
711 } else if (av_stristart(p
, "Range:", &p
)) {
712 rtsp_parse_range_npt(p
, &reply
->range_start
, &reply
->range_end
);
716 static int url_readbuf(URLContext
*h
, unsigned char *buf
, int size
)
722 ret
= url_read(h
, buf
+len
, size
-len
);
730 /* skip a RTP/TCP interleaved packet */
731 static void rtsp_skip_packet(AVFormatContext
*s
)
733 RTSPState
*rt
= s
->priv_data
;
737 ret
= url_readbuf(rt
->rtsp_hd
, buf
, 3);
740 len
= AV_RB16(buf
+ 1);
742 printf("skipping RTP packet len=%d\n", len
);
747 if (len1
> sizeof(buf
))
749 ret
= url_readbuf(rt
->rtsp_hd
, buf
, len1
);
756 static void rtsp_send_cmd(AVFormatContext
*s
,
757 const char *cmd
, RTSPHeader
*reply
,
758 unsigned char **content_ptr
)
760 RTSPState
*rt
= s
->priv_data
;
761 char buf
[4096], buf1
[1024], *q
;
764 int content_length
, line_count
;
765 unsigned char *content
= NULL
;
767 memset(reply
, 0, sizeof(RTSPHeader
));
770 av_strlcpy(buf
, cmd
, sizeof(buf
));
771 snprintf(buf1
, sizeof(buf1
), "CSeq: %d\r\n", rt
->seq
);
772 av_strlcat(buf
, buf1
, sizeof(buf
));
773 if (rt
->session_id
[0] != '\0' && !strstr(cmd
, "\nIf-Match:")) {
774 snprintf(buf1
, sizeof(buf1
), "Session: %s\r\n", rt
->session_id
);
775 av_strlcat(buf
, buf1
, sizeof(buf
));
777 av_strlcat(buf
, "\r\n", sizeof(buf
));
779 printf("Sending:\n%s--\n", buf
);
781 url_write(rt
->rtsp_hd
, buf
, strlen(buf
));
783 /* parse reply (XXX: use buffers) */
785 rt
->last_reply
[0] = '\0';
789 if (url_readbuf(rt
->rtsp_hd
, &ch
, 1) != 1)
794 /* XXX: only parse it if first char on line ? */
796 } else if (ch
!= '\r') {
797 if ((q
- buf
) < sizeof(buf
) - 1)
803 printf("line='%s'\n", buf
);
805 /* test if last line */
809 if (line_count
== 0) {
811 get_word(buf1
, sizeof(buf1
), &p
);
812 get_word(buf1
, sizeof(buf1
), &p
);
813 reply
->status_code
= atoi(buf1
);
815 rtsp_parse_line(reply
, p
);
816 av_strlcat(rt
->last_reply
, p
, sizeof(rt
->last_reply
));
817 av_strlcat(rt
->last_reply
, "\n", sizeof(rt
->last_reply
));
822 if (rt
->session_id
[0] == '\0' && reply
->session_id
[0] != '\0')
823 av_strlcpy(rt
->session_id
, reply
->session_id
, sizeof(rt
->session_id
));
825 content_length
= reply
->content_length
;
826 if (content_length
> 0) {
827 /* leave some room for a trailing '\0' (useful for simple parsing) */
828 content
= av_malloc(content_length
+ 1);
829 (void)url_readbuf(rt
->rtsp_hd
, content
, content_length
);
830 content
[content_length
] = '\0';
833 *content_ptr
= content
;
839 /* close and free RTSP streams */
840 static void rtsp_close_streams(RTSPState
*rt
)
845 for(i
=0;i
<rt
->nb_rtsp_streams
;i
++) {
846 rtsp_st
= rt
->rtsp_streams
[i
];
848 if (rtsp_st
->rtp_ctx
)
849 rtp_parse_close(rtsp_st
->rtp_ctx
);
850 if (rtsp_st
->rtp_handle
)
851 url_close(rtsp_st
->rtp_handle
);
852 if (rtsp_st
->dynamic_handler
&& rtsp_st
->dynamic_protocol_context
)
853 rtsp_st
->dynamic_handler
->close(rtsp_st
->dynamic_protocol_context
);
856 av_free(rt
->rtsp_streams
);
860 * @returns 0 on success, <0 on error, 1 if protocol is unavailable.
863 make_setup_request (AVFormatContext
*s
, const char *host
, int port
, int protocol
)
865 RTSPState
*rt
= s
->priv_data
;
869 RTSPHeader reply1
, *reply
= &reply1
;
872 /* for each stream, make the setup request */
873 /* XXX: we assume the same server is used for the control of each
876 for(j
= RTSP_RTP_PORT_MIN
, i
= 0; i
< rt
->nb_rtsp_streams
; ++i
) {
877 char transport
[2048];
879 rtsp_st
= rt
->rtsp_streams
[i
];
881 /* compute available transports */
885 if (protocol
== RTSP_PROTOCOL_RTP_UDP
) {
888 /* first try in specified port range */
889 if (RTSP_RTP_PORT_MIN
!= 0) {
890 while(j
<= RTSP_RTP_PORT_MAX
) {
891 snprintf(buf
, sizeof(buf
), "rtp://%s?localport=%d", host
, j
);
892 j
+= 2; /* we will use two port by rtp stream (rtp and rtcp) */
893 if (url_open(&rtsp_st
->rtp_handle
, buf
, URL_RDWR
) == 0) {
899 /* then try on any port
900 ** if (url_open(&rtsp_st->rtp_handle, "rtp://", URL_RDONLY) < 0) {
901 ** err = AVERROR_INVALIDDATA;
907 port
= rtp_get_local_port(rtsp_st
->rtp_handle
);
908 if (transport
[0] != '\0')
909 av_strlcat(transport
, ",", sizeof(transport
));
910 snprintf(transport
+ strlen(transport
), sizeof(transport
) - strlen(transport
) - 1,
911 "RTP/AVP/UDP;unicast;client_port=%d-%d",
916 else if (protocol
== RTSP_PROTOCOL_RTP_TCP
) {
917 if (transport
[0] != '\0')
918 av_strlcat(transport
, ",", sizeof(transport
));
919 snprintf(transport
+ strlen(transport
), sizeof(transport
) - strlen(transport
) - 1,
923 else if (protocol
== RTSP_PROTOCOL_RTP_UDP_MULTICAST
) {
924 if (transport
[0] != '\0')
925 av_strlcat(transport
, ",", sizeof(transport
));
926 snprintf(transport
+ strlen(transport
),
927 sizeof(transport
) - strlen(transport
) - 1,
928 "RTP/AVP/UDP;multicast");
930 snprintf(cmd
, sizeof(cmd
),
931 "SETUP %s RTSP/1.0\r\n"
933 rtsp_st
->control_url
, transport
);
934 rtsp_send_cmd(s
, cmd
, reply
, NULL
);
935 if (reply
->status_code
== 461 /* Unsupported protocol */ && i
== 0) {
938 } else if (reply
->status_code
!= RTSP_STATUS_OK
||
939 reply
->nb_transports
!= 1) {
940 err
= AVERROR_INVALIDDATA
;
944 /* XXX: same protocol for all streams is required */
946 if (reply
->transports
[0].protocol
!= rt
->protocol
) {
947 err
= AVERROR_INVALIDDATA
;
951 rt
->protocol
= reply
->transports
[0].protocol
;
954 /* close RTP connection if not choosen */
955 if (reply
->transports
[0].protocol
!= RTSP_PROTOCOL_RTP_UDP
&&
956 (protocol
== RTSP_PROTOCOL_RTP_UDP
)) {
957 url_close(rtsp_st
->rtp_handle
);
958 rtsp_st
->rtp_handle
= NULL
;
961 switch(reply
->transports
[0].protocol
) {
962 case RTSP_PROTOCOL_RTP_TCP
:
963 rtsp_st
->interleaved_min
= reply
->transports
[0].interleaved_min
;
964 rtsp_st
->interleaved_max
= reply
->transports
[0].interleaved_max
;
967 case RTSP_PROTOCOL_RTP_UDP
:
971 /* XXX: also use address if specified */
972 snprintf(url
, sizeof(url
), "rtp://%s:%d",
973 host
, reply
->transports
[0].server_port_min
);
974 if (rtp_set_remote_url(rtsp_st
->rtp_handle
, url
) < 0) {
975 err
= AVERROR_INVALIDDATA
;
980 case RTSP_PROTOCOL_RTP_UDP_MULTICAST
:
985 in
.s_addr
= htonl(reply
->transports
[0].destination
);
986 snprintf(url
, sizeof(url
), "rtp://%s:%d?ttl=%d",
988 reply
->transports
[0].port_min
,
989 reply
->transports
[0].ttl
);
990 if (url_open(&rtsp_st
->rtp_handle
, url
, URL_RDWR
) < 0) {
991 err
= AVERROR_INVALIDDATA
;
997 /* open the RTP context */
999 if (rtsp_st
->stream_index
>= 0)
1000 st
= s
->streams
[rtsp_st
->stream_index
];
1002 s
->ctx_flags
|= AVFMTCTX_NOHEADER
;
1003 rtsp_st
->rtp_ctx
= rtp_parse_open(s
, st
, rtsp_st
->rtp_handle
, rtsp_st
->sdp_payload_type
, &rtsp_st
->rtp_payload_data
);
1005 if (!rtsp_st
->rtp_ctx
) {
1006 err
= AVERROR(ENOMEM
);
1009 if(rtsp_st
->dynamic_handler
) {
1010 rtsp_st
->rtp_ctx
->dynamic_protocol_context
= rtsp_st
->dynamic_protocol_context
;
1011 rtsp_st
->rtp_ctx
->parse_packet
= rtsp_st
->dynamic_handler
->parse_packet
;
1019 for (i
=0; i
<rt
->nb_rtsp_streams
; i
++) {
1020 if (rt
->rtsp_streams
[i
]->rtp_handle
) {
1021 url_close(rt
->rtsp_streams
[i
]->rtp_handle
);
1022 rt
->rtsp_streams
[i
]->rtp_handle
= NULL
;
1028 static int rtsp_read_header(AVFormatContext
*s
,
1029 AVFormatParameters
*ap
)
1031 RTSPState
*rt
= s
->priv_data
;
1032 char host
[1024], path
[1024], tcpname
[1024], cmd
[2048], *option_list
, *option
;
1033 URLContext
*rtsp_hd
;
1035 RTSPHeader reply1
, *reply
= &reply1
;
1036 unsigned char *content
= NULL
;
1037 int protocol_mask
= 0;
1039 /* extract hostname and port */
1040 url_split(NULL
, 0, NULL
, 0,
1041 host
, sizeof(host
), &port
, path
, sizeof(path
), s
->filename
);
1043 port
= RTSP_DEFAULT_PORT
;
1045 /* search for options */
1046 option_list
= strchr(path
, '?');
1048 /* remove the options from the path */
1050 while(option_list
) {
1051 /* move the option pointer */
1052 option
= option_list
;
1053 option_list
= strchr(option_list
, '&');
1055 *(option_list
++) = 0;
1056 /* handle the options */
1057 if (strcmp(option
, "udp") == 0)
1058 protocol_mask
= (1<< RTSP_PROTOCOL_RTP_UDP
);
1059 else if (strcmp(option
, "multicast") == 0)
1060 protocol_mask
= (1<< RTSP_PROTOCOL_RTP_UDP_MULTICAST
);
1061 else if (strcmp(option
, "tcp") == 0)
1062 protocol_mask
= (1<< RTSP_PROTOCOL_RTP_TCP
);
1067 protocol_mask
= (1 << RTSP_PROTOCOL_RTP_LAST
) - 1;
1069 /* open the tcp connexion */
1070 snprintf(tcpname
, sizeof(tcpname
), "tcp://%s:%d", host
, port
);
1071 if (url_open(&rtsp_hd
, tcpname
, URL_RDWR
) < 0)
1072 return AVERROR(EIO
);
1073 rt
->rtsp_hd
= rtsp_hd
;
1076 /* describe the stream */
1077 snprintf(cmd
, sizeof(cmd
),
1078 "DESCRIBE %s RTSP/1.0\r\n"
1079 "Accept: application/sdp\r\n",
1081 rtsp_send_cmd(s
, cmd
, reply
, &content
);
1083 err
= AVERROR_INVALIDDATA
;
1086 if (reply
->status_code
!= RTSP_STATUS_OK
) {
1087 err
= AVERROR_INVALIDDATA
;
1091 /* now we got the SDP description, we parse it */
1092 ret
= sdp_parse(s
, (const char *)content
);
1095 err
= AVERROR_INVALIDDATA
;
1100 int protocol
= ff_log2_tab
[protocol_mask
& ~(protocol_mask
- 1)];
1102 err
= make_setup_request(s
, host
, port
, protocol
);
1105 protocol_mask
&= ~(1 << protocol
);
1106 if (protocol_mask
== 0 && err
== 1) {
1107 err
= AVERROR(FF_NETERROR(EPROTONOSUPPORT
));
1112 rt
->state
= RTSP_STATE_IDLE
;
1113 rt
->seek_timestamp
= 0; /* default is to start stream at position
1115 if (ap
->initial_pause
) {
1116 /* do not start immediately */
1118 if (rtsp_read_play(s
) < 0) {
1119 err
= AVERROR_INVALIDDATA
;
1125 rtsp_close_streams(rt
);
1127 url_close(rt
->rtsp_hd
);
1131 static int tcp_read_packet(AVFormatContext
*s
, RTSPStream
**prtsp_st
,
1132 uint8_t *buf
, int buf_size
)
1134 RTSPState
*rt
= s
->priv_data
;
1135 int id
, len
, i
, ret
;
1136 RTSPStream
*rtsp_st
;
1138 #ifdef DEBUG_RTP_TCP
1139 printf("tcp_read_packet:\n");
1143 ret
= url_readbuf(rt
->rtsp_hd
, buf
, 1);
1144 #ifdef DEBUG_RTP_TCP
1145 printf("ret=%d c=%02x [%c]\n", ret
, buf
[0], buf
[0]);
1152 ret
= url_readbuf(rt
->rtsp_hd
, buf
, 3);
1156 len
= AV_RB16(buf
+ 1);
1157 #ifdef DEBUG_RTP_TCP
1158 printf("id=%d len=%d\n", id
, len
);
1160 if (len
> buf_size
|| len
< 12)
1163 ret
= url_readbuf(rt
->rtsp_hd
, buf
, len
);
1167 /* find the matching stream */
1168 for(i
= 0; i
< rt
->nb_rtsp_streams
; i
++) {
1169 rtsp_st
= rt
->rtsp_streams
[i
];
1170 if (id
>= rtsp_st
->interleaved_min
&&
1171 id
<= rtsp_st
->interleaved_max
)
1176 *prtsp_st
= rtsp_st
;
1180 static int udp_read_packet(AVFormatContext
*s
, RTSPStream
**prtsp_st
,
1181 uint8_t *buf
, int buf_size
)
1183 RTSPState
*rt
= s
->priv_data
;
1184 RTSPStream
*rtsp_st
;
1186 int fd1
, fd2
, fd_max
, n
, i
, ret
;
1190 if (url_interrupt_cb())
1191 return AVERROR(EINTR
);
1194 for(i
= 0; i
< rt
->nb_rtsp_streams
; i
++) {
1195 rtsp_st
= rt
->rtsp_streams
[i
];
1196 /* currently, we cannot probe RTCP handle because of blocking restrictions */
1197 rtp_get_file_handles(rtsp_st
->rtp_handle
, &fd1
, &fd2
);
1203 tv
.tv_usec
= 100 * 1000;
1204 n
= select(fd_max
+ 1, &rfds
, NULL
, NULL
, &tv
);
1206 for(i
= 0; i
< rt
->nb_rtsp_streams
; i
++) {
1207 rtsp_st
= rt
->rtsp_streams
[i
];
1208 rtp_get_file_handles(rtsp_st
->rtp_handle
, &fd1
, &fd2
);
1209 if (FD_ISSET(fd1
, &rfds
)) {
1210 ret
= url_read(rtsp_st
->rtp_handle
, buf
, buf_size
);
1212 *prtsp_st
= rtsp_st
;
1221 static int rtsp_read_packet(AVFormatContext
*s
,
1224 RTSPState
*rt
= s
->priv_data
;
1225 RTSPStream
*rtsp_st
;
1227 uint8_t buf
[RTP_MAX_PACKET_LENGTH
];
1229 /* get next frames from the same RTP packet */
1231 ret
= rtp_parse_packet(rt
->cur_rtp
, pkt
, NULL
, 0);
1235 } else if (ret
== 1) {
1242 /* read next RTP packet */
1244 switch(rt
->protocol
) {
1246 case RTSP_PROTOCOL_RTP_TCP
:
1247 len
= tcp_read_packet(s
, &rtsp_st
, buf
, sizeof(buf
));
1249 case RTSP_PROTOCOL_RTP_UDP
:
1250 case RTSP_PROTOCOL_RTP_UDP_MULTICAST
:
1251 len
= udp_read_packet(s
, &rtsp_st
, buf
, sizeof(buf
));
1252 if (len
>=0 && rtsp_st
->rtp_ctx
)
1253 rtp_check_and_send_back_rr(rtsp_st
->rtp_ctx
, len
);
1258 ret
= rtp_parse_packet(rtsp_st
->rtp_ctx
, pkt
, buf
, len
);
1262 /* more packets may follow, so we save the RTP context */
1263 rt
->cur_rtp
= rtsp_st
->rtp_ctx
;
1268 static int rtsp_read_play(AVFormatContext
*s
)
1270 RTSPState
*rt
= s
->priv_data
;
1271 RTSPHeader reply1
, *reply
= &reply1
;
1274 av_log(s
, AV_LOG_DEBUG
, "hello state=%d\n", rt
->state
);
1276 if (rt
->state
== RTSP_STATE_PAUSED
) {
1277 snprintf(cmd
, sizeof(cmd
),
1278 "PLAY %s RTSP/1.0\r\n",
1281 snprintf(cmd
, sizeof(cmd
),
1282 "PLAY %s RTSP/1.0\r\n"
1283 "Range: npt=%0.3f-\r\n",
1285 (double)rt
->seek_timestamp
/ AV_TIME_BASE
);
1287 rtsp_send_cmd(s
, cmd
, reply
, NULL
);
1288 if (reply
->status_code
!= RTSP_STATUS_OK
) {
1291 rt
->state
= RTSP_STATE_PLAYING
;
1296 /* pause the stream */
1297 static int rtsp_read_pause(AVFormatContext
*s
)
1299 RTSPState
*rt
= s
->priv_data
;
1300 RTSPHeader reply1
, *reply
= &reply1
;
1305 if (rt
->state
!= RTSP_STATE_PLAYING
)
1308 snprintf(cmd
, sizeof(cmd
),
1309 "PAUSE %s RTSP/1.0\r\n",
1311 rtsp_send_cmd(s
, cmd
, reply
, NULL
);
1312 if (reply
->status_code
!= RTSP_STATUS_OK
) {
1315 rt
->state
= RTSP_STATE_PAUSED
;
1320 static int rtsp_read_seek(AVFormatContext
*s
, int stream_index
,
1321 int64_t timestamp
, int flags
)
1323 RTSPState
*rt
= s
->priv_data
;
1325 rt
->seek_timestamp
= av_rescale_q(timestamp
, s
->streams
[stream_index
]->time_base
, AV_TIME_BASE_Q
);
1328 case RTSP_STATE_IDLE
:
1330 case RTSP_STATE_PLAYING
:
1331 if (rtsp_read_play(s
) != 0)
1334 case RTSP_STATE_PAUSED
:
1335 rt
->state
= RTSP_STATE_IDLE
;
1341 static int rtsp_read_close(AVFormatContext
*s
)
1343 RTSPState
*rt
= s
->priv_data
;
1344 RTSPHeader reply1
, *reply
= &reply1
;
1348 /* NOTE: it is valid to flush the buffer here */
1349 if (rt
->protocol
== RTSP_PROTOCOL_RTP_TCP
) {
1350 url_fclose(&rt
->rtsp_gb
);
1353 snprintf(cmd
, sizeof(cmd
),
1354 "TEARDOWN %s RTSP/1.0\r\n",
1356 rtsp_send_cmd(s
, cmd
, reply
, NULL
);
1358 rtsp_close_streams(rt
);
1359 url_close(rt
->rtsp_hd
);
1363 #ifdef CONFIG_RTSP_DEMUXER
1364 AVInputFormat rtsp_demuxer
= {
1366 NULL_IF_CONFIG_SMALL("RTSP input format"),
1373 .flags
= AVFMT_NOFILE
,
1374 .read_play
= rtsp_read_play
,
1375 .read_pause
= rtsp_read_pause
,
1379 static int sdp_probe(AVProbeData
*p1
)
1381 const char *p
= p1
->buf
, *p_end
= p1
->buf
+ p1
->buf_size
;
1383 /* we look for a line beginning "c=IN IP4" */
1384 while (p
< p_end
&& *p
!= '\0') {
1385 if (p
+ sizeof("c=IN IP4") - 1 < p_end
&& av_strstart(p
, "c=IN IP4", NULL
))
1386 return AVPROBE_SCORE_MAX
/ 2;
1388 while(p
< p_end
- 1 && *p
!= '\n') p
++;
1397 #define SDP_MAX_SIZE 8192
1399 static int sdp_read_header(AVFormatContext
*s
,
1400 AVFormatParameters
*ap
)
1402 RTSPState
*rt
= s
->priv_data
;
1403 RTSPStream
*rtsp_st
;
1409 /* read the whole sdp file */
1410 /* XXX: better loading */
1411 content
= av_malloc(SDP_MAX_SIZE
);
1412 size
= get_buffer(s
->pb
, content
, SDP_MAX_SIZE
- 1);
1415 return AVERROR_INVALIDDATA
;
1417 content
[size
] ='\0';
1419 sdp_parse(s
, content
);
1422 /* open each RTP stream */
1423 for(i
=0;i
<rt
->nb_rtsp_streams
;i
++) {
1424 rtsp_st
= rt
->rtsp_streams
[i
];
1426 snprintf(url
, sizeof(url
), "rtp://%s:%d?localport=%d&ttl=%d",
1427 inet_ntoa(rtsp_st
->sdp_ip
),
1431 if (url_open(&rtsp_st
->rtp_handle
, url
, URL_RDWR
) < 0) {
1432 err
= AVERROR_INVALIDDATA
;
1435 /* open the RTP context */
1437 if (rtsp_st
->stream_index
>= 0)
1438 st
= s
->streams
[rtsp_st
->stream_index
];
1440 s
->ctx_flags
|= AVFMTCTX_NOHEADER
;
1441 rtsp_st
->rtp_ctx
= rtp_parse_open(s
, st
, rtsp_st
->rtp_handle
, rtsp_st
->sdp_payload_type
, &rtsp_st
->rtp_payload_data
);
1442 if (!rtsp_st
->rtp_ctx
) {
1443 err
= AVERROR(ENOMEM
);
1446 if(rtsp_st
->dynamic_handler
) {
1447 rtsp_st
->rtp_ctx
->dynamic_protocol_context
= rtsp_st
->dynamic_protocol_context
;
1448 rtsp_st
->rtp_ctx
->parse_packet
= rtsp_st
->dynamic_handler
->parse_packet
;
1454 rtsp_close_streams(rt
);
1458 static int sdp_read_packet(AVFormatContext
*s
,
1461 return rtsp_read_packet(s
, pkt
);
1464 static int sdp_read_close(AVFormatContext
*s
)
1466 RTSPState
*rt
= s
->priv_data
;
1467 rtsp_close_streams(rt
);
1471 #ifdef CONFIG_SDP_DEMUXER
1472 AVInputFormat sdp_demuxer
= {
1474 NULL_IF_CONFIG_SMALL("SDP"),
1483 #ifdef CONFIG_REDIR_DEMUXER
1484 /* dummy redirector format (used directly in av_open_input_file now) */
1485 static int redir_probe(AVProbeData
*pd
)
1489 while (redir_isspace(*p
))
1491 if (av_strstart(p
, "http://", NULL
) ||
1492 av_strstart(p
, "rtsp://", NULL
))
1493 return AVPROBE_SCORE_MAX
;
1497 static int redir_read_header(AVFormatContext
*s
, AVFormatParameters
*ap
)
1501 AVFormatContext
*ic
= NULL
;
1502 ByteIOContext
*f
= s
->pb
;
1504 /* parse each URL and try to open it */
1506 while (c
!= URL_EOF
) {
1509 if (!redir_isspace(c
))
1518 if (c
== URL_EOF
|| redir_isspace(c
))
1520 if ((q
- buf
) < sizeof(buf
) - 1)
1525 //printf("URL='%s'\n", buf);
1526 /* try to open the media file */
1527 if (av_open_input_file(&ic
, buf
, NULL
, 0, NULL
) == 0)
1531 return AVERROR(EIO
);
1539 AVInputFormat redir_demuxer
= {
1541 NULL_IF_CONFIG_SMALL("Redirector format"),