From 6f85dba3768089679ff5e35ad2f1841918d0adb2 Mon Sep 17 00:00:00 2001 From: Andreas Huber Date: Wed, 15 Sep 2010 11:18:13 -0700 Subject: Various fixes to improve resilience of the rtsp stack against spurious errors instead of asserting. Change-Id: Idbec5996ed0675c70e911b9c0514961fea099fb4 --- media/libstagefright/rtsp/APacketSource.cpp | 6 ++- media/libstagefright/rtsp/ARTSPConnection.cpp | 49 +++++++++++++++----- media/libstagefright/rtsp/MyHandler.h | 65 +++++++++++++++++---------- 3 files changed, 84 insertions(+), 36 deletions(-) (limited to 'media/libstagefright/rtsp') diff --git a/media/libstagefright/rtsp/APacketSource.cpp b/media/libstagefright/rtsp/APacketSource.cpp index b63798f..b3e86eb 100644 --- a/media/libstagefright/rtsp/APacketSource.cpp +++ b/media/libstagefright/rtsp/APacketSource.cpp @@ -764,7 +764,11 @@ int64_t APacketSource::getQueueDurationUs(bool *eos) { int64_t lastTimeUs; CHECK(last->meta()->findInt64("timeUs", &lastTimeUs)); - CHECK_GE(lastTimeUs, firstTimeUs); + if (lastTimeUs < firstTimeUs) { + LOG(ERROR) << "Huh? Time moving backwards? " + << firstTimeUs << " > " << lastTimeUs; + return 0; + } return lastTimeUs - firstTimeUs; } diff --git a/media/libstagefright/rtsp/ARTSPConnection.cpp b/media/libstagefright/rtsp/ARTSPConnection.cpp index cbd4836..da4a73a 100644 --- a/media/libstagefright/rtsp/ARTSPConnection.cpp +++ b/media/libstagefright/rtsp/ARTSPConnection.cpp @@ -175,19 +175,38 @@ void ARTSPConnection::onConnect(const sp &msg) { mState = CONNECTING; - mSocket = socket(AF_INET, SOCK_STREAM, 0); - - MakeSocketBlocking(mSocket, false); - AString url; CHECK(msg->findString("url", &url)); + sp reply; + CHECK(msg->findMessage("reply", &reply)); + AString host, path; unsigned port; - CHECK(ParseURL(url.c_str(), &host, &port, &path)); + if (!ParseURL(url.c_str(), &host, &port, &path)) { + LOG(ERROR) << "Malformed rtsp url " << url; + + reply->setInt32("result", ERROR_MALFORMED); + reply->post(); + + mState = DISCONNECTED; + return; + } struct hostent *ent = gethostbyname(host.c_str()); - CHECK(ent != NULL); + if (ent == NULL) { + LOG(ERROR) << "Unknown host " << host; + + reply->setInt32("result", -ENOENT); + reply->post(); + + mState = DISCONNECTED; + return; + } + + mSocket = socket(AF_INET, SOCK_STREAM, 0); + + MakeSocketBlocking(mSocket, false); struct sockaddr_in remote; memset(remote.sin_zero, 0, sizeof(remote.sin_zero)); @@ -198,9 +217,6 @@ void ARTSPConnection::onConnect(const sp &msg) { int err = ::connect( mSocket, (const struct sockaddr *)&remote, sizeof(remote)); - sp reply; - CHECK(msg->findMessage("reply", &reply)); - reply->setInt32("server-ip", ntohl(remote.sin_addr.s_addr)); if (err < 0) { @@ -337,13 +353,20 @@ void ARTSPConnection::onSendRequest(const sp &msg) { if (n == 0) { // Server closed the connection. - TRESPASS(); + LOG(ERROR) << "Server unexpectedly closed the connection."; + + reply->setInt32("result", ERROR_IO); + reply->post(); + return; } else if (n < 0) { if (errno == EINTR) { continue; } - TRESPASS(); + LOG(ERROR) << "Error sending rtsp request."; + reply->setInt32("result", -errno); + reply->post(); + return; } numBytesSent += (size_t)n; @@ -415,13 +438,15 @@ status_t ARTSPConnection::receive(void *data, size_t size) { ssize_t n = recv(mSocket, (uint8_t *)data + offset, size - offset, 0); if (n == 0) { // Server closed the connection. + LOG(ERROR) << "Server unexpectedly closed the connection."; return ERROR_IO; } else if (n < 0) { if (errno == EINTR) { continue; } - TRESPASS(); + LOG(ERROR) << "Error reading rtsp response."; + return -errno; } offset += (size_t)n; diff --git a/media/libstagefright/rtsp/MyHandler.h b/media/libstagefright/rtsp/MyHandler.h index b849117..526bef3 100644 --- a/media/libstagefright/rtsp/MyHandler.h +++ b/media/libstagefright/rtsp/MyHandler.h @@ -209,22 +209,24 @@ struct MyHandler : public AHandler { 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); + if (!mSessionDesc->isValid()) { + result = ERROR_MALFORMED; } else { - i = response->mHeaders.indexOfKey("content-location"); + ssize_t i = response->mHeaders.indexOfKey("content-base"); if (i >= 0) { mBaseURL = response->mHeaders.valueAt(i); } 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); - setupTrack(1); + CHECK_GT(mSessionDesc->countTracks(), 1u); + setupTrack(1); + } } } @@ -333,13 +335,17 @@ struct MyHandler : public AHandler { sp response = static_cast(obj.get()); - CHECK_EQ(response->mStatusCode, 200u); + if (response->mStatusCode != 200) { + result = UNKNOWN_ERROR; + } else { + parsePlayResponse(response); - parsePlayResponse(response); + sp timeout = new AMessage('tiou', id()); + timeout->post(kStartupTimeoutUs); + } + } - sp timeout = new AMessage('tiou', id()); - timeout->post(kStartupTimeoutUs); - } else { + if (result != OK) { sp reply = new AMessage('disc', id()); mConn->disconnect(reply); } @@ -477,6 +483,11 @@ struct MyHandler : public AHandler { uint32_t seqNum = (uint32_t)accessUnit->int32Data(); + if (mSeekPending) { + LOG(INFO) << "we're seeking, dropping stale packet."; + break; + } + if (seqNum < track->mFirstSeqNumInSegment) { LOG(INFO) << "dropping stale access-unit " << "(" << seqNum << " < " @@ -600,18 +611,26 @@ struct MyHandler : public AHandler { LOG(INFO) << "PLAY completed with result " << result << " (" << strerror(-result) << ")"; - CHECK_EQ(result, (status_t)OK); + if (result == OK) { + sp obj; + CHECK(msg->findObject("response", &obj)); + sp response = + static_cast(obj.get()); - sp obj; - CHECK(msg->findObject("response", &obj)); - sp response = - static_cast(obj.get()); + if (response->mStatusCode != 200) { + result = UNKNOWN_ERROR; + } else { + parsePlayResponse(response); - CHECK_EQ(response->mStatusCode, 200u); + LOG(INFO) << "seek completed."; + } + } - parsePlayResponse(response); + if (result != OK) { + LOG(ERROR) << "seek failed, aborting."; + (new AMessage('abor', id()))->post(); + } - LOG(INFO) << "seek completed."; mSeekPending = false; break; } -- cgit v1.1