15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/renderer_host/media/audio_input_sync_writer.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 97dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/memory/shared_memory.h" 10e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "content/browser/renderer_host/media/media_stream_manager.h" 11e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 126d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)using media::AudioBus; 136d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content { 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 166d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)AudioInputSyncWriter::AudioInputSyncWriter(base::SharedMemory* shared_memory, 176d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) int shared_memory_segment_count, 186d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) const media::AudioParameters& params) 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : shared_memory_(shared_memory), 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) shared_memory_segment_count_(shared_memory_segment_count), 21e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch current_segment_id_(0), 226d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) creation_time_(base::Time::Now()), 236d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) audio_bus_memory_size_(AudioBus::CalculateMemorySize(params)) { 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_GT(shared_memory_segment_count, 0); 25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK_EQ(shared_memory->requested_size() % shared_memory_segment_count, 0u); 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) shared_memory_segment_size_ = 27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) shared_memory->requested_size() / shared_memory_segment_count; 286d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) DVLOG(1) << "SharedMemory::requested_size: " 296d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) << shared_memory->requested_size(); 306d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) DVLOG(1) << "shared_memory_segment_count: " << shared_memory_segment_count; 31116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DVLOG(1) << "audio_bus_memory_size: " << audio_bus_memory_size_; 326d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) 336d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // Create vector of audio buses by wrapping existing blocks of memory. 346d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) uint8* ptr = static_cast<uint8*>(shared_memory_->memory()); 356d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) for (int i = 0; i < shared_memory_segment_count; ++i) { 366d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) media::AudioInputBuffer* buffer = 376d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) reinterpret_cast<media::AudioInputBuffer*>(ptr); 386d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) scoped_ptr<media::AudioBus> audio_bus = 396d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) media::AudioBus::WrapMemory(params, buffer->audio); 406d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) audio_buses_.push_back(audio_bus.release()); 416d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) ptr += shared_memory_segment_size_; 426d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) } 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AudioInputSyncWriter::~AudioInputSyncWriter() {} 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(henrika): Combine into one method (including Write). 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioInputSyncWriter::UpdateRecordedBytes(uint32 bytes) { 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) socket_->Send(&bytes, sizeof(bytes)); 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 526d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)void AudioInputSyncWriter::Write(const media::AudioBus* data, 536d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) double volume, 546d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) bool key_pressed) { 55cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#if !defined(OS_ANDROID) 56cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) static const base::TimeDelta kLogDelayThreadhold = 57cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::TimeDelta::FromMilliseconds(500); 58cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 59e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch std::ostringstream oss; 60e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch if (last_write_time_.is_null()) { 61e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // This is the first time Write is called. 62e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch base::TimeDelta interval = base::Time::Now() - creation_time_; 631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci oss << "AISW::Write: audio input data received for the first time: delay " 641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci "= " << interval.InMilliseconds() << "ms"; 65cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 66e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch } else { 67e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch base::TimeDelta interval = base::Time::Now() - last_write_time_; 68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (interval > kLogDelayThreadhold) { 691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci oss << "AISW::Write: audio input data delay unexpectedly long: delay = " 701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci << interval.InMilliseconds() << "ms"; 71e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch } 72e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch } 731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!oss.str().empty()) { 74e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch MediaStreamManager::SendMessageToNativeLog(oss.str()); 751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DVLOG(1) << oss.str(); 761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 77e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 78e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch last_write_time_ = base::Time::Now(); 79cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#endif 80e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 816d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // Write audio parameters to shared memory. 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) uint8* ptr = static_cast<uint8*>(shared_memory_->memory()); 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ptr += current_segment_id_ * shared_memory_segment_size_; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) media::AudioInputBuffer* buffer = 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) reinterpret_cast<media::AudioInputBuffer*>(ptr); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer->params.volume = volume; 876d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) buffer->params.size = audio_bus_memory_size_; 883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) buffer->params.key_pressed = key_pressed; 896d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) 906d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // Copy data from the native audio layer into shared memory using pre- 916d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // allocated audio buses. 926d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) media::AudioBus* audio_bus = audio_buses_[current_segment_id_]; 936d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) data->CopyTo(audio_bus); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (++current_segment_id_ >= shared_memory_segment_count_) 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) current_segment_id_ = 0; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioInputSyncWriter::Close() { 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) socket_->Close(); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AudioInputSyncWriter::Init() { 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) socket_.reset(new base::CancelableSyncSocket()); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) foreign_socket_.reset(new base::CancelableSyncSocket()); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return base::CancelableSyncSocket::CreatePair(socket_.get(), 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) foreign_socket_.get()); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool AudioInputSyncWriter::PrepareForeignSocket( 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::ProcessHandle process_handle, 1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::SyncSocket::TransitDescriptor* descriptor) { 1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return foreign_socket_->PrepareTransitDescriptor(process_handle, descriptor); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace content 118