Skip to content

Commit 1daf8a1

Browse files
theandi666nadlabak
authored andcommitted
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 b7eea9d commit 1daf8a1

1 file changed

Lines changed: 93 additions & 3 deletions

File tree

media/libstagefright/rtsp/MyHandler.h

Lines changed: 93 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,16 @@
4040
#include <sys/socket.h>
4141
#include <netdb.h>
4242

43-
// If no access units are received within 3 secs, assume that the rtp
43+
// If no access units are received within 10 secs, assume that the rtp
4444
// stream has ended and signal end of stream.
45-
static int64_t kAccessUnitTimeoutUs = 3000000ll;
45+
static int64_t kAccessUnitTimeoutUs = 10000000ll;
4646

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

51+
static int64_t kDefaultKeepAliveTimeoutUs = 60000000ll;
52+
5153
namespace android {
5254

5355
static void MakeUserAgentString(AString *s) {
@@ -110,7 +112,9 @@ struct MyHandler : public AHandler {
110112
mTryFakeRTCP(false),
111113
mReceivedFirstRTCPPacket(false),
112114
mReceivedFirstRTPPacket(false),
113-
mSeekable(false) {
115+
mSeekable(false),
116+
mKeepAliveTimeoutUs(kDefaultKeepAliveTimeoutUs),
117+
mKeepAliveGeneration(0) {
114118
mNetLooper->setName("rtsp net");
115119
mNetLooper->start(false /* runOnCallingThread */,
116120
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"
@@ -549,6 +583,9 @@ struct MyHandler : public AHandler {
549583
if (index < mSessionDesc->countTracks()) {
550584
setupTrack(index);
551585
} else if (mSetupTracksSuccessful) {
586+
++mKeepAliveGeneration;
587+
postKeepAlive();
588+
552589
AString request = "PLAY ";
553590
request.append(mSessionURL);
554591
request.append(" RTSP/1.0\r\n");
@@ -600,6 +637,51 @@ struct MyHandler : public AHandler {
600637
break;
601638
}
602639

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

1047+
void postKeepAlive() {
1048+
sp<AMessage> msg = new AMessage('aliv', id());
1049+
msg->setInt32("generation", mKeepAliveGeneration);
1050+
msg->post((mKeepAliveTimeoutUs * 9) / 10);
1051+
}
1052+
9651053
void postAccessUnitTimeoutCheck() {
9661054
if (mCheckPending) {
9671055
return;
@@ -1092,6 +1180,8 @@ struct MyHandler : public AHandler {
10921180
bool mReceivedFirstRTCPPacket;
10931181
bool mReceivedFirstRTPPacket;
10941182
bool mSeekable;
1183+
int64_t mKeepAliveTimeoutUs;
1184+
int32_t mKeepAliveGeneration;
10951185

10961186
struct TrackInfo {
10971187
AString mURL;

0 commit comments

Comments
 (0)