Bug 1050664 - 1. Fix IsDormantNeeded() function. 2. Invoke mSource->stop at the suspend code path that will rewind the sampletable implicitly. r=cpearce
authorBenjamin Chen <bechen@mozilla.com>
Tue, 26 Aug 2014 16:17:08 +0800
changeset 223262 a3bc4d864cce12866a84dfa497794a87ddc0ad04
parent 223261 c7ccab163c19e00024d772c6b7df55a3544c4531
child 223263 cb0615aada17f5072b064b1f95d25c5fc6db19f7
push id3979
push userraliiev@mozilla.com
push dateMon, 13 Oct 2014 16:35:44 +0000
treeherdermozilla-beta@30f2cc610691 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscpearce
bugs1050664
milestone34.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 1050664 - 1. Fix IsDormantNeeded() function. 2. Invoke mSource->stop at the suspend code path that will rewind the sampletable implicitly. r=cpearce
content/media/omx/MediaCodecReader.cpp
content/media/omx/MediaCodecReader.h
--- a/content/media/omx/MediaCodecReader.cpp
+++ b/content/media/omx/MediaCodecReader.cpp
@@ -125,17 +125,18 @@ MediaCodecReader::TrackInputCopier::Copy
   memcpy(aCodecBuffer->data(),
          (uint8_t*)aSourceBuffer->data() + aSourceBuffer->range_offset(),
          aSourceBuffer->range_length());
 
   return true;
 }
 
 MediaCodecReader::Track::Track()
-  : mDurationUs(INT64_C(0))
+  : mSourceIsStopped(true)
+  , mDurationUs(INT64_C(0))
   , mInputIndex(sInvalidInputIndex)
   , mInputEndOfStream(false)
   , mOutputEndOfStream(false)
   , mSeekTimeUs(sInvalidTimestampUs)
   , mFlushed(false)
   , mDiscontinuity(false)
   , mTaskQueue(nullptr)
 {
@@ -215,22 +216,32 @@ bool
 MediaCodecReader::IsWaitingMediaResources()
 {
   return mVideoTrack.mCodec != nullptr && !mVideoTrack.mCodec->allocated();
 }
 
 bool
 MediaCodecReader::IsDormantNeeded()
 {
-  return mVideoTrack.mCodec != nullptr;
+  return mVideoTrack.mSource != nullptr;
 }
 
 void
 MediaCodecReader::ReleaseMediaResources()
 {
+  // Stop the mSource because we are in the dormant state and the stop function
+  // will rewind the mSource to the beginning of the stream.
+  if (mVideoTrack.mSource != nullptr) {
+    mVideoTrack.mSource->stop();
+    mVideoTrack.mSourceIsStopped = true;
+  }
+  if (mAudioTrack.mSource != nullptr) {
+    mAudioTrack.mSource->stop();
+    mAudioTrack.mSourceIsStopped = true;
+  }
   ReleaseCriticalResources();
 }
 
 void
 MediaCodecReader::Shutdown()
 {
   ReleaseResources();
 }
@@ -831,25 +842,27 @@ MediaCodecReader::CreateMediaSources()
     NS_WARNING("OMX decoder could not find audio or video tracks");
     return false;
   }
 
   if (audioTrackIndex != invalidTrackIndex && mAudioTrack.mSource == nullptr) {
     sp<MediaSource> audioSource = mExtractor->getTrack(audioTrackIndex);
     if (audioSource != nullptr && audioSource->start() == OK) {
       mAudioTrack.mSource = audioSource;
+      mAudioTrack.mSourceIsStopped = false;
     }
     // Get one another track instance for audio offload playback.
     mAudioOffloadTrack.mSource = mExtractor->getTrack(audioTrackIndex);
   }
 
   if (videoTrackIndex != invalidTrackIndex && mVideoTrack.mSource == nullptr) {
     sp<MediaSource> videoSource = mExtractor->getTrack(videoTrackIndex);
     if (videoSource != nullptr && videoSource->start() == OK) {
       mVideoTrack.mSource = videoSource;
+      mVideoTrack.mSourceIsStopped = false;
     }
   }
 
   return
     (audioTrackIndex == invalidTrackIndex || mAudioTrack.mSource != nullptr) &&
     (videoTrackIndex == invalidTrackIndex || mVideoTrack.mSource != nullptr);
 }
 
@@ -1224,16 +1237,24 @@ MediaCodecReader::FillCodecInputData(Tra
   size_t index = 0;
   while (aTrack.mInputIndex.isValid() ||
          aTrack.mCodec->dequeueInputBuffer(&index) == OK) {
     if (!aTrack.mInputIndex.isValid()) {
       aTrack.mInputIndex = index;
     }
     MOZ_ASSERT(aTrack.mInputIndex.isValid(), "aElement.mInputIndex should be valid");
 
+    // Start the mSource before we read it.
+    if (aTrack.mSourceIsStopped) {
+      if (aTrack.mSource->start() == OK) {
+        aTrack.mSourceIsStopped = false;
+      } else {
+        return UNKNOWN_ERROR;
+      }
+    }
     MediaBuffer* source_buffer = nullptr;
     status_t status = OK;
     if (IsValidTimestampUs(aTrack.mSeekTimeUs)) {
       MediaSource::ReadOptions options;
       options.setSeekTo(aTrack.mSeekTimeUs);
       status = aTrack.mSource->read(&source_buffer, &options);
     } else {
       status = aTrack.mSource->read(&source_buffer);
@@ -1306,17 +1327,17 @@ MediaCodecReader::GetCodecOutputData(Tra
     if (!IsValidDurationUs(duration)) {
       return -EAGAIN;
     }
 
     status = aTrack.mCodec->dequeueOutputBuffer(&info.mIndex, &info.mOffset,
       &info.mSize, &info.mTimeUs, &info.mFlags, duration);
     // Check EOS first.
     if (status == ERROR_END_OF_STREAM ||
-        info.mFlags & MediaCodec::BUFFER_FLAG_EOS) {
+        (info.mFlags & MediaCodec::BUFFER_FLAG_EOS)) {
       aBuffer = info;
       aBuffer.mBuffer = aTrack.mOutputBuffers[info.mIndex];
       aTrack.mOutputEndOfStream = true;
       return ERROR_END_OF_STREAM;
     }
 
     if (status == OK) {
       if (!IsValidTimestampUs(aThreshold) || info.mTimeUs >= aThreshold) {
--- a/content/media/omx/MediaCodecReader.h
+++ b/content/media/omx/MediaCodecReader.h
@@ -95,16 +95,17 @@ protected:
   };
 
   struct Track
   {
     Track();
 
     // pipeline parameters
     android::sp<android::MediaSource> mSource;
+    bool mSourceIsStopped;
     android::sp<android::MediaCodecProxy> mCodec;
     android::Vector<android::sp<android::ABuffer> > mInputBuffers;
     android::Vector<android::sp<android::ABuffer> > mOutputBuffers;
 
     // pipeline copier
     nsAutoPtr<TrackInputCopier> mInputCopier;
 
     // media parameters