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/webm/webm_cluster_parser.h" | 5 #include "media/webm/webm_cluster_parser.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "media/base/data_buffer.h" | 8 #include "media/base/data_buffer.h" |
9 #include "media/base/decrypt_config.h" | 9 #include "media/base/decrypt_config.h" |
10 #include "media/webm/webm_constants.h" | 10 #include "media/webm/webm_constants.h" |
(...skipping 23 matching lines...) Expand all Loading... | |
34 video_encryption_key_id_.reset(new uint8[video_encryption_key_id_size]); | 34 video_encryption_key_id_.reset(new uint8[video_encryption_key_id_size]); |
35 memcpy(video_encryption_key_id_.get(), video_encryption_key_id, | 35 memcpy(video_encryption_key_id_.get(), video_encryption_key_id, |
36 video_encryption_key_id_size); | 36 video_encryption_key_id_size); |
37 } | 37 } |
38 } | 38 } |
39 | 39 |
40 WebMClusterParser::~WebMClusterParser() {} | 40 WebMClusterParser::~WebMClusterParser() {} |
41 | 41 |
42 void WebMClusterParser::Reset() { | 42 void WebMClusterParser::Reset() { |
43 audio_buffers_.clear(); | 43 audio_buffers_.clear(); |
44 delayed_audio_buffer_ = NULL; | |
44 video_buffers_.clear(); | 45 video_buffers_.clear(); |
46 delayed_video_buffer_ = NULL; | |
45 last_block_timecode_ = -1; | 47 last_block_timecode_ = -1; |
46 cluster_timecode_ = -1; | 48 cluster_timecode_ = -1; |
47 parser_.Reset(); | 49 parser_.Reset(); |
48 } | 50 } |
49 | 51 |
50 int WebMClusterParser::Parse(const uint8* buf, int size) { | 52 int WebMClusterParser::Parse(const uint8* buf, int size) { |
51 audio_buffers_.clear(); | 53 audio_buffers_.clear(); |
52 video_buffers_.clear(); | 54 video_buffers_.clear(); |
53 | 55 |
54 int result = parser_.Parse(buf, size); | 56 int result = parser_.Parse(buf, size); |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
159 if (block_data_.get()) { | 161 if (block_data_.get()) { |
160 DVLOG(1) << "More than 1 Block in a BlockGroup is not supported."; | 162 DVLOG(1) << "More than 1 Block in a BlockGroup is not supported."; |
161 return false; | 163 return false; |
162 } | 164 } |
163 | 165 |
164 block_data_.reset(new uint8[size]); | 166 block_data_.reset(new uint8[size]); |
165 memcpy(block_data_.get(), data, size); | 167 memcpy(block_data_.get(), data, size); |
166 block_data_size_ = size; | 168 block_data_size_ = size; |
167 return true; | 169 return true; |
168 } | 170 } |
171 | |
169 bool WebMClusterParser::OnBlock(int track_num, int timecode, | 172 bool WebMClusterParser::OnBlock(int track_num, int timecode, |
170 int block_duration, | 173 int block_duration, |
171 int flags, | 174 int flags, |
172 const uint8* data, int size) { | 175 const uint8* data, int size) { |
173 if (cluster_timecode_ == -1) { | 176 if (cluster_timecode_ == -1) { |
174 DVLOG(1) << "Got a block before cluster timecode."; | 177 DVLOG(1) << "Got a block before cluster timecode."; |
175 return false; | 178 return false; |
176 } | 179 } |
177 | 180 |
178 if (timecode < 0) { | 181 if (timecode < 0) { |
(...skipping 17 matching lines...) Expand all Loading... | |
196 scoped_refptr<StreamParserBuffer> buffer = | 199 scoped_refptr<StreamParserBuffer> buffer = |
197 StreamParserBuffer::CopyFrom(data, size, is_keyframe); | 200 StreamParserBuffer::CopyFrom(data, size, is_keyframe); |
198 | 201 |
199 if (track_num == video_track_num_ && video_encryption_key_id_.get()) { | 202 if (track_num == video_track_num_ && video_encryption_key_id_.get()) { |
200 buffer->SetDecryptConfig(scoped_ptr<DecryptConfig>(new DecryptConfig( | 203 buffer->SetDecryptConfig(scoped_ptr<DecryptConfig>(new DecryptConfig( |
201 video_encryption_key_id_.get(), video_encryption_key_id_size_))); | 204 video_encryption_key_id_.get(), video_encryption_key_id_size_))); |
202 } | 205 } |
203 | 206 |
204 buffer->SetTimestamp(timestamp); | 207 buffer->SetTimestamp(timestamp); |
205 BufferQueue* queue = NULL; | 208 BufferQueue* queue = NULL; |
209 scoped_refptr<StreamParserBuffer>* delayed_buffer; | |
scherkus (not reviewing)
2012/05/17 02:45:46
I'm finding this pointer-to-a-scoped_refptr<T> to
acolwell GONE FROM CHROMIUM
2012/05/17 18:28:51
Excellent idea! I moved this all into a helper cla
| |
206 base::TimeDelta duration = kNoTimestamp(); | 210 base::TimeDelta duration = kNoTimestamp(); |
207 | 211 |
208 if (track_num == audio_track_num_) { | 212 if (track_num == audio_track_num_) { |
209 duration = audio_default_duration_; | 213 duration = audio_default_duration_; |
210 queue = &audio_buffers_; | 214 queue = &audio_buffers_; |
215 delayed_buffer = &delayed_audio_buffer_; | |
211 } else if (track_num == video_track_num_) { | 216 } else if (track_num == video_track_num_) { |
212 duration = video_default_duration_; | 217 duration = video_default_duration_; |
213 queue = &video_buffers_; | 218 queue = &video_buffers_; |
219 delayed_buffer = &delayed_video_buffer_; | |
214 } else { | 220 } else { |
215 DVLOG(1) << "Unexpected track number " << track_num; | 221 DVLOG(1) << "Unexpected track number " << track_num; |
216 return false; | 222 return false; |
217 } | 223 } |
218 | 224 |
219 if (block_duration >= 0) { | 225 if (block_duration >= 0) { |
220 duration = base::TimeDelta::FromMicroseconds( | 226 duration = base::TimeDelta::FromMicroseconds( |
221 block_duration * timecode_multiplier_); | 227 block_duration * timecode_multiplier_); |
222 } | 228 } |
223 | 229 |
224 buffer->SetDuration(duration); | 230 buffer->SetDuration(duration); |
225 | 231 |
226 if (!queue->empty() && | 232 if (!queue->empty() && |
227 buffer->GetTimestamp() == queue->back()->GetTimestamp()) { | 233 buffer->GetTimestamp() == queue->back()->GetTimestamp()) { |
228 DVLOG(1) << "Got a block timecode that is not strictly monotonically " | 234 DVLOG(1) << "Got a block timecode that is not strictly monotonically " |
229 << "increasing for track " << track_num; | 235 << "increasing for track " << track_num; |
230 return false; | 236 return false; |
231 } | 237 } |
232 | 238 |
239 if (*delayed_buffer) { | |
240 // Update the duration of the delayed buffer and place it into the queue. | |
241 base::TimeDelta new_duration = | |
242 buffer->GetTimestamp() - (*delayed_buffer)->GetTimestamp(); | |
243 | |
244 if (new_duration <= base::TimeDelta()) | |
scherkus (not reviewing)
2012/05/17 02:45:46
when would this happen? out of order timestamps?
acolwell GONE FROM CHROMIUM
2012/05/17 18:28:51
Yes. It can happen if a muxer creates a cluster wi
| |
245 return false; | |
246 | |
247 (*delayed_buffer)->SetDuration(new_duration); | |
248 queue->push_back(*delayed_buffer); | |
249 | |
250 *delayed_buffer = NULL; | |
251 } | |
252 | |
253 // Place the buffer in delayed buffer slot if we don't know | |
254 // its duration. | |
255 if (buffer->GetDuration() == kNoTimestamp()) { | |
256 *delayed_buffer = buffer; | |
257 return true; | |
258 } | |
259 | |
233 queue->push_back(buffer); | 260 queue->push_back(buffer); |
234 return true; | 261 return true; |
235 } | 262 } |
236 | 263 |
237 } // namespace media | 264 } // namespace media |
OLD | NEW |