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
3 // found in the LICENSE file.
5 #include "content/browser/renderer_host/media/audio_input_sync_writer.h"
9 #include "base/memory/shared_memory.h"
10 #include "content/browser/renderer_host/media/media_stream_manager.h"
12 static const uint32 kLogDelayThreadholdMs
= 500;
16 AudioInputSyncWriter::AudioInputSyncWriter(
17 base::SharedMemory
* shared_memory
,
18 int shared_memory_segment_count
)
19 : shared_memory_(shared_memory
),
20 shared_memory_segment_count_(shared_memory_segment_count
),
21 current_segment_id_(0),
22 creation_time_(base::Time::Now()) {
23 DCHECK_GT(shared_memory_segment_count
, 0);
24 DCHECK_EQ(shared_memory
->requested_size() % shared_memory_segment_count
, 0u);
25 shared_memory_segment_size_
=
26 shared_memory
->requested_size() / shared_memory_segment_count
;
29 AudioInputSyncWriter::~AudioInputSyncWriter() {}
31 // TODO(henrika): Combine into one method (including Write).
32 void AudioInputSyncWriter::UpdateRecordedBytes(uint32 bytes
) {
33 socket_
->Send(&bytes
, sizeof(bytes
));
36 uint32
AudioInputSyncWriter::Write(const void* data
,
40 std::ostringstream oss
;
41 if (last_write_time_
.is_null()) {
42 // This is the first time Write is called.
43 base::TimeDelta interval
= base::Time::Now() - creation_time_
;
44 oss
<< "Audio input data received for the first time: delay = "
45 << interval
.InMilliseconds() << "ms.";
47 base::TimeDelta interval
= base::Time::Now() - last_write_time_
;
48 if (interval
.InMilliseconds() > kLogDelayThreadholdMs
) {
49 oss
<< "Audio input data delay unexpectedly long: delay = "
50 << interval
.InMilliseconds() << "ms.";
53 if (!oss
.str().empty())
54 MediaStreamManager::SendMessageToNativeLog(oss
.str());
56 last_write_time_
= base::Time::Now();
58 uint8
* ptr
= static_cast<uint8
*>(shared_memory_
->memory());
59 ptr
+= current_segment_id_
* shared_memory_segment_size_
;
60 media::AudioInputBuffer
* buffer
=
61 reinterpret_cast<media::AudioInputBuffer
*>(ptr
);
62 buffer
->params
.volume
= volume
;
63 buffer
->params
.size
= size
;
64 buffer
->params
.key_pressed
= key_pressed
;
65 memcpy(buffer
->audio
, data
, size
);
67 if (++current_segment_id_
>= shared_memory_segment_count_
)
68 current_segment_id_
= 0;
73 void AudioInputSyncWriter::Close() {
77 bool AudioInputSyncWriter::Init() {
78 socket_
.reset(new base::CancelableSyncSocket());
79 foreign_socket_
.reset(new base::CancelableSyncSocket());
80 return base::CancelableSyncSocket::CreatePair(socket_
.get(),
81 foreign_socket_
.get());
86 bool AudioInputSyncWriter::PrepareForeignSocketHandle(
87 base::ProcessHandle process_handle
,
88 base::SyncSocket::Handle
* foreign_handle
) {
89 ::DuplicateHandle(GetCurrentProcess(), foreign_socket_
->handle(),
90 process_handle
, foreign_handle
,
91 0, FALSE
, DUPLICATE_SAME_ACCESS
);
92 return (*foreign_handle
!= 0);
97 bool AudioInputSyncWriter::PrepareForeignSocketHandle(
98 base::ProcessHandle process_handle
,
99 base::FileDescriptor
* foreign_handle
) {
100 foreign_handle
->fd
= foreign_socket_
->handle();
101 foreign_handle
->auto_close
= false;
102 return (foreign_handle
->fd
!= -1);
107 } // namespace content