Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 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 | 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 <algorithm> | 5 #include <algorithm> |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/location.h" | 8 #include "base/location.h" |
| 9 #include "base/memory/ptr_util.h" | 9 #include "base/memory/ptr_util.h" |
| 10 #include "base/metrics/histogram_macros.h" | |
| 10 #include "base/synchronization/lock.h" | 11 #include "base/synchronization/lock.h" |
| 11 #include "base/threading/thread_task_runner_handle.h" | 12 #include "base/threading/thread_task_runner_handle.h" |
| 12 #include "content/renderer/media/audio_device_factory.h" | 13 #include "content/renderer/media/audio_device_factory.h" |
| 13 #include "content/renderer/media/audio_renderer_sink_cache_impl.h" | 14 #include "content/renderer/media/audio_renderer_sink_cache_impl.h" |
| 14 #include "media/audio/audio_device_description.h" | 15 #include "media/audio/audio_device_description.h" |
| 15 #include "media/base/audio_renderer_sink.h" | 16 #include "media/base/audio_renderer_sink.h" |
| 16 #include "url/origin.h" | 17 #include "url/origin.h" |
| 17 | 18 |
| 18 namespace content { | 19 namespace content { |
| 19 | 20 |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 81 | 82 |
| 82 auto cache_iter = | 83 auto cache_iter = |
| 83 FindCacheEntry_Locked(source_render_frame_id, device_id, | 84 FindCacheEntry_Locked(source_render_frame_id, device_id, |
| 84 security_origin, false /* unused_only */); | 85 security_origin, false /* unused_only */); |
| 85 | 86 |
| 86 if (cache_iter != cache_.end()) { | 87 if (cache_iter != cache_.end()) { |
| 87 // A matching cached sink is found. | 88 // A matching cached sink is found. |
| 88 DVLOG(1) << "GetSinkInfo: address: " << cache_iter->sink.get() | 89 DVLOG(1) << "GetSinkInfo: address: " << cache_iter->sink.get() |
| 89 << " - reused a cached sink."; | 90 << " - reused a cached sink."; |
| 90 | 91 |
| 92 UMA_HISTOGRAM_BOOLEAN("Media.Audio.SinkCache.GetOutputDeviceInfoHit", | |
| 93 true); | |
| 91 return cache_iter->sink->GetOutputDeviceInfo(); | 94 return cache_iter->sink->GetOutputDeviceInfo(); |
| 92 } | 95 } |
| 93 | 96 |
| 94 // No matching sink found, create a new one. | 97 // No matching sink found, create a new one. |
| 95 cache_entry.device_id = device_id; | 98 cache_entry.device_id = device_id; |
| 96 cache_entry.sink = create_sink_cb_.Run( | 99 cache_entry.sink = create_sink_cb_.Run( |
| 97 source_render_frame_id, 0 /* session_id */, device_id, security_origin); | 100 source_render_frame_id, 0 /* session_id */, device_id, security_origin); |
| 98 | 101 |
| 99 DVLOG(1) << "GetSinkInfo: address: " << cache_entry.sink.get() | 102 DVLOG(1) << "GetSinkInfo: address: " << cache_entry.sink.get() |
| 100 << " - no matching cached sink found, created a new one."; | 103 << " - no matching cached sink found, created a new one."; |
| 101 | 104 |
| 102 // Cache a newly-created sink. | 105 // Cache a newly-created sink. |
| 103 cache_.push_back(cache_entry); | 106 cache_.push_back(cache_entry); |
| 104 } | 107 } |
| 105 | 108 |
| 109 UMA_HISTOGRAM_BOOLEAN("Media.Audio.SinkCache.GetOutputDeviceInfoHit", false); | |
|
Henrik Grunell
2016/07/04 14:24:59
It would be nice to have the session ID case in it
o1ka
2016/07/06 13:17:30
Done.
| |
| 110 | |
| 106 // Schedule it for deletion. | 111 // Schedule it for deletion. |
| 107 DeleteLaterIfUnused(cache_entry.sink.get()); | 112 DeleteLaterIfUnused(cache_entry.sink.get()); |
| 108 | 113 |
| 109 DVLOG(1) << "GetSinkInfo: address: " << cache_entry.sink.get() | 114 DVLOG(1) << "GetSinkInfo: address: " << cache_entry.sink.get() |
| 110 << " created. source_render_frame_id: " << source_render_frame_id | 115 << " created. source_render_frame_id: " << source_render_frame_id |
| 111 << " session_id: " << session_id << " device_id: " << device_id | 116 << " session_id: " << session_id << " device_id: " << device_id |
| 112 << " security_origin: " << security_origin; | 117 << " security_origin: " << security_origin; |
| 113 | 118 |
| 114 return cache_entry.sink->GetOutputDeviceInfo(); | 119 return cache_entry.sink->GetOutputDeviceInfo(); |
| 115 } | 120 } |
| 116 | 121 |
| 117 scoped_refptr<media::AudioRendererSink> AudioRendererSinkCacheImpl::GetSink( | 122 scoped_refptr<media::AudioRendererSink> AudioRendererSinkCacheImpl::GetSink( |
| 118 int source_render_frame_id, | 123 int source_render_frame_id, |
| 119 const std::string& device_id, | 124 const std::string& device_id, |
| 120 const url::Origin& security_origin) { | 125 const url::Origin& security_origin) { |
| 126 UMA_HISTOGRAM_BOOLEAN("Media.Audio.SinkCache.UsedForSinkCreation", true); | |
|
Henrik Grunell
2016/07/04 14:24:59
False is never recorded?
o1ka
2016/07/06 13:17:30
Recorded in AudioDeviceFactory
| |
| 127 | |
| 121 base::AutoLock auto_lock(cache_lock_); | 128 base::AutoLock auto_lock(cache_lock_); |
| 122 | 129 |
| 123 auto cache_iter = | 130 auto cache_iter = |
| 124 FindCacheEntry_Locked(source_render_frame_id, device_id, security_origin, | 131 FindCacheEntry_Locked(source_render_frame_id, device_id, security_origin, |
| 125 true /* unused_only */); | 132 true /* unused_only */); |
| 126 | 133 |
| 127 if (cache_iter != cache_.end()) { | 134 if (cache_iter != cache_.end()) { |
| 128 // Found unused sink; mark it as used and return. | 135 // Found unused sink; mark it as used and return. |
| 129 DVLOG(1) << "GetSink: address: " << cache_iter->sink.get() | 136 DVLOG(1) << "GetSink: address: " << cache_iter->sink.get() |
| 130 << " - found unused cached sink, reusing it."; | 137 << " - found unused cached sink, reusing it."; |
| 131 | 138 |
| 132 cache_iter->used = true; | 139 cache_iter->used = true; |
| 140 UMA_HISTOGRAM_BOOLEAN("Media.Audio.SinkCache.InfoSinkReusedForOutput", | |
|
Henrik Grunell
2016/07/04 14:24:59
I don't understand this histogram. Seems to record
o1ka
2016/07/06 13:17:30
Discussed offline.
| |
| 141 true); | |
| 133 return cache_iter->sink; | 142 return cache_iter->sink; |
| 134 } | 143 } |
| 135 | 144 |
| 136 // No unused sink is found, create one, mark it used, cache it and return. | 145 // No unused sink is found, create one, mark it used, cache it and return. |
| 137 CacheEntry cache_entry = { | 146 CacheEntry cache_entry = { |
| 138 source_render_frame_id, device_id, security_origin, | 147 source_render_frame_id, device_id, security_origin, |
| 139 create_sink_cb_.Run(source_render_frame_id, 0 /* session_id */, device_id, | 148 create_sink_cb_.Run(source_render_frame_id, 0 /* session_id */, device_id, |
| 140 security_origin), | 149 security_origin), |
| 141 true /* used */}; | 150 true /* used */}; |
| 142 | 151 |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 198 << "Attempt to delete a non-aquired sink."; | 207 << "Attempt to delete a non-aquired sink."; |
| 199 | 208 |
| 200 if (!force_delete_used && cache_iter->used) { | 209 if (!force_delete_used && cache_iter->used) { |
| 201 DVLOG(1) << "DeleteSink: address: " << sink_ptr | 210 DVLOG(1) << "DeleteSink: address: " << sink_ptr |
| 202 << " sink in use, skipping deletion."; | 211 << " sink in use, skipping deletion."; |
| 203 return; | 212 return; |
| 204 } | 213 } |
| 205 | 214 |
| 206 // To stop the sink before deletion if it's not used, we need to hold | 215 // To stop the sink before deletion if it's not used, we need to hold |
| 207 // a ref to it. | 216 // a ref to it. |
| 208 if (!cache_iter->used) | 217 if (!cache_iter->used) { |
| 209 sink_to_stop = cache_iter->sink; | 218 sink_to_stop = cache_iter->sink; |
| 219 UMA_HISTOGRAM_BOOLEAN("Media.Audio.SinkCache.InfoSinkReusedForOutput", | |
| 220 false); | |
| 221 } | |
| 210 | 222 |
| 211 cache_.erase(cache_iter); | 223 cache_.erase(cache_iter); |
| 212 DVLOG(1) << "DeleteSink: address: " << sink_ptr; | 224 DVLOG(1) << "DeleteSink: address: " << sink_ptr; |
| 213 } // Lock scope; | 225 } // Lock scope; |
| 214 | 226 |
| 215 // Stop the sink out of the lock scope. | 227 // Stop the sink out of the lock scope. |
| 216 if (sink_to_stop.get()) { | 228 if (sink_to_stop.get()) { |
| 217 DCHECK_EQ(sink_ptr, sink_to_stop.get()); | 229 DCHECK_EQ(sink_ptr, sink_to_stop.get()); |
| 218 sink_to_stop->Stop(); | 230 sink_to_stop->Stop(); |
| 219 DVLOG(1) << "DeleteSink: address: " << sink_ptr << " stopped."; | 231 DVLOG(1) << "DeleteSink: address: " << sink_ptr << " stopped."; |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 244 return val.device_id == device_id && | 256 return val.device_id == device_id && |
| 245 val.security_origin == security_origin; | 257 val.security_origin == security_origin; |
| 246 }); | 258 }); |
| 247 }; | 259 }; |
| 248 | 260 |
| 249 int AudioRendererSinkCacheImpl::GetCacheSizeForTesting() { | 261 int AudioRendererSinkCacheImpl::GetCacheSizeForTesting() { |
| 250 return cache_.size(); | 262 return cache_.size(); |
| 251 } | 263 } |
| 252 | 264 |
| 253 } // namespace content | 265 } // namespace content |
| OLD | NEW |