OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 "chrome/browser/renderer_host/audio_renderer_host.h" | 5 #include "chrome/browser/renderer_host/audio_renderer_host.h" |
6 | 6 |
7 #include "base/lock.h" | 7 #include "base/lock.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" |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
48 base::SysInfo::OperatingSystemVersionNumbers(&major, &minor, &bugfix); | 48 base::SysInfo::OperatingSystemVersionNumbers(&major, &minor, &bugfix); |
49 if (major < 10 || (major == 10 && minor <= 5)) | 49 if (major < 10 || (major == 10 && minor <= 5)) |
50 return kMaxStreamsLeopard; | 50 return kMaxStreamsLeopard; |
51 #endif | 51 #endif |
52 | 52 |
53 // In OS other than OSX Leopard, the number of audio streams allowed is a | 53 // In OS other than OSX Leopard, the number of audio streams allowed is a |
54 // lot more so we return a separate number. | 54 // lot more so we return a separate number. |
55 return kMaxStreams; | 55 return kMaxStreams; |
56 } | 56 } |
57 | 57 |
58 static uint32 SelectHardwarePacketSize(AudioParameters params) { | 58 static uint32 SelectSamplesPerPacket(AudioParameters params) { |
59 // Select the number of samples that can provide at least | 59 // Select the number of samples that can provide at least |
60 // |kMillisecondsPerHardwarePacket| worth of audio data. | 60 // |kMillisecondsPerHardwarePacket| worth of audio data. |
61 int samples = kMinSamplesPerHardwarePacket; | 61 int samples = kMinSamplesPerHardwarePacket; |
62 while (samples <= kMaxSamplesPerHardwarePacket && | 62 while (samples <= kMaxSamplesPerHardwarePacket && |
63 samples * base::Time::kMillisecondsPerSecond < | 63 samples * base::Time::kMillisecondsPerSecond < |
64 params.sample_rate * kMillisecondsPerHardwarePacket) { | 64 params.sample_rate * kMillisecondsPerHardwarePacket) { |
65 samples *= 2; | 65 samples *= 2; |
66 } | 66 } |
67 return params.channels * samples * params.bits_per_sample / 8; | 67 return samples; |
68 } | 68 } |
69 | 69 |
70 AudioRendererHost::AudioEntry::AudioEntry() | 70 AudioRendererHost::AudioEntry::AudioEntry() |
71 : render_view_id(0), | 71 : render_view_id(0), |
72 stream_id(0), | 72 stream_id(0), |
73 pending_buffer_request(false), | 73 pending_buffer_request(false), |
74 pending_close(false) { | 74 pending_close(false) { |
75 } | 75 } |
76 | 76 |
77 AudioRendererHost::AudioEntry::~AudioEntry() {} | 77 AudioRendererHost::AudioEntry::~AudioEntry() {} |
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
340 | 340 |
341 // Limit the number of audio streams opened. This is to prevent using | 341 // Limit the number of audio streams opened. This is to prevent using |
342 // excessive resources for a large number of audio streams. More | 342 // excessive resources for a large number of audio streams. More |
343 // importantly it prevents instability on certain systems. | 343 // importantly it prevents instability on certain systems. |
344 // See bug: http://crbug.com/30242 | 344 // See bug: http://crbug.com/30242 |
345 if (audio_entries_.size() >= GetMaxAudioStreamsAllowed()) { | 345 if (audio_entries_.size() >= GetMaxAudioStreamsAllowed()) { |
346 SendErrorMessage(msg.routing_id(), stream_id); | 346 SendErrorMessage(msg.routing_id(), stream_id); |
347 return; | 347 return; |
348 } | 348 } |
349 | 349 |
350 // Select the hardwaer packet size if not specified. | 350 AudioParameters audio_params(params.params); |
351 uint32 hardware_packet_size = params.packet_size; | 351 |
352 if (!hardware_packet_size) { | 352 // Select the hardware packet size if not specified. |
353 hardware_packet_size = SelectHardwarePacketSize(params.params); | 353 if (!audio_params.samples_per_packet) { |
| 354 audio_params.samples_per_packet = SelectSamplesPerPacket(audio_params); |
354 } | 355 } |
| 356 uint32 packet_size = audio_params.GetPacketSize(); |
355 | 357 |
356 scoped_ptr<AudioEntry> entry(new AudioEntry()); | 358 scoped_ptr<AudioEntry> entry(new AudioEntry()); |
357 // Create the shared memory and share with the renderer process. | 359 // Create the shared memory and share with the renderer process. |
358 if (!entry->shared_memory.CreateAndMapAnonymous(hardware_packet_size)) { | 360 if (!entry->shared_memory.CreateAndMapAnonymous(packet_size)) { |
359 // If creation of shared memory failed then send an error message. | 361 // If creation of shared memory failed then send an error message. |
360 SendErrorMessage(msg.routing_id(), stream_id); | 362 SendErrorMessage(msg.routing_id(), stream_id); |
361 return; | 363 return; |
362 } | 364 } |
363 | 365 |
364 if (low_latency) { | 366 if (low_latency) { |
365 // If this is the low latency mode, we need to construct a SyncReader first. | 367 // If this is the low latency mode, we need to construct a SyncReader first. |
366 scoped_ptr<AudioSyncReader> reader( | 368 scoped_ptr<AudioSyncReader> reader( |
367 new AudioSyncReader(&entry->shared_memory)); | 369 new AudioSyncReader(&entry->shared_memory)); |
368 | 370 |
369 // Then try to initialize the sync reader. | 371 // Then try to initialize the sync reader. |
370 if (!reader->Init()) { | 372 if (!reader->Init()) { |
371 SendErrorMessage(msg.routing_id(), stream_id); | 373 SendErrorMessage(msg.routing_id(), stream_id); |
372 return; | 374 return; |
373 } | 375 } |
374 | 376 |
375 // If we have successfully created the SyncReader then assign it to the | 377 // If we have successfully created the SyncReader then assign it to the |
376 // entry and construct an AudioOutputController. | 378 // entry and construct an AudioOutputController. |
377 entry->reader.reset(reader.release()); | 379 entry->reader.reset(reader.release()); |
378 entry->controller = | 380 entry->controller = |
379 media::AudioOutputController::CreateLowLatency( | 381 media::AudioOutputController::CreateLowLatency(this, audio_params, |
380 this, params.params, | 382 entry->reader.get()); |
381 hardware_packet_size, | |
382 entry->reader.get()); | |
383 } else { | 383 } else { |
384 // The choice of buffer capacity is based on experiment. | 384 // The choice of buffer capacity is based on experiment. |
385 entry->controller = | 385 entry->controller = |
386 media::AudioOutputController::Create(this, params.params, | 386 media::AudioOutputController::Create(this, audio_params, |
387 hardware_packet_size, | 387 3 * packet_size); |
388 3 * hardware_packet_size); | |
389 } | 388 } |
390 | 389 |
391 if (!entry->controller) { | 390 if (!entry->controller) { |
392 SendErrorMessage(msg.routing_id(), stream_id); | 391 SendErrorMessage(msg.routing_id(), stream_id); |
393 return; | 392 return; |
394 } | 393 } |
395 | 394 |
396 // If we have created the controller successfully create a entry and add it | 395 // If we have created the controller successfully create a entry and add it |
397 // to the map. | 396 // to the map. |
398 entry->render_view_id = msg.routing_id(); | 397 entry->render_view_id = msg.routing_id(); |
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
582 | 581 |
583 // Iterate the map of entries. | 582 // Iterate the map of entries. |
584 // TODO(hclam): Implement a faster look up method. | 583 // TODO(hclam): Implement a faster look up method. |
585 for (AudioEntryMap::iterator i = audio_entries_.begin(); | 584 for (AudioEntryMap::iterator i = audio_entries_.begin(); |
586 i != audio_entries_.end(); ++i) { | 585 i != audio_entries_.end(); ++i) { |
587 if (controller == i->second->controller.get()) | 586 if (controller == i->second->controller.get()) |
588 return i->second; | 587 return i->second; |
589 } | 588 } |
590 return NULL; | 589 return NULL; |
591 } | 590 } |
OLD | NEW |