Index: content/browser/renderer_host/media/audio_sync_reader.cc |
=================================================================== |
--- content/browser/renderer_host/media/audio_sync_reader.cc (revision 100908) |
+++ content/browser/renderer_host/media/audio_sync_reader.cc (working copy) |
@@ -8,9 +8,12 @@ |
#include "base/process_util.h" |
#include "base/shared_memory.h" |
+#include "base/threading/platform_thread.h" |
#include "media/audio/audio_buffers_state.h" |
#include "media/audio/audio_util.h" |
+const int kMinIntervalBetweenReadCallsInMs = 10; |
+ |
AudioSyncReader::AudioSyncReader(base::SharedMemory* shared_memory) |
: shared_memory_(shared_memory) { |
} |
@@ -26,6 +29,23 @@ |
uint32 AudioSyncReader::Read(void* data, uint32 size) { |
uint32 max_size = media::PacketSizeSizeInBytes( |
shared_memory_->created_size()); |
+ |
+#if defined(OS_WIN) |
+ // HACK: yield if reader is called too often. |
+ // Problem is lack of synchronization between host and renderer. We cannot be |
+ // sure if renderer already filled the buffer, and due to all the plugins we |
+ // cannot change the API, so we yield if previous call was too recent. |
+ // Optimization: if renderer is "new" one that writes length of data we can |
+ // stop yielding the moment length is written -- not ideal solution, |
+ // but better than nothing. |
+ while (media::IsUnknownDataSize(shared_memory_, max_size) && |
+ ((base::Time::Now() - previous_call_time_).InMilliseconds() < |
+ kMinIntervalBetweenReadCallsInMs)) { |
+ base::PlatformThread::YieldCurrentThread(); |
+ } |
+ previous_call_time_ = base::Time::Now(); |
+#endif |
+ |
uint32 read_size = std::min(media::GetActualDataSizeInBytes(shared_memory_, |
max_size), |
size); |
@@ -40,8 +60,9 @@ |
// Zero out the entire buffer. |
memset(shared_memory_->memory(), 0, max_size); |
- // Store max length of data into buffer, in case client does not do that. |
- media::SetActualDataSizeInBytes(shared_memory_, max_size, max_size); |
+ // Store unknown length of data into buffer, in case renderer does not store |
+ // the length itself. It also helps in decision if we need to yield. |
+ media::SetUnknownDataSize(shared_memory_, max_size); |
return read_size; |
} |