From 501eac5dc4da3d507849af7ff8b29976bdbc38d3 Mon Sep 17 00:00:00 2001 From: Randy Lin Date: Wed, 29 Jan 2014 23:09:43 +0800 Subject: [PATCH] Bug 957841 - MediaRecorder crash [@ mozilla::dom::MediaRecorder::Session::AfterTracksAdded]. r=roc --- content/media/MediaRecorder.cpp | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/content/media/MediaRecorder.cpp b/content/media/MediaRecorder.cpp index 9bfc4ab34f9..e8d55d0319b 100644 --- a/content/media/MediaRecorder.cpp +++ b/content/media/MediaRecorder.cpp @@ -172,7 +172,8 @@ class MediaRecorder::Session: public nsIObserver // We need to switch MediaRecorder to "Stop" state first to make sure // MediaRecorder is not associated with this Session anymore, then, it's // safe to delete this Session. - if (recorder->mState != RecordingState::Inactive) { + // Also avoid to run if this session already call stop before + if (!mSession->mStopIssued) { ErrorResult result; recorder->Stop(result); NS_DispatchToMainThread(new DestroyRunnable(mSession.forget())); @@ -182,8 +183,8 @@ class MediaRecorder::Session: public nsIObserver // Dispatch stop event and clear MIME type. recorder->DispatchSimpleEvent(NS_LITERAL_STRING("stop")); - recorder->SetMimeType(NS_LITERAL_STRING("")); - + mSession->mMimeType = NS_LITERAL_STRING(""); + recorder->SetMimeType(mSession->mMimeType); return NS_OK; } @@ -200,7 +201,8 @@ class MediaRecorder::Session: public nsIObserver public: Session(MediaRecorder* aRecorder, int32_t aTimeSlice) : mRecorder(aRecorder), - mTimeSlice(aTimeSlice) + mTimeSlice(aTimeSlice), + mStopIssued(false) { MOZ_ASSERT(NS_IsMainThread()); @@ -226,6 +228,7 @@ public: { MOZ_ASSERT(NS_IsMainThread()); + mStopIssued = true; CleanupStreams(); nsContentUtils::UnregisterShutdownObserver(this); } @@ -248,10 +251,7 @@ public: already_AddRefed GetEncodedData() { - nsString mimeType; - mRecorder->GetMimeType(mimeType); - - return mEncodedBufferCache->ExtractBlob(mimeType); + return mEncodedBufferCache->ExtractBlob(mMimeType); } bool IsEncoderError() @@ -274,10 +274,8 @@ private: // Pull encoded media data from MediaEncoder nsTArray > encodedBuf; - nsString mimeType; - mEncoder->GetEncodedData(&encodedBuf, mimeType); - - mRecorder->SetMimeType(mimeType); + mEncoder->GetEncodedData(&encodedBuf, mMimeType); + mRecorder->SetMimeType(mMimeType); // Append pulled data into cache buffer. for (uint32_t i = 0; i < encodedBuf.Length(); i++) { @@ -325,8 +323,10 @@ private: return; } - // media stream is ready but has been issued stop command - if (mRecorder->mState == RecordingState::Inactive) { + // Media stream is ready but UA issues a stop method follow by start method. + // The Session::stop would clean the mTrackUnionStream. If the AfterTracksAdded + // comes after stop command, this function would crash. + if (!mTrackUnionStream) { DoSessionEndTask(NS_OK); return; } @@ -400,6 +400,8 @@ private: nsRefPtr mEncoder; // A buffer to cache encoded meda data. nsAutoPtr mEncodedBufferCache; + // Current session mimeType + nsString mMimeType; // Timestamp of the last fired dataavailable event. TimeStamp mLastBlobTimeStamp; // The interval of passing encoded data from EncodedBufferCache to onDataAvailable @@ -407,6 +409,8 @@ private: // onDataAvailable, instead, it passive wait the client side pull encoded data // by calling requestData API. const int32_t mTimeSlice; + // Indicate this session's stop has been called. + bool mStopIssued; }; NS_IMPL_ISUPPORTS1(MediaRecorder::Session, nsIObserver)