Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(554)

Side by Side Diff: Source/WTF/wtf/MediaTime.cpp

Issue 14238015: Move Source/WTF/wtf to Source/wtf (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 2012 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14 * its contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include "config.h"
30 #include "MediaTime.h"
31
32 #include <algorithm>
33 #include <wtf/CheckedArithmetic.h>
34 #include <wtf/MathExtras.h>
35
36 using namespace std;
37
38 namespace WTF {
39
40 static int32_t greatestCommonDivisor(int32_t a, int32_t b)
41 {
42 // Euclid's Algorithm
43 int32_t temp = 0;
44 while (b) {
45 temp = b;
46 b = a % b;
47 a = temp;
48 }
49 return a;
50 }
51
52 static int32_t leastCommonMultiple(int32_t a, int32_t b, int32_t &result)
53 {
54 return safeMultiply(a, b / greatestCommonDivisor(a, b), result);
55 }
56
57 const int32_t MediaTime::MaximumTimeScale = 0x7fffffffL;
58
59 MediaTime::MediaTime()
60 : m_timeValue(0)
61 , m_timeScale(DefaultTimeScale)
62 , m_timeFlags(Valid)
63 {
64 }
65
66 MediaTime::MediaTime(int64_t value, int32_t scale, uint32_t flags)
67 : m_timeValue(value)
68 , m_timeScale(scale)
69 , m_timeFlags(flags)
70 {
71 }
72
73 MediaTime::~MediaTime()
74 {
75 }
76
77 MediaTime::MediaTime(const MediaTime& rhs)
78 {
79 *this = rhs;
80 }
81
82 MediaTime MediaTime::createWithFloat(float floatTime, int32_t timeScale)
83 {
84 if (floatTime != floatTime)
85 return invalidTime();
86 if (std::isinf(floatTime))
87 return std::signbit(floatTime) ? negativeInfiniteTime() : positiveInfini teTime();
88 if (floatTime > numeric_limits<int64_t>::max())
89 return positiveInfiniteTime();
90 if (floatTime < numeric_limits<int64_t>::min())
91 return negativeInfiniteTime();
92
93 while (floatTime * timeScale > numeric_limits<int64_t>::max())
94 timeScale /= 2;
95 return MediaTime(static_cast<int64_t>(floatTime * timeScale), timeScale, Val id);
96 }
97
98 MediaTime MediaTime::createWithDouble(double doubleTime, int32_t timeScale)
99 {
100 if (doubleTime != doubleTime)
101 return invalidTime();
102 if (std::isinf(doubleTime))
103 return std::signbit(doubleTime) ? negativeInfiniteTime() : positiveInfin iteTime();
104 if (doubleTime > numeric_limits<int64_t>::max())
105 return positiveInfiniteTime();
106 if (doubleTime < numeric_limits<int64_t>::min())
107 return negativeInfiniteTime();
108
109 while (doubleTime * timeScale > numeric_limits<int64_t>::max())
110 timeScale /= 2;
111 return MediaTime(static_cast<int64_t>(doubleTime * timeScale), timeScale, Va lid);
112 }
113
114 float MediaTime::toFloat() const
115 {
116 if (isInvalid() || isIndefinite())
117 return std::numeric_limits<float>::quiet_NaN();
118 if (isPositiveInfinite())
119 return std::numeric_limits<float>::infinity();
120 if (isNegativeInfinite())
121 return -std::numeric_limits<float>::infinity();
122 return static_cast<float>(m_timeValue) / m_timeScale;
123 }
124
125 double MediaTime::toDouble() const
126 {
127 if (isInvalid() || isIndefinite())
128 return std::numeric_limits<double>::quiet_NaN();
129 if (isPositiveInfinite())
130 return std::numeric_limits<double>::infinity();
131 if (isNegativeInfinite())
132 return -std::numeric_limits<double>::infinity();
133 return static_cast<double>(m_timeValue) / m_timeScale;
134 }
135
136 MediaTime& MediaTime::operator=(const MediaTime& rhs)
137 {
138 m_timeValue = rhs.m_timeValue;
139 m_timeScale = rhs.m_timeScale;
140 m_timeFlags = rhs.m_timeFlags;
141 return *this;
142 }
143
144 MediaTime MediaTime::operator+(const MediaTime& rhs) const
145 {
146 if (rhs.isInvalid() || isInvalid())
147 return invalidTime();
148
149 if (rhs.isIndefinite() || isIndefinite())
150 return indefiniteTime();
151
152 if (isPositiveInfinite()) {
153 if (rhs.isNegativeInfinite())
154 return invalidTime();
155 return positiveInfiniteTime();
156 }
157
158 if (isNegativeInfinite()) {
159 if (rhs.isPositiveInfinite())
160 return invalidTime();
161 return negativeInfiniteTime();
162 }
163
164 int32_t commonTimeScale;
165 if (!leastCommonMultiple(this->m_timeScale, rhs.m_timeScale, commonTimeScale ) || commonTimeScale > MaximumTimeScale)
166 commonTimeScale = MaximumTimeScale;
167 MediaTime a = *this;
168 MediaTime b = rhs;
169 a.setTimeScale(commonTimeScale);
170 b.setTimeScale(commonTimeScale);
171 while (!safeAdd(a.m_timeValue, b.m_timeValue, a.m_timeValue)) {
172 if (commonTimeScale == 1)
173 return a.m_timeValue > 0 ? positiveInfiniteTime() : negativeInfinite Time();
174 commonTimeScale /= 2;
175 a.setTimeScale(commonTimeScale);
176 b.setTimeScale(commonTimeScale);
177 }
178 return a;
179 }
180
181 MediaTime MediaTime::operator-(const MediaTime& rhs) const
182 {
183 if (rhs.isInvalid() || isInvalid())
184 return invalidTime();
185
186 if (rhs.isIndefinite() || isIndefinite())
187 return indefiniteTime();
188
189 if (isPositiveInfinite()) {
190 if (rhs.isPositiveInfinite())
191 return invalidTime();
192 return positiveInfiniteTime();
193 }
194
195 if (isNegativeInfinite()) {
196 if (rhs.isNegativeInfinite())
197 return invalidTime();
198 return negativeInfiniteTime();
199 }
200
201 int32_t commonTimeScale;
202 if (!leastCommonMultiple(this->m_timeScale, rhs.m_timeScale, commonTimeScale ) || commonTimeScale > MaximumTimeScale)
203 commonTimeScale = MaximumTimeScale;
204 MediaTime a = *this;
205 MediaTime b = rhs;
206 a.setTimeScale(commonTimeScale);
207 b.setTimeScale(commonTimeScale);
208 while (!safeSub(a.m_timeValue, b.m_timeValue, a.m_timeValue)) {
209 if (commonTimeScale == 1)
210 return a.m_timeValue > 0 ? positiveInfiniteTime() : negativeInfinite Time();
211 commonTimeScale /= 2;
212 a.setTimeScale(commonTimeScale);
213 b.setTimeScale(commonTimeScale);
214 }
215 return a;
216 }
217
218 bool MediaTime::operator<(const MediaTime& rhs) const
219 {
220 return compare(rhs) == LessThan;
221 }
222
223 bool MediaTime::operator>(const MediaTime& rhs) const
224 {
225 return compare(rhs) == GreaterThan;
226 }
227
228 bool MediaTime::operator==(const MediaTime& rhs) const
229 {
230 return compare(rhs) == EqualTo;
231 }
232
233 bool MediaTime::operator>=(const MediaTime& rhs) const
234 {
235 return compare(rhs) >= EqualTo;
236 }
237
238 bool MediaTime::operator<=(const MediaTime& rhs) const
239 {
240 return compare(rhs) <= EqualTo;
241 }
242
243 MediaTime::ComparisonFlags MediaTime::compare(const MediaTime& rhs) const
244 {
245 if ((isPositiveInfinite() && rhs.isPositiveInfinite())
246 || (isNegativeInfinite() && rhs.isNegativeInfinite())
247 || (isInvalid() && rhs.isInvalid())
248 || (isIndefinite() && rhs.isIndefinite()))
249 return EqualTo;
250
251 if (isInvalid())
252 return GreaterThan;
253
254 if (rhs.isInvalid())
255 return LessThan;
256
257 if (rhs.isNegativeInfinite() || isPositiveInfinite())
258 return GreaterThan;
259
260 if (rhs.isPositiveInfinite() || isNegativeInfinite())
261 return LessThan;
262
263 if (isIndefinite())
264 return GreaterThan;
265
266 if (rhs.isIndefinite())
267 return LessThan;
268
269 int64_t rhsWhole = rhs.m_timeValue / rhs.m_timeScale;
270 int64_t lhsWhole = m_timeValue / m_timeScale;
271 if (lhsWhole > rhsWhole)
272 return GreaterThan;
273 if (lhsWhole < rhsWhole)
274 return LessThan;
275
276 int64_t rhsRemain = rhs.m_timeValue % rhs.m_timeScale;
277 int64_t lhsRemain = m_timeValue % m_timeScale;
278 int64_t lhsFactor = lhsRemain * rhs.m_timeScale;
279 int64_t rhsFactor = rhsRemain * m_timeScale;
280
281 if (lhsFactor == rhsFactor)
282 return EqualTo;
283 return lhsFactor > rhsFactor ? GreaterThan : LessThan;
284 }
285
286 const MediaTime& MediaTime::zeroTime()
287 {
288 static const MediaTime* time = new MediaTime(0, 1, Valid);
289 return *time;
290 }
291
292 const MediaTime& MediaTime::invalidTime()
293 {
294 static const MediaTime* time = new MediaTime(-1, 1, 0);
295 return *time;
296 }
297
298 const MediaTime& MediaTime::positiveInfiniteTime()
299 {
300 static const MediaTime* time = new MediaTime(0, 1, PositiveInfinite | Valid) ;
301 return *time;
302 }
303
304 const MediaTime& MediaTime::negativeInfiniteTime()
305 {
306 static const MediaTime* time = new MediaTime(-1, 1, NegativeInfinite | Valid );
307 return *time;
308 }
309
310 const MediaTime& MediaTime::indefiniteTime()
311 {
312 static const MediaTime* time = new MediaTime(0, 1, Indefinite | Valid);
313 return *time;
314 }
315
316 void MediaTime::setTimeScale(int32_t timeScale)
317 {
318 if (timeScale == m_timeScale)
319 return;
320 timeScale = std::min(MaximumTimeScale, timeScale);
321 int64_t wholePart = m_timeValue / m_timeScale;
322
323 // If setting the time scale will cause an overflow, divide the
324 // timescale by two until the number will fit, and round the
325 // result.
326 int64_t newWholePart;
327 while (!safeMultiply(wholePart, timeScale, newWholePart))
328 timeScale /= 2;
329
330 int64_t remainder = m_timeValue % m_timeScale;
331 m_timeValue = newWholePart + (remainder * timeScale) / m_timeScale;
332 m_timeScale = timeScale;
333 }
334
335 static int32_t signum(int64_t val)
336 {
337 return (0 < val) - (val < 0);
338 }
339
340 MediaTime abs(const MediaTime& rhs)
341 {
342 if (rhs.isInvalid())
343 return MediaTime::invalidTime();
344 if (rhs.isNegativeInfinite() || rhs.isPositiveInfinite())
345 return MediaTime::positiveInfiniteTime();
346 MediaTime val = rhs;
347 val.m_timeValue *= signum(rhs.m_timeScale) * signum(rhs.m_timeValue);
348 return val;
349 }
350
351 }
352
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698