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

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

Issue 1534273002: Switch to standard integer types in media/. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: more Created 5 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 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
71 // based on the number of channels requested. NULL is returned if no device 71 // based on the number of channels requested. NULL is returned if no device
72 // can be found to match the channel numbers. In this case, using 72 // can be found to match the channel numbers. In this case, using
73 // kDefaultDevice is probably the best bet. 73 // kDefaultDevice is probably the best bet.
74 // 74 //
75 // A five channel source is assumed to be surround50 instead of surround41 75 // A five channel source is assumed to be surround50 instead of surround41
76 // (which is also 5 channels). 76 // (which is also 5 channels).
77 // 77 //
78 // TODO(ajwong): The source data should have enough info to tell us if we want 78 // TODO(ajwong): The source data should have enough info to tell us if we want
79 // surround41 versus surround51, etc., instead of needing us to guess based on 79 // surround41 versus surround51, etc., instead of needing us to guess based on
80 // channel number. Fix API to pass that data down. 80 // channel number. Fix API to pass that data down.
81 static const char* GuessSpecificDeviceName(uint32 channels) { 81 static const char* GuessSpecificDeviceName(uint32_t channels) {
82 switch (channels) { 82 switch (channels) {
83 case 8: 83 case 8:
84 return "surround71"; 84 return "surround71";
85 85
86 case 7: 86 case 7:
87 return "surround70"; 87 return "surround70";
88 88
89 case 6: 89 case 6:
90 return "surround51"; 90 return "surround51";
91 91
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
124 }; 124 };
125 return os; 125 return os;
126 } 126 }
127 127
128 const char AlsaPcmOutputStream::kDefaultDevice[] = "default"; 128 const char AlsaPcmOutputStream::kDefaultDevice[] = "default";
129 const char AlsaPcmOutputStream::kAutoSelectDevice[] = ""; 129 const char AlsaPcmOutputStream::kAutoSelectDevice[] = "";
130 const char AlsaPcmOutputStream::kPlugPrefix[] = "plug:"; 130 const char AlsaPcmOutputStream::kPlugPrefix[] = "plug:";
131 131
132 // We use 40ms as our minimum required latency. If it is needed, we may be able 132 // We use 40ms as our minimum required latency. If it is needed, we may be able
133 // to get it down to 20ms. 133 // to get it down to 20ms.
134 const uint32 AlsaPcmOutputStream::kMinLatencyMicros = 40 * 1000; 134 const uint32_t AlsaPcmOutputStream::kMinLatencyMicros = 40 * 1000;
135 135
136 AlsaPcmOutputStream::AlsaPcmOutputStream(const std::string& device_name, 136 AlsaPcmOutputStream::AlsaPcmOutputStream(const std::string& device_name,
137 const AudioParameters& params, 137 const AudioParameters& params,
138 AlsaWrapper* wrapper, 138 AlsaWrapper* wrapper,
139 AudioManagerBase* manager) 139 AudioManagerBase* manager)
140 : requested_device_name_(device_name), 140 : requested_device_name_(device_name),
141 pcm_format_(alsa_util::BitsToFormat(params.bits_per_sample())), 141 pcm_format_(alsa_util::BitsToFormat(params.bits_per_sample())),
142 channels_(params.channels()), 142 channels_(params.channels()),
143 channel_layout_(params.channel_layout()), 143 channel_layout_(params.channel_layout()),
144 sample_rate_(params.sample_rate()), 144 sample_rate_(params.sample_rate()),
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
215 215
216 // Finish initializing the stream if the device was opened successfully. 216 // Finish initializing the stream if the device was opened successfully.
217 if (playback_handle_ == NULL) { 217 if (playback_handle_ == NULL) {
218 stop_stream_ = true; 218 stop_stream_ = true;
219 TransitionTo(kInError); 219 TransitionTo(kInError);
220 return false; 220 return false;
221 } 221 }
222 bytes_per_output_frame_ = 222 bytes_per_output_frame_ =
223 channel_mixer_ ? mixed_audio_bus_->channels() * bytes_per_sample_ 223 channel_mixer_ ? mixed_audio_bus_->channels() * bytes_per_sample_
224 : bytes_per_frame_; 224 : bytes_per_frame_;
225 uint32 output_packet_size = frames_per_packet_ * bytes_per_output_frame_; 225 uint32_t output_packet_size = frames_per_packet_ * bytes_per_output_frame_;
226 buffer_.reset(new media::SeekableBuffer(0, output_packet_size)); 226 buffer_.reset(new media::SeekableBuffer(0, output_packet_size));
227 227
228 // Get alsa buffer size. 228 // Get alsa buffer size.
229 snd_pcm_uframes_t buffer_size; 229 snd_pcm_uframes_t buffer_size;
230 snd_pcm_uframes_t period_size; 230 snd_pcm_uframes_t period_size;
231 int error = 231 int error =
232 wrapper_->PcmGetParams(playback_handle_, &buffer_size, &period_size); 232 wrapper_->PcmGetParams(playback_handle_, &buffer_size, &period_size);
233 if (error < 0) { 233 if (error < 0) {
234 LOG(ERROR) << "Failed to get playback buffer size from ALSA: " 234 LOG(ERROR) << "Failed to get playback buffer size from ALSA: "
235 << wrapper_->StrError(error); 235 << wrapper_->StrError(error);
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
351 return; 351 return;
352 } 352 }
353 353
354 *source_exhausted = false; 354 *source_exhausted = false;
355 355
356 // Request more data only when we run out of data in the buffer, because 356 // Request more data only when we run out of data in the buffer, because
357 // WritePacket() consumes only the current chunk of data. 357 // WritePacket() consumes only the current chunk of data.
358 if (!buffer_->forward_bytes()) { 358 if (!buffer_->forward_bytes()) {
359 // Before making a request to source for data we need to determine the 359 // Before making a request to source for data we need to determine the
360 // delay (in bytes) for the requested data to be played. 360 // delay (in bytes) for the requested data to be played.
361 const uint32 hardware_delay = GetCurrentDelay() * bytes_per_frame_; 361 const uint32_t hardware_delay = GetCurrentDelay() * bytes_per_frame_;
362 362
363 scoped_refptr<media::DataBuffer> packet = 363 scoped_refptr<media::DataBuffer> packet =
364 new media::DataBuffer(packet_size_); 364 new media::DataBuffer(packet_size_);
365 int frames_filled = RunDataCallback( 365 int frames_filled = RunDataCallback(
366 audio_bus_.get(), hardware_delay); 366 audio_bus_.get(), hardware_delay);
367 367
368 size_t packet_size = frames_filled * bytes_per_frame_; 368 size_t packet_size = frames_filled * bytes_per_frame_;
369 DCHECK_LE(packet_size, packet_size_); 369 DCHECK_LE(packet_size, packet_size_);
370 370
371 // TODO(dalecurtis): Channel downmixing, upmixing, should be done in mixer; 371 // TODO(dalecurtis): Channel downmixing, upmixing, should be done in mixer;
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
422 if (stop_stream_) { 422 if (stop_stream_) {
423 buffer_->Clear(); 423 buffer_->Clear();
424 return; 424 return;
425 } 425 }
426 426
427 if (state() != kIsPlaying) 427 if (state() != kIsPlaying)
428 return; 428 return;
429 429
430 CHECK_EQ(buffer_->forward_bytes() % bytes_per_output_frame_, 0u); 430 CHECK_EQ(buffer_->forward_bytes() % bytes_per_output_frame_, 0u);
431 431
432 const uint8* buffer_data; 432 const uint8_t* buffer_data;
433 int buffer_size; 433 int buffer_size;
434 if (buffer_->GetCurrentChunk(&buffer_data, &buffer_size)) { 434 if (buffer_->GetCurrentChunk(&buffer_data, &buffer_size)) {
435 snd_pcm_sframes_t frames = std::min( 435 snd_pcm_sframes_t frames = std::min(
436 static_cast<snd_pcm_sframes_t>(buffer_size / bytes_per_output_frame_), 436 static_cast<snd_pcm_sframes_t>(buffer_size / bytes_per_output_frame_),
437 GetAvailableFrames()); 437 GetAvailableFrames());
438 438
439 if (!frames) 439 if (!frames)
440 return; 440 return;
441 441
442 snd_pcm_sframes_t frames_written = 442 snd_pcm_sframes_t frames_written =
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
489 489
490 ScheduleNextWrite(source_exhausted); 490 ScheduleNextWrite(source_exhausted);
491 } 491 }
492 492
493 void AlsaPcmOutputStream::ScheduleNextWrite(bool source_exhausted) { 493 void AlsaPcmOutputStream::ScheduleNextWrite(bool source_exhausted) {
494 DCHECK(IsOnAudioThread()); 494 DCHECK(IsOnAudioThread());
495 495
496 if (stop_stream_ || state() != kIsPlaying) 496 if (stop_stream_ || state() != kIsPlaying)
497 return; 497 return;
498 498
499 const uint32 kTargetFramesAvailable = alsa_buffer_frames_ / 2; 499 const uint32_t kTargetFramesAvailable = alsa_buffer_frames_ / 2;
500 uint32 available_frames = GetAvailableFrames(); 500 uint32_t available_frames = GetAvailableFrames();
501 501
502 base::TimeDelta next_fill_time; 502 base::TimeDelta next_fill_time;
503 if (buffer_->forward_bytes() && available_frames) { 503 if (buffer_->forward_bytes() && available_frames) {
504 // If we've got data available and ALSA has room, deliver it immediately. 504 // If we've got data available and ALSA has room, deliver it immediately.
505 next_fill_time = base::TimeDelta(); 505 next_fill_time = base::TimeDelta();
506 } else if (buffer_->forward_bytes()) { 506 } else if (buffer_->forward_bytes()) {
507 // If we've got data available and no room, poll until room is available. 507 // If we've got data available and no room, poll until room is available.
508 // Polling in this manner allows us to ensure a more consistent callback 508 // Polling in this manner allows us to ensure a more consistent callback
509 // schedule. In testing this yields a variance of +/- 5ms versus the non- 509 // schedule. In testing this yields a variance of +/- 5ms versus the non-
510 // polling strategy which is around +/- 30ms and bimodal. 510 // polling strategy which is around +/- 30ms and bimodal.
(...skipping 18 matching lines...) Expand all
529 next_fill_time); 529 next_fill_time);
530 } 530 }
531 531
532 // static 532 // static
533 base::TimeDelta AlsaPcmOutputStream::FramesToTimeDelta(int frames, 533 base::TimeDelta AlsaPcmOutputStream::FramesToTimeDelta(int frames,
534 double sample_rate) { 534 double sample_rate) {
535 return base::TimeDelta::FromMicroseconds( 535 return base::TimeDelta::FromMicroseconds(
536 frames * base::Time::kMicrosecondsPerSecond / sample_rate); 536 frames * base::Time::kMicrosecondsPerSecond / sample_rate);
537 } 537 }
538 538
539 std::string AlsaPcmOutputStream::FindDeviceForChannels(uint32 channels) { 539 std::string AlsaPcmOutputStream::FindDeviceForChannels(uint32_t channels) {
540 // Constants specified by the ALSA API for device hints. 540 // Constants specified by the ALSA API for device hints.
541 static const int kGetAllDevices = -1; 541 static const int kGetAllDevices = -1;
542 static const char kPcmInterfaceName[] = "pcm"; 542 static const char kPcmInterfaceName[] = "pcm";
543 static const char kIoHintName[] = "IOID"; 543 static const char kIoHintName[] = "IOID";
544 static const char kNameHintName[] = "NAME"; 544 static const char kNameHintName[] = "NAME";
545 545
546 const char* wanted_device = GuessSpecificDeviceName(channels); 546 const char* wanted_device = GuessSpecificDeviceName(channels);
547 if (!wanted_device) 547 if (!wanted_device)
548 return std::string(); 548 return std::string();
549 549
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
635 if (available_frames < 0) { 635 if (available_frames < 0) {
636 available_frames = wrapper_->PcmRecover(playback_handle_, 636 available_frames = wrapper_->PcmRecover(playback_handle_,
637 available_frames, 637 available_frames,
638 kPcmRecoverIsSilent); 638 kPcmRecoverIsSilent);
639 } 639 }
640 if (available_frames < 0) { 640 if (available_frames < 0) {
641 LOG(ERROR) << "Failed querying available frames. Assuming 0: " 641 LOG(ERROR) << "Failed querying available frames. Assuming 0: "
642 << wrapper_->StrError(available_frames); 642 << wrapper_->StrError(available_frames);
643 return 0; 643 return 0;
644 } 644 }
645 if (static_cast<uint32>(available_frames) > alsa_buffer_frames_ * 2) { 645 if (static_cast<uint32_t>(available_frames) > alsa_buffer_frames_ * 2) {
646 LOG(ERROR) << "ALSA returned " << available_frames << " of " 646 LOG(ERROR) << "ALSA returned " << available_frames << " of "
647 << alsa_buffer_frames_ << " frames available."; 647 << alsa_buffer_frames_ << " frames available.";
648 return alsa_buffer_frames_; 648 return alsa_buffer_frames_;
649 } 649 }
650 650
651 return available_frames; 651 return available_frames;
652 } 652 }
653 653
654 snd_pcm_t* AlsaPcmOutputStream::AutoSelectDevice(unsigned int latency) { 654 snd_pcm_t* AlsaPcmOutputStream::AutoSelectDevice(unsigned int latency) {
655 // For auto-selection: 655 // For auto-selection:
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
692 pcm_format_, latency)) != NULL) { 692 pcm_format_, latency)) != NULL) {
693 return handle; 693 return handle;
694 } 694 }
695 } 695 }
696 } 696 }
697 697
698 // For the kDefaultDevice device, we can only reliably depend on 2-channel 698 // For the kDefaultDevice device, we can only reliably depend on 2-channel
699 // output to have the correct ordering according to Lennart. For the channel 699 // output to have the correct ordering according to Lennart. For the channel
700 // formats that we know how to downmix from (3 channel to 8 channel), setup 700 // formats that we know how to downmix from (3 channel to 8 channel), setup
701 // downmixing. 701 // downmixing.
702 uint32 default_channels = channels_; 702 uint32_t default_channels = channels_;
703 if (default_channels > 2) { 703 if (default_channels > 2) {
704 channel_mixer_.reset( 704 channel_mixer_.reset(
705 new ChannelMixer(channel_layout_, kDefaultOutputChannelLayout)); 705 new ChannelMixer(channel_layout_, kDefaultOutputChannelLayout));
706 default_channels = 2; 706 default_channels = 2;
707 mixed_audio_bus_ = AudioBus::Create( 707 mixed_audio_bus_ = AudioBus::Create(
708 default_channels, audio_bus_->frames()); 708 default_channels, audio_bus_->frames());
709 } 709 }
710 710
711 // Step 4. 711 // Step 4.
712 device_name_ = kDefaultDevice; 712 device_name_ = kDefaultDevice;
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
770 770
771 AlsaPcmOutputStream::InternalState AlsaPcmOutputStream::state() { 771 AlsaPcmOutputStream::InternalState AlsaPcmOutputStream::state() {
772 return state_; 772 return state_;
773 } 773 }
774 774
775 bool AlsaPcmOutputStream::IsOnAudioThread() const { 775 bool AlsaPcmOutputStream::IsOnAudioThread() const {
776 return message_loop_ && message_loop_ == base::MessageLoop::current(); 776 return message_loop_ && message_loop_ == base::MessageLoop::current();
777 } 777 }
778 778
779 int AlsaPcmOutputStream::RunDataCallback(AudioBus* audio_bus, 779 int AlsaPcmOutputStream::RunDataCallback(AudioBus* audio_bus,
780 uint32 total_bytes_delay) { 780 uint32_t total_bytes_delay) {
781 TRACE_EVENT0("audio", "AlsaPcmOutputStream::RunDataCallback"); 781 TRACE_EVENT0("audio", "AlsaPcmOutputStream::RunDataCallback");
782 782
783 if (source_callback_) 783 if (source_callback_)
784 return source_callback_->OnMoreData(audio_bus, total_bytes_delay, 0); 784 return source_callback_->OnMoreData(audio_bus, total_bytes_delay, 0);
785 785
786 return 0; 786 return 0;
787 } 787 }
788 788
789 void AlsaPcmOutputStream::RunErrorCallback(int code) { 789 void AlsaPcmOutputStream::RunErrorCallback(int code) {
790 if (source_callback_) 790 if (source_callback_)
791 source_callback_->OnError(this); 791 source_callback_->OnError(this);
792 } 792 }
793 793
794 // Changes the AudioSourceCallback to proxy calls to. Pass in NULL to 794 // Changes the AudioSourceCallback to proxy calls to. Pass in NULL to
795 // release ownership of the currently registered callback. 795 // release ownership of the currently registered callback.
796 void AlsaPcmOutputStream::set_source_callback(AudioSourceCallback* callback) { 796 void AlsaPcmOutputStream::set_source_callback(AudioSourceCallback* callback) {
797 DCHECK(IsOnAudioThread()); 797 DCHECK(IsOnAudioThread());
798 source_callback_ = callback; 798 source_callback_ = callback;
799 } 799 }
800 800
801 } // namespace media 801 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698