| 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 |