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 audio_bus_ = media::AudioBus::WrapMemory(params, shared_memory->memory()); | |
Chris Rogers
2012/08/24 20:20:26
I think we need to have a sanity check here that t
DaleCurtis
2012/08/24 23:53:12
Done.
| |
24 packet_size_ = media::PacketSizeSizeInBytes(shared_memory_->created_size()); | |
21 } | 25 } |
22 | 26 |
23 AudioSyncReader::~AudioSyncReader() { | 27 AudioSyncReader::~AudioSyncReader() { |
24 } | 28 } |
25 | 29 |
26 bool AudioSyncReader::DataReady() { | 30 bool AudioSyncReader::DataReady() { |
27 return !media::IsUnknownDataSize( | 31 return !media::IsUnknownDataSize(shared_memory_, packet_size_); |
28 shared_memory_, | |
29 media::PacketSizeSizeInBytes(shared_memory_->created_size())); | |
30 } | 32 } |
31 | 33 |
32 // media::AudioOutputController::SyncReader implementations. | 34 // media::AudioOutputController::SyncReader implementations. |
33 void AudioSyncReader::UpdatePendingBytes(uint32 bytes) { | 35 void AudioSyncReader::UpdatePendingBytes(uint32 bytes) { |
34 if (bytes != static_cast<uint32>(media::kPauseMark)) { | 36 if (bytes != static_cast<uint32>(media::kPauseMark)) { |
35 // Store unknown length of data into buffer, so we later | 37 // Store unknown length of data into buffer, so we later |
36 // can find out if data became available. | 38 // can find out if data became available. |
37 media::SetUnknownDataSize( | 39 media::SetUnknownDataSize(shared_memory_, packet_size_); |
38 shared_memory_, | |
39 media::PacketSizeSizeInBytes(shared_memory_->created_size())); | |
40 } | 40 } |
41 | 41 |
42 if (socket_.get()) { | 42 if (socket_.get()) { |
43 socket_->Send(&bytes, sizeof(bytes)); | 43 socket_->Send(&bytes, sizeof(bytes)); |
44 } | 44 } |
45 } | 45 } |
46 | 46 |
47 uint32 AudioSyncReader::Read(void* data, uint32 size) { | 47 int AudioSyncReader::Read(media::AudioBus* audio_bus) { |
48 uint32 max_size = media::PacketSizeSizeInBytes( | |
49 shared_memory_->created_size()); | |
50 | |
51 #if defined(OS_WIN) | 48 #if defined(OS_WIN) |
52 // HACK: yield if reader is called too often. | 49 // HACK: yield if reader is called too often. |
53 // Problem is lack of synchronization between host and renderer. We cannot be | 50 // 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 | 51 // 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. | 52 // 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 | 53 // Optimization: if renderer is "new" one that writes length of data we can |
57 // stop yielding the moment length is written -- not ideal solution, | 54 // stop yielding the moment length is written -- not ideal solution, |
58 // but better than nothing. | 55 // but better than nothing. |
59 while (!DataReady() && | 56 while (!DataReady() && |
60 ((base::Time::Now() - previous_call_time_).InMilliseconds() < | 57 ((base::Time::Now() - previous_call_time_).InMilliseconds() < |
61 kMinIntervalBetweenReadCallsInMs)) { | 58 kMinIntervalBetweenReadCallsInMs)) { |
62 base::PlatformThread::YieldCurrentThread(); | 59 base::PlatformThread::YieldCurrentThread(); |
63 } | 60 } |
64 previous_call_time_ = base::Time::Now(); | 61 previous_call_time_ = base::Time::Now(); |
65 #endif | 62 #endif |
66 | 63 |
67 uint32 read_size = std::min(media::GetActualDataSizeInBytes(shared_memory_, | 64 // Retrieve the actual number of bytes available from the shared memory. |
68 max_size), | 65 int size = media::GetActualDataSizeInBytes(shared_memory_, packet_size_); |
69 size); | 66 DCHECK_EQ(static_cast<size_t>(size) % sizeof(*audio_bus_->channel(0)), 0U); |
70 | 67 |
71 // Get the data from the buffer. | 68 // Copy data from the shared memory into the caller's AudioBus. |
72 memcpy(data, shared_memory_->memory(), read_size); | 69 // TODO(dalecurtis): See if it's sane to avoid the copy by modifying the |
70 // caller's AudioBus to point to the shared memory. | |
71 audio_bus_->CopyTo(audio_bus); | |
73 | 72 |
74 // If amount read was less than requested, then zero out the remainder. | 73 // TODO(dalecurtis): Do we need to zero out remaining frames? |
Chris Rogers
2012/08/24 20:20:26
Please do, I remember specifically that we had a b
DaleCurtis
2012/08/24 23:53:12
Done.
| |
75 if (read_size < size) | |
76 memset(static_cast<char*>(data) + read_size, 0, size - read_size); | |
77 | 74 |
78 // Zero out the entire buffer. | 75 // Zero out the entire buffer. |
79 memset(shared_memory_->memory(), 0, max_size); | 76 // TODO(dalecurtis): This is probably unnecessary. |
Chris Rogers
2012/08/24 20:20:26
It seems like it should be unnecessary, and in nor
DaleCurtis
2012/08/24 23:53:12
Thanks for the information, left alone.
| |
77 memset(shared_memory_->memory(), 0, packet_size_); | |
80 | 78 |
81 // Store unknown length of data into buffer, in case renderer does not store | 79 // 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. | 80 // the length itself. It also helps in decision if we need to yield. |
83 media::SetUnknownDataSize(shared_memory_, max_size); | 81 media::SetUnknownDataSize(shared_memory_, packet_size_); |
84 | 82 |
85 return read_size; | 83 // Return the actual number of frames read. |
84 return size / (sizeof(*audio_bus_->channel(0)) * audio_bus_->channels()); | |
86 } | 85 } |
87 | 86 |
88 void AudioSyncReader::Close() { | 87 void AudioSyncReader::Close() { |
89 if (socket_.get()) { | 88 if (socket_.get()) { |
90 socket_->Close(); | 89 socket_->Close(); |
91 } | 90 } |
92 } | 91 } |
93 | 92 |
94 bool AudioSyncReader::Init() { | 93 bool AudioSyncReader::Init() { |
95 socket_.reset(new base::CancelableSyncSocket()); | 94 socket_.reset(new base::CancelableSyncSocket()); |
(...skipping 17 matching lines...) Expand all Loading... | |
113 bool AudioSyncReader::PrepareForeignSocketHandle( | 112 bool AudioSyncReader::PrepareForeignSocketHandle( |
114 base::ProcessHandle process_handle, | 113 base::ProcessHandle process_handle, |
115 base::FileDescriptor* foreign_handle) { | 114 base::FileDescriptor* foreign_handle) { |
116 foreign_handle->fd = foreign_socket_->handle(); | 115 foreign_handle->fd = foreign_socket_->handle(); |
117 foreign_handle->auto_close = false; | 116 foreign_handle->auto_close = false; |
118 if (foreign_handle->fd != -1) | 117 if (foreign_handle->fd != -1) |
119 return true; | 118 return true; |
120 return false; | 119 return false; |
121 } | 120 } |
122 #endif | 121 #endif |
OLD | NEW |