Originally committed as revision 17614 to svn://svn.ffmpeg.org/ffmpeg/trunk
Ronald S. Bultje authored on 2009/02/26 23:15:41... | ... |
@@ -27,16 +27,24 @@ |
27 | 27 |
#include "rtpdec.h" |
28 | 28 |
#include "network.h" |
29 | 29 |
|
30 |
+/** |
|
31 |
+ * Network layer over which RTP/etc packet data will be transported. |
|
32 |
+ */ |
|
30 | 33 |
enum RTSPLowerTransport { |
31 |
- RTSP_LOWER_TRANSPORT_UDP = 0, |
|
32 |
- RTSP_LOWER_TRANSPORT_TCP = 1, |
|
33 |
- RTSP_LOWER_TRANSPORT_UDP_MULTICAST = 2, |
|
34 |
+ RTSP_LOWER_TRANSPORT_UDP = 0, /**< UDP/unicast */ |
|
35 |
+ RTSP_LOWER_TRANSPORT_TCP = 1, /**< TCP; interleaved in RTSP */ |
|
36 |
+ RTSP_LOWER_TRANSPORT_UDP_MULTICAST = 2, /**< UDP/multicast */ |
|
34 | 37 |
RTSP_LOWER_TRANSPORT_NB |
35 | 38 |
}; |
36 | 39 |
|
40 |
+/** |
|
41 |
+ * Packet profile of the data that we will be receiving. Real servers |
|
42 |
+ * commonly send RDT (although they can sometimes send RTP as well), |
|
43 |
+ * whereas most others will send RTP. |
|
44 |
+ */ |
|
37 | 45 |
enum RTSPTransport { |
38 |
- RTSP_TRANSPORT_RTP, |
|
39 |
- RTSP_TRANSPORT_RDT, |
|
46 |
+ RTSP_TRANSPORT_RTP, /**< Standards-compliant RTP */ |
|
47 |
+ RTSP_TRANSPORT_RDT, /**< Realmedia Data Transport */ |
|
40 | 48 |
RTSP_TRANSPORT_NB |
41 | 49 |
}; |
42 | 50 |
|
... | ... |
@@ -48,36 +56,99 @@ enum RTSPTransport { |
48 | 48 |
#define RTSP_RTP_PORT_MIN 5000 |
49 | 49 |
#define RTSP_RTP_PORT_MAX 10000 |
50 | 50 |
|
51 |
+/** |
|
52 |
+ * This describes a single item in the "Transport:" line of one stream as |
|
53 |
+ * negotiated by the SETUP RTSP command. Multiple transports are comma- |
|
54 |
+ * separated ("Transport: x-read-rdt/tcp;interleaved=0-1,rtp/avp/udp; |
|
55 |
+ * client_port=1000-1001;server_port=1800-1801") and described in separate |
|
56 |
+ * RTSPTransportFields. |
|
57 |
+ */ |
|
51 | 58 |
typedef struct RTSPTransportField { |
52 |
- int interleaved_min, interleaved_max; /**< interleave ids, if TCP transport */ |
|
53 |
- int port_min, port_max; /**< RTP ports */ |
|
54 |
- int client_port_min, client_port_max; /**< RTP ports */ |
|
55 |
- int server_port_min, server_port_max; /**< RTP ports */ |
|
56 |
- int ttl; /**< ttl value */ |
|
59 |
+ /** interleave ids, if TCP transport; each TCP/RTSP data packet starts |
|
60 |
+ * with a '$', stream length and stream ID. If the stream ID is within |
|
61 |
+ * the range of this interleaved_min-max, then the packet belongs to |
|
62 |
+ * this stream. */ |
|
63 |
+ int interleaved_min, interleaved_max; |
|
64 |
+ |
|
65 |
+ /** UDP multicast port range; the ports to which we should connect to |
|
66 |
+ * receive multicast UDP data. */ |
|
67 |
+ int port_min, port_max; |
|
68 |
+ |
|
69 |
+ /** UDP client ports; these should be the local ports of the UDP RTP |
|
70 |
+ * (and RTCP) sockets over which we receive RTP/RTCP data. */ |
|
71 |
+ int client_port_min, client_port_max; |
|
72 |
+ |
|
73 |
+ /** UDP unicast server port range; the ports to which we should connect |
|
74 |
+ * to receive unicast UDP RTP/RTCP data. */ |
|
75 |
+ int server_port_min, server_port_max; |
|
76 |
+ |
|
77 |
+ /** time-to-live value (required for multicast); the amount of HOPs that |
|
78 |
+ * packets will be allowed to make before being discarded. */ |
|
79 |
+ int ttl; |
|
80 |
+ |
|
57 | 81 |
uint32_t destination; /**< destination IP address */ |
82 |
+ |
|
83 |
+ /** data/packet transport protocol; e.g. RTP or RDT */ |
|
58 | 84 |
enum RTSPTransport transport; |
85 |
+ |
|
86 |
+ /** network layer transport protocol; e.g. TCP or UDP uni-/multicast */ |
|
59 | 87 |
enum RTSPLowerTransport lower_transport; |
60 | 88 |
} RTSPTransportField; |
61 | 89 |
|
90 |
+/** |
|
91 |
+ * This describes the server response to each RTSP command. |
|
92 |
+ */ |
|
62 | 93 |
typedef struct RTSPMessageHeader { |
94 |
+ /** length of the data following this header */ |
|
63 | 95 |
int content_length; |
96 |
+ |
|
64 | 97 |
enum RTSPStatusCode status_code; /**< response code from server */ |
98 |
+ |
|
99 |
+ /** number of items in the 'transports' variable below */ |
|
65 | 100 |
int nb_transports; |
66 |
- /** in AV_TIME_BASE unit, AV_NOPTS_VALUE if not used */ |
|
101 |
+ |
|
102 |
+ /** Time range of the streams that the server will stream. In |
|
103 |
+ * AV_TIME_BASE unit, AV_NOPTS_VALUE if not used */ |
|
67 | 104 |
int64_t range_start, range_end; |
105 |
+ |
|
106 |
+ /** describes the complete "Transport:" line of the server in response |
|
107 |
+ * to a SETUP RTSP command by the client */ |
|
68 | 108 |
RTSPTransportField transports[RTSP_MAX_TRANSPORTS]; |
69 |
- int seq; /**< sequence number */ |
|
109 |
+ |
|
110 |
+ int seq; /**< sequence number */ |
|
111 |
+ |
|
112 |
+ /** the "Session:" field. This value is initially set by the server and |
|
113 |
+ * should be re-transmitted by the client in every RTSP command. */ |
|
70 | 114 |
char session_id[512]; |
71 |
- char real_challenge[64]; /**< the RealChallenge1 field from the server */ |
|
115 |
+ |
|
116 |
+ /** the "RealChallenge1:" field from the server */ |
|
117 |
+ char real_challenge[64]; |
|
118 |
+ |
|
119 |
+ /** the "Server: field, which can be used to identify some special-case |
|
120 |
+ * servers that are not 100% standards-compliant. We use this to identify |
|
121 |
+ * Windows Media Server, which has a value "WMServer/v.e.r.sion", where |
|
122 |
+ * version is a sequence of digits (e.g. 9.0.0.3372). Helix/Real servers |
|
123 |
+ * use something like "Helix [..] Server Version v.e.r.sion (platform) |
|
124 |
+ * (RealServer compatible)" or "RealServer Version v.e.r.sion (platform)", |
|
125 |
+ * where platform is the output of $uname -msr | sed 's/ /-/g'. */ |
|
72 | 126 |
char server[64]; |
73 | 127 |
} RTSPMessageHeader; |
74 | 128 |
|
129 |
+/** |
|
130 |
+ * Client state, i.e. whether we are currently receiving data (PLAYING) or |
|
131 |
+ * setup-but-not-receiving (PAUSED). State can be changed in applications |
|
132 |
+ * by calling av_read_play/pause(). |
|
133 |
+ */ |
|
75 | 134 |
enum RTSPClientState { |
76 |
- RTSP_STATE_IDLE, |
|
77 |
- RTSP_STATE_PLAYING, |
|
78 |
- RTSP_STATE_PAUSED, |
|
135 |
+ RTSP_STATE_IDLE, /**< not initialized */ |
|
136 |
+ RTSP_STATE_PLAYING, /**< initialized and receiving data */ |
|
137 |
+ RTSP_STATE_PAUSED, /**< initialized, but not receiving data */ |
|
79 | 138 |
}; |
80 | 139 |
|
140 |
+/** |
|
141 |
+ * Identifies particular servers that require special handling, such as |
|
142 |
+ * standards-incompliant "Transport:" lines in the SETUP request. |
|
143 |
+ */ |
|
81 | 144 |
enum RTSPServerType { |
82 | 145 |
RTSP_SERVER_RTP, /**< Standards-compliant RTP-server */ |
83 | 146 |
RTSP_SERVER_REAL, /**< Realmedia-style server */ |
... | ... |
@@ -85,44 +156,115 @@ enum RTSPServerType { |
85 | 85 |
RTSP_SERVER_NB |
86 | 86 |
}; |
87 | 87 |
|
88 |
+/** |
|
89 |
+ * Private data for the RTSP demuxer. |
|
90 |
+ */ |
|
88 | 91 |
typedef struct RTSPState { |
89 | 92 |
URLContext *rtsp_hd; /* RTSP TCP connexion handle */ |
93 |
+ |
|
94 |
+ /** number of items in the 'rtsp_streams' variable */ |
|
90 | 95 |
int nb_rtsp_streams; |
91 |
- struct RTSPStream **rtsp_streams; |
|
92 | 96 |
|
97 |
+ struct RTSPStream **rtsp_streams; /**< streams in this session */ |
|
98 |
+ |
|
99 |
+ /** indicator of whether we are currently receiving data from the |
|
100 |
+ * server. Basically this isn't more than a simple cache of the |
|
101 |
+ * last PLAY/PAUSE command sent to the server, to make sure we don't |
|
102 |
+ * send 2x the same unexpectedly or commands in the wrong state. */ |
|
93 | 103 |
enum RTSPClientState state; |
104 |
+ |
|
105 |
+ /** the seek value requested when calling av_seek_frame(). This value |
|
106 |
+ * is subsequently used as part of the "Range" parameter when emitting |
|
107 |
+ * the RTSP PLAY command. If we are currently playing, this command is |
|
108 |
+ * called instantly. If we are currently paused, this command is called |
|
109 |
+ * whenever we resume playback. Either way, the value is only used once, |
|
110 |
+ * see rtsp_read_play() and rtsp_read_seek(). */ |
|
94 | 111 |
int64_t seek_timestamp; |
95 | 112 |
|
96 | 113 |
/* XXX: currently we use unbuffered input */ |
97 | 114 |
// ByteIOContext rtsp_gb; |
98 |
- int seq; /* RTSP command sequence number */ |
|
115 |
+ |
|
116 |
+ int seq; /**< RTSP command sequence number */ |
|
117 |
+ |
|
118 |
+ /** copy of RTSPMessageHeader->session_id, i.e. the server-provided session |
|
119 |
+ * identifier that the client should re-transmit in each RTSP command */ |
|
99 | 120 |
char session_id[512]; |
121 |
+ |
|
122 |
+ /** the negotiated data/packet transport protocol; e.g. RTP or RDT */ |
|
100 | 123 |
enum RTSPTransport transport; |
124 |
+ |
|
125 |
+ /** the negotiated network layer transport protocol; e.g. TCP or UDP |
|
126 |
+ * uni-/multicast */ |
|
101 | 127 |
enum RTSPLowerTransport lower_transport; |
128 |
+ |
|
129 |
+ /** brand of server that we're talking to; e.g. WMS, REAL or other. |
|
130 |
+ * Detected based on the value of RTSPMessageHeader->server or the presence |
|
131 |
+ * of RTSPMessageHeader->real_challenge */ |
|
102 | 132 |
enum RTSPServerType server_type; |
133 |
+ |
|
134 |
+ /** The last reply of the server to a RTSP command */ |
|
103 | 135 |
char last_reply[2048]; /* XXX: allocate ? */ |
136 |
+ |
|
137 |
+ /** RTSPStream->transport_priv of the last stream that we read a |
|
138 |
+ * packet from */ |
|
104 | 139 |
void *cur_transport_priv; |
140 |
+ |
|
141 |
+ /** The following are used for Real stream selection */ |
|
142 |
+ //@{ |
|
143 |
+ /** whether we need to send a "SET_PARAMETER Subscribe:" command */ |
|
105 | 144 |
int need_subscription; |
145 |
+ |
|
146 |
+ /** stream setup during the last frame read. This is used to detect if |
|
147 |
+ * we need to subscribe or unsubscribe to any new streams. */ |
|
106 | 148 |
enum AVDiscard real_setup_cache[MAX_STREAMS]; |
149 |
+ |
|
150 |
+ /** the last value of the "SET_PARAMETER Subscribe:" RTSP command. |
|
151 |
+ * this is used to send the same "Unsubscribe:" if stream setup changed, |
|
152 |
+ * before sending a new "Subscribe:" command. */ |
|
107 | 153 |
char last_subscription[1024]; |
154 |
+ //@} |
|
108 | 155 |
} RTSPState; |
109 | 156 |
|
157 |
+/** |
|
158 |
+ * Describes a single stream, as identified by a single m= line block in the |
|
159 |
+ * SDP content. In the case of RDT, one RTSPStream can represent multiple |
|
160 |
+ * AVStreams. In this case, each AVStream in this set has similar content |
|
161 |
+ * (but different codec/bitrate). |
|
162 |
+ */ |
|
110 | 163 |
typedef struct RTSPStream { |
111 |
- URLContext *rtp_handle; /* RTP stream handle */ |
|
112 |
- void *transport_priv; /* RTP/RDT parse context */ |
|
164 |
+ URLContext *rtp_handle; /**< RTP stream handle (if UDP) */ |
|
165 |
+ void *transport_priv; /**< RTP/RDT parse context */ |
|
166 |
+ |
|
167 |
+ /** corresponding stream index, if any. -1 if none (MPEG2TS case) */ |
|
168 |
+ int stream_index; |
|
169 |
+ |
|
170 |
+ /** interleave IDs; copies of RTSPTransportField->interleaved_min/max |
|
171 |
+ * for the selected transport. Only used for TCP. */ |
|
172 |
+ int interleaved_min, interleaved_max; |
|
173 |
+ |
|
174 |
+ char control_url[1024]; /**< url for this stream (from SDP) */ |
|
175 |
+ |
|
176 |
+ /** The following are used only in SDP, not RTSP */ |
|
177 |
+ //@{ |
|
178 |
+ int sdp_port; /**< port (from SDP content) */ |
|
179 |
+ struct in_addr sdp_ip; /**< IP address (from SDP content) */ |
|
180 |
+ int sdp_ttl; /**< IP Time-To-Live (from SDP content) */ |
|
181 |
+ int sdp_payload_type; /**< payload type */ |
|
182 |
+ //@} |
|
113 | 183 |
|
114 |
- int stream_index; /* corresponding stream index, if any. -1 if none (MPEG2TS case) */ |
|
115 |
- int interleaved_min, interleaved_max; /* interleave ids, if TCP transport */ |
|
116 |
- char control_url[1024]; /* url for this stream (from SDP) */ |
|
184 |
+ /** rtp payload parsing infos from SDP (i.e. mapping between private |
|
185 |
+ * payload IDs and media-types (string), so that we can derive what |
|
186 |
+ * type of payload we're dealing with (and how to parse it). */ |
|
187 |
+ RTPPayloadData rtp_payload_data; |
|
117 | 188 |
|
118 |
- int sdp_port; /* port (from SDP content - not used in RTSP) */ |
|
119 |
- struct in_addr sdp_ip; /* IP address (from SDP content - not used in RTSP) */ |
|
120 |
- int sdp_ttl; /* IP TTL (from SDP content - not used in RTSP) */ |
|
121 |
- int sdp_payload_type; /* payload type - only used in SDP */ |
|
122 |
- RTPPayloadData rtp_payload_data; /* rtp payload parsing infos from SDP */ |
|
189 |
+ /** The following are used for dynamic protocols (rtp_*.c/rdt.c) */ |
|
190 |
+ //@{ |
|
191 |
+ /** handler structure */ |
|
192 |
+ RTPDynamicProtocolHandler *dynamic_handler; |
|
123 | 193 |
|
124 |
- RTPDynamicProtocolHandler *dynamic_handler; ///< Only valid if it's a dynamic protocol. (This is the handler structure) |
|
125 |
- PayloadContext *dynamic_protocol_context; ///< Only valid if it's a dynamic protocol. (This is any private data associated with the dynamic protocol) |
|
194 |
+ /** private data associated with the dynamic protocol */ |
|
195 |
+ PayloadContext *dynamic_protocol_context; |
|
196 |
+ //@} |
|
126 | 197 |
} RTSPStream; |
127 | 198 |
|
128 | 199 |
int rtsp_init(void); |