Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 } | |
|
Alexei Svitkine (slow)
2014/08/29 22:22:18
Nit: Add "// namespace" and a blank line before th
no longer working on chromium
2014/09/02 10:00:21
Done.
| |
| 39 | |
| 16 AudioInputSyncWriter::AudioInputSyncWriter(base::SharedMemory* shared_memory, | 40 AudioInputSyncWriter::AudioInputSyncWriter(base::SharedMemory* shared_memory, |
| 17 int shared_memory_segment_count, | 41 int shared_memory_segment_count, |
| 18 const media::AudioParameters& params) | 42 const media::AudioParameters& params) |
| 19 : shared_memory_(shared_memory), | 43 : shared_memory_(shared_memory), |
| 20 shared_memory_segment_count_(shared_memory_segment_count), | 44 shared_memory_segment_count_(shared_memory_segment_count), |
| 21 current_segment_id_(0), | 45 current_segment_id_(0), |
| 22 creation_time_(base::Time::Now()), | 46 creation_time_(base::Time::Now()), |
| 23 audio_bus_memory_size_(AudioBus::CalculateMemorySize(params)) { | 47 audio_bus_memory_size_(AudioBus::CalculateMemorySize(params)) { |
| 24 DCHECK_GT(shared_memory_segment_count, 0); | 48 DCHECK_GT(shared_memory_segment_count, 0); |
| 25 DCHECK_EQ(shared_memory->requested_size() % shared_memory_segment_count, 0u); | 49 DCHECK_EQ(shared_memory->requested_size() % shared_memory_segment_count, 0u); |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 37 reinterpret_cast<media::AudioInputBuffer*>(ptr); | 61 reinterpret_cast<media::AudioInputBuffer*>(ptr); |
| 38 scoped_ptr<media::AudioBus> audio_bus = | 62 scoped_ptr<media::AudioBus> audio_bus = |
| 39 media::AudioBus::WrapMemory(params, buffer->audio); | 63 media::AudioBus::WrapMemory(params, buffer->audio); |
| 40 audio_buses_.push_back(audio_bus.release()); | 64 audio_buses_.push_back(audio_bus.release()); |
| 41 ptr += shared_memory_segment_size_; | 65 ptr += shared_memory_segment_size_; |
| 42 } | 66 } |
| 43 } | 67 } |
| 44 | 68 |
| 45 AudioInputSyncWriter::~AudioInputSyncWriter() {} | 69 AudioInputSyncWriter::~AudioInputSyncWriter() {} |
| 46 | 70 |
| 47 // TODO(henrika): Combine into one method (including Write). | 71 void AudioInputSyncWriter::Write(const media::AudioBus* data, double volume, |
| 48 void AudioInputSyncWriter::UpdateRecordedBytes(uint32 bytes) { | 72 bool key_pressed, |
| 49 socket_->Send(&bytes, sizeof(bytes)); | 73 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) | 74 #if !defined(OS_ANDROID) |
| 56 static const base::TimeDelta kLogDelayThreadhold = | 75 static const base::TimeDelta kLogDelayThreadhold = |
| 57 base::TimeDelta::FromMilliseconds(500); | 76 base::TimeDelta::FromMilliseconds(500); |
| 58 | 77 |
| 59 std::ostringstream oss; | 78 std::ostringstream oss; |
| 60 if (last_write_time_.is_null()) { | 79 if (last_write_time_.is_null()) { |
| 61 // This is the first time Write is called. | 80 // This is the first time Write is called. |
| 62 base::TimeDelta interval = base::Time::Now() - creation_time_; | 81 base::TimeDelta interval = base::Time::Now() - creation_time_; |
| 63 oss << "Audio input data received for the first time: delay = " | 82 oss << "Audio input data received for the first time: delay = " |
| 64 << interval.InMilliseconds() << "ms."; | 83 << interval.InMilliseconds() << "ms."; |
| 65 | 84 |
| 66 } else { | 85 } else { |
| 67 base::TimeDelta interval = base::Time::Now() - last_write_time_; | 86 base::TimeDelta interval = base::Time::Now() - last_write_time_; |
| 68 if (interval > kLogDelayThreadhold) { | 87 if (interval > kLogDelayThreadhold) { |
| 69 oss << "Audio input data delay unexpectedly long: delay = " | 88 oss << "Audio input data delay unexpectedly long: delay = " |
| 70 << interval.InMilliseconds() << "ms."; | 89 << interval.InMilliseconds() << "ms."; |
| 71 } | 90 } |
| 72 } | 91 } |
| 73 if (!oss.str().empty()) | 92 if (!oss.str().empty()) MediaStreamManager::SendMessageToNativeLog(oss.str()); |
| 74 MediaStreamManager::SendMessageToNativeLog(oss.str()); | |
| 75 | 93 |
| 76 last_write_time_ = base::Time::Now(); | 94 last_write_time_ = base::Time::Now(); |
| 77 #endif | 95 #endif |
| 78 | 96 |
| 79 // Write audio parameters to shared memory. | 97 // Write audio parameters to shared memory. |
| 80 uint8* ptr = static_cast<uint8*>(shared_memory_->memory()); | 98 uint8* ptr = static_cast<uint8*>(shared_memory_->memory()); |
| 81 ptr += current_segment_id_ * shared_memory_segment_size_; | 99 ptr += current_segment_id_ * shared_memory_segment_size_; |
| 82 media::AudioInputBuffer* buffer = | 100 media::AudioInputBuffer* buffer = |
| 83 reinterpret_cast<media::AudioInputBuffer*>(ptr); | 101 reinterpret_cast<media::AudioInputBuffer*>(ptr); |
| 102 | |
| 103 // The renderer should set the size to 0 after consuming the buffer. In case | |
| 104 // it is not 0, it means buffer has not been consumed yet. | |
| 105 if (buffer->params.size) | |
| 106 LogAllBuffersAreFull(shared_memory_segment_size_); | |
| 107 | |
| 84 buffer->params.volume = volume; | 108 buffer->params.volume = volume; |
| 85 buffer->params.size = audio_bus_memory_size_; | 109 buffer->params.size = audio_bus_memory_size_; |
| 86 buffer->params.key_pressed = key_pressed; | 110 buffer->params.key_pressed = key_pressed; |
| 87 | 111 |
| 88 // Copy data from the native audio layer into shared memory using pre- | 112 // Copy data from the native audio layer into shared memory using pre- |
| 89 // allocated audio buses. | 113 // allocated audio buses. |
| 90 media::AudioBus* audio_bus = audio_buses_[current_segment_id_]; | 114 media::AudioBus* audio_bus = audio_buses_[current_segment_id_]; |
| 91 data->CopyTo(audio_bus); | 115 data->CopyTo(audio_bus); |
| 92 | 116 |
| 93 if (++current_segment_id_ >= shared_memory_segment_count_) | 117 if (++current_segment_id_ >= shared_memory_segment_count_) |
| 94 current_segment_id_ = 0; | 118 current_segment_id_ = 0; |
| 119 | |
| 120 // Notify the synchronous peer. | |
| 121 socket_->Send(&hardware_delay_bytes, sizeof(hardware_delay_bytes)); | |
| 95 } | 122 } |
| 96 | 123 |
| 97 void AudioInputSyncWriter::Close() { | 124 void AudioInputSyncWriter::Close() { socket_->Close(); } |
| 98 socket_->Close(); | |
| 99 } | |
| 100 | 125 |
| 101 bool AudioInputSyncWriter::Init() { | 126 bool AudioInputSyncWriter::Init() { |
| 102 socket_.reset(new base::CancelableSyncSocket()); | 127 socket_.reset(new base::CancelableSyncSocket()); |
| 103 foreign_socket_.reset(new base::CancelableSyncSocket()); | 128 foreign_socket_.reset(new base::CancelableSyncSocket()); |
| 104 return base::CancelableSyncSocket::CreatePair(socket_.get(), | 129 return base::CancelableSyncSocket::CreatePair(socket_.get(), |
| 105 foreign_socket_.get()); | 130 foreign_socket_.get()); |
| 106 } | 131 } |
| 107 | 132 |
| 108 #if defined(OS_WIN) | 133 #if defined(OS_WIN) |
| 109 | 134 |
| 110 bool AudioInputSyncWriter::PrepareForeignSocketHandle( | 135 bool AudioInputSyncWriter::PrepareForeignSocketHandle( |
| 111 base::ProcessHandle process_handle, | 136 base::ProcessHandle process_handle, |
| 112 base::SyncSocket::Handle* foreign_handle) { | 137 base::SyncSocket::Handle* foreign_handle) { |
| 113 ::DuplicateHandle(GetCurrentProcess(), foreign_socket_->handle(), | 138 ::DuplicateHandle(GetCurrentProcess(), foreign_socket_->handle(), |
| 114 process_handle, foreign_handle, | 139 process_handle, foreign_handle, 0, FALSE, |
| 115 0, FALSE, DUPLICATE_SAME_ACCESS); | 140 DUPLICATE_SAME_ACCESS); |
| 116 return (*foreign_handle != 0); | 141 return (*foreign_handle != 0); |
| 117 } | 142 } |
| 118 | 143 |
| 119 #else | 144 #else |
| 120 | 145 |
| 121 bool AudioInputSyncWriter::PrepareForeignSocketHandle( | 146 bool AudioInputSyncWriter::PrepareForeignSocketHandle( |
| 122 base::ProcessHandle process_handle, | 147 base::ProcessHandle process_handle, |
| 123 base::FileDescriptor* foreign_handle) { | 148 base::FileDescriptor* foreign_handle) { |
| 124 foreign_handle->fd = foreign_socket_->handle(); | 149 foreign_handle->fd = foreign_socket_->handle(); |
| 125 foreign_handle->auto_close = false; | 150 foreign_handle->auto_close = false; |
| 126 return (foreign_handle->fd != -1); | 151 return (foreign_handle->fd != -1); |
| 127 } | 152 } |
| 128 | 153 |
| 129 #endif | 154 #endif |
| 130 | 155 |
| 131 } // namespace content | 156 } // namespace content |
| OLD | NEW |