Bug 1392498 - Move TimeIntervals to dom::TimeRanges conversion into TimeRanges class. r=jya
authorChris Pearce <cpearce@mozilla.com>
Mon, 21 Aug 2017 15:08:25 +1200
changeset 377191 ac74aef901edd88bc3839a05039e0f9ed644a4a7
parent 377190 e90afee2e1413638f2a865e1f4abca292eebf00e
child 377192 0cb8d97fe9261df38202ce9eacff788ad49683fa
push id94244
push userarchaeopteryx@coole-files.de
push dateMon, 28 Aug 2017 15:10:59 +0000
treeherdermozilla-inbound@40c5c8d062de [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjya
bugs1392498
milestone57.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 1392498 - Move TimeIntervals to dom::TimeRanges conversion into TimeRanges class. r=jya If TimeUnits.h includes mozilla/dom/TimeRanges.h, then the build ends up pulling in the Gecko DOM bindings, which pulls in a whole lot of JavaScript and DOM bindings code. That makes it trickier to import GeckoMedia into Servo, and makes Gecko's build slower, so move the code to convert TimeIntervals into dom::TimeRanges. Also remove an extraneous "virtual" and add "const" to some functions in TimeRanges. MozReview-Commit-ID: BLeehaf9gCE
dom/html/HTMLMediaElement.cpp
dom/html/HTMLVideoElement.cpp
dom/html/TimeRanges.cpp
dom/html/TimeRanges.h
dom/media/TimeUnits.h
dom/media/gtest/TestIntervalSet.cpp
dom/media/mediasource/SourceBuffer.cpp
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -2652,17 +2652,17 @@ HTMLMediaElement::SetCurrentTime(double 
  * Check if aValue is inside a range of aRanges, and if so sets aIsInRanges
  * to true and put the range index in aIntervalIndex. If aValue is not
  * inside a range, aIsInRanges is set to false, and aIntervalIndex
  * is set to the index of the range which ends immediately before aValue
  * (and can be -1 if aValue is before aRanges.Start(0)). Returns NS_OK
  * on success, and NS_ERROR_FAILURE on failure.
  */
 static nsresult
-IsInRanges(dom::TimeRanges& aRanges,
+IsInRanges(TimeRanges& aRanges,
            double aValue,
            bool& aIsInRanges,
            int32_t& aIntervalIndex)
 {
   aIsInRanges = false;
   uint32_t length;
   nsresult rv = aRanges.GetLength(&length);
   NS_ENSURE_SUCCESS(rv, rv);
@@ -2735,23 +2735,23 @@ HTMLMediaElement::Seek(double aTime,
   if (!mDecoder) {
     // mDecoder must always be set in order to reach this point.
     NS_ASSERTION(mDecoder, "SetCurrentTime failed: no decoder");
     promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
     return promise.forget();
   }
 
   // Clamp the seek target to inside the seekable ranges.
-  RefPtr<dom::TimeRanges> seekable = new dom::TimeRanges(ToSupports(OwnerDoc()));
   media::TimeIntervals seekableIntervals = mDecoder->GetSeekable();
   if (seekableIntervals.IsInvalid()) {
     aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); // This will reject the promise.
     return promise.forget();
   }
-  seekableIntervals.ToTimeRanges(seekable);
+  RefPtr<TimeRanges> seekable =
+    new TimeRanges(ToSupports(OwnerDoc()), seekableIntervals);
   uint32_t length = 0;
   seekable->GetLength(&length);
   if (!length) {
     promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
     return promise.forget();
   }
 
   // If the position we want to seek to is not in a seekable range, we seek
@@ -2860,20 +2860,19 @@ NS_IMETHODIMP HTMLMediaElement::GetDurat
 {
   *aDuration = Duration();
   return NS_OK;
 }
 
 already_AddRefed<TimeRanges>
 HTMLMediaElement::Seekable() const
 {
-  RefPtr<TimeRanges> ranges = new TimeRanges(ToSupports(OwnerDoc()));
-  if (mDecoder) {
-    mDecoder->GetSeekable().ToTimeRanges(ranges);
-  }
+  media::TimeIntervals seekable =
+    mDecoder ? mDecoder->GetSeekable() : media::TimeIntervals();
+  RefPtr<TimeRanges> ranges = new TimeRanges(ToSupports(OwnerDoc()), seekable);
   return ranges.forget();
 }
 
 NS_IMETHODIMP HTMLMediaElement::GetSeekable(nsIDOMTimeRanges** aSeekable)
 {
   RefPtr<TimeRanges> ranges = Seekable();
   ranges.forget(aSeekable);
   return NS_OK;
@@ -6544,23 +6543,19 @@ HTMLMediaElement::CopyInnerTo(Element* a
     dest->SetMediaInfo(mMediaInfo);
   }
   return rv;
 }
 
 already_AddRefed<TimeRanges>
 HTMLMediaElement::Buffered() const
 {
-  RefPtr<TimeRanges> ranges = new TimeRanges(ToSupports(OwnerDoc()));
-  if (mDecoder) {
-    media::TimeIntervals buffered = mDecoder->GetBuffered();
-    if (!buffered.IsInvalid()) {
-      buffered.ToTimeRanges(ranges);
-    }
-  }
+  media::TimeIntervals buffered =
+    mDecoder ? mDecoder->GetBuffered() : media::TimeIntervals();
+  RefPtr<TimeRanges> ranges = new TimeRanges(ToSupports(OwnerDoc()), buffered);
   return ranges.forget();
 }
 
 nsresult HTMLMediaElement::GetBuffered(nsIDOMTimeRanges** aBuffered)
 {
   RefPtr<TimeRanges> ranges = Buffered();
   ranges.forget(aBuffered);
   return NS_OK;
--- a/dom/html/HTMLVideoElement.cpp
+++ b/dom/html/HTMLVideoElement.cpp
@@ -25,16 +25,17 @@
 
 #include "FrameStatistics.h"
 #include "MediaError.h"
 #include "MediaDecoder.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/dom/WakeLock.h"
 #include "mozilla/dom/power/PowerManagerService.h"
 #include "mozilla/dom/Performance.h"
+#include "mozilla/dom/TimeRanges.h"
 #include "mozilla/dom/VideoPlaybackQuality.h"
 
 #include <algorithm>
 #include <limits>
 
 NS_IMPL_NS_NEW_HTML_ELEMENT(Video)
 
 namespace mozilla {
--- a/dom/html/TimeRanges.cpp
+++ b/dom/html/TimeRanges.cpp
@@ -2,16 +2,17 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * 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/. */
 
 #include "mozilla/dom/TimeRanges.h"
 #include "mozilla/dom/TimeRangesBinding.h"
 #include "mozilla/dom/HTMLMediaElement.h"
+#include "TimeUnits.h"
 #include "nsError.h"
 
 namespace mozilla {
 namespace dom {
 
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(TimeRanges, mParent)
 NS_IMPL_CYCLE_COLLECTING_ADDREF(TimeRanges)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(TimeRanges)
@@ -26,29 +27,58 @@ TimeRanges::TimeRanges()
 {
 }
 
 TimeRanges::TimeRanges(nsISupports* aParent)
   : mParent(aParent)
 {
 }
 
+TimeRanges::TimeRanges(nsISupports* aParent,
+                       const media::TimeIntervals& aTimeIntervals)
+  : TimeRanges(aParent)
+{
+  if (aTimeIntervals.IsInvalid()) {
+    return;
+  }
+  for (const media::TimeInterval& interval : aTimeIntervals) {
+    Add(interval.mStart.ToSeconds(), interval.mEnd.ToSeconds());
+  }
+}
+
+TimeRanges::TimeRanges(const media::TimeIntervals& aTimeIntervals)
+  : TimeRanges(nullptr, aTimeIntervals)
+{
+}
+
+media::TimeIntervals
+TimeRanges::ToTimeIntervals() const
+{
+  media::TimeIntervals t;
+  for (uint32_t i = 0; i < Length(); i++) {
+    ErrorResult rv;
+    t += media::TimeInterval(media::TimeUnit::FromSeconds(Start(i, rv)),
+                             media::TimeUnit::FromSeconds(End(i, rv)));
+  }
+  return t;
+}
+
 TimeRanges::~TimeRanges()
 {
 }
 
 NS_IMETHODIMP
 TimeRanges::GetLength(uint32_t* aLength)
 {
   *aLength = Length();
   return NS_OK;
 }
 
 double
-TimeRanges::Start(uint32_t aIndex, ErrorResult& aRv)
+TimeRanges::Start(uint32_t aIndex, ErrorResult& aRv) const
 {
   if (aIndex >= mRanges.Length()) {
     aRv = NS_ERROR_DOM_INDEX_SIZE_ERR;
     return 0;
   }
 
   return mRanges[aIndex].mStart;
 }
@@ -57,17 +87,17 @@ NS_IMETHODIMP
 TimeRanges::Start(uint32_t aIndex, double* aTime)
 {
   ErrorResult rv;
   *aTime = Start(aIndex, rv);
   return rv.StealNSResult();
 }
 
 double
-TimeRanges::End(uint32_t aIndex, ErrorResult& aRv)
+TimeRanges::End(uint32_t aIndex, ErrorResult& aRv) const
 {
   if (aIndex >= mRanges.Length()) {
     aRv = NS_ERROR_DOM_INDEX_SIZE_ERR;
     return 0;
   }
 
   return mRanges[aIndex].mEnd;
 }
--- a/dom/html/TimeRanges.h
+++ b/dom/html/TimeRanges.h
@@ -8,38 +8,42 @@
 #define mozilla_dom_TimeRanges_h_
 
 #include "nsCOMPtr.h"
 #include "nsIDOMTimeRanges.h"
 #include "nsISupports.h"
 #include "nsTArray.h"
 #include "nsWrapperCache.h"
 #include "mozilla/ErrorResult.h"
+#include "TimeUnits.h"
 
 namespace mozilla {
+
 namespace dom {
-
 class TimeRanges;
-
 } // namespace dom
 
 namespace dom {
 
 // Implements media TimeRanges:
 // http://www.whatwg.org/specs/web-apps/current-work/multipage/video.html#timeranges
 class TimeRanges final : public nsIDOMTimeRanges,
                          public nsWrapperCache
 {
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(TimeRanges)
   NS_DECL_NSIDOMTIMERANGES
 
   TimeRanges();
   explicit TimeRanges(nsISupports* aParent);
+  explicit TimeRanges(const media::TimeIntervals& aTimeIntervals);
+  TimeRanges(nsISupports* aParent, const media::TimeIntervals& aTimeIntervals);
+
+  media::TimeIntervals ToTimeIntervals() const;
 
   void Add(double aStart, double aEnd);
 
   // Returns the start time of the first range, or -1 if no ranges exist.
   double GetStartTime();
 
   // Returns the end time of the last range, or -1 if no ranges exist.
   double GetEndTime();
@@ -48,28 +52,29 @@ public:
   void Normalize(double aTolerance = 0.0);
 
   // Mutate this TimeRange to be the union of this and aOtherRanges.
   void Union(const TimeRanges* aOtherRanges, double aTolerance);
 
   // Mutate this TimeRange to be the intersection of this and aOtherRanges.
   void Intersection(const TimeRanges* aOtherRanges);
 
-  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
+  JSObject* WrapObject(JSContext* aCx,
+                       JS::Handle<JSObject*> aGivenProto) override;
 
   nsISupports* GetParentObject() const;
 
   uint32_t Length() const
   {
     return mRanges.Length();
   }
 
-  virtual double Start(uint32_t aIndex, ErrorResult& aRv);
+  double Start(uint32_t aIndex, ErrorResult& aRv) const;
 
-  virtual double End(uint32_t aIndex, ErrorResult& aRv);
+  double End(uint32_t aIndex, ErrorResult& aRv) const;
 
   // Shift all values by aOffset seconds.
   void Shift(double aOffset);
 
 private:
   ~TimeRanges();
 
   // Comparator which orders TimeRanges by start time. Used by Normalize().
--- a/dom/media/TimeUnits.h
+++ b/dom/media/TimeUnits.h
@@ -6,25 +6,24 @@
 
 #ifndef TIME_UNITS_H
 #define TIME_UNITS_H
 
 #include "Intervals.h"
 #include "mozilla/CheckedInt.h"
 #include "mozilla/FloatingPoint.h"
 #include "mozilla/Maybe.h"
-#include "mozilla/dom/TimeRanges.h"
 #include "mozilla/TimeStamp.h"
 
 namespace mozilla {
 namespace media {
 class TimeIntervals;
 } // namespace media
 } // namespace mozilla
-// CopyChooser specalization for nsTArray
+// CopyChooser specialization for nsTArray
 template<>
 struct nsTArray_CopyChooser<mozilla::media::TimeIntervals>
 {
   typedef nsTArray_CopyWithConstructors<mozilla::media::TimeIntervals> Type;
 };
 
 namespace mozilla {
 
@@ -236,42 +235,14 @@ public:
   }
   bool IsInvalid() const
   {
     return Length() == 1 && Start(0).ToMicroseconds() == INT64_MIN &&
       End(0).ToMicroseconds() == INT64_MIN;
   }
 
   TimeIntervals() = default;
-
-  // Make TimeIntervals interchangeable with dom::TimeRanges.
-  explicit TimeIntervals(dom::TimeRanges* aRanges)
-  {
-    for (uint32_t i = 0; i < aRanges->Length(); i++) {
-      ErrorResult rv;
-      *this +=
-        TimeInterval(TimeUnit::FromSeconds(aRanges->Start(i, rv)),
-                     TimeUnit::FromSeconds(aRanges->End(i, rv)));
-    }
-  }
-  TimeIntervals& operator = (dom::TimeRanges* aRanges)
-  {
-    *this = TimeIntervals(aRanges);
-    return *this;
-  }
-
-  static TimeIntervals FromTimeRanges(dom::TimeRanges* aRanges)
-  {
-    return TimeIntervals(aRanges);
-  }
-
-  void ToTimeRanges(dom::TimeRanges* aRanges) const
-  {
-    for (IndexType i = 0; i < Length(); i++) {
-      aRanges->Add(Start(i).ToSeconds(), End(i).ToSeconds());
-    }
-  }
 };
 
 } // namespace media
 } // namespace mozilla
 
 #endif // TIME_UNITS_H
--- a/dom/media/gtest/TestIntervalSet.cpp
+++ b/dom/media/gtest/TestIntervalSet.cpp
@@ -531,18 +531,17 @@ TEST(IntervalSet, TimeRangesSeconds)
 
   media::TimeIntervals i1;
   i1.Add(media::TimeInterval(media::TimeUnit::FromSeconds(16), media::TimeUnit::FromSeconds(27)));
   i1.Add(media::TimeInterval(media::TimeUnit::FromSeconds(7), media::TimeUnit::FromSeconds(15)));
   i1.Add(media::TimeInterval(media::TimeUnit::FromSeconds(53), media::TimeUnit::FromSeconds(57)));
   i1.Add(media::TimeInterval(media::TimeUnit::FromSeconds(45), media::TimeUnit::FromSeconds(50)));
 
   media::TimeIntervals i(i0 + i1);
-  RefPtr<dom::TimeRanges> tr = new dom::TimeRanges();
-  i.ToTimeRanges(tr);
+  RefPtr<dom::TimeRanges> tr = new dom::TimeRanges(i);
   EXPECT_EQ(tr->Length(), i.Length());
   for (dom::TimeRanges::index_type index = 0; index < tr->Length(); index++) {
     ErrorResult rv;
     EXPECT_EQ(tr->Start(index, rv), i[index].mStart.ToSeconds());
     EXPECT_EQ(tr->Start(index, rv), i.Start(index).ToSeconds());
     EXPECT_EQ(tr->End(index, rv), i[index].mEnd.ToSeconds());
     EXPECT_EQ(tr->End(index, rv), i.End(index).ToSeconds());
   }
@@ -567,32 +566,23 @@ TEST(IntervalSet, TimeRangesConversion)
   RefPtr<dom::TimeRanges> tr = new dom::TimeRanges();
   tr->Add(20, 25);
   tr->Add(40, 60);
   tr->Add(5, 10);
   tr->Add(16, 27);
   tr->Add(53, 57);
   tr->Add(45, 50);
 
-  // explicit copy constructor
-  media::TimeIntervals i1(tr);
+  // explicit copy constructor and ToTimeIntervals.
+  media::TimeIntervals i1(tr->ToTimeIntervals());
   CheckTimeRanges(tr, i1);
 
-  // static FromTimeRanges
-  media::TimeIntervals i2 = media::TimeIntervals::FromTimeRanges(tr);
-  CheckTimeRanges(tr, i2);
-
-  media::TimeIntervals i3;
-  // operator=(TimeRanges*)
-  i3 = tr;
-  CheckTimeRanges(tr, i3);
-
-  // operator= test
-  i1 = tr.get();
-  CheckTimeRanges(tr, i1);
+  // ctor(const TimeIntervals&)
+  RefPtr<dom::TimeRanges> tr2 = new dom::TimeRanges(tr->ToTimeIntervals());
+  CheckTimeRanges(tr2, i1);
 }
 
 TEST(IntervalSet, TimeRangesMicroseconds)
 {
   media::TimeIntervals i0;
 
   i0 += media::TimeInterval(media::TimeUnit::FromMicroseconds(20), media::TimeUnit::FromMicroseconds(25));
   i0 += media::TimeInterval(media::TimeUnit::FromMicroseconds(40), media::TimeUnit::FromMicroseconds(60));
@@ -600,18 +590,17 @@ TEST(IntervalSet, TimeRangesMicroseconds
 
   media::TimeIntervals i1;
   i1.Add(media::TimeInterval(media::TimeUnit::FromMicroseconds(16), media::TimeUnit::FromMicroseconds(27)));
   i1.Add(media::TimeInterval(media::TimeUnit::FromMicroseconds(7), media::TimeUnit::FromMicroseconds(15)));
   i1.Add(media::TimeInterval(media::TimeUnit::FromMicroseconds(53), media::TimeUnit::FromMicroseconds(57)));
   i1.Add(media::TimeInterval(media::TimeUnit::FromMicroseconds(45), media::TimeUnit::FromMicroseconds(50)));
 
   media::TimeIntervals i(i0 + i1);
-  RefPtr<dom::TimeRanges> tr = new dom::TimeRanges();
-  i.ToTimeRanges(tr);
+  RefPtr<dom::TimeRanges> tr = new dom::TimeRanges(i);
   EXPECT_EQ(tr->Length(), i.Length());
   for (dom::TimeRanges::index_type index = 0; index < tr->Length(); index++) {
     ErrorResult rv;
     EXPECT_EQ(tr->Start(index, rv), i[index].mStart.ToSeconds());
     EXPECT_EQ(tr->Start(index, rv), i.Start(index).ToSeconds());
     EXPECT_EQ(tr->End(index, rv), i[index].mEnd.ToSeconds());
     EXPECT_EQ(tr->End(index, rv), i.End(index).ToSeconds());
   }
@@ -625,19 +614,18 @@ TEST(IntervalSet, TimeRangesMicroseconds
     EXPECT_EQ(tr->End(index, rv), i[index].mEnd.ToSeconds());
     EXPECT_EQ(tr->End(index, rv), i.End(index).ToSeconds());
   }
 
   // Check infinity values aren't lost in the conversion.
   tr = new dom::TimeRanges();
   tr->Add(0, 30);
   tr->Add(50, std::numeric_limits<double>::infinity());
-  media::TimeIntervals i_oo{media::TimeIntervals::FromTimeRanges(tr)};
-  RefPtr<dom::TimeRanges> tr2 = new dom::TimeRanges();
-  i_oo.ToTimeRanges(tr2);
+  media::TimeIntervals i_oo = tr->ToTimeIntervals();
+  RefPtr<dom::TimeRanges> tr2 = new dom::TimeRanges(i_oo);
   EXPECT_EQ(tr->Length(), tr2->Length());
   for (dom::TimeRanges::index_type index = 0; index < tr->Length(); index++) {
     ErrorResult rv;
     EXPECT_EQ(tr->Start(index, rv), tr2->Start(index, rv));
     EXPECT_EQ(tr->End(index, rv), tr2->End(index, rv));
   }
 }
 
--- a/dom/media/mediasource/SourceBuffer.cpp
+++ b/dom/media/mediasource/SourceBuffer.cpp
@@ -109,24 +109,23 @@ SourceBuffer::GetBuffered(ErrorResult& a
   if (!IsAttached()) {
     aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
     return nullptr;
   }
   bool rangeChanged = true;
   media::TimeIntervals intersection = mTrackBuffersManager->Buffered();
   MSE_DEBUGV("intersection=%s", DumpTimeRanges(intersection).get());
   if (mBuffered) {
-    media::TimeIntervals currentValue(mBuffered);
+    media::TimeIntervals currentValue(mBuffered->ToTimeIntervals());
     rangeChanged = (intersection != currentValue);
     MSE_DEBUGV("currentValue=%s", DumpTimeRanges(currentValue).get());
   }
   // 5. If intersection ranges does not contain the exact same range information as the current value of this attribute, then update the current value of this attribute to intersection ranges.
   if (rangeChanged) {
-    mBuffered = new TimeRanges(ToSupports(this));
-    intersection.ToTimeRanges(mBuffered);
+    mBuffered = new TimeRanges(ToSupports(this), intersection);
   }
   // 6. Return the current value of this attribute.
   return mBuffered;
 }
 
 media::TimeIntervals
 SourceBuffer::GetTimeIntervals()
 {