OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include "content/renderer/media/websourcebuffer_impl.h" | |
6 | |
7 #include <limits> | |
8 | |
9 #include "base/float_util.h" | |
10 #include "media/filters/chunk_demuxer.h" | |
11 | |
12 namespace content { | |
13 | |
14 static base::TimeDelta DoubleToTimeDelta(double time) { | |
15 DCHECK(!base::IsNaN(time)); | |
16 DCHECK_NE(time, -std::numeric_limits<double>::infinity()); | |
17 | |
18 if (time == std::numeric_limits<double>::infinity()) | |
19 return media::kInfiniteDuration(); | |
20 | |
21 // Don't use base::TimeDelta::Max() here, as we want the largest finite time | |
22 // delta. | |
23 base::TimeDelta max_time = base::TimeDelta::FromInternalValue(kint64max - 1); | |
24 double max_time_in_seconds = max_time.InSecondsF(); | |
25 | |
26 if (time >= max_time_in_seconds) | |
27 return max_time; | |
28 | |
29 return base::TimeDelta::FromMicroseconds( | |
30 time * base::Time::kMicrosecondsPerSecond); | |
31 } | |
32 | |
33 WebSourceBufferImpl::WebSourceBufferImpl( | |
34 const std::string& id, media::ChunkDemuxer* demuxer) | |
35 : id_(id), | |
36 demuxer_(demuxer), | |
37 append_window_end_(media::kInfiniteDuration()) { | |
38 DCHECK(demuxer_); | |
39 } | |
40 | |
41 WebSourceBufferImpl::~WebSourceBufferImpl() { | |
42 DCHECK(!demuxer_) << "Object destroyed w/o removedFromMediaSource() call"; | |
43 } | |
44 | |
45 bool WebSourceBufferImpl::setMode(WebSourceBuffer::AppendMode mode) { | |
46 if (demuxer_->IsParsingMediaSegment(id_)) | |
47 return false; | |
48 | |
49 switch (mode) { | |
50 case WebSourceBuffer::AppendModeSegments: | |
51 demuxer_->SetSequenceMode(id_, false); | |
52 return true; | |
53 case WebSourceBuffer::AppendModeSequence: | |
54 demuxer_->SetSequenceMode(id_, true); | |
55 return true; | |
56 } | |
57 | |
58 NOTREACHED(); | |
59 return false; | |
60 } | |
61 | |
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(); | |
68 } | |
69 return result; | |
70 } | |
71 | |
72 void WebSourceBufferImpl::append( | |
73 const unsigned char* data, | |
74 unsigned length, | |
75 double* timestamp_offset) { | |
76 base::TimeDelta old_offset = timestamp_offset_; | |
77 demuxer_->AppendData(id_, data, length, | |
78 append_window_start_, append_window_end_, | |
79 ×tamp_offset_); | |
80 | |
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(); | |
88 } | |
89 | |
90 void WebSourceBufferImpl::abort() { | |
91 demuxer_->Abort(id_, | |
92 append_window_start_, append_window_end_, | |
93 ×tamp_offset_); | |
94 | |
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. | |
98 } | |
99 | |
100 void WebSourceBufferImpl::remove(double start, double end) { | |
101 DCHECK_GE(start, 0); | |
102 DCHECK_GE(end, 0); | |
103 demuxer_->Remove(id_, DoubleToTimeDelta(start), DoubleToTimeDelta(end)); | |
104 } | |
105 | |
106 bool WebSourceBufferImpl::setTimestampOffset(double offset) { | |
107 if (demuxer_->IsParsingMediaSegment(id_)) | |
108 return false; | |
109 | |
110 timestamp_offset_ = DoubleToTimeDelta(offset); | |
111 | |
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_); | |
116 return true; | |
117 } | |
118 | |
119 void WebSourceBufferImpl::setAppendWindowStart(double start) { | |
120 DCHECK_GE(start, 0); | |
121 append_window_start_ = DoubleToTimeDelta(start); | |
122 } | |
123 | |
124 void WebSourceBufferImpl::setAppendWindowEnd(double end) { | |
125 DCHECK_GE(end, 0); | |
126 append_window_end_ = DoubleToTimeDelta(end); | |
127 } | |
128 | |
129 void WebSourceBufferImpl::removedFromMediaSource() { | |
130 demuxer_->RemoveId(id_); | |
131 demuxer_ = NULL; | |
132 } | |
133 | |
134 } // namespace content | |
OLD | NEW |