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_sync_reader.h" | 5 #include "content/browser/renderer_host/media/audio_sync_reader.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/process_util.h" | 9 #include "base/process_util.h" |
10 #include "base/shared_memory.h" | 10 #include "base/shared_memory.h" |
11 #include "base/threading/platform_thread.h" | 11 #include "base/threading/platform_thread.h" |
12 #include "media/audio/audio_buffers_state.h" | 12 #include "media/audio/audio_buffers_state.h" |
13 #include "media/audio/audio_parameters.h" | |
13 #include "media/audio/shared_memory_util.h" | 14 #include "media/audio/shared_memory_util.h" |
14 | 15 |
15 #if defined(OS_WIN) | 16 #if defined(OS_WIN) |
16 const int kMinIntervalBetweenReadCallsInMs = 10; | 17 const int kMinIntervalBetweenReadCallsInMs = 10; |
17 #endif | 18 #endif |
18 | 19 |
19 AudioSyncReader::AudioSyncReader(base::SharedMemory* shared_memory) | 20 AudioSyncReader::AudioSyncReader(base::SharedMemory* shared_memory, |
21 const media::AudioParameters& params) | |
20 : shared_memory_(shared_memory) { | 22 : shared_memory_(shared_memory) { |
23 packet_size_ = media::PacketSizeInBytes(shared_memory_->created_size()); | |
24 DCHECK_EQ(packet_size_, media::AudioBus::CalculateMemorySize(params)); | |
25 audio_bus_ = media::AudioBus::WrapMemory(params, shared_memory->memory()); | |
21 } | 26 } |
22 | 27 |
23 AudioSyncReader::~AudioSyncReader() { | 28 AudioSyncReader::~AudioSyncReader() { |
24 } | 29 } |
25 | 30 |
26 bool AudioSyncReader::DataReady() { | 31 bool AudioSyncReader::DataReady() { |
27 return !media::IsUnknownDataSize( | 32 return !media::IsUnknownDataSize(shared_memory_, packet_size_); |
28 shared_memory_, | |
29 media::PacketSizeInBytes(shared_memory_->created_size())); | |
30 } | 33 } |
31 | 34 |
32 // media::AudioOutputController::SyncReader implementations. | 35 // media::AudioOutputController::SyncReader implementations. |
33 void AudioSyncReader::UpdatePendingBytes(uint32 bytes) { | 36 void AudioSyncReader::UpdatePendingBytes(uint32 bytes) { |
34 if (bytes != static_cast<uint32>(media::kPauseMark)) { | 37 if (bytes != static_cast<uint32>(media::kPauseMark)) { |
35 // Store unknown length of data into buffer, so we later | 38 // Store unknown length of data into buffer, so we later |
36 // can find out if data became available. | 39 // can find out if data became available. |
37 media::SetUnknownDataSize( | 40 media::SetUnknownDataSize(shared_memory_, packet_size_); |
38 shared_memory_, | |
39 media::PacketSizeInBytes(shared_memory_->created_size())); | |
40 } | 41 } |
41 | 42 |
42 if (socket_.get()) { | 43 if (socket_.get()) { |
43 socket_->Send(&bytes, sizeof(bytes)); | 44 socket_->Send(&bytes, sizeof(bytes)); |
44 } | 45 } |
45 } | 46 } |
46 | 47 |
47 uint32 AudioSyncReader::Read(void* data, uint32 size) { | 48 int AudioSyncReader::Read(media::AudioBus* audio_bus) { |
48 uint32 max_size = media::PacketSizeInBytes( | |
49 shared_memory_->created_size()); | |
50 | |
51 #if defined(OS_WIN) | 49 #if defined(OS_WIN) |
52 // HACK: yield if reader is called too often. | 50 // HACK: yield if reader is called too often. |
53 // Problem is lack of synchronization between host and renderer. We cannot be | 51 // Problem is lack of synchronization between host and renderer. We cannot be |
54 // sure if renderer already filled the buffer, and due to all the plugins we | 52 // sure if renderer already filled the buffer, and due to all the plugins we |
55 // cannot change the API, so we yield if previous call was too recent. | 53 // cannot change the API, so we yield if previous call was too recent. |
56 // Optimization: if renderer is "new" one that writes length of data we can | 54 // Optimization: if renderer is "new" one that writes length of data we can |
57 // stop yielding the moment length is written -- not ideal solution, | 55 // stop yielding the moment length is written -- not ideal solution, |
58 // but better than nothing. | 56 // but better than nothing. |
59 while (!DataReady() && | 57 while (!DataReady() && |
60 ((base::Time::Now() - previous_call_time_).InMilliseconds() < | 58 ((base::Time::Now() - previous_call_time_).InMilliseconds() < |
61 kMinIntervalBetweenReadCallsInMs)) { | 59 kMinIntervalBetweenReadCallsInMs)) { |
62 base::PlatformThread::YieldCurrentThread(); | 60 base::PlatformThread::YieldCurrentThread(); |
63 } | 61 } |
64 previous_call_time_ = base::Time::Now(); | 62 previous_call_time_ = base::Time::Now(); |
65 #endif | 63 #endif |
66 | 64 |
67 uint32 read_size = std::min(media::GetActualDataSizeInBytes(shared_memory_, | 65 // Retrieve the actual number of bytes available from the shared memory. |
68 max_size), | 66 int size = media::GetActualDataSizeInBytes(shared_memory_, packet_size_); |
69 size); | 67 DCHECK_EQ(static_cast<size_t>(size) % sizeof(*audio_bus_->channel(0)), 0U); |
Chris Rogers
2012/08/28 22:32:05
It would be nice to have a little more whitespace
DaleCurtis
2012/08/29 04:34:43
Done.
| |
68 // Compute the actual number of frames read. | |
69 int frames = | |
70 size / (sizeof(*audio_bus_->channel(0)) * audio_bus_->channels()); | |
71 DCHECK_LE(frames, audio_bus_->frames()); | |
70 | 72 |
71 // Get the data from the buffer. | 73 // Copy data from the shared memory into the caller's AudioBus. |
72 memcpy(data, shared_memory_->memory(), read_size); | 74 // TODO(dalecurtis): See if it's sane to avoid the copy by modifying the |
75 // caller's AudioBus to point to the shared memory. | |
Chris Rogers
2012/08/28 22:32:05
Up to you, but I would remove this TODO since the
DaleCurtis
2012/08/29 04:34:43
Done.
| |
76 audio_bus_->CopyTo(audio_bus); | |
73 | 77 |
74 // If amount read was less than requested, then zero out the remainder. | 78 // Zero out any unfilled frames. |
75 if (read_size < size) | 79 audio_bus_->ZeroFramesPartial(frames, audio_bus_->frames() - frames); |
76 memset(static_cast<char*>(data) + read_size, 0, size - read_size); | |
77 | 80 |
78 // Zero out the entire buffer. | 81 // Zero out the entire buffer. |
79 memset(shared_memory_->memory(), 0, max_size); | 82 memset(shared_memory_->memory(), 0, packet_size_); |
80 | 83 |
81 // Store unknown length of data into buffer, in case renderer does not store | 84 // Store unknown length of data into buffer, in case renderer does not store |
82 // the length itself. It also helps in decision if we need to yield. | 85 // the length itself. It also helps in decision if we need to yield. |
83 media::SetUnknownDataSize(shared_memory_, max_size); | 86 media::SetUnknownDataSize(shared_memory_, packet_size_); |
84 | 87 |
85 return read_size; | 88 // Return the actual number of frames read. |
89 return frames; | |
86 } | 90 } |
87 | 91 |
88 void AudioSyncReader::Close() { | 92 void AudioSyncReader::Close() { |
89 if (socket_.get()) { | 93 if (socket_.get()) { |
90 socket_->Close(); | 94 socket_->Close(); |
91 } | 95 } |
92 } | 96 } |
93 | 97 |
94 bool AudioSyncReader::Init() { | 98 bool AudioSyncReader::Init() { |
95 socket_.reset(new base::CancelableSyncSocket()); | 99 socket_.reset(new base::CancelableSyncSocket()); |
(...skipping 17 matching lines...) Expand all Loading... | |
113 bool AudioSyncReader::PrepareForeignSocketHandle( | 117 bool AudioSyncReader::PrepareForeignSocketHandle( |
114 base::ProcessHandle process_handle, | 118 base::ProcessHandle process_handle, |
115 base::FileDescriptor* foreign_handle) { | 119 base::FileDescriptor* foreign_handle) { |
116 foreign_handle->fd = foreign_socket_->handle(); | 120 foreign_handle->fd = foreign_socket_->handle(); |
117 foreign_handle->auto_close = false; | 121 foreign_handle->auto_close = false; |
118 if (foreign_handle->fd != -1) | 122 if (foreign_handle->fd != -1) |
119 return true; | 123 return true; |
120 return false; | 124 return false; |
121 } | 125 } |
122 #endif | 126 #endif |
OLD | NEW |