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

Unified Diff: content/browser/renderer_host/media/audio_input_sync_writer.cc

Issue 1302423006: Ensure that data is not overwritten in the audio input shared memory ring buffer that sits on the b… (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 4 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: content/browser/renderer_host/media/audio_input_sync_writer.cc
diff --git a/content/browser/renderer_host/media/audio_input_sync_writer.cc b/content/browser/renderer_host/media/audio_input_sync_writer.cc
index 600881af9a93799011f993ebaae27a766a2414c0..76204b90babbf43de283e8abbf988dfba19eab4c 100644
--- a/content/browser/renderer_host/media/audio_input_sync_writer.cc
+++ b/content/browser/renderer_host/media/audio_input_sync_writer.cc
@@ -7,12 +7,20 @@
#include <algorithm>
#include "base/memory/shared_memory.h"
+#include "base/metrics/histogram.h"
#include "content/browser/renderer_host/media/media_stream_manager.h"
using media::AudioBus;
namespace content {
+namespace {
+ // TODO BEFORE COMMIT: Which value makes sense? I.e. how long can we accept
+ // blocking the soundcard thread and wait before dropping data.
+ const base::TimeDelta kReadCheckTimeout =
henrika (OOO until Aug 14) 2015/08/28 07:56:25 Have you experimented with high load to see the ef
Henrik Grunell 2015/08/28 12:21:57 I've stress tested on my machine, couldn't provoke
+ base::TimeDelta::FromMilliseconds(10);
+}
+
AudioInputSyncWriter::AudioInputSyncWriter(base::SharedMemory* shared_memory,
int shared_memory_segment_count,
const media::AudioParameters& params)
@@ -21,7 +29,9 @@ AudioInputSyncWriter::AudioInputSyncWriter(base::SharedMemory* shared_memory,
current_segment_id_(0),
creation_time_(base::Time::Now()),
audio_bus_memory_size_(AudioBus::CalculateMemorySize(params)),
- next_buffer_id_(0) {
+ next_buffer_id_(0),
+ expected_buffer_reads_(0),
+ read_verification_timeouts_(0) {
DCHECK_GT(shared_memory_segment_count, 0);
DCHECK_EQ(shared_memory->requested_size() % shared_memory_segment_count, 0u);
shared_memory_segment_size_ =
@@ -45,7 +55,11 @@ AudioInputSyncWriter::AudioInputSyncWriter(base::SharedMemory* shared_memory,
}
}
-AudioInputSyncWriter::~AudioInputSyncWriter() {}
+AudioInputSyncWriter::~AudioInputSyncWriter() {
+ // TODO BEFORE COMMIT: Maybe percentage makes more sense here?
DaleCurtis 2015/08/27 16:43:39 For consistency please use the same pattern as we
Henrik Grunell 2015/08/28 12:21:57 Done.
+ UMA_HISTOGRAM_COUNTS_1000("Media.AudioCapturerMissedReadDeadline",
+ read_verification_timeouts_);
+}
void AudioInputSyncWriter::Write(const media::AudioBus* data,
double volume,
@@ -77,6 +91,33 @@ void AudioInputSyncWriter::Write(const media::AudioBus* data,
last_write_time_ = base::Time::Now();
#endif
+ // Check that the renderer side has read data so that we don't overwrite.
+ // The renderer side sends a signal over the socket each time it has read
+ // data. Here, we count the number of reads we expect to have been done. When
+ // we reach |shared_memory_segment_count_|, we do
+ // (|shared_memory_segment_count_| / 2) socket receives, which normally is
+ // in queue. If we timeout, there's a problem with being able to read at the
+ // high enough pace, and we throw away the audio buffer.
+ if (expected_buffer_reads_ ==
henrika (OOO until Aug 14) 2015/08/28 07:56:25 Did you check this scheme for a segment count equa
Henrik Grunell 2015/08/28 12:21:57 Good point. I changed the for loop condition to sh
+ static_cast<int>(shared_memory_segment_count_)) {
+ size_t bytes_received = 0;
+ uint32 dummy = 0;
+ for (uint32 i = 0; i < shared_memory_segment_count_ / 2; ++i) {
+ bytes_received =
+ socket_->ReceiveWithTimeout(&dummy, sizeof(dummy), kReadCheckTimeout);
+ if (bytes_received != sizeof(dummy)) {
+ const std::string error_message =
+ "Verifying shared memory read timed out. Dropping audio data.";
+ LOG(ERROR) << error_message;
+ MediaStreamManager::SendMessageToNativeLog(error_message);
+ ++read_verification_timeouts_;
+ return;
+ }
+ --expected_buffer_reads_;
+ DCHECK_GE(expected_buffer_reads_, 0);
+ }
+ }
+
// Write audio parameters to shared memory.
uint8* ptr = static_cast<uint8*>(shared_memory_->memory());
ptr += current_segment_id_ * shared_memory_segment_size_;
@@ -97,6 +138,10 @@ void AudioInputSyncWriter::Write(const media::AudioBus* data,
if (++current_segment_id_ >= shared_memory_segment_count_)
current_segment_id_ = 0;
+
+ ++expected_buffer_reads_;
+ DCHECK_LE(expected_buffer_reads_,
+ static_cast<int>(shared_memory_segment_count_));
}
void AudioInputSyncWriter::Close() {

Powered by Google App Engine
This is Rietveld 408576698