Autofill: Port changes to iOS JS code.
[chromium-blink-merge.git] / media / blink / websourcebuffer_impl.cc
blob0e387785ae1db4d0bb3a64b54d7dac0d3b1100fc
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 "media/blink/websourcebuffer_impl.h"
7 #include <cmath>
8 #include <limits>
10 #include "base/bind.h"
11 #include "base/callback.h"
12 #include "base/callback_helpers.h"
13 #include "media/filters/chunk_demuxer.h"
14 #include "third_party/WebKit/public/platform/WebSourceBufferClient.h"
16 namespace media {
18 static base::TimeDelta DoubleToTimeDelta(double time) {
19 DCHECK(!std::isnan(time));
20 DCHECK_NE(time, -std::numeric_limits<double>::infinity());
22 if (time == std::numeric_limits<double>::infinity())
23 return kInfiniteDuration();
25 // Don't use base::TimeDelta::Max() here, as we want the largest finite time
26 // delta.
27 base::TimeDelta max_time = base::TimeDelta::FromInternalValue(kint64max - 1);
28 double max_time_in_seconds = max_time.InSecondsF();
30 if (time >= max_time_in_seconds)
31 return max_time;
33 return base::TimeDelta::FromMicroseconds(
34 time * base::Time::kMicrosecondsPerSecond);
37 WebSourceBufferImpl::WebSourceBufferImpl(
38 const std::string& id, ChunkDemuxer* demuxer)
39 : id_(id),
40 demuxer_(demuxer),
41 client_(NULL),
42 append_window_end_(kInfiniteDuration()) {
43 DCHECK(demuxer_);
46 WebSourceBufferImpl::~WebSourceBufferImpl() {
47 DCHECK(!demuxer_) << "Object destroyed w/o removedFromMediaSource() call";
48 DCHECK(!client_);
51 void WebSourceBufferImpl::setClient(blink::WebSourceBufferClient* client) {
52 DCHECK(client);
53 DCHECK(!client_);
54 client_ = client;
57 bool WebSourceBufferImpl::setMode(WebSourceBuffer::AppendMode mode) {
58 if (demuxer_->IsParsingMediaSegment(id_))
59 return false;
61 switch (mode) {
62 case WebSourceBuffer::AppendModeSegments:
63 demuxer_->SetSequenceMode(id_, false);
64 return true;
65 case WebSourceBuffer::AppendModeSequence:
66 demuxer_->SetSequenceMode(id_, true);
67 return true;
70 NOTREACHED();
71 return false;
74 blink::WebTimeRanges WebSourceBufferImpl::buffered() {
75 Ranges<base::TimeDelta> ranges = demuxer_->GetBufferedRanges(id_);
76 blink::WebTimeRanges result(ranges.size());
77 for (size_t i = 0; i < ranges.size(); i++) {
78 result[i].start = ranges.start(i).InSecondsF();
79 result[i].end = ranges.end(i).InSecondsF();
81 return result;
84 void WebSourceBufferImpl::append(
85 const unsigned char* data,
86 unsigned length,
87 double* timestamp_offset) {
88 base::TimeDelta old_offset = timestamp_offset_;
89 demuxer_->AppendData(id_, data, length,
90 append_window_start_, append_window_end_,
91 &timestamp_offset_,
92 base::Bind(&WebSourceBufferImpl::InitSegmentReceived,
93 base::Unretained(this)));
95 // Coded frame processing may update the timestamp offset. If the caller
96 // provides a non-NULL |timestamp_offset| and frame processing changes the
97 // timestamp offset, report the new offset to the caller. Do not update the
98 // caller's offset otherwise, to preserve any pre-existing value that may have
99 // more than microsecond precision.
100 if (timestamp_offset && old_offset != timestamp_offset_)
101 *timestamp_offset = timestamp_offset_.InSecondsF();
104 void WebSourceBufferImpl::abort() {
105 demuxer_->Abort(id_,
106 append_window_start_, append_window_end_,
107 &timestamp_offset_);
109 // TODO(wolenetz): abort should be able to modify the caller timestamp offset
110 // (just like WebSourceBufferImpl::append).
111 // See http://crbug.com/370229 for further details.
114 void WebSourceBufferImpl::remove(double start, double end) {
115 DCHECK_GE(start, 0);
116 DCHECK_GE(end, 0);
117 demuxer_->Remove(id_, DoubleToTimeDelta(start), DoubleToTimeDelta(end));
120 bool WebSourceBufferImpl::setTimestampOffset(double offset) {
121 if (demuxer_->IsParsingMediaSegment(id_))
122 return false;
124 timestamp_offset_ = DoubleToTimeDelta(offset);
126 // http://www.w3.org/TR/media-source/#widl-SourceBuffer-timestampOffset
127 // Step 6: If the mode attribute equals "sequence", then set the group start
128 // timestamp to new timestamp offset.
129 demuxer_->SetGroupStartTimestampIfInSequenceMode(id_, timestamp_offset_);
130 return true;
133 void WebSourceBufferImpl::setAppendWindowStart(double start) {
134 DCHECK_GE(start, 0);
135 append_window_start_ = DoubleToTimeDelta(start);
138 void WebSourceBufferImpl::setAppendWindowEnd(double end) {
139 DCHECK_GE(end, 0);
140 append_window_end_ = DoubleToTimeDelta(end);
143 void WebSourceBufferImpl::removedFromMediaSource() {
144 demuxer_->RemoveId(id_);
145 demuxer_ = NULL;
146 client_ = NULL;
149 void WebSourceBufferImpl::InitSegmentReceived() {
150 DVLOG(1) << __FUNCTION__;
151 client_->initializationSegmentReceived();
154 } // namespace media