| 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 | 10 |
| 11 #include "base/bind.h" | 11 #include "base/bind.h" |
| 12 #include "base/logging.h" | 12 #include "base/logging.h" |
| 13 #include "base/trace_event/trace_event.h" | 13 #include "base/trace_event/trace_event.h" |
| 14 #include "media/base/audio_splicer.h" | 14 #include "media/base/audio_splicer.h" |
| 15 #include "media/filters/source_buffer_platform.h" | 15 #include "media/filters/source_buffer_platform.h" |
| 16 #include "media/filters/source_buffer_range.h" | 16 #include "media/filters/source_buffer_range.h" |
| 17 | 17 |
| 18 namespace media { | 18 namespace media { |
| 19 | 19 |
| 20 namespace { |
| 21 |
| 22 enum { |
| 23 // An arbitrarily-chosen number to estimate the duration of a buffer if none |
| 24 // is set and there's not enough information to get a better estimate. |
| 25 kDefaultBufferDurationInMs = 125, |
| 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 kMaxSpliceGenerationWarningLogs = 50, |
| 32 kMaxSpliceGenerationSuccessLogs = 20, |
| 33 }; |
| 34 |
| 20 // Helper method that returns true if |ranges| is sorted in increasing order, | 35 // Helper method that returns true if |ranges| is sorted in increasing order, |
| 21 // false otherwise. | 36 // false otherwise. |
| 22 static bool IsRangeListSorted( | 37 bool IsRangeListSorted(const std::list<media::SourceBufferRange*>& ranges) { |
| 23 const std::list<media::SourceBufferRange*>& ranges) { | |
| 24 DecodeTimestamp prev = kNoDecodeTimestamp(); | 38 DecodeTimestamp prev = kNoDecodeTimestamp(); |
| 25 for (std::list<SourceBufferRange*>::const_iterator itr = | 39 for (std::list<SourceBufferRange*>::const_iterator itr = |
| 26 ranges.begin(); itr != ranges.end(); ++itr) { | 40 ranges.begin(); itr != ranges.end(); ++itr) { |
| 27 if (prev != kNoDecodeTimestamp() && prev >= (*itr)->GetStartTimestamp()) | 41 if (prev != kNoDecodeTimestamp() && prev >= (*itr)->GetStartTimestamp()) |
| 28 return false; | 42 return false; |
| 29 prev = (*itr)->GetEndTimestamp(); | 43 prev = (*itr)->GetEndTimestamp(); |
| 30 } | 44 } |
| 31 return true; | 45 return true; |
| 32 } | 46 } |
| 33 | 47 |
| 34 // Returns an estimate of how far from the beginning or end of a range a buffer | 48 // Returns an estimate of how far from the beginning or end of a range a buffer |
| 35 // can be to still be considered in the range, given the |approximate_duration| | 49 // can be to still be considered in the range, given the |approximate_duration| |
| 36 // of a buffer in the stream. | 50 // of a buffer in the stream. |
| 37 // TODO(wolenetz): Once all stream parsers emit accurate frame durations, use | 51 // TODO(wolenetz): Once all stream parsers emit accurate frame durations, use |
| 38 // logic like FrameProcessor (2*last_frame_duration + last_decode_timestamp) | 52 // logic like FrameProcessor (2*last_frame_duration + last_decode_timestamp) |
| 39 // instead of an overall maximum interbuffer delta for range discontinuity | 53 // instead of an overall maximum interbuffer delta for range discontinuity |
| 40 // detection, and adjust similarly for splice frame discontinuity detection. | 54 // detection, and adjust similarly for splice frame discontinuity detection. |
| 41 // See http://crbug.com/351489 and http://crbug.com/351166. | 55 // See http://crbug.com/351489 and http://crbug.com/351166. |
| 42 static base::TimeDelta ComputeFudgeRoom(base::TimeDelta approximate_duration) { | 56 base::TimeDelta ComputeFudgeRoom(base::TimeDelta approximate_duration) { |
| 43 // Because we do not know exactly when is the next timestamp, any buffer | 57 // Because we do not know exactly when is the next timestamp, any buffer |
| 44 // that starts within 2x the approximate duration of a buffer is considered | 58 // that starts within 2x the approximate duration of a buffer is considered |
| 45 // within this range. | 59 // within this range. |
| 46 return 2 * approximate_duration; | 60 return 2 * approximate_duration; |
| 47 } | 61 } |
| 48 | 62 |
| 49 // An arbitrarily-chosen number to estimate the duration of a buffer if none | |
| 50 // is set and there's not enough information to get a better estimate. | |
| 51 static int kDefaultBufferDurationInMs = 125; | |
| 52 | |
| 53 // The amount of time the beginning of the buffered data can differ from the | 63 // The amount of time the beginning of the buffered data can differ from the |
| 54 // start time in order to still be considered the start of stream. | 64 // start time in order to still be considered the start of stream. |
| 55 static base::TimeDelta kSeekToStartFudgeRoom() { | 65 base::TimeDelta kSeekToStartFudgeRoom() { |
| 56 return base::TimeDelta::FromMilliseconds(1000); | 66 return base::TimeDelta::FromMilliseconds(1000); |
| 57 } | 67 } |
| 58 | 68 |
| 59 // Helper method for logging, converts a range into a readable string. | 69 // Helper method for logging, converts a range into a readable string. |
| 60 static std::string RangeToString(const SourceBufferRange& range) { | 70 std::string RangeToString(const SourceBufferRange& range) { |
| 61 std::stringstream ss; | 71 std::stringstream ss; |
| 62 ss << "[" << range.GetStartTimestamp().InSecondsF() | 72 ss << "[" << range.GetStartTimestamp().InSecondsF() |
| 63 << ";" << range.GetEndTimestamp().InSecondsF() | 73 << ";" << range.GetEndTimestamp().InSecondsF() |
| 64 << "(" << range.GetBufferedEndTimestamp().InSecondsF() << ")]"; | 74 << "(" << range.GetBufferedEndTimestamp().InSecondsF() << ")]"; |
| 65 return ss.str(); | 75 return ss.str(); |
| 66 } | 76 } |
| 67 | 77 |
| 68 // Helper method for logging, converts a set of ranges into a readable string. | 78 // Helper method for logging, converts a set of ranges into a readable string. |
| 69 static std::string RangesToString(const SourceBufferStream::RangeList& ranges) { | 79 std::string RangesToString(const SourceBufferStream::RangeList& ranges) { |
| 70 if (ranges.empty()) | 80 if (ranges.empty()) |
| 71 return "<EMPTY>"; | 81 return "<EMPTY>"; |
| 72 | 82 |
| 73 std::stringstream ss; | 83 std::stringstream ss; |
| 74 for (const auto* range_ptr : ranges) { | 84 for (const auto* range_ptr : ranges) { |
| 75 if (range_ptr != ranges.front()) | 85 if (range_ptr != ranges.front()) |
| 76 ss << " "; | 86 ss << " "; |
| 77 ss << RangeToString(*range_ptr); | 87 ss << RangeToString(*range_ptr); |
| 78 } | 88 } |
| 79 return ss.str(); | 89 return ss.str(); |
| 80 } | 90 } |
| 81 | 91 |
| 82 static SourceBufferRange::GapPolicy TypeToGapPolicy( | 92 SourceBufferRange::GapPolicy TypeToGapPolicy(SourceBufferStream::Type type) { |
| 83 SourceBufferStream::Type type) { | |
| 84 switch (type) { | 93 switch (type) { |
| 85 case SourceBufferStream::kAudio: | 94 case SourceBufferStream::kAudio: |
| 86 case SourceBufferStream::kVideo: | 95 case SourceBufferStream::kVideo: |
| 87 return SourceBufferRange::NO_GAPS_ALLOWED; | 96 return SourceBufferRange::NO_GAPS_ALLOWED; |
| 88 case SourceBufferStream::kText: | 97 case SourceBufferStream::kText: |
| 89 return SourceBufferRange::ALLOW_GAPS; | 98 return SourceBufferRange::ALLOW_GAPS; |
| 90 } | 99 } |
| 91 | 100 |
| 92 NOTREACHED(); | 101 NOTREACHED(); |
| 93 return SourceBufferRange::NO_GAPS_ALLOWED; | 102 return SourceBufferRange::NO_GAPS_ALLOWED; |
| 94 } | 103 } |
| 95 | 104 |
| 105 } // namespace |
| 106 |
| 96 SourceBufferStream::SourceBufferStream(const AudioDecoderConfig& audio_config, | 107 SourceBufferStream::SourceBufferStream(const AudioDecoderConfig& audio_config, |
| 97 const scoped_refptr<MediaLog>& media_log, | 108 const scoped_refptr<MediaLog>& media_log, |
| 98 bool splice_frames_enabled) | 109 bool splice_frames_enabled) |
| 99 : media_log_(media_log), | 110 : media_log_(media_log), |
| 100 current_config_index_(0), | 111 current_config_index_(0), |
| 101 append_config_index_(0), | 112 append_config_index_(0), |
| 102 seek_pending_(false), | 113 seek_pending_(false), |
| 103 end_of_stream_(false), | 114 end_of_stream_(false), |
| 104 seek_buffer_timestamp_(kNoTimestamp()), | 115 seek_buffer_timestamp_(kNoTimestamp()), |
| 105 selected_range_(NULL), | 116 selected_range_(NULL), |
| 106 media_segment_start_time_(kNoDecodeTimestamp()), | 117 media_segment_start_time_(kNoDecodeTimestamp()), |
| 107 range_for_next_append_(ranges_.end()), | 118 range_for_next_append_(ranges_.end()), |
| 108 new_media_segment_(false), | 119 new_media_segment_(false), |
| 109 last_appended_buffer_timestamp_(kNoDecodeTimestamp()), | 120 last_appended_buffer_timestamp_(kNoDecodeTimestamp()), |
| 110 last_appended_buffer_is_keyframe_(false), | 121 last_appended_buffer_is_keyframe_(false), |
| 111 last_output_buffer_timestamp_(kNoDecodeTimestamp()), | 122 last_output_buffer_timestamp_(kNoDecodeTimestamp()), |
| 112 max_interbuffer_distance_(kNoTimestamp()), | 123 max_interbuffer_distance_(kNoTimestamp()), |
| 113 memory_limit_(kSourceBufferAudioMemoryLimit), | 124 memory_limit_(kSourceBufferAudioMemoryLimit), |
| 114 config_change_pending_(false), | 125 config_change_pending_(false), |
| 115 splice_buffers_index_(0), | 126 splice_buffers_index_(0), |
| 116 pending_buffers_complete_(false), | 127 pending_buffers_complete_(false), |
| 117 splice_frames_enabled_(splice_frames_enabled) { | 128 splice_frames_enabled_(splice_frames_enabled), |
| 129 num_splice_generation_warning_logs_(0), |
| 130 num_splice_generation_success_logs_(0) { |
| 118 DCHECK(audio_config.IsValidConfig()); | 131 DCHECK(audio_config.IsValidConfig()); |
| 119 audio_configs_.push_back(audio_config); | 132 audio_configs_.push_back(audio_config); |
| 120 } | 133 } |
| 121 | 134 |
| 122 SourceBufferStream::SourceBufferStream(const VideoDecoderConfig& video_config, | 135 SourceBufferStream::SourceBufferStream(const VideoDecoderConfig& video_config, |
| 123 const scoped_refptr<MediaLog>& media_log, | 136 const scoped_refptr<MediaLog>& media_log, |
| 124 bool splice_frames_enabled) | 137 bool splice_frames_enabled) |
| 125 : media_log_(media_log), | 138 : media_log_(media_log), |
| 126 current_config_index_(0), | 139 current_config_index_(0), |
| 127 append_config_index_(0), | 140 append_config_index_(0), |
| 128 seek_pending_(false), | 141 seek_pending_(false), |
| 129 end_of_stream_(false), | 142 end_of_stream_(false), |
| 130 seek_buffer_timestamp_(kNoTimestamp()), | 143 seek_buffer_timestamp_(kNoTimestamp()), |
| 131 selected_range_(NULL), | 144 selected_range_(NULL), |
| 132 media_segment_start_time_(kNoDecodeTimestamp()), | 145 media_segment_start_time_(kNoDecodeTimestamp()), |
| 133 range_for_next_append_(ranges_.end()), | 146 range_for_next_append_(ranges_.end()), |
| 134 new_media_segment_(false), | 147 new_media_segment_(false), |
| 135 last_appended_buffer_timestamp_(kNoDecodeTimestamp()), | 148 last_appended_buffer_timestamp_(kNoDecodeTimestamp()), |
| 136 last_appended_buffer_is_keyframe_(false), | 149 last_appended_buffer_is_keyframe_(false), |
| 137 last_output_buffer_timestamp_(kNoDecodeTimestamp()), | 150 last_output_buffer_timestamp_(kNoDecodeTimestamp()), |
| 138 max_interbuffer_distance_(kNoTimestamp()), | 151 max_interbuffer_distance_(kNoTimestamp()), |
| 139 memory_limit_(kSourceBufferVideoMemoryLimit), | 152 memory_limit_(kSourceBufferVideoMemoryLimit), |
| 140 config_change_pending_(false), | 153 config_change_pending_(false), |
| 141 splice_buffers_index_(0), | 154 splice_buffers_index_(0), |
| 142 pending_buffers_complete_(false), | 155 pending_buffers_complete_(false), |
| 143 splice_frames_enabled_(splice_frames_enabled) { | 156 splice_frames_enabled_(splice_frames_enabled), |
| 157 num_splice_generation_warning_logs_(0), |
| 158 num_splice_generation_success_logs_(0) { |
| 144 DCHECK(video_config.IsValidConfig()); | 159 DCHECK(video_config.IsValidConfig()); |
| 145 video_configs_.push_back(video_config); | 160 video_configs_.push_back(video_config); |
| 146 } | 161 } |
| 147 | 162 |
| 148 SourceBufferStream::SourceBufferStream(const TextTrackConfig& text_config, | 163 SourceBufferStream::SourceBufferStream(const TextTrackConfig& text_config, |
| 149 const scoped_refptr<MediaLog>& media_log, | 164 const scoped_refptr<MediaLog>& media_log, |
| 150 bool splice_frames_enabled) | 165 bool splice_frames_enabled) |
| 151 : media_log_(media_log), | 166 : media_log_(media_log), |
| 152 current_config_index_(0), | 167 current_config_index_(0), |
| 153 append_config_index_(0), | 168 append_config_index_(0), |
| 154 text_track_config_(text_config), | 169 text_track_config_(text_config), |
| 155 seek_pending_(false), | 170 seek_pending_(false), |
| 156 end_of_stream_(false), | 171 end_of_stream_(false), |
| 157 seek_buffer_timestamp_(kNoTimestamp()), | 172 seek_buffer_timestamp_(kNoTimestamp()), |
| 158 selected_range_(NULL), | 173 selected_range_(NULL), |
| 159 media_segment_start_time_(kNoDecodeTimestamp()), | 174 media_segment_start_time_(kNoDecodeTimestamp()), |
| 160 range_for_next_append_(ranges_.end()), | 175 range_for_next_append_(ranges_.end()), |
| 161 new_media_segment_(false), | 176 new_media_segment_(false), |
| 162 last_appended_buffer_timestamp_(kNoDecodeTimestamp()), | 177 last_appended_buffer_timestamp_(kNoDecodeTimestamp()), |
| 163 last_appended_buffer_is_keyframe_(false), | 178 last_appended_buffer_is_keyframe_(false), |
| 164 last_output_buffer_timestamp_(kNoDecodeTimestamp()), | 179 last_output_buffer_timestamp_(kNoDecodeTimestamp()), |
| 165 max_interbuffer_distance_(kNoTimestamp()), | 180 max_interbuffer_distance_(kNoTimestamp()), |
| 166 memory_limit_(kSourceBufferAudioMemoryLimit), | 181 memory_limit_(kSourceBufferAudioMemoryLimit), |
| 167 config_change_pending_(false), | 182 config_change_pending_(false), |
| 168 splice_buffers_index_(0), | 183 splice_buffers_index_(0), |
| 169 pending_buffers_complete_(false), | 184 pending_buffers_complete_(false), |
| 170 splice_frames_enabled_(splice_frames_enabled) { | 185 splice_frames_enabled_(splice_frames_enabled), |
| 171 } | 186 num_splice_generation_warning_logs_(0), |
| 187 num_splice_generation_success_logs_(0) {} |
| 172 | 188 |
| 173 SourceBufferStream::~SourceBufferStream() { | 189 SourceBufferStream::~SourceBufferStream() { |
| 174 while (!ranges_.empty()) { | 190 while (!ranges_.empty()) { |
| 175 delete ranges_.front(); | 191 delete ranges_.front(); |
| 176 ranges_.pop_front(); | 192 ranges_.pop_front(); |
| 177 } | 193 } |
| 178 } | 194 } |
| 179 | 195 |
| 180 void SourceBufferStream::OnNewMediaSegment( | 196 void SourceBufferStream::OnNewMediaSegment( |
| 181 DecodeTimestamp media_segment_start_time) { | 197 DecodeTimestamp media_segment_start_time) { |
| (...skipping 1359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1541 splice_dts, max_splice_end_dts, &pre_splice_buffers)) { | 1557 splice_dts, max_splice_end_dts, &pre_splice_buffers)) { |
| 1542 return; | 1558 return; |
| 1543 } | 1559 } |
| 1544 | 1560 |
| 1545 // If there are gaps in the timeline, it's possible that we only find buffers | 1561 // If there are gaps in the timeline, it's possible that we only find buffers |
| 1546 // after the splice point but within the splice range. For simplicity, we do | 1562 // after the splice point but within the splice range. For simplicity, we do |
| 1547 // not generate splice frames in this case. | 1563 // not generate splice frames in this case. |
| 1548 // | 1564 // |
| 1549 // We also do not want to generate splices if the first new buffer replaces an | 1565 // We also do not want to generate splices if the first new buffer replaces an |
| 1550 // existing buffer exactly. | 1566 // existing buffer exactly. |
| 1551 if (pre_splice_buffers.front()->timestamp() >= splice_timestamp) | 1567 if (pre_splice_buffers.front()->timestamp() >= splice_timestamp) { |
| 1568 LIMITED_MEDIA_LOG(DEBUG, media_log_, num_splice_generation_warning_logs_, |
| 1569 kMaxSpliceGenerationWarningLogs) |
| 1570 << "Skipping splice frame generation: first new buffer at " |
| 1571 << splice_timestamp.InMicroseconds() |
| 1572 << "us begins at or before existing buffer at " |
| 1573 << pre_splice_buffers.front()->timestamp().InMicroseconds() << "us."; |
| 1574 DVLOG(1) << "Skipping splice: overlapped buffers begin at or after the " |
| 1575 "first new buffer."; |
| 1552 return; | 1576 return; |
| 1577 } |
| 1553 | 1578 |
| 1554 // If any |pre_splice_buffers| are already splices or preroll, do not generate | 1579 // If any |pre_splice_buffers| are already splices or preroll, do not generate |
| 1555 // a splice. | 1580 // a splice. |
| 1556 for (size_t i = 0; i < pre_splice_buffers.size(); ++i) { | 1581 for (size_t i = 0; i < pre_splice_buffers.size(); ++i) { |
| 1557 const BufferQueue& original_splice_buffers = | 1582 const BufferQueue& original_splice_buffers = |
| 1558 pre_splice_buffers[i]->splice_buffers(); | 1583 pre_splice_buffers[i]->splice_buffers(); |
| 1559 if (!original_splice_buffers.empty()) { | 1584 if (!original_splice_buffers.empty()) { |
| 1585 LIMITED_MEDIA_LOG(DEBUG, media_log_, num_splice_generation_warning_logs_, |
| 1586 kMaxSpliceGenerationWarningLogs) |
| 1587 << "Skipping splice frame generation: overlapped buffers at " |
| 1588 << pre_splice_buffers[i]->timestamp().InMicroseconds() |
| 1589 << "us are in a previously buffered splice."; |
| 1560 DVLOG(1) << "Can't generate splice: overlapped buffers contain a " | 1590 DVLOG(1) << "Can't generate splice: overlapped buffers contain a " |
| 1561 "pre-existing splice."; | 1591 "pre-existing splice."; |
| 1562 return; | 1592 return; |
| 1563 } | 1593 } |
| 1564 | 1594 |
| 1565 if (pre_splice_buffers[i]->preroll_buffer().get()) { | 1595 if (pre_splice_buffers[i]->preroll_buffer().get()) { |
| 1596 LIMITED_MEDIA_LOG(DEBUG, media_log_, num_splice_generation_warning_logs_, |
| 1597 kMaxSpliceGenerationWarningLogs) |
| 1598 << "Skipping splice frame generation: overlapped buffers at " |
| 1599 << pre_splice_buffers[i]->timestamp().InMicroseconds() |
| 1600 << "us contain preroll."; |
| 1566 DVLOG(1) << "Can't generate splice: overlapped buffers contain preroll."; | 1601 DVLOG(1) << "Can't generate splice: overlapped buffers contain preroll."; |
| 1567 return; | 1602 return; |
| 1568 } | 1603 } |
| 1569 } | 1604 } |
| 1570 | 1605 |
| 1571 // Don't generate splice frames which represent less than a millisecond (which | 1606 // Don't generate splice frames which represent less than a millisecond (which |
| 1572 // is frequently the extent of timestamp resolution for poorly encoded media) | 1607 // is frequently the extent of timestamp resolution for poorly encoded media) |
| 1573 // or less than two frames (need at least two to crossfade). | 1608 // or less than two samples (need at least two to crossfade). |
| 1574 const base::TimeDelta splice_duration = | 1609 const base::TimeDelta splice_duration = |
| 1575 pre_splice_buffers.back()->timestamp() + | 1610 pre_splice_buffers.back()->timestamp() + |
| 1576 pre_splice_buffers.back()->duration() - splice_timestamp; | 1611 pre_splice_buffers.back()->duration() - splice_timestamp; |
| 1577 const base::TimeDelta minimum_splice_duration = std::max( | 1612 const base::TimeDelta minimum_splice_duration = std::max( |
| 1578 base::TimeDelta::FromMilliseconds(1), | 1613 base::TimeDelta::FromMilliseconds(1), |
| 1579 base::TimeDelta::FromSecondsD( | 1614 base::TimeDelta::FromSecondsD( |
| 1580 2.0 / audio_configs_[append_config_index_].samples_per_second())); | 1615 2.0 / audio_configs_[append_config_index_].samples_per_second())); |
| 1581 if (splice_duration < minimum_splice_duration) { | 1616 if (splice_duration < minimum_splice_duration) { |
| 1617 LIMITED_MEDIA_LOG(DEBUG, media_log_, num_splice_generation_warning_logs_, |
| 1618 kMaxSpliceGenerationWarningLogs) |
| 1619 << "Skipping splice frame generation: not enough samples for splicing " |
| 1620 "new buffer at " |
| 1621 << splice_timestamp.InMicroseconds() << "us. Have " |
| 1622 << splice_duration.InMicroseconds() << "us, but need " |
| 1623 << minimum_splice_duration.InMicroseconds() << "us."; |
| 1582 DVLOG(1) << "Can't generate splice: not enough samples for crossfade; have " | 1624 DVLOG(1) << "Can't generate splice: not enough samples for crossfade; have " |
| 1583 << splice_duration.InMicroseconds() << " us, but need " | 1625 << splice_duration.InMicroseconds() << "us, but need " |
| 1584 << minimum_splice_duration.InMicroseconds() << " us."; | 1626 << minimum_splice_duration.InMicroseconds() << "us."; |
| 1585 return; | 1627 return; |
| 1586 } | 1628 } |
| 1587 | 1629 |
| 1588 DVLOG(1) << "Generating splice frame @ " << new_buffers.front()->timestamp() | 1630 DVLOG(1) << "Generating splice frame @ " << new_buffers.front()->timestamp() |
| 1589 << ", splice duration: " << splice_duration.InMicroseconds() | 1631 << ", splice duration: " << splice_duration.InMicroseconds() |
| 1590 << " us"; | 1632 << " us"; |
| 1633 LIMITED_MEDIA_LOG(DEBUG, media_log_, num_splice_generation_success_logs_, |
| 1634 kMaxSpliceGenerationSuccessLogs) |
| 1635 << "Generated splice of overlap duration " |
| 1636 << splice_duration.InMicroseconds() << "us into new buffer at " |
| 1637 << splice_timestamp.InMicroseconds() << "us."; |
| 1591 new_buffers.front()->ConvertToSpliceBuffer(pre_splice_buffers); | 1638 new_buffers.front()->ConvertToSpliceBuffer(pre_splice_buffers); |
| 1592 } | 1639 } |
| 1593 | 1640 |
| 1594 bool SourceBufferStream::SetPendingBuffer( | 1641 bool SourceBufferStream::SetPendingBuffer( |
| 1595 scoped_refptr<StreamParserBuffer>* out_buffer) { | 1642 scoped_refptr<StreamParserBuffer>* out_buffer) { |
| 1596 DCHECK(out_buffer->get()); | 1643 DCHECK(out_buffer->get()); |
| 1597 DCHECK(!pending_buffer_.get()); | 1644 DCHECK(!pending_buffer_.get()); |
| 1598 | 1645 |
| 1599 const bool have_splice_buffers = !(*out_buffer)->splice_buffers().empty(); | 1646 const bool have_splice_buffers = !(*out_buffer)->splice_buffers().empty(); |
| 1600 const bool have_preroll_buffer = !!(*out_buffer)->preroll_buffer().get(); | 1647 const bool have_preroll_buffer = !!(*out_buffer)->preroll_buffer().get(); |
| 1601 | 1648 |
| 1602 if (!have_splice_buffers && !have_preroll_buffer) | 1649 if (!have_splice_buffers && !have_preroll_buffer) |
| 1603 return false; | 1650 return false; |
| 1604 | 1651 |
| 1605 DCHECK_NE(have_splice_buffers, have_preroll_buffer); | 1652 DCHECK_NE(have_splice_buffers, have_preroll_buffer); |
| 1606 splice_buffers_index_ = 0; | 1653 splice_buffers_index_ = 0; |
| 1607 pending_buffer_.swap(*out_buffer); | 1654 pending_buffer_.swap(*out_buffer); |
| 1608 pending_buffers_complete_ = false; | 1655 pending_buffers_complete_ = false; |
| 1609 return true; | 1656 return true; |
| 1610 } | 1657 } |
| 1611 | 1658 |
| 1612 } // namespace media | 1659 } // namespace media |
| OLD | NEW |