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

Side by Side Diff: media/filters/source_buffer_stream.cc

Issue 1236543007: MSE: Log buffered audio splice generation to media-internals (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Use LIMITED_MEDIA_LOG instead: simpler impl and more log detail Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « media/filters/source_buffer_stream.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/filters/source_buffer_stream.h" 5 #include "media/filters/source_buffer_stream.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <map> 8 #include <map>
9 #include <sstream> 9 #include <sstream>
10 10
(...skipping 30 matching lines...) Expand all
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
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
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
OLDNEW
« no previous file with comments | « media/filters/source_buffer_stream.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698