Merge "Make sure we only reallocate buffers on a genuine port definition change."
diff --git a/media/libstagefright/rtsp/ARTPConnection.cpp b/media/libstagefright/rtsp/ARTPConnection.cpp
index 42a22b7..12f8f32 100644
--- a/media/libstagefright/rtsp/ARTPConnection.cpp
+++ b/media/libstagefright/rtsp/ARTPConnection.cpp
@@ -263,6 +263,10 @@
         }
     }
 
+    if (maxSocket == -1) {
+        return;
+    }
+
     int res = select(maxSocket + 1, &rs, NULL, NULL, &tv);
     CHECK_GE(res, 0);
 
@@ -292,6 +296,10 @@
              it != mStreams.end(); ++it) {
             StreamInfo *s = &*it;
 
+            if (s->mIsInjected) {
+                continue;
+            }
+
             if (s->mNumRTCPPacketsReceived == 0) {
                 // We have never received any RTCP packets on this stream,
                 // we don't even know where to send a report.
diff --git a/media/libstagefright/rtsp/ARTPSession.cpp b/media/libstagefright/rtsp/ARTPSession.cpp
index d2c56f7..f60c1a9 100644
--- a/media/libstagefright/rtsp/ARTPSession.cpp
+++ b/media/libstagefright/rtsp/ARTPSession.cpp
@@ -167,6 +167,7 @@
 #endif
 
             accessUnit->meta()->setInt64("ntp-time", ntpTime);
+            accessUnit->meta()->setInt64("timeUs", 0);
 
 #if 0
             int32_t damaged;
diff --git a/media/libstagefright/rtsp/MyHandler.h b/media/libstagefright/rtsp/MyHandler.h
index 7c06db3..3d8d86b 100644
--- a/media/libstagefright/rtsp/MyHandler.h
+++ b/media/libstagefright/rtsp/MyHandler.h
@@ -31,8 +31,6 @@
 #include <media/stagefright/foundation/AMessage.h>
 #include <media/stagefright/MediaErrors.h>
 
-#define USE_TCP_INTERLEAVED     0
-
 // If no access units are received within 3 secs, assume that the rtp
 // stream has ended and signal end of stream.
 static int64_t kAccessUnitTimeoutUs = 3000000ll;
@@ -83,7 +81,8 @@
           mFirstAccessUnit(true),
           mFirstAccessUnitNTP(0),
           mNumAccessUnitsReceived(0),
-          mCheckPending(false) {
+          mCheckPending(false),
+          mTryTCPInterleaving(false) {
         mNetLooper->setName("rtsp net");
         mNetLooper->start(false /* runOnCallingThread */,
                           false /* canCallJava */,
@@ -158,7 +157,13 @@
 
             case 'disc':
             {
-                (new AMessage('quit', id()))->post();
+                int32_t reconnect;
+                if (msg->findInt32("reconnect", &reconnect) && reconnect) {
+                    sp<AMessage> reply = new AMessage('conn', id());
+                    mConn->connect(mSessionURL.c_str(), reply);
+                } else {
+                    (new AMessage('quit', id()))->post();
+                }
                 break;
             }
 
@@ -325,10 +330,6 @@
 
                     parsePlayResponse(response);
 
-                    mDoneMsg->setInt32("result", OK);
-                    mDoneMsg->post();
-                    mDoneMsg = NULL;
-
                     sp<AMessage> timeout = new AMessage('tiou', id());
                     timeout->post(kStartupTimeoutUs);
                 } else {
@@ -342,12 +343,26 @@
             case 'abor':
             {
                 for (size_t i = 0; i < mTracks.size(); ++i) {
-                    mTracks.editItemAt(i).mPacketSource->signalEOS(
-                            ERROR_END_OF_STREAM);
+                    TrackInfo *info = &mTracks.editItemAt(i);
+
+                    info->mPacketSource->signalEOS(ERROR_END_OF_STREAM);
+
+                    if (!info->mUsingInterleavedTCP) {
+                        mRTPConn->removeStream(info->mRTPSocket, info->mRTCPSocket);
+
+                        close(info->mRTPSocket);
+                        close(info->mRTCPSocket);
+                    }
                 }
+                mTracks.clear();
 
                 sp<AMessage> reply = new AMessage('tear', id());
 
+                int32_t reconnect;
+                if (msg->findInt32("reconnect", &reconnect) && reconnect) {
+                    reply->setInt32("reconnect", true);
+                }
+
                 AString request;
                 request = "TEARDOWN ";
 
@@ -374,6 +389,12 @@
                      << result << " (" << strerror(-result) << ")";
 
                 sp<AMessage> reply = new AMessage('disc', id());
+
+                int32_t reconnect;
+                if (msg->findInt32("reconnect", &reconnect) && reconnect) {
+                    reply->setInt32("reconnect", true);
+                }
+
                 mConn->disconnect(reply);
                 break;
             }
@@ -414,6 +435,11 @@
                 size_t trackIndex;
                 CHECK(msg->findSize("track-index", &trackIndex));
 
+                if (trackIndex >= mTracks.size()) {
+                    LOG(ERROR) << "late packets ignored.";
+                    break;
+                }
+
                 TrackInfo *track = &mTracks.editItemAt(trackIndex);
 
                 int32_t eos;
@@ -457,6 +483,10 @@
                 }
 
                 if (mFirstAccessUnit) {
+                    mDoneMsg->setInt32("result", OK);
+                    mDoneMsg->post();
+                    mDoneMsg = NULL;
+
                     mFirstAccessUnit = false;
                     mFirstAccessUnitNTP = ntpTime;
                 }
@@ -583,8 +613,19 @@
             case 'tiou':
             {
                 if (mFirstAccessUnit) {
-                    LOG(WARNING) << "Never received any data, disconnecting.";
-                    (new AMessage('abor', id()))->post();
+                    if (mTryTCPInterleaving) {
+                        LOG(WARNING) << "Never received any data, disconnecting.";
+                        (new AMessage('abor', id()))->post();
+                    } else {
+                        LOG(WARNING)
+                            << "Never received any data, switching transports.";
+
+                        mTryTCPInterleaving = true;
+
+                        sp<AMessage> msg = new AMessage('abor', id());
+                        msg->setInt32("reconnect", true);
+                        msg->post();
+                    }
                 }
                 break;
             }
@@ -705,6 +746,7 @@
     uint64_t mFirstAccessUnitNTP;
     int64_t mNumAccessUnitsReceived;
     bool mCheckPending;
+    bool mTryTCPInterleaving;
 
     struct TrackInfo {
         AString mURL;
@@ -723,6 +765,7 @@
     void setupTrack(size_t index) {
         sp<APacketSource> source =
             new APacketSource(mSessionDesc, index);
+
         if (source->initCheck() != OK) {
             LOG(WARNING) << "Unsupported format. Ignoring track #"
                          << index << ".";
@@ -754,26 +797,26 @@
         request.append(trackURL);
         request.append(" RTSP/1.0\r\n");
 
-#if USE_TCP_INTERLEAVED
-        size_t interleaveIndex = 2 * (mTracks.size() - 1);
-        info->mUsingInterleavedTCP = true;
-        info->mRTPSocket = interleaveIndex;
-        info->mRTCPSocket = interleaveIndex + 1;
+        if (mTryTCPInterleaving) {
+            size_t interleaveIndex = 2 * (mTracks.size() - 1);
+            info->mUsingInterleavedTCP = true;
+            info->mRTPSocket = interleaveIndex;
+            info->mRTCPSocket = interleaveIndex + 1;
 
-        request.append("Transport: RTP/AVP/TCP;interleaved=");
-        request.append(interleaveIndex);
-        request.append("-");
-        request.append(interleaveIndex + 1);
-#else
-        unsigned rtpPort;
-        ARTPConnection::MakePortPair(
-                &info->mRTPSocket, &info->mRTCPSocket, &rtpPort);
+            request.append("Transport: RTP/AVP/TCP;interleaved=");
+            request.append(interleaveIndex);
+            request.append("-");
+            request.append(interleaveIndex + 1);
+        } else {
+            unsigned rtpPort;
+            ARTPConnection::MakePortPair(
+                    &info->mRTPSocket, &info->mRTCPSocket, &rtpPort);
 
-        request.append("Transport: RTP/AVP/UDP;unicast;client_port=");
-        request.append(rtpPort);
-        request.append("-");
-        request.append(rtpPort + 1);
-#endif
+            request.append("Transport: RTP/AVP/UDP;unicast;client_port=");
+            request.append(rtpPort);
+            request.append("-");
+            request.append(rtpPort + 1);
+        }
 
         request.append("\r\n");