am 99fa510e: Merge "Better detection of connection problems - timeout if no rtcp packets arrive within a certain time, not a final frame (which may take longer)" into gingerbread

Merge commit '99fa510e67cb973b45fc216c75bdc817421e14ae' into gingerbread-plus-aosp

* commit '99fa510e67cb973b45fc216c75bdc817421e14ae':
  Better detection of connection problems - timeout if no rtcp packets arrive within a certain time, not a final frame (which may take longer)
This commit is contained in:
Andreas Huber
2010-08-31 14:45:07 -07:00
committed by Android Git Automerger
2 changed files with 78 additions and 54 deletions

View File

@@ -362,7 +362,6 @@ status_t ARTPConnection::receive(StreamInfo *s, bool receiveRTP) {
if (receiveRTP) { if (receiveRTP) {
err = parseRTP(s, buffer); err = parseRTP(s, buffer);
} else { } else {
++s->mNumRTCPPacketsReceived;
err = parseRTCP(s, buffer); err = parseRTCP(s, buffer);
} }
@@ -456,6 +455,12 @@ status_t ARTPConnection::parseRTP(StreamInfo *s, const sp<ABuffer> &buffer) {
} }
status_t ARTPConnection::parseRTCP(StreamInfo *s, const sp<ABuffer> &buffer) { 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(); const uint8_t *data = buffer->data();
size_t size = buffer->size(); size_t size = buffer->size();
@@ -626,7 +631,6 @@ void ARTPConnection::onInjectPacket(const sp<AMessage> &msg) {
if (it->mRTPSocket == index) { if (it->mRTPSocket == index) {
err = parseRTP(s, buffer); err = parseRTP(s, buffer);
} else { } else {
++s->mNumRTCPPacketsReceived;
err = parseRTCP(s, buffer); err = parseRTCP(s, buffer);
} }
} }

View File

@@ -82,7 +82,8 @@ struct MyHandler : public AHandler {
mFirstAccessUnitNTP(0), mFirstAccessUnitNTP(0),
mNumAccessUnitsReceived(0), mNumAccessUnitsReceived(0),
mCheckPending(false), mCheckPending(false),
mTryTCPInterleaving(false) { mTryTCPInterleaving(false),
mReceivedFirstRTCPPacket(false) {
mNetLooper->setName("rtsp net"); mNetLooper->setName("rtsp net");
mNetLooper->start(false /* runOnCallingThread */, mNetLooper->start(false /* runOnCallingThread */,
false /* canCallJava */, false /* canCallJava */,
@@ -199,31 +200,35 @@ struct MyHandler : public AHandler {
break; break;
} }
CHECK_EQ(response->mStatusCode, 200u); if (response->mStatusCode != 200) {
result = UNKNOWN_ERROR;
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 { } 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) { if (i >= 0) {
mBaseURL = response->mHeaders.valueAt(i); mBaseURL = response->mHeaders.valueAt(i);
} else { } 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); CHECK_GT(mSessionDesc->countTracks(), 1u);
setupTrack(1); setupTrack(1);
} else { }
}
if (result != OK) {
sp<AMessage> reply = new AMessage('disc', id()); sp<AMessage> reply = new AMessage('disc', id());
mConn->disconnect(reply); mConn->disconnect(reply);
} }
@@ -247,6 +252,39 @@ struct MyHandler : public AHandler {
LOG(INFO) << "SETUP(" << index << ") completed with result " LOG(INFO) << "SETUP(" << index << ") completed with result "
<< result << " (" << strerror(-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 (result != OK) {
if (track) { if (track) {
if (!track->mUsingInterleavedTCP) { if (!track->mUsingInterleavedTCP) {
@@ -256,37 +294,6 @@ struct MyHandler : public AHandler {
mTracks.removeItemsAt(trackIndex); 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; ++index;
@@ -355,6 +362,12 @@ struct MyHandler : public AHandler {
} }
} }
mTracks.clear(); mTracks.clear();
mSetupTracksSuccessful = false;
mSeekPending = false;
mFirstAccessUnit = true;
mFirstAccessUnitNTP = 0;
mNumAccessUnitsReceived = 0;
mReceivedFirstRTCPPacket = false;
sp<AMessage> reply = new AMessage('tear', id()); sp<AMessage> reply = new AMessage('tear', id());
@@ -424,6 +437,12 @@ struct MyHandler : public AHandler {
case 'accu': case 'accu':
{ {
int32_t firstRTCP;
if (msg->findInt32("first-rtcp", &firstRTCP)) {
mReceivedFirstRTCPPacket = true;
break;
}
++mNumAccessUnitsReceived; ++mNumAccessUnitsReceived;
if (!mCheckPending) { if (!mCheckPending) {
@@ -612,7 +631,7 @@ struct MyHandler : public AHandler {
case 'tiou': case 'tiou':
{ {
if (mFirstAccessUnit) { if (!mReceivedFirstRTCPPacket) {
if (mTryTCPInterleaving) { if (mTryTCPInterleaving) {
LOG(WARNING) << "Never received any data, disconnecting."; LOG(WARNING) << "Never received any data, disconnecting.";
(new AMessage('abor', id()))->post(); (new AMessage('abor', id()))->post();
@@ -747,6 +766,7 @@ private:
int64_t mNumAccessUnitsReceived; int64_t mNumAccessUnitsReceived;
bool mCheckPending; bool mCheckPending;
bool mTryTCPInterleaving; bool mTryTCPInterleaving;
bool mReceivedFirstRTCPPacket;
struct TrackInfo { struct TrackInfo {
AString mURL; AString mURL;