Bug 1117486 - [FFOS2.0][Woodduck] System crash by replaying the same RTSP clip several times. r=bechen
authorEthan Tseng <ettseng@mozilla.com>
Mon, 16 Feb 2015 12:37:09 +0800
changeset 232738 074a9461cafd2784ad9c9d8ec21085ad37515768
parent 232737 420b643efff12dd8e9dbbd9aae30a10817340bec
child 232739 2a019a588c26b3fdbdf7bb35e05d0cd1f70bfb69
push id56646
push userryanvm@gmail.com
push dateTue, 10 Mar 2015 14:27:41 +0000
treeherdermozilla-inbound@9264aec18c62 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbechen
bugs1117486
milestone39.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1117486 - [FFOS2.0][Woodduck] System crash by replaying the same RTSP clip several times. r=bechen
netwerk/protocol/rtsp/rtsp/RTSPConnectionHandler.h
netwerk/protocol/rtsp/rtsp/RTSPSource.cpp
netwerk/protocol/rtsp/rtsp/RTSPSource.h
--- a/netwerk/protocol/rtsp/rtsp/RTSPConnectionHandler.h
+++ b/netwerk/protocol/rtsp/rtsp/RTSPConnectionHandler.h
@@ -1099,16 +1099,21 @@ struct RtspConnectionHandler : public AH
                 sp<AMessage> reply = new AMessage(kWhatSeek1, id());
                 reply->setInt64("time", timeUs);
                 mConn->sendRequest(request.c_str(), reply);
                 break;
             }
 
             case kWhatSeek1:
             {
+                if (mAborted || !mSeekPending) {
+                    LOGV("We're aborted, dropping stale packet.");
+                    break;
+                }
+
                 // Session is paused now.
                 for (size_t i = 0; i < mTracks.size(); ++i) {
                     TrackInfo *info = &mTracks.editItemAt(i);
 
                     postQueueSeekDiscontinuity(i);
 
                     info->mRTPAnchor = 0;
                     info->mNTPAnchorUs = -1;
@@ -1131,26 +1136,24 @@ struct RtspConnectionHandler : public AH
 
                 sp<AMessage> reply = new AMessage(kWhatSeek2, id());
                 mConn->sendRequest(request.c_str(), reply);
                 break;
             }
 
             case kWhatSeek2:
             {
-                CHECK(mSeekPending);
-
                 int32_t result;
                 CHECK(msg->findInt32("result", &result));
 
                 LOGI("PLAY completed with result %d (%s)",
                      result, strerror(-result));
-                if (mAborted) {
-                  LOGV("we're aborted, dropping stale packet.");
-                  break;
+                if (mAborted || !mSeekPending) {
+                    LOGV("We're aborted, dropping stale packet.");
+                    break;
                 }
 
                 for (size_t i = 0; i < mTracks.size(); i++) {
                     setCheckPending(i, false);
                     postAccessUnitTimeoutCheck(i);
                 }
 
                 if (result == OK) {
--- a/netwerk/protocol/rtsp/rtsp/RTSPSource.cpp
+++ b/netwerk/protocol/rtsp/rtsp/RTSPSource.cpp
@@ -420,16 +420,20 @@ void RTSPSource::onMessageReceived(const
                 mPlayPending = false;
                 performPlay(mLatestPausedUnit);
             }
             break;
         }
 
         case RtspConnectionHandler::kWhatAccessUnitComplete:
         {
+            if (!isValidState()) {
+                LOGI("We're disconnected, dropping access unit.");
+                break;
+            }
             size_t trackIndex;
             CHECK(msg->findSize("trackIndex", &trackIndex));
             CHECK_LT(trackIndex, mTracks.size());
 
             sp<RefBase> obj;
             CHECK(msg->findObject("accessUnit", &obj));
 
             sp<ABuffer> accessUnit = static_cast<ABuffer *>(obj.get());
@@ -476,16 +480,20 @@ void RTSPSource::onMessageReceived(const
             }
 
             onTrackDataAvailable(trackIndex);
             break;
         }
 
         case RtspConnectionHandler::kWhatEOS:
         {
+            if (!isValidState()) {
+                LOGI("We're disconnected, dropping end-of-stream message.");
+                break;
+            }
             size_t trackIndex;
             CHECK(msg->findSize("trackIndex", &trackIndex));
             CHECK_LT(trackIndex, mTracks.size());
 
             int32_t finalResult;
             CHECK(msg->findInt32("finalResult", &finalResult));
             CHECK_NE(finalResult, (status_t)OK);
 
@@ -496,16 +504,20 @@ void RTSPSource::onMessageReceived(const
             }
 
             onTrackEndOfStream(trackIndex);
             break;
         }
 
         case RtspConnectionHandler::kWhatSeekDiscontinuity:
         {
+            if (!isValidState()) {
+                LOGI("We're disconnected, dropping seek discontinuity message.");
+                break;
+            }
             size_t trackIndex;
             CHECK(msg->findSize("trackIndex", &trackIndex));
             CHECK_LT(trackIndex, mTracks.size());
 
             TrackInfo *info = &mTracks.editItemAt(trackIndex);
             sp<AnotherPacketSource> source = info->mSource;
             if (source != NULL) {
 #if ANDROID_VERSION >= 21
@@ -516,16 +528,21 @@ void RTSPSource::onMessageReceived(const
 #endif
             }
 
             break;
         }
 
         case RtspConnectionHandler::kWhatNormalPlayTimeMapping:
         {
+            if (!isValidState()) {
+                LOGI("We're disconnected, dropping normal play time mapping "
+                     "message.");
+                break;
+            }
             size_t trackIndex;
             CHECK(msg->findSize("trackIndex", &trackIndex));
             CHECK_LT(trackIndex, mTracks.size());
 
             uint32_t rtpTime;
             CHECK(msg->findInt32("rtpTime", (int32_t *)&rtpTime));
 
             int64_t nptUs;
@@ -766,15 +783,24 @@ void RTSPSource::onTrackEndOfStream(size
     meta->SetFrameType(MEDIASTREAM_FRAMETYPE_END_OF_STREAM);
 
     nsCString data;
     data.AssignLiteral("END_OF_STREAM");
 
     mListener->OnMediaDataAvailable(trackIndex, data, data.Length(), 0, meta.get());
 }
 
+inline bool RTSPSource::isValidState()
+{
+    if (mState == DISCONNECTED || mTracks.size() == 0) {
+        return false;
+    }
+    return true;
+}
+
+
 
 bool RTSPSource::isLiveStream() {
     int64_t duration = 0;
     getDuration(&duration);
     return duration == 0;
 }
 }  // namespace android
--- a/netwerk/protocol/rtsp/rtsp/RTSPSource.h
+++ b/netwerk/protocol/rtsp/rtsp/RTSPSource.h
@@ -147,16 +147,18 @@ private:
     void performSuspend();
 
     void performPlaybackEnded();
 
     void onTrackDataAvailable(size_t trackIndex);
 
     void onTrackEndOfStream(size_t trackIndex);
 
+    inline bool isValidState();
+
     bool isLiveStream();
 
     // This flag is set if we have just disconnected
     // in order to pretend pausing a live stream.
     bool mDisconnectedToPauseLiveStream;
 
     // While performing a play operation, if the current state of RTSP connection
     // is disconnected, we will start over establishing connection to the server.