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

Side by Side Diff: content/renderer/media/renderer_webaudiodevice_impl.cc

Issue 2501863003: Support for AudioContextOptions latencyHint. (Closed)
Patch Set: Add baseLatency and fix use of hardwareSampleRate. Created 4 years 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
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "content/renderer/media/renderer_webaudiodevice_impl.h" 5 #include "content/renderer/media/renderer_webaudiodevice_impl.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <string> 9 #include <string>
10 10
11 #include "base/command_line.h" 11 #include "base/command_line.h"
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/time/time.h" 13 #include "base/time/time.h"
14 #include "build/build_config.h" 14 #include "build/build_config.h"
15 #include "content/renderer/media/audio_device_factory.h" 15 #include "content/renderer/media/audio_device_factory.h"
16 #include "content/renderer/render_frame_impl.h" 16 #include "content/renderer/render_frame_impl.h"
17 #include "content/renderer/render_thread_impl.h" 17 #include "content/renderer/render_thread_impl.h"
18 #include "media/base/silent_sink_suspender.h" 18 #include "media/base/silent_sink_suspender.h"
19 #include "third_party/WebKit/public/web/WebLocalFrame.h" 19 #include "third_party/WebKit/public/web/WebLocalFrame.h"
20 #include "third_party/WebKit/public/web/WebView.h" 20 #include "third_party/WebKit/public/web/WebView.h"
21 21
22 using blink::WebAudioDevice; 22 using blink::WebAudioDevice;
23 using blink::WebAudioLatencyHint;
23 using blink::WebLocalFrame; 24 using blink::WebLocalFrame;
24 using blink::WebVector; 25 using blink::WebVector;
25 using blink::WebView; 26 using blink::WebView;
26 27
28 namespace {
o1ka 2016/11/30 11:46:26 nit: you can move unnamed namespace into |content|
Andrew MacPherson 2016/12/01 12:11:56 Done.
29
30 content::AudioDeviceFactory::SourceType GetLatencyHintSourceType(
31 WebAudioLatencyHint::Category latency_category) {
32 switch (latency_category) {
33 case WebAudioLatencyHint::CategoryInteractive:
34 return content::AudioDeviceFactory::kSourceWebAudioInteractive;
35 case WebAudioLatencyHint::CategoryBalanced:
36 return content::AudioDeviceFactory::kSourceWebAudioBalanced;
37 case WebAudioLatencyHint::CategoryPlayback:
38 return content::AudioDeviceFactory::kSourceWebAudioPlayback;
39 }
40 NOTREACHED();
41 return content::AudioDeviceFactory::kSourceWebAudioInteractive;
42 }
43
44 } // namespace
45
27 namespace content { 46 namespace content {
28 47
29 RendererWebAudioDeviceImpl::RendererWebAudioDeviceImpl( 48 RendererWebAudioDeviceImpl::RendererWebAudioDeviceImpl(
30 const media::AudioParameters& params, 49 media::ChannelLayout layout,
50 const blink::WebAudioLatencyHint& latency_hint,
31 WebAudioDevice::RenderCallback* callback, 51 WebAudioDevice::RenderCallback* callback,
32 int session_id, 52 int session_id,
33 const url::Origin& security_origin) 53 const url::Origin& security_origin)
34 : params_(params), 54 : latency_hint_(latency_hint),
o1ka 2016/11/30 11:46:26 It does not look like you need |latency_hint_| any
Andrew MacPherson 2016/12/01 12:11:56 The idea with storing the latency_hint_ was that i
35 client_callback_(callback), 55 client_callback_(callback),
36 session_id_(session_id), 56 session_id_(session_id),
37 security_origin_(security_origin) { 57 security_origin_(security_origin) {
38 DCHECK(client_callback_); 58 DCHECK(client_callback_);
59
60 blink::WebLocalFrame* const web_frame =
61 blink::WebLocalFrame::frameForCurrentContext();
62 RenderFrame* const render_frame = RenderFrame::FromWebFrame(web_frame);
o1ka 2016/11/30 11:46:26 Make FrameIdFromCurrentContext() helper function,
Andrew MacPherson 2016/12/01 12:11:56 Done except for the check in the constructor. Shou
63 media::AudioParameters hardware_params(
64 AudioDeviceFactory::GetOutputDeviceInfo(render_frame->GetRoutingID(),
65 session_id_, std::string(),
66 security_origin_)
67 .output_params());
68
69 int output_buffer_size = 0;
70
71 media::AudioLatency::LatencyType latency =
72 AudioDeviceFactory::GetSourceLatencyType(
73 GetLatencyHintSourceType(latency_hint_.category()));
74
75 // Adjust output buffer size according to the latency requirement.
76 switch (latency) {
77 case media::AudioLatency::LATENCY_INTERACTIVE:
78 output_buffer_size = media::AudioLatency::GetInteractiveBufferSize(
79 hardware_params.frames_per_buffer());
80 break;
81 case media::AudioLatency::LATENCY_RTC:
82 output_buffer_size = media::AudioLatency::GetRtcBufferSize(
83 hardware_params.sample_rate(), hardware_params.frames_per_buffer());
84 break;
85 case media::AudioLatency::LATENCY_PLAYBACK:
86 output_buffer_size = media::AudioLatency::GetHighLatencyBufferSize(
87 hardware_params.sample_rate(), 0);
88 break;
89 case media::AudioLatency::LATENCY_EXACT_MS:
90 // TODO(olka): add support when WebAudio requires it.
91 default:
92 NOTREACHED();
93 }
94
95 DCHECK_NE(output_buffer_size, 0);
96
97 sink_params_.Reset(media::AudioParameters::AUDIO_PCM_LOW_LATENCY, layout,
98 hardware_params.sample_rate(), 16, output_buffer_size);
99
100 // Specify the latency info to be passed to the browser side.
101 sink_params_.set_latency_tag(latency);
39 } 102 }
40 103
41 RendererWebAudioDeviceImpl::~RendererWebAudioDeviceImpl() { 104 RendererWebAudioDeviceImpl::~RendererWebAudioDeviceImpl() {
42 DCHECK(!sink_); 105 DCHECK(!sink_);
43 } 106 }
44 107
45 void RendererWebAudioDeviceImpl::start() { 108 void RendererWebAudioDeviceImpl::start() {
46 DCHECK(thread_checker_.CalledOnValidThread()); 109 DCHECK(thread_checker_.CalledOnValidThread());
47 110
48 if (sink_) 111 if (sink_)
49 return; // Already started. 112 return; // Already started.
50 113
51 // Assumption: This method is being invoked within a V8 call stack. CHECKs 114 // Assumption: This method is being invoked within a V8 call stack. CHECKs
52 // will fail in the call to frameForCurrentContext() otherwise. 115 // will fail in the call to frameForCurrentContext() otherwise.
53 // 116 //
54 // Therefore, we can perform look-ups to determine which RenderView is 117 // Therefore, we can perform look-ups to determine which RenderView is
55 // starting the audio device. The reason for all this is because the creator 118 // starting the audio device. The reason for all this is because the creator
56 // of the WebAudio objects might not be the actual source of the audio (e.g., 119 // of the WebAudio objects might not be the actual source of the audio (e.g.,
57 // an extension creates a object that is passed and used within a page). 120 // an extension creates a object that is passed and used within a page).
58 WebLocalFrame* const web_frame = WebLocalFrame::frameForCurrentContext(); 121 WebLocalFrame* const web_frame = WebLocalFrame::frameForCurrentContext();
59 RenderFrame* const render_frame = 122 RenderFrame* const render_frame =
60 web_frame ? RenderFrame::FromWebFrame(web_frame) : NULL; 123 web_frame ? RenderFrame::FromWebFrame(web_frame) : NULL;
61 sink_ = AudioDeviceFactory::NewAudioRendererSink( 124 sink_ = AudioDeviceFactory::NewAudioRendererSink(
62 AudioDeviceFactory::kSourceWebAudioInteractive, 125 GetLatencyHintSourceType(latency_hint_.category()),
63 render_frame ? render_frame->GetRoutingID() : MSG_ROUTING_NONE, 126 render_frame ? render_frame->GetRoutingID() : MSG_ROUTING_NONE,
64 session_id_, std::string(), security_origin_); 127 session_id_, std::string(), security_origin_);
65 128
66 // Specify the latency info to be passed to the browser side.
67 media::AudioParameters sink_params(params_);
68 sink_params.set_latency_tag(AudioDeviceFactory::GetSourceLatencyType(
69 AudioDeviceFactory::kSourceWebAudioInteractive));
70
71 #if defined(OS_ANDROID) 129 #if defined(OS_ANDROID)
72 // Use the media thread instead of the render thread for fake Render() calls 130 // Use the media thread instead of the render thread for fake Render() calls
73 // since it has special connotations for Blink and garbage collection. Timeout 131 // since it has special connotations for Blink and garbage collection. Timeout
74 // value chosen to be highly unlikely in the normal case. 132 // value chosen to be highly unlikely in the normal case.
75 webaudio_suspender_.reset(new media::SilentSinkSuspender( 133 webaudio_suspender_.reset(new media::SilentSinkSuspender(
76 this, base::TimeDelta::FromSeconds(30), sink_params, sink_, 134 this, base::TimeDelta::FromSeconds(30), sink_params_, sink_,
77 RenderThreadImpl::current()->GetMediaThreadTaskRunner())); 135 RenderThreadImpl::current()->GetMediaThreadTaskRunner()));
78 sink_->Initialize(sink_params, webaudio_suspender_.get()); 136 sink_->Initialize(sink_params_, webaudio_suspender_.get());
79 #else 137 #else
80 sink_->Initialize(sink_params, this); 138 sink_->Initialize(sink_params_, this);
81 #endif 139 #endif
82 140
83 sink_->Start(); 141 sink_->Start();
84 sink_->Play(); 142 sink_->Play();
85 } 143 }
86 144
87 void RendererWebAudioDeviceImpl::stop() { 145 void RendererWebAudioDeviceImpl::stop() {
88 DCHECK(thread_checker_.CalledOnValidThread()); 146 DCHECK(thread_checker_.CalledOnValidThread());
89 if (sink_) { 147 if (sink_) {
90 sink_->Stop(); 148 sink_->Stop();
91 sink_ = nullptr; 149 sink_ = nullptr;
92 } 150 }
93 151
94 #if defined(OS_ANDROID) 152 #if defined(OS_ANDROID)
95 webaudio_suspender_.reset(); 153 webaudio_suspender_.reset();
96 #endif 154 #endif
97 } 155 }
98 156
99 double RendererWebAudioDeviceImpl::sampleRate() { 157 double RendererWebAudioDeviceImpl::sampleRate() {
100 return params_.sample_rate(); 158 return sink_params_.sample_rate();
159 }
160
161 int RendererWebAudioDeviceImpl::framesPerBuffer() {
162 return sink_params_.frames_per_buffer();
101 } 163 }
102 164
103 int RendererWebAudioDeviceImpl::Render(media::AudioBus* dest, 165 int RendererWebAudioDeviceImpl::Render(media::AudioBus* dest,
104 uint32_t frames_delayed, 166 uint32_t frames_delayed,
105 uint32_t frames_skipped) { 167 uint32_t frames_skipped) {
106 // Wrap the output pointers using WebVector. 168 // Wrap the output pointers using WebVector.
107 WebVector<float*> web_audio_dest_data(static_cast<size_t>(dest->channels())); 169 WebVector<float*> web_audio_dest_data(static_cast<size_t>(dest->channels()));
108 for (int i = 0; i < dest->channels(); ++i) 170 for (int i = 0; i < dest->channels(); ++i)
109 web_audio_dest_data[i] = dest->channel(i); 171 web_audio_dest_data[i] = dest->channel(i);
110 172
111 // TODO(xians): Remove the following |web_audio_source_data| after 173 // TODO(xians): Remove the following |web_audio_source_data| after
112 // changing the blink interface. 174 // changing the blink interface.
113 WebVector<float*> web_audio_source_data(static_cast<size_t>(0)); 175 WebVector<float*> web_audio_source_data(static_cast<size_t>(0));
114 client_callback_->render(web_audio_source_data, web_audio_dest_data, 176 client_callback_->render(web_audio_source_data, web_audio_dest_data,
115 dest->frames()); 177 dest->frames());
116 return dest->frames(); 178 return dest->frames();
117 } 179 }
118 180
119 void RendererWebAudioDeviceImpl::OnRenderError() { 181 void RendererWebAudioDeviceImpl::OnRenderError() {
120 // TODO(crogers): implement error handling. 182 // TODO(crogers): implement error handling.
121 } 183 }
122 184
123 } // namespace content 185 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698