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

Side by Side Diff: content/browser/renderer_host/media/audio_stream_registry_impl.cc

Issue 2578983003: Add AudioStreamRegistry. Move stream counting logic (Closed)
Patch Set: Thread checks. Created 3 years, 11 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
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/browser/renderer_host/media/audio_stream_registry_impl.h"
6
7 #include <algorithm>
8 #include <utility>
9
10 #include "base/lazy_instance.h"
11 #include "base/metrics/histogram_macros.h"
12 #include "content/public/browser/browser_thread.h"
13 #include "content/public/browser/render_process_host.h"
14 #include "media/audio/audio_streams_tracker.h"
15
16 namespace content {
17
18 namespace {
19
20 base::LazyInstance<media::AudioStreamsTracker> g_audio_output_streams_tracker =
21 LAZY_INSTANCE_INITIALIZER;
22
23 void NotifyRenderProcessHostThatAudioStateChanged(int render_process_id) {
24 DCHECK_CURRENTLY_ON(BrowserThread::UI);
25
26 RenderProcessHost* render_process_host =
27 RenderProcessHost::FromID(render_process_id);
28
29 if (render_process_host)
30 render_process_host->AudioStateChanged();
31 }
32
33 } // namespace
34
35 AudioStreamRegistryImpl::AudioStreamRegistryImpl(int render_process_id)
36 : render_process_id_(render_process_id) {}
37
38 AudioStreamRegistryImpl::~AudioStreamRegistryImpl() {
39 DCHECK_CURRENTLY_ON(BrowserThread::IO);
40 DCHECK(output_streams_.empty());
41 DCHECK(stream_currently_playing_.empty());
42
43 if (max_simultaneous_output_streams_ > 0) {
44 UMA_HISTOGRAM_CUSTOM_COUNTS("Media.AudioRendererIpcStreams",
45 max_simultaneous_output_streams_, 1, 50, 51);
46 UMA_HISTOGRAM_CUSTOM_COUNTS(
47 "Media.AudioRendererIpcStreamsTotal",
48 g_audio_output_streams_tracker.Get().max_stream_count(), 1, 100, 101);
49 g_audio_output_streams_tracker.Get().ResetMaxStreamCount();
50 }
51 }
52
53 // static
54 AudioStreamRegistryImpl::UniquePtr AudioStreamRegistryImpl::Create(
55 int render_process_id) {
56 return {new AudioStreamRegistryImpl(render_process_id), {}};
57 }
58
59 bool AudioStreamRegistryImpl::HasActiveAudio() {
60 return !base::AtomicRefCountIsZero(&num_playing_output_streams_);
61 }
62
63 #if BUILDFLAG(ENABLE_WEBRTC)
64 void AudioStreamRegistryImpl::EnableDebugRecording(
65 const base::FilePath& base_file_name) {
66 DCHECK_CURRENTLY_ON(BrowserThread::IO);
67 if (!debug_recording_path_.empty()) {
68 // There is already a recording in progress.
69 DisableDebugRecording();
70 }
71 debug_recording_path_ = base_file_name;
72 for (Stream* stream : output_streams_)
73 stream->EnableDebugRecording(base_file_name);
74 }
75
76 void AudioStreamRegistryImpl::DisableDebugRecording() {
77 DCHECK_CURRENTLY_ON(BrowserThread::IO);
78 debug_recording_path_.clear();
79 for (Stream* stream : output_streams_)
80 stream->DisableDebugRecording();
81 }
82 #endif // BUILDFLAG(ENABLE_WEBRTC)
83
84 void AudioStreamRegistryImpl::RegisterOutputStream(Stream* stream) {
85 DCHECK_CURRENTLY_ON(BrowserThread::IO);
86 bool did_insert = output_streams_.insert(stream).second;
87 DCHECK(did_insert);
88
89 #if BUILDFLAG(ENABLE_WEBRTC)
90 if (!debug_recording_path_.empty())
91 stream->EnableDebugRecording(debug_recording_path_);
92 #endif // BUILDFLAG(ENABLE_WEBRTC)
93
94 max_simultaneous_output_streams_ =
95 std::max(max_simultaneous_output_streams_, output_streams_.size());
96 g_audio_output_streams_tracker.Get().IncreaseStreamCount();
97 #if DCHECK_IS_ON()
98 stream_currently_playing_.insert(std::make_pair(stream, false));
99 #endif
100 }
101
102 void AudioStreamRegistryImpl::DeregisterOutputStream(Stream* stream) {
103 DCHECK_CURRENTLY_ON(BrowserThread::IO);
104 size_t num_erased = output_streams_.erase(stream);
105 DCHECK_EQ(num_erased, 1u);
106
107 g_audio_output_streams_tracker.Get().DecreaseStreamCount();
108 #if BUILDFLAG(ENABLE_WEBRTC)
109 if (!debug_recording_path_.empty())
110 stream->DisableDebugRecording();
111 #endif // BUILDFLAG(ENABLE_WEBRTC)
112
113 #if DCHECK_IS_ON()
114 DCHECK(!stream_currently_playing_.at(stream));
115 stream_currently_playing_.erase(stream);
116 #endif
117 }
118
119 void AudioStreamRegistryImpl::OutputStreamStateChanged(Stream* stream,
120 bool playing) {
121 DCHECK_CURRENTLY_ON(BrowserThread::IO);
122 #if DCHECK_IS_ON()
123 auto it = stream_currently_playing_.find(stream);
124 DCHECK(it != stream_currently_playing_.end());
125 DCHECK(it->second != playing);
126 it->second = playing;
127 #endif
128 if (playing) {
129 base::AtomicRefCountInc(&num_playing_output_streams_);
130
131 // Inform the RenderProcessHost when audio starts playing for the first
132 // time. The nonatomic increment-and-read is ok since this is the only
133 // thread that |num_playing_output_streams_| may be updated on.
134 if (base::AtomicRefCountIsOne(&num_playing_output_streams_)) {
135 BrowserThread::PostTask(
136 BrowserThread::UI, FROM_HERE,
137 base::Bind(&NotifyRenderProcessHostThatAudioStateChanged,
138 render_process_id_));
139 }
140 } else {
141 // Inform the RenderProcessHost when there is no more audio playing.
142 DCHECK(!base::AtomicRefCountIsZero(&num_playing_output_streams_));
143 if (!base::AtomicRefCountDec(&num_playing_output_streams_)) {
144 BrowserThread::PostTask(
145 BrowserThread::UI, FROM_HERE,
146 base::Bind(&NotifyRenderProcessHostThatAudioStateChanged,
147 render_process_id_));
148 }
149 }
150 }
151
152 // static
153 void AudioStreamRegistryImpl::DetachAudioStreamsTrackerFromThreadForTesting() {
154 g_audio_output_streams_tracker.Get().DetachFromThreadForTesting();
155 }
156
157 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698