Originally committed as revision 22675 to svn://svn.ffmpeg.org/ffmpeg/trunk
Martin Storsjö authored on 2010/03/26 06:46:14... | ... |
@@ -994,7 +994,8 @@ int ff_rtsp_read_reply(AVFormatContext *s, RTSPMessageHeader *reply, |
994 | 994 |
} |
995 | 995 |
|
996 | 996 |
void ff_rtsp_send_cmd_with_content_async(AVFormatContext *s, |
997 |
- const char *cmd, |
|
997 |
+ const char *method, const char *url, |
|
998 |
+ const char *headers, |
|
998 | 999 |
const unsigned char *send_content, |
999 | 1000 |
int send_content_length) |
1000 | 1001 |
{ |
... | ... |
@@ -1002,10 +1003,13 @@ void ff_rtsp_send_cmd_with_content_async(AVFormatContext *s, |
1002 | 1002 |
char buf[4096], buf1[1024]; |
1003 | 1003 |
|
1004 | 1004 |
rt->seq++; |
1005 |
- av_strlcpy(buf, cmd, sizeof(buf)); |
|
1005 |
+ snprintf(buf, sizeof(buf), "%s %s RTSP/1.0\r\n", method, url); |
|
1006 |
+ if (headers) |
|
1007 |
+ av_strlcat(buf, headers, sizeof(buf)); |
|
1006 | 1008 |
snprintf(buf1, sizeof(buf1), "CSeq: %d\r\n", rt->seq); |
1007 | 1009 |
av_strlcat(buf, buf1, sizeof(buf)); |
1008 |
- if (rt->session_id[0] != '\0' && !strstr(cmd, "\nIf-Match:")) { |
|
1010 |
+ if (rt->session_id[0] != '\0' && (!headers || |
|
1011 |
+ !strstr(headers, "\nIf-Match:"))) { |
|
1009 | 1012 |
snprintf(buf1, sizeof(buf1), "Session: %s\r\n", rt->session_id); |
1010 | 1013 |
av_strlcat(buf, buf1, sizeof(buf)); |
1011 | 1014 |
} |
... | ... |
@@ -1025,26 +1029,30 @@ void ff_rtsp_send_cmd_with_content_async(AVFormatContext *s, |
1025 | 1025 |
rt->last_cmd_time = av_gettime(); |
1026 | 1026 |
} |
1027 | 1027 |
|
1028 |
-void ff_rtsp_send_cmd_async(AVFormatContext *s, const char *cmd) |
|
1028 |
+void ff_rtsp_send_cmd_async(AVFormatContext *s, const char *method, |
|
1029 |
+ const char *url, const char *headers) |
|
1029 | 1030 |
{ |
1030 |
- ff_rtsp_send_cmd_with_content_async(s, cmd, NULL, 0); |
|
1031 |
+ ff_rtsp_send_cmd_with_content_async(s, method, url, headers, NULL, 0); |
|
1031 | 1032 |
} |
1032 | 1033 |
|
1033 |
-void ff_rtsp_send_cmd(AVFormatContext *s, |
|
1034 |
- const char *cmd, RTSPMessageHeader *reply, |
|
1034 |
+void ff_rtsp_send_cmd(AVFormatContext *s, const char *method, const char *url, |
|
1035 |
+ const char *headers, RTSPMessageHeader *reply, |
|
1035 | 1036 |
unsigned char **content_ptr) |
1036 | 1037 |
{ |
1037 |
- ff_rtsp_send_cmd_with_content(s, cmd, reply, content_ptr, NULL, 0); |
|
1038 |
+ ff_rtsp_send_cmd_with_content(s, method, url, headers, reply, |
|
1039 |
+ content_ptr, NULL, 0); |
|
1038 | 1040 |
} |
1039 | 1041 |
|
1040 | 1042 |
void ff_rtsp_send_cmd_with_content(AVFormatContext *s, |
1041 |
- const char *cmd, |
|
1043 |
+ const char *method, const char *url, |
|
1044 |
+ const char *header, |
|
1042 | 1045 |
RTSPMessageHeader *reply, |
1043 | 1046 |
unsigned char **content_ptr, |
1044 | 1047 |
const unsigned char *send_content, |
1045 | 1048 |
int send_content_length) |
1046 | 1049 |
{ |
1047 |
- ff_rtsp_send_cmd_with_content_async(s, cmd, send_content, send_content_length); |
|
1050 |
+ ff_rtsp_send_cmd_with_content_async(s, method, url, header, |
|
1051 |
+ send_content, send_content_length); |
|
1048 | 1052 |
|
1049 | 1053 |
ff_rtsp_read_reply(s, reply, content_ptr, 0); |
1050 | 1054 |
} |
... | ... |
@@ -1173,9 +1181,8 @@ static int make_setup_request(AVFormatContext *s, const char *host, int port, |
1173 | 1173 |
rt->server_type == RTSP_SERVER_WMS) |
1174 | 1174 |
av_strlcat(transport, ";mode=play", sizeof(transport)); |
1175 | 1175 |
snprintf(cmd, sizeof(cmd), |
1176 |
- "SETUP %s RTSP/1.0\r\n" |
|
1177 | 1176 |
"Transport: %s\r\n", |
1178 |
- rtsp_st->control_url, transport); |
|
1177 |
+ transport); |
|
1179 | 1178 |
if (i == 0 && rt->server_type == RTSP_SERVER_REAL) { |
1180 | 1179 |
char real_res[41], real_csum[9]; |
1181 | 1180 |
ff_rdt_calc_response_and_checksum(real_res, real_csum, |
... | ... |
@@ -1185,7 +1192,7 @@ static int make_setup_request(AVFormatContext *s, const char *host, int port, |
1185 | 1185 |
"RealChallenge2: %s, sd=%s\r\n", |
1186 | 1186 |
rt->session_id, real_res, real_csum); |
1187 | 1187 |
} |
1188 |
- ff_rtsp_send_cmd(s, cmd, reply, NULL); |
|
1188 |
+ ff_rtsp_send_cmd(s, "SETUP", rtsp_st->control_url, cmd, reply, NULL); |
|
1189 | 1189 |
if (reply->status_code == 461 /* Unsupported protocol */ && i == 0) { |
1190 | 1190 |
err = 1; |
1191 | 1191 |
goto fail; |
... | ... |
@@ -1295,17 +1302,13 @@ static int rtsp_read_play(AVFormatContext *s) |
1295 | 1295 |
|
1296 | 1296 |
if (!(rt->server_type == RTSP_SERVER_REAL && rt->need_subscription)) { |
1297 | 1297 |
if (rt->state == RTSP_STATE_PAUSED) { |
1298 |
- snprintf(cmd, sizeof(cmd), |
|
1299 |
- "PLAY %s RTSP/1.0\r\n", |
|
1300 |
- rt->control_uri); |
|
1298 |
+ cmd[0] = 0; |
|
1301 | 1299 |
} else { |
1302 | 1300 |
snprintf(cmd, sizeof(cmd), |
1303 |
- "PLAY %s RTSP/1.0\r\n" |
|
1304 | 1301 |
"Range: npt=%0.3f-\r\n", |
1305 |
- rt->control_uri, |
|
1306 | 1302 |
(double)rt->seek_timestamp / AV_TIME_BASE); |
1307 | 1303 |
} |
1308 |
- ff_rtsp_send_cmd(s, cmd, reply, NULL); |
|
1304 |
+ ff_rtsp_send_cmd(s, "PLAY", rt->control_uri, cmd, reply, NULL); |
|
1309 | 1305 |
if (reply->status_code != RTSP_STATUS_OK) { |
1310 | 1306 |
return -1; |
1311 | 1307 |
} |
... | ... |
@@ -1323,9 +1326,7 @@ static int rtsp_setup_input_streams(AVFormatContext *s, RTSPMessageHeader *reply |
1323 | 1323 |
|
1324 | 1324 |
/* describe the stream */ |
1325 | 1325 |
snprintf(cmd, sizeof(cmd), |
1326 |
- "DESCRIBE %s RTSP/1.0\r\n" |
|
1327 |
- "Accept: application/sdp\r\n", |
|
1328 |
- rt->control_uri); |
|
1326 |
+ "Accept: application/sdp\r\n"); |
|
1329 | 1327 |
if (rt->server_type == RTSP_SERVER_REAL) { |
1330 | 1328 |
/** |
1331 | 1329 |
* The Require: attribute is needed for proper streaming from |
... | ... |
@@ -1335,7 +1336,7 @@ static int rtsp_setup_input_streams(AVFormatContext *s, RTSPMessageHeader *reply |
1335 | 1335 |
"Require: com.real.retain-entity-for-setup\r\n", |
1336 | 1336 |
sizeof(cmd)); |
1337 | 1337 |
} |
1338 |
- ff_rtsp_send_cmd(s, cmd, reply, &content); |
|
1338 |
+ ff_rtsp_send_cmd(s, "DESCRIBE", rt->control_uri, cmd, reply, &content); |
|
1339 | 1339 |
if (!content) |
1340 | 1340 |
return AVERROR_INVALIDDATA; |
1341 | 1341 |
if (reply->status_code != RTSP_STATUS_OK) { |
... | ... |
@@ -1356,7 +1357,6 @@ static int rtsp_setup_output_streams(AVFormatContext *s, const char *addr) |
1356 | 1356 |
{ |
1357 | 1357 |
RTSPState *rt = s->priv_data; |
1358 | 1358 |
RTSPMessageHeader reply1, *reply = &reply1; |
1359 |
- char cmd[1024]; |
|
1360 | 1359 |
int i; |
1361 | 1360 |
char *sdp; |
1362 | 1361 |
AVFormatContext sdp_ctx, *ctx_array[1]; |
... | ... |
@@ -1364,10 +1364,6 @@ static int rtsp_setup_output_streams(AVFormatContext *s, const char *addr) |
1364 | 1364 |
rt->start_time = av_gettime(); |
1365 | 1365 |
|
1366 | 1366 |
/* Announce the stream */ |
1367 |
- snprintf(cmd, sizeof(cmd), |
|
1368 |
- "ANNOUNCE %s RTSP/1.0\r\n" |
|
1369 |
- "Content-Type: application/sdp\r\n", |
|
1370 |
- rt->control_uri); |
|
1371 | 1367 |
sdp = av_mallocz(8192); |
1372 | 1368 |
if (sdp == NULL) |
1373 | 1369 |
return AVERROR(ENOMEM); |
... | ... |
@@ -1392,7 +1388,9 @@ static int rtsp_setup_output_streams(AVFormatContext *s, const char *addr) |
1392 | 1392 |
return AVERROR_INVALIDDATA; |
1393 | 1393 |
} |
1394 | 1394 |
av_log(s, AV_LOG_INFO, "SDP:\n%s\n", sdp); |
1395 |
- ff_rtsp_send_cmd_with_content(s, cmd, reply, NULL, sdp, strlen(sdp)); |
|
1395 |
+ ff_rtsp_send_cmd_with_content(s, "ANNOUNCE", rt->control_uri, |
|
1396 |
+ "Content-Type: application/sdp\r\n", |
|
1397 |
+ reply, NULL, sdp, strlen(sdp)); |
|
1396 | 1398 |
av_free(sdp); |
1397 | 1399 |
if (reply->status_code != RTSP_STATUS_OK) |
1398 | 1400 |
return AVERROR_INVALIDDATA; |
... | ... |
@@ -1521,8 +1519,7 @@ redirect: |
1521 | 1521 |
/* request options supported by the server; this also detects server |
1522 | 1522 |
* type */ |
1523 | 1523 |
for (rt->server_type = RTSP_SERVER_RTP;;) { |
1524 |
- snprintf(cmd, sizeof(cmd), |
|
1525 |
- "OPTIONS %s RTSP/1.0\r\n", rt->control_uri); |
|
1524 |
+ cmd[0] = 0; |
|
1526 | 1525 |
if (rt->server_type == RTSP_SERVER_REAL) |
1527 | 1526 |
av_strlcat(cmd, |
1528 | 1527 |
/** |
... | ... |
@@ -1539,7 +1536,7 @@ redirect: |
1539 | 1539 |
"CompanyID: KnKV4M4I/B2FjJ1TToLycw==\r\n" |
1540 | 1540 |
"GUID: 00000000-0000-0000-0000-000000000000\r\n", |
1541 | 1541 |
sizeof(cmd)); |
1542 |
- ff_rtsp_send_cmd(s, cmd, reply, NULL); |
|
1542 |
+ ff_rtsp_send_cmd(s, "OPTIONS", rt->control_uri, cmd, reply, NULL); |
|
1543 | 1543 |
if (reply->status_code != RTSP_STATUS_OK) { |
1544 | 1544 |
err = AVERROR_INVALIDDATA; |
1545 | 1545 |
goto fail; |
... | ... |
@@ -1812,10 +1809,10 @@ static int rtsp_read_packet(AVFormatContext *s, AVPacket *pkt) |
1812 | 1812 |
if (memcmp (cache, rt->real_setup_cache, |
1813 | 1813 |
sizeof(enum AVDiscard) * s->nb_streams)) { |
1814 | 1814 |
snprintf(cmd, sizeof(cmd), |
1815 |
- "SET_PARAMETER %s RTSP/1.0\r\n" |
|
1816 | 1815 |
"Unsubscribe: %s\r\n", |
1817 |
- rt->control_uri, rt->last_subscription); |
|
1818 |
- ff_rtsp_send_cmd(s, cmd, reply, NULL); |
|
1816 |
+ rt->last_subscription); |
|
1817 |
+ ff_rtsp_send_cmd(s, "SET_PARAMETER", rt->control_uri, |
|
1818 |
+ cmd, reply, NULL); |
|
1819 | 1819 |
if (reply->status_code != RTSP_STATUS_OK) |
1820 | 1820 |
return AVERROR_INVALIDDATA; |
1821 | 1821 |
rt->need_subscription = 1; |
... | ... |
@@ -1830,9 +1827,7 @@ static int rtsp_read_packet(AVFormatContext *s, AVPacket *pkt) |
1830 | 1830 |
rt->last_subscription[0] = 0; |
1831 | 1831 |
|
1832 | 1832 |
snprintf(cmd, sizeof(cmd), |
1833 |
- "SET_PARAMETER %s RTSP/1.0\r\n" |
|
1834 |
- "Subscribe: ", |
|
1835 |
- rt->control_uri); |
|
1833 |
+ "Subscribe: "); |
|
1836 | 1834 |
for (i = 0; i < rt->nb_rtsp_streams; i++) { |
1837 | 1835 |
rule_nr = 0; |
1838 | 1836 |
for (r = 0; r < s->nb_streams; r++) { |
... | ... |
@@ -1851,7 +1846,8 @@ static int rtsp_read_packet(AVFormatContext *s, AVPacket *pkt) |
1851 | 1851 |
} |
1852 | 1852 |
} |
1853 | 1853 |
av_strlcatf(cmd, sizeof(cmd), "%s\r\n", rt->last_subscription); |
1854 |
- ff_rtsp_send_cmd(s, cmd, reply, NULL); |
|
1854 |
+ ff_rtsp_send_cmd(s, "SET_PARAMETER", rt->control_uri, |
|
1855 |
+ cmd, reply, NULL); |
|
1855 | 1856 |
if (reply->status_code != RTSP_STATUS_OK) |
1856 | 1857 |
return AVERROR_INVALIDDATA; |
1857 | 1858 |
rt->need_subscription = 0; |
... | ... |
@@ -1870,12 +1866,9 @@ static int rtsp_read_packet(AVFormatContext *s, AVPacket *pkt) |
1870 | 1870 |
rt->server_type == RTSP_SERVER_REAL) && |
1871 | 1871 |
(av_gettime() - rt->last_cmd_time) / 1000000 >= rt->timeout / 2) { |
1872 | 1872 |
if (rt->server_type == RTSP_SERVER_WMS) { |
1873 |
- snprintf(cmd, sizeof(cmd) - 1, |
|
1874 |
- "GET_PARAMETER %s RTSP/1.0\r\n", |
|
1875 |
- rt->control_uri); |
|
1876 |
- ff_rtsp_send_cmd_async(s, cmd); |
|
1873 |
+ ff_rtsp_send_cmd_async(s, "GET_PARAMETER", rt->control_uri, NULL); |
|
1877 | 1874 |
} else { |
1878 |
- ff_rtsp_send_cmd_async(s, "OPTIONS * RTSP/1.0\r\n"); |
|
1875 |
+ ff_rtsp_send_cmd_async(s, "OPTIONS", "*", NULL); |
|
1879 | 1876 |
} |
1880 | 1877 |
} |
1881 | 1878 |
|
... | ... |
@@ -1887,17 +1880,13 @@ static int rtsp_read_pause(AVFormatContext *s) |
1887 | 1887 |
{ |
1888 | 1888 |
RTSPState *rt = s->priv_data; |
1889 | 1889 |
RTSPMessageHeader reply1, *reply = &reply1; |
1890 |
- char cmd[1024]; |
|
1891 | 1890 |
|
1892 | 1891 |
rt = s->priv_data; |
1893 | 1892 |
|
1894 | 1893 |
if (rt->state != RTSP_STATE_STREAMING) |
1895 | 1894 |
return 0; |
1896 | 1895 |
else if (!(rt->server_type == RTSP_SERVER_REAL && rt->need_subscription)) { |
1897 |
- snprintf(cmd, sizeof(cmd), |
|
1898 |
- "PAUSE %s RTSP/1.0\r\n", |
|
1899 |
- rt->control_uri); |
|
1900 |
- ff_rtsp_send_cmd(s, cmd, reply, NULL); |
|
1896 |
+ ff_rtsp_send_cmd(s, "PAUSE", rt->control_uri, NULL, reply, NULL); |
|
1901 | 1897 |
if (reply->status_code != RTSP_STATUS_OK) { |
1902 | 1898 |
return -1; |
1903 | 1899 |
} |
... | ... |
@@ -1935,7 +1924,6 @@ static int rtsp_read_seek(AVFormatContext *s, int stream_index, |
1935 | 1935 |
static int rtsp_read_close(AVFormatContext *s) |
1936 | 1936 |
{ |
1937 | 1937 |
RTSPState *rt = s->priv_data; |
1938 |
- char cmd[1024]; |
|
1939 | 1938 |
|
1940 | 1939 |
#if 0 |
1941 | 1940 |
/* NOTE: it is valid to flush the buffer here */ |
... | ... |
@@ -1943,10 +1931,7 @@ static int rtsp_read_close(AVFormatContext *s) |
1943 | 1943 |
url_fclose(&rt->rtsp_gb); |
1944 | 1944 |
} |
1945 | 1945 |
#endif |
1946 |
- snprintf(cmd, sizeof(cmd), |
|
1947 |
- "TEARDOWN %s RTSP/1.0\r\n", |
|
1948 |
- rt->control_uri); |
|
1949 |
- ff_rtsp_send_cmd_async(s, cmd); |
|
1946 |
+ ff_rtsp_send_cmd_async(s, "TEARDOWN", rt->control_uri, NULL); |
|
1950 | 1947 |
|
1951 | 1948 |
ff_rtsp_close_streams(s); |
1952 | 1949 |
url_close(rt->rtsp_hd); |
... | ... |
@@ -330,13 +330,16 @@ extern int rtsp_rtp_port_max; |
330 | 330 |
* Send a command to the RTSP server without waiting for the reply. |
331 | 331 |
* |
332 | 332 |
* @param s RTSP (de)muxer context |
333 |
- * @param cmd the full first line of the request |
|
333 |
+ * @param method the method for the request |
|
334 |
+ * @param url the target url for the request |
|
335 |
+ * @param headers extra header lines to include in the request |
|
334 | 336 |
* @param send_content if non-null, the data to send as request body content |
335 | 337 |
* @param send_content_length the length of the send_content data, or 0 if |
336 | 338 |
* send_content is null |
337 | 339 |
*/ |
338 | 340 |
void ff_rtsp_send_cmd_with_content_async(AVFormatContext *s, |
339 |
- const char *cmd, |
|
341 |
+ const char *method, const char *url, |
|
342 |
+ const char *headers, |
|
340 | 343 |
const unsigned char *send_content, |
341 | 344 |
int send_content_length); |
342 | 345 |
/** |
... | ... |
@@ -344,13 +347,16 @@ void ff_rtsp_send_cmd_with_content_async(AVFormatContext *s, |
344 | 344 |
* |
345 | 345 |
* @see rtsp_send_cmd_with_content_async |
346 | 346 |
*/ |
347 |
-void ff_rtsp_send_cmd_async(AVFormatContext *s, const char *cmd); |
|
347 |
+void ff_rtsp_send_cmd_async(AVFormatContext *s, const char *method, |
|
348 |
+ const char *url, const char *headers); |
|
348 | 349 |
|
349 | 350 |
/** |
350 | 351 |
* Send a command to the RTSP server and wait for the reply. |
351 | 352 |
* |
352 | 353 |
* @param s RTSP (de)muxer context |
353 |
- * @param cmd the full first line of the request |
|
354 |
+ * @param method the method for the request |
|
355 |
+ * @param url the target url for the request |
|
356 |
+ * @param headers extra header lines to include in the request |
|
354 | 357 |
* @param reply pointer where the RTSP message header will be stored |
355 | 358 |
* @param content_ptr pointer where the RTSP message body, if any, will |
356 | 359 |
* be stored (length is in reply) |
... | ... |
@@ -359,7 +365,8 @@ void ff_rtsp_send_cmd_async(AVFormatContext *s, const char *cmd); |
359 | 359 |
* send_content is null |
360 | 360 |
*/ |
361 | 361 |
void ff_rtsp_send_cmd_with_content(AVFormatContext *s, |
362 |
- const char *cmd, |
|
362 |
+ const char *method, const char *url, |
|
363 |
+ const char *headers, |
|
363 | 364 |
RTSPMessageHeader *reply, |
364 | 365 |
unsigned char **content_ptr, |
365 | 366 |
const unsigned char *send_content, |
... | ... |
@@ -370,7 +377,8 @@ void ff_rtsp_send_cmd_with_content(AVFormatContext *s, |
370 | 370 |
* |
371 | 371 |
* @see rtsp_send_cmd_with_content |
372 | 372 |
*/ |
373 |
-void ff_rtsp_send_cmd(AVFormatContext *s, const char *cmd, |
|
373 |
+void ff_rtsp_send_cmd(AVFormatContext *s, const char *method, |
|
374 |
+ const char *url, const char *headers, |
|
374 | 375 |
RTSPMessageHeader *reply, unsigned char **content_ptr); |
375 | 376 |
|
376 | 377 |
/** |
... | ... |
@@ -36,11 +36,9 @@ static int rtsp_write_record(AVFormatContext *s) |
36 | 36 |
char cmd[1024]; |
37 | 37 |
|
38 | 38 |
snprintf(cmd, sizeof(cmd), |
39 |
- "RECORD %s RTSP/1.0\r\n" |
|
40 | 39 |
"Range: npt=%0.3f-\r\n", |
41 |
- rt->control_uri, |
|
42 | 40 |
(double) 0); |
43 |
- ff_rtsp_send_cmd(s, cmd, reply, NULL); |
|
41 |
+ ff_rtsp_send_cmd(s, "RECORD", rt->control_uri, cmd, reply, NULL); |
|
44 | 42 |
if (reply->status_code != RTSP_STATUS_OK) |
45 | 43 |
return -1; |
46 | 44 |
rt->state = RTSP_STATE_STREAMING; |
... | ... |
@@ -159,12 +157,8 @@ static int rtsp_write_packet(AVFormatContext *s, AVPacket *pkt) |
159 | 159 |
static int rtsp_write_close(AVFormatContext *s) |
160 | 160 |
{ |
161 | 161 |
RTSPState *rt = s->priv_data; |
162 |
- char cmd[1024]; |
|
163 | 162 |
|
164 |
- snprintf(cmd, sizeof(cmd), |
|
165 |
- "TEARDOWN %s RTSP/1.0\r\n", |
|
166 |
- rt->control_uri); |
|
167 |
- ff_rtsp_send_cmd_async(s, cmd); |
|
163 |
+ ff_rtsp_send_cmd_async(s, "TEARDOWN", rt->control_uri, NULL); |
|
168 | 164 |
|
169 | 165 |
ff_rtsp_close_streams(s); |
170 | 166 |
url_close(rt->rtsp_hd); |