Better detection of connection problems - timeout if no rtcp packets arrive within a certain time, not a final frame (which may take longer)

Change-Id: I3c1ae79bb9342770e959ebdcdc6b748549b76330
related-to-bug: 2556656
diff --git a/media/libstagefright/rtsp/ARTPConnection.cpp b/media/libstagefright/rtsp/ARTPConnection.cpp
index 12f8f32..10c9e02 100644
--- a/media/libstagefright/rtsp/ARTPConnection.cpp
+++ b/media/libstagefright/rtsp/ARTPConnection.cpp
@@ -362,7 +362,6 @@
     if (receiveRTP) {
         err = parseRTP(s, buffer);
     } else {
-        ++s->mNumRTCPPacketsReceived;
         err = parseRTCP(s, buffer);
     }
 
@@ -456,6 +455,12 @@
 }
 
 status_t ARTPConnection::parseRTCP(StreamInfo *s, const sp<ABuffer> &buffer) {
+    if (s->mNumRTCPPacketsReceived++ == 0) {
+        sp<AMessage> notify = s->mNotifyMsg->dup();
+        notify->setInt32("first-rtcp", true);
+        notify->post();
+    }
+
     const uint8_t *data = buffer->data();
     size_t size = buffer->size();
 
@@ -626,7 +631,6 @@
     if (it->mRTPSocket == index) {
         err = parseRTP(s, buffer);
     } else {
-        ++s->mNumRTCPPacketsReceived;
         err = parseRTCP(s, buffer);
     }
 }
diff --git a/media/libstagefright/rtsp/MyHandler.h b/media/libstagefright/rtsp/MyHandler.h
index ee6f65a..b849117 100644
--- a/media/libstagefright/rtsp/MyHandler.h
+++ b/media/libstagefright/rtsp/MyHandler.h
@@ -82,7 +82,8 @@
           mFirstAccessUnitNTP(0),
           mNumAccessUnitsReceived(0),
           mCheckPending(false),
-          mTryTCPInterleaving(false) {
+          mTryTCPInterleaving(false),
+          mReceivedFirstRTCPPacket(false) {
         mNetLooper->setName("rtsp net");
         mNetLooper->start(false /* runOnCallingThread */,
                           false /* canCallJava */,
@@ -199,31 +200,35 @@
                         break;
                     }
 
-                    CHECK_EQ(response->mStatusCode, 200u);
-
-                    mSessionDesc = new ASessionDescription;
-
-                    mSessionDesc->setTo(
-                            response->mContent->data(),
-                            response->mContent->size());
-
-                    CHECK(mSessionDesc->isValid());
-
-                    ssize_t i = response->mHeaders.indexOfKey("content-base");
-                    if (i >= 0) {
-                        mBaseURL = response->mHeaders.valueAt(i);
+                    if (response->mStatusCode != 200) {
+                        result = UNKNOWN_ERROR;
                     } else {
-                        i = response->mHeaders.indexOfKey("content-location");
+                        mSessionDesc = new ASessionDescription;
+
+                        mSessionDesc->setTo(
+                                response->mContent->data(),
+                                response->mContent->size());
+
+                        CHECK(mSessionDesc->isValid());
+
+                        ssize_t i = response->mHeaders.indexOfKey("content-base");
                         if (i >= 0) {
                             mBaseURL = response->mHeaders.valueAt(i);
                         } else {
-                            mBaseURL = mSessionURL;
+                            i = response->mHeaders.indexOfKey("content-location");
+                            if (i >= 0) {
+                                mBaseURL = response->mHeaders.valueAt(i);
+                            } else {
+                                mBaseURL = mSessionURL;
+                            }
                         }
-                    }
 
-                    CHECK_GT(mSessionDesc->countTracks(), 1u);
-                    setupTrack(1);
-                } else {
+                        CHECK_GT(mSessionDesc->countTracks(), 1u);
+                        setupTrack(1);
+                    }
+                }
+
+                if (result != OK) {
                     sp<AMessage> reply = new AMessage('disc', id());
                     mConn->disconnect(reply);
                 }
@@ -247,6 +252,39 @@
                 LOG(INFO) << "SETUP(" << index << ") completed with result "
                      << result << " (" << strerror(-result) << ")";
 
+                if (result == OK) {
+                    CHECK(track != NULL);
+
+                    sp<RefBase> obj;
+                    CHECK(msg->findObject("response", &obj));
+                    sp<ARTSPResponse> response =
+                        static_cast<ARTSPResponse *>(obj.get());
+
+                    if (response->mStatusCode != 200) {
+                        result = UNKNOWN_ERROR;
+                    } else {
+                        ssize_t i = response->mHeaders.indexOfKey("session");
+                        CHECK_GE(i, 0);
+
+                        mSessionID = response->mHeaders.valueAt(i);
+                        i = mSessionID.find(";");
+                        if (i >= 0) {
+                            // Remove options, i.e. ";timeout=90"
+                            mSessionID.erase(i, mSessionID.size() - i);
+                        }
+
+                        sp<AMessage> notify = new AMessage('accu', id());
+                        notify->setSize("track-index", trackIndex);
+
+                        mRTPConn->addStream(
+                                track->mRTPSocket, track->mRTCPSocket,
+                                mSessionDesc, index,
+                                notify, track->mUsingInterleavedTCP);
+
+                        mSetupTracksSuccessful = true;
+                    }
+                }
+
                 if (result != OK) {
                     if (track) {
                         if (!track->mUsingInterleavedTCP) {
@@ -256,37 +294,6 @@
 
                         mTracks.removeItemsAt(trackIndex);
                     }
-                } else {
-                    CHECK(track != NULL);
-
-                    sp<RefBase> obj;
-                    CHECK(msg->findObject("response", &obj));
-                    sp<ARTSPResponse> response =
-                        static_cast<ARTSPResponse *>(obj.get());
-
-                    CHECK_EQ(response->mStatusCode, 200u);
-
-                    ssize_t i = response->mHeaders.indexOfKey("session");
-                    CHECK_GE(i, 0);
-
-                    if (index == 1) {
-                        mSessionID = response->mHeaders.valueAt(i);
-                        i = mSessionID.find(";");
-                        if (i >= 0) {
-                            // Remove options, i.e. ";timeout=90"
-                            mSessionID.erase(i, mSessionID.size() - i);
-                        }
-                    }
-
-                    sp<AMessage> notify = new AMessage('accu', id());
-                    notify->setSize("track-index", trackIndex);
-
-                    mRTPConn->addStream(
-                            track->mRTPSocket, track->mRTCPSocket,
-                            mSessionDesc, index,
-                            notify, track->mUsingInterleavedTCP);
-
-                    mSetupTracksSuccessful = true;
                 }
 
                 ++index;
@@ -355,6 +362,12 @@
                     }
                 }
                 mTracks.clear();
+                mSetupTracksSuccessful = false;
+                mSeekPending = false;
+                mFirstAccessUnit = true;
+                mFirstAccessUnitNTP = 0;
+                mNumAccessUnitsReceived = 0;
+                mReceivedFirstRTCPPacket = false;
 
                 sp<AMessage> reply = new AMessage('tear', id());
 
@@ -424,6 +437,12 @@
 
             case 'accu':
             {
+                int32_t firstRTCP;
+                if (msg->findInt32("first-rtcp", &firstRTCP)) {
+                    mReceivedFirstRTCPPacket = true;
+                    break;
+                }
+
                 ++mNumAccessUnitsReceived;
 
                 if (!mCheckPending) {
@@ -612,7 +631,7 @@
 
             case 'tiou':
             {
-                if (mFirstAccessUnit) {
+                if (!mReceivedFirstRTCPPacket) {
                     if (mTryTCPInterleaving) {
                         LOG(WARNING) << "Never received any data, disconnecting.";
                         (new AMessage('abor', id()))->post();
@@ -747,6 +766,7 @@
     int64_t mNumAccessUnitsReceived;
     bool mCheckPending;
     bool mTryTCPInterleaving;
+    bool mReceivedFirstRTCPPacket;
 
     struct TrackInfo {
         AString mURL;