| 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;
|
| }
|
|
|