Index: media/audio/mac/audio_input_mac.cc |
diff --git a/media/audio/mac/audio_input_mac.cc b/media/audio/mac/audio_input_mac.cc |
index fd2d9be06b37ae495a73a9b332891e6cfef1b601..a29e3ec45330980172fd8f3b85e90341f8aeedd3 100644 |
--- a/media/audio/mac/audio_input_mac.cc |
+++ b/media/audio/mac/audio_input_mac.cc |
@@ -192,12 +192,28 @@ void PCMQueueInAudioInputStream::HandleInputBuffer( |
return; |
} |
- if (audio_buffer->mAudioDataByteSize) |
+ if (audio_buffer->mAudioDataByteSize) { |
+ // The AudioQueue API may use a large internal buffer and repeatedly call us |
+ // back to back once that internal buffer is filled. When this happens the |
+ // renderer client does not have enough time to read data back from the |
+ // shared memory before the next write comes along. If HandleInputBuffer() |
+ // is called too frequently, Sleep() to simulate realtime input and ensure |
+ // the shared memory doesn't get trampled. |
+ base::TimeDelta elapsed = base::Time::Now() - last_fill_; |
+ base::TimeDelta buffer_length = base::TimeDelta::FromMilliseconds( |
+ audio_buffer->mAudioDataByteSize * base::Time::kMillisecondsPerSecond / |
+ static_cast<float>(format_.mBytesPerFrame * format_.mSampleRate)); |
+ if (elapsed < buffer_length) |
+ base::PlatformThread::Sleep(buffer_length - elapsed); |
Chris Rogers
2012/12/06 23:19:55
As we discussed in offline, this is really a stop-
DaleCurtis
2012/12/06 23:41:07
Added a comment. As discussed offline, the calling
|
+ |
callback_->OnData(this, |
reinterpret_cast<const uint8*>(audio_buffer->mAudioData), |
audio_buffer->mAudioDataByteSize, |
audio_buffer->mAudioDataByteSize, |
0.0); |
+ |
+ last_fill_ = base::Time::Now(); |
+ } |
// Recycle the buffer. |
OSStatus err = QueueNextBuffer(audio_buffer); |
if (err != noErr) { |