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

Side by Side Diff: content/browser/renderer_host/media/audio_input_sync_writer.cc

Issue 510913005: Add native log and uma stat when all input shared memory buffers are full (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: added unittest and addressed comments. Created 6 years, 3 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/renderer_host/media/audio_input_sync_writer.h" 5 #include "content/browser/renderer_host/media/audio_input_sync_writer.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/memory/shared_memory.h" 9 #include "base/memory/shared_memory.h"
10 #include "base/metrics/histogram.h"
11 #include "base/strings/stringprintf.h"
10 #include "content/browser/renderer_host/media/media_stream_manager.h" 12 #include "content/browser/renderer_host/media/media_stream_manager.h"
11 13
12 using media::AudioBus; 14 using media::AudioBus;
13 15
14 namespace content { 16 namespace content {
15 17
18 namespace {
19
20 enum AudioInputBufferType {
21 AUDIO_INPUT_SINGLE_BUFFER = 0,
22 AUDIO_INPUT_CIRCULAR_BUFFER = 1,
23 NUM_AUDIO_INPUT_BUFFER
24 };
25
26 // Log to native log and uma stats that all the buffers are full.
27 void LogAllBuffersAreFull(int number_of_buffers) {
28 AudioInputBufferType type = AUDIO_INPUT_SINGLE_BUFFER;
29 if (number_of_buffers != 1) {
30 type = AUDIO_INPUT_CIRCULAR_BUFFER;
31 MediaStreamManager::SendMessageToNativeLog(base::StringPrintf(
32 "AIS, circular buffers are full. Number of buffers is %d",
33 number_of_buffers));
34 }
35 UMA_HISTOGRAM_ENUMERATION("Media.AudioInputSyncWriterBuffersAreFull", type,
36 NUM_AUDIO_INPUT_BUFFER);
37 }
38
39 } // namespace
40
16 AudioInputSyncWriter::AudioInputSyncWriter(base::SharedMemory* shared_memory, 41 AudioInputSyncWriter::AudioInputSyncWriter(base::SharedMemory* shared_memory,
17 int shared_memory_segment_count, 42 int shared_memory_segment_count,
18 const media::AudioParameters& params) 43 const media::AudioParameters& params)
19 : shared_memory_(shared_memory), 44 : shared_memory_(shared_memory),
20 shared_memory_segment_count_(shared_memory_segment_count), 45 shared_memory_segment_count_(shared_memory_segment_count),
21 current_segment_id_(0), 46 current_segment_id_(0),
22 creation_time_(base::Time::Now()), 47 creation_time_(base::Time::Now()),
23 audio_bus_memory_size_(AudioBus::CalculateMemorySize(params)) { 48 audio_bus_memory_size_(AudioBus::CalculateMemorySize(params)) {
24 DCHECK_GT(shared_memory_segment_count, 0); 49 DCHECK_GT(shared_memory_segment_count, 0);
25 DCHECK_EQ(shared_memory->requested_size() % shared_memory_segment_count, 0u); 50 DCHECK_EQ(shared_memory->requested_size() % shared_memory_segment_count, 0u);
(...skipping 11 matching lines...) Expand all
37 reinterpret_cast<media::AudioInputBuffer*>(ptr); 62 reinterpret_cast<media::AudioInputBuffer*>(ptr);
38 scoped_ptr<media::AudioBus> audio_bus = 63 scoped_ptr<media::AudioBus> audio_bus =
39 media::AudioBus::WrapMemory(params, buffer->audio); 64 media::AudioBus::WrapMemory(params, buffer->audio);
40 audio_buses_.push_back(audio_bus.release()); 65 audio_buses_.push_back(audio_bus.release());
41 ptr += shared_memory_segment_size_; 66 ptr += shared_memory_segment_size_;
42 } 67 }
43 } 68 }
44 69
45 AudioInputSyncWriter::~AudioInputSyncWriter() {} 70 AudioInputSyncWriter::~AudioInputSyncWriter() {}
46 71
47 // TODO(henrika): Combine into one method (including Write). 72 void AudioInputSyncWriter::Write(const media::AudioBus* data, double volume,
48 void AudioInputSyncWriter::UpdateRecordedBytes(uint32 bytes) { 73 bool key_pressed,
49 socket_->Send(&bytes, sizeof(bytes)); 74 uint32 hardware_delay_bytes) {
50 }
51
52 void AudioInputSyncWriter::Write(const media::AudioBus* data,
53 double volume,
54 bool key_pressed) {
55 #if !defined(OS_ANDROID) 75 #if !defined(OS_ANDROID)
56 static const base::TimeDelta kLogDelayThreadhold = 76 static const base::TimeDelta kLogDelayThreadhold =
57 base::TimeDelta::FromMilliseconds(500); 77 base::TimeDelta::FromMilliseconds(500);
58 78
59 std::ostringstream oss; 79 std::ostringstream oss;
60 if (last_write_time_.is_null()) { 80 if (last_write_time_.is_null()) {
61 // This is the first time Write is called. 81 // This is the first time Write is called.
62 base::TimeDelta interval = base::Time::Now() - creation_time_; 82 base::TimeDelta interval = base::Time::Now() - creation_time_;
63 oss << "AISW::Write => audio input data received for the first time: delay " 83 oss << "AISW::Write => audio input data received for the first time: delay "
64 "= " << interval.InMilliseconds() << "ms"; 84 "= " << interval.InMilliseconds() << "ms";
65 85
66 } else { 86 } else {
67 base::TimeDelta interval = base::Time::Now() - last_write_time_; 87 base::TimeDelta interval = base::Time::Now() - last_write_time_;
68 if (interval > kLogDelayThreadhold) { 88 if (interval > kLogDelayThreadhold) {
69 oss << "AISW::Write => audio input data delay unexpectedly long: delay = " 89 oss << "AISW::Write => audio input data delay unexpectedly long: delay = "
70 << interval.InMilliseconds() << "ms"; 90 << interval.InMilliseconds() << "ms";
71 } 91 }
72 } 92 }
93
73 if (!oss.str().empty()) { 94 if (!oss.str().empty()) {
74 MediaStreamManager::SendMessageToNativeLog(oss.str()); 95 MediaStreamManager::SendMessageToNativeLog(oss.str());
75 DVLOG(1) << oss.str(); 96 DVLOG(1) << oss.str();
76 } 97 }
77 98
78 last_write_time_ = base::Time::Now(); 99 last_write_time_ = base::Time::Now();
79 #endif 100 #endif
80 101
81 // Write audio parameters to shared memory. 102 // Write audio parameters to shared memory.
82 uint8* ptr = static_cast<uint8*>(shared_memory_->memory()); 103 uint8* ptr = static_cast<uint8*>(shared_memory_->memory());
83 ptr += current_segment_id_ * shared_memory_segment_size_; 104 ptr += current_segment_id_ * shared_memory_segment_size_;
84 media::AudioInputBuffer* buffer = 105 media::AudioInputBuffer* buffer =
85 reinterpret_cast<media::AudioInputBuffer*>(ptr); 106 reinterpret_cast<media::AudioInputBuffer*>(ptr);
107
108 // The renderer should set the size to 0 after consuming the buffer. In case
109 // it is not 0, it means buffer has not been consumed yet.
110 if (buffer->params.size)
111 LogAllBuffersAreFull(shared_memory_segment_size_);
112
86 buffer->params.volume = volume; 113 buffer->params.volume = volume;
87 buffer->params.size = audio_bus_memory_size_; 114 buffer->params.size = audio_bus_memory_size_;
88 buffer->params.key_pressed = key_pressed; 115 buffer->params.key_pressed = key_pressed;
89 116
90 // Copy data from the native audio layer into shared memory using pre- 117 // Copy data from the native audio layer into shared memory using pre-
91 // allocated audio buses. 118 // allocated audio buses.
92 media::AudioBus* audio_bus = audio_buses_[current_segment_id_]; 119 media::AudioBus* audio_bus = audio_buses_[current_segment_id_];
93 data->CopyTo(audio_bus); 120 data->CopyTo(audio_bus);
94 121
95 if (++current_segment_id_ >= shared_memory_segment_count_) 122 if (++current_segment_id_ >= shared_memory_segment_count_)
96 current_segment_id_ = 0; 123 current_segment_id_ = 0;
124
125 // Notify the synchronous peer.
126 socket_->Send(&hardware_delay_bytes, sizeof(hardware_delay_bytes));
97 } 127 }
98 128
99 void AudioInputSyncWriter::Close() { 129 void AudioInputSyncWriter::Close() { socket_->Close(); }
100 socket_->Close();
101 }
102 130
103 bool AudioInputSyncWriter::Init() { 131 bool AudioInputSyncWriter::Init() {
104 socket_.reset(new base::CancelableSyncSocket()); 132 socket_.reset(new base::CancelableSyncSocket());
105 foreign_socket_.reset(new base::CancelableSyncSocket()); 133 foreign_socket_.reset(new base::CancelableSyncSocket());
106 return base::CancelableSyncSocket::CreatePair(socket_.get(), 134 return base::CancelableSyncSocket::CreatePair(socket_.get(),
107 foreign_socket_.get()); 135 foreign_socket_.get());
108 } 136 }
109 137
110 #if defined(OS_WIN) 138 #if defined(OS_WIN)
111 139
112 bool AudioInputSyncWriter::PrepareForeignSocketHandle( 140 bool AudioInputSyncWriter::PrepareForeignSocketHandle(
113 base::ProcessHandle process_handle, 141 base::ProcessHandle process_handle,
114 base::SyncSocket::Handle* foreign_handle) { 142 base::SyncSocket::Handle* foreign_handle) {
115 ::DuplicateHandle(GetCurrentProcess(), foreign_socket_->handle(), 143 ::DuplicateHandle(GetCurrentProcess(), foreign_socket_->handle(),
116 process_handle, foreign_handle, 144 process_handle, foreign_handle, 0, FALSE,
117 0, FALSE, DUPLICATE_SAME_ACCESS); 145 DUPLICATE_SAME_ACCESS);
118 return (*foreign_handle != 0); 146 return (*foreign_handle != 0);
119 } 147 }
120 148
121 #else 149 #else
122 150
123 bool AudioInputSyncWriter::PrepareForeignSocketHandle( 151 bool AudioInputSyncWriter::PrepareForeignSocketHandle(
124 base::ProcessHandle process_handle, 152 base::ProcessHandle process_handle,
125 base::FileDescriptor* foreign_handle) { 153 base::FileDescriptor* foreign_handle) {
126 foreign_handle->fd = foreign_socket_->handle(); 154 foreign_handle->fd = foreign_socket_->handle();
127 foreign_handle->auto_close = false; 155 foreign_handle->auto_close = false;
128 return (foreign_handle->fd != -1); 156 return (foreign_handle->fd != -1);
129 } 157 }
130 158
131 #endif 159 #endif
132 160
133 } // namespace content 161 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698