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

Unified Diff: third_party/WebKit/Source/platform/audio/PushPullFIFO.cpp

Issue 2777903005: Add WebThread in AudioDestination to support AudioWorkletThread (Closed)
Patch Set: Refactoring WIP (please ignore) Created 3 years, 8 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 side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/platform/audio/PushPullFIFO.cpp
diff --git a/third_party/WebKit/Source/platform/audio/PushPullFIFO.cpp b/third_party/WebKit/Source/platform/audio/PushPullFIFO.cpp
index fdfafd7a37b7ebf3252a98ece9924cee92556794..8f9e9b9e7333616fc29415a44da7b42807342ce0 100644
--- a/third_party/WebKit/Source/platform/audio/PushPullFIFO.cpp
+++ b/third_party/WebKit/Source/platform/audio/PushPullFIFO.cpp
@@ -18,8 +18,13 @@ const unsigned kMaxMessagesToLog = 100;
const size_t PushPullFIFO::kMaxFIFOLength = 65536;
-PushPullFIFO::PushPullFIFO(unsigned number_of_channels, size_t fifo_length)
- : fifo_length_(fifo_length),
+PushPullFIFO::PushPullFIFO(unsigned number_of_channels,
+ size_t fifo_length,
+ ThreadIdentifier rendering_thread_id,
+ AudioIOCallback& web_audio_render_callback)
+ : rendering_thread_id_(rendering_thread_id),
o1ka 2017/04/13 08:36:53 This is too much information for a FIFO. Also, we
hongchan 2017/04/14 16:31:48 Done.
+ web_audio_render_callback_(web_audio_render_callback),
+ fifo_length_(fifo_length),
frames_available_(0),
index_read_(0),
index_write_(0),
@@ -27,62 +32,60 @@ PushPullFIFO::PushPullFIFO(unsigned number_of_channels, size_t fifo_length)
underflow_count_(0) {
CHECK_LE(fifo_length_, kMaxFIFOLength);
fifo_bus_ = AudioBus::Create(number_of_channels, fifo_length_);
+ render_bus_ = AudioBus::Create(number_of_channels,
+ AudioUtilities::kRenderQuantumFrames);
}
PushPullFIFO::~PushPullFIFO() {}
-// Push the data from |inputBus| to FIFO. The size of push is determined by
-// the length of |inputBus|.
-void PushPullFIFO::Push(const AudioBus* input_bus) {
- CHECK(input_bus);
- CHECK_EQ(input_bus->length(), AudioUtilities::kRenderQuantumFrames);
- SECURITY_CHECK(input_bus->length() <= fifo_length_);
- SECURITY_CHECK(index_write_ < fifo_length_);
-
- const size_t input_bus_length = input_bus->length();
- const size_t remainder = fifo_length_ - index_write_;
-
- for (unsigned i = 0; i < fifo_bus_->NumberOfChannels(); ++i) {
- float* fifo_bus_channel = fifo_bus_->Channel(i)->MutableData();
- const float* input_bus_channel = input_bus->Channel(i)->Data();
- if (remainder >= input_bus_length) {
- // The remainder is big enough for the input data.
- memcpy(fifo_bus_channel + index_write_, input_bus_channel,
- input_bus_length * sizeof(*fifo_bus_channel));
- } else {
- // The input data overflows the remainder size. Wrap around the index.
- memcpy(fifo_bus_channel + index_write_, input_bus_channel,
- remainder * sizeof(*fifo_bus_channel));
- memcpy(fifo_bus_channel, input_bus_channel + remainder,
- (input_bus_length - remainder) * sizeof(*fifo_bus_channel));
+void PushPullFIFO::FillRequestedFrames(size_t frames_requested,
+ size_t callback_buffer_size,
+ AudioIOPosition output_position) {
+ DCHECK(IsRenderingThread());
+
+ MutexLocker lock(lock_);
+
+ base::TimeTicks output_position_received_timestamp = base::TimeTicks::Now();
+
+ size_t frames_to_render = frames_requested > frames_available_
+ ? frames_requested - frames_available_
+ : 0;
+
+ for (size_t pushed_frames = 0; pushed_frames < frames_to_render;
+ pushed_frames += AudioUtilities::kRenderQuantumFrames) {
+ // If platform buffer is more than two times longer than |framesToProcess|
+ // we do not want output position to get stuck so we promote it
+ // using the elapsed time from the moment it was initially obtained.
+ if (callback_buffer_size > AudioUtilities::kRenderQuantumFrames * 2) {
+ double delta =
+ (base::TimeTicks::Now() - output_position_received_timestamp)
+ .InSecondsF();
+ output_position.position += delta;
+ output_position.timestamp += delta;
}
- }
- // Update the write index; wrap it around if necessary.
- index_write_ = (index_write_ + input_bus_length) % fifo_length_;
-
- // In case of overflow, move the |indexRead| to the updated |indexWrite| to
- // avoid reading overwritten frames by the next pull.
- if (input_bus_length > fifo_length_ - frames_available_) {
- index_read_ = index_write_;
- if (++overflow_count_ < kMaxMessagesToLog) {
- LOG(WARNING) << "PushPullFIFO: overflow while pushing ("
- << "overflowCount=" << overflow_count_
- << ", availableFrames=" << frames_available_
- << ", inputFrames=" << input_bus_length
- << ", fifoLength=" << fifo_length_ << ")";
- }
+ // Some implementations give only rough estimation of |delay| so
+ // we might have negative estimation |outputPosition| value.
+ if (output_position.position < 0.0)
+ output_position.position = 0.0;
+
+ // Process WebAudio graph and push the rendered output to FIFO.
+ web_audio_render_callback_.Render(nullptr,
+ render_bus_.Get(),
+ AudioUtilities::kRenderQuantumFrames,
+ output_position);
+ Push(render_bus_.Get());
}
-
- // Update the number of frames available in FIFO.
- frames_available_ =
- std::min(frames_available_ + input_bus_length, fifo_length_);
- DCHECK_EQ((index_read_ + frames_available_) % fifo_length_, index_write_);
}
// Pull the data out of FIFO to |outputBus|. If remaining frame in the FIFO
// is less than the frames to pull, provides remaining frame plus the silence.
void PushPullFIFO::Pull(AudioBus* output_bus, size_t frames_requested) {
+ // This runs on audio device thread.
+ DCHECK(!IsRenderingThread());
+
+ MutexLocker lock(lock_);
+
#if OS(ANDROID)
if (!output_bus) {
// Log when outputBus or FIFO object is invalid. (crbug.com/692423)
@@ -110,6 +113,7 @@ void PushPullFIFO::Pull(AudioBus* output_bus, size_t frames_requested) {
<< " >= " << fifo_length_ << ")";
}
#endif
+
CHECK(output_bus);
SECURITY_CHECK(frames_requested <= output_bus->length());
SECURITY_CHECK(frames_requested <= fifo_length_);
@@ -164,9 +168,71 @@ void PushPullFIFO::Pull(AudioBus* output_bus, size_t frames_requested) {
DCHECK_EQ((index_read_ + frames_available_) % fifo_length_, index_write_);
}
+AudioBus* PushPullFIFO::GetFIFOBusForTest() const {
+ MutexLocker lock(lock_);
+ return fifo_bus_.Get();
+}
+
const PushPullFIFOStateForTest PushPullFIFO::GetStateForTest() const {
- return {length(), NumberOfChannels(), FramesAvailable(), index_read_,
+ return {length(), NumberOfChannels(), frames_available_, index_read_,
index_write_, overflow_count_, underflow_count_};
+
+}
+
+bool PushPullFIFO::IsRenderingThread() {
+ return rendering_thread_id_ == CurrentThread();
+}
+
+// Push the data from |inputBus| to FIFO. The size of push is determined by
+// the length of |inputBus|.
+void PushPullFIFO::Push(const AudioBus* input_bus) {
+ // This runs on WebAudio rendering thread.
+ DCHECK(IsRenderingThread());
+
+ CHECK(input_bus);
+ CHECK_EQ(input_bus->length(), AudioUtilities::kRenderQuantumFrames);
+ SECURITY_CHECK(input_bus->length() <= fifo_length_);
+ SECURITY_CHECK(index_write_ < fifo_length_);
+
+ const size_t input_bus_length = input_bus->length();
+ const size_t remainder = fifo_length_ - index_write_;
+
+ for (unsigned i = 0; i < fifo_bus_->NumberOfChannels(); ++i) {
+ float* fifo_bus_channel = fifo_bus_->Channel(i)->MutableData();
+ const float* input_bus_channel = input_bus->Channel(i)->Data();
+ if (remainder >= input_bus_length) {
+ // The remainder is big enough for the input data.
+ memcpy(fifo_bus_channel + index_write_, input_bus_channel,
+ input_bus_length * sizeof(*fifo_bus_channel));
+ } else {
+ // The input data overflows the remainder size. Wrap around the index.
+ memcpy(fifo_bus_channel + index_write_, input_bus_channel,
+ remainder * sizeof(*fifo_bus_channel));
+ memcpy(fifo_bus_channel, input_bus_channel + remainder,
+ (input_bus_length - remainder) * sizeof(*fifo_bus_channel));
+ }
+ }
+
+ // Update the write index; wrap it around if necessary.
+ index_write_ = (index_write_ + input_bus_length) % fifo_length_;
+
+ // In case of overflow, move the |indexRead| to the updated |indexWrite| to
+ // avoid reading overwritten frames by the next pull.
+ if (input_bus_length > fifo_length_ - frames_available_) {
+ index_read_ = index_write_;
+ if (++overflow_count_ < kMaxMessagesToLog) {
+ LOG(WARNING) << "PushPullFIFO: overflow while pushing ("
+ << "overflowCount=" << overflow_count_
+ << ", availableFrames=" << frames_available_
+ << ", inputFrames=" << input_bus_length
+ << ", fifoLength=" << fifo_length_ << ")";
+ }
+ }
+
+ // Update the number of frames available in FIFO.
+ frames_available_ =
+ std::min(frames_available_ + input_bus_length, fifo_length_);
+ DCHECK_EQ((index_read_ + frames_available_) % fifo_length_, index_write_);
}
} // namespace blink

Powered by Google App Engine
This is Rietveld 408576698