Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Toggle main menu visibility
Loading...
Searching...
No Matches
qmediatimerange.cpp
Go to the documentation of this file.
1
// Copyright (C) 2016 The Qt Company Ltd.
2
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4
#
include
<
QtCore
/
qdebug
.
h
>
5
6
#
include
"qmediatimerange.h"
7
8
QT_BEGIN_NAMESPACE
9
10
/*!
11
\class QMediaTimeRange::Interval
12
\brief The QMediaTimeRange::Interval class represents a time interval with
13
integer precision.
14
\inmodule QtMultimedia
15
16
\ingroup multimedia
17
\ingroup multimedia_core
18
19
An interval is specified by an inclusive start() and end() time. These
20
must be set in the constructor, as this is an immutable class. The
21
specific units of time represented by the class have not been defined - it
22
is suitable for any times which can be represented by a signed 64 bit
23
integer.
24
25
The isNormal() method determines if a time interval is normal (a normal
26
time interval has start() <= end()). A normal interval can be received
27
from an abnormal interval by calling the normalized() method.
28
29
The contains() method determines if a specified time lies within the time
30
interval.
31
32
The translated() method returns a time interval which has been translated
33
forwards or backwards through time by a specified offset.
34
35
\sa QMediaTimeRange
36
*/
37
38
/*!
39
\fn QMediaTimeRange::Interval::Interval(qint64 start, qint64 end)
40
41
Constructs an interval with the specified \a start and \a end times.
42
*/
43
44
/*!
45
\fn QMediaTimeRange::Interval::start() const
46
47
Returns the start time of the interval.
48
49
\sa end()
50
*/
51
52
/*!
53
\fn QMediaTimeRange::Interval::end() const
54
55
Returns the end time of the interval.
56
57
\sa start()
58
*/
59
60
/*!
61
\fn QMediaTimeRange::Interval::contains(qint64 time) const
62
63
Returns true if the time interval contains the specified \a time.
64
That is, start() <= time <= end().
65
*/
66
67
/*!
68
\fn QMediaTimeRange::Interval::isNormal() const
69
70
Returns true if this time interval is normal.
71
A normal time interval has start() <= end().
72
73
\sa normalized()
74
*/
75
76
/*!
77
\fn QMediaTimeRange::Interval::normalized() const
78
79
Returns a normalized version of this interval.
80
81
If the start() time of the interval is greater than the end() time,
82
then the returned interval has the start and end times swapped.
83
*/
84
85
/*!
86
\fn QMediaTimeRange::Interval::translated(qint64 offset) const
87
88
Returns a copy of this time interval, translated by a value of \a offset.
89
An interval can be moved forward through time with a positive offset, or backward
90
through time with a negative offset.
91
*/
92
93
/*!
94
\fn bool QMediaTimeRange::Interval::operator==(QMediaTimeRange::Interval lhs, QMediaTimeRange::Interval rhs)
95
96
Returns true if \a lhs is exactly equal to \a rhs.
97
*/
98
99
/*!
100
\fn bool QMediaTimeRange::Interval::operator!=(QMediaTimeRange::Interval lhs, QMediaTimeRange::Interval rhs)
101
102
Returns true if \a lhs is not exactly equal to \a rhs.
103
*/
104
105
class
QMediaTimeRangePrivate :
public
QSharedData
106
{
107
public
:
108
QMediaTimeRangePrivate() =
default
;
109
QMediaTimeRangePrivate(
const
QMediaTimeRange::Interval &interval);
110
111
QList<QMediaTimeRange::Interval> intervals;
112
113
void
addInterval(
const
QMediaTimeRange::Interval &interval);
114
void
removeInterval(
const
QMediaTimeRange::Interval &interval);
115
};
116
117
QT_DEFINE_QESDP_SPECIALIZATION_DTOR
(
QMediaTimeRangePrivate
);
118
119
QMediaTimeRangePrivate::QMediaTimeRangePrivate(
const
QMediaTimeRange::Interval &interval)
120
{
121
if
(interval.isNormal())
122
intervals << interval;
123
}
124
125
void
QMediaTimeRangePrivate::addInterval(
const
QMediaTimeRange::Interval &interval)
126
{
127
// Handle normalized intervals only
128
if
(!interval.isNormal())
129
return
;
130
131
// Find a place to insert the interval
132
int
i;
133
for
(i = 0; i < intervals.size(); i++) {
134
// Insert before this element
135
if
(interval.s < intervals[i].s) {
136
intervals.insert(i, interval);
137
break
;
138
}
139
}
140
141
// Interval needs to be added to the end of the list
142
if
(i == intervals.size())
143
intervals.append(interval);
144
145
// Do we need to correct the element before us?
146
if
(i > 0 && intervals[i - 1].e >= interval.s - 1)
147
i--;
148
149
// Merge trailing ranges
150
while
(i < intervals.size() - 1
151
&& intervals[i].e >= intervals[i + 1].s - 1) {
152
intervals[i].e = qMax(intervals[i].e, intervals[i + 1].e);
153
intervals.removeAt(i + 1);
154
}
155
}
156
157
void
QMediaTimeRangePrivate::removeInterval(
const
QMediaTimeRange::Interval &interval)
158
{
159
// Handle normalized intervals only
160
if
(!interval.isNormal())
161
return
;
162
163
for
(
int
i = 0; i < intervals.size(); i++) {
164
const
QMediaTimeRange::Interval r = intervals.at(i);
165
166
if
(r.e < interval.s) {
167
// Before the removal interval
168
continue
;
169
}
else
if
(interval.e < r.s) {
170
// After the removal interval - stop here
171
break
;
172
}
else
if
(r.s < interval.s && interval.e < r.e) {
173
// Split case - a single range has a chunk removed
174
intervals[i].e = interval.s -1;
175
addInterval(QMediaTimeRange::Interval(interval.e + 1, r.e));
176
break
;
177
}
else
if
(r.s < interval.s) {
178
// Trimming Tail Case
179
intervals[i].e = interval.s - 1;
180
}
else
if
(interval.e < r.e) {
181
// Trimming Head Case - we can stop after this
182
intervals[i].s = interval.e + 1;
183
break
;
184
}
else
{
185
// Complete coverage case
186
intervals.removeAt(i);
187
--i;
188
}
189
}
190
}
191
192
/*!
193
\class QMediaTimeRange
194
\brief The QMediaTimeRange class represents a set of zero or more disjoint
195
time intervals.
196
\ingroup multimedia
197
\inmodule QtMultimedia
198
199
\reentrant
200
201
The earliestTime(), latestTime(), intervals() and isEmpty()
202
methods are used to get information about the current time range.
203
204
The addInterval(), removeInterval() and clear() methods are used to modify
205
the current time range.
206
207
When adding or removing intervals from the time range, existing intervals
208
within the range may be expanded, trimmed, deleted, merged or split to ensure
209
that all intervals within the time range remain distinct and disjoint. As a
210
consequence, all intervals added or removed from a time range must be
211
\l{QMediaTimeRange::Interval::isNormal()}{normal}.
212
213
\sa QMediaTimeRange::Interval
214
*/
215
216
/*!
217
Constructs an empty time range.
218
*/
219
QMediaTimeRange::QMediaTimeRange()
220
: d(
new
QMediaTimeRangePrivate)
221
{
222
223
}
224
225
/*!
226
Constructs a time range that contains an initial interval from
227
\a start to \a end inclusive.
228
229
If the interval is not \l{QMediaTimeRange::Interval::isNormal()}{normal},
230
the resulting time range will be empty.
231
232
\sa addInterval()
233
*/
234
QMediaTimeRange::QMediaTimeRange(qint64 start, qint64 end)
235
: QMediaTimeRange(Interval(start, end))
236
{
237
}
238
239
/*!
240
Constructs a time range that contains an initial interval, \a interval.
241
242
If \a interval is not \l{QMediaTimeRange::Interval::isNormal()}{normal},
243
the resulting time range will be empty.
244
245
\sa addInterval()
246
*/
247
QMediaTimeRange::QMediaTimeRange(
const
QMediaTimeRange::Interval &interval)
248
: d(
new
QMediaTimeRangePrivate(interval))
249
{
250
}
251
252
/*!
253
Constructs a time range by copying another time \a range.
254
*/
255
QMediaTimeRange::QMediaTimeRange(
const
QMediaTimeRange &range)
noexcept
=
default
;
256
257
/*! \fn QMediaTimeRange::QMediaTimeRange(QMediaTimeRange &&other)
258
259
Constructs a time range by moving from \a other.
260
*/
261
262
/*!
263
\fn void QMediaTimeRange::swap(QMediaTimeRange &other) noexcept
264
265
Swaps the current instance with the \a other.
266
*/
267
268
/*!
269
\fn QMediaTimeRange::~QMediaTimeRange()
270
271
Destructor.
272
*/
273
QMediaTimeRange::~QMediaTimeRange() =
default
;
274
275
/*!
276
Takes a copy of the \a other time range and returns itself.
277
*/
278
QMediaTimeRange &QMediaTimeRange::operator=(
const
QMediaTimeRange &other)
noexcept
=
default
;
279
280
/*!
281
\fn QMediaTimeRange &QMediaTimeRange::operator=(QMediaTimeRange &&other)
282
283
Moves \a other into this time range.
284
*/
285
286
/*!
287
Sets the time range to a single continuous interval, \a interval.
288
*/
289
QMediaTimeRange &QMediaTimeRange::operator=(
const
QMediaTimeRange::Interval &interval)
290
{
291
d =
new
QMediaTimeRangePrivate(interval);
292
return
*
this
;
293
}
294
295
/*!
296
Returns the earliest time within the time range.
297
298
For empty time ranges, this value is equal to zero.
299
300
\sa latestTime()
301
*/
302
qint64 QMediaTimeRange::earliestTime()
const
303
{
304
if
(!d->intervals.isEmpty())
305
return
d->intervals[0].start();
306
307
return
0;
308
}
309
310
/*!
311
Returns the latest time within the time range.
312
313
For empty time ranges, this value is equal to zero.
314
315
\sa earliestTime()
316
*/
317
qint64 QMediaTimeRange::latestTime()
const
318
{
319
if
(!d->intervals.isEmpty())
320
return
d->intervals[d->intervals.size() - 1].end();
321
322
return
0;
323
}
324
325
/*!
326
\overload
327
328
Adds the interval specified by \a start and \a end
329
to the time range.
330
331
\sa addInterval()
332
*/
333
void
QMediaTimeRange::addInterval(qint64 start, qint64 end)
334
{
335
detach();
336
d->addInterval(Interval(start, end));
337
}
338
339
/*!
340
Adds the specified \a interval to the time range.
341
342
Adding intervals which are not \l{QMediaTimeRange::Interval::isNormal()}{normal}
343
is invalid, and will be ignored.
344
345
If the specified interval is adjacent to, or overlaps existing
346
intervals within the time range, these intervals will be merged.
347
348
This operation takes linear time.
349
350
\sa removeInterval()
351
*/
352
void
QMediaTimeRange::addInterval(
const
QMediaTimeRange::Interval &interval)
353
{
354
detach();
355
d->addInterval(interval);
356
}
357
358
/*!
359
Adds each of the intervals in \a range to this time range.
360
361
Equivalent to calling addInterval() for each interval in \a range.
362
*/
363
void
QMediaTimeRange::addTimeRange(
const
QMediaTimeRange &range)
364
{
365
detach();
366
const
auto
intervals = range.intervals();
367
for
(
const
Interval &i : intervals) {
368
d->addInterval(i);
369
}
370
}
371
372
/*!
373
\overload
374
375
Removes the interval specified by \a start and \a end
376
from the time range.
377
378
\sa removeInterval()
379
*/
380
void
QMediaTimeRange::removeInterval(qint64 start, qint64 end)
381
{
382
detach();
383
d->removeInterval(Interval(start, end));
384
}
385
386
/*!
387
\fn QMediaTimeRange::removeInterval(const QMediaTimeRange::Interval &interval)
388
389
Removes the specified \a interval from the time range.
390
391
Removing intervals which are not \l{QMediaTimeRange::Interval::isNormal()}{normal}
392
is invalid, and will be ignored.
393
394
Intervals within the time range will be trimmed, split or deleted
395
such that no intervals within the time range include any part of the
396
target interval.
397
398
This operation takes linear time.
399
400
\sa addInterval()
401
*/
402
void
QMediaTimeRange::removeInterval(
const
QMediaTimeRange::Interval &interval)
403
{
404
detach();
405
d->removeInterval(interval);
406
}
407
408
/*!
409
Removes each of the intervals in \a range from this time range.
410
411
Equivalent to calling removeInterval() for each interval in \a range.
412
*/
413
void
QMediaTimeRange::removeTimeRange(
const
QMediaTimeRange &range)
414
{
415
detach();
416
const
auto
intervals = range.intervals();
417
for
(
const
Interval &i : intervals) {
418
d->removeInterval(i);
419
}
420
}
421
422
/*!
423
Adds each interval in \a other to the time range and returns the result.
424
*/
425
QMediaTimeRange& QMediaTimeRange::operator+=(
const
QMediaTimeRange &other)
426
{
427
addTimeRange(other);
428
return
*
this
;
429
}
430
431
/*!
432
Adds the specified \a interval to the time range and returns the result.
433
*/
434
QMediaTimeRange& QMediaTimeRange::operator+=(
const
QMediaTimeRange::Interval &interval)
435
{
436
addInterval(interval);
437
return
*
this
;
438
}
439
440
/*!
441
Removes each interval in \a other from the time range and returns the result.
442
*/
443
QMediaTimeRange& QMediaTimeRange::operator-=(
const
QMediaTimeRange &other)
444
{
445
removeTimeRange(other);
446
return
*
this
;
447
}
448
449
/*!
450
Removes the specified \a interval from the time range and returns the result.
451
*/
452
QMediaTimeRange& QMediaTimeRange::operator-=(
const
QMediaTimeRange::Interval &interval)
453
{
454
removeInterval(interval);
455
return
*
this
;
456
}
457
458
/*!
459
\fn QMediaTimeRange::clear()
460
461
Removes all intervals from the time range.
462
463
\sa removeInterval()
464
*/
465
void
QMediaTimeRange::clear()
466
{
467
detach();
468
d->intervals.clear();
469
}
470
471
/*!
472
\internal
473
*/
474
void
QMediaTimeRange::detach()
475
{
476
d.detach();
477
}
478
479
/*!
480
\fn QMediaTimeRange::intervals() const
481
482
Returns the list of intervals covered by this time range.
483
*/
484
QList<QMediaTimeRange::Interval> QMediaTimeRange::intervals()
const
485
{
486
return
d->intervals;
487
}
488
489
/*!
490
\fn QMediaTimeRange::isEmpty() const
491
492
Returns true if there are no intervals within the time range.
493
494
\sa intervals()
495
*/
496
bool
QMediaTimeRange::isEmpty()
const
497
{
498
return
d->intervals.isEmpty();
499
}
500
501
/*!
502
\fn QMediaTimeRange::isContinuous() const
503
504
Returns true if the time range consists of a continuous interval.
505
That is, there is one or fewer disjoint intervals within the time range.
506
*/
507
bool
QMediaTimeRange::isContinuous()
const
508
{
509
return
(d->intervals.size() <= 1);
510
}
511
512
/*!
513
\fn QMediaTimeRange::contains(qint64 time) const
514
515
Returns true if the specified \a time lies within the time range.
516
*/
517
bool
QMediaTimeRange::contains(qint64 time)
const
518
{
519
for
(
int
i = 0; i < d->intervals.size(); i++) {
520
if
(d->intervals[i].contains(time))
521
return
true
;
522
523
if
(time < d->intervals[i].start())
524
break
;
525
}
526
527
return
false
;
528
}
529
530
/*!
531
\fn bool QMediaTimeRange::operator==(const QMediaTimeRange &lhs, const QMediaTimeRange &rhs)
532
533
Returns true if all intervals in \a lhs are present in \a rhs.
534
*/
535
536
/*!
537
\fn bool QMediaTimeRange::operator!=(const QMediaTimeRange &lhs, const QMediaTimeRange &rhs)
538
539
Returns true if one or more intervals in \a lhs are not present in \a rhs.
540
*/
541
542
/*!
543
\fn QMediaTimeRange operator+(const QMediaTimeRange &r1, const QMediaTimeRange &r2)
544
\relates QMediaTimeRange
545
546
Returns a time range containing the union between \a r1 and \a r2.
547
*/
548
549
/*!
550
\fn QMediaTimeRange operator-(const QMediaTimeRange &r1, const QMediaTimeRange &r2)
551
\relates QMediaTimeRange
552
553
Returns a time range containing \a r2 subtracted from \a r1.
554
*/
555
556
#
ifndef
QT_NO_DEBUG_STREAM
557
QDebug
operator
<<(QDebug dbg,
const
QMediaTimeRange::Interval &interval)
558
{
559
QDebugStateSaver saver(dbg);
560
dbg.nospace();
561
dbg <<
"QMediaTimeRange::Interval( "
<< interval.start() <<
", "
<< interval.end() <<
" )"
;
562
return
dbg;
563
}
564
565
QDebug
operator
<<(QDebug dbg,
const
QMediaTimeRange &range)
566
{
567
QDebugStateSaver saver(dbg);
568
dbg.nospace();
569
dbg <<
"QMediaTimeRange( "
;
570
const
auto
intervals = range.intervals();
571
for
(
const
auto
&interval : intervals)
572
dbg <<
'('
<< interval.start() <<
", "
<< interval.end() <<
") "
;
573
dbg.space();
574
dbg <<
')'
;
575
return
dbg;
576
}
577
#
endif
578
579
QT_END_NAMESPACE
operator<<
QDebug operator<<(QDebug dbg, const QFileInfo &fi)
Definition
qfileinfo.cpp:1830
QT_DEFINE_QESDP_SPECIALIZATION_DTOR
QT_DEFINE_QESDP_SPECIALIZATION_DTOR(QMediaTimeRangePrivate)
qtmultimedia
src
multimedia
qmediatimerange.cpp
Generated on
for Qt by
1.18.0