Skip to content

Commit a1b3e3d

Browse files
committed
Send RTSP control connection keep-alive requests
default to 60 secs unless overridden by server's session-id response. Change-Id: I7c3aff5b787dbb57cc0dccf9db3c75e5cf7e778c related-to-bug: 5562303
1 parent b78ae75 commit a1b3e3d

File tree

1 file changed

+92
-2
lines changed

1 file changed

+92
-2
lines changed

media/libstagefright/rtsp/MyHandler.h

Lines changed: 92 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,14 @@
4444

4545
// If no access units are received within 5 secs, assume that the rtp
4646
// stream has ended and signal end of stream.
47-
static int64_t kAccessUnitTimeoutUs = 5000000ll;
47+
static int64_t kAccessUnitTimeoutUs = 10000000ll;
4848

4949
// If no access units arrive for the first 10 secs after starting the
5050
// stream, assume none ever will and signal EOS or switch transports.
5151
static int64_t kStartupTimeoutUs = 10000000ll;
5252

53+
static int64_t kDefaultKeepAliveTimeoutUs = 60000000ll;
54+
5355
namespace android {
5456

5557
static void MakeUserAgentString(AString *s) {
@@ -130,7 +132,9 @@ struct MyHandler : public AHandler {
130132
mTryFakeRTCP(false),
131133
mReceivedFirstRTCPPacket(false),
132134
mReceivedFirstRTPPacket(false),
133-
mSeekable(false) {
135+
mSeekable(false),
136+
mKeepAliveTimeoutUs(kDefaultKeepAliveTimeoutUs),
137+
mKeepAliveGeneration(0) {
134138
mNetLooper->setName("rtsp net");
135139
mNetLooper->start(false /* runOnCallingThread */,
136140
false /* canCallJava */,
@@ -371,6 +375,8 @@ struct MyHandler : public AHandler {
371375

372376
case 'disc':
373377
{
378+
++mKeepAliveGeneration;
379+
374380
int32_t reconnect;
375381
if (msg->findInt32("reconnect", &reconnect) && reconnect) {
376382
sp<AMessage> reply = new AMessage('conn', id());
@@ -502,6 +508,34 @@ struct MyHandler : public AHandler {
502508
CHECK_GE(i, 0);
503509

504510
mSessionID = response->mHeaders.valueAt(i);
511+
512+
mKeepAliveTimeoutUs = kDefaultKeepAliveTimeoutUs;
513+
AString timeoutStr;
514+
if (GetAttribute(
515+
mSessionID.c_str(), "timeout", &timeoutStr)) {
516+
char *end;
517+
unsigned long timeoutSecs =
518+
strtoul(timeoutStr.c_str(), &end, 10);
519+
520+
if (end == timeoutStr.c_str() || *end != '\0') {
521+
LOGW("server specified malformed timeout '%s'",
522+
timeoutStr.c_str());
523+
524+
mKeepAliveTimeoutUs = kDefaultKeepAliveTimeoutUs;
525+
} else if (timeoutSecs < 15) {
526+
LOGW("server specified too short a timeout "
527+
"(%lu secs), using default.",
528+
timeoutSecs);
529+
530+
mKeepAliveTimeoutUs = kDefaultKeepAliveTimeoutUs;
531+
} else {
532+
mKeepAliveTimeoutUs = timeoutSecs * 1000000ll;
533+
534+
LOGI("server specified timeout of %lu secs.",
535+
timeoutSecs);
536+
}
537+
}
538+
505539
i = mSessionID.find(";");
506540
if (i >= 0) {
507541
// Remove options, i.e. ";timeout=90"
@@ -555,6 +589,9 @@ struct MyHandler : public AHandler {
555589
if (index < mSessionDesc->countTracks()) {
556590
setupTrack(index);
557591
} else if (mSetupTracksSuccessful) {
592+
++mKeepAliveGeneration;
593+
postKeepAlive();
594+
558595
AString request = "PLAY ";
559596
request.append(mSessionURL);
560597
request.append(" RTSP/1.0\r\n");
@@ -606,6 +643,51 @@ struct MyHandler : public AHandler {
606643
break;
607644
}
608645

646+
case 'aliv':
647+
{
648+
int32_t generation;
649+
CHECK(msg->findInt32("generation", &generation));
650+
651+
if (generation != mKeepAliveGeneration) {
652+
// obsolete event.
653+
break;
654+
}
655+
656+
AString request;
657+
request.append("OPTIONS ");
658+
request.append(mSessionURL);
659+
request.append(" RTSP/1.0\r\n");
660+
request.append("Session: ");
661+
request.append(mSessionID);
662+
request.append("\r\n");
663+
request.append("\r\n");
664+
665+
sp<AMessage> reply = new AMessage('opts', id());
666+
reply->setInt32("generation", mKeepAliveGeneration);
667+
mConn->sendRequest(request.c_str(), reply);
668+
break;
669+
}
670+
671+
case 'opts':
672+
{
673+
int32_t result;
674+
CHECK(msg->findInt32("result", &result));
675+
676+
LOGI("OPTIONS completed with result %d (%s)",
677+
result, strerror(-result));
678+
679+
int32_t generation;
680+
CHECK(msg->findInt32("generation", &generation));
681+
682+
if (generation != mKeepAliveGeneration) {
683+
// obsolete event.
684+
break;
685+
}
686+
687+
postKeepAlive();
688+
break;
689+
}
690+
609691
case 'abor':
610692
{
611693
for (size_t i = 0; i < mTracks.size(); ++i) {
@@ -952,6 +1034,12 @@ struct MyHandler : public AHandler {
9521034
}
9531035
}
9541036

1037+
void postKeepAlive() {
1038+
sp<AMessage> msg = new AMessage('aliv', id());
1039+
msg->setInt32("generation", mKeepAliveGeneration);
1040+
msg->post((mKeepAliveTimeoutUs * 9) / 10);
1041+
}
1042+
9551043
void postAccessUnitTimeoutCheck() {
9561044
if (mCheckPending) {
9571045
return;
@@ -1120,6 +1208,8 @@ struct MyHandler : public AHandler {
11201208
bool mReceivedFirstRTCPPacket;
11211209
bool mReceivedFirstRTPPacket;
11221210
bool mSeekable;
1211+
int64_t mKeepAliveTimeoutUs;
1212+
int32_t mKeepAliveGeneration;
11231213

11241214
Vector<TrackInfo> mTracks;
11251215

0 commit comments

Comments
 (0)