Bug 899935 - Produce zero-length output if calling Stop right after a Start call of MediaRecorder. r=roc
authorShelly Lin <slin@mozilla.com>
Thu, 29 Aug 2013 19:59:08 +0800
changeset 153022 b3668dd7f9550e71bed652f40aaca398ac3d6483
parent 153021 c52fb7fbabd7ac94514a17c6f868694faeb722ce
child 153023 af09edead9b84d7c8dba0bfe5c5f0cd06c26bda8
push idunknown
push userunknown
push dateunknown
reviewersroc
bugs899935
milestone26.0a1
Bug 899935 - Produce zero-length output if calling Stop right after a Start call of MediaRecorder. r=roc
content/media/MediaRecorder.cpp
content/media/encoder/TrackEncoder.cpp
--- a/content/media/MediaRecorder.cpp
+++ b/content/media/MediaRecorder.cpp
@@ -84,20 +84,24 @@ public:
   {
   public:
     ReleaseEncoderThreadTask(already_AddRefed<MediaRecorder> recorder)
       : mRecorder(recorder) {}
 
     NS_IMETHODIMP Run()
     {
       MOZ_ASSERT(NS_IsMainThread());
+      mRecorder->mReadThread->Shutdown();
+      mRecorder->mReadThread = nullptr;
+
+      // Setting mState to Inactive here is for the case where SourceStream
+      // ends itself, thus the recorder should stop itself too.
       mRecorder->mState = RecordingState::Inactive;
       mRecorder->DispatchSimpleEvent(NS_LITERAL_STRING("stop"));
-      mRecorder->mReadThread->Shutdown();
-      mRecorder->mReadThread = nullptr;
+
       return NS_OK;
     }
 
   private:
     nsRefPtr<MediaRecorder> mRecorder;
   };
 
   NS_IMETHODIMP Run()
@@ -149,17 +153,17 @@ MediaRecorder::ExtractEncodedData()
     for (uint i = 0; i < outputBufs.Length(); i++) {
       mEncodedBufferCache->AppendBuffer(outputBufs[i]);
     }
 
     if (mTimeSlice > 0 && (TimeStamp::Now() - lastBlobTimeStamp).ToMilliseconds() > mTimeSlice) {
       NS_DispatchToMainThread(new PushBlobTask(this));
       lastBlobTimeStamp = TimeStamp::Now();
     }
-  } while (mState == RecordingState::Recording && !mEncoder->IsShutdown());
+  } while (!mEncoder->IsShutdown());
 
   NS_DispatchToMainThread(new PushBlobTask(this));
 }
 
 void
 MediaRecorder::Start(const Optional<int32_t>& aTimeSlice, ErrorResult& aResult)
 {
   if (mState != RecordingState::Inactive) {
@@ -224,17 +228,22 @@ MediaRecorder::Start(const Optional<int3
 void
 MediaRecorder::Stop(ErrorResult& aResult)
 {
   if (mState == RecordingState::Inactive) {
     aResult.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
     return;
   }
   mState = RecordingState::Inactive;
-  mTrackUnionStream->RemoveListener(mEncoder);
+
+  mStreamPort->Destroy();
+  mStreamPort = nullptr;
+
+  mTrackUnionStream->Destroy();
+  mTrackUnionStream = nullptr;
 }
 
 void
 MediaRecorder::Pause(ErrorResult& aResult)
 {
   if (mState != RecordingState::Recording) {
     aResult.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
     return;
--- a/content/media/encoder/TrackEncoder.cpp
+++ b/content/media/encoder/TrackEncoder.cpp
@@ -77,17 +77,17 @@ AudioTrackEncoder::NotifyRemoved(MediaSt
 }
 
 void
 AudioTrackEncoder::NotifyEndOfStream()
 {
   // If source audio chunks are completely silent till the end of encoding,
   // initialize the encoder with default channel counts and sampling rate, and
   // append this many null data to the segment of track encoder.
-  if (!mCanceled && !mInitialized && mSilentDuration > 0) {
+  if (!mCanceled && !mInitialized) {
     Init(DEFAULT_CHANNELS, DEFAULT_SAMPLING_RATE);
     mRawSegment->AppendNullData(mSilentDuration);
     mSilentDuration = 0;
   }
 
   ReentrantMonitorAutoEnter mon(mReentrantMonitor);
   mEndOfStream = true;
   mReentrantMonitor.NotifyAll();