From b17d11c6329848b6f6e3af90baf2bcf044275ce9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Thu, 25 Mar 2010 21:46:14 +0000 Subject: [PATCH] Add separate method/url parameters to the rtsp_send_cmd functions Originally committed as revision 22675 to svn://svn.ffmpeg.org/ffmpeg/trunk --- libavformat/rtsp.c | 93 ++++++++++++++++++------------------------- libavformat/rtsp.h | 20 +++++++--- libavformat/rtspenc.c | 10 +---- 3 files changed, 55 insertions(+), 68 deletions(-) diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c index da27989a1f..c5502bbed4 100644 --- a/libavformat/rtsp.c +++ b/libavformat/rtsp.c @@ -994,7 +994,8 @@ int ff_rtsp_read_reply(AVFormatContext *s, RTSPMessageHeader *reply, } void ff_rtsp_send_cmd_with_content_async(AVFormatContext *s, - const char *cmd, + const char *method, const char *url, + const char *headers, const unsigned char *send_content, int send_content_length) { @@ -1002,10 +1003,13 @@ void ff_rtsp_send_cmd_with_content_async(AVFormatContext *s, char buf[4096], buf1[1024]; rt->seq++; - av_strlcpy(buf, cmd, sizeof(buf)); + snprintf(buf, sizeof(buf), "%s %s RTSP/1.0\r\n", method, url); + if (headers) + av_strlcat(buf, headers, sizeof(buf)); snprintf(buf1, sizeof(buf1), "CSeq: %d\r\n", rt->seq); av_strlcat(buf, buf1, sizeof(buf)); - if (rt->session_id[0] != '\0' && !strstr(cmd, "\nIf-Match:")) { + if (rt->session_id[0] != '\0' && (!headers || + !strstr(headers, "\nIf-Match:"))) { snprintf(buf1, sizeof(buf1), "Session: %s\r\n", rt->session_id); av_strlcat(buf, buf1, sizeof(buf)); } @@ -1025,26 +1029,30 @@ void ff_rtsp_send_cmd_with_content_async(AVFormatContext *s, rt->last_cmd_time = av_gettime(); } -void ff_rtsp_send_cmd_async(AVFormatContext *s, const char *cmd) +void ff_rtsp_send_cmd_async(AVFormatContext *s, const char *method, + const char *url, const char *headers) { - ff_rtsp_send_cmd_with_content_async(s, cmd, NULL, 0); + ff_rtsp_send_cmd_with_content_async(s, method, url, headers, NULL, 0); } -void ff_rtsp_send_cmd(AVFormatContext *s, - const char *cmd, RTSPMessageHeader *reply, +void ff_rtsp_send_cmd(AVFormatContext *s, const char *method, const char *url, + const char *headers, RTSPMessageHeader *reply, unsigned char **content_ptr) { - ff_rtsp_send_cmd_with_content(s, cmd, reply, content_ptr, NULL, 0); + ff_rtsp_send_cmd_with_content(s, method, url, headers, reply, + content_ptr, NULL, 0); } void ff_rtsp_send_cmd_with_content(AVFormatContext *s, - const char *cmd, + const char *method, const char *url, + const char *header, RTSPMessageHeader *reply, unsigned char **content_ptr, const unsigned char *send_content, int send_content_length) { - ff_rtsp_send_cmd_with_content_async(s, cmd, send_content, send_content_length); + ff_rtsp_send_cmd_with_content_async(s, method, url, header, + send_content, send_content_length); ff_rtsp_read_reply(s, reply, content_ptr, 0); } @@ -1173,9 +1181,8 @@ static int make_setup_request(AVFormatContext *s, const char *host, int port, rt->server_type == RTSP_SERVER_WMS) av_strlcat(transport, ";mode=play", sizeof(transport)); snprintf(cmd, sizeof(cmd), - "SETUP %s RTSP/1.0\r\n" "Transport: %s\r\n", - rtsp_st->control_url, transport); + transport); if (i == 0 && rt->server_type == RTSP_SERVER_REAL) { char real_res[41], real_csum[9]; 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, "RealChallenge2: %s, sd=%s\r\n", rt->session_id, real_res, real_csum); } - ff_rtsp_send_cmd(s, cmd, reply, NULL); + ff_rtsp_send_cmd(s, "SETUP", rtsp_st->control_url, cmd, reply, NULL); if (reply->status_code == 461 /* Unsupported protocol */ && i == 0) { err = 1; goto fail; @@ -1295,17 +1302,13 @@ static int rtsp_read_play(AVFormatContext *s) if (!(rt->server_type == RTSP_SERVER_REAL && rt->need_subscription)) { if (rt->state == RTSP_STATE_PAUSED) { - snprintf(cmd, sizeof(cmd), - "PLAY %s RTSP/1.0\r\n", - rt->control_uri); + cmd[0] = 0; } else { snprintf(cmd, sizeof(cmd), - "PLAY %s RTSP/1.0\r\n" "Range: npt=%0.3f-\r\n", - rt->control_uri, (double)rt->seek_timestamp / AV_TIME_BASE); } - ff_rtsp_send_cmd(s, cmd, reply, NULL); + ff_rtsp_send_cmd(s, "PLAY", rt->control_uri, cmd, reply, NULL); if (reply->status_code != RTSP_STATUS_OK) { return -1; } @@ -1323,9 +1326,7 @@ static int rtsp_setup_input_streams(AVFormatContext *s, RTSPMessageHeader *reply /* describe the stream */ snprintf(cmd, sizeof(cmd), - "DESCRIBE %s RTSP/1.0\r\n" - "Accept: application/sdp\r\n", - rt->control_uri); + "Accept: application/sdp\r\n"); if (rt->server_type == RTSP_SERVER_REAL) { /** * The Require: attribute is needed for proper streaming from @@ -1335,7 +1336,7 @@ static int rtsp_setup_input_streams(AVFormatContext *s, RTSPMessageHeader *reply "Require: com.real.retain-entity-for-setup\r\n", sizeof(cmd)); } - ff_rtsp_send_cmd(s, cmd, reply, &content); + ff_rtsp_send_cmd(s, "DESCRIBE", rt->control_uri, cmd, reply, &content); if (!content) return AVERROR_INVALIDDATA; if (reply->status_code != RTSP_STATUS_OK) { @@ -1356,7 +1357,6 @@ static int rtsp_setup_output_streams(AVFormatContext *s, const char *addr) { RTSPState *rt = s->priv_data; RTSPMessageHeader reply1, *reply = &reply1; - char cmd[1024]; int i; char *sdp; AVFormatContext sdp_ctx, *ctx_array[1]; @@ -1364,10 +1364,6 @@ static int rtsp_setup_output_streams(AVFormatContext *s, const char *addr) rt->start_time = av_gettime(); /* Announce the stream */ - snprintf(cmd, sizeof(cmd), - "ANNOUNCE %s RTSP/1.0\r\n" - "Content-Type: application/sdp\r\n", - rt->control_uri); sdp = av_mallocz(8192); if (sdp == NULL) return AVERROR(ENOMEM); @@ -1392,7 +1388,9 @@ static int rtsp_setup_output_streams(AVFormatContext *s, const char *addr) return AVERROR_INVALIDDATA; } av_log(s, AV_LOG_INFO, "SDP:\n%s\n", sdp); - ff_rtsp_send_cmd_with_content(s, cmd, reply, NULL, sdp, strlen(sdp)); + ff_rtsp_send_cmd_with_content(s, "ANNOUNCE", rt->control_uri, + "Content-Type: application/sdp\r\n", + reply, NULL, sdp, strlen(sdp)); av_free(sdp); if (reply->status_code != RTSP_STATUS_OK) return AVERROR_INVALIDDATA; @@ -1521,8 +1519,7 @@ redirect: /* request options supported by the server; this also detects server * type */ for (rt->server_type = RTSP_SERVER_RTP;;) { - snprintf(cmd, sizeof(cmd), - "OPTIONS %s RTSP/1.0\r\n", rt->control_uri); + cmd[0] = 0; if (rt->server_type == RTSP_SERVER_REAL) av_strlcat(cmd, /** @@ -1539,7 +1536,7 @@ redirect: "CompanyID: KnKV4M4I/B2FjJ1TToLycw==\r\n" "GUID: 00000000-0000-0000-0000-000000000000\r\n", sizeof(cmd)); - ff_rtsp_send_cmd(s, cmd, reply, NULL); + ff_rtsp_send_cmd(s, "OPTIONS", rt->control_uri, cmd, reply, NULL); if (reply->status_code != RTSP_STATUS_OK) { err = AVERROR_INVALIDDATA; goto fail; @@ -1812,10 +1809,10 @@ static int rtsp_read_packet(AVFormatContext *s, AVPacket *pkt) if (memcmp (cache, rt->real_setup_cache, sizeof(enum AVDiscard) * s->nb_streams)) { snprintf(cmd, sizeof(cmd), - "SET_PARAMETER %s RTSP/1.0\r\n" "Unsubscribe: %s\r\n", - rt->control_uri, rt->last_subscription); - ff_rtsp_send_cmd(s, cmd, reply, NULL); + rt->last_subscription); + ff_rtsp_send_cmd(s, "SET_PARAMETER", rt->control_uri, + cmd, reply, NULL); if (reply->status_code != RTSP_STATUS_OK) return AVERROR_INVALIDDATA; rt->need_subscription = 1; @@ -1830,9 +1827,7 @@ static int rtsp_read_packet(AVFormatContext *s, AVPacket *pkt) rt->last_subscription[0] = 0; snprintf(cmd, sizeof(cmd), - "SET_PARAMETER %s RTSP/1.0\r\n" - "Subscribe: ", - rt->control_uri); + "Subscribe: "); for (i = 0; i < rt->nb_rtsp_streams; i++) { rule_nr = 0; for (r = 0; r < s->nb_streams; r++) { @@ -1851,7 +1846,8 @@ static int rtsp_read_packet(AVFormatContext *s, AVPacket *pkt) } } av_strlcatf(cmd, sizeof(cmd), "%s\r\n", rt->last_subscription); - ff_rtsp_send_cmd(s, cmd, reply, NULL); + ff_rtsp_send_cmd(s, "SET_PARAMETER", rt->control_uri, + cmd, reply, NULL); if (reply->status_code != RTSP_STATUS_OK) return AVERROR_INVALIDDATA; rt->need_subscription = 0; @@ -1870,12 +1866,9 @@ static int rtsp_read_packet(AVFormatContext *s, AVPacket *pkt) rt->server_type == RTSP_SERVER_REAL) && (av_gettime() - rt->last_cmd_time) / 1000000 >= rt->timeout / 2) { if (rt->server_type == RTSP_SERVER_WMS) { - snprintf(cmd, sizeof(cmd) - 1, - "GET_PARAMETER %s RTSP/1.0\r\n", - rt->control_uri); - ff_rtsp_send_cmd_async(s, cmd); + ff_rtsp_send_cmd_async(s, "GET_PARAMETER", rt->control_uri, NULL); } else { - ff_rtsp_send_cmd_async(s, "OPTIONS * RTSP/1.0\r\n"); + ff_rtsp_send_cmd_async(s, "OPTIONS", "*", NULL); } } @@ -1887,17 +1880,13 @@ static int rtsp_read_pause(AVFormatContext *s) { RTSPState *rt = s->priv_data; RTSPMessageHeader reply1, *reply = &reply1; - char cmd[1024]; rt = s->priv_data; if (rt->state != RTSP_STATE_STREAMING) return 0; else if (!(rt->server_type == RTSP_SERVER_REAL && rt->need_subscription)) { - snprintf(cmd, sizeof(cmd), - "PAUSE %s RTSP/1.0\r\n", - rt->control_uri); - ff_rtsp_send_cmd(s, cmd, reply, NULL); + ff_rtsp_send_cmd(s, "PAUSE", rt->control_uri, NULL, reply, NULL); if (reply->status_code != RTSP_STATUS_OK) { return -1; } @@ -1935,7 +1924,6 @@ static int rtsp_read_seek(AVFormatContext *s, int stream_index, static int rtsp_read_close(AVFormatContext *s) { RTSPState *rt = s->priv_data; - char cmd[1024]; #if 0 /* NOTE: it is valid to flush the buffer here */ @@ -1943,10 +1931,7 @@ static int rtsp_read_close(AVFormatContext *s) url_fclose(&rt->rtsp_gb); } #endif - snprintf(cmd, sizeof(cmd), - "TEARDOWN %s RTSP/1.0\r\n", - rt->control_uri); - ff_rtsp_send_cmd_async(s, cmd); + ff_rtsp_send_cmd_async(s, "TEARDOWN", rt->control_uri, NULL); ff_rtsp_close_streams(s); url_close(rt->rtsp_hd); diff --git a/libavformat/rtsp.h b/libavformat/rtsp.h index 13e251b72b..d317eee44b 100644 --- a/libavformat/rtsp.h +++ b/libavformat/rtsp.h @@ -330,13 +330,16 @@ extern int rtsp_rtp_port_max; * Send a command to the RTSP server without waiting for the reply. * * @param s RTSP (de)muxer context - * @param cmd the full first line of the request + * @param method the method for the request + * @param url the target url for the request + * @param headers extra header lines to include in the request * @param send_content if non-null, the data to send as request body content * @param send_content_length the length of the send_content data, or 0 if * send_content is null */ void ff_rtsp_send_cmd_with_content_async(AVFormatContext *s, - const char *cmd, + const char *method, const char *url, + const char *headers, const unsigned char *send_content, int send_content_length); /** @@ -344,13 +347,16 @@ void ff_rtsp_send_cmd_with_content_async(AVFormatContext *s, * * @see rtsp_send_cmd_with_content_async */ -void ff_rtsp_send_cmd_async(AVFormatContext *s, const char *cmd); +void ff_rtsp_send_cmd_async(AVFormatContext *s, const char *method, + const char *url, const char *headers); /** * Send a command to the RTSP server and wait for the reply. * * @param s RTSP (de)muxer context - * @param cmd the full first line of the request + * @param method the method for the request + * @param url the target url for the request + * @param headers extra header lines to include in the request * @param reply pointer where the RTSP message header will be stored * @param content_ptr pointer where the RTSP message body, if any, will * be stored (length is in reply) @@ -359,7 +365,8 @@ void ff_rtsp_send_cmd_async(AVFormatContext *s, const char *cmd); * send_content is null */ void ff_rtsp_send_cmd_with_content(AVFormatContext *s, - const char *cmd, + const char *method, const char *url, + const char *headers, RTSPMessageHeader *reply, unsigned char **content_ptr, const unsigned char *send_content, @@ -370,7 +377,8 @@ void ff_rtsp_send_cmd_with_content(AVFormatContext *s, * * @see rtsp_send_cmd_with_content */ -void ff_rtsp_send_cmd(AVFormatContext *s, const char *cmd, +void ff_rtsp_send_cmd(AVFormatContext *s, const char *method, + const char *url, const char *headers, RTSPMessageHeader *reply, unsigned char **content_ptr); /** diff --git a/libavformat/rtspenc.c b/libavformat/rtspenc.c index 5eab8000fd..f7aadd6e41 100644 --- a/libavformat/rtspenc.c +++ b/libavformat/rtspenc.c @@ -36,11 +36,9 @@ static int rtsp_write_record(AVFormatContext *s) char cmd[1024]; snprintf(cmd, sizeof(cmd), - "RECORD %s RTSP/1.0\r\n" "Range: npt=%0.3f-\r\n", - rt->control_uri, (double) 0); - ff_rtsp_send_cmd(s, cmd, reply, NULL); + ff_rtsp_send_cmd(s, "RECORD", rt->control_uri, cmd, reply, NULL); if (reply->status_code != RTSP_STATUS_OK) return -1; rt->state = RTSP_STATE_STREAMING; @@ -159,12 +157,8 @@ static int rtsp_write_packet(AVFormatContext *s, AVPacket *pkt) static int rtsp_write_close(AVFormatContext *s) { RTSPState *rt = s->priv_data; - char cmd[1024]; - snprintf(cmd, sizeof(cmd), - "TEARDOWN %s RTSP/1.0\r\n", - rt->control_uri); - ff_rtsp_send_cmd_async(s, cmd); + ff_rtsp_send_cmd_async(s, "TEARDOWN", rt->control_uri, NULL); ff_rtsp_close_streams(s); url_close(rt->rtsp_hd);