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

Side by Side Diff: content/renderer/media/audio_renderer_sink_cache_impl.h

Issue 1942803002: Caching AudioOutputDevice instances in mixer manager (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase, fix for sleep() compile error on win and a bit of cleanup around timeouts. Created 4 years, 7 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/renderer/media/audio_renderer_sink_cache.h"
6
7 #include <map>
8
9 #include "base/single_thread_task_runner.h"
10 #include "base/synchronization/lock.h"
11 #include "content/common/content_export.h"
12 #include "media/audio/audio_device_description.h"
13 #include "media/base/audio_renderer_sink.h"
14
15 namespace content {
16
17 // AudioRendererSinkCache implementation.
18 class CONTENT_EXPORT AudioRendererSinkCacheImpl
19 : public AudioRendererSinkCache {
20 public:
21 // Callback to be used for AudioRendererSink creation
22 typedef base::Callback<scoped_refptr<media::AudioRendererSink>(
23 int render_frame_id,
24 int session_id,
25 const std::string& device_id,
26 const url::Origin& security_origin)>
27 CreateSinkCallback;
28
29 AudioRendererSinkCacheImpl(
30 scoped_refptr<base::SingleThreadTaskRunner> task_runner,
31 const CreateSinkCallback& create_sink_callback);
32
33 ~AudioRendererSinkCacheImpl() final;
34
35 media::OutputDeviceInfo GetSinkInfo(int source_render_frame_id,
36 int session_id,
37 const std::string& device_id,
38 const url::Origin& security_origin) final;
39
40 media::AudioRendererSink* GetSink(int source_render_frame_id,
41 const std::string& device_id,
42 const url::Origin& security_origin) final;
43
44 void ReleaseSink(media::AudioRendererSink* sink) final;
45
46 private:
47 friend class AudioRendererSinkCacheTest;
48
49 // Cached sink deletion timeout.
50 // For example: (1) sink was create and cached in GetSinkInfo(), and then (2)
51 // the same sink is requested in GetSink(), if time interval between (1) and
52 // (2) is less than |kDeleteTimeoutMs|, then sink cached in (1) is reused in
53 // (2). On the other hand, if after (1) nobody is interested in the sink
54 // within |kDeleteTimeoutMs|, it is garbage-collected.
55 enum { kDeleteTimeoutMs = 5000 };
56
57 // The key to be used to access a cached sink (not unique,there can be
58 // multiple sinks per device.
59 struct SinkKey {
60 SinkKey(int source_render_frame_id,
61 const std::string& device_id,
62 const url::Origin& security_origin);
63 SinkKey(const SinkKey& other);
64 int source_render_frame_id;
65 std::string device_id;
66 url::Origin security_origin;
67 };
68
69 // Strict weak ordering of the keys.
70 struct SinkKeyCompare {
71 bool operator()(const SinkKey& a, const SinkKey& b) const {
72 if (a.source_render_frame_id != b.source_render_frame_id)
73 return a.source_render_frame_id < b.source_render_frame_id;
74
75 if (media::AudioDeviceDescription::IsDefaultDevice(a.device_id) &&
76 media::AudioDeviceDescription::IsDefaultDevice(b.device_id)) {
77 // Both device IDs represent the same default device => do not compare
78 // them; the default device is always authorized => ignoring security
79 // origin.
80 return false;
81 }
82
83 if (a.device_id != b.device_id)
84 return a.device_id < b.device_id;
85
86 return a.security_origin < b.security_origin;
87 }
88 };
89
90 // Cached sink data.
91 struct AudioRendererSinkReference {
92 AudioRendererSinkReference(scoped_refptr<media::AudioRendererSink> sink,
93 bool used);
94 AudioRendererSinkReference(const AudioRendererSinkReference& other);
95 ~AudioRendererSinkReference();
96 scoped_refptr<media::AudioRendererSink> sink; // Sink instance
97 bool used; // True if in used by a client.
98 };
99
100 typedef std::multimap<SinkKey, AudioRendererSinkReference, SinkKeyCompare>
miu 2016/05/12 21:53:06 1. If the number of sinks is small, consider using
o1ka 2016/05/17 17:17:24 1. multimap is also used for find() in GetSinkInfo
miu 2016/05/19 22:27:14 Well, okay. I'll admit I'm "bike-shedding" a littl
o1ka 2016/05/20 10:40:32 Ok. But before reverting this to the first version
101 AudioRendererSinkMap;
102
103 // Schedules a sink for deletion. Deletion will be performed on the same
104 // thread the cache is created on.
105 void DeleteLaterIfUnused(media::AudioRendererSink* sink);
106
107 // Deletes a sink from the cache. If |force_delete_used| is set, a sink being
108 // deleted can (and should) be in use at the moment of deletion; otherwise the
109 // sink is deleted only if unused.
110 void DeleteSink(media::AudioRendererSink* sink, bool force_delete_used);
111
112 // Creates a sink with a specified |key| and |used| state and inserts it into
113 // the cache. Note: |sinks_lock_| must be held while operating on the result
114 // of this function, otherwise the sink may be deleted and the pointer becomes
115 // invalid.
116 media::AudioRendererSink* InsertNewSink(const SinkKey& key, bool used);
117
118 // Task runner for scheduled sink garbage collection.
119 scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
miu 2016/05/12 21:53:06 Please make this const.
o1ka 2016/05/17 17:17:24 Done.
120
121 // Callback used for sink creation.
122 const CreateSinkCallback create_sink_cb_;
123
124 // Cached sinks, protected by lock.
125 base::Lock sinks_lock_;
126 AudioRendererSinkMap sinks_;
127
128 base::WeakPtrFactory<AudioRendererSinkCacheImpl> weak_ptr_factory_;
129
130 DISALLOW_COPY_AND_ASSIGN(AudioRendererSinkCacheImpl);
131 };
132
133 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698