1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/renderer/media/websourcebuffer_impl.h"
9 #include "base/float_util.h"
10 #include "media/filters/chunk_demuxer.h"
14 static base::TimeDelta
DoubleToTimeDelta(double time
) {
15 DCHECK(!base::IsNaN(time
));
16 DCHECK_NE(time
, -std::numeric_limits
<double>::infinity());
18 if (time
== std::numeric_limits
<double>::infinity())
19 return media::kInfiniteDuration();
21 // Don't use base::TimeDelta::Max() here, as we want the largest finite time
23 base::TimeDelta max_time
= base::TimeDelta::FromInternalValue(kint64max
- 1);
24 double max_time_in_seconds
= max_time
.InSecondsF();
26 if (time
>= max_time_in_seconds
)
29 return base::TimeDelta::FromMicroseconds(
30 time
* base::Time::kMicrosecondsPerSecond
);
33 WebSourceBufferImpl::WebSourceBufferImpl(
34 const std::string
& id
, media::ChunkDemuxer
* demuxer
)
37 append_window_end_(media::kInfiniteDuration()) {
41 WebSourceBufferImpl::~WebSourceBufferImpl() {
42 DCHECK(!demuxer_
) << "Object destroyed w/o removedFromMediaSource() call";
45 bool WebSourceBufferImpl::setMode(WebSourceBuffer::AppendMode mode
) {
46 if (demuxer_
->IsParsingMediaSegment(id_
))
50 case WebSourceBuffer::AppendModeSegments
:
51 demuxer_
->SetSequenceMode(id_
, false);
53 case WebSourceBuffer::AppendModeSequence
:
54 demuxer_
->SetSequenceMode(id_
, true);
62 blink::WebTimeRanges
WebSourceBufferImpl::buffered() {
63 media::Ranges
<base::TimeDelta
> ranges
= demuxer_
->GetBufferedRanges(id_
);
64 blink::WebTimeRanges
result(ranges
.size());
65 for (size_t i
= 0; i
< ranges
.size(); i
++) {
66 result
[i
].start
= ranges
.start(i
).InSecondsF();
67 result
[i
].end
= ranges
.end(i
).InSecondsF();
72 void WebSourceBufferImpl::append(
73 const unsigned char* data
,
75 double* timestamp_offset
) {
76 base::TimeDelta old_offset
= timestamp_offset_
;
77 demuxer_
->AppendData(id_
, data
, length
,
78 append_window_start_
, append_window_end_
,
81 // Coded frame processing may update the timestamp offset. If the caller
82 // provides a non-NULL |timestamp_offset| and frame processing changes the
83 // timestamp offset, report the new offset to the caller. Do not update the
84 // caller's offset otherwise, to preserve any pre-existing value that may have
85 // more than microsecond precision.
86 if (timestamp_offset
&& old_offset
!= timestamp_offset_
)
87 *timestamp_offset
= timestamp_offset_
.InSecondsF();
90 void WebSourceBufferImpl::abort() {
92 append_window_start_
, append_window_end_
,
95 // TODO(wolenetz): abort should be able to modify the caller timestamp offset
96 // (just like WebSourceBufferImpl::append).
97 // See http://crbug.com/370229 for further details.
100 void WebSourceBufferImpl::remove(double start
, double end
) {
103 demuxer_
->Remove(id_
, DoubleToTimeDelta(start
), DoubleToTimeDelta(end
));
106 bool WebSourceBufferImpl::setTimestampOffset(double offset
) {
107 if (demuxer_
->IsParsingMediaSegment(id_
))
110 timestamp_offset_
= DoubleToTimeDelta(offset
);
112 // http://www.w3.org/TR/media-source/#widl-SourceBuffer-timestampOffset
113 // Step 6: If the mode attribute equals "sequence", then set the group start
114 // timestamp to new timestamp offset.
115 demuxer_
->SetGroupStartTimestampIfInSequenceMode(id_
, timestamp_offset_
);
119 void WebSourceBufferImpl::setAppendWindowStart(double start
) {
121 append_window_start_
= DoubleToTimeDelta(start
);
124 void WebSourceBufferImpl::setAppendWindowEnd(double end
) {
126 append_window_end_
= DoubleToTimeDelta(end
);
129 void WebSourceBufferImpl::removedFromMediaSource() {
130 demuxer_
->RemoveId(id_
);
134 } // namespace content