diff options
author | Andreas Huber <andih@google.com> | 2011-11-08 15:31:23 -0800 |
---|---|---|
committer | Danny Baumann <dannybaumann@web.de> | 2012-06-07 11:33:51 +0200 |
commit | 01d2fa137ba2448d22cc58942cb1ab85e9ef89d0 (patch) | |
tree | f308af737e71e7f41978d0762b9725c0b4625a3c | |
parent | c338f719c53e712817722baeb080e21a60992784 (diff) | |
download | frameworks_base-01d2fa137ba2448d22cc58942cb1ab85e9ef89d0.zip frameworks_base-01d2fa137ba2448d22cc58942cb1ab85e9ef89d0.tar.gz frameworks_base-01d2fa137ba2448d22cc58942cb1ab85e9ef89d0.tar.bz2 |
Send RTSP control connection keep-alive requests
default to 60 secs unless overridden by server's session-id response.
Change-Id: I7c3aff5b787dbb57cc0dccf9db3c75e5cf7e778c
related-to-bug: 5562303
-rw-r--r-- | media/libstagefright/rtsp/MyHandler.h | 96 |
1 files changed, 93 insertions, 3 deletions
diff --git a/media/libstagefright/rtsp/MyHandler.h b/media/libstagefright/rtsp/MyHandler.h index 72a2fdb..891c3f6 100644 --- a/media/libstagefright/rtsp/MyHandler.h +++ b/media/libstagefright/rtsp/MyHandler.h @@ -40,14 +40,16 @@ #include <sys/socket.h> #include <netdb.h> -// If no access units are received within 3 secs, assume that the rtp +// If no access units are received within 10 secs, assume that the rtp // stream has ended and signal end of stream. -static int64_t kAccessUnitTimeoutUs = 3000000ll; +static int64_t kAccessUnitTimeoutUs = 10000000ll; // If no access units arrive for the first 10 secs after starting the // stream, assume none ever will and signal EOS or switch transports. static int64_t kStartupTimeoutUs = 10000000ll; +static int64_t kDefaultKeepAliveTimeoutUs = 60000000ll; + namespace android { static void MakeUserAgentString(AString *s) { @@ -110,7 +112,9 @@ struct MyHandler : public AHandler { mTryFakeRTCP(false), mReceivedFirstRTCPPacket(false), mReceivedFirstRTPPacket(false), - mSeekable(false) { + mSeekable(false), + mKeepAliveTimeoutUs(kDefaultKeepAliveTimeoutUs), + mKeepAliveGeneration(0) { mNetLooper->setName("rtsp net"); mNetLooper->start(false /* runOnCallingThread */, false /* canCallJava */, @@ -371,6 +375,8 @@ struct MyHandler : public AHandler { case 'disc': { + ++mKeepAliveGeneration; + int32_t reconnect; if (msg->findInt32("reconnect", &reconnect) && reconnect) { sp<AMessage> reply = new AMessage('conn', id()); @@ -502,6 +508,34 @@ struct MyHandler : public AHandler { CHECK_GE(i, 0); mSessionID = response->mHeaders.valueAt(i); + + mKeepAliveTimeoutUs = kDefaultKeepAliveTimeoutUs; + AString timeoutStr; + if (GetAttribute( + mSessionID.c_str(), "timeout", &timeoutStr)) { + char *end; + unsigned long timeoutSecs = + strtoul(timeoutStr.c_str(), &end, 10); + + if (end == timeoutStr.c_str() || *end != '\0') { + LOGW("server specified malformed timeout '%s'", + timeoutStr.c_str()); + + mKeepAliveTimeoutUs = kDefaultKeepAliveTimeoutUs; + } else if (timeoutSecs < 15) { + LOGW("server specified too short a timeout " + "(%lu secs), using default.", + timeoutSecs); + + mKeepAliveTimeoutUs = kDefaultKeepAliveTimeoutUs; + } else { + mKeepAliveTimeoutUs = timeoutSecs * 1000000ll; + + LOGI("server specified timeout of %lu secs.", + timeoutSecs); + } + } + i = mSessionID.find(";"); if (i >= 0) { // Remove options, i.e. ";timeout=90" @@ -549,6 +583,9 @@ struct MyHandler : public AHandler { if (index < mSessionDesc->countTracks()) { setupTrack(index); } else if (mSetupTracksSuccessful) { + ++mKeepAliveGeneration; + postKeepAlive(); + AString request = "PLAY "; request.append(mSessionURL); request.append(" RTSP/1.0\r\n"); @@ -600,6 +637,51 @@ struct MyHandler : public AHandler { break; } + case 'aliv': + { + int32_t generation; + CHECK(msg->findInt32("generation", &generation)); + + if (generation != mKeepAliveGeneration) { + // obsolete event. + break; + } + + AString request; + request.append("OPTIONS "); + request.append(mSessionURL); + request.append(" RTSP/1.0\r\n"); + request.append("Session: "); + request.append(mSessionID); + request.append("\r\n"); + request.append("\r\n"); + + sp<AMessage> reply = new AMessage('opts', id()); + reply->setInt32("generation", mKeepAliveGeneration); + mConn->sendRequest(request.c_str(), reply); + break; + } + + case 'opts': + { + int32_t result; + CHECK(msg->findInt32("result", &result)); + + LOGI("OPTIONS completed with result %d (%s)", + result, strerror(-result)); + + int32_t generation; + CHECK(msg->findInt32("generation", &generation)); + + if (generation != mKeepAliveGeneration) { + // obsolete event. + break; + } + + postKeepAlive(); + break; + } + case 'abor': { for (size_t i = 0; i < mTracks.size(); ++i) { @@ -962,6 +1044,12 @@ struct MyHandler : public AHandler { } } + void postKeepAlive() { + sp<AMessage> msg = new AMessage('aliv', id()); + msg->setInt32("generation", mKeepAliveGeneration); + msg->post((mKeepAliveTimeoutUs * 9) / 10); + } + void postAccessUnitTimeoutCheck() { if (mCheckPending) { return; @@ -1092,6 +1180,8 @@ private: bool mReceivedFirstRTCPPacket; bool mReceivedFirstRTPPacket; bool mSeekable; + int64_t mKeepAliveTimeoutUs; + int32_t mKeepAliveGeneration; struct TrackInfo { AString mURL; |