Merge "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." into gingerbread
This commit is contained in:
committed by
Android (Google) Code Review
commit
abb8398e5a
@@ -263,6 +263,10 @@ void ARTPConnection::onPollStreams() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (maxSocket == -1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int res = select(maxSocket + 1, &rs, NULL, NULL, &tv);
|
int res = select(maxSocket + 1, &rs, NULL, NULL, &tv);
|
||||||
CHECK_GE(res, 0);
|
CHECK_GE(res, 0);
|
||||||
|
|
||||||
@@ -292,6 +296,10 @@ void ARTPConnection::onPollStreams() {
|
|||||||
it != mStreams.end(); ++it) {
|
it != mStreams.end(); ++it) {
|
||||||
StreamInfo *s = &*it;
|
StreamInfo *s = &*it;
|
||||||
|
|
||||||
|
if (s->mIsInjected) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (s->mNumRTCPPacketsReceived == 0) {
|
if (s->mNumRTCPPacketsReceived == 0) {
|
||||||
// We have never received any RTCP packets on this stream,
|
// We have never received any RTCP packets on this stream,
|
||||||
// we don't even know where to send a report.
|
// we don't even know where to send a report.
|
||||||
|
|||||||
@@ -31,8 +31,6 @@
|
|||||||
#include <media/stagefright/foundation/AMessage.h>
|
#include <media/stagefright/foundation/AMessage.h>
|
||||||
#include <media/stagefright/MediaErrors.h>
|
#include <media/stagefright/MediaErrors.h>
|
||||||
|
|
||||||
#define USE_TCP_INTERLEAVED 0
|
|
||||||
|
|
||||||
// If no access units are received within 3 secs, assume that the rtp
|
// If no access units are received within 3 secs, assume that the rtp
|
||||||
// stream has ended and signal end of stream.
|
// stream has ended and signal end of stream.
|
||||||
static int64_t kAccessUnitTimeoutUs = 3000000ll;
|
static int64_t kAccessUnitTimeoutUs = 3000000ll;
|
||||||
@@ -83,7 +81,8 @@ struct MyHandler : public AHandler {
|
|||||||
mFirstAccessUnit(true),
|
mFirstAccessUnit(true),
|
||||||
mFirstAccessUnitNTP(0),
|
mFirstAccessUnitNTP(0),
|
||||||
mNumAccessUnitsReceived(0),
|
mNumAccessUnitsReceived(0),
|
||||||
mCheckPending(false) {
|
mCheckPending(false),
|
||||||
|
mTryTCPInterleaving(false) {
|
||||||
mNetLooper->setName("rtsp net");
|
mNetLooper->setName("rtsp net");
|
||||||
mNetLooper->start(false /* runOnCallingThread */,
|
mNetLooper->start(false /* runOnCallingThread */,
|
||||||
false /* canCallJava */,
|
false /* canCallJava */,
|
||||||
@@ -158,7 +157,13 @@ struct MyHandler : public AHandler {
|
|||||||
|
|
||||||
case 'disc':
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -325,10 +330,6 @@ struct MyHandler : public AHandler {
|
|||||||
|
|
||||||
parsePlayResponse(response);
|
parsePlayResponse(response);
|
||||||
|
|
||||||
mDoneMsg->setInt32("result", OK);
|
|
||||||
mDoneMsg->post();
|
|
||||||
mDoneMsg = NULL;
|
|
||||||
|
|
||||||
sp<AMessage> timeout = new AMessage('tiou', id());
|
sp<AMessage> timeout = new AMessage('tiou', id());
|
||||||
timeout->post(kStartupTimeoutUs);
|
timeout->post(kStartupTimeoutUs);
|
||||||
} else {
|
} else {
|
||||||
@@ -342,12 +343,26 @@ struct MyHandler : public AHandler {
|
|||||||
case 'abor':
|
case 'abor':
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < mTracks.size(); ++i) {
|
for (size_t i = 0; i < mTracks.size(); ++i) {
|
||||||
mTracks.editItemAt(i).mPacketSource->signalEOS(
|
TrackInfo *info = &mTracks.editItemAt(i);
|
||||||
ERROR_END_OF_STREAM);
|
|
||||||
|
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());
|
sp<AMessage> reply = new AMessage('tear', id());
|
||||||
|
|
||||||
|
int32_t reconnect;
|
||||||
|
if (msg->findInt32("reconnect", &reconnect) && reconnect) {
|
||||||
|
reply->setInt32("reconnect", true);
|
||||||
|
}
|
||||||
|
|
||||||
AString request;
|
AString request;
|
||||||
request = "TEARDOWN ";
|
request = "TEARDOWN ";
|
||||||
|
|
||||||
@@ -374,6 +389,12 @@ struct MyHandler : public AHandler {
|
|||||||
<< result << " (" << strerror(-result) << ")";
|
<< result << " (" << strerror(-result) << ")";
|
||||||
|
|
||||||
sp<AMessage> reply = new AMessage('disc', id());
|
sp<AMessage> reply = new AMessage('disc', id());
|
||||||
|
|
||||||
|
int32_t reconnect;
|
||||||
|
if (msg->findInt32("reconnect", &reconnect) && reconnect) {
|
||||||
|
reply->setInt32("reconnect", true);
|
||||||
|
}
|
||||||
|
|
||||||
mConn->disconnect(reply);
|
mConn->disconnect(reply);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -414,6 +435,11 @@ struct MyHandler : public AHandler {
|
|||||||
size_t trackIndex;
|
size_t trackIndex;
|
||||||
CHECK(msg->findSize("track-index", &trackIndex));
|
CHECK(msg->findSize("track-index", &trackIndex));
|
||||||
|
|
||||||
|
if (trackIndex >= mTracks.size()) {
|
||||||
|
LOG(ERROR) << "late packets ignored.";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
TrackInfo *track = &mTracks.editItemAt(trackIndex);
|
TrackInfo *track = &mTracks.editItemAt(trackIndex);
|
||||||
|
|
||||||
int32_t eos;
|
int32_t eos;
|
||||||
@@ -457,6 +483,10 @@ struct MyHandler : public AHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mFirstAccessUnit) {
|
if (mFirstAccessUnit) {
|
||||||
|
mDoneMsg->setInt32("result", OK);
|
||||||
|
mDoneMsg->post();
|
||||||
|
mDoneMsg = NULL;
|
||||||
|
|
||||||
mFirstAccessUnit = false;
|
mFirstAccessUnit = false;
|
||||||
mFirstAccessUnitNTP = ntpTime;
|
mFirstAccessUnitNTP = ntpTime;
|
||||||
}
|
}
|
||||||
@@ -583,8 +613,19 @@ struct MyHandler : public AHandler {
|
|||||||
case 'tiou':
|
case 'tiou':
|
||||||
{
|
{
|
||||||
if (mFirstAccessUnit) {
|
if (mFirstAccessUnit) {
|
||||||
LOG(WARNING) << "Never received any data, disconnecting.";
|
if (mTryTCPInterleaving) {
|
||||||
(new AMessage('abor', id()))->post();
|
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;
|
break;
|
||||||
}
|
}
|
||||||
@@ -705,6 +746,7 @@ private:
|
|||||||
uint64_t mFirstAccessUnitNTP;
|
uint64_t mFirstAccessUnitNTP;
|
||||||
int64_t mNumAccessUnitsReceived;
|
int64_t mNumAccessUnitsReceived;
|
||||||
bool mCheckPending;
|
bool mCheckPending;
|
||||||
|
bool mTryTCPInterleaving;
|
||||||
|
|
||||||
struct TrackInfo {
|
struct TrackInfo {
|
||||||
AString mURL;
|
AString mURL;
|
||||||
@@ -723,6 +765,7 @@ private:
|
|||||||
void setupTrack(size_t index) {
|
void setupTrack(size_t index) {
|
||||||
sp<APacketSource> source =
|
sp<APacketSource> source =
|
||||||
new APacketSource(mSessionDesc, index);
|
new APacketSource(mSessionDesc, index);
|
||||||
|
|
||||||
if (source->initCheck() != OK) {
|
if (source->initCheck() != OK) {
|
||||||
LOG(WARNING) << "Unsupported format. Ignoring track #"
|
LOG(WARNING) << "Unsupported format. Ignoring track #"
|
||||||
<< index << ".";
|
<< index << ".";
|
||||||
@@ -754,26 +797,26 @@ private:
|
|||||||
request.append(trackURL);
|
request.append(trackURL);
|
||||||
request.append(" RTSP/1.0\r\n");
|
request.append(" RTSP/1.0\r\n");
|
||||||
|
|
||||||
#if USE_TCP_INTERLEAVED
|
if (mTryTCPInterleaving) {
|
||||||
size_t interleaveIndex = 2 * (mTracks.size() - 1);
|
size_t interleaveIndex = 2 * (mTracks.size() - 1);
|
||||||
info->mUsingInterleavedTCP = true;
|
info->mUsingInterleavedTCP = true;
|
||||||
info->mRTPSocket = interleaveIndex;
|
info->mRTPSocket = interleaveIndex;
|
||||||
info->mRTCPSocket = interleaveIndex + 1;
|
info->mRTCPSocket = interleaveIndex + 1;
|
||||||
|
|
||||||
request.append("Transport: RTP/AVP/TCP;interleaved=");
|
request.append("Transport: RTP/AVP/TCP;interleaved=");
|
||||||
request.append(interleaveIndex);
|
request.append(interleaveIndex);
|
||||||
request.append("-");
|
request.append("-");
|
||||||
request.append(interleaveIndex + 1);
|
request.append(interleaveIndex + 1);
|
||||||
#else
|
} else {
|
||||||
unsigned rtpPort;
|
unsigned rtpPort;
|
||||||
ARTPConnection::MakePortPair(
|
ARTPConnection::MakePortPair(
|
||||||
&info->mRTPSocket, &info->mRTCPSocket, &rtpPort);
|
&info->mRTPSocket, &info->mRTCPSocket, &rtpPort);
|
||||||
|
|
||||||
request.append("Transport: RTP/AVP/UDP;unicast;client_port=");
|
request.append("Transport: RTP/AVP/UDP;unicast;client_port=");
|
||||||
request.append(rtpPort);
|
request.append(rtpPort);
|
||||||
request.append("-");
|
request.append("-");
|
||||||
request.append(rtpPort + 1);
|
request.append(rtpPort + 1);
|
||||||
#endif
|
}
|
||||||
|
|
||||||
request.append("\r\n");
|
request.append("\r\n");
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user