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

Side by Side Diff: media/audio/linux/alsa_output.cc

Issue 10832285: Switch OnMoreData() to use AudioBus. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase. Comments. Created 8 years, 3 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
« no previous file with comments | « media/audio/linux/alsa_output.h ('k') | media/audio/linux/alsa_output_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 // THREAD SAFETY 5 // THREAD SAFETY
6 // 6 //
7 // AlsaPcmOutputStream object is *not* thread-safe and should only be used 7 // AlsaPcmOutputStream object is *not* thread-safe and should only be used
8 // from the audio thread. We DCHECK on this assumption whenever we can. 8 // from the audio thread. We DCHECK on this assumption whenever we can.
9 // 9 //
10 // SEMANTICS OF Close() 10 // SEMANTICS OF Close()
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 // 84 //
85 // This function makes a best guess at the specific > 2 channel device name 85 // This function makes a best guess at the specific > 2 channel device name
86 // based on the number of channels requested. NULL is returned if no device 86 // based on the number of channels requested. NULL is returned if no device
87 // can be found to match the channel numbers. In this case, using 87 // can be found to match the channel numbers. In this case, using
88 // kDefaultDevice is probably the best bet. 88 // kDefaultDevice is probably the best bet.
89 // 89 //
90 // A five channel source is assumed to be surround50 instead of surround41 90 // A five channel source is assumed to be surround50 instead of surround41
91 // (which is also 5 channels). 91 // (which is also 5 channels).
92 // 92 //
93 // TODO(ajwong): The source data should have enough info to tell us if we want 93 // TODO(ajwong): The source data should have enough info to tell us if we want
94 // surround41 versus surround51, etc., instead of needing us to guess base don 94 // surround41 versus surround51, etc., instead of needing us to guess based on
95 // channel number. Fix API to pass that data down. 95 // channel number. Fix API to pass that data down.
96 static const char* GuessSpecificDeviceName(uint32 channels) { 96 static const char* GuessSpecificDeviceName(uint32 channels) {
97 switch (channels) { 97 switch (channels) {
98 case 8: 98 case 8:
99 return "surround71"; 99 return "surround71";
100 100
101 case 7: 101 case 7:
102 return "surround70"; 102 return "surround70";
103 103
104 case 6: 104 case 6:
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 alsa_buffer_frames_(0), 168 alsa_buffer_frames_(0),
169 stop_stream_(false), 169 stop_stream_(false),
170 wrapper_(wrapper), 170 wrapper_(wrapper),
171 manager_(manager), 171 manager_(manager),
172 message_loop_(MessageLoop::current()), 172 message_loop_(MessageLoop::current()),
173 playback_handle_(NULL), 173 playback_handle_(NULL),
174 frames_per_packet_(packet_size_ / bytes_per_frame_), 174 frames_per_packet_(packet_size_ / bytes_per_frame_),
175 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)), 175 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)),
176 state_(kCreated), 176 state_(kCreated),
177 volume_(1.0f), 177 volume_(1.0f),
178 source_callback_(NULL) { 178 source_callback_(NULL),
179 audio_bus_(AudioBus::Create(params)) {
179 DCHECK(manager_->GetMessageLoop()->BelongsToCurrentThread()); 180 DCHECK(manager_->GetMessageLoop()->BelongsToCurrentThread());
181 DCHECK_EQ(audio_bus_->frames() * bytes_per_frame_, packet_size_);
180 182
181 // Sanity check input values. 183 // Sanity check input values.
182 if (params.sample_rate() > kAlsaMaxSampleRate || 184 if (params.sample_rate() > kAlsaMaxSampleRate ||
183 params.sample_rate() <= 0) { 185 params.sample_rate() <= 0) {
184 LOG(WARNING) << "Unsupported audio frequency."; 186 LOG(WARNING) << "Unsupported audio frequency.";
185 TransitionTo(kInError); 187 TransitionTo(kInError);
186 } 188 }
187 189
188 if (AudioParameters::AUDIO_PCM_LINEAR != params.format() && 190 if (AudioParameters::AUDIO_PCM_LINEAR != params.format() &&
189 AudioParameters::AUDIO_PCM_LOW_LATENCY != params.format()) { 191 AudioParameters::AUDIO_PCM_LOW_LATENCY != params.format()) {
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
369 // Before making a request to source for data we need to determine the 371 // Before making a request to source for data we need to determine the
370 // delay (in bytes) for the requested data to be played. 372 // delay (in bytes) for the requested data to be played.
371 373
372 uint32 buffer_delay = buffer_->forward_bytes() * bytes_per_frame_ / 374 uint32 buffer_delay = buffer_->forward_bytes() * bytes_per_frame_ /
373 bytes_per_output_frame_; 375 bytes_per_output_frame_;
374 376
375 uint32 hardware_delay = GetCurrentDelay() * bytes_per_frame_; 377 uint32 hardware_delay = GetCurrentDelay() * bytes_per_frame_;
376 378
377 scoped_refptr<media::DataBuffer> packet = 379 scoped_refptr<media::DataBuffer> packet =
378 new media::DataBuffer(packet_size_); 380 new media::DataBuffer(packet_size_);
379 int packet_size = RunDataCallback(packet->GetWritableData(), 381 int frames_filled = RunDataCallback(
380 packet->GetBufferSize(), 382 audio_bus_.get(), AudioBuffersState(buffer_delay, hardware_delay));
381 AudioBuffersState(buffer_delay, 383 size_t packet_size = frames_filled * bytes_per_frame_;
382 hardware_delay)); 384 DCHECK_LE(packet_size, packet_size_);
383 CHECK_LE(packet_size, packet->GetBufferSize()); 385 // Note: If this ever changes to output raw float the data must be clipped
386 // and sanitized since it may come from an untrusted source such as NaCl.
387 audio_bus_->ToInterleaved(
388 frames_filled, bytes_per_sample_, packet->GetWritableData());
384 389
385 // Reset the |last_fill_time| to avoid back to back RunDataCallback(). 390 // Reset the |last_fill_time| to avoid back to back RunDataCallback().
386 last_fill_time_ = base::Time::Now(); 391 last_fill_time_ = base::Time::Now();
387 392
388 // This should not happen, but in case it does, drop any trailing bytes 393 // TODO(dalecurtis): Channel downmixing, upmixing, should be done in mixer;
389 // that aren't large enough to make a frame. Without this, packet writing 394 // volume adjust should use SSE optimized vector_fmul() prior to interleave.
390 // may stall because the last few bytes in the packet may never get used by
391 // WritePacket.
392 DCHECK_EQ(0u, packet_size % bytes_per_frame_);
393 packet_size = (packet_size / bytes_per_frame_) * bytes_per_frame_;
394
395 if (should_downmix_) { 395 if (should_downmix_) {
396 if (media::FoldChannels(packet->GetWritableData(), 396 if (media::FoldChannels(packet->GetWritableData(),
397 packet_size, 397 packet_size,
398 channels_, 398 channels_,
399 bytes_per_sample_, 399 bytes_per_sample_,
400 volume_)) { 400 volume_)) {
401 // Adjust packet size for downmix. 401 // Adjust packet size for downmix.
402 packet_size = packet_size / bytes_per_frame_ * bytes_per_output_frame_; 402 packet_size = packet_size / bytes_per_frame_ * bytes_per_output_frame_;
403 } else { 403 } else {
404 LOG(ERROR) << "Folding failed"; 404 LOG(ERROR) << "Folding failed";
(...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after
777 } 777 }
778 778
779 AlsaPcmOutputStream::InternalState AlsaPcmOutputStream::state() { 779 AlsaPcmOutputStream::InternalState AlsaPcmOutputStream::state() {
780 return state_; 780 return state_;
781 } 781 }
782 782
783 bool AlsaPcmOutputStream::IsOnAudioThread() const { 783 bool AlsaPcmOutputStream::IsOnAudioThread() const {
784 return message_loop_ && message_loop_ == MessageLoop::current(); 784 return message_loop_ && message_loop_ == MessageLoop::current();
785 } 785 }
786 786
787 uint32 AlsaPcmOutputStream::RunDataCallback(uint8* dest, 787 int AlsaPcmOutputStream::RunDataCallback(AudioBus* audio_bus,
788 uint32 max_size, 788 AudioBuffersState buffers_state) {
789 AudioBuffersState buffers_state) {
790 TRACE_EVENT0("audio", "AlsaPcmOutputStream::RunDataCallback"); 789 TRACE_EVENT0("audio", "AlsaPcmOutputStream::RunDataCallback");
791 790
792 if (source_callback_) 791 if (source_callback_)
793 return source_callback_->OnMoreData(dest, max_size, buffers_state); 792 return source_callback_->OnMoreData(audio_bus, buffers_state);
794 793
795 return 0; 794 return 0;
796 } 795 }
797 796
798 void AlsaPcmOutputStream::RunErrorCallback(int code) { 797 void AlsaPcmOutputStream::RunErrorCallback(int code) {
799 if (source_callback_) 798 if (source_callback_)
800 source_callback_->OnError(this, code); 799 source_callback_->OnError(this, code);
801 } 800 }
802 801
803 // Changes the AudioSourceCallback to proxy calls to. Pass in NULL to 802 // Changes the AudioSourceCallback to proxy calls to. Pass in NULL to
804 // release ownership of the currently registered callback. 803 // release ownership of the currently registered callback.
805 void AlsaPcmOutputStream::set_source_callback(AudioSourceCallback* callback) { 804 void AlsaPcmOutputStream::set_source_callback(AudioSourceCallback* callback) {
806 DCHECK(IsOnAudioThread()); 805 DCHECK(IsOnAudioThread());
807 source_callback_ = callback; 806 source_callback_ = callback;
808 } 807 }
809 808
810 } // namespace media 809 } // namespace media
OLDNEW
« no previous file with comments | « media/audio/linux/alsa_output.h ('k') | media/audio/linux/alsa_output_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698