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

Side by Side Diff: content/browser/renderer_host/media/audio_renderer_host.cc

Issue 9845033: Move the MediaObserver getter from ResourceContext to ContentBrowserClient, since we only need to s… (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: fix dcheck Created 8 years, 9 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 | Annotate | Revision Log
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/browser/renderer_host/media/audio_renderer_host.h" 5 #include "content/browser/renderer_host/media/audio_renderer_host.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/metrics/histogram.h" 8 #include "base/metrics/histogram.h"
9 #include "base/process.h" 9 #include "base/process.h"
10 #include "base/shared_memory.h" 10 #include "base/shared_memory.h"
11 #include "content/browser/browser_main_loop.h" 11 #include "content/browser/browser_main_loop.h"
12 #include "content/browser/renderer_host/media/audio_sync_reader.h" 12 #include "content/browser/renderer_host/media/audio_sync_reader.h"
13 #include "content/common/media/audio_messages.h" 13 #include "content/common/media/audio_messages.h"
14 #include "content/public/browser/media_observer.h" 14 #include "content/public/browser/media_observer.h"
15 #include "content/public/browser/resource_context.h"
16 #include "media/audio/audio_util.h" 15 #include "media/audio/audio_util.h"
17 16
18 using content::BrowserMessageFilter; 17 using content::BrowserMessageFilter;
19 using content::BrowserThread; 18 using content::BrowserThread;
20 19
21 AudioRendererHost::AudioEntry::AudioEntry() 20 AudioRendererHost::AudioEntry::AudioEntry()
22 : stream_id(0), 21 : stream_id(0),
23 pending_close(false) { 22 pending_close(false) {
24 } 23 }
25 24
26 AudioRendererHost::AudioEntry::~AudioEntry() {} 25 AudioRendererHost::AudioEntry::~AudioEntry() {}
27 26
28 /////////////////////////////////////////////////////////////////////////////// 27 ///////////////////////////////////////////////////////////////////////////////
29 // AudioRendererHost implementations. 28 // AudioRendererHost implementations.
30 AudioRendererHost::AudioRendererHost( 29 AudioRendererHost::AudioRendererHost(
31 content::ResourceContext* resource_context, 30 AudioManager* audio_manager,
32 AudioManager* audio_manager) 31 content::MediaObserver* media_observer)
33 : resource_context_(resource_context), 32 : audio_manager_(audio_manager),
34 audio_manager_(audio_manager) { 33 media_observer_(media_observer) {
35 } 34 }
36 35
37 AudioRendererHost::~AudioRendererHost() { 36 AudioRendererHost::~AudioRendererHost() {
38 DCHECK(audio_entries_.empty()); 37 DCHECK(audio_entries_.empty());
39 } 38 }
40 39
41 void AudioRendererHost::OnChannelClosing() { 40 void AudioRendererHost::OnChannelClosing() {
42 BrowserMessageFilter::OnChannelClosing(); 41 BrowserMessageFilter::OnChannelClosing();
43 42
44 // Channel is closing, so |resource_context_| is about to become invalid.
45 resource_context_ = NULL;
46
47 // Since the IPC channel is gone, close all requested audio streams. 43 // Since the IPC channel is gone, close all requested audio streams.
48 DeleteEntries(); 44 DeleteEntries();
49 } 45 }
50 46
51 void AudioRendererHost::OnDestruct() const { 47 void AudioRendererHost::OnDestruct() const {
52 BrowserThread::DeleteOnIOThread::Destruct(this); 48 BrowserThread::DeleteOnIOThread::Destruct(this);
53 } 49 }
54 50
55 /////////////////////////////////////////////////////////////////////////////// 51 ///////////////////////////////////////////////////////////////////////////////
56 // media::AudioOutputController::EventHandler implementations. 52 // media::AudioOutputController::EventHandler implementations.
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
233 229
234 if (!entry->controller) { 230 if (!entry->controller) {
235 SendErrorMessage(stream_id); 231 SendErrorMessage(stream_id);
236 return; 232 return;
237 } 233 }
238 234
239 // If we have created the controller successfully, create an entry and add it 235 // If we have created the controller successfully, create an entry and add it
240 // to the map. 236 // to the map.
241 entry->stream_id = stream_id; 237 entry->stream_id = stream_id;
242 audio_entries_.insert(std::make_pair(stream_id, entry.release())); 238 audio_entries_.insert(std::make_pair(stream_id, entry.release()));
243 if (GetMediaObserver()) 239 if (media_observer_)
244 GetMediaObserver()->OnSetAudioStreamStatus(this, stream_id, "created"); 240 media_observer_->OnSetAudioStreamStatus(this, stream_id, "created");
245 } 241 }
246 242
247 void AudioRendererHost::OnPlayStream(int stream_id) { 243 void AudioRendererHost::OnPlayStream(int stream_id) {
248 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 244 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
249 245
250 AudioEntry* entry = LookupById(stream_id); 246 AudioEntry* entry = LookupById(stream_id);
251 if (!entry) { 247 if (!entry) {
252 SendErrorMessage(stream_id); 248 SendErrorMessage(stream_id);
253 return; 249 return;
254 } 250 }
255 251
256 entry->controller->Play(); 252 entry->controller->Play();
257 if (GetMediaObserver()) 253 if (media_observer_)
258 GetMediaObserver()->OnSetAudioStreamPlaying(this, stream_id, true); 254 media_observer_->OnSetAudioStreamPlaying(this, stream_id, true);
259 } 255 }
260 256
261 void AudioRendererHost::OnPauseStream(int stream_id) { 257 void AudioRendererHost::OnPauseStream(int stream_id) {
262 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 258 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
263 259
264 AudioEntry* entry = LookupById(stream_id); 260 AudioEntry* entry = LookupById(stream_id);
265 if (!entry) { 261 if (!entry) {
266 SendErrorMessage(stream_id); 262 SendErrorMessage(stream_id);
267 return; 263 return;
268 } 264 }
269 265
270 entry->controller->Pause(); 266 entry->controller->Pause();
271 if (GetMediaObserver()) 267 if (media_observer_)
272 GetMediaObserver()->OnSetAudioStreamPlaying(this, stream_id, false); 268 media_observer_->OnSetAudioStreamPlaying(this, stream_id, false);
273 } 269 }
274 270
275 void AudioRendererHost::OnFlushStream(int stream_id) { 271 void AudioRendererHost::OnFlushStream(int stream_id) {
276 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 272 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
277 273
278 AudioEntry* entry = LookupById(stream_id); 274 AudioEntry* entry = LookupById(stream_id);
279 if (!entry) { 275 if (!entry) {
280 SendErrorMessage(stream_id); 276 SendErrorMessage(stream_id);
281 return; 277 return;
282 } 278 }
283 279
284 entry->controller->Flush(); 280 entry->controller->Flush();
285 if (GetMediaObserver()) 281 if (media_observer_)
286 GetMediaObserver()->OnSetAudioStreamStatus(this, stream_id, "flushed"); 282 media_observer_->OnSetAudioStreamStatus(this, stream_id, "flushed");
287 } 283 }
288 284
289 void AudioRendererHost::OnCloseStream(int stream_id) { 285 void AudioRendererHost::OnCloseStream(int stream_id) {
290 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 286 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
291 287
292 if (GetMediaObserver()) 288 if (media_observer_)
293 GetMediaObserver()->OnSetAudioStreamStatus(this, stream_id, "closed"); 289 media_observer_->OnSetAudioStreamStatus(this, stream_id, "closed");
294 290
295 AudioEntry* entry = LookupById(stream_id); 291 AudioEntry* entry = LookupById(stream_id);
296 292
297 if (entry) 293 if (entry)
298 CloseAndDeleteStream(entry); 294 CloseAndDeleteStream(entry);
299 } 295 }
300 296
301 void AudioRendererHost::OnSetVolume(int stream_id, double volume) { 297 void AudioRendererHost::OnSetVolume(int stream_id, double volume) {
302 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 298 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
303 299
304 AudioEntry* entry = LookupById(stream_id); 300 AudioEntry* entry = LookupById(stream_id);
305 if (!entry) { 301 if (!entry) {
306 SendErrorMessage(stream_id); 302 SendErrorMessage(stream_id);
307 return; 303 return;
308 } 304 }
309 305
310 // Make sure the volume is valid. 306 // Make sure the volume is valid.
311 if (volume < 0 || volume > 1.0) 307 if (volume < 0 || volume > 1.0)
312 return; 308 return;
313 entry->controller->SetVolume(volume); 309 entry->controller->SetVolume(volume);
314 if (GetMediaObserver()) 310 if (media_observer_)
315 GetMediaObserver()->OnSetAudioStreamVolume(this, stream_id, volume); 311 media_observer_->OnSetAudioStreamVolume(this, stream_id, volume);
316 } 312 }
317 313
318 void AudioRendererHost::SendErrorMessage(int32 stream_id) { 314 void AudioRendererHost::SendErrorMessage(int32 stream_id) {
319 Send(new AudioMsg_NotifyStreamStateChanged(stream_id, kAudioStreamError)); 315 Send(new AudioMsg_NotifyStreamStateChanged(stream_id, kAudioStreamError));
320 } 316 }
321 317
322 void AudioRendererHost::DeleteEntries() { 318 void AudioRendererHost::DeleteEntries() {
323 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 319 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
324 320
325 for (AudioEntryMap::iterator i = audio_entries_.begin(); 321 for (AudioEntryMap::iterator i = audio_entries_.begin();
(...skipping 23 matching lines...) Expand all
349 void AudioRendererHost::DeleteEntry(AudioEntry* entry) { 345 void AudioRendererHost::DeleteEntry(AudioEntry* entry) {
350 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 346 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
351 347
352 // Delete the entry when this method goes out of scope. 348 // Delete the entry when this method goes out of scope.
353 scoped_ptr<AudioEntry> entry_deleter(entry); 349 scoped_ptr<AudioEntry> entry_deleter(entry);
354 350
355 // Erase the entry identified by |stream_id| from the map. 351 // Erase the entry identified by |stream_id| from the map.
356 audio_entries_.erase(entry->stream_id); 352 audio_entries_.erase(entry->stream_id);
357 353
358 // Notify the media observer. 354 // Notify the media observer.
359 if (GetMediaObserver()) 355 if (media_observer_)
360 GetMediaObserver()->OnDeleteAudioStream(this, entry->stream_id); 356 media_observer_->OnDeleteAudioStream(this, entry->stream_id);
361 } 357 }
362 358
363 void AudioRendererHost::DeleteEntryOnError(AudioEntry* entry) { 359 void AudioRendererHost::DeleteEntryOnError(AudioEntry* entry) {
364 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 360 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
365 361
366 // Sends the error message first before we close the stream because 362 // Sends the error message first before we close the stream because
367 // |entry| is destroyed in DeleteEntry(). 363 // |entry| is destroyed in DeleteEntry().
368 SendErrorMessage(entry->stream_id); 364 SendErrorMessage(entry->stream_id);
369 365
370 if (GetMediaObserver()) 366 if (media_observer_)
371 GetMediaObserver()->OnSetAudioStreamStatus(this, entry->stream_id, "error"); 367 media_observer_->OnSetAudioStreamStatus(this, entry->stream_id, "error");
372 CloseAndDeleteStream(entry); 368 CloseAndDeleteStream(entry);
373 } 369 }
374 370
375 AudioRendererHost::AudioEntry* AudioRendererHost::LookupById(int stream_id) { 371 AudioRendererHost::AudioEntry* AudioRendererHost::LookupById(int stream_id) {
376 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 372 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
377 373
378 AudioEntryMap::iterator i = audio_entries_.find(stream_id); 374 AudioEntryMap::iterator i = audio_entries_.find(stream_id);
379 if (i != audio_entries_.end() && !i->second->pending_close) 375 if (i != audio_entries_.end() && !i->second->pending_close)
380 return i->second; 376 return i->second;
381 return NULL; 377 return NULL;
382 } 378 }
383 379
384 AudioRendererHost::AudioEntry* AudioRendererHost::LookupByController( 380 AudioRendererHost::AudioEntry* AudioRendererHost::LookupByController(
385 media::AudioOutputController* controller) { 381 media::AudioOutputController* controller) {
386 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 382 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
387 383
388 // Iterate the map of entries. 384 // Iterate the map of entries.
389 // TODO(hclam): Implement a faster look up method. 385 // TODO(hclam): Implement a faster look up method.
390 for (AudioEntryMap::iterator i = audio_entries_.begin(); 386 for (AudioEntryMap::iterator i = audio_entries_.begin();
391 i != audio_entries_.end(); ++i) { 387 i != audio_entries_.end(); ++i) {
392 if (!i->second->pending_close && controller == i->second->controller.get()) 388 if (!i->second->pending_close && controller == i->second->controller.get())
393 return i->second; 389 return i->second;
394 } 390 }
395 return NULL; 391 return NULL;
396 } 392 }
397
398 content::MediaObserver* AudioRendererHost::GetMediaObserver() {
399 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
400 if (resource_context_)
401 return resource_context_->GetMediaObserver();
402 return NULL;
403 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698