Add separate method/url parameters to the rtsp_send_cmd functions

Originally committed as revision 22675 to svn://svn.ffmpeg.org/ffmpeg/trunk
release/0.6
Martin Storsjö 15 years ago
parent c5c20ae436
commit b17d11c632
  1. 93
      libavformat/rtsp.c
  2. 20
      libavformat/rtsp.h
  3. 10
      libavformat/rtspenc.c

@ -994,7 +994,8 @@ int ff_rtsp_read_reply(AVFormatContext *s, RTSPMessageHeader *reply,
} }
void ff_rtsp_send_cmd_with_content_async(AVFormatContext *s, 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, const unsigned char *send_content,
int send_content_length) int send_content_length)
{ {
@ -1002,10 +1003,13 @@ void ff_rtsp_send_cmd_with_content_async(AVFormatContext *s,
char buf[4096], buf1[1024]; char buf[4096], buf1[1024];
rt->seq++; 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); snprintf(buf1, sizeof(buf1), "CSeq: %d\r\n", rt->seq);
av_strlcat(buf, buf1, sizeof(buf)); 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); snprintf(buf1, sizeof(buf1), "Session: %s\r\n", rt->session_id);
av_strlcat(buf, buf1, sizeof(buf)); 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(); 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, void ff_rtsp_send_cmd(AVFormatContext *s, const char *method, const char *url,
const char *cmd, RTSPMessageHeader *reply, const char *headers, RTSPMessageHeader *reply,
unsigned char **content_ptr) 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, void ff_rtsp_send_cmd_with_content(AVFormatContext *s,
const char *cmd, const char *method, const char *url,
const char *header,
RTSPMessageHeader *reply, RTSPMessageHeader *reply,
unsigned char **content_ptr, unsigned char **content_ptr,
const unsigned char *send_content, const unsigned char *send_content,
int send_content_length) 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); 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) rt->server_type == RTSP_SERVER_WMS)
av_strlcat(transport, ";mode=play", sizeof(transport)); av_strlcat(transport, ";mode=play", sizeof(transport));
snprintf(cmd, sizeof(cmd), snprintf(cmd, sizeof(cmd),
"SETUP %s RTSP/1.0\r\n"
"Transport: %s\r\n", "Transport: %s\r\n",
rtsp_st->control_url, transport); transport);
if (i == 0 && rt->server_type == RTSP_SERVER_REAL) { if (i == 0 && rt->server_type == RTSP_SERVER_REAL) {
char real_res[41], real_csum[9]; char real_res[41], real_csum[9];
ff_rdt_calc_response_and_checksum(real_res, real_csum, 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", "RealChallenge2: %s, sd=%s\r\n",
rt->session_id, real_res, real_csum); 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) { if (reply->status_code == 461 /* Unsupported protocol */ && i == 0) {
err = 1; err = 1;
goto fail; 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->server_type == RTSP_SERVER_REAL && rt->need_subscription)) {
if (rt->state == RTSP_STATE_PAUSED) { if (rt->state == RTSP_STATE_PAUSED) {
snprintf(cmd, sizeof(cmd), cmd[0] = 0;
"PLAY %s RTSP/1.0\r\n",
rt->control_uri);
} else { } else {
snprintf(cmd, sizeof(cmd), snprintf(cmd, sizeof(cmd),
"PLAY %s RTSP/1.0\r\n"
"Range: npt=%0.3f-\r\n", "Range: npt=%0.3f-\r\n",
rt->control_uri,
(double)rt->seek_timestamp / AV_TIME_BASE); (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) { if (reply->status_code != RTSP_STATUS_OK) {
return -1; return -1;
} }
@ -1323,9 +1326,7 @@ static int rtsp_setup_input_streams(AVFormatContext *s, RTSPMessageHeader *reply
/* describe the stream */ /* describe the stream */
snprintf(cmd, sizeof(cmd), snprintf(cmd, sizeof(cmd),
"DESCRIBE %s RTSP/1.0\r\n" "Accept: application/sdp\r\n");
"Accept: application/sdp\r\n",
rt->control_uri);
if (rt->server_type == RTSP_SERVER_REAL) { if (rt->server_type == RTSP_SERVER_REAL) {
/** /**
* The Require: attribute is needed for proper streaming from * 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", "Require: com.real.retain-entity-for-setup\r\n",
sizeof(cmd)); sizeof(cmd));
} }
ff_rtsp_send_cmd(s, cmd, reply, &content); ff_rtsp_send_cmd(s, "DESCRIBE", rt->control_uri, cmd, reply, &content);
if (!content) if (!content)
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
if (reply->status_code != RTSP_STATUS_OK) { 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; RTSPState *rt = s->priv_data;
RTSPMessageHeader reply1, *reply = &reply1; RTSPMessageHeader reply1, *reply = &reply1;
char cmd[1024];
int i; int i;
char *sdp; char *sdp;
AVFormatContext sdp_ctx, *ctx_array[1]; 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(); rt->start_time = av_gettime();
/* Announce the stream */ /* 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); sdp = av_mallocz(8192);
if (sdp == NULL) if (sdp == NULL)
return AVERROR(ENOMEM); return AVERROR(ENOMEM);
@ -1392,7 +1388,9 @@ static int rtsp_setup_output_streams(AVFormatContext *s, const char *addr)
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} }
av_log(s, AV_LOG_INFO, "SDP:\n%s\n", sdp); 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); av_free(sdp);
if (reply->status_code != RTSP_STATUS_OK) if (reply->status_code != RTSP_STATUS_OK)
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
@ -1521,8 +1519,7 @@ redirect:
/* request options supported by the server; this also detects server /* request options supported by the server; this also detects server
* type */ * type */
for (rt->server_type = RTSP_SERVER_RTP;;) { for (rt->server_type = RTSP_SERVER_RTP;;) {
snprintf(cmd, sizeof(cmd), cmd[0] = 0;
"OPTIONS %s RTSP/1.0\r\n", rt->control_uri);
if (rt->server_type == RTSP_SERVER_REAL) if (rt->server_type == RTSP_SERVER_REAL)
av_strlcat(cmd, av_strlcat(cmd,
/** /**
@ -1539,7 +1536,7 @@ redirect:
"CompanyID: KnKV4M4I/B2FjJ1TToLycw==\r\n" "CompanyID: KnKV4M4I/B2FjJ1TToLycw==\r\n"
"GUID: 00000000-0000-0000-0000-000000000000\r\n", "GUID: 00000000-0000-0000-0000-000000000000\r\n",
sizeof(cmd)); 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) { if (reply->status_code != RTSP_STATUS_OK) {
err = AVERROR_INVALIDDATA; err = AVERROR_INVALIDDATA;
goto fail; goto fail;
@ -1812,10 +1809,10 @@ static int rtsp_read_packet(AVFormatContext *s, AVPacket *pkt)
if (memcmp (cache, rt->real_setup_cache, if (memcmp (cache, rt->real_setup_cache,
sizeof(enum AVDiscard) * s->nb_streams)) { sizeof(enum AVDiscard) * s->nb_streams)) {
snprintf(cmd, sizeof(cmd), snprintf(cmd, sizeof(cmd),
"SET_PARAMETER %s RTSP/1.0\r\n"
"Unsubscribe: %s\r\n", "Unsubscribe: %s\r\n",
rt->control_uri, rt->last_subscription); 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) if (reply->status_code != RTSP_STATUS_OK)
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
rt->need_subscription = 1; rt->need_subscription = 1;
@ -1830,9 +1827,7 @@ static int rtsp_read_packet(AVFormatContext *s, AVPacket *pkt)
rt->last_subscription[0] = 0; rt->last_subscription[0] = 0;
snprintf(cmd, sizeof(cmd), snprintf(cmd, sizeof(cmd),
"SET_PARAMETER %s RTSP/1.0\r\n" "Subscribe: ");
"Subscribe: ",
rt->control_uri);
for (i = 0; i < rt->nb_rtsp_streams; i++) { for (i = 0; i < rt->nb_rtsp_streams; i++) {
rule_nr = 0; rule_nr = 0;
for (r = 0; r < s->nb_streams; r++) { 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); 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) if (reply->status_code != RTSP_STATUS_OK)
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
rt->need_subscription = 0; rt->need_subscription = 0;
@ -1870,12 +1866,9 @@ static int rtsp_read_packet(AVFormatContext *s, AVPacket *pkt)
rt->server_type == RTSP_SERVER_REAL) && rt->server_type == RTSP_SERVER_REAL) &&
(av_gettime() - rt->last_cmd_time) / 1000000 >= rt->timeout / 2) { (av_gettime() - rt->last_cmd_time) / 1000000 >= rt->timeout / 2) {
if (rt->server_type == RTSP_SERVER_WMS) { if (rt->server_type == RTSP_SERVER_WMS) {
snprintf(cmd, sizeof(cmd) - 1, ff_rtsp_send_cmd_async(s, "GET_PARAMETER", rt->control_uri, NULL);
"GET_PARAMETER %s RTSP/1.0\r\n",
rt->control_uri);
ff_rtsp_send_cmd_async(s, cmd);
} else { } 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; RTSPState *rt = s->priv_data;
RTSPMessageHeader reply1, *reply = &reply1; RTSPMessageHeader reply1, *reply = &reply1;
char cmd[1024];
rt = s->priv_data; rt = s->priv_data;
if (rt->state != RTSP_STATE_STREAMING) if (rt->state != RTSP_STATE_STREAMING)
return 0; return 0;
else if (!(rt->server_type == RTSP_SERVER_REAL && rt->need_subscription)) { else if (!(rt->server_type == RTSP_SERVER_REAL && rt->need_subscription)) {
snprintf(cmd, sizeof(cmd), ff_rtsp_send_cmd(s, "PAUSE", rt->control_uri, NULL, reply, NULL);
"PAUSE %s RTSP/1.0\r\n",
rt->control_uri);
ff_rtsp_send_cmd(s, cmd, reply, NULL);
if (reply->status_code != RTSP_STATUS_OK) { if (reply->status_code != RTSP_STATUS_OK) {
return -1; return -1;
} }
@ -1935,7 +1924,6 @@ static int rtsp_read_seek(AVFormatContext *s, int stream_index,
static int rtsp_read_close(AVFormatContext *s) static int rtsp_read_close(AVFormatContext *s)
{ {
RTSPState *rt = s->priv_data; RTSPState *rt = s->priv_data;
char cmd[1024];
#if 0 #if 0
/* NOTE: it is valid to flush the buffer here */ /* 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); url_fclose(&rt->rtsp_gb);
} }
#endif #endif
snprintf(cmd, sizeof(cmd), ff_rtsp_send_cmd_async(s, "TEARDOWN", rt->control_uri, NULL);
"TEARDOWN %s RTSP/1.0\r\n",
rt->control_uri);
ff_rtsp_send_cmd_async(s, cmd);
ff_rtsp_close_streams(s); ff_rtsp_close_streams(s);
url_close(rt->rtsp_hd); url_close(rt->rtsp_hd);

@ -330,13 +330,16 @@ extern int rtsp_rtp_port_max;
* Send a command to the RTSP server without waiting for the reply. * Send a command to the RTSP server without waiting for the reply.
* *
* @param s RTSP (de)muxer context * @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 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 * @param send_content_length the length of the send_content data, or 0 if
* send_content is null * send_content is null
*/ */
void ff_rtsp_send_cmd_with_content_async(AVFormatContext *s, 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, const unsigned char *send_content,
int send_content_length); 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 * @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. * Send a command to the RTSP server and wait for the reply.
* *
* @param s RTSP (de)muxer context * @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 reply pointer where the RTSP message header will be stored
* @param content_ptr pointer where the RTSP message body, if any, will * @param content_ptr pointer where the RTSP message body, if any, will
* be stored (length is in reply) * 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 * send_content is null
*/ */
void ff_rtsp_send_cmd_with_content(AVFormatContext *s, void ff_rtsp_send_cmd_with_content(AVFormatContext *s,
const char *cmd, const char *method, const char *url,
const char *headers,
RTSPMessageHeader *reply, RTSPMessageHeader *reply,
unsigned char **content_ptr, unsigned char **content_ptr,
const unsigned char *send_content, const unsigned char *send_content,
@ -370,7 +377,8 @@ void ff_rtsp_send_cmd_with_content(AVFormatContext *s,
* *
* @see rtsp_send_cmd_with_content * @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); RTSPMessageHeader *reply, unsigned char **content_ptr);
/** /**

@ -36,11 +36,9 @@ static int rtsp_write_record(AVFormatContext *s)
char cmd[1024]; char cmd[1024];
snprintf(cmd, sizeof(cmd), snprintf(cmd, sizeof(cmd),
"RECORD %s RTSP/1.0\r\n"
"Range: npt=%0.3f-\r\n", "Range: npt=%0.3f-\r\n",
rt->control_uri,
(double) 0); (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) if (reply->status_code != RTSP_STATUS_OK)
return -1; return -1;
rt->state = RTSP_STATE_STREAMING; 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) static int rtsp_write_close(AVFormatContext *s)
{ {
RTSPState *rt = s->priv_data; RTSPState *rt = s->priv_data;
char cmd[1024];
snprintf(cmd, sizeof(cmd), ff_rtsp_send_cmd_async(s, "TEARDOWN", rt->control_uri, NULL);
"TEARDOWN %s RTSP/1.0\r\n",
rt->control_uri);
ff_rtsp_send_cmd_async(s, cmd);
ff_rtsp_close_streams(s); ff_rtsp_close_streams(s);
url_close(rt->rtsp_hd); url_close(rt->rtsp_hd);

Loading…
Cancel
Save