OLD | NEW |
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 "media/audio/mac/audio_output_mac.h" | 5 #include "media/audio/mac/audio_output_mac.h" |
6 | 6 |
7 #include <CoreServices/CoreServices.h> | 7 #include <CoreServices/CoreServices.h> |
8 | 8 |
9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
10 #include "base/debug/trace_event.h" | 10 #include "base/debug/trace_event.h" |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
46 packet_size_(params.GetBytesPerBuffer()), | 46 packet_size_(params.GetBytesPerBuffer()), |
47 silence_bytes_(0), | 47 silence_bytes_(0), |
48 volume_(1), | 48 volume_(1), |
49 pending_bytes_(0), | 49 pending_bytes_(0), |
50 num_source_channels_(params.channels()), | 50 num_source_channels_(params.channels()), |
51 source_layout_(params.channel_layout()), | 51 source_layout_(params.channel_layout()), |
52 num_core_channels_(0), | 52 num_core_channels_(0), |
53 should_swizzle_(false), | 53 should_swizzle_(false), |
54 should_down_mix_(false), | 54 should_down_mix_(false), |
55 stopped_event_(true /* manual reset */, false /* initial state */), | 55 stopped_event_(true /* manual reset */, false /* initial state */), |
56 num_buffers_left_(kNumBuffers) { | 56 num_buffers_left_(kNumBuffers), |
| 57 audio_bus_(AudioBus::Create(params)) { |
57 // We must have a manager. | 58 // We must have a manager. |
58 DCHECK(manager_); | 59 DCHECK(manager_); |
59 // A frame is one sample across all channels. In interleaved audio the per | 60 // A frame is one sample across all channels. In interleaved audio the per |
60 // frame fields identify the set of n |channels|. In uncompressed audio, a | 61 // frame fields identify the set of n |channels|. In uncompressed audio, a |
61 // packet is always one frame. | 62 // packet is always one frame. |
62 format_.mSampleRate = params.sample_rate(); | 63 format_.mSampleRate = params.sample_rate(); |
63 format_.mFormatID = kAudioFormatLinearPCM; | 64 format_.mFormatID = kAudioFormatLinearPCM; |
64 format_.mFormatFlags = kLinearPCMFormatFlagIsPacked; | 65 format_.mFormatFlags = kLinearPCMFormatFlagIsPacked; |
65 format_.mBitsPerChannel = params.bits_per_sample(); | 66 format_.mBitsPerChannel = params.bits_per_sample(); |
66 format_.mChannelsPerFrame = params.channels(); | 67 format_.mChannelsPerFrame = params.channels(); |
(...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
402 // Should never touch audio_stream after signaling as it | 403 // Should never touch audio_stream after signaling as it |
403 // can be deleted at any moment. | 404 // can be deleted at any moment. |
404 audio_stream->stopped_event_.Signal(); | 405 audio_stream->stopped_event_.Signal(); |
405 } | 406 } |
406 return; | 407 return; |
407 } | 408 } |
408 | 409 |
409 // Adjust the number of pending bytes by subtracting the amount played. | 410 // Adjust the number of pending bytes by subtracting the amount played. |
410 if (!static_cast<AudioQueueUserData*>(buffer->mUserData)->empty_buffer) | 411 if (!static_cast<AudioQueueUserData*>(buffer->mUserData)->empty_buffer) |
411 audio_stream->pending_bytes_ -= buffer->mAudioDataByteSize; | 412 audio_stream->pending_bytes_ -= buffer->mAudioDataByteSize; |
| 413 |
412 uint32 capacity = buffer->mAudioDataBytesCapacity; | 414 uint32 capacity = buffer->mAudioDataBytesCapacity; |
| 415 AudioBus* audio_bus = audio_stream->audio_bus_.get(); |
| 416 DCHECK_EQ( |
| 417 audio_bus->frames() * audio_stream->format_.mBytesPerFrame, capacity); |
413 // TODO(sergeyu): Specify correct hardware delay for AudioBuffersState. | 418 // TODO(sergeyu): Specify correct hardware delay for AudioBuffersState. |
414 uint32 filled = source->OnMoreData( | 419 int frames_filled = source->OnMoreData( |
415 reinterpret_cast<uint8*>(buffer->mAudioData), capacity, | 420 audio_bus, AudioBuffersState(audio_stream->pending_bytes_, 0)); |
416 AudioBuffersState(audio_stream->pending_bytes_, 0)); | 421 uint32 filled = frames_filled * audio_stream->format_.mBytesPerFrame; |
| 422 // Note: If this ever changes to output raw float the data must be clipped and |
| 423 // sanitized since it may come from an untrusted source such as NaCl. |
| 424 audio_bus->ToInterleaved( |
| 425 frames_filled, audio_stream->format_.mBitsPerChannel / 8, |
| 426 buffer->mAudioData); |
417 | 427 |
418 // In order to keep the callback running, we need to provide a positive amount | 428 // In order to keep the callback running, we need to provide a positive amount |
419 // of data to the audio queue. To simulate the behavior of Windows, we write | 429 // of data to the audio queue. To simulate the behavior of Windows, we write |
420 // a buffer of silence. | 430 // a buffer of silence. |
421 if (!filled) { | 431 if (!filled) { |
422 CHECK(audio_stream->silence_bytes_ <= static_cast<int>(capacity)); | 432 CHECK(audio_stream->silence_bytes_ <= static_cast<int>(capacity)); |
423 filled = audio_stream->silence_bytes_; | 433 filled = audio_stream->silence_bytes_; |
424 | 434 |
425 // Assume unsigned audio. | 435 // Assume unsigned audio. |
426 int silence_value = 128; | 436 int silence_value = 128; |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
531 source_ = source; | 541 source_ = source; |
532 } | 542 } |
533 | 543 |
534 AudioOutputStream::AudioSourceCallback* | 544 AudioOutputStream::AudioSourceCallback* |
535 PCMQueueOutAudioOutputStream::GetSource() { | 545 PCMQueueOutAudioOutputStream::GetSource() { |
536 base::AutoLock lock(source_lock_); | 546 base::AutoLock lock(source_lock_); |
537 return source_; | 547 return source_; |
538 } | 548 } |
539 | 549 |
540 } // namespace media | 550 } // namespace media |
OLD | NEW |