rtsp: Only do keepalive using GET_PARAMETER if the server supports it

This is more like what VLC does. If the server doesn't mention
supporting GET_PARAMETER in response to an OPTIONS request,
VLC doesn't send any keepalive requests at all. After this patch,
libavformat will still send OPTIONS keepalives if GET_PARAMETER
isn't explicitly said to be supported.

Some RTSP cameras don't support GET_PARAMETER, and will
close the connection if this is sent as keepalive request
(but support OPTIONS just fine, but probably don't need any
keepalive at all). Some other cameras don't support using
OPTIONS as keepalive, but require GET_PARAMETER instead.

Signed-off-by: Martin Storsjö <martin@martin.st>
This commit is contained in:
Martin Storsjö 2011-05-09 20:11:16 +03:00
parent 3fd62c6e24
commit 0b4949b518
3 changed files with 12 additions and 1 deletions

View File

@ -808,6 +808,10 @@ void ff_rtsp_parse_line(RTSPMessageHeader *reply, const char *buf,
p += strspn(p, SPACE_CHARS); p += strspn(p, SPACE_CHARS);
if (method && !strcmp(method, "PLAY")) if (method && !strcmp(method, "PLAY"))
rtsp_parse_rtp_info(rt, p); rtsp_parse_rtp_info(rt, p);
} else if (av_stristart(p, "Public:", &p) && rt) {
if (strstr(p, "GET_PARAMETER") &&
method && !strcmp(method, "OPTIONS"))
rt->get_parameter_supported = 1;
} }
} }

View File

@ -331,6 +331,11 @@ typedef struct RTSPState {
* Polling array for udp * Polling array for udp
*/ */
struct pollfd *p; struct pollfd *p;
/**
* Whether the server supports the GET_PARAMETER method.
*/
int get_parameter_supported;
} RTSPState; } RTSPState;
/** /**

View File

@ -341,7 +341,9 @@ retry:
/* send dummy request to keep TCP connection alive */ /* send dummy request to keep TCP connection alive */
if ((av_gettime() - rt->last_cmd_time) / 1000000 >= rt->timeout / 2) { if ((av_gettime() - rt->last_cmd_time) / 1000000 >= rt->timeout / 2) {
if (rt->server_type != RTSP_SERVER_REAL) { if (rt->server_type == RTSP_SERVER_WMS ||
(rt->server_type != RTSP_SERVER_REAL &&
rt->get_parameter_supported)) {
ff_rtsp_send_cmd_async(s, "GET_PARAMETER", rt->control_uri, NULL); ff_rtsp_send_cmd_async(s, "GET_PARAMETER", rt->control_uri, NULL);
} else { } else {
ff_rtsp_send_cmd_async(s, "OPTIONS", "*", NULL); ff_rtsp_send_cmd_async(s, "OPTIONS", "*", NULL);