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

Side by Side Diff: media/base/audio_renderer_mixer.cc

Issue 2067863003: Mixing audio with different latency requirements (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Review comments addressed Created 4 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
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/base/audio_renderer_mixer.h" 5 #include "media/base/audio_renderer_mixer.h"
6 6
7 #include <cmath> 7 #include <cmath>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/bind_helpers.h" 10 #include "base/bind_helpers.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/memory/ptr_util.h" 12 #include "base/memory/ptr_util.h"
13 #include "base/metrics/histogram_macros.h"
13 14
14 namespace media { 15 namespace media {
15 16
16 enum { kPauseDelaySeconds = 10 }; 17 enum { kPauseDelaySeconds = 10 };
17 18
19 // Tracks the maximum value of a counter and logs it into a UMA histogram upon
DaleCurtis 2016/06/29 17:08:55 Feels like there should be some UMA built in for t
20 // each increase of the maximum. NOT thread-safe, make sure it is used under
21 // lock.
22 class AudioRendererMixer::UMAMaxValueTracker {
23 public:
24 UMAMaxValueTracker(const UmaLogCallback& log_callback)
25 : log_callback_(log_callback), count_(0), max_count_(0) {}
26
27 ~UMAMaxValueTracker() {}
28
29 // Increments the counter, updates the maximum.
30 void Increment() {
31 ++count_;
32 if (max_count_ < count_) {
33 max_count_ = count_;
34 log_callback_.Run(max_count_);
35 }
36 }
37
38 // Decrements the counter.
39 void Decrement() {
40 DCHECK_GE(count_, 0);
41 --count_;
42 }
43
44 private:
45 const UmaLogCallback log_callback_;
46 int count_;
47 int max_count_;
48 DISALLOW_COPY_AND_ASSIGN(UMAMaxValueTracker);
49 };
50
18 AudioRendererMixer::AudioRendererMixer(const AudioParameters& output_params, 51 AudioRendererMixer::AudioRendererMixer(const AudioParameters& output_params,
19 scoped_refptr<AudioRendererSink> sink) 52 scoped_refptr<AudioRendererSink> sink,
53 const UmaLogCallback& log_callback)
20 : output_params_(output_params), 54 : output_params_(output_params),
21 audio_sink_(std::move(sink)), 55 audio_sink_(std::move(sink)),
22 master_converter_(output_params, output_params, true), 56 master_converter_(output_params, output_params, true),
23 pause_delay_(base::TimeDelta::FromSeconds(kPauseDelaySeconds)), 57 pause_delay_(base::TimeDelta::FromSeconds(kPauseDelaySeconds)),
24 last_play_time_(base::TimeTicks::Now()), 58 last_play_time_(base::TimeTicks::Now()),
25 // Initialize |playing_| to true since Start() results in an auto-play. 59 // Initialize |playing_| to true since Start() results in an auto-play.
26 playing_(true) { 60 playing_(true),
61 input_count_tracker_(new UMAMaxValueTracker(log_callback)) {
27 DCHECK(audio_sink_); 62 DCHECK(audio_sink_);
28 audio_sink_->Initialize(output_params, this); 63 audio_sink_->Initialize(output_params, this);
29 audio_sink_->Start(); 64 audio_sink_->Start();
30 } 65 }
31 66
32 AudioRendererMixer::~AudioRendererMixer() { 67 AudioRendererMixer::~AudioRendererMixer() {
33 // AudioRendererSink must be stopped before mixer is destructed. 68 // AudioRendererSink must be stopped before mixer is destructed.
34 audio_sink_->Stop(); 69 audio_sink_->Stop();
35 70
36 // Ensure that all mixer inputs have removed themselves prior to destruction. 71 // Ensure that all mixer inputs have removed themselves prior to destruction.
(...skipping 26 matching lines...) Expand all
63 // size requests, disabling FIFO. 98 // size requests, disabling FIFO.
64 new LoopbackAudioConverter( 99 new LoopbackAudioConverter(
65 input_params, output_params_, true)))); 100 input_params, output_params_, true))));
66 converter = result.first; 101 converter = result.first;
67 102
68 // Add newly-created resampler as an input to the master mixer. 103 // Add newly-created resampler as an input to the master mixer.
69 master_converter_.AddInput(converter->second.get()); 104 master_converter_.AddInput(converter->second.get());
70 } 105 }
71 converter->second->AddInput(input); 106 converter->second->AddInput(input);
72 } 107 }
108
109 input_count_tracker_->Increment();
73 } 110 }
74 111
75 void AudioRendererMixer::RemoveMixerInput( 112 void AudioRendererMixer::RemoveMixerInput(
76 const AudioParameters& input_params, 113 const AudioParameters& input_params,
77 AudioConverter::InputCallback* input) { 114 AudioConverter::InputCallback* input) {
78 base::AutoLock auto_lock(lock_); 115 base::AutoLock auto_lock(lock_);
79 116
80 int input_sample_rate = input_params.sample_rate(); 117 int input_sample_rate = input_params.sample_rate();
81 if (is_master_sample_rate(input_sample_rate)) { 118 if (is_master_sample_rate(input_sample_rate)) {
82 master_converter_.RemoveInput(input); 119 master_converter_.RemoveInput(input);
83 } else { 120 } else {
84 AudioConvertersMap::iterator converter = 121 AudioConvertersMap::iterator converter =
85 converters_.find(input_sample_rate); 122 converters_.find(input_sample_rate);
86 DCHECK(converter != converters_.end()); 123 DCHECK(converter != converters_.end());
87 converter->second->RemoveInput(input); 124 converter->second->RemoveInput(input);
88 if (converter->second->empty()) { 125 if (converter->second->empty()) {
89 // Remove converter when it's empty. 126 // Remove converter when it's empty.
90 master_converter_.RemoveInput(converter->second.get()); 127 master_converter_.RemoveInput(converter->second.get());
91 converters_.erase(converter); 128 converters_.erase(converter);
92 } 129 }
93 } 130 }
131
132 input_count_tracker_->Decrement();
94 } 133 }
95 134
96 void AudioRendererMixer::AddErrorCallback(const base::Closure& error_cb) { 135 void AudioRendererMixer::AddErrorCallback(const base::Closure& error_cb) {
97 base::AutoLock auto_lock(lock_); 136 base::AutoLock auto_lock(lock_);
98 error_callbacks_.push_back(error_cb); 137 error_callbacks_.push_back(error_cb);
99 } 138 }
100 139
101 void AudioRendererMixer::RemoveErrorCallback(const base::Closure& error_cb) { 140 void AudioRendererMixer::RemoveErrorCallback(const base::Closure& error_cb) {
102 base::AutoLock auto_lock(lock_); 141 base::AutoLock auto_lock(lock_);
103 for (ErrorCallbackList::iterator it = error_callbacks_.begin(); 142 for (ErrorCallbackList::iterator it = error_callbacks_.begin();
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 } 182 }
144 183
145 void AudioRendererMixer::OnRenderError() { 184 void AudioRendererMixer::OnRenderError() {
146 // Call each mixer input and signal an error. 185 // Call each mixer input and signal an error.
147 base::AutoLock auto_lock(lock_); 186 base::AutoLock auto_lock(lock_);
148 for (const auto& cb : error_callbacks_) 187 for (const auto& cb : error_callbacks_)
149 cb.Run(); 188 cb.Run();
150 } 189 }
151 190
152 } // namespace media 191 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698