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

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: Rebase. Comments. 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 || !SetPendingBuffer(out_buffer))
1141 // Just return if GetNextBufferInternal() failed or there's no fade out
1142 // preroll, there's nothing else to do.
1143 if (status != SourceBufferStream::kSuccess ||
1144 (*out_buffer)->splice_buffers().empty()) {
1145 return status; 1141 return status;
1146 }
1147
1148 // Fall through into splice buffer processing.
1149 splice_buffers_index_ = 0;
1150 splice_buffer_.swap(*out_buffer);
1151 } 1142 }
1152 1143
1153 DCHECK(splice_buffer_); 1144 if (!pending_buffer_->splice_buffers().empty())
1154 const BufferQueue& splice_buffers = splice_buffer_->splice_buffers(); 1145 return HandleNextBufferWithSplice(out_buffer);
1146
1147 DCHECK(pending_buffer_->preroll_buffer());
1148 return HandleNextBufferWithPreroll(out_buffer);
1149 }
1150
1151 SourceBufferStream::Status SourceBufferStream::HandleNextBufferWithSplice(
1152 scoped_refptr<StreamParserBuffer>* out_buffer) {
1153 const BufferQueue& splice_buffers = pending_buffer_->splice_buffers();
1155 const size_t last_splice_buffer_index = splice_buffers.size() - 1; 1154 const size_t last_splice_buffer_index = splice_buffers.size() - 1;
1156 1155
1157 // Are there any splice buffers left to hand out? The last buffer should be 1156 // 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. 1157 // handed out separately since it represents the first post-splice buffer.
1159 if (splice_buffers_index_ < last_splice_buffer_index) { 1158 if (splice_buffers_index_ < last_splice_buffer_index) {
1160 // Account for config changes which occur between fade out buffers. 1159 // Account for config changes which occur between fade out buffers.
1161 if (current_config_index_ != 1160 if (current_config_index_ !=
1162 splice_buffers[splice_buffers_index_]->GetConfigId()) { 1161 splice_buffers[splice_buffers_index_]->GetConfigId()) {
1163 config_change_pending_ = true; 1162 config_change_pending_ = true;
1164 DVLOG(1) << "Config change (splice buffer config ID does not match)."; 1163 DVLOG(1) << "Config change (splice buffer config ID does not match).";
1165 return SourceBufferStream::kConfigChange; 1164 return SourceBufferStream::kConfigChange;
1166 } 1165 }
1167 1166
1168 // Every pre splice buffer must have the same splice_timestamp(). 1167 // Every pre splice buffer must have the same splice_timestamp().
1169 DCHECK(splice_buffer_->splice_timestamp() == 1168 DCHECK(pending_buffer_->splice_timestamp() ==
1170 splice_buffers[splice_buffers_index_]->splice_timestamp()); 1169 splice_buffers[splice_buffers_index_]->splice_timestamp());
1171 1170
1171 // No pre splice buffers should have preroll.
1172 DCHECK(!splice_buffers[splice_buffers_index_]->preroll_buffer());
1173
1172 *out_buffer = splice_buffers[splice_buffers_index_++]; 1174 *out_buffer = splice_buffers[splice_buffers_index_++];
1173 return SourceBufferStream::kSuccess; 1175 return SourceBufferStream::kSuccess;
1174 } 1176 }
1175 1177
1176 // Did we hand out the last pre-splice buffer on the previous call? 1178 // Did we hand out the last pre-splice buffer on the previous call?
1177 if (!pre_splice_complete_) { 1179 if (!pending_buffers_complete_) {
1178 DCHECK_EQ(splice_buffers_index_, last_splice_buffer_index); 1180 DCHECK_EQ(splice_buffers_index_, last_splice_buffer_index);
1179 pre_splice_complete_ = true; 1181 pending_buffers_complete_ = true;
1180 config_change_pending_ = true; 1182 config_change_pending_ = true;
1181 DVLOG(1) << "Config change (forced for fade in of splice frame)."; 1183 DVLOG(1) << "Config change (forced for fade in of splice frame).";
1182 return SourceBufferStream::kConfigChange; 1184 return SourceBufferStream::kConfigChange;
1183 } 1185 }
1184 1186
1185 // All pre-splice buffers have been handed out and a config change completed, 1187 // 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 1188 // 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 1189 // always issued prior to handing out this buffer, any changes in config id
1188 // have been inherently handled. 1190 // have been inherently handled.
1189 DCHECK(pre_splice_complete_); 1191 DCHECK(pending_buffers_complete_);
1190 DCHECK_EQ(splice_buffers_index_, splice_buffers.size() - 1); 1192 DCHECK_EQ(splice_buffers_index_, splice_buffers.size() - 1);
1191 DCHECK(splice_buffers.back()->splice_timestamp() == kNoTimestamp()); 1193 DCHECK(splice_buffers.back()->splice_timestamp() == kNoTimestamp());
1192 *out_buffer = splice_buffers.back(); 1194 *out_buffer = splice_buffers.back();
1193 splice_buffer_ = NULL; 1195 pending_buffer_ = NULL;
1194 splice_buffers_index_ = 0; 1196
1195 pre_splice_complete_ = false; 1197 // If the last splice buffer has preroll, hand off to the preroll handler.
1198 return SetPendingBuffer(out_buffer) ? HandleNextBufferWithPreroll(out_buffer)
1199 : SourceBufferStream::kSuccess;
1200 }
1201
1202 SourceBufferStream::Status SourceBufferStream::HandleNextBufferWithPreroll(
1203 scoped_refptr<StreamParserBuffer>* out_buffer) {
1204 // Any config change should have already been handled.
1205 DCHECK_EQ(current_config_index_, pending_buffer_->GetConfigId());
1206
1207 // Check if the preroll buffer has already been handed out.
1208 if (!pending_buffers_complete_) {
1209 pending_buffers_complete_ = true;
1210 *out_buffer = pending_buffer_->preroll_buffer();
1211 return SourceBufferStream::kSuccess;
1212 }
1213
1214 // Preroll complete, hand out the final buffer.
1215 *out_buffer = pending_buffer_;
1216 pending_buffer_ = NULL;
1196 return SourceBufferStream::kSuccess; 1217 return SourceBufferStream::kSuccess;
1197 } 1218 }
1198 1219
1199 SourceBufferStream::Status SourceBufferStream::GetNextBufferInternal( 1220 SourceBufferStream::Status SourceBufferStream::GetNextBufferInternal(
1200 scoped_refptr<StreamParserBuffer>* out_buffer) { 1221 scoped_refptr<StreamParserBuffer>* out_buffer) {
1201 CHECK(!config_change_pending_); 1222 CHECK(!config_change_pending_);
1202 1223
1203 if (!track_buffer_.empty()) { 1224 if (!track_buffer_.empty()) {
1204 DCHECK(!selected_range_); 1225 DCHECK(!selected_range_);
1205 scoped_refptr<StreamParserBuffer>& next_buffer = track_buffer_.front(); 1226 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(); 1442 append_config_index_ = video_configs_.size();
1422 DVLOG(2) << "New video config - index: " << append_config_index_; 1443 DVLOG(2) << "New video config - index: " << append_config_index_;
1423 video_configs_.resize(video_configs_.size() + 1); 1444 video_configs_.resize(video_configs_.size() + 1);
1424 video_configs_[append_config_index_] = config; 1445 video_configs_[append_config_index_] = config;
1425 return true; 1446 return true;
1426 } 1447 }
1427 1448
1428 void SourceBufferStream::CompleteConfigChange() { 1449 void SourceBufferStream::CompleteConfigChange() {
1429 config_change_pending_ = false; 1450 config_change_pending_ = false;
1430 1451
1431 if (splice_buffer_) { 1452 if (pending_buffer_) {
1432 current_config_index_ = 1453 current_config_index_ =
1433 GetConfigId(splice_buffer_, splice_buffers_index_); 1454 GetConfigId(pending_buffer_, splice_buffers_index_);
1434 return; 1455 return;
1435 } 1456 }
1436 1457
1437 if (!track_buffer_.empty()) { 1458 if (!track_buffer_.empty()) {
1438 current_config_index_ = GetConfigId(track_buffer_.front(), 0); 1459 current_config_index_ = GetConfigId(track_buffer_.front(), 0);
1439 return; 1460 return;
1440 } 1461 }
1441 1462
1442 if (selected_range_ && selected_range_->HasNextBuffer()) 1463 if (selected_range_ && selected_range_->HasNextBuffer())
1443 current_config_index_ = selected_range_->GetNextConfigId(); 1464 current_config_index_ = selected_range_->GetNextConfigId();
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
1630 1651
1631 // If there are gaps in the timeline, it's possible that we only find buffers 1652 // 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 1653 // after the splice point but within the splice range. For simplicity, we do
1633 // not generate splice frames in this case. 1654 // not generate splice frames in this case.
1634 // 1655 //
1635 // We also do not want to generate splices if the first new buffer replaces an 1656 // We also do not want to generate splices if the first new buffer replaces an
1636 // existing buffer exactly. 1657 // existing buffer exactly.
1637 if (pre_splice_buffers.front()->timestamp() >= splice_timestamp) 1658 if (pre_splice_buffers.front()->timestamp() >= splice_timestamp)
1638 return; 1659 return;
1639 1660
1640 // If any |pre_splice_buffers| are already splices, do not generate a splice. 1661 // If any |pre_splice_buffers| are already splices or preroll, do not generate
1662 // a splice.
1641 for (size_t i = 0; i < pre_splice_buffers.size(); ++i) { 1663 for (size_t i = 0; i < pre_splice_buffers.size(); ++i) {
1642 const BufferQueue& original_splice_buffers = 1664 const BufferQueue& original_splice_buffers =
1643 pre_splice_buffers[i]->splice_buffers(); 1665 pre_splice_buffers[i]->splice_buffers();
1644 if (!original_splice_buffers.empty()) { 1666 if (!original_splice_buffers.empty()) {
1645 DVLOG(1) << "Can't generate splice: overlapped buffers contain a " 1667 DVLOG(1) << "Can't generate splice: overlapped buffers contain a "
1646 "pre-existing splice."; 1668 "pre-existing splice.";
1647 return; 1669 return;
1648 } 1670 }
1671
1672 if (pre_splice_buffers[i]->preroll_buffer()) {
1673 DVLOG(1) << "Can't generate splice: overlapped buffers contain preroll.";
1674 return;
1675 }
1649 } 1676 }
1650 1677
1651 // Don't generate splice frames which represent less than two frames, since we 1678 // 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 1679 // need at least that much to generate a crossfade. Per the spec, make this
1653 // check using the sample rate of the overlapping buffers. 1680 // check using the sample rate of the overlapping buffers.
1654 const base::TimeDelta splice_duration = 1681 const base::TimeDelta splice_duration =
1655 pre_splice_buffers.back()->timestamp() + 1682 pre_splice_buffers.back()->timestamp() +
1656 pre_splice_buffers.back()->duration() - splice_timestamp; 1683 pre_splice_buffers.back()->duration() - splice_timestamp;
1657 const base::TimeDelta minimum_splice_duration = base::TimeDelta::FromSecondsD( 1684 const base::TimeDelta minimum_splice_duration = base::TimeDelta::FromSecondsD(
1658 2.0 / audio_configs_[append_config_index_].samples_per_second()); 1685 2.0 / audio_configs_[append_config_index_].samples_per_second());
(...skipping 531 matching lines...) Expand 10 before | Expand all | Expand 10 after
2190 } 2217 }
2191 if (buffer->end_of_stream() || buffer->timestamp() >= end) 2218 if (buffer->end_of_stream() || buffer->timestamp() >= end)
2192 break; 2219 break;
2193 if (buffer->timestamp() + buffer->duration() <= start) 2220 if (buffer->timestamp() + buffer->duration() <= start)
2194 continue; 2221 continue;
2195 buffers->push_back(buffer); 2222 buffers->push_back(buffer);
2196 } 2223 }
2197 return previous_size < buffers->size(); 2224 return previous_size < buffers->size();
2198 } 2225 }
2199 2226
2227 bool SourceBufferStream::SetPendingBuffer(
2228 scoped_refptr<StreamParserBuffer>* out_buffer) {
2229 DCHECK(*out_buffer);
2230 DCHECK(!pending_buffer_);
2231
2232 const bool have_splice_buffers = !(*out_buffer)->splice_buffers().empty();
2233 const bool have_preroll_buffer = (*out_buffer)->preroll_buffer();
2234
2235 if (!have_splice_buffers && !have_preroll_buffer)
2236 return false;
2237
2238 if (have_splice_buffers)
2239 DCHECK(!have_preroll_buffer);
2240
2241 if (have_preroll_buffer)
2242 DCHECK(!have_splice_buffers);
acolwell GONE FROM CHROMIUM 2014/05/23 17:27:30 I think something like DCHECK_NE(have_splice_buffe
DaleCurtis 2014/05/23 21:46:26 Done.
2243
2244 splice_buffers_index_ = 0;
2245 pending_buffer_.swap(*out_buffer);
2246 pending_buffers_complete_ = false;
2247 return true;
2248 }
2249
2200 } // namespace media 2250 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698