Upstream version 10.38.222.0
[platform/framework/web/crosswalk.git] / src / content / renderer / media / websourcebuffer_impl.cc
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                        &timestamp_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                   &timestamp_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