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 |
(...skipping 30 matching lines...) Expand all Loading... | |
41 // See http://crbug.com/351489 and http://crbug.com/351166. | 41 // See http://crbug.com/351489 and http://crbug.com/351166. |
42 static base::TimeDelta ComputeFudgeRoom(base::TimeDelta approximate_duration) { | 42 static base::TimeDelta ComputeFudgeRoom(base::TimeDelta approximate_duration) { |
43 // Because we do not know exactly when is the next timestamp, any buffer | 43 // 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 | 44 // that starts within 2x the approximate duration of a buffer is considered |
45 // within this range. | 45 // within this range. |
46 return 2 * approximate_duration; | 46 return 2 * approximate_duration; |
47 } | 47 } |
48 | 48 |
49 // An arbitrarily-chosen number to estimate the duration of a buffer if none | 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. | 50 // is set and there's not enough information to get a better estimate. |
51 static int kDefaultBufferDurationInMs = 125; | 51 static int kDefaultBufferDurationInMs = 125; |
DaleCurtis
2015/07/16 20:39:22
These three should all be marked const.
wolenetz
2015/07/17 17:38:15
Good catch! I've converted these to enum values, a
| |
52 | 52 |
53 // Limit the number of MEDIA_LOG() logs for splice buffer generation warnings | |
DaleCurtis
2015/07/16 20:39:21
I feel like these will be hit really fast.
chcunningham
2015/07/17 01:36:26
I wouldn't have guessed so. Do you expect we have
wolenetz
2015/07/17 17:38:15
I think there is room to increase, though there is
DaleCurtis
2015/07/17 18:22:34
Yes I definitely think we need a more programmatic
| |
54 // and successes. | |
55 static int kMaxSpliceGenerationWarningLogs = 5; | |
56 static int kMaxSpliceGenerationSuccessLogs = 5; | |
57 | |
53 // The amount of time the beginning of the buffered data can differ from the | 58 // 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. | 59 // start time in order to still be considered the start of stream. |
55 static base::TimeDelta kSeekToStartFudgeRoom() { | 60 static base::TimeDelta kSeekToStartFudgeRoom() { |
56 return base::TimeDelta::FromMilliseconds(1000); | 61 return base::TimeDelta::FromMilliseconds(1000); |
57 } | 62 } |
58 | 63 |
59 // Helper method for logging, converts a range into a readable string. | 64 // Helper method for logging, converts a range into a readable string. |
60 static std::string RangeToString(const SourceBufferRange& range) { | 65 static std::string RangeToString(const SourceBufferRange& range) { |
61 std::stringstream ss; | 66 std::stringstream ss; |
62 ss << "[" << range.GetStartTimestamp().InSecondsF() | 67 ss << "[" << range.GetStartTimestamp().InSecondsF() |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
107 range_for_next_append_(ranges_.end()), | 112 range_for_next_append_(ranges_.end()), |
108 new_media_segment_(false), | 113 new_media_segment_(false), |
109 last_appended_buffer_timestamp_(kNoDecodeTimestamp()), | 114 last_appended_buffer_timestamp_(kNoDecodeTimestamp()), |
110 last_appended_buffer_is_keyframe_(false), | 115 last_appended_buffer_is_keyframe_(false), |
111 last_output_buffer_timestamp_(kNoDecodeTimestamp()), | 116 last_output_buffer_timestamp_(kNoDecodeTimestamp()), |
112 max_interbuffer_distance_(kNoTimestamp()), | 117 max_interbuffer_distance_(kNoTimestamp()), |
113 memory_limit_(kSourceBufferAudioMemoryLimit), | 118 memory_limit_(kSourceBufferAudioMemoryLimit), |
114 config_change_pending_(false), | 119 config_change_pending_(false), |
115 splice_buffers_index_(0), | 120 splice_buffers_index_(0), |
116 pending_buffers_complete_(false), | 121 pending_buffers_complete_(false), |
117 splice_frames_enabled_(splice_frames_enabled) { | 122 splice_frames_enabled_(splice_frames_enabled), |
123 num_splice_generation_warning_logs_(0), | |
124 num_splice_generation_success_logs_(0) { | |
118 DCHECK(audio_config.IsValidConfig()); | 125 DCHECK(audio_config.IsValidConfig()); |
119 audio_configs_.push_back(audio_config); | 126 audio_configs_.push_back(audio_config); |
120 } | 127 } |
121 | 128 |
122 SourceBufferStream::SourceBufferStream(const VideoDecoderConfig& video_config, | 129 SourceBufferStream::SourceBufferStream(const VideoDecoderConfig& video_config, |
123 const scoped_refptr<MediaLog>& media_log, | 130 const scoped_refptr<MediaLog>& media_log, |
124 bool splice_frames_enabled) | 131 bool splice_frames_enabled) |
125 : media_log_(media_log), | 132 : media_log_(media_log), |
126 current_config_index_(0), | 133 current_config_index_(0), |
127 append_config_index_(0), | 134 append_config_index_(0), |
128 seek_pending_(false), | 135 seek_pending_(false), |
129 end_of_stream_(false), | 136 end_of_stream_(false), |
130 seek_buffer_timestamp_(kNoTimestamp()), | 137 seek_buffer_timestamp_(kNoTimestamp()), |
131 selected_range_(NULL), | 138 selected_range_(NULL), |
132 media_segment_start_time_(kNoDecodeTimestamp()), | 139 media_segment_start_time_(kNoDecodeTimestamp()), |
133 range_for_next_append_(ranges_.end()), | 140 range_for_next_append_(ranges_.end()), |
134 new_media_segment_(false), | 141 new_media_segment_(false), |
135 last_appended_buffer_timestamp_(kNoDecodeTimestamp()), | 142 last_appended_buffer_timestamp_(kNoDecodeTimestamp()), |
136 last_appended_buffer_is_keyframe_(false), | 143 last_appended_buffer_is_keyframe_(false), |
137 last_output_buffer_timestamp_(kNoDecodeTimestamp()), | 144 last_output_buffer_timestamp_(kNoDecodeTimestamp()), |
138 max_interbuffer_distance_(kNoTimestamp()), | 145 max_interbuffer_distance_(kNoTimestamp()), |
139 memory_limit_(kSourceBufferVideoMemoryLimit), | 146 memory_limit_(kSourceBufferVideoMemoryLimit), |
140 config_change_pending_(false), | 147 config_change_pending_(false), |
141 splice_buffers_index_(0), | 148 splice_buffers_index_(0), |
142 pending_buffers_complete_(false), | 149 pending_buffers_complete_(false), |
143 splice_frames_enabled_(splice_frames_enabled) { | 150 splice_frames_enabled_(splice_frames_enabled), |
151 num_splice_generation_warning_logs_(0), | |
152 num_splice_generation_success_logs_(0) { | |
144 DCHECK(video_config.IsValidConfig()); | 153 DCHECK(video_config.IsValidConfig()); |
145 video_configs_.push_back(video_config); | 154 video_configs_.push_back(video_config); |
146 } | 155 } |
147 | 156 |
148 SourceBufferStream::SourceBufferStream(const TextTrackConfig& text_config, | 157 SourceBufferStream::SourceBufferStream(const TextTrackConfig& text_config, |
149 const scoped_refptr<MediaLog>& media_log, | 158 const scoped_refptr<MediaLog>& media_log, |
150 bool splice_frames_enabled) | 159 bool splice_frames_enabled) |
151 : media_log_(media_log), | 160 : media_log_(media_log), |
152 current_config_index_(0), | 161 current_config_index_(0), |
153 append_config_index_(0), | 162 append_config_index_(0), |
154 text_track_config_(text_config), | 163 text_track_config_(text_config), |
155 seek_pending_(false), | 164 seek_pending_(false), |
156 end_of_stream_(false), | 165 end_of_stream_(false), |
157 seek_buffer_timestamp_(kNoTimestamp()), | 166 seek_buffer_timestamp_(kNoTimestamp()), |
158 selected_range_(NULL), | 167 selected_range_(NULL), |
159 media_segment_start_time_(kNoDecodeTimestamp()), | 168 media_segment_start_time_(kNoDecodeTimestamp()), |
160 range_for_next_append_(ranges_.end()), | 169 range_for_next_append_(ranges_.end()), |
161 new_media_segment_(false), | 170 new_media_segment_(false), |
162 last_appended_buffer_timestamp_(kNoDecodeTimestamp()), | 171 last_appended_buffer_timestamp_(kNoDecodeTimestamp()), |
163 last_appended_buffer_is_keyframe_(false), | 172 last_appended_buffer_is_keyframe_(false), |
164 last_output_buffer_timestamp_(kNoDecodeTimestamp()), | 173 last_output_buffer_timestamp_(kNoDecodeTimestamp()), |
165 max_interbuffer_distance_(kNoTimestamp()), | 174 max_interbuffer_distance_(kNoTimestamp()), |
166 memory_limit_(kSourceBufferAudioMemoryLimit), | 175 memory_limit_(kSourceBufferAudioMemoryLimit), |
167 config_change_pending_(false), | 176 config_change_pending_(false), |
168 splice_buffers_index_(0), | 177 splice_buffers_index_(0), |
169 pending_buffers_complete_(false), | 178 pending_buffers_complete_(false), |
170 splice_frames_enabled_(splice_frames_enabled) { | 179 splice_frames_enabled_(splice_frames_enabled), |
171 } | 180 num_splice_generation_warning_logs_(0), |
181 num_splice_generation_success_logs_(0) {} | |
172 | 182 |
173 SourceBufferStream::~SourceBufferStream() { | 183 SourceBufferStream::~SourceBufferStream() { |
174 while (!ranges_.empty()) { | 184 while (!ranges_.empty()) { |
175 delete ranges_.front(); | 185 delete ranges_.front(); |
176 ranges_.pop_front(); | 186 ranges_.pop_front(); |
177 } | 187 } |
178 } | 188 } |
179 | 189 |
180 void SourceBufferStream::OnNewMediaSegment( | 190 void SourceBufferStream::OnNewMediaSegment( |
181 DecodeTimestamp media_segment_start_time) { | 191 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)) { | 1551 splice_dts, max_splice_end_dts, &pre_splice_buffers)) { |
1542 return; | 1552 return; |
1543 } | 1553 } |
1544 | 1554 |
1545 // If there are gaps in the timeline, it's possible that we only find buffers | 1555 // 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 | 1556 // after the splice point but within the splice range. For simplicity, we do |
1547 // not generate splice frames in this case. | 1557 // not generate splice frames in this case. |
1548 // | 1558 // |
1549 // We also do not want to generate splices if the first new buffer replaces an | 1559 // We also do not want to generate splices if the first new buffer replaces an |
1550 // existing buffer exactly. | 1560 // existing buffer exactly. |
1551 if (pre_splice_buffers.front()->timestamp() >= splice_timestamp) | 1561 if (pre_splice_buffers.front()->timestamp() >= splice_timestamp) { |
1562 LIMITED_MEDIA_LOG(DEBUG, media_log_, num_splice_generation_warning_logs_, | |
1563 kMaxSpliceGenerationWarningLogs) | |
1564 << "Skipping splice frame buffering: first new buffer at " | |
DaleCurtis
2015/07/16 20:39:22
s/buffering/generation/ ditto for all the rest.
wolenetz
2015/07/17 17:38:15
Done
| |
1565 << splice_timestamp.InMicroseconds() | |
1566 << "us begins at or before existing buffer at " | |
1567 << pre_splice_buffers.front()->timestamp().InMicroseconds() << "us."; | |
1568 DVLOG(1) << "Skipping splice: overlapped buffers begin at or after the " | |
DaleCurtis
2015/07/16 20:39:21
Do we need both of these?
wolenetz
2015/07/17 17:38:15
I think the DVLOGs have value still (in the LIMITE
| |
1569 "first new buffer."; | |
1552 return; | 1570 return; |
1571 } | |
1553 | 1572 |
1554 // If any |pre_splice_buffers| are already splices or preroll, do not generate | 1573 // If any |pre_splice_buffers| are already splices or preroll, do not generate |
1555 // a splice. | 1574 // a splice. |
1556 for (size_t i = 0; i < pre_splice_buffers.size(); ++i) { | 1575 for (size_t i = 0; i < pre_splice_buffers.size(); ++i) { |
1557 const BufferQueue& original_splice_buffers = | 1576 const BufferQueue& original_splice_buffers = |
1558 pre_splice_buffers[i]->splice_buffers(); | 1577 pre_splice_buffers[i]->splice_buffers(); |
1559 if (!original_splice_buffers.empty()) { | 1578 if (!original_splice_buffers.empty()) { |
1579 LIMITED_MEDIA_LOG(DEBUG, media_log_, num_splice_generation_warning_logs_, | |
1580 kMaxSpliceGenerationWarningLogs) | |
1581 << "Skipping splice frame buffering: overlapped buffers at " | |
1582 << pre_splice_buffers[i]->timestamp().InMicroseconds() | |
1583 << "us are in a previously buffered splice."; | |
1560 DVLOG(1) << "Can't generate splice: overlapped buffers contain a " | 1584 DVLOG(1) << "Can't generate splice: overlapped buffers contain a " |
1561 "pre-existing splice."; | 1585 "pre-existing splice."; |
1562 return; | 1586 return; |
1563 } | 1587 } |
1564 | 1588 |
1565 if (pre_splice_buffers[i]->preroll_buffer().get()) { | 1589 if (pre_splice_buffers[i]->preroll_buffer().get()) { |
1590 LIMITED_MEDIA_LOG(DEBUG, media_log_, num_splice_generation_warning_logs_, | |
1591 kMaxSpliceGenerationWarningLogs) | |
1592 << "Skipping splice frame buffering: overlapped buffers at " | |
1593 << pre_splice_buffers[i]->timestamp().InMicroseconds() | |
1594 << "us contain preroll."; | |
1566 DVLOG(1) << "Can't generate splice: overlapped buffers contain preroll."; | 1595 DVLOG(1) << "Can't generate splice: overlapped buffers contain preroll."; |
1567 return; | 1596 return; |
1568 } | 1597 } |
1569 } | 1598 } |
1570 | 1599 |
1571 // Don't generate splice frames which represent less than a millisecond (which | 1600 // Don't generate splice frames which represent less than a millisecond (which |
1572 // is frequently the extent of timestamp resolution for poorly encoded media) | 1601 // is frequently the extent of timestamp resolution for poorly encoded media) |
1573 // or less than two frames (need at least two to crossfade). | 1602 // or less than two frames (need at least two to crossfade). |
1574 const base::TimeDelta splice_duration = | 1603 const base::TimeDelta splice_duration = |
1575 pre_splice_buffers.back()->timestamp() + | 1604 pre_splice_buffers.back()->timestamp() + |
1576 pre_splice_buffers.back()->duration() - splice_timestamp; | 1605 pre_splice_buffers.back()->duration() - splice_timestamp; |
1577 const base::TimeDelta minimum_splice_duration = std::max( | 1606 const base::TimeDelta minimum_splice_duration = std::max( |
1578 base::TimeDelta::FromMilliseconds(1), | 1607 base::TimeDelta::FromMilliseconds(1), |
1579 base::TimeDelta::FromSecondsD( | 1608 base::TimeDelta::FromSecondsD( |
1580 2.0 / audio_configs_[append_config_index_].samples_per_second())); | 1609 2.0 / audio_configs_[append_config_index_].samples_per_second())); |
1581 if (splice_duration < minimum_splice_duration) { | 1610 if (splice_duration < minimum_splice_duration) { |
1611 LIMITED_MEDIA_LOG(DEBUG, media_log_, num_splice_generation_warning_logs_, | |
1612 kMaxSpliceGenerationWarningLogs) | |
1613 << "Skipping splice frame buffering: not enough samples for splicing " | |
1614 "new buffer at " | |
1615 << splice_timestamp.InMicroseconds() << "us. Have " | |
1616 << splice_duration.InMicroseconds() << "us, but need " | |
1617 << minimum_splice_duration.InMicroseconds() << "us."; | |
1582 DVLOG(1) << "Can't generate splice: not enough samples for crossfade; have " | 1618 DVLOG(1) << "Can't generate splice: not enough samples for crossfade; have " |
1583 << splice_duration.InMicroseconds() << " us, but need " | 1619 << splice_duration.InMicroseconds() << "us, but need " |
1584 << minimum_splice_duration.InMicroseconds() << " us."; | 1620 << minimum_splice_duration.InMicroseconds() << "us."; |
1585 return; | 1621 return; |
1586 } | 1622 } |
1587 | 1623 |
1588 DVLOG(1) << "Generating splice frame @ " << new_buffers.front()->timestamp() | 1624 DVLOG(1) << "Generating splice frame @ " << new_buffers.front()->timestamp() |
1589 << ", splice duration: " << splice_duration.InMicroseconds() | 1625 << ", splice duration: " << splice_duration.InMicroseconds() |
1590 << " us"; | 1626 << " us"; |
1627 LIMITED_MEDIA_LOG(DEBUG, media_log_, num_splice_generation_success_logs_, | |
1628 kMaxSpliceGenerationSuccessLogs) | |
1629 << "Generated splice of overlap duration " | |
1630 << splice_duration.InMicroseconds() << "us into new buffer at " | |
1631 << splice_timestamp.InMicroseconds() << "us."; | |
1591 new_buffers.front()->ConvertToSpliceBuffer(pre_splice_buffers); | 1632 new_buffers.front()->ConvertToSpliceBuffer(pre_splice_buffers); |
1592 } | 1633 } |
1593 | 1634 |
1594 bool SourceBufferStream::SetPendingBuffer( | 1635 bool SourceBufferStream::SetPendingBuffer( |
1595 scoped_refptr<StreamParserBuffer>* out_buffer) { | 1636 scoped_refptr<StreamParserBuffer>* out_buffer) { |
1596 DCHECK(out_buffer->get()); | 1637 DCHECK(out_buffer->get()); |
1597 DCHECK(!pending_buffer_.get()); | 1638 DCHECK(!pending_buffer_.get()); |
1598 | 1639 |
1599 const bool have_splice_buffers = !(*out_buffer)->splice_buffers().empty(); | 1640 const bool have_splice_buffers = !(*out_buffer)->splice_buffers().empty(); |
1600 const bool have_preroll_buffer = !!(*out_buffer)->preroll_buffer().get(); | 1641 const bool have_preroll_buffer = !!(*out_buffer)->preroll_buffer().get(); |
1601 | 1642 |
1602 if (!have_splice_buffers && !have_preroll_buffer) | 1643 if (!have_splice_buffers && !have_preroll_buffer) |
1603 return false; | 1644 return false; |
1604 | 1645 |
1605 DCHECK_NE(have_splice_buffers, have_preroll_buffer); | 1646 DCHECK_NE(have_splice_buffers, have_preroll_buffer); |
1606 splice_buffers_index_ = 0; | 1647 splice_buffers_index_ = 0; |
1607 pending_buffer_.swap(*out_buffer); | 1648 pending_buffer_.swap(*out_buffer); |
1608 pending_buffers_complete_ = false; | 1649 pending_buffers_complete_ = false; |
1609 return true; | 1650 return true; |
1610 } | 1651 } |
1611 | 1652 |
1612 } // namespace media | 1653 } // namespace media |
OLD | NEW |