1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
16 MP4Interval() : start
{}, end
{} {}
17 MP4Interval(T aStart
, T aEnd
) : start(aStart
), end(aEnd
) {
18 MOZ_ASSERT(aStart
<= aEnd
);
20 T
Length() { return end
- start
; }
21 MP4Interval
Intersection(const MP4Interval
& aOther
) const {
22 T s
= start
> aOther
.start
? start
: aOther
.start
;
23 T e
= end
< aOther
.end
? end
: aOther
.end
;
27 return MP4Interval(s
, e
);
29 bool Contains(const MP4Interval
& aOther
) const {
30 return aOther
.start
>= start
&& aOther
.end
<= end
;
32 bool operator==(const MP4Interval
& aOther
) const {
33 return start
== aOther
.start
&& end
== aOther
.end
;
35 bool operator!=(const MP4Interval
& aOther
) const {
36 return !(*this == aOther
);
38 bool IsNull() const { return end
== start
; }
39 MP4Interval
Extents(const MP4Interval
& aOther
) const {
43 return MP4Interval(std::min(start
, aOther
.start
),
44 std::max(end
, aOther
.end
));
50 nsCString
ToString() {
51 return nsPrintfCString("[%s, %s]", start
.ToString().get(),
52 end
.ToString().get());
55 static void SemiNormalAppend(nsTArray
<MP4Interval
<T
>>& aIntervals
,
56 MP4Interval
<T
> aMP4Interval
) {
57 if (!aIntervals
.IsEmpty() &&
58 aIntervals
.LastElement().end
== aMP4Interval
.start
) {
59 aIntervals
.LastElement().end
= aMP4Interval
.end
;
61 aIntervals
.AppendElement(aMP4Interval
);
65 static void Normalize(const nsTArray
<MP4Interval
<T
>>& aIntervals
,
66 nsTArray
<MP4Interval
<T
>>* aNormalized
) {
67 if (!aNormalized
|| !aIntervals
.Length()) {
68 MOZ_ASSERT(aNormalized
);
71 MOZ_ASSERT(aNormalized
->IsEmpty());
73 nsTArray
<MP4Interval
<T
>> sorted
= aIntervals
.Clone();
74 sorted
.Sort(Compare());
76 MP4Interval
<T
> current
= sorted
[0];
77 for (size_t i
= 1; i
< sorted
.Length(); i
++) {
78 MOZ_ASSERT(sorted
[i
].start
<= sorted
[i
].end
);
79 if (current
.Contains(sorted
[i
])) {
82 if (current
.end
>= sorted
[i
].start
) {
83 current
.end
= sorted
[i
].end
;
85 aNormalized
->AppendElement(current
);
89 aNormalized
->AppendElement(current
);
92 static void Intersection(const nsTArray
<MP4Interval
<T
>>& a0
,
93 const nsTArray
<MP4Interval
<T
>>& a1
,
94 nsTArray
<MP4Interval
<T
>>* aIntersection
) {
95 MOZ_ASSERT(IsNormalized(a0
));
96 MOZ_ASSERT(IsNormalized(a1
));
99 while (i0
< a0
.Length() && i1
< a1
.Length()) {
100 MP4Interval i
= a0
[i0
].Intersection(a1
[i1
]);
102 aIntersection
->AppendElement(i
);
104 if (a0
[i0
].end
< a1
[i1
].end
) {
106 // Assert that the array is sorted
107 MOZ_ASSERT(i0
== a0
.Length() || a0
[i0
- 1].start
< a0
[i0
].start
);
110 // Assert that the array is sorted
111 MOZ_ASSERT(i1
== a1
.Length() || a1
[i1
- 1].start
< a1
[i1
].start
);
116 static bool IsNormalized(const nsTArray
<MP4Interval
<T
>>& aIntervals
) {
117 for (size_t i
= 1; i
< aIntervals
.Length(); i
++) {
118 if (aIntervals
[i
- 1].end
>= aIntervals
[i
].start
) {
126 bool Equals(const MP4Interval
<T
>& a0
, const MP4Interval
<T
>& a1
) const {
127 return a0
.start
== a1
.start
&& a0
.end
== a1
.end
;
130 bool LessThan(const MP4Interval
<T
>& a0
, const MP4Interval
<T
>& a1
) const {
131 return a0
.start
< a1
.start
;
135 } // namespace mozilla