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 28 matching lines...) Expand all Loading... |
39 void WebMClusterParser::Reset() { | 39 void WebMClusterParser::Reset() { |
40 last_block_timecode_ = -1; | 40 last_block_timecode_ = -1; |
41 cluster_timecode_ = -1; | 41 cluster_timecode_ = -1; |
42 cluster_start_time_ = kNoTimestamp(); | 42 cluster_start_time_ = kNoTimestamp(); |
43 parser_.Reset(); | 43 parser_.Reset(); |
44 audio_.Reset(); | 44 audio_.Reset(); |
45 video_.Reset(); | 45 video_.Reset(); |
46 } | 46 } |
47 | 47 |
48 int WebMClusterParser::Parse(const uint8* buf, int size) { | 48 int WebMClusterParser::Parse(const uint8* buf, int size) { |
49 audio_.ClearBufferQueue(); | 49 audio_.Reset(); |
50 video_.ClearBufferQueue(); | 50 video_.Reset(); |
51 | 51 |
52 int result = parser_.Parse(buf, size); | 52 int result = parser_.Parse(buf, size); |
53 | 53 |
54 if (result <= 0) | 54 if (result <= 0) |
55 return result; | 55 return result; |
56 | 56 |
57 if (parser_.IsParsingComplete()) { | 57 if (parser_.IsParsingComplete()) { |
58 // If there were no buffers in this cluster, set the cluster start time to | 58 // If there were no buffers in this cluster, set the cluster start time to |
59 // be the |cluster_timecode_|. | 59 // be the |cluster_timecode_|. |
60 if (cluster_start_time_ == kNoTimestamp()) { | 60 if (cluster_start_time_ == kNoTimestamp()) { |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
224 } | 224 } |
225 | 225 |
226 WebMClusterParser::Track::Track(int track_num) | 226 WebMClusterParser::Track::Track(int track_num) |
227 : track_num_(track_num) { | 227 : track_num_(track_num) { |
228 } | 228 } |
229 | 229 |
230 WebMClusterParser::Track::~Track() {} | 230 WebMClusterParser::Track::~Track() {} |
231 | 231 |
232 bool WebMClusterParser::Track::AddBuffer( | 232 bool WebMClusterParser::Track::AddBuffer( |
233 const scoped_refptr<StreamParserBuffer>& buffer) { | 233 const scoped_refptr<StreamParserBuffer>& buffer) { |
234 if (!buffers_.empty() && | 234 DVLOG(2) << "AddBuffer() : " << track_num_ |
235 buffer->GetTimestamp() == buffers_.back()->GetTimestamp()) { | |
236 DVLOG(1) << "Got a block timecode that is not strictly monotonically " | |
237 << "increasing for track " << track_num_; | |
238 return false; | |
239 } | |
240 | |
241 if (!delayed_buffers_.empty()) { | |
242 // Update the duration of the delayed buffer and place it into the queue. | |
243 scoped_refptr<StreamParserBuffer> delayed_buffer = delayed_buffers_.front(); | |
244 | |
245 // If we get another buffer with the same timestamp, put it in the delay | |
246 // queue. | |
247 if (buffer->GetTimestamp() == delayed_buffer->GetTimestamp()) { | |
248 delayed_buffers_.push_back(buffer); | |
249 | |
250 // If this buffer happens to have a duration, use it to set the | |
251 // duration on all the other buffers in the queue. | |
252 if (buffer->GetDuration() != kNoTimestamp()) | |
253 SetDelayedBufferDurations(buffer->GetDuration()); | |
254 | |
255 return true; | |
256 } | |
257 | |
258 base::TimeDelta new_duration = | |
259 buffer->GetTimestamp() - delayed_buffer->GetTimestamp(); | |
260 | |
261 if (new_duration < base::TimeDelta()) { | |
262 DVLOG(1) << "Detected out of order timestamps."; | |
263 return false; | |
264 } | |
265 | |
266 SetDelayedBufferDurations(new_duration); | |
267 } | |
268 | |
269 // Place the buffer in delayed buffer slot if we don't know | |
270 // its duration. | |
271 if (buffer->GetDuration() == kNoTimestamp()) { | |
272 delayed_buffers_.push_back(buffer); | |
273 return true; | |
274 } | |
275 | |
276 AddToBufferQueue(buffer); | |
277 return true; | |
278 } | |
279 | |
280 void WebMClusterParser::Track::Reset() { | |
281 buffers_.clear(); | |
282 delayed_buffers_.clear(); | |
283 } | |
284 | |
285 void WebMClusterParser::Track::ClearBufferQueue() { | |
286 buffers_.clear(); | |
287 } | |
288 | |
289 void WebMClusterParser::Track::SetDelayedBufferDurations( | |
290 base::TimeDelta duration) { | |
291 | |
292 for (BufferQueue::iterator itr = delayed_buffers_.begin(); | |
293 itr < delayed_buffers_.end(); ++itr) { | |
294 (*itr)->SetDuration(duration); | |
295 | |
296 AddToBufferQueue(*itr); | |
297 } | |
298 delayed_buffers_.clear(); | |
299 } | |
300 | |
301 void WebMClusterParser::Track::AddToBufferQueue( | |
302 const scoped_refptr<StreamParserBuffer>& buffer) { | |
303 DCHECK(buffer->GetDuration() > base::TimeDelta()); | |
304 | |
305 DVLOG(2) << "AddToBufferQueue() : " << track_num_ | |
306 << " ts " << buffer->GetTimestamp().InSecondsF() | 235 << " ts " << buffer->GetTimestamp().InSecondsF() |
307 << " dur " << buffer->GetDuration().InSecondsF() | 236 << " dur " << buffer->GetDuration().InSecondsF() |
308 << " kf " << buffer->IsKeyframe() | 237 << " kf " << buffer->IsKeyframe() |
309 << " size " << buffer->GetDataSize(); | 238 << " size " << buffer->GetDataSize(); |
310 | 239 |
311 buffers_.push_back(buffer); | 240 buffers_.push_back(buffer); |
| 241 return true; |
| 242 } |
| 243 |
| 244 void WebMClusterParser::Track::Reset() { |
| 245 buffers_.clear(); |
312 } | 246 } |
313 | 247 |
314 } // namespace media | 248 } // namespace media |
OLD | NEW |