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

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: Address comments from PS2 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
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
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
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