Bug 1190472 - part 1 - improve MediaRawDataQueue's reference-counting behavior; r=kinetik
authorNathan Froyd <froydnj@mozilla.com>
Thu, 01 Oct 2015 19:02:18 -0400
changeset 268551 e0d5a28ba9d4ac6b4315dc9bf541362f12dcf226
parent 268550 07d5679826c99dcb8f4e1fe8d0172db507488755
child 268552 3c4316e8d12a65200a4dde956cb67a51e87097ce
push id66874
push usernfroyd@mozilla.com
push dateTue, 20 Oct 2015 17:36:25 +0000
treeherdermozilla-inbound@0e80a5538a67 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskinetik
bugs1190472
milestone44.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 1190472 - part 1 - improve MediaRawDataQueue's reference-counting behavior; r=kinetik Sometimes when we push onto the queue, we don't need to hold a reference afterwards. In that case, we can pass the reference in and avoid unnecessary reference counting.
dom/media/webm/WebMDemuxer.cpp
dom/media/webm/WebMDemuxer.h
--- a/dom/media/webm/WebMDemuxer.cpp
+++ b/dom/media/webm/WebMDemuxer.cpp
@@ -814,19 +814,18 @@ WebMTrackDemuxer::Seek(media::TimeUnit a
 
   media::TimeUnit seekTime = aTime;
   mSamples.Reset();
   mParent->SeekInternal(aTime);
   mParent->GetNextPacket(mType, &mSamples);
 
   // Check what time we actually seeked to.
   if (mSamples.GetSize() > 0) {
-    RefPtr<MediaRawData> sample(mSamples.PopFront());
+    const RefPtr<MediaRawData>& sample = mSamples.First();
     seekTime = media::TimeUnit::FromMicroseconds(sample->mTime);
-    mSamples.PushFront(sample);
   }
   SetNextKeyFrameTime();
 
   return SeekPromise::CreateAndResolve(seekTime, __func__);
 }
 
 RefPtr<MediaRawData>
 WebMTrackDemuxer::NextSample()
@@ -871,43 +870,43 @@ WebMTrackDemuxer::SetNextKeyFrameTime()
     return;
   }
 
   int64_t frameTime = -1;
 
   mNextKeyframeTime.reset();
 
   MediaRawDataQueue skipSamplesQueue;
-  RefPtr<MediaRawData> sample;
   bool foundKeyframe = false;
   while (!foundKeyframe && mSamples.GetSize()) {
-    sample = mSamples.PopFront();
+    RefPtr<MediaRawData> sample = mSamples.PopFront();
     if (sample->mKeyframe) {
       frameTime = sample->mTime;
       foundKeyframe = true;
     }
-    skipSamplesQueue.Push(sample);
+    skipSamplesQueue.Push(sample.forget());
   }
   Maybe<int64_t> startTime;
   if (skipSamplesQueue.GetSize()) {
-    sample = skipSamplesQueue.PopFront();
+    const RefPtr<MediaRawData>& sample = skipSamplesQueue.First();
     startTime.emplace(sample->mTimecode);
-    skipSamplesQueue.PushFront(sample);
   }
   // Demux and buffer frames until we find a keyframe.
+  RefPtr<MediaRawData> sample;
   while (!foundKeyframe && (sample = NextSample())) {
     if (sample->mKeyframe) {
       frameTime = sample->mTime;
       foundKeyframe = true;
     }
-    skipSamplesQueue.Push(sample);
+    int64_t sampleTimecode = sample->mTimecode;
+    skipSamplesQueue.Push(sample.forget());
     if (!startTime) {
-      startTime.emplace(sample->mTimecode);
+      startTime.emplace(sampleTimecode);
     } else if (!foundKeyframe &&
-               sample->mTimecode > startTime.ref() + MAX_LOOK_AHEAD) {
+               sampleTimecode > startTime.ref() + MAX_LOOK_AHEAD) {
       WEBM_DEBUG("Couldn't find keyframe in a reasonable time, aborting");
       break;
     }
   }
   // We may have demuxed more than intended, so ensure that all frames are kept
   // in the right order.
   mSamples.PushFront(skipSamplesQueue);
 
@@ -967,17 +966,17 @@ WebMTrackDemuxer::SkipToNextRandomAccess
   RefPtr<MediaRawData> sample;
 
   WEBM_DEBUG("TimeThreshold: %f", aTimeThreshold.ToSeconds());
   while (!found && (sample = NextSample())) {
     parsed++;
     if (sample->mKeyframe && sample->mTime >= aTimeThreshold.ToMicroseconds()) {
       found = true;
       mSamples.Reset();
-      mSamples.PushFront(sample);
+      mSamples.PushFront(sample.forget());
     }
   }
   SetNextKeyFrameTime();
   if (found) {
     WEBM_DEBUG("next sample: %f (parsed: %d)",
                media::TimeUnit::FromMicroseconds(sample->mTime).ToSeconds(),
                parsed);
     return SkipAccessPointPromise::CreateAndResolve(parsed, __func__);
--- a/dom/media/webm/WebMDemuxer.h
+++ b/dom/media/webm/WebMDemuxer.h
@@ -4,16 +4,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 #if !defined(WebMDemuxer_h_)
 #define WebMDemuxer_h_
 
 #include "nsTArray.h"
 #include "MediaDataDemuxer.h"
 #include "NesteggPacketHolder.h"
+#include "mozilla/Move.h"
 
 typedef struct nestegg nestegg;
 
 namespace mozilla {
 
 class WebMBufferedState;
 
 // Queue for holding MediaRawData samples
@@ -22,24 +23,32 @@ class MediaRawDataQueue {
   uint32_t GetSize() {
     return mQueue.size();
   }
 
   void Push(MediaRawData* aItem) {
     mQueue.push_back(aItem);
   }
 
+  void Push(already_AddRefed<MediaRawData>&& aItem) {
+    mQueue.push_back(Move(aItem));
+  }
+
   void Push(const MediaRawDataQueue& aOther) {
     mQueue.insert(mQueue.end(), aOther.mQueue.begin(), aOther.mQueue.end());
   }
 
   void PushFront(MediaRawData* aItem) {
     mQueue.push_front(aItem);
   }
 
+  void PushFront(already_AddRefed<MediaRawData>&& aItem) {
+    mQueue.push_front(Move(aItem));
+  }
+
   void PushFront(const MediaRawDataQueue& aOther) {
     mQueue.insert(mQueue.begin(), aOther.mQueue.begin(), aOther.mQueue.end());
   }
 
   already_AddRefed<MediaRawData> PopFront() {
     RefPtr<MediaRawData> result = mQueue.front().forget();
     mQueue.pop_front();
     return result.forget();