OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "media/base/stream_parser_buffer.h" | 5 #include "media/base/stream_parser_buffer.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
11 #include "media/base/timestamp_constants.h" | 11 #include "media/base/timestamp_constants.h" |
12 | 12 |
13 namespace media { | 13 namespace media { |
14 | 14 |
15 static scoped_refptr<StreamParserBuffer> CopyBuffer( | |
16 const StreamParserBuffer& buffer) { | |
17 if (buffer.end_of_stream()) | |
18 return StreamParserBuffer::CreateEOSBuffer(); | |
19 | |
20 scoped_refptr<StreamParserBuffer> copied_buffer = | |
21 StreamParserBuffer::CopyFrom(buffer.data(), | |
22 buffer.data_size(), | |
23 buffer.side_data(), | |
24 buffer.side_data_size(), | |
25 buffer.is_key_frame(), | |
26 buffer.type(), | |
27 buffer.track_id()); | |
28 copied_buffer->SetDecodeTimestamp(buffer.GetDecodeTimestamp()); | |
29 copied_buffer->SetConfigId(buffer.GetConfigId()); | |
30 copied_buffer->set_timestamp(buffer.timestamp()); | |
31 copied_buffer->set_duration(buffer.duration()); | |
32 copied_buffer->set_is_duration_estimated(buffer.is_duration_estimated()); | |
33 copied_buffer->set_discard_padding(buffer.discard_padding()); | |
34 copied_buffer->set_splice_timestamp(buffer.splice_timestamp()); | |
35 const DecryptConfig* decrypt_config = buffer.decrypt_config(); | |
36 if (decrypt_config) { | |
37 copied_buffer->set_decrypt_config(base::MakeUnique<DecryptConfig>( | |
38 decrypt_config->key_id(), decrypt_config->iv(), | |
39 decrypt_config->subsamples())); | |
40 } | |
41 | |
42 return copied_buffer; | |
43 } | |
44 | |
45 scoped_refptr<StreamParserBuffer> StreamParserBuffer::CreateEOSBuffer() { | 15 scoped_refptr<StreamParserBuffer> StreamParserBuffer::CreateEOSBuffer() { |
46 return make_scoped_refptr(new StreamParserBuffer(NULL, 0, NULL, 0, false, | 16 return make_scoped_refptr(new StreamParserBuffer(NULL, 0, NULL, 0, false, |
47 DemuxerStream::UNKNOWN, 0)); | 17 DemuxerStream::UNKNOWN, 0)); |
48 } | 18 } |
49 | 19 |
50 scoped_refptr<StreamParserBuffer> StreamParserBuffer::CopyFrom( | 20 scoped_refptr<StreamParserBuffer> StreamParserBuffer::CopyFrom( |
51 const uint8_t* data, | 21 const uint8_t* data, |
52 int data_size, | 22 int data_size, |
53 bool is_key_frame, | 23 bool is_key_frame, |
54 Type type, | 24 Type type, |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
112 int StreamParserBuffer::GetConfigId() const { | 82 int StreamParserBuffer::GetConfigId() const { |
113 return config_id_; | 83 return config_id_; |
114 } | 84 } |
115 | 85 |
116 void StreamParserBuffer::SetConfigId(int config_id) { | 86 void StreamParserBuffer::SetConfigId(int config_id) { |
117 config_id_ = config_id; | 87 config_id_ = config_id; |
118 if (preroll_buffer_.get()) | 88 if (preroll_buffer_.get()) |
119 preroll_buffer_->SetConfigId(config_id); | 89 preroll_buffer_->SetConfigId(config_id); |
120 } | 90 } |
121 | 91 |
122 int StreamParserBuffer::GetSpliceBufferConfigId(size_t index) const { | |
123 return index < splice_buffers().size() | |
124 ? splice_buffers_[index]->GetConfigId() | |
125 : GetConfigId(); | |
126 } | |
127 | |
128 const char* StreamParserBuffer::GetTypeName() const { | 92 const char* StreamParserBuffer::GetTypeName() const { |
129 switch (type()) { | 93 switch (type()) { |
130 case DemuxerStream::AUDIO: | 94 case DemuxerStream::AUDIO: |
131 return "audio"; | 95 return "audio"; |
132 case DemuxerStream::VIDEO: | 96 case DemuxerStream::VIDEO: |
133 return "video"; | 97 return "video"; |
134 case DemuxerStream::TEXT: | 98 case DemuxerStream::TEXT: |
135 return "text"; | 99 return "text"; |
136 case DemuxerStream::UNKNOWN: | 100 case DemuxerStream::UNKNOWN: |
137 return "unknown"; | 101 return "unknown"; |
138 } | 102 } |
139 NOTREACHED(); | 103 NOTREACHED(); |
140 return ""; | 104 return ""; |
141 } | 105 } |
142 | 106 |
143 void StreamParserBuffer::ConvertToSpliceBuffer( | |
144 const BufferQueue& pre_splice_buffers) { | |
145 DCHECK(splice_buffers_.empty()); | |
146 DCHECK(duration() > base::TimeDelta()) | |
147 << "Only buffers with a valid duration can convert to a splice buffer." | |
148 << " pts " << timestamp().InSecondsF() | |
149 << " dts " << GetDecodeTimestamp().InSecondsF() | |
150 << " dur " << duration().InSecondsF(); | |
151 DCHECK(!end_of_stream()); | |
152 | |
153 // Splicing requires non-estimated sample accurate durations to be confident | |
154 // things will sound smooth. Also, we cannot be certain whether estimated | |
155 // overlap is really a splice scenario, or just over estimation. | |
156 DCHECK(!is_duration_estimated_); | |
157 | |
158 // Make a copy of this first, before making any changes. | |
159 scoped_refptr<StreamParserBuffer> overlapping_buffer = CopyBuffer(*this); | |
160 overlapping_buffer->set_splice_timestamp(kNoTimestamp); | |
161 | |
162 const scoped_refptr<StreamParserBuffer>& first_splice_buffer = | |
163 pre_splice_buffers.front(); | |
164 | |
165 // Ensure the given buffers are actually before the splice point. | |
166 DCHECK(first_splice_buffer->timestamp() <= overlapping_buffer->timestamp()); | |
167 | |
168 // TODO(dalecurtis): We should also clear |data| and |side_data|, but since | |
169 // that implies EOS care must be taken to ensure there are no clients relying | |
170 // on that behavior. | |
171 | |
172 // Move over any preroll from this buffer. | |
173 if (preroll_buffer_.get()) { | |
174 DCHECK(!overlapping_buffer->preroll_buffer_.get()); | |
175 overlapping_buffer->preroll_buffer_.swap(preroll_buffer_); | |
176 } | |
177 | |
178 // Rewrite |this| buffer as a splice buffer. | |
179 SetDecodeTimestamp(first_splice_buffer->GetDecodeTimestamp()); | |
180 SetConfigId(first_splice_buffer->GetConfigId()); | |
181 set_timestamp(first_splice_buffer->timestamp()); | |
182 set_is_key_frame(first_splice_buffer->is_key_frame()); | |
183 type_ = first_splice_buffer->type(); | |
184 track_id_ = first_splice_buffer->track_id(); | |
185 set_splice_timestamp(overlapping_buffer->timestamp()); | |
186 | |
187 // The splice duration is the duration of all buffers before the splice plus | |
188 // the highest ending timestamp after the splice point. | |
189 DCHECK(overlapping_buffer->duration() > base::TimeDelta()); | |
190 DCHECK(pre_splice_buffers.back()->duration() > base::TimeDelta()); | |
191 set_duration( | |
192 std::max(overlapping_buffer->timestamp() + overlapping_buffer->duration(), | |
193 pre_splice_buffers.back()->timestamp() + | |
194 pre_splice_buffers.back()->duration()) - | |
195 first_splice_buffer->timestamp()); | |
196 | |
197 // Copy all pre splice buffers into our wrapper buffer. | |
198 for (BufferQueue::const_iterator it = pre_splice_buffers.begin(); | |
199 it != pre_splice_buffers.end(); | |
200 ++it) { | |
201 const scoped_refptr<StreamParserBuffer>& buffer = *it; | |
202 DCHECK(!buffer->end_of_stream()); | |
203 DCHECK(!buffer->preroll_buffer().get()); | |
204 DCHECK(buffer->splice_buffers().empty()); | |
205 DCHECK(!buffer->is_duration_estimated()); | |
206 splice_buffers_.push_back(CopyBuffer(*buffer.get())); | |
207 splice_buffers_.back()->set_splice_timestamp(splice_timestamp()); | |
208 } | |
209 | |
210 splice_buffers_.push_back(overlapping_buffer); | |
211 } | |
212 | |
213 void StreamParserBuffer::SetPrerollBuffer( | 107 void StreamParserBuffer::SetPrerollBuffer( |
214 const scoped_refptr<StreamParserBuffer>& preroll_buffer) { | 108 const scoped_refptr<StreamParserBuffer>& preroll_buffer) { |
215 DCHECK(!preroll_buffer_.get()); | 109 DCHECK(!preroll_buffer_.get()); |
216 DCHECK(!end_of_stream()); | 110 DCHECK(!end_of_stream()); |
217 DCHECK(!preroll_buffer->end_of_stream()); | 111 DCHECK(!preroll_buffer->end_of_stream()); |
218 DCHECK(!preroll_buffer->preroll_buffer_.get()); | 112 DCHECK(!preroll_buffer->preroll_buffer_.get()); |
219 DCHECK(preroll_buffer->splice_timestamp() == kNoTimestamp); | |
220 DCHECK(preroll_buffer->splice_buffers().empty()); | |
221 DCHECK(preroll_buffer->timestamp() <= timestamp()); | 113 DCHECK(preroll_buffer->timestamp() <= timestamp()); |
222 DCHECK(preroll_buffer->discard_padding() == DecoderBuffer::DiscardPadding()); | 114 DCHECK(preroll_buffer->discard_padding() == DecoderBuffer::DiscardPadding()); |
223 DCHECK_EQ(preroll_buffer->type(), type()); | 115 DCHECK_EQ(preroll_buffer->type(), type()); |
224 DCHECK_EQ(preroll_buffer->track_id(), track_id()); | 116 DCHECK_EQ(preroll_buffer->track_id(), track_id()); |
225 | 117 |
226 preroll_buffer_ = preroll_buffer; | 118 preroll_buffer_ = preroll_buffer; |
227 preroll_buffer_->set_timestamp(timestamp()); | 119 preroll_buffer_->set_timestamp(timestamp()); |
120 preroll_buffer_->SetConfigId(GetConfigId()); | |
chcunningham
2016/11/11 00:50:50
This seemed to be missing. Probably not critical.
| |
228 preroll_buffer_->SetDecodeTimestamp(GetDecodeTimestamp()); | 121 preroll_buffer_->SetDecodeTimestamp(GetDecodeTimestamp()); |
229 | 122 |
230 // Mark the entire buffer for discard. | 123 // Mark the entire buffer for discard. |
231 preroll_buffer_->set_discard_padding( | 124 preroll_buffer_->set_discard_padding( |
232 std::make_pair(kInfiniteDuration, base::TimeDelta())); | 125 std::make_pair(kInfiniteDuration, base::TimeDelta())); |
233 } | 126 } |
234 | 127 |
235 void StreamParserBuffer::set_timestamp(base::TimeDelta timestamp) { | 128 void StreamParserBuffer::set_timestamp(base::TimeDelta timestamp) { |
236 DecoderBuffer::set_timestamp(timestamp); | 129 DecoderBuffer::set_timestamp(timestamp); |
237 if (preroll_buffer_.get()) | 130 if (preroll_buffer_.get()) |
238 preroll_buffer_->set_timestamp(timestamp); | 131 preroll_buffer_->set_timestamp(timestamp); |
239 } | 132 } |
240 | 133 |
241 } // namespace media | 134 } // namespace media |
OLD | NEW |