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

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

Issue 1834323002: MediaStream audio: Refactor 3 separate "glue" implementations into one. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: REBASE + Workaround to ensure MediaStreamAudioProcessor is destroyed on the main thread. 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 #ifndef CONTENT_RENDERER_MEDIA_MEDIA_STREAM_AUDIO_DELIVERER_H_
6 #define CONTENT_RENDERER_MEDIA_MEDIA_STREAM_AUDIO_DELIVERER_H_
7
8 #include <algorithm>
9 #include <vector>
10
11 #include "base/synchronization/lock.h"
12 #include "base/threading/thread_checker.h"
13 #include "media/base/audio_parameters.h"
14
15 namespace content {
16
17 // Template containing functionality common to both MediaStreamAudioSource and
18 // MediaStreamAudioTrack. This is used for managing the connections between
19 // objects through which audio data flows, and doing so in a thread-safe manner.
20 //
21 // The Consumer parameter of the template is the type of the objects to which
22 // audio data is delivered: MediaStreamAudioTrack or MediaStreamAudioSink. It's
23 // assumed the Consumer class defines methods named OnSetFormat() and OnData()
24 // that have the same signature as the ones defined in this template.
25 // MediaStreamAudioDeliverer will always guarantee the Consumer's OnSetFormat()
26 // and OnData() methods are called sequentially.
27 template <typename Consumer>
28 class MediaStreamAudioDeliverer {
29 public:
30 MediaStreamAudioDeliverer() {}
31 ~MediaStreamAudioDeliverer() {}
32
33 // Returns the current audio parameters. These will be invalid before the
34 // first call to OnSetFormat(). This method is thread-safe.
35 media::AudioParameters GetAudioParameters() const {
36 base::AutoLock auto_lock(params_lock_);
37 return params_;
38 }
39
40 // Begin delivering audio to |consumer|. The caller must guarantee |consumer|
41 // is not destroyed until after calling RemoveConsumer(consumer). This method
42 // must be called on the main thread.
43 void AddConsumer(Consumer* consumer) {
44 DCHECK(thread_checker_.CalledOnValidThread());
45 DCHECK(consumer);
46 base::AutoLock auto_lock(consumers_lock_);
47 DCHECK(std::find(consumers_.begin(), consumers_.end(), consumer) ==
48 consumers_.end());
49 DCHECK(std::find(pending_consumers_.begin(), pending_consumers_.end(),
50 consumer) == pending_consumers_.end());
51 pending_consumers_.push_back(consumer);
52 }
53
54 // Stop delivering audio to |consumer|. Returns true if |consumer| was the
55 // last consumer removed, false otherwise. When this method returns, no
56 // further calls will be made to OnSetFormat() or OnData() on any thread.
57 // This method must be called on the main thread.
58 bool RemoveConsumer(Consumer* consumer) {
59 DCHECK(thread_checker_.CalledOnValidThread());
60 base::AutoLock auto_lock(consumers_lock_);
61 const bool had_consumers =
62 !consumers_.empty() || !pending_consumers_.empty();
63 auto it = std::find(consumers_.begin(), consumers_.end(), consumer);
64 if (it != consumers_.end()) {
65 consumers_.erase(it);
66 } else {
67 it = std::find(pending_consumers_.begin(), pending_consumers_.end(),
68 consumer);
69 if (it != pending_consumers_.end())
70 pending_consumers_.erase(it);
71 }
72 return had_consumers && consumers_.empty() && pending_consumers_.empty();
73 }
74
75 // Returns the current list of connected Consumers. This is normally used to
76 // send a notification to all consumers. This method must be called on the
77 // main thread.
78 void GetConsumerList(std::vector<Consumer*>* consumer_list) const {
79 DCHECK(thread_checker_.CalledOnValidThread());
80 base::AutoLock auto_lock(consumers_lock_);
81 *consumer_list = consumers_;
82 consumer_list->insert(consumer_list->end(),
83 pending_consumers_.begin(), pending_consumers_.end());
84 }
85
86 // Change the format of the audio passed in the next call to OnData(). This
87 // method may be called on any thread but, logically, should only be called
88 // between calls to OnData().
89 void OnSetFormat(const media::AudioParameters& params) {
90 DCHECK(params.IsValid());
91 base::AutoLock auto_lock(consumers_lock_);
92 {
93 base::AutoLock auto_params_lock(params_lock_);
94 if (params_.Equals(params))
95 return;
96 params_ = params;
97 }
98 pending_consumers_.insert(pending_consumers_.end(),
99 consumers_.begin(), consumers_.end());
100 consumers_.clear();
101 }
102
103 // Deliver data to all consumers. This method may be called on any thread.
104 void OnData(const media::AudioBus& audio_bus,
105 base::TimeTicks reference_time) {
106 base::AutoLock auto_lock(consumers_lock_);
107
108 // Call OnSetFormat() for all pending consumers and move them to the
109 // active-delivery list.
110 if (!pending_consumers_.empty()) {
111 const media::AudioParameters params = GetAudioParameters();
112 DCHECK(params.IsValid());
113 for (Consumer* consumer : pending_consumers_)
114 consumer->OnSetFormat(params);
115 consumers_.insert(consumers_.end(),
116 pending_consumers_.begin(), pending_consumers_.end());
117 pending_consumers_.clear();
118 }
119
120 // Deliver the audio data to each consumer.
121 for (Consumer* consumer : consumers_)
122 consumer->OnData(audio_bus, reference_time);
123 }
124
125 private:
126 // In debug builds, check that all methods that could cause object graph or
127 // data flow changes are being called on the main thread.
128 base::ThreadChecker thread_checker_;
129
130 // Protects concurrent access to |pending_consumers_| and |consumers_|.
131 mutable base::Lock consumers_lock_;
132
133 // Any consumers needing a call to OnSetFormat(), to be notified of the
134 // changed audio format, are placed in this list. This includes consumers
135 // added via AddConsumer() that need to have an initial OnSetFormat() call
136 // before audio data is first delivered. Consumers are moved from this list to
137 // |consumers_| on the audio thread.
138 std::vector<Consumer*> pending_consumers_;
139
140 // Consumers that are up-to-date on the current audio format and are receiving
141 // audio data are placed in this list.
142 std::vector<Consumer*> consumers_;
143
144 // Protects concurrent access to |params_|.
145 mutable base::Lock params_lock_;
146
147 // Specifies the current format of the audio passing through this
148 // MediaStreamAudioDeliverer.
149 media::AudioParameters params_;
150
151 DISALLOW_COPY_AND_ASSIGN(MediaStreamAudioDeliverer);
152 };
153
154 } // namespace content
155
156 #endif // CONTENT_RENDERER_MEDIA_MEDIA_STREAM_AUDIO_DELIVERER_H_
OLDNEW
« no previous file with comments | « content/renderer/media/external_media_stream_audio_source.cc ('k') | content/renderer/media/media_stream_audio_processor.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698