diff options
| author | Andreas Huber <andih@google.com> | 2011-11-08 15:31:23 -0800 | 
|---|---|---|
| committer | Andreas Huber <andih@google.com> | 2011-11-08 15:39:15 -0800 | 
| commit | 908dbdee96856693decc04fa143c2ba525495d43 (patch) | |
| tree | 64a11df6061e668c16ce5afe02e3741d145d08d6 | |
| parent | 936a981ba15d528a023311aa32f46446813551d9 (diff) | |
| download | frameworks_av-908dbdee96856693decc04fa143c2ba525495d43.zip frameworks_av-908dbdee96856693decc04fa143c2ba525495d43.tar.gz frameworks_av-908dbdee96856693decc04fa143c2ba525495d43.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 | 94 | 
1 files changed, 92 insertions, 2 deletions
diff --git a/media/libstagefright/rtsp/MyHandler.h b/media/libstagefright/rtsp/MyHandler.h index af7dd23..6a5efa4 100644 --- a/media/libstagefright/rtsp/MyHandler.h +++ b/media/libstagefright/rtsp/MyHandler.h @@ -44,12 +44,14 @@  // If no access units are received within 5 secs, assume that the rtp  // stream has ended and signal end of stream. -static int64_t kAccessUnitTimeoutUs = 5000000ll; +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) { @@ -130,7 +132,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" @@ -555,6 +589,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"); @@ -606,6 +643,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) { @@ -952,6 +1034,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; @@ -1120,6 +1208,8 @@ private:      bool mReceivedFirstRTCPPacket;      bool mReceivedFirstRTPPacket;      bool mSeekable; +    int64_t mKeepAliveTimeoutUs; +    int32_t mKeepAliveGeneration;      Vector<TrackInfo> mTracks;  | 
