Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 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 "platform/audio/PushPullFIFO.h" | 5 #include "platform/audio/PushPullFIFO.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 #include "platform/audio/AudioUtilities.h" | 8 #include "platform/audio/AudioUtilities.h" |
| 9 #include "platform/wtf/PtrUtil.h" | 9 #include "platform/wtf/PtrUtil.h" |
| 10 | 10 |
| 11 namespace blink { | 11 namespace blink { |
| 12 | 12 |
| 13 namespace { | 13 namespace { |
| 14 | 14 |
| 15 // Suppress the warning log if over/underflow happens more than 100 times. | 15 // Suppress the warning log if over/underflow happens more than 100 times. |
| 16 const unsigned kMaxMessagesToLog = 100; | 16 const unsigned kMaxMessagesToLog = 100; |
| 17 } | 17 } |
| 18 | 18 |
| 19 const size_t PushPullFIFO::kMaxFIFOLength = 65536; | 19 const size_t PushPullFIFO::kMaxFIFOLength = 65536; |
| 20 | 20 |
| 21 PushPullFIFO::PushPullFIFO(unsigned number_of_channels, size_t fifo_length) | 21 PushPullFIFO::PushPullFIFO(unsigned number_of_channels, size_t fifo_length) |
| 22 : fifo_length_(fifo_length), | 22 : fifo_length_(fifo_length), |
| 23 frames_available_(0), | 23 frames_available_(0), |
| 24 index_read_(0), | 24 index_read_(0), |
| 25 index_write_(0), | 25 index_write_(0) { |
|
nhiroki
2017/04/25 00:35:51
Optional: How about initializing these variables i
hongchan
2017/04/25 20:36:41
Done.
| |
| 26 overflow_count_(0), | |
| 27 underflow_count_(0) { | |
| 28 CHECK_LE(fifo_length_, kMaxFIFOLength); | 26 CHECK_LE(fifo_length_, kMaxFIFOLength); |
| 29 fifo_bus_ = AudioBus::Create(number_of_channels, fifo_length_); | 27 fifo_bus_ = AudioBus::Create(number_of_channels, fifo_length_); |
| 30 } | 28 } |
| 31 | 29 |
| 32 PushPullFIFO::~PushPullFIFO() {} | 30 PushPullFIFO::~PushPullFIFO() {} |
| 33 | 31 |
| 34 // Push the data from |inputBus| to FIFO. The size of push is determined by | 32 // Push the data from |inputBus| to FIFO. The size of push is determined by |
| 35 // the length of |inputBus|. | 33 // the length of |inputBus|. |
| 36 void PushPullFIFO::Push(const AudioBus* input_bus) { | 34 void PushPullFIFO::Push(const AudioBus* input_bus) { |
| 35 MutexLocker locker(lock_); | |
| 36 | |
| 37 CHECK(input_bus); | 37 CHECK(input_bus); |
| 38 CHECK_EQ(input_bus->length(), AudioUtilities::kRenderQuantumFrames); | 38 CHECK_EQ(input_bus->length(), AudioUtilities::kRenderQuantumFrames); |
| 39 SECURITY_CHECK(input_bus->length() <= fifo_length_); | 39 SECURITY_CHECK(input_bus->length() <= fifo_length_); |
| 40 SECURITY_CHECK(index_write_ < fifo_length_); | 40 SECURITY_CHECK(index_write_ < fifo_length_); |
| 41 | 41 |
| 42 const size_t input_bus_length = input_bus->length(); | 42 const size_t input_bus_length = input_bus->length(); |
| 43 const size_t remainder = fifo_length_ - index_write_; | 43 const size_t remainder = fifo_length_ - index_write_; |
| 44 | 44 |
| 45 for (unsigned i = 0; i < fifo_bus_->NumberOfChannels(); ++i) { | 45 for (unsigned i = 0; i < fifo_bus_->NumberOfChannels(); ++i) { |
| 46 float* fifo_bus_channel = fifo_bus_->Channel(i)->MutableData(); | 46 float* fifo_bus_channel = fifo_bus_->Channel(i)->MutableData(); |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 75 } | 75 } |
| 76 | 76 |
| 77 // Update the number of frames available in FIFO. | 77 // Update the number of frames available in FIFO. |
| 78 frames_available_ = | 78 frames_available_ = |
| 79 std::min(frames_available_ + input_bus_length, fifo_length_); | 79 std::min(frames_available_ + input_bus_length, fifo_length_); |
| 80 DCHECK_EQ((index_read_ + frames_available_) % fifo_length_, index_write_); | 80 DCHECK_EQ((index_read_ + frames_available_) % fifo_length_, index_write_); |
| 81 } | 81 } |
| 82 | 82 |
| 83 // Pull the data out of FIFO to |outputBus|. If remaining frame in the FIFO | 83 // Pull the data out of FIFO to |outputBus|. If remaining frame in the FIFO |
| 84 // is less than the frames to pull, provides remaining frame plus the silence. | 84 // is less than the frames to pull, provides remaining frame plus the silence. |
| 85 void PushPullFIFO::Pull(AudioBus* output_bus, size_t frames_requested) { | 85 size_t PushPullFIFO::Pull(AudioBus* output_bus, size_t frames_requested) { |
| 86 MutexLocker locker(lock_); | |
| 87 | |
| 86 #if OS(ANDROID) | 88 #if OS(ANDROID) |
| 87 if (!output_bus) { | 89 if (!output_bus) { |
| 88 // Log when outputBus or FIFO object is invalid. (crbug.com/692423) | 90 // Log when outputBus or FIFO object is invalid. (crbug.com/692423) |
| 89 LOG(WARNING) << "[WebAudio/PushPullFIFO::pull <" << static_cast<void*>(this) | 91 LOG(WARNING) << "[WebAudio/PushPullFIFO::pull <" << static_cast<void*>(this) |
| 90 << ">] |outputBus| is invalid."; | 92 << ">] |outputBus| is invalid."; |
| 91 // Silently return to avoid crash. | 93 // Silently return to avoid crash. |
| 92 return; | 94 return 0; |
| 93 } | 95 } |
| 94 | 96 |
| 95 // The following checks are in place to catch the inexplicable crash. | 97 // The following checks are in place to catch the inexplicable crash. |
| 96 // (crbug.com/692423) | 98 // (crbug.com/692423) |
| 97 if (frames_requested > output_bus->length()) { | 99 if (frames_requested > output_bus->length()) { |
| 98 LOG(WARNING) << "[WebAudio/PushPullFIFO::pull <" << static_cast<void*>(this) | 100 LOG(WARNING) << "[WebAudio/PushPullFIFO::pull <" << static_cast<void*>(this) |
| 99 << ">] framesRequested > outputBus->length() (" | 101 << ">] framesRequested > outputBus->length() (" |
| 100 << frames_requested << " > " << output_bus->length() << ")"; | 102 << frames_requested << " > " << output_bus->length() << ")"; |
| 101 } | 103 } |
| 102 if (frames_requested > fifo_length_) { | 104 if (frames_requested > fifo_length_) { |
| 103 LOG(WARNING) << "[WebAudio/PushPullFIFO::pull <" << static_cast<void*>(this) | 105 LOG(WARNING) << "[WebAudio/PushPullFIFO::pull <" << static_cast<void*>(this) |
| 104 << ">] framesRequested > m_fifoLength (" << frames_requested | 106 << ">] framesRequested > m_fifoLength (" << frames_requested |
| 105 << " > " << fifo_length_ << ")"; | 107 << " > " << fifo_length_ << ")"; |
| 106 } | 108 } |
| 107 if (index_read_ >= fifo_length_) { | 109 if (index_read_ >= fifo_length_) { |
| 108 LOG(WARNING) << "[WebAudio/PushPullFIFO::pull <" << static_cast<void*>(this) | 110 LOG(WARNING) << "[WebAudio/PushPullFIFO::pull <" << static_cast<void*>(this) |
| 109 << ">] m_indexRead >= m_fifoLength (" << index_read_ | 111 << ">] m_indexRead >= m_fifoLength (" << index_read_ |
| 110 << " >= " << fifo_length_ << ")"; | 112 << " >= " << fifo_length_ << ")"; |
| 111 } | 113 } |
| 112 #endif | 114 #endif |
| 115 | |
| 113 CHECK(output_bus); | 116 CHECK(output_bus); |
| 114 SECURITY_CHECK(frames_requested <= output_bus->length()); | 117 SECURITY_CHECK(frames_requested <= output_bus->length()); |
| 115 SECURITY_CHECK(frames_requested <= fifo_length_); | 118 SECURITY_CHECK(frames_requested <= fifo_length_); |
| 116 SECURITY_CHECK(index_read_ < fifo_length_); | 119 SECURITY_CHECK(index_read_ < fifo_length_); |
| 117 | 120 |
| 118 const size_t remainder = fifo_length_ - index_read_; | 121 const size_t remainder = fifo_length_ - index_read_; |
| 119 const size_t frames_to_fill = std::min(frames_available_, frames_requested); | 122 const size_t frames_to_fill = std::min(frames_available_, frames_requested); |
| 120 | 123 |
| 121 for (unsigned i = 0; i < fifo_bus_->NumberOfChannels(); ++i) { | 124 for (unsigned i = 0; i < fifo_bus_->NumberOfChannels(); ++i) { |
| 122 const float* fifo_bus_channel = fifo_bus_->Channel(i)->Data(); | 125 const float* fifo_bus_channel = fifo_bus_->Channel(i)->Data(); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 155 << "underflowCount=" << underflow_count_ | 158 << "underflowCount=" << underflow_count_ |
| 156 << ", availableFrames=" << frames_available_ | 159 << ", availableFrames=" << frames_available_ |
| 157 << ", requestedFrames=" << frames_requested | 160 << ", requestedFrames=" << frames_requested |
| 158 << ", fifoLength=" << fifo_length_ << ")"; | 161 << ", fifoLength=" << fifo_length_ << ")"; |
| 159 } | 162 } |
| 160 } | 163 } |
| 161 | 164 |
| 162 // Update the number of frames in FIFO. | 165 // Update the number of frames in FIFO. |
| 163 frames_available_ -= frames_to_fill; | 166 frames_available_ -= frames_to_fill; |
| 164 DCHECK_EQ((index_read_ + frames_available_) % fifo_length_, index_write_); | 167 DCHECK_EQ((index_read_ + frames_available_) % fifo_length_, index_write_); |
| 168 | |
| 169 // |framesToRender > 0| means the frames in FIFO is not enough to fulfill the | |
| 170 // requested frames from the audio device. | |
| 171 return frames_requested > frames_available_ | |
| 172 ? frames_requested - frames_available_ | |
| 173 : 0; | |
| 165 } | 174 } |
| 166 | 175 |
| 167 const PushPullFIFOStateForTest PushPullFIFO::GetStateForTest() const { | 176 const PushPullFIFOStateForTest PushPullFIFO::GetStateForTest() const { |
|
nhiroki
2017/04/25 00:35:51
Should we protect this by the lock, too?
hongchan
2017/04/25 20:36:41
This method is only for test, and to use the lock
| |
| 168 return {length(), NumberOfChannels(), FramesAvailable(), index_read_, | 177 return {length(), NumberOfChannels(), frames_available_, index_read_, |
| 169 index_write_, overflow_count_, underflow_count_}; | 178 index_write_, overflow_count_, underflow_count_}; |
| 170 } | 179 } |
| 171 | 180 |
| 172 } // namespace blink | 181 } // namespace blink |
| OLD | NEW |