Chromium Code Reviews| 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/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 #include <sstream> | 9 #include <sstream> |
| 10 #include <string> | |
| 10 | 11 |
| 11 #include "base/bind.h" | 12 #include "base/bind.h" |
| 12 #include "base/logging.h" | 13 #include "base/logging.h" |
| 13 #include "base/trace_event/trace_event.h" | 14 #include "base/trace_event/trace_event.h" |
| 14 #include "media/base/audio_splicer.h" | |
| 15 #include "media/base/timestamp_constants.h" | 15 #include "media/base/timestamp_constants.h" |
| 16 #include "media/filters/source_buffer_platform.h" | 16 #include "media/filters/source_buffer_platform.h" |
| 17 #include "media/filters/source_buffer_range.h" | 17 #include "media/filters/source_buffer_range.h" |
| 18 | 18 |
| 19 namespace media { | 19 namespace media { |
| 20 | 20 |
| 21 namespace { | 21 namespace { |
| 22 | 22 |
| 23 // An arbitrarily-chosen number to estimate the duration of a buffer if none is | 23 // An arbitrarily-chosen number to estimate the duration of a buffer if none is |
| 24 // set and there's not enough information to get a better estimate. | 24 // set and there's not enough information to get a better estimate. |
| 25 const int kDefaultBufferDurationInMs = 125; | 25 const int kDefaultBufferDurationInMs = 125; |
| 26 | 26 |
| 27 // Limit the number of MEDIA_LOG() logs for splice buffer generation warnings | |
| 28 // and successes. Though these values are high enough to possibly exhaust the | |
| 29 // media internals event cache (along with other events), these logs are | |
| 30 // important for debugging splice generation. | |
| 31 const int kMaxSpliceGenerationWarningLogs = 50; | |
| 32 const int kMaxSpliceGenerationSuccessLogs = 20; | |
| 33 | |
| 34 // Limit the number of MEDIA_LOG() logs for track buffer time gaps. | 27 // Limit the number of MEDIA_LOG() logs for track buffer time gaps. |
| 35 const int kMaxTrackBufferGapWarningLogs = 20; | 28 const int kMaxTrackBufferGapWarningLogs = 20; |
| 36 | 29 |
| 37 // Limit the number of MEDIA_LOG() logs for MSE GC algorithm warnings. | 30 // Limit the number of MEDIA_LOG() logs for MSE GC algorithm warnings. |
| 38 const int kMaxGarbageCollectAlgorithmWarningLogs = 20; | 31 const int kMaxGarbageCollectAlgorithmWarningLogs = 20; |
| 39 | 32 |
| 33 // Limit the number of MEDIA_LOG() logs for splice overlap trimming. | |
| 34 const int kMaxAudioSpliceLogs = 20; | |
| 35 | |
| 40 // Limit the number of MEDIA_LOG() logs for same DTS for non-keyframe followed | 36 // Limit the number of MEDIA_LOG() logs for same DTS for non-keyframe followed |
| 41 // by keyframe. Prior to relaxing the "media segments must begin with a | 37 // by keyframe. Prior to relaxing the "media segments must begin with a |
| 42 // keyframe" requirement, we issued decode error for this situation. That was | 38 // keyframe" requirement, we issued decode error for this situation. That was |
| 43 // likely too strict, and now that the keyframe requirement is relaxed, we have | 39 // likely too strict, and now that the keyframe requirement is relaxed, we have |
| 44 // no knowledge of media segment boundaries here. Now, we log but don't trigger | 40 // no knowledge of media segment boundaries here. Now, we log but don't trigger |
| 45 // decode error, since we allow these sequences which may cause extra decoder | 41 // decode error, since we allow these sequences which may cause extra decoder |
| 46 // work or other side-effects. | 42 // work or other side-effects. |
| 47 const int kMaxStrangeSameTimestampsLogs = 20; | 43 const int kMaxStrangeSameTimestampsLogs = 20; |
| 48 | 44 |
| 49 // Helper method that returns true if |ranges| is sorted in increasing order, | 45 // Helper method that returns true if |ranges| is sorted in increasing order, |
| 50 // false otherwise. | 46 // false otherwise. |
| 51 bool IsRangeListSorted(const std::list<media::SourceBufferRange*>& ranges) { | 47 bool IsRangeListSorted(const std::list<media::SourceBufferRange*>& ranges) { |
| 52 DecodeTimestamp prev = kNoDecodeTimestamp(); | 48 DecodeTimestamp prev = kNoDecodeTimestamp(); |
| 53 for (std::list<SourceBufferRange*>::const_iterator itr = | 49 for (std::list<SourceBufferRange*>::const_iterator itr = |
| 54 ranges.begin(); itr != ranges.end(); ++itr) { | 50 ranges.begin(); itr != ranges.end(); ++itr) { |
| 55 if (prev != kNoDecodeTimestamp() && prev >= (*itr)->GetStartTimestamp()) | 51 if (prev != kNoDecodeTimestamp() && prev >= (*itr)->GetStartTimestamp()) |
| 56 return false; | 52 return false; |
| 57 prev = (*itr)->GetEndTimestamp(); | 53 prev = (*itr)->GetEndTimestamp(); |
| 58 } | 54 } |
| 59 return true; | 55 return true; |
| 60 } | 56 } |
| 61 | 57 |
| 62 // Returns an estimate of how far from the beginning or end of a range a buffer | 58 // Returns an estimate of how far from the beginning or end of a range a buffer |
| 63 // can be to still be considered in the range, given the |approximate_duration| | 59 // can be to still be considered in the range, given the |approximate_duration| |
| 64 // of a buffer in the stream. | 60 // of a buffer in the stream. |
| 65 // TODO(wolenetz): Once all stream parsers emit accurate frame durations, use | 61 // TODO(wolenetz): Once all stream parsers emit accurate frame durations, use |
| 66 // logic like FrameProcessor (2*last_frame_duration + last_decode_timestamp) | 62 // logic like FrameProcessor (2*last_frame_duration + last_decode_timestamp) |
| 67 // instead of an overall maximum interbuffer delta for range discontinuity | 63 // instead of an overall maximum interbuffer delta for range discontinuity |
| 68 // detection, and adjust similarly for splice frame discontinuity detection. | 64 // detection. |
| 69 // See http://crbug.com/351489 and http://crbug.com/351166. | 65 // See http://crbug.com/351489 and http://crbug.com/351166. |
| 70 base::TimeDelta ComputeFudgeRoom(base::TimeDelta approximate_duration) { | 66 base::TimeDelta ComputeFudgeRoom(base::TimeDelta approximate_duration) { |
| 71 // Because we do not know exactly when is the next timestamp, any buffer | 67 // Because we do not know exactly when is the next timestamp, any buffer |
| 72 // that starts within 2x the approximate duration of a buffer is considered | 68 // that starts within 2x the approximate duration of a buffer is considered |
| 73 // within this range. | 69 // within this range. |
| 74 return 2 * approximate_duration; | 70 return 2 * approximate_duration; |
| 75 } | 71 } |
| 76 | 72 |
| 77 // The amount of time the beginning of the buffered data can differ from the | 73 // The amount of time the beginning of the buffered data can differ from the |
| 78 // start time in order to still be considered the start of stream. | 74 // start time in order to still be considered the start of stream. |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 135 return SourceBufferRange::ALLOW_GAPS; | 131 return SourceBufferRange::ALLOW_GAPS; |
| 136 } | 132 } |
| 137 | 133 |
| 138 NOTREACHED(); | 134 NOTREACHED(); |
| 139 return SourceBufferRange::NO_GAPS_ALLOWED; | 135 return SourceBufferRange::NO_GAPS_ALLOWED; |
| 140 } | 136 } |
| 141 | 137 |
| 142 } // namespace | 138 } // namespace |
| 143 | 139 |
| 144 SourceBufferStream::SourceBufferStream(const AudioDecoderConfig& audio_config, | 140 SourceBufferStream::SourceBufferStream(const AudioDecoderConfig& audio_config, |
| 145 const scoped_refptr<MediaLog>& media_log, | 141 const scoped_refptr<MediaLog>& media_log) |
| 146 bool splice_frames_enabled) | |
| 147 : media_log_(media_log), | 142 : media_log_(media_log), |
| 148 seek_buffer_timestamp_(kNoTimestamp), | 143 seek_buffer_timestamp_(kNoTimestamp), |
| 149 coded_frame_group_start_time_(kNoDecodeTimestamp()), | 144 coded_frame_group_start_time_(kNoDecodeTimestamp()), |
| 150 range_for_next_append_(ranges_.end()), | 145 range_for_next_append_(ranges_.end()), |
| 151 last_output_buffer_timestamp_(kNoDecodeTimestamp()), | 146 last_output_buffer_timestamp_(kNoDecodeTimestamp()), |
| 152 max_interbuffer_distance_(kNoTimestamp), | 147 max_interbuffer_distance_(kNoTimestamp), |
| 153 memory_limit_(kSourceBufferAudioMemoryLimit), | 148 memory_limit_(kSourceBufferAudioMemoryLimit) { |
| 154 splice_frames_enabled_(splice_frames_enabled) { | |
| 155 DCHECK(audio_config.IsValidConfig()); | 149 DCHECK(audio_config.IsValidConfig()); |
| 156 audio_configs_.push_back(audio_config); | 150 audio_configs_.push_back(audio_config); |
| 157 } | 151 } |
| 158 | 152 |
| 159 SourceBufferStream::SourceBufferStream(const VideoDecoderConfig& video_config, | 153 SourceBufferStream::SourceBufferStream(const VideoDecoderConfig& video_config, |
| 160 const scoped_refptr<MediaLog>& media_log, | 154 const scoped_refptr<MediaLog>& media_log) |
| 161 bool splice_frames_enabled) | |
| 162 : media_log_(media_log), | 155 : media_log_(media_log), |
| 163 seek_buffer_timestamp_(kNoTimestamp), | 156 seek_buffer_timestamp_(kNoTimestamp), |
| 164 coded_frame_group_start_time_(kNoDecodeTimestamp()), | 157 coded_frame_group_start_time_(kNoDecodeTimestamp()), |
| 165 range_for_next_append_(ranges_.end()), | 158 range_for_next_append_(ranges_.end()), |
| 166 last_output_buffer_timestamp_(kNoDecodeTimestamp()), | 159 last_output_buffer_timestamp_(kNoDecodeTimestamp()), |
| 167 max_interbuffer_distance_(kNoTimestamp), | 160 max_interbuffer_distance_(kNoTimestamp), |
| 168 memory_limit_(kSourceBufferVideoMemoryLimit), | 161 memory_limit_(kSourceBufferVideoMemoryLimit) { |
| 169 splice_frames_enabled_(splice_frames_enabled) { | |
| 170 DCHECK(video_config.IsValidConfig()); | 162 DCHECK(video_config.IsValidConfig()); |
| 171 video_configs_.push_back(video_config); | 163 video_configs_.push_back(video_config); |
| 172 } | 164 } |
| 173 | 165 |
| 174 SourceBufferStream::SourceBufferStream(const TextTrackConfig& text_config, | 166 SourceBufferStream::SourceBufferStream(const TextTrackConfig& text_config, |
| 175 const scoped_refptr<MediaLog>& media_log, | 167 const scoped_refptr<MediaLog>& media_log) |
| 176 bool splice_frames_enabled) | |
| 177 : media_log_(media_log), | 168 : media_log_(media_log), |
| 178 text_track_config_(text_config), | 169 text_track_config_(text_config), |
| 179 seek_buffer_timestamp_(kNoTimestamp), | 170 seek_buffer_timestamp_(kNoTimestamp), |
| 180 coded_frame_group_start_time_(kNoDecodeTimestamp()), | 171 coded_frame_group_start_time_(kNoDecodeTimestamp()), |
| 181 range_for_next_append_(ranges_.end()), | 172 range_for_next_append_(ranges_.end()), |
| 182 last_output_buffer_timestamp_(kNoDecodeTimestamp()), | 173 last_output_buffer_timestamp_(kNoDecodeTimestamp()), |
| 183 max_interbuffer_distance_(kNoTimestamp), | 174 max_interbuffer_distance_(kNoTimestamp), |
| 184 memory_limit_(kSourceBufferAudioMemoryLimit), | 175 memory_limit_(kSourceBufferAudioMemoryLimit) {} |
| 185 splice_frames_enabled_(splice_frames_enabled) {} | |
| 186 | 176 |
| 187 SourceBufferStream::~SourceBufferStream() { | 177 SourceBufferStream::~SourceBufferStream() { |
| 188 while (!ranges_.empty()) { | 178 while (!ranges_.empty()) { |
| 189 delete ranges_.front(); | 179 delete ranges_.front(); |
| 190 ranges_.pop_front(); | 180 ranges_.pop_front(); |
| 191 } | 181 } |
| 192 } | 182 } |
| 193 | 183 |
| 194 void SourceBufferStream::OnStartOfCodedFrameGroup( | 184 void SourceBufferStream::OnStartOfCodedFrameGroup( |
| 195 DecodeTimestamp coded_frame_group_start_time) { | 185 DecodeTimestamp coded_frame_group_start_time) { |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 258 | 248 |
| 259 // Save a snapshot of stream state before range modifications are made. | 249 // Save a snapshot of stream state before range modifications are made. |
| 260 DecodeTimestamp next_buffer_timestamp = GetNextBufferTimestamp(); | 250 DecodeTimestamp next_buffer_timestamp = GetNextBufferTimestamp(); |
| 261 BufferQueue deleted_buffers; | 251 BufferQueue deleted_buffers; |
| 262 | 252 |
| 263 PrepareRangesForNextAppend(buffers, &deleted_buffers); | 253 PrepareRangesForNextAppend(buffers, &deleted_buffers); |
| 264 | 254 |
| 265 // If there's a range for |buffers|, insert |buffers| accordingly. Otherwise, | 255 // If there's a range for |buffers|, insert |buffers| accordingly. Otherwise, |
| 266 // create a new range with |buffers|. | 256 // create a new range with |buffers|. |
| 267 if (range_for_next_append_ != ranges_.end()) { | 257 if (range_for_next_append_ != ranges_.end()) { |
| 268 if (new_coded_frame_group_ && (!splice_frames_enabled_ || | 258 if (new_coded_frame_group_) { |
| 269 buffers.front()->splice_buffers().empty())) { | |
| 270 // If the first append to this stream in a new coded frame group continues | 259 // If the first append to this stream in a new coded frame group continues |
| 271 // a previous range, use the new group's start time instead of the first | 260 // a previous range, use the new group's start time instead of the first |
| 272 // new buffer's timestamp as the proof of adjacency to the existing range. | 261 // new buffer's timestamp as the proof of adjacency to the existing range. |
| 273 // A large gap (larger than our normal buffer adjacency test) can occur in | 262 // A large gap (larger than our normal buffer adjacency test) can occur in |
| 274 // a muxed set of streams (which share a common coded frame group start | 263 // a muxed set of streams (which share a common coded frame group start |
| 275 // time) with a significantly jagged start across the streams. | 264 // time) with a significantly jagged start across the streams. |
| 276 // Don't do this logic if there was a splice frame generated for the first | |
| 277 // new buffer, since splices are guaranteed to be in the same range and | |
| 278 // adjacent, and since the splice frame's timestamp can be less than | |
| 279 // |coded_frame_group_start_time_| due to the splicing. | |
| 280 (*range_for_next_append_) | 265 (*range_for_next_append_) |
| 281 ->AppendBuffersToEnd(buffers, coded_frame_group_start_time_); | 266 ->AppendBuffersToEnd(buffers, coded_frame_group_start_time_); |
| 282 } else { | 267 } else { |
| 283 // Otherwise, use the first new buffer's timestamp as the proof of | 268 // Otherwise, use the first new buffer's timestamp as the proof of |
| 284 // adjacency. | 269 // adjacency. |
| 285 (*range_for_next_append_) | 270 (*range_for_next_append_) |
| 286 ->AppendBuffersToEnd(buffers, kNoDecodeTimestamp()); | 271 ->AppendBuffersToEnd(buffers, kNoDecodeTimestamp()); |
| 287 } | 272 } |
| 288 | 273 |
| 289 last_appended_buffer_timestamp_ = buffers.back()->GetDecodeTimestamp(); | 274 last_appended_buffer_timestamp_ = buffers.back()->GetDecodeTimestamp(); |
| (...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 552 DCHECK(IsRangeListSorted(ranges_)); | 537 DCHECK(IsRangeListSorted(ranges_)); |
| 553 DCHECK(OnlySelectedRangeIsSeeked()); | 538 DCHECK(OnlySelectedRangeIsSeeked()); |
| 554 } | 539 } |
| 555 | 540 |
| 556 void SourceBufferStream::ResetSeekState() { | 541 void SourceBufferStream::ResetSeekState() { |
| 557 SetSelectedRange(NULL); | 542 SetSelectedRange(NULL); |
| 558 track_buffer_.clear(); | 543 track_buffer_.clear(); |
| 559 config_change_pending_ = false; | 544 config_change_pending_ = false; |
| 560 last_output_buffer_timestamp_ = kNoDecodeTimestamp(); | 545 last_output_buffer_timestamp_ = kNoDecodeTimestamp(); |
| 561 just_exhausted_track_buffer_ = false; | 546 just_exhausted_track_buffer_ = false; |
| 562 splice_buffers_index_ = 0; | |
| 563 pending_buffer_ = NULL; | 547 pending_buffer_ = NULL; |
| 564 pending_buffers_complete_ = false; | 548 pending_buffers_complete_ = false; |
| 565 } | 549 } |
| 566 | 550 |
| 567 bool SourceBufferStream::ShouldSeekToStartOfBuffered( | 551 bool SourceBufferStream::ShouldSeekToStartOfBuffered( |
| 568 base::TimeDelta seek_timestamp) const { | 552 base::TimeDelta seek_timestamp) const { |
| 569 if (ranges_.empty()) | 553 if (ranges_.empty()) |
| 570 return false; | 554 return false; |
| 571 base::TimeDelta beginning_of_buffered = | 555 base::TimeDelta beginning_of_buffered = |
| 572 ranges_.front()->GetStartTimestamp().ToPresentationTime(); | 556 ranges_.front()->GetStartTimestamp().ToPresentationTime(); |
| (...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 962 if (range_for_next_append_ != ranges_.begin()) { | 946 if (range_for_next_append_ != ranges_.begin()) { |
| 963 RangeList::iterator range_before_next = range_for_next_append_; | 947 RangeList::iterator range_before_next = range_for_next_append_; |
| 964 --range_before_next; | 948 --range_before_next; |
| 965 MergeWithAdjacentRangeIfNecessary(range_before_next); | 949 MergeWithAdjacentRangeIfNecessary(range_before_next); |
| 966 } | 950 } |
| 967 MergeWithAdjacentRangeIfNecessary(range_for_next_append_); | 951 MergeWithAdjacentRangeIfNecessary(range_for_next_append_); |
| 968 } | 952 } |
| 969 return bytes_freed; | 953 return bytes_freed; |
| 970 } | 954 } |
| 971 | 955 |
| 956 void SourceBufferStream::TrimSpliceOverlap(const BufferQueue& new_buffers) { | |
| 957 DCHECK(!new_buffers.empty()); | |
| 958 DCHECK_EQ(kAudio, GetType()); | |
| 959 | |
| 960 // Find the overlapped range (if any). | |
| 961 const base::TimeDelta splice_timestamp = new_buffers.front()->timestamp(); | |
| 962 const DecodeTimestamp splice_dts = | |
| 963 DecodeTimestamp::FromPresentationTime(splice_timestamp); | |
| 964 RangeList::iterator range_itr = FindExistingRangeFor(splice_dts); | |
| 965 if (range_itr == ranges_.end()) { | |
| 966 DVLOG(3) << __func__ << " No splice trimming. No range overlap at time " | |
| 967 << splice_timestamp.InMicroseconds(); | |
| 968 return; | |
| 969 } | |
| 970 | |
| 971 // Search for overlapped buffer needs exclusive end value. Choosing smallest | |
| 972 // possible value. | |
| 973 const DecodeTimestamp end_dts = | |
| 974 splice_dts + base::TimeDelta::FromInternalValue(1); | |
| 975 | |
| 976 // Find if new buffer's start would overlap an existing buffer. | |
| 977 BufferQueue overlapped_buffers; | |
| 978 if (!(*range_itr) | |
| 979 ->GetBuffersInRange(splice_dts, end_dts, &overlapped_buffers)) { | |
| 980 // Bail if no overlapped buffers found. | |
| 981 DVLOG(3) << __func__ << " No splice trimming. No buffer overlap at time " | |
| 982 << splice_timestamp.InMicroseconds(); | |
| 983 return; | |
| 984 } | |
| 985 | |
| 986 // At most one buffer should exist containing the time of the newly appended | |
| 987 // buffer's start. GetBuffersInRange does not currently return buffers with | |
| 988 // zero duration. | |
| 989 DCHECK_EQ(overlapped_buffers.size(), 1U) | |
| 990 << __func__ << " Found more than one overlapped buffer"; | |
| 991 StreamParserBuffer* overlapped_buffer = overlapped_buffers.front().get(); | |
| 992 | |
| 993 if (overlapped_buffer->timestamp() == splice_timestamp) { | |
| 994 // Ignore buffers with the same start time. They will be completely removed | |
| 995 // in PreapreRangesForNextAppend(). | |
| 996 DVLOG(3) << __func__ << " No splice trimming at time " | |
| 997 << splice_timestamp.InMicroseconds() | |
| 998 << ". Overlapped buffer will be completely removed."; | |
| 999 return; | |
| 1000 } | |
| 1001 | |
| 1002 // Determine the duration of overlap. | |
| 1003 base::TimeDelta overlapped_end_time = | |
| 1004 overlapped_buffer->timestamp() + overlapped_buffer->duration(); | |
| 1005 base::TimeDelta overlap_duration = overlapped_end_time - splice_timestamp; | |
| 1006 | |
| 1007 // Trim overlap from the existing buffer. | |
| 1008 if (overlap_duration > base::TimeDelta()) { | |
| 1009 DecoderBuffer::DiscardPadding discard_padding = | |
| 1010 overlapped_buffer->discard_padding(); | |
| 1011 discard_padding.second += overlap_duration; | |
| 1012 overlapped_buffer->set_discard_padding(discard_padding); | |
| 1013 overlapped_buffer->set_duration(overlapped_buffer->duration() - | |
| 1014 overlap_duration); | |
| 1015 | |
| 1016 std::stringstream log_string; | |
| 1017 log_string << "Audio buffer splice at PTS=" | |
| 1018 << splice_timestamp.InMicroseconds() | |
| 1019 << "us. Trimmed tail of overlapped buffer (PTS=" | |
| 1020 << overlapped_buffer->timestamp().InMicroseconds() << "us) by " | |
| 1021 << overlap_duration.InMicroseconds() << "us."; | |
| 1022 LIMITED_MEDIA_LOG(DEBUG, media_log_, num_splice_logs_, kMaxAudioSpliceLogs) | |
| 1023 << log_string.str(); | |
| 1024 DVLOG(1) << __func__ << log_string.str(); | |
| 1025 } | |
| 1026 } | |
| 1027 | |
| 972 void SourceBufferStream::PrepareRangesForNextAppend( | 1028 void SourceBufferStream::PrepareRangesForNextAppend( |
| 973 const BufferQueue& new_buffers, BufferQueue* deleted_buffers) { | 1029 const BufferQueue& new_buffers, BufferQueue* deleted_buffers) { |
| 974 DCHECK(deleted_buffers); | 1030 DCHECK(deleted_buffers); |
| 975 | 1031 |
| 976 // Handle splices between the existing buffers and the new buffers. If a | 1032 if (GetType() == kAudio) |
| 977 // splice is generated the timestamp and duration of the first buffer in | 1033 TrimSpliceOverlap(new_buffers); |
| 978 // |new_buffers| will be modified. | |
| 979 if (splice_frames_enabled_) | |
| 980 GenerateSpliceFrame(new_buffers); | |
| 981 | 1034 |
| 1035 base::TimeDelta prev_duration = last_appended_buffer_duration_; | |
| 982 DecodeTimestamp prev_timestamp = last_appended_buffer_timestamp_; | 1036 DecodeTimestamp prev_timestamp = last_appended_buffer_timestamp_; |
| 983 DecodeTimestamp next_timestamp = new_buffers.front()->GetDecodeTimestamp(); | 1037 DecodeTimestamp next_timestamp = new_buffers.front()->GetDecodeTimestamp(); |
| 984 | 1038 |
| 1039 // 1. Clean up the old buffers between the last appended buffer and the | |
| 1040 // beginning of |new_buffers|. | |
| 985 if (prev_timestamp != kNoDecodeTimestamp() && | 1041 if (prev_timestamp != kNoDecodeTimestamp() && |
| 986 prev_timestamp != next_timestamp) { | 1042 prev_timestamp != next_timestamp) { |
| 987 // Clean up the old buffers between the last appended buffer and the | |
| 988 // beginning of |new_buffers|. | |
| 989 RemoveInternal(prev_timestamp, next_timestamp, true, deleted_buffers); | 1043 RemoveInternal(prev_timestamp, next_timestamp, true, deleted_buffers); |
| 990 } | 1044 } |
| 991 | 1045 |
| 992 // Always make the start of the delete range exclusive for same timestamp | 1046 // 2. Delete the buffers that |new_buffers| overlaps. |
| 993 // across the last buffer in the previous append and the first buffer in the | |
| 994 // current append. Never be exclusive if a splice frame was generated because | |
| 995 // we don't generate splice frames for same timestamp situations. | |
| 996 DCHECK(new_buffers.front()->splice_timestamp() != | |
| 997 new_buffers.front()->timestamp()); | |
| 998 const bool exclude_start = new_buffers.front()->splice_buffers().empty() && | |
| 999 prev_timestamp == next_timestamp; | |
| 1000 | |
| 1001 // Delete the buffers that |new_buffers| overlaps. | |
| 1002 DecodeTimestamp start = new_buffers.front()->GetDecodeTimestamp(); | |
| 1003 if (new_coded_frame_group_) { | 1047 if (new_coded_frame_group_) { |
| 1004 // Extend the deletion range earlier to the coded frame group start time if | 1048 // Extend the deletion range earlier to the coded frame group start time if |
| 1005 // this is the first append in a new coded frame group. Note that |start| | 1049 // this is the first append in a new coded frame group. |
| 1006 // could already be less than |coded_frame_group_start_time_| if a splice | |
| 1007 // was generated. | |
| 1008 DCHECK(coded_frame_group_start_time_ != kNoDecodeTimestamp()); | 1050 DCHECK(coded_frame_group_start_time_ != kNoDecodeTimestamp()); |
| 1009 start = std::min(coded_frame_group_start_time_, start); | 1051 next_timestamp = std::min(coded_frame_group_start_time_, next_timestamp); |
| 1010 } | 1052 } |
| 1011 DecodeTimestamp end = new_buffers.back()->GetDecodeTimestamp(); | 1053 |
| 1012 base::TimeDelta duration = new_buffers.back()->duration(); | 1054 // Exclude the start timestamp from removal if the previous append is a zero |
| 1055 // duration frame with the same timestamp as the current append. This avoids | |
| 1056 // deleting zero-duration VP9 alt-ref frames while still deleting frames | |
| 1057 // with non-zero duration that are now overlapped. | |
| 1058 const bool exclude_start = | |
| 1059 prev_timestamp == next_timestamp && prev_duration == base::TimeDelta(); | |
| 1013 | 1060 |
| 1014 // Set end time for remove to include the duration of last buffer. If the | 1061 // Set end time for remove to include the duration of last buffer. If the |
| 1015 // duration is estimated, use 1 microsecond instead to ensure frames are not | 1062 // duration is estimated, use 1 microsecond instead to ensure frames are not |
| 1016 // accidentally removed due to over-estimation. | 1063 // accidentally removed due to over-estimation. |
| 1064 DecodeTimestamp end = new_buffers.back()->GetDecodeTimestamp(); | |
| 1065 base::TimeDelta duration = new_buffers.back()->duration(); | |
| 1017 if (duration != kNoTimestamp && duration > base::TimeDelta() && | 1066 if (duration != kNoTimestamp && duration > base::TimeDelta() && |
| 1018 !new_buffers.back()->is_duration_estimated()) { | 1067 !new_buffers.back()->is_duration_estimated()) { |
| 1019 end += duration; | 1068 end += duration; |
| 1020 } else { | 1069 } else { |
| 1021 // TODO(chcunningham): Emit warning when 0ms durations are not expected. | 1070 // TODO(chcunningham): Emit warning when 0ms durations are not expected. |
| 1022 // http://crbug.com/312836 | 1071 // http://crbug.com/312836 |
| 1023 end += base::TimeDelta::FromInternalValue(1); | 1072 end += base::TimeDelta::FromInternalValue(1); |
| 1024 } | 1073 } |
| 1025 | 1074 |
| 1026 RemoveInternal(start, end, exclude_start, deleted_buffers); | 1075 // Finally do the deletion of overlap. |
| 1076 RemoveInternal(next_timestamp, end, exclude_start, deleted_buffers); | |
| 1027 } | 1077 } |
| 1028 | 1078 |
| 1029 bool SourceBufferStream::AreAdjacentInSequence( | 1079 bool SourceBufferStream::AreAdjacentInSequence( |
| 1030 DecodeTimestamp first_timestamp, DecodeTimestamp second_timestamp) const { | 1080 DecodeTimestamp first_timestamp, DecodeTimestamp second_timestamp) const { |
| 1031 return first_timestamp < second_timestamp && | 1081 return first_timestamp < second_timestamp && |
| 1032 second_timestamp <= | 1082 second_timestamp <= |
| 1033 first_timestamp + ComputeFudgeRoom(GetMaxInterbufferDistance()); | 1083 first_timestamp + ComputeFudgeRoom(GetMaxInterbufferDistance()); |
| 1034 } | 1084 } |
| 1035 | 1085 |
| 1036 void SourceBufferStream::PruneTrackBuffer(const DecodeTimestamp timestamp) { | 1086 void SourceBufferStream::PruneTrackBuffer(const DecodeTimestamp timestamp) { |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1155 if (!pending_buffer_.get()) { | 1205 if (!pending_buffer_.get()) { |
| 1156 const SourceBufferStream::Status status = GetNextBufferInternal(out_buffer); | 1206 const SourceBufferStream::Status status = GetNextBufferInternal(out_buffer); |
| 1157 if (status != SourceBufferStream::kSuccess || | 1207 if (status != SourceBufferStream::kSuccess || |
| 1158 !SetPendingBuffer(out_buffer)) { | 1208 !SetPendingBuffer(out_buffer)) { |
| 1159 DVLOG(2) << __func__ << " " << GetStreamTypeName() | 1209 DVLOG(2) << __func__ << " " << GetStreamTypeName() |
| 1160 << ": no pending buffer, returning status " << status; | 1210 << ": no pending buffer, returning status " << status; |
| 1161 return status; | 1211 return status; |
| 1162 } | 1212 } |
| 1163 } | 1213 } |
| 1164 | 1214 |
| 1165 if (!pending_buffer_->splice_buffers().empty()) { | |
| 1166 const SourceBufferStream::Status status = | |
| 1167 HandleNextBufferWithSplice(out_buffer); | |
| 1168 DVLOG(2) << __func__ << " " << GetStreamTypeName() | |
| 1169 << ": handled next buffer with splice, returning status " | |
| 1170 << status; | |
| 1171 return status; | |
| 1172 } | |
| 1173 | |
| 1174 DCHECK(pending_buffer_->preroll_buffer().get()); | 1215 DCHECK(pending_buffer_->preroll_buffer().get()); |
| 1175 | 1216 |
| 1176 const SourceBufferStream::Status status = | 1217 const SourceBufferStream::Status status = |
| 1177 HandleNextBufferWithPreroll(out_buffer); | 1218 HandleNextBufferWithPreroll(out_buffer); |
| 1178 DVLOG(2) << __func__ << " " << GetStreamTypeName() | 1219 DVLOG(2) << __func__ << " " << GetStreamTypeName() |
| 1179 << ": handled next buffer with preroll, returning status " << status; | 1220 << ": handled next buffer with preroll, returning status " << status; |
| 1180 return status; | 1221 return status; |
| 1181 } | 1222 } |
| 1182 | 1223 |
| 1183 SourceBufferStream::Status SourceBufferStream::HandleNextBufferWithSplice( | |
| 1184 scoped_refptr<StreamParserBuffer>* out_buffer) { | |
| 1185 const BufferQueue& splice_buffers = pending_buffer_->splice_buffers(); | |
| 1186 const size_t last_splice_buffer_index = splice_buffers.size() - 1; | |
| 1187 | |
| 1188 // Are there any splice buffers left to hand out? The last buffer should be | |
| 1189 // handed out separately since it represents the first post-splice buffer. | |
| 1190 if (splice_buffers_index_ < last_splice_buffer_index) { | |
| 1191 // Account for config changes which occur between fade out buffers. | |
| 1192 if (current_config_index_ != | |
| 1193 splice_buffers[splice_buffers_index_]->GetConfigId()) { | |
| 1194 config_change_pending_ = true; | |
| 1195 DVLOG(1) << "Config change (splice buffer config ID does not match)."; | |
| 1196 return SourceBufferStream::kConfigChange; | |
| 1197 } | |
| 1198 | |
| 1199 // Every pre splice buffer must have the same splice_timestamp(). | |
| 1200 DCHECK(pending_buffer_->splice_timestamp() == | |
| 1201 splice_buffers[splice_buffers_index_]->splice_timestamp()); | |
| 1202 | |
| 1203 // No pre splice buffers should have preroll. | |
| 1204 DCHECK(!splice_buffers[splice_buffers_index_]->preroll_buffer().get()); | |
| 1205 | |
| 1206 *out_buffer = splice_buffers[splice_buffers_index_++]; | |
| 1207 return SourceBufferStream::kSuccess; | |
| 1208 } | |
| 1209 | |
| 1210 // Did we hand out the last pre-splice buffer on the previous call? | |
| 1211 if (!pending_buffers_complete_) { | |
| 1212 DCHECK_EQ(splice_buffers_index_, last_splice_buffer_index); | |
| 1213 pending_buffers_complete_ = true; | |
| 1214 config_change_pending_ = true; | |
| 1215 DVLOG(1) << "Config change (forced for fade in of splice frame)."; | |
| 1216 return SourceBufferStream::kConfigChange; | |
| 1217 } | |
| 1218 | |
| 1219 // All pre-splice buffers have been handed out and a config change completed, | |
| 1220 // so hand out the final buffer for fade in. Because a config change is | |
| 1221 // always issued prior to handing out this buffer, any changes in config id | |
| 1222 // have been inherently handled. | |
| 1223 DCHECK(pending_buffers_complete_); | |
| 1224 DCHECK_EQ(splice_buffers_index_, splice_buffers.size() - 1); | |
| 1225 DCHECK(splice_buffers.back()->splice_timestamp() == kNoTimestamp); | |
| 1226 *out_buffer = splice_buffers.back(); | |
| 1227 pending_buffer_ = NULL; | |
| 1228 | |
| 1229 // If the last splice buffer has preroll, hand off to the preroll handler. | |
| 1230 return SetPendingBuffer(out_buffer) ? HandleNextBufferWithPreroll(out_buffer) | |
| 1231 : SourceBufferStream::kSuccess; | |
| 1232 } | |
| 1233 | |
| 1234 SourceBufferStream::Status SourceBufferStream::HandleNextBufferWithPreroll( | 1224 SourceBufferStream::Status SourceBufferStream::HandleNextBufferWithPreroll( |
| 1235 scoped_refptr<StreamParserBuffer>* out_buffer) { | 1225 scoped_refptr<StreamParserBuffer>* out_buffer) { |
| 1236 // Any config change should have already been handled. | 1226 // Any config change should have already been handled. |
| 1237 DCHECK_EQ(current_config_index_, pending_buffer_->GetConfigId()); | 1227 DCHECK_EQ(current_config_index_, pending_buffer_->GetConfigId()); |
| 1238 | 1228 |
| 1239 // Check if the preroll buffer has already been handed out. | 1229 // Check if the preroll buffer has already been handed out. |
| 1240 if (!pending_buffers_complete_) { | 1230 if (!pending_buffers_complete_) { |
| 1241 pending_buffers_complete_ = true; | 1231 pending_buffers_complete_ = true; |
| 1242 *out_buffer = pending_buffer_->preroll_buffer(); | 1232 *out_buffer = pending_buffer_->preroll_buffer(); |
| 1243 return SourceBufferStream::kSuccess; | 1233 return SourceBufferStream::kSuccess; |
| (...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1532 append_config_index_ = video_configs_.size(); | 1522 append_config_index_ = video_configs_.size(); |
| 1533 DVLOG(2) << "New video config - index: " << append_config_index_; | 1523 DVLOG(2) << "New video config - index: " << append_config_index_; |
| 1534 video_configs_.resize(video_configs_.size() + 1); | 1524 video_configs_.resize(video_configs_.size() + 1); |
| 1535 video_configs_[append_config_index_] = config; | 1525 video_configs_[append_config_index_] = config; |
| 1536 return true; | 1526 return true; |
| 1537 } | 1527 } |
| 1538 | 1528 |
| 1539 void SourceBufferStream::CompleteConfigChange() { | 1529 void SourceBufferStream::CompleteConfigChange() { |
| 1540 config_change_pending_ = false; | 1530 config_change_pending_ = false; |
| 1541 | 1531 |
| 1542 if (pending_buffer_.get()) { | |
| 1543 current_config_index_ = | |
| 1544 pending_buffer_->GetSpliceBufferConfigId(splice_buffers_index_); | |
| 1545 return; | |
| 1546 } | |
| 1547 | |
| 1548 if (!track_buffer_.empty()) { | 1532 if (!track_buffer_.empty()) { |
| 1549 current_config_index_ = track_buffer_.front()->GetSpliceBufferConfigId(0); | 1533 current_config_index_ = track_buffer_.front()->GetSpliceBufferConfigId(0); |
| 1550 return; | 1534 return; |
| 1551 } | 1535 } |
| 1552 | 1536 |
| 1553 if (selected_range_ && selected_range_->HasNextBuffer()) | 1537 if (selected_range_ && selected_range_->HasNextBuffer()) |
| 1554 current_config_index_ = selected_range_->GetNextConfigId(); | 1538 current_config_index_ = selected_range_->GetNextConfigId(); |
| 1555 } | 1539 } |
| 1556 | 1540 |
| 1557 void SourceBufferStream::SetSelectedRangeIfNeeded( | 1541 void SourceBufferStream::SetSelectedRangeIfNeeded( |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1685 DVLOG(1) << __func__ << " deleting range_for_next_append_."; | 1669 DVLOG(1) << __func__ << " deleting range_for_next_append_."; |
| 1686 range_for_next_append_ = ranges_.end(); | 1670 range_for_next_append_ = ranges_.end(); |
| 1687 last_appended_buffer_timestamp_ = kNoDecodeTimestamp(); | 1671 last_appended_buffer_timestamp_ = kNoDecodeTimestamp(); |
| 1688 last_appended_buffer_is_keyframe_ = false; | 1672 last_appended_buffer_is_keyframe_ = false; |
| 1689 } | 1673 } |
| 1690 | 1674 |
| 1691 delete **itr; | 1675 delete **itr; |
| 1692 *itr = ranges_.erase(*itr); | 1676 *itr = ranges_.erase(*itr); |
| 1693 } | 1677 } |
| 1694 | 1678 |
| 1695 void SourceBufferStream::GenerateSpliceFrame(const BufferQueue& new_buffers) { | |
| 1696 DCHECK(!new_buffers.empty()); | |
| 1697 | |
| 1698 // Splice frames are only supported for audio. | |
| 1699 if (GetType() != kAudio) | |
| 1700 return; | |
| 1701 | |
| 1702 // Find the overlapped range (if any). | |
| 1703 const base::TimeDelta splice_timestamp = new_buffers.front()->timestamp(); | |
| 1704 const DecodeTimestamp splice_dts = | |
| 1705 DecodeTimestamp::FromPresentationTime(splice_timestamp); | |
| 1706 RangeList::iterator range_itr = FindExistingRangeFor(splice_dts); | |
| 1707 if (range_itr == ranges_.end()) | |
| 1708 return; | |
| 1709 | |
| 1710 const DecodeTimestamp max_splice_end_dts = | |
| 1711 splice_dts + base::TimeDelta::FromMilliseconds( | |
| 1712 AudioSplicer::kCrossfadeDurationInMilliseconds); | |
| 1713 | |
| 1714 // Find all buffers involved before the splice point. | |
| 1715 BufferQueue pre_splice_buffers; | |
| 1716 if (!(*range_itr)->GetBuffersInRange( | |
| 1717 splice_dts, max_splice_end_dts, &pre_splice_buffers)) { | |
| 1718 return; | |
| 1719 } | |
| 1720 | |
| 1721 // If there are gaps in the timeline, it's possible that we only find buffers | |
| 1722 // after the splice point but within the splice range. For simplicity, we do | |
| 1723 // not generate splice frames in this case. | |
| 1724 // | |
| 1725 // We also do not want to generate splices if the first new buffer replaces an | |
| 1726 // existing buffer exactly. | |
| 1727 if (pre_splice_buffers.front()->timestamp() >= splice_timestamp) { | |
| 1728 LIMITED_MEDIA_LOG(DEBUG, media_log_, num_splice_generation_warning_logs_, | |
| 1729 kMaxSpliceGenerationWarningLogs) | |
| 1730 << "Skipping splice frame generation: first new buffer at " | |
| 1731 << splice_timestamp.InMicroseconds() | |
| 1732 << "us begins at or before existing buffer at " | |
| 1733 << pre_splice_buffers.front()->timestamp().InMicroseconds() << "us."; | |
| 1734 DVLOG(1) << "Skipping splice: overlapped buffers begin at or after the " | |
| 1735 "first new buffer."; | |
| 1736 return; | |
| 1737 } | |
| 1738 | |
| 1739 // If any |pre_splice_buffers| are already splices or preroll, do not generate | |
| 1740 // a splice. | |
| 1741 for (size_t i = 0; i < pre_splice_buffers.size(); ++i) { | |
| 1742 const BufferQueue& original_splice_buffers = | |
| 1743 pre_splice_buffers[i]->splice_buffers(); | |
| 1744 if (!original_splice_buffers.empty()) { | |
| 1745 LIMITED_MEDIA_LOG(DEBUG, media_log_, num_splice_generation_warning_logs_, | |
| 1746 kMaxSpliceGenerationWarningLogs) | |
| 1747 << "Skipping splice frame generation: overlapped buffers at " | |
| 1748 << pre_splice_buffers[i]->timestamp().InMicroseconds() | |
| 1749 << "us are in a previously buffered splice."; | |
| 1750 DVLOG(1) << "Can't generate splice: overlapped buffers contain a " | |
| 1751 "pre-existing splice."; | |
| 1752 return; | |
| 1753 } | |
| 1754 | |
| 1755 if (pre_splice_buffers[i]->preroll_buffer().get()) { | |
| 1756 LIMITED_MEDIA_LOG(DEBUG, media_log_, num_splice_generation_warning_logs_, | |
| 1757 kMaxSpliceGenerationWarningLogs) | |
| 1758 << "Skipping splice frame generation: overlapped buffers at " | |
| 1759 << pre_splice_buffers[i]->timestamp().InMicroseconds() | |
| 1760 << "us contain preroll."; | |
| 1761 DVLOG(1) << "Can't generate splice: overlapped buffers contain preroll."; | |
| 1762 return; | |
| 1763 } | |
| 1764 } | |
| 1765 | |
| 1766 // Don't generate splice frames which represent less than a millisecond (which | |
|
DaleCurtis
2016/09/16 21:01:04
Probably you want to carry this over to avoid bad
chcunningham
2016/09/16 22:25:24
Done.
| |
| 1767 // is frequently the extent of timestamp resolution for poorly encoded media) | |
| 1768 // or less than two samples (need at least two to crossfade). | |
| 1769 const base::TimeDelta splice_duration = | |
| 1770 pre_splice_buffers.back()->timestamp() + | |
| 1771 pre_splice_buffers.back()->duration() - splice_timestamp; | |
| 1772 const base::TimeDelta minimum_splice_duration = std::max( | |
| 1773 base::TimeDelta::FromMilliseconds(1), | |
| 1774 base::TimeDelta::FromSecondsD( | |
| 1775 2.0 / audio_configs_[append_config_index_].samples_per_second())); | |
| 1776 if (splice_duration < minimum_splice_duration) { | |
| 1777 LIMITED_MEDIA_LOG(DEBUG, media_log_, num_splice_generation_warning_logs_, | |
| 1778 kMaxSpliceGenerationWarningLogs) | |
| 1779 << "Skipping splice frame generation: not enough samples for splicing " | |
| 1780 "new buffer at " | |
| 1781 << splice_timestamp.InMicroseconds() << "us. Have " | |
| 1782 << splice_duration.InMicroseconds() << "us, but need " | |
| 1783 << minimum_splice_duration.InMicroseconds() << "us."; | |
| 1784 DVLOG(1) << "Can't generate splice: not enough samples for crossfade; have " | |
| 1785 << splice_duration.InMicroseconds() << "us, but need " | |
| 1786 << minimum_splice_duration.InMicroseconds() << "us."; | |
| 1787 return; | |
| 1788 } | |
| 1789 | |
| 1790 DVLOG(1) << "Generating splice frame @ " << new_buffers.front()->timestamp() | |
| 1791 << ", splice duration: " << splice_duration.InMicroseconds() | |
| 1792 << " us"; | |
| 1793 LIMITED_MEDIA_LOG(DEBUG, media_log_, num_splice_generation_success_logs_, | |
| 1794 kMaxSpliceGenerationSuccessLogs) | |
| 1795 << "Generated splice of overlap duration " | |
| 1796 << splice_duration.InMicroseconds() << "us into new buffer at " | |
| 1797 << splice_timestamp.InMicroseconds() << "us."; | |
| 1798 new_buffers.front()->ConvertToSpliceBuffer(pre_splice_buffers); | |
| 1799 } | |
| 1800 | |
| 1801 bool SourceBufferStream::SetPendingBuffer( | 1679 bool SourceBufferStream::SetPendingBuffer( |
| 1802 scoped_refptr<StreamParserBuffer>* out_buffer) { | 1680 scoped_refptr<StreamParserBuffer>* out_buffer) { |
| 1803 DCHECK(out_buffer->get()); | 1681 DCHECK(out_buffer->get()); |
| 1804 DCHECK(!pending_buffer_.get()); | 1682 DCHECK(!pending_buffer_.get()); |
| 1805 | 1683 |
| 1806 const bool have_splice_buffers = !(*out_buffer)->splice_buffers().empty(); | |
| 1807 const bool have_preroll_buffer = !!(*out_buffer)->preroll_buffer().get(); | 1684 const bool have_preroll_buffer = !!(*out_buffer)->preroll_buffer().get(); |
| 1808 | 1685 |
| 1809 if (!have_splice_buffers && !have_preroll_buffer) | 1686 if (!have_preroll_buffer) |
| 1810 return false; | 1687 return false; |
| 1811 | 1688 |
| 1812 DCHECK_NE(have_splice_buffers, have_preroll_buffer); | |
| 1813 splice_buffers_index_ = 0; | |
| 1814 pending_buffer_.swap(*out_buffer); | 1689 pending_buffer_.swap(*out_buffer); |
| 1815 pending_buffers_complete_ = false; | 1690 pending_buffers_complete_ = false; |
| 1816 return true; | 1691 return true; |
| 1817 } | 1692 } |
| 1818 | 1693 |
| 1819 } // namespace media | 1694 } // namespace media |
| OLD | NEW |