From 7aef03379179c109c2547c33c410bfc93c8db576 Mon Sep 17 00:00:00 2001 From: Andreas Huber Date: Mon, 30 Aug 2010 15:25:35 -0700 Subject: Instead of closing the connection altogether if no UDP packets arrive after a certain time, try changing transports (to interleaved TCP). Also properly close the sockets on disconnection. Change-Id: Ie8d6a3865a0477e28d4b76bb9038e468451287b1 related-to-bug: 2556656 --- media/libstagefright/rtsp/ARTPConnection.cpp | 8 ++ media/libstagefright/rtsp/MyHandler.h | 107 +++++++++++++++++++-------- 2 files changed, 83 insertions(+), 32 deletions(-) (limited to 'media/libstagefright/rtsp') 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 @@ void ARTPConnection::onPollStreams() { } } + if (maxSocket == -1) { + return; + } + int res = select(maxSocket + 1, &rs, NULL, NULL, &tv); CHECK_GE(res, 0); @@ -292,6 +296,10 @@ void ARTPConnection::onPollStreams() { 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/MyHandler.h b/media/libstagefright/rtsp/MyHandler.h index f20dd6f..ee6f65a 100644 --- a/media/libstagefright/rtsp/MyHandler.h +++ b/media/libstagefright/rtsp/MyHandler.h @@ -31,8 +31,6 @@ #include #include -#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 @@ struct MyHandler : public AHandler { 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 @@ struct MyHandler : public AHandler { case 'disc': { - (new AMessage('quit', id()))->post(); + int32_t reconnect; + if (msg->findInt32("reconnect", &reconnect) && reconnect) { + sp reply = new AMessage('conn', id()); + mConn->connect(mSessionURL.c_str(), reply); + } else { + (new AMessage('quit', id()))->post(); + } break; } @@ -325,10 +330,6 @@ struct MyHandler : public AHandler { parsePlayResponse(response); - mDoneMsg->setInt32("result", OK); - mDoneMsg->post(); - mDoneMsg = NULL; - sp timeout = new AMessage('tiou', id()); timeout->post(kStartupTimeoutUs); } else { @@ -342,12 +343,26 @@ struct MyHandler : public AHandler { 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 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 @@ struct MyHandler : public AHandler { << result << " (" << strerror(-result) << ")"; sp 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 @@ struct MyHandler : public AHandler { 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 @@ struct MyHandler : public AHandler { } if (mFirstAccessUnit) { + mDoneMsg->setInt32("result", OK); + mDoneMsg->post(); + mDoneMsg = NULL; + mFirstAccessUnit = false; mFirstAccessUnitNTP = ntpTime; } @@ -583,8 +613,19 @@ struct MyHandler : public AHandler { 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 msg = new AMessage('abor', id()); + msg->setInt32("reconnect", true); + msg->post(); + } } break; } @@ -705,6 +746,7 @@ private: uint64_t mFirstAccessUnitNTP; int64_t mNumAccessUnitsReceived; bool mCheckPending; + bool mTryTCPInterleaving; struct TrackInfo { AString mURL; @@ -723,6 +765,7 @@ private: void setupTrack(size_t index) { sp source = new APacketSource(mSessionDesc, index); + if (source->initCheck() != OK) { LOG(WARNING) << "Unsupported format. Ignoring track #" << index << "."; @@ -754,26 +797,26 @@ private: 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; - - 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 + 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/UDP;unicast;client_port="); + request.append(rtpPort); + request.append("-"); + request.append(rtpPort + 1); + } request.append("\r\n"); -- cgit v1.1