Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(225)

Side by Side Diff: media/filters/source_buffer_stream.cc

Issue 276573002: Add gapless playback support for AAC playback. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Now with tests! Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/filters/source_buffer_stream.h" 5 #include "media/filters/source_buffer_stream.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <map> 8 #include <map>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after
352 media_segment_start_time_(kNoTimestamp()), 352 media_segment_start_time_(kNoTimestamp()),
353 range_for_next_append_(ranges_.end()), 353 range_for_next_append_(ranges_.end()),
354 new_media_segment_(false), 354 new_media_segment_(false),
355 last_appended_buffer_timestamp_(kNoTimestamp()), 355 last_appended_buffer_timestamp_(kNoTimestamp()),
356 last_appended_buffer_is_keyframe_(false), 356 last_appended_buffer_is_keyframe_(false),
357 last_output_buffer_timestamp_(kNoTimestamp()), 357 last_output_buffer_timestamp_(kNoTimestamp()),
358 max_interbuffer_distance_(kNoTimestamp()), 358 max_interbuffer_distance_(kNoTimestamp()),
359 memory_limit_(kDefaultAudioMemoryLimit), 359 memory_limit_(kDefaultAudioMemoryLimit),
360 config_change_pending_(false), 360 config_change_pending_(false),
361 splice_buffers_index_(0), 361 splice_buffers_index_(0),
362 pre_splice_complete_(false), 362 pending_buffers_complete_(false),
363 splice_frames_enabled_(splice_frames_enabled) { 363 splice_frames_enabled_(splice_frames_enabled) {
364 DCHECK(audio_config.IsValidConfig()); 364 DCHECK(audio_config.IsValidConfig());
365 audio_configs_.push_back(audio_config); 365 audio_configs_.push_back(audio_config);
366 } 366 }
367 367
368 SourceBufferStream::SourceBufferStream(const VideoDecoderConfig& video_config, 368 SourceBufferStream::SourceBufferStream(const VideoDecoderConfig& video_config,
369 const LogCB& log_cb, 369 const LogCB& log_cb,
370 bool splice_frames_enabled) 370 bool splice_frames_enabled)
371 : log_cb_(log_cb), 371 : log_cb_(log_cb),
372 current_config_index_(0), 372 current_config_index_(0),
373 append_config_index_(0), 373 append_config_index_(0),
374 seek_pending_(false), 374 seek_pending_(false),
375 end_of_stream_(false), 375 end_of_stream_(false),
376 seek_buffer_timestamp_(kNoTimestamp()), 376 seek_buffer_timestamp_(kNoTimestamp()),
377 selected_range_(NULL), 377 selected_range_(NULL),
378 media_segment_start_time_(kNoTimestamp()), 378 media_segment_start_time_(kNoTimestamp()),
379 range_for_next_append_(ranges_.end()), 379 range_for_next_append_(ranges_.end()),
380 new_media_segment_(false), 380 new_media_segment_(false),
381 last_appended_buffer_timestamp_(kNoTimestamp()), 381 last_appended_buffer_timestamp_(kNoTimestamp()),
382 last_appended_buffer_is_keyframe_(false), 382 last_appended_buffer_is_keyframe_(false),
383 last_output_buffer_timestamp_(kNoTimestamp()), 383 last_output_buffer_timestamp_(kNoTimestamp()),
384 max_interbuffer_distance_(kNoTimestamp()), 384 max_interbuffer_distance_(kNoTimestamp()),
385 memory_limit_(kDefaultVideoMemoryLimit), 385 memory_limit_(kDefaultVideoMemoryLimit),
386 config_change_pending_(false), 386 config_change_pending_(false),
387 splice_buffers_index_(0), 387 splice_buffers_index_(0),
388 pre_splice_complete_(false), 388 pending_buffers_complete_(false),
389 splice_frames_enabled_(splice_frames_enabled) { 389 splice_frames_enabled_(splice_frames_enabled) {
390 DCHECK(video_config.IsValidConfig()); 390 DCHECK(video_config.IsValidConfig());
391 video_configs_.push_back(video_config); 391 video_configs_.push_back(video_config);
392 } 392 }
393 393
394 SourceBufferStream::SourceBufferStream(const TextTrackConfig& text_config, 394 SourceBufferStream::SourceBufferStream(const TextTrackConfig& text_config,
395 const LogCB& log_cb, 395 const LogCB& log_cb,
396 bool splice_frames_enabled) 396 bool splice_frames_enabled)
397 : log_cb_(log_cb), 397 : log_cb_(log_cb),
398 current_config_index_(0), 398 current_config_index_(0),
399 append_config_index_(0), 399 append_config_index_(0),
400 text_track_config_(text_config), 400 text_track_config_(text_config),
401 seek_pending_(false), 401 seek_pending_(false),
402 end_of_stream_(false), 402 end_of_stream_(false),
403 seek_buffer_timestamp_(kNoTimestamp()), 403 seek_buffer_timestamp_(kNoTimestamp()),
404 selected_range_(NULL), 404 selected_range_(NULL),
405 media_segment_start_time_(kNoTimestamp()), 405 media_segment_start_time_(kNoTimestamp()),
406 range_for_next_append_(ranges_.end()), 406 range_for_next_append_(ranges_.end()),
407 new_media_segment_(false), 407 new_media_segment_(false),
408 last_appended_buffer_timestamp_(kNoTimestamp()), 408 last_appended_buffer_timestamp_(kNoTimestamp()),
409 last_appended_buffer_is_keyframe_(false), 409 last_appended_buffer_is_keyframe_(false),
410 last_output_buffer_timestamp_(kNoTimestamp()), 410 last_output_buffer_timestamp_(kNoTimestamp()),
411 max_interbuffer_distance_(kNoTimestamp()), 411 max_interbuffer_distance_(kNoTimestamp()),
412 memory_limit_(kDefaultAudioMemoryLimit), 412 memory_limit_(kDefaultAudioMemoryLimit),
413 config_change_pending_(false), 413 config_change_pending_(false),
414 splice_buffers_index_(0), 414 splice_buffers_index_(0),
415 pre_splice_complete_(false), 415 pending_buffers_complete_(false),
416 splice_frames_enabled_(splice_frames_enabled) {} 416 splice_frames_enabled_(splice_frames_enabled) {}
417 417
418 SourceBufferStream::~SourceBufferStream() { 418 SourceBufferStream::~SourceBufferStream() {
419 while (!ranges_.empty()) { 419 while (!ranges_.empty()) {
420 delete ranges_.front(); 420 delete ranges_.front();
421 ranges_.pop_front(); 421 ranges_.pop_front();
422 } 422 }
423 } 423 }
424 424
425 void SourceBufferStream::OnNewMediaSegment( 425 void SourceBufferStream::OnNewMediaSegment(
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after
686 DCHECK(OnlySelectedRangeIsSeeked()); 686 DCHECK(OnlySelectedRangeIsSeeked());
687 DVLOG(1) << __FUNCTION__ << " : done"; 687 DVLOG(1) << __FUNCTION__ << " : done";
688 } 688 }
689 689
690 void SourceBufferStream::ResetSeekState() { 690 void SourceBufferStream::ResetSeekState() {
691 SetSelectedRange(NULL); 691 SetSelectedRange(NULL);
692 track_buffer_.clear(); 692 track_buffer_.clear();
693 config_change_pending_ = false; 693 config_change_pending_ = false;
694 last_output_buffer_timestamp_ = kNoTimestamp(); 694 last_output_buffer_timestamp_ = kNoTimestamp();
695 splice_buffers_index_ = 0; 695 splice_buffers_index_ = 0;
696 splice_buffer_ = NULL; 696 pending_buffer_ = NULL;
697 pre_splice_complete_ = false; 697 pending_buffers_complete_ = false;
698 } 698 }
699 699
700 bool SourceBufferStream::ShouldSeekToStartOfBuffered( 700 bool SourceBufferStream::ShouldSeekToStartOfBuffered(
701 base::TimeDelta seek_timestamp) const { 701 base::TimeDelta seek_timestamp) const {
702 if (ranges_.empty()) 702 if (ranges_.empty())
703 return false; 703 return false;
704 base::TimeDelta beginning_of_buffered = 704 base::TimeDelta beginning_of_buffered =
705 ranges_.front()->GetStartTimestamp(); 705 ranges_.front()->GetStartTimestamp();
706 return (seek_timestamp <= beginning_of_buffered && 706 return (seek_timestamp <= beginning_of_buffered &&
707 beginning_of_buffered < kSeekToStartFudgeRoom()); 707 beginning_of_buffered < kSeekToStartFudgeRoom());
(...skipping 420 matching lines...) Expand 10 before | Expand all | Expand 10 after
1128 // If we're about to delete the selected range, also reset the seek state. 1128 // If we're about to delete the selected range, also reset the seek state.
1129 DCHECK((*itr)->GetStartTimestamp() >= duration); 1129 DCHECK((*itr)->GetStartTimestamp() >= duration);
1130 if (*itr == selected_range_) 1130 if (*itr == selected_range_)
1131 ResetSeekState(); 1131 ResetSeekState();
1132 DeleteAndRemoveRange(&itr); 1132 DeleteAndRemoveRange(&itr);
1133 } 1133 }
1134 } 1134 }
1135 1135
1136 SourceBufferStream::Status SourceBufferStream::GetNextBuffer( 1136 SourceBufferStream::Status SourceBufferStream::GetNextBuffer(
1137 scoped_refptr<StreamParserBuffer>* out_buffer) { 1137 scoped_refptr<StreamParserBuffer>* out_buffer) {
1138 if (!splice_buffer_) { 1138 if (!pending_buffer_) {
1139 const SourceBufferStream::Status status = GetNextBufferInternal(out_buffer); 1139 const SourceBufferStream::Status status = GetNextBufferInternal(out_buffer);
1140 1140 if (status == SourceBufferStream::kSuccess) {
1141 // Just return if GetNextBufferInternal() failed or there's no fade out 1141 if (!(*out_buffer)->get_splice_buffers().empty())
1142 // preroll, there's nothing else to do. 1142 return HandleNextBufferWithSplice(out_buffer);
1143 if (status != SourceBufferStream::kSuccess || 1143 if ((*out_buffer)->GetPrerollBuffer())
1144 (*out_buffer)->get_splice_buffers().empty()) { 1144 return HandleNextBufferWithPreroll(out_buffer);
1145 return status;
1146 } 1145 }
1147 1146 return status;
1148 // Fall through into splice buffer processing.
1149 splice_buffers_index_ = 0;
1150 splice_buffer_.swap(*out_buffer);
1151 } 1147 }
1152 1148
1153 DCHECK(splice_buffer_); 1149 if (!pending_buffer_->get_splice_buffers().empty())
1154 const BufferQueue& splice_buffers = splice_buffer_->get_splice_buffers(); 1150 return HandleNextBufferWithSplice(out_buffer);
1151
1152 DCHECK(pending_buffer_->GetPrerollBuffer());
1153 return HandleNextBufferWithPreroll(out_buffer);
1154 }
1155
1156 SourceBufferStream::Status SourceBufferStream::HandleNextBufferWithSplice(
1157 scoped_refptr<StreamParserBuffer>* out_buffer) {
1158 if (!pending_buffer_) {
acolwell GONE FROM CHROMIUM 2014/05/16 17:01:11 It seems weird to have this here. Why not put this
DaleCurtis 2014/05/16 17:48:59 This is done for consistency with the HandleNextBu
acolwell GONE FROM CHROMIUM 2014/05/16 20:26:05 I think the setting logic should be extracted into
DaleCurtis 2014/05/22 23:58:57 Done.
1159 DCHECK(*out_buffer);
1160 DCHECK(!(*out_buffer)->get_splice_buffers().empty());
1161 splice_buffers_index_ = 0;
1162 pending_buffer_.swap(*out_buffer);
1163 pending_buffers_complete_ = false;
1164 }
1165
1166 const BufferQueue& splice_buffers = pending_buffer_->get_splice_buffers();
1155 const size_t last_splice_buffer_index = splice_buffers.size() - 1; 1167 const size_t last_splice_buffer_index = splice_buffers.size() - 1;
1156 1168
1157 // Are there any splice buffers left to hand out? The last buffer should be 1169 // Are there any splice buffers left to hand out? The last buffer should be
1158 // handed out separately since it represents the first post-splice buffer. 1170 // handed out separately since it represents the first post-splice buffer.
1159 if (splice_buffers_index_ < last_splice_buffer_index) { 1171 if (splice_buffers_index_ < last_splice_buffer_index) {
1160 // Account for config changes which occur between fade out buffers. 1172 // Account for config changes which occur between fade out buffers.
1161 if (current_config_index_ != 1173 if (current_config_index_ !=
1162 splice_buffers[splice_buffers_index_]->GetConfigId()) { 1174 splice_buffers[splice_buffers_index_]->GetConfigId()) {
1163 config_change_pending_ = true; 1175 config_change_pending_ = true;
1164 DVLOG(1) << "Config change (splice buffer config ID does not match)."; 1176 DVLOG(1) << "Config change (splice buffer config ID does not match).";
1165 return SourceBufferStream::kConfigChange; 1177 return SourceBufferStream::kConfigChange;
1166 } 1178 }
1167 1179
1168 // Every pre splice buffer must have the same splice_timestamp(). 1180 // Every pre splice buffer must have the same splice_timestamp().
1169 DCHECK(splice_buffer_->splice_timestamp() == 1181 DCHECK(pending_buffer_->splice_timestamp() ==
1170 splice_buffers[splice_buffers_index_]->splice_timestamp()); 1182 splice_buffers[splice_buffers_index_]->splice_timestamp());
1171 1183
1184 // No pre splice buffers should have preroll.
1185 DCHECK(!splice_buffers[splice_buffers_index_]->GetPrerollBuffer());
1186
1172 *out_buffer = splice_buffers[splice_buffers_index_++]; 1187 *out_buffer = splice_buffers[splice_buffers_index_++];
1173 return SourceBufferStream::kSuccess; 1188 return SourceBufferStream::kSuccess;
1174 } 1189 }
1175 1190
1176 // Did we hand out the last pre-splice buffer on the previous call? 1191 // Did we hand out the last pre-splice buffer on the previous call?
1177 if (!pre_splice_complete_) { 1192 if (!pending_buffers_complete_) {
1178 DCHECK_EQ(splice_buffers_index_, last_splice_buffer_index); 1193 DCHECK_EQ(splice_buffers_index_, last_splice_buffer_index);
1179 pre_splice_complete_ = true; 1194 pending_buffers_complete_ = true;
1180 config_change_pending_ = true; 1195 config_change_pending_ = true;
1181 DVLOG(1) << "Config change (forced for fade in of splice frame)."; 1196 DVLOG(1) << "Config change (forced for fade in of splice frame).";
1182 return SourceBufferStream::kConfigChange; 1197 return SourceBufferStream::kConfigChange;
1183 } 1198 }
1184 1199
1185 // All pre-splice buffers have been handed out and a config change completed, 1200 // All pre-splice buffers have been handed out and a config change completed,
1186 // so hand out the final buffer for fade in. Because a config change is 1201 // so hand out the final buffer for fade in. Because a config change is
1187 // always issued prior to handing out this buffer, any changes in config id 1202 // always issued prior to handing out this buffer, any changes in config id
1188 // have been inherently handled. 1203 // have been inherently handled.
1189 DCHECK(pre_splice_complete_); 1204 DCHECK(pending_buffers_complete_);
1190 DCHECK_EQ(splice_buffers_index_, splice_buffers.size() - 1); 1205 DCHECK_EQ(splice_buffers_index_, splice_buffers.size() - 1);
1191 DCHECK(splice_buffers.back()->splice_timestamp() == kNoTimestamp()); 1206 DCHECK(splice_buffers.back()->splice_timestamp() == kNoTimestamp());
1192 *out_buffer = splice_buffers.back(); 1207 *out_buffer = splice_buffers.back();
1193 splice_buffer_ = NULL; 1208 pending_buffer_ = NULL;
1194 splice_buffers_index_ = 0; 1209 splice_buffers_index_ = 0;
1195 pre_splice_complete_ = false; 1210
1211 // If the last splice buffer has preroll hand off to the preroll handler.
1212 return (*out_buffer)->GetPrerollBuffer()
1213 ? HandleNextBufferWithPreroll(out_buffer)
1214 : SourceBufferStream::kSuccess;
1215 }
1216
1217 SourceBufferStream::Status SourceBufferStream::HandleNextBufferWithPreroll(
1218 scoped_refptr<StreamParserBuffer>* out_buffer) {
1219 if (!pending_buffer_) {
1220 DCHECK(*out_buffer);
1221 DCHECK((*out_buffer)->GetPrerollBuffer());
1222 pending_buffer_.swap(*out_buffer);
acolwell GONE FROM CHROMIUM 2014/05/16 17:01:11 This seems odd as well. I think the setting operat
DaleCurtis 2014/05/16 17:48:59 As detailed above.
DaleCurtis 2014/05/22 23:58:57 Done.
1223 pending_buffers_complete_ = false;
1224 }
1225
1226 // The preroll buffer should not be a splice buffer.
1227 DCHECK(pending_buffer_->get_splice_buffers().empty());
wolenetz 2014/05/17 00:41:17 nit: is it worth adding DCHECK_EQ(0, splice_buffer
DaleCurtis 2014/05/22 23:58:57 Moved into SetPendingBuffer().
wolenetz 2014/05/23 19:59:45 The set is moved into SetPendingBuffer(), though t
1228
1229 // Any config change should have already been handled.
1230 DCHECK_EQ(current_config_index_, pending_buffer_->GetConfigId());
1231
1232 // Check if the preroll buffer has already been handed out.
1233 if (!pending_buffers_complete_) {
1234 pending_buffers_complete_ = true;
1235 *out_buffer = pending_buffer_->GetPrerollBuffer();
1236 return SourceBufferStream::kSuccess;
1237 }
1238
1239 // Preroll complete, hand out the final buffer.
1240 *out_buffer = pending_buffer_;
1241 pending_buffer_ = NULL;
1196 return SourceBufferStream::kSuccess; 1242 return SourceBufferStream::kSuccess;
1197 } 1243 }
1198 1244
1199 SourceBufferStream::Status SourceBufferStream::GetNextBufferInternal( 1245 SourceBufferStream::Status SourceBufferStream::GetNextBufferInternal(
1200 scoped_refptr<StreamParserBuffer>* out_buffer) { 1246 scoped_refptr<StreamParserBuffer>* out_buffer) {
1201 CHECK(!config_change_pending_); 1247 CHECK(!config_change_pending_);
1202 1248
1203 if (!track_buffer_.empty()) { 1249 if (!track_buffer_.empty()) {
1204 DCHECK(!selected_range_); 1250 DCHECK(!selected_range_);
1205 scoped_refptr<StreamParserBuffer>& next_buffer = track_buffer_.front(); 1251 scoped_refptr<StreamParserBuffer>& next_buffer = track_buffer_.front();
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
1421 append_config_index_ = video_configs_.size(); 1467 append_config_index_ = video_configs_.size();
1422 DVLOG(2) << "New video config - index: " << append_config_index_; 1468 DVLOG(2) << "New video config - index: " << append_config_index_;
1423 video_configs_.resize(video_configs_.size() + 1); 1469 video_configs_.resize(video_configs_.size() + 1);
1424 video_configs_[append_config_index_] = config; 1470 video_configs_[append_config_index_] = config;
1425 return true; 1471 return true;
1426 } 1472 }
1427 1473
1428 void SourceBufferStream::CompleteConfigChange() { 1474 void SourceBufferStream::CompleteConfigChange() {
1429 config_change_pending_ = false; 1475 config_change_pending_ = false;
1430 1476
1431 if (splice_buffer_) { 1477 if (pending_buffer_) {
1432 current_config_index_ = 1478 current_config_index_ =
1433 GetConfigId(splice_buffer_, splice_buffers_index_); 1479 GetConfigId(pending_buffer_, splice_buffers_index_);
1434 return; 1480 return;
1435 } 1481 }
1436 1482
1437 if (!track_buffer_.empty()) { 1483 if (!track_buffer_.empty()) {
1438 current_config_index_ = GetConfigId(track_buffer_.front(), 0); 1484 current_config_index_ = GetConfigId(track_buffer_.front(), 0);
1439 return; 1485 return;
1440 } 1486 }
1441 1487
1442 if (selected_range_ && selected_range_->HasNextBuffer()) 1488 if (selected_range_ && selected_range_->HasNextBuffer())
1443 current_config_index_ = selected_range_->GetNextConfigId(); 1489 current_config_index_ = selected_range_->GetNextConfigId();
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
1630 1676
1631 // If there are gaps in the timeline, it's possible that we only find buffers 1677 // If there are gaps in the timeline, it's possible that we only find buffers
1632 // after the splice point but within the splice range. For simplicity, we do 1678 // after the splice point but within the splice range. For simplicity, we do
1633 // not generate splice frames in this case. 1679 // not generate splice frames in this case.
1634 // 1680 //
1635 // We also do not want to generate splices if the first new buffer replaces an 1681 // We also do not want to generate splices if the first new buffer replaces an
1636 // existing buffer exactly. 1682 // existing buffer exactly.
1637 if (pre_splice_buffers.front()->timestamp() >= splice_timestamp) 1683 if (pre_splice_buffers.front()->timestamp() >= splice_timestamp)
1638 return; 1684 return;
1639 1685
1640 // If any |pre_splice_buffers| are already splices, do not generate a splice. 1686 // If any |pre_splice_buffers| are already splices or preroll, do not generate
1687 // a splice.
1641 for (size_t i = 0; i < pre_splice_buffers.size(); ++i) { 1688 for (size_t i = 0; i < pre_splice_buffers.size(); ++i) {
1642 const BufferQueue& original_splice_buffers = 1689 const BufferQueue& original_splice_buffers =
1643 pre_splice_buffers[i]->get_splice_buffers(); 1690 pre_splice_buffers[i]->get_splice_buffers();
1644 if (!original_splice_buffers.empty()) { 1691 if (!original_splice_buffers.empty()) {
1645 DVLOG(1) << "Can't generate splice: overlapped buffers contain a " 1692 DVLOG(1) << "Can't generate splice: overlapped buffers contain a "
1646 "pre-existing splice."; 1693 "pre-existing splice.";
1647 return; 1694 return;
1648 } 1695 }
1696
1697 if (pre_splice_buffers[i]->GetPrerollBuffer()) {
1698 DVLOG(1) << "Can't generate splice: overlapped buffers contain preroll.";
1699 return;
1700 }
1649 } 1701 }
1650 1702
1651 // Don't generate splice frames which represent less than two frames, since we 1703 // Don't generate splice frames which represent less than two frames, since we
1652 // need at least that much to generate a crossfade. Per the spec, make this 1704 // need at least that much to generate a crossfade. Per the spec, make this
1653 // check using the sample rate of the overlapping buffers. 1705 // check using the sample rate of the overlapping buffers.
1654 const base::TimeDelta splice_duration = 1706 const base::TimeDelta splice_duration =
1655 pre_splice_buffers.back()->timestamp() + 1707 pre_splice_buffers.back()->timestamp() +
1656 pre_splice_buffers.back()->duration() - splice_timestamp; 1708 pre_splice_buffers.back()->duration() - splice_timestamp;
1657 const base::TimeDelta minimum_splice_duration = base::TimeDelta::FromSecondsD( 1709 const base::TimeDelta minimum_splice_duration = base::TimeDelta::FromSecondsD(
1658 2.0 / audio_configs_[append_config_index_].samples_per_second()); 1710 2.0 / audio_configs_[append_config_index_].samples_per_second());
(...skipping 532 matching lines...) Expand 10 before | Expand all | Expand 10 after
2191 if (buffer->end_of_stream() || buffer->timestamp() >= end) 2243 if (buffer->end_of_stream() || buffer->timestamp() >= end)
2192 break; 2244 break;
2193 if (buffer->timestamp() + buffer->duration() <= start) 2245 if (buffer->timestamp() + buffer->duration() <= start)
2194 continue; 2246 continue;
2195 buffers->push_back(buffer); 2247 buffers->push_back(buffer);
2196 } 2248 }
2197 return previous_size < buffers->size(); 2249 return previous_size < buffers->size();
2198 } 2250 }
2199 2251
2200 } // namespace media 2252 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698