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

Side by Side Diff: media/base/silent_sink_suspender.h

Issue 2382473002: Merge M54: "Break out WebAudio suspension code into new class. Add tests." (Closed)
Patch Set: Fix conflicts. Created 4 years, 2 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
« no previous file with comments | « media/base/fake_audio_render_callback.cc ('k') | media/base/silent_sink_suspender.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 MEDIA_BASE_SILENT_SINK_SUSPENDER_H_
6 #define MEDIA_BASE_SILENT_SINK_SUSPENDER_H_
7
8 #include <stdint.h>
9
10 #include <deque>
11
12 #include "base/cancelable_callback.h"
13 #include "base/compiler_specific.h"
14 #include "base/macros.h"
15 #include "base/memory/ref_counted.h"
16 #include "base/synchronization/lock.h"
17 #include "base/time/time.h"
18 #include "media/audio/fake_audio_worker.h"
19 #include "media/base/audio_parameters.h"
20 #include "media/base/audio_renderer_sink.h"
21 #include "media/base/media_export.h"
22
23 namespace base {
24 class SingleThreadTaskRunner;
25 }
26
27 namespace media {
28
29 // Helper class for suspending AudioRenderSink instances after silence has been
30 // detected for some time. When this is detected, the provided |sink_| is paused
31 // and a fake sink is injected to black hole the silent audio data and avoid
32 // physical hardwasre usage. Note: The transition from real to fake audio output
33 // and vice versa may result in some irregular Render() callbacks.
34 class MEDIA_EXPORT SilentSinkSuspender
35 : NON_EXPORTED_BASE(public AudioRendererSink::RenderCallback) {
36 public:
37 // |callback| is the true producer of audio data, |params| are the parameters
38 // used to initialize |sink|, |sink| is the sink to monitor for idle, and
39 // |worker| is the task runner to run the fake Render() callbacks on. The
40 // amount of silence to allow before suspension is |silence_timeout|.
41 SilentSinkSuspender(
42 AudioRendererSink::RenderCallback* callback,
43 base::TimeDelta silence_timeout,
44 const AudioParameters& params,
45 const scoped_refptr<AudioRendererSink>& sink,
46 const scoped_refptr<base::SingleThreadTaskRunner>& worker);
47 ~SilentSinkSuspender() override;
48
49 // AudioRendererSink::RenderCallback implementation.
50 int Render(AudioBus* dest,
51 uint32_t frames_delayed,
52 uint32_t frames_skipped) override;
53 void OnRenderError() override;
54
55 bool is_using_fake_sink_for_testing() const { return is_using_fake_sink_; }
56
57 private:
58 // If |use_fake_sink| is true, pauses |sink_| and plays |fake_sink_|; if
59 // false, pauses |fake_sink_| and plays |sink_|.
60 void TransitionSinks(bool use_fake_sink);
61
62 // Actual RenderCallback providing audio data to the output device.
63 AudioRendererSink::RenderCallback* const callback_;
64
65 // Parameters used to construct |sink_|.
66 const AudioParameters params_;
67
68 // Sink monitored for silent output.
69 scoped_refptr<AudioRendererSink> sink_;
70
71 // Task runner this class is constructed on. Used to run TransitionSinks().
72 scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
73
74 // Time when the silence starts.
75 base::TimeTicks first_silence_time_;
76
77 // Amount of time that can elapse before replacing |sink_| with |fake_sink_|.
78 const base::TimeDelta silence_timeout_;
79
80 // A fake audio sink object that consumes data when long period of silence
81 // audio is detected. This object lives on |task_runner_| and will run
82 // callbacks on RenderThreadImpl::GetMediaThreadTaskRunner().
83 FakeAudioWorker fake_sink_;
84
85 // AudioRendererSink::Pause() is not synchronous, so we need a lock to ensure
86 // we don't have concurrent access to Render().
87 base::Lock transition_lock_;
88
89 // Whether audio output is directed to |fake_sink_|. Must only be used when
90 // |transition_lock_| is held or both sinks are stopped.
91 bool is_using_fake_sink_ = false;
92
93 // Whether we're in the middle of a transition to or from |fake_sink_|. Must
94 // only be used when |transition_lock_| is held or both sinks are stopped.
95 bool is_transition_pending_ = false;
96
97 // Buffers accumulated during the transition from |fake_sink_| to |sink_|.
98 std::deque<std::unique_ptr<AudioBus>> buffers_after_silence_;
99
100 // A cancelable task that is posted to switch to or from the |fake_sink_|
101 // after a period of silence or first non-silent audio respective. We do this
102 // on Android to save battery consumption.
103 base::CancelableCallback<void(bool)> sink_transition_callback_;
104
105 DISALLOW_COPY_AND_ASSIGN(SilentSinkSuspender);
106 };
107
108 } // namespace content
109
110 #endif // MEDIA_BASE_SILENT_SINK_SUSPENDER_H_
OLDNEW
« no previous file with comments | « media/base/fake_audio_render_callback.cc ('k') | media/base/silent_sink_suspender.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698