1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "media/filters/source_buffer_range.h" 6 7 #include <algorithm> 8 9 namespace media { 10 11 // Comparison operators for std::upper_bound() and std::lower_bound(). 12 static bool CompareTimeDeltaToStreamParserBuffer( 13 const DecodeTimestamp& decode_timestamp, 14 const scoped_refptr<StreamParserBuffer>& buffer) { 15 return decode_timestamp < buffer->GetDecodeTimestamp(); 16 } 17 static bool CompareStreamParserBufferToTimeDelta( 18 const scoped_refptr<StreamParserBuffer>& buffer, 19 const DecodeTimestamp& decode_timestamp) { 20 return buffer->GetDecodeTimestamp() < decode_timestamp; 21 } 22 23 bool SourceBufferRange::AllowSameTimestamp( 24 bool prev_is_keyframe, bool current_is_keyframe) { 25 return prev_is_keyframe || !current_is_keyframe; 26 } 27 28 SourceBufferRange::SourceBufferRange( 29 GapPolicy gap_policy, const BufferQueue& new_buffers, 30 DecodeTimestamp media_segment_start_time, 31 const InterbufferDistanceCB& interbuffer_distance_cb) 32 : gap_policy_(gap_policy), 33 keyframe_map_index_base_(0), 34 next_buffer_index_(-1), 35 media_segment_start_time_(media_segment_start_time), 36 interbuffer_distance_cb_(interbuffer_distance_cb), 37 size_in_bytes_(0) { 38 CHECK(!new_buffers.empty()); 39 DCHECK(new_buffers.front()->IsKeyframe()); 40 DCHECK(!interbuffer_distance_cb.is_null()); 41 AppendBuffersToEnd(new_buffers); 42 } 43 44 SourceBufferRange::~SourceBufferRange() {} 45 46 void SourceBufferRange::AppendBuffersToEnd(const BufferQueue& new_buffers) { 47 DCHECK(buffers_.empty() || CanAppendBuffersToEnd(new_buffers)); 48 DCHECK(media_segment_start_time_ == kNoDecodeTimestamp() || 49 media_segment_start_time_ <= 50 new_buffers.front()->GetDecodeTimestamp()); 51 for (BufferQueue::const_iterator itr = new_buffers.begin(); 52 itr != new_buffers.end(); 53 ++itr) { 54 DCHECK((*itr)->GetDecodeTimestamp() != kNoDecodeTimestamp()); 55 buffers_.push_back(*itr); 56 size_in_bytes_ += (*itr)->data_size(); 57 58 if ((*itr)->IsKeyframe()) { 59 keyframe_map_.insert( 60 std::make_pair((*itr)->GetDecodeTimestamp(), 61 buffers_.size() - 1 + keyframe_map_index_base_)); 62 } 63 } 64 } 65 66 void SourceBufferRange::Seek(DecodeTimestamp timestamp) { 67 DCHECK(CanSeekTo(timestamp)); 68 DCHECK(!keyframe_map_.empty()); 69 70 KeyframeMap::iterator result = GetFirstKeyframeBefore(timestamp); 71 next_buffer_index_ = result->second - keyframe_map_index_base_; 72 DCHECK_LT(next_buffer_index_, static_cast<int>(buffers_.size())); 73 } 74 75 void SourceBufferRange::SeekAheadTo(DecodeTimestamp timestamp) { 76 SeekAhead(timestamp, false); 77 } 78 79 void SourceBufferRange::SeekAheadPast(DecodeTimestamp timestamp) { 80 SeekAhead(timestamp, true); 81 } 82 83 void SourceBufferRange::SeekAhead(DecodeTimestamp timestamp, 84 bool skip_given_timestamp) { 85 DCHECK(!keyframe_map_.empty()); 86 87 KeyframeMap::iterator result = 88 GetFirstKeyframeAt(timestamp, skip_given_timestamp); 89 90 // If there isn't a keyframe after |timestamp|, then seek to end and return 91 // kNoTimestamp to signal such. 92 if (result == keyframe_map_.end()) { 93 next_buffer_index_ = -1; 94 return; 95 } 96 next_buffer_index_ = result->second - keyframe_map_index_base_; 97 DCHECK_LT(next_buffer_index_, static_cast<int>(buffers_.size())); 98 } 99 100 void SourceBufferRange::SeekToStart() { 101 DCHECK(!buffers_.empty()); 102 next_buffer_index_ = 0; 103 } 104 105 SourceBufferRange* SourceBufferRange::SplitRange( 106 DecodeTimestamp timestamp, bool is_exclusive) { 107 CHECK(!buffers_.empty()); 108 109 // Find the first keyframe after |timestamp|. If |is_exclusive|, do not 110 // include keyframes at |timestamp|. 111 KeyframeMap::iterator new_beginning_keyframe = 112 GetFirstKeyframeAt(timestamp, is_exclusive); 113 114 // If there is no keyframe after |timestamp|, we can't split the range. 115 if (new_beginning_keyframe == keyframe_map_.end()) 116 return NULL; 117 118 // Remove the data beginning at |keyframe_index| from |buffers_| and save it 119 // into |removed_buffers|. 120 int keyframe_index = 121 new_beginning_keyframe->second - keyframe_map_index_base_; 122 DCHECK_LT(keyframe_index, static_cast<int>(buffers_.size())); 123 BufferQueue::iterator starting_point = buffers_.begin() + keyframe_index; 124 BufferQueue removed_buffers(starting_point, buffers_.end()); 125 126 DecodeTimestamp new_range_start_timestamp = kNoDecodeTimestamp(); 127 if (GetStartTimestamp() < buffers_.front()->GetDecodeTimestamp() && 128 timestamp < removed_buffers.front()->GetDecodeTimestamp()) { 129 // The split is in the gap between |media_segment_start_time_| and 130 // the first buffer of the new range so we should set the start 131 // time of the new range to |timestamp| so we preserve part of the 132 // gap in the new range. 133 new_range_start_timestamp = timestamp; 134 } 135 136 keyframe_map_.erase(new_beginning_keyframe, keyframe_map_.end()); 137 FreeBufferRange(starting_point, buffers_.end()); 138 139 // Create a new range with |removed_buffers|. 140 SourceBufferRange* split_range = 141 new SourceBufferRange( 142 gap_policy_, removed_buffers, new_range_start_timestamp, 143 interbuffer_distance_cb_); 144 145 // If the next buffer position is now in |split_range|, update the state of 146 // this range and |split_range| accordingly. 147 if (next_buffer_index_ >= static_cast<int>(buffers_.size())) { 148 split_range->next_buffer_index_ = next_buffer_index_ - keyframe_index; 149 ResetNextBufferPosition(); 150 } 151 152 return split_range; 153 } 154 155 SourceBufferRange::BufferQueue::iterator SourceBufferRange::GetBufferItrAt( 156 DecodeTimestamp timestamp, 157 bool skip_given_timestamp) { 158 return skip_given_timestamp 159 ? std::upper_bound(buffers_.begin(), 160 buffers_.end(), 161 timestamp, 162 CompareTimeDeltaToStreamParserBuffer) 163 : std::lower_bound(buffers_.begin(), 164 buffers_.end(), 165 timestamp, 166 CompareStreamParserBufferToTimeDelta); 167 } 168 169 SourceBufferRange::KeyframeMap::iterator 170 SourceBufferRange::GetFirstKeyframeAt(DecodeTimestamp timestamp, 171 bool skip_given_timestamp) { 172 return skip_given_timestamp ? 173 keyframe_map_.upper_bound(timestamp) : 174 keyframe_map_.lower_bound(timestamp); 175 } 176 177 SourceBufferRange::KeyframeMap::iterator 178 SourceBufferRange::GetFirstKeyframeBefore(DecodeTimestamp timestamp) { 179 KeyframeMap::iterator result = keyframe_map_.lower_bound(timestamp); 180 // lower_bound() returns the first element >= |timestamp|, so we want the 181 // previous element if it did not return the element exactly equal to 182 // |timestamp|. 183 if (result != keyframe_map_.begin() && 184 (result == keyframe_map_.end() || result->first != timestamp)) { 185 --result; 186 } 187 return result; 188 } 189 190 void SourceBufferRange::DeleteAll(BufferQueue* removed_buffers) { 191 TruncateAt(buffers_.begin(), removed_buffers); 192 } 193 194 bool SourceBufferRange::TruncateAt( 195 DecodeTimestamp timestamp, BufferQueue* removed_buffers, 196 bool is_exclusive) { 197 // Find the place in |buffers_| where we will begin deleting data. 198 BufferQueue::iterator starting_point = 199 GetBufferItrAt(timestamp, is_exclusive); 200 return TruncateAt(starting_point, removed_buffers); 201 } 202 203 int SourceBufferRange::DeleteGOPFromFront(BufferQueue* deleted_buffers) { 204 DCHECK(!FirstGOPContainsNextBufferPosition()); 205 DCHECK(deleted_buffers); 206 207 int buffers_deleted = 0; 208 int total_bytes_deleted = 0; 209 210 KeyframeMap::iterator front = keyframe_map_.begin(); 211 DCHECK(front != keyframe_map_.end()); 212 213 // Delete the keyframe at the start of |keyframe_map_|. 214 keyframe_map_.erase(front); 215 216 // Now we need to delete all the buffers that depend on the keyframe we've 217 // just deleted. 218 int end_index = keyframe_map_.size() > 0 ? 219 keyframe_map_.begin()->second - keyframe_map_index_base_ : 220 buffers_.size(); 221 222 // Delete buffers from the beginning of the buffered range up until (but not 223 // including) the next keyframe. 224 for (int i = 0; i < end_index; i++) { 225 int bytes_deleted = buffers_.front()->data_size(); 226 size_in_bytes_ -= bytes_deleted; 227 total_bytes_deleted += bytes_deleted; 228 deleted_buffers->push_back(buffers_.front()); 229 buffers_.pop_front(); 230 ++buffers_deleted; 231 } 232 233 // Update |keyframe_map_index_base_| to account for the deleted buffers. 234 keyframe_map_index_base_ += buffers_deleted; 235 236 if (next_buffer_index_ > -1) { 237 next_buffer_index_ -= buffers_deleted; 238 DCHECK_GE(next_buffer_index_, 0); 239 } 240 241 // Invalidate media segment start time if we've deleted the first buffer of 242 // the range. 243 if (buffers_deleted > 0) 244 media_segment_start_time_ = kNoDecodeTimestamp(); 245 246 return total_bytes_deleted; 247 } 248 249 int SourceBufferRange::DeleteGOPFromBack(BufferQueue* deleted_buffers) { 250 DCHECK(!LastGOPContainsNextBufferPosition()); 251 DCHECK(deleted_buffers); 252 253 // Remove the last GOP's keyframe from the |keyframe_map_|. 254 KeyframeMap::iterator back = keyframe_map_.end(); 255 DCHECK_GT(keyframe_map_.size(), 0u); 256 --back; 257 258 // The index of the first buffer in the last GOP is equal to the new size of 259 // |buffers_| after that GOP is deleted. 260 size_t goal_size = back->second - keyframe_map_index_base_; 261 keyframe_map_.erase(back); 262 263 int total_bytes_deleted = 0; 264 while (buffers_.size() != goal_size) { 265 int bytes_deleted = buffers_.back()->data_size(); 266 size_in_bytes_ -= bytes_deleted; 267 total_bytes_deleted += bytes_deleted; 268 // We're removing buffers from the back, so push each removed buffer to the 269 // front of |deleted_buffers| so that |deleted_buffers| are in nondecreasing 270 // order. 271 deleted_buffers->push_front(buffers_.back()); 272 buffers_.pop_back(); 273 } 274 275 return total_bytes_deleted; 276 } 277 278 int SourceBufferRange::GetRemovalGOP( 279 DecodeTimestamp start_timestamp, DecodeTimestamp end_timestamp, 280 int total_bytes_to_free, DecodeTimestamp* removal_end_timestamp) { 281 int bytes_to_free = total_bytes_to_free; 282 int bytes_removed = 0; 283 284 KeyframeMap::iterator gop_itr = GetFirstKeyframeAt(start_timestamp, false); 285 if (gop_itr == keyframe_map_.end()) 286 return 0; 287 int keyframe_index = gop_itr->second - keyframe_map_index_base_; 288 BufferQueue::iterator buffer_itr = buffers_.begin() + keyframe_index; 289 KeyframeMap::iterator gop_end = keyframe_map_.end(); 290 if (end_timestamp < GetBufferedEndTimestamp()) 291 gop_end = GetFirstKeyframeBefore(end_timestamp); 292 293 // Check if the removal range is within a GOP and skip the loop if so. 294 // [keyframe]...[start_timestamp]...[end_timestamp]...[keyframe] 295 KeyframeMap::iterator gop_itr_prev = gop_itr; 296 if (gop_itr_prev != keyframe_map_.begin() && --gop_itr_prev == gop_end) 297 gop_end = gop_itr; 298 299 while (gop_itr != gop_end && bytes_to_free > 0) { 300 ++gop_itr; 301 302 int gop_size = 0; 303 int next_gop_index = gop_itr == keyframe_map_.end() ? 304 buffers_.size() : gop_itr->second - keyframe_map_index_base_; 305 BufferQueue::iterator next_gop_start = buffers_.begin() + next_gop_index; 306 for (; buffer_itr != next_gop_start; ++buffer_itr) 307 gop_size += (*buffer_itr)->data_size(); 308 309 bytes_removed += gop_size; 310 bytes_to_free -= gop_size; 311 } 312 if (bytes_removed > 0) { 313 *removal_end_timestamp = gop_itr == keyframe_map_.end() ? 314 GetBufferedEndTimestamp() : gop_itr->first; 315 } 316 return bytes_removed; 317 } 318 319 bool SourceBufferRange::FirstGOPContainsNextBufferPosition() const { 320 if (!HasNextBufferPosition()) 321 return false; 322 323 // If there is only one GOP, it must contain the next buffer position. 324 if (keyframe_map_.size() == 1u) 325 return true; 326 327 KeyframeMap::const_iterator second_gop = keyframe_map_.begin(); 328 ++second_gop; 329 return next_buffer_index_ < second_gop->second - keyframe_map_index_base_; 330 } 331 332 bool SourceBufferRange::LastGOPContainsNextBufferPosition() const { 333 if (!HasNextBufferPosition()) 334 return false; 335 336 // If there is only one GOP, it must contain the next buffer position. 337 if (keyframe_map_.size() == 1u) 338 return true; 339 340 KeyframeMap::const_iterator last_gop = keyframe_map_.end(); 341 --last_gop; 342 return last_gop->second - keyframe_map_index_base_ <= next_buffer_index_; 343 } 344 345 void SourceBufferRange::FreeBufferRange( 346 const BufferQueue::iterator& starting_point, 347 const BufferQueue::iterator& ending_point) { 348 for (BufferQueue::iterator itr = starting_point; 349 itr != ending_point; ++itr) { 350 size_in_bytes_ -= (*itr)->data_size(); 351 DCHECK_GE(size_in_bytes_, 0); 352 } 353 buffers_.erase(starting_point, ending_point); 354 } 355 356 bool SourceBufferRange::TruncateAt( 357 const BufferQueue::iterator& starting_point, BufferQueue* removed_buffers) { 358 DCHECK(!removed_buffers || removed_buffers->empty()); 359 360 // Return if we're not deleting anything. 361 if (starting_point == buffers_.end()) 362 return buffers_.empty(); 363 364 // Reset the next buffer index if we will be deleting the buffer that's next 365 // in sequence. 366 if (HasNextBufferPosition()) { 367 DecodeTimestamp next_buffer_timestamp = GetNextTimestamp(); 368 if (next_buffer_timestamp == kNoDecodeTimestamp() || 369 next_buffer_timestamp >= (*starting_point)->GetDecodeTimestamp()) { 370 if (HasNextBuffer() && removed_buffers) { 371 int starting_offset = starting_point - buffers_.begin(); 372 int next_buffer_offset = next_buffer_index_ - starting_offset; 373 DCHECK_GE(next_buffer_offset, 0); 374 BufferQueue saved(starting_point + next_buffer_offset, buffers_.end()); 375 removed_buffers->swap(saved); 376 } 377 ResetNextBufferPosition(); 378 } 379 } 380 381 // Remove keyframes from |starting_point| onward. 382 KeyframeMap::iterator starting_point_keyframe = 383 keyframe_map_.lower_bound((*starting_point)->GetDecodeTimestamp()); 384 keyframe_map_.erase(starting_point_keyframe, keyframe_map_.end()); 385 386 // Remove everything from |starting_point| onward. 387 FreeBufferRange(starting_point, buffers_.end()); 388 return buffers_.empty(); 389 } 390 391 bool SourceBufferRange::GetNextBuffer( 392 scoped_refptr<StreamParserBuffer>* out_buffer) { 393 if (!HasNextBuffer()) 394 return false; 395 396 *out_buffer = buffers_[next_buffer_index_]; 397 next_buffer_index_++; 398 return true; 399 } 400 401 bool SourceBufferRange::HasNextBuffer() const { 402 return next_buffer_index_ >= 0 && 403 next_buffer_index_ < static_cast<int>(buffers_.size()); 404 } 405 406 int SourceBufferRange::GetNextConfigId() const { 407 DCHECK(HasNextBuffer()); 408 // If the next buffer is an audio splice frame, the next effective config id 409 // comes from the first fade out preroll buffer. 410 return buffers_[next_buffer_index_]->GetSpliceBufferConfigId(0); 411 } 412 413 DecodeTimestamp SourceBufferRange::GetNextTimestamp() const { 414 DCHECK(!buffers_.empty()); 415 DCHECK(HasNextBufferPosition()); 416 417 if (next_buffer_index_ >= static_cast<int>(buffers_.size())) { 418 return kNoDecodeTimestamp(); 419 } 420 421 return buffers_[next_buffer_index_]->GetDecodeTimestamp(); 422 } 423 424 bool SourceBufferRange::HasNextBufferPosition() const { 425 return next_buffer_index_ >= 0; 426 } 427 428 void SourceBufferRange::ResetNextBufferPosition() { 429 next_buffer_index_ = -1; 430 } 431 432 void SourceBufferRange::AppendRangeToEnd(const SourceBufferRange& range, 433 bool transfer_current_position) { 434 DCHECK(CanAppendRangeToEnd(range)); 435 DCHECK(!buffers_.empty()); 436 437 if (transfer_current_position && range.next_buffer_index_ >= 0) 438 next_buffer_index_ = range.next_buffer_index_ + buffers_.size(); 439 440 AppendBuffersToEnd(range.buffers_); 441 } 442 443 bool SourceBufferRange::CanAppendRangeToEnd( 444 const SourceBufferRange& range) const { 445 return CanAppendBuffersToEnd(range.buffers_); 446 } 447 448 bool SourceBufferRange::CanAppendBuffersToEnd( 449 const BufferQueue& buffers) const { 450 DCHECK(!buffers_.empty()); 451 return IsNextInSequence(buffers.front()->GetDecodeTimestamp(), 452 buffers.front()->IsKeyframe()); 453 } 454 455 bool SourceBufferRange::BelongsToRange(DecodeTimestamp timestamp) const { 456 DCHECK(!buffers_.empty()); 457 458 return (IsNextInSequence(timestamp, false) || 459 (GetStartTimestamp() <= timestamp && timestamp <= GetEndTimestamp())); 460 } 461 462 bool SourceBufferRange::CanSeekTo(DecodeTimestamp timestamp) const { 463 DecodeTimestamp start_timestamp = 464 std::max(DecodeTimestamp(), GetStartTimestamp() - GetFudgeRoom()); 465 return !keyframe_map_.empty() && start_timestamp <= timestamp && 466 timestamp < GetBufferedEndTimestamp(); 467 } 468 469 bool SourceBufferRange::CompletelyOverlaps( 470 const SourceBufferRange& range) const { 471 return GetStartTimestamp() <= range.GetStartTimestamp() && 472 GetEndTimestamp() >= range.GetEndTimestamp(); 473 } 474 475 bool SourceBufferRange::EndOverlaps(const SourceBufferRange& range) const { 476 return range.GetStartTimestamp() <= GetEndTimestamp() && 477 GetEndTimestamp() < range.GetEndTimestamp(); 478 } 479 480 DecodeTimestamp SourceBufferRange::GetStartTimestamp() const { 481 DCHECK(!buffers_.empty()); 482 DecodeTimestamp start_timestamp = media_segment_start_time_; 483 if (start_timestamp == kNoDecodeTimestamp()) 484 start_timestamp = buffers_.front()->GetDecodeTimestamp(); 485 return start_timestamp; 486 } 487 488 DecodeTimestamp SourceBufferRange::GetEndTimestamp() const { 489 DCHECK(!buffers_.empty()); 490 return buffers_.back()->GetDecodeTimestamp(); 491 } 492 493 DecodeTimestamp SourceBufferRange::GetBufferedEndTimestamp() const { 494 DCHECK(!buffers_.empty()); 495 base::TimeDelta duration = buffers_.back()->duration(); 496 if (duration == kNoTimestamp() || duration == base::TimeDelta()) 497 duration = GetApproximateDuration(); 498 return GetEndTimestamp() + duration; 499 } 500 501 DecodeTimestamp SourceBufferRange::NextKeyframeTimestamp( 502 DecodeTimestamp timestamp) { 503 DCHECK(!keyframe_map_.empty()); 504 505 if (timestamp < GetStartTimestamp() || timestamp >= GetBufferedEndTimestamp()) 506 return kNoDecodeTimestamp(); 507 508 KeyframeMap::iterator itr = GetFirstKeyframeAt(timestamp, false); 509 if (itr == keyframe_map_.end()) 510 return kNoDecodeTimestamp(); 511 512 // If the timestamp is inside the gap between the start of the media 513 // segment and the first buffer, then just pretend there is a 514 // keyframe at the specified timestamp. 515 if (itr == keyframe_map_.begin() && 516 timestamp > media_segment_start_time_ && 517 timestamp < itr->first) { 518 return timestamp; 519 } 520 521 return itr->first; 522 } 523 524 DecodeTimestamp SourceBufferRange::KeyframeBeforeTimestamp( 525 DecodeTimestamp timestamp) { 526 DCHECK(!keyframe_map_.empty()); 527 528 if (timestamp < GetStartTimestamp() || timestamp >= GetBufferedEndTimestamp()) 529 return kNoDecodeTimestamp(); 530 531 return GetFirstKeyframeBefore(timestamp)->first; 532 } 533 534 bool SourceBufferRange::IsNextInSequence( 535 DecodeTimestamp timestamp, bool is_keyframe) const { 536 DecodeTimestamp end = buffers_.back()->GetDecodeTimestamp(); 537 if (end < timestamp && 538 (gap_policy_ == ALLOW_GAPS || 539 timestamp <= end + GetFudgeRoom())) { 540 return true; 541 } 542 543 return timestamp == end && AllowSameTimestamp( 544 buffers_.back()->IsKeyframe(), is_keyframe); 545 } 546 547 base::TimeDelta SourceBufferRange::GetFudgeRoom() const { 548 // Because we do not know exactly when is the next timestamp, any buffer 549 // that starts within 2x the approximate duration of a buffer is considered 550 // within this range. 551 return 2 * GetApproximateDuration(); 552 } 553 554 base::TimeDelta SourceBufferRange::GetApproximateDuration() const { 555 base::TimeDelta max_interbuffer_distance = interbuffer_distance_cb_.Run(); 556 DCHECK(max_interbuffer_distance != kNoTimestamp()); 557 return max_interbuffer_distance; 558 } 559 560 bool SourceBufferRange::GetBuffersInRange(DecodeTimestamp start, 561 DecodeTimestamp end, 562 BufferQueue* buffers) { 563 // Find the nearest buffer with a decode timestamp <= start. 564 const DecodeTimestamp first_timestamp = KeyframeBeforeTimestamp(start); 565 if (first_timestamp == kNoDecodeTimestamp()) 566 return false; 567 568 // Find all buffers involved in the range. 569 const size_t previous_size = buffers->size(); 570 for (BufferQueue::iterator it = GetBufferItrAt(first_timestamp, false); 571 it != buffers_.end(); 572 ++it) { 573 const scoped_refptr<StreamParserBuffer>& buffer = *it; 574 // Buffers without duration are not supported, so bail if we encounter any. 575 if (buffer->duration() == kNoTimestamp() || 576 buffer->duration() <= base::TimeDelta()) { 577 return false; 578 } 579 if (buffer->end_of_stream() || 580 buffer->timestamp() >= end.ToPresentationTime()) { 581 break; 582 } 583 584 if (buffer->timestamp() + buffer->duration() <= start.ToPresentationTime()) 585 continue; 586 buffers->push_back(buffer); 587 } 588 return previous_size < buffers->size(); 589 } 590 591 } // namespace media 592