Update V8 to version 4.7.56.
[chromium-blink-merge.git] / media / base / stream_parser_buffer.cc
bloba9bb77517a28c46e806a60e8481b199f68a5cba4
1 // Copyright (c) 2012 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/base/stream_parser_buffer.h"
7 #include "base/logging.h"
8 #include "media/base/timestamp_constants.h"
10 namespace media {
12 static scoped_refptr<StreamParserBuffer> CopyBuffer(
13 const StreamParserBuffer& buffer) {
14 if (buffer.end_of_stream())
15 return StreamParserBuffer::CreateEOSBuffer();
17 scoped_refptr<StreamParserBuffer> copied_buffer =
18 StreamParserBuffer::CopyFrom(buffer.data(),
19 buffer.data_size(),
20 buffer.side_data(),
21 buffer.side_data_size(),
22 buffer.is_key_frame(),
23 buffer.type(),
24 buffer.track_id());
25 copied_buffer->SetDecodeTimestamp(buffer.GetDecodeTimestamp());
26 copied_buffer->SetConfigId(buffer.GetConfigId());
27 copied_buffer->set_timestamp(buffer.timestamp());
28 copied_buffer->set_duration(buffer.duration());
29 copied_buffer->set_is_duration_estimated(buffer.is_duration_estimated());
30 copied_buffer->set_discard_padding(buffer.discard_padding());
31 copied_buffer->set_splice_timestamp(buffer.splice_timestamp());
32 const DecryptConfig* decrypt_config = buffer.decrypt_config();
33 if (decrypt_config) {
34 copied_buffer->set_decrypt_config(
35 make_scoped_ptr(new DecryptConfig(decrypt_config->key_id(),
36 decrypt_config->iv(),
37 decrypt_config->subsamples())));
40 return copied_buffer;
43 scoped_refptr<StreamParserBuffer> StreamParserBuffer::CreateEOSBuffer() {
44 return make_scoped_refptr(new StreamParserBuffer(NULL, 0, NULL, 0, false,
45 DemuxerStream::UNKNOWN, 0));
48 scoped_refptr<StreamParserBuffer> StreamParserBuffer::CopyFrom(
49 const uint8* data, int data_size, bool is_key_frame, Type type,
50 TrackId track_id) {
51 return make_scoped_refptr(
52 new StreamParserBuffer(data, data_size, NULL, 0, is_key_frame, type,
53 track_id));
56 scoped_refptr<StreamParserBuffer> StreamParserBuffer::CopyFrom(
57 const uint8* data, int data_size,
58 const uint8* side_data, int side_data_size,
59 bool is_key_frame, Type type, TrackId track_id) {
60 return make_scoped_refptr(
61 new StreamParserBuffer(data, data_size, side_data, side_data_size,
62 is_key_frame, type, track_id));
65 DecodeTimestamp StreamParserBuffer::GetDecodeTimestamp() const {
66 if (decode_timestamp_ == kNoDecodeTimestamp())
67 return DecodeTimestamp::FromPresentationTime(timestamp());
68 return decode_timestamp_;
71 void StreamParserBuffer::SetDecodeTimestamp(DecodeTimestamp timestamp) {
72 decode_timestamp_ = timestamp;
73 if (preroll_buffer_.get())
74 preroll_buffer_->SetDecodeTimestamp(timestamp);
77 StreamParserBuffer::StreamParserBuffer(const uint8* data,
78 int data_size,
79 const uint8* side_data,
80 int side_data_size,
81 bool is_key_frame,
82 Type type,
83 TrackId track_id)
84 : DecoderBuffer(data, data_size, side_data, side_data_size),
85 decode_timestamp_(kNoDecodeTimestamp()),
86 config_id_(kInvalidConfigId),
87 type_(type),
88 track_id_(track_id),
89 is_duration_estimated_(false) {
90 // TODO(scherkus): Should DataBuffer constructor accept a timestamp and
91 // duration to force clients to set them? Today they end up being zero which
92 // is both a common and valid value and could lead to bugs.
93 if (data) {
94 set_duration(kNoTimestamp());
97 if (is_key_frame)
98 set_is_key_frame(true);
101 StreamParserBuffer::~StreamParserBuffer() {}
103 int StreamParserBuffer::GetConfigId() const {
104 return config_id_;
107 void StreamParserBuffer::SetConfigId(int config_id) {
108 config_id_ = config_id;
109 if (preroll_buffer_.get())
110 preroll_buffer_->SetConfigId(config_id);
113 int StreamParserBuffer::GetSpliceBufferConfigId(size_t index) const {
114 return index < splice_buffers().size()
115 ? splice_buffers_[index]->GetConfigId()
116 : GetConfigId();
119 const char* StreamParserBuffer::GetTypeName() const {
120 switch (type()) {
121 case DemuxerStream::AUDIO:
122 return "audio";
123 case DemuxerStream::VIDEO:
124 return "video";
125 case DemuxerStream::TEXT:
126 return "text";
127 case DemuxerStream::UNKNOWN:
128 return "unknown";
129 case DemuxerStream::NUM_TYPES:
130 // Fall-through to NOTREACHED().
131 break;
133 NOTREACHED();
134 return "";
137 void StreamParserBuffer::ConvertToSpliceBuffer(
138 const BufferQueue& pre_splice_buffers) {
139 DCHECK(splice_buffers_.empty());
140 DCHECK(duration() > base::TimeDelta())
141 << "Only buffers with a valid duration can convert to a splice buffer."
142 << " pts " << timestamp().InSecondsF()
143 << " dts " << GetDecodeTimestamp().InSecondsF()
144 << " dur " << duration().InSecondsF();
145 DCHECK(!end_of_stream());
147 // Splicing requires non-estimated sample accurate durations to be confident
148 // things will sound smooth. Also, we cannot be certain whether estimated
149 // overlap is really a splice scenario, or just over estimation.
150 DCHECK(!is_duration_estimated_);
152 // Make a copy of this first, before making any changes.
153 scoped_refptr<StreamParserBuffer> overlapping_buffer = CopyBuffer(*this);
154 overlapping_buffer->set_splice_timestamp(kNoTimestamp());
156 const scoped_refptr<StreamParserBuffer>& first_splice_buffer =
157 pre_splice_buffers.front();
159 // Ensure the given buffers are actually before the splice point.
160 DCHECK(first_splice_buffer->timestamp() <= overlapping_buffer->timestamp());
162 // TODO(dalecurtis): We should also clear |data| and |side_data|, but since
163 // that implies EOS care must be taken to ensure there are no clients relying
164 // on that behavior.
166 // Move over any preroll from this buffer.
167 if (preroll_buffer_.get()) {
168 DCHECK(!overlapping_buffer->preroll_buffer_.get());
169 overlapping_buffer->preroll_buffer_.swap(preroll_buffer_);
172 // Rewrite |this| buffer as a splice buffer.
173 SetDecodeTimestamp(first_splice_buffer->GetDecodeTimestamp());
174 SetConfigId(first_splice_buffer->GetConfigId());
175 set_timestamp(first_splice_buffer->timestamp());
176 set_is_key_frame(first_splice_buffer->is_key_frame());
177 type_ = first_splice_buffer->type();
178 track_id_ = first_splice_buffer->track_id();
179 set_splice_timestamp(overlapping_buffer->timestamp());
181 // The splice duration is the duration of all buffers before the splice plus
182 // the highest ending timestamp after the splice point.
183 DCHECK(overlapping_buffer->duration() > base::TimeDelta());
184 DCHECK(pre_splice_buffers.back()->duration() > base::TimeDelta());
185 set_duration(
186 std::max(overlapping_buffer->timestamp() + overlapping_buffer->duration(),
187 pre_splice_buffers.back()->timestamp() +
188 pre_splice_buffers.back()->duration()) -
189 first_splice_buffer->timestamp());
191 // Copy all pre splice buffers into our wrapper buffer.
192 for (BufferQueue::const_iterator it = pre_splice_buffers.begin();
193 it != pre_splice_buffers.end();
194 ++it) {
195 const scoped_refptr<StreamParserBuffer>& buffer = *it;
196 DCHECK(!buffer->end_of_stream());
197 DCHECK(!buffer->preroll_buffer().get());
198 DCHECK(buffer->splice_buffers().empty());
199 DCHECK(!buffer->is_duration_estimated());
200 splice_buffers_.push_back(CopyBuffer(*buffer.get()));
201 splice_buffers_.back()->set_splice_timestamp(splice_timestamp());
204 splice_buffers_.push_back(overlapping_buffer);
207 void StreamParserBuffer::SetPrerollBuffer(
208 const scoped_refptr<StreamParserBuffer>& preroll_buffer) {
209 DCHECK(!preroll_buffer_.get());
210 DCHECK(!end_of_stream());
211 DCHECK(!preroll_buffer->end_of_stream());
212 DCHECK(!preroll_buffer->preroll_buffer_.get());
213 DCHECK(preroll_buffer->splice_timestamp() == kNoTimestamp());
214 DCHECK(preroll_buffer->splice_buffers().empty());
215 DCHECK(preroll_buffer->timestamp() <= timestamp());
216 DCHECK(preroll_buffer->discard_padding() == DecoderBuffer::DiscardPadding());
217 DCHECK_EQ(preroll_buffer->type(), type());
218 DCHECK_EQ(preroll_buffer->track_id(), track_id());
220 preroll_buffer_ = preroll_buffer;
221 preroll_buffer_->set_timestamp(timestamp());
222 preroll_buffer_->SetDecodeTimestamp(GetDecodeTimestamp());
224 // Mark the entire buffer for discard.
225 preroll_buffer_->set_discard_padding(
226 std::make_pair(kInfiniteDuration(), base::TimeDelta()));
229 void StreamParserBuffer::set_timestamp(base::TimeDelta timestamp) {
230 DecoderBuffer::set_timestamp(timestamp);
231 if (preroll_buffer_.get())
232 preroll_buffer_->set_timestamp(timestamp);
235 } // namespace media