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 "ppapi/shared_impl/ppb_audio_shared.h" | 5 #include "ppapi/shared_impl/ppb_audio_shared.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "ppapi/shared_impl/ppapi_globals.h" | 8 #include "ppapi/shared_impl/ppapi_globals.h" |
9 | 9 |
10 using base::subtle::Atomic32; | 10 using base::subtle::Atomic32; |
11 | 11 |
12 namespace ppapi { | 12 namespace ppapi { |
13 | 13 |
14 #if defined(OS_NACL) | |
15 namespace { | |
16 // Because this is static, the function pointers will be NULL initially. | |
17 PP_ThreadFunctions thread_functions; | |
18 } | |
19 #endif // defined(OS_NACL) | |
20 | |
14 // FIXME: The following two functions (TotalSharedMemorySizeInBytes, | 21 // FIXME: The following two functions (TotalSharedMemorySizeInBytes, |
15 // SetActualDataSizeInBytes) are copied from audio_util.cc. | 22 // SetActualDataSizeInBytes) are copied from audio_util.cc. |
16 // Remove these functions once a minimal media library is provided for them. | 23 // Remove these functions once a minimal media library is provided for them. |
17 // code.google.com/p/chromium/issues/detail?id=123203 | 24 // code.google.com/p/chromium/issues/detail?id=123203 |
18 | 25 |
19 uint32 TotalSharedMemorySizeInBytes(uint32 packet_size) { | 26 uint32 TotalSharedMemorySizeInBytes(uint32 packet_size) { |
20 // Need to reserve extra 4 bytes for size of data. | 27 // Need to reserve extra 4 bytes for size of data. |
21 return packet_size + sizeof(Atomic32); | 28 return packet_size + sizeof(Atomic32); |
22 } | 29 } |
23 | 30 |
24 void SetActualDataSizeInBytes(base::SharedMemory* shared_memory, | 31 void SetActualDataSizeInBytes(base::SharedMemory* shared_memory, |
25 uint32 shared_memory_size, | 32 uint32 shared_memory_size, |
26 uint32 actual_data_size) { | 33 uint32 actual_data_size) { |
27 char* ptr = static_cast<char*>(shared_memory->memory()) + shared_memory_size; | 34 char* ptr = static_cast<char*>(shared_memory->memory()) + shared_memory_size; |
28 DCHECK_EQ(0u, reinterpret_cast<size_t>(ptr) & 3); | 35 DCHECK_EQ(0u, reinterpret_cast<size_t>(ptr) & 3); |
29 | 36 |
30 // Set actual data size at the end of the buffer. | 37 // Set actual data size at the end of the buffer. |
31 base::subtle::Release_Store(reinterpret_cast<volatile Atomic32*>(ptr), | 38 base::subtle::Release_Store(reinterpret_cast<volatile Atomic32*>(ptr), |
32 actual_data_size); | 39 actual_data_size); |
33 } | 40 } |
34 | 41 |
35 const int PPB_Audio_Shared::kPauseMark = -1; | 42 const int PPB_Audio_Shared::kPauseMark = -1; |
36 | 43 |
37 PPB_Audio_Shared::PPB_Audio_Shared() | 44 PPB_Audio_Shared::PPB_Audio_Shared() |
38 : playing_(false), | 45 : playing_(false), |
39 shared_memory_size_(0), | 46 shared_memory_size_(0), |
47 #if defined(OS_NACL) | |
48 thread_id_(), | |
dmichael (off chromium)
2012/07/25 03:12:26
It would be clearer to put 0 in explicitly.
bbudge
2012/07/25 12:04:37
I copied it from the SRPC code because I thought i
| |
49 thread_active_(false), | |
50 #endif | |
40 callback_(NULL), | 51 callback_(NULL), |
41 user_data_(NULL) { | 52 user_data_(NULL) { |
42 } | 53 } |
43 | 54 |
44 PPB_Audio_Shared::~PPB_Audio_Shared() { | 55 PPB_Audio_Shared::~PPB_Audio_Shared() { |
45 StopThread(); | 56 StopThread(); |
46 } | 57 } |
47 | 58 |
48 void PPB_Audio_Shared::SetCallback(PPB_Audio_Callback callback, | 59 void PPB_Audio_Shared::SetCallback(PPB_Audio_Callback callback, |
49 void* user_data) { | 60 void* user_data) { |
50 callback_ = callback; | 61 callback_ = callback; |
51 user_data_ = user_data; | 62 user_data_ = user_data; |
52 } | 63 } |
53 | 64 |
54 void PPB_Audio_Shared::SetStartPlaybackState() { | 65 void PPB_Audio_Shared::SetStartPlaybackState() { |
55 DCHECK(!playing_); | 66 DCHECK(!playing_); |
67 #if !defined(OS_NACL) | |
56 DCHECK(!audio_thread_.get()); | 68 DCHECK(!audio_thread_.get()); |
57 | 69 #else |
70 DCHECK(!thread_active_); | |
71 #endif | |
58 // If the socket doesn't exist, that means that the plugin has started before | 72 // If the socket doesn't exist, that means that the plugin has started before |
59 // the browser has had a chance to create all the shared memory info and | 73 // the browser has had a chance to create all the shared memory info and |
60 // notify us. This is a common case. In this case, we just set the playing_ | 74 // notify us. This is a common case. In this case, we just set the playing_ |
61 // flag and the playback will automatically start when that data is available | 75 // flag and the playback will automatically start when that data is available |
62 // in SetStreamInfo. | 76 // in SetStreamInfo. |
63 playing_ = true; | 77 playing_ = true; |
64 StartThread(); | 78 StartThread(); |
65 } | 79 } |
66 | 80 |
67 void PPB_Audio_Shared::SetStopPlaybackState() { | 81 void PPB_Audio_Shared::SetStopPlaybackState() { |
(...skipping 16 matching lines...) Expand all Loading... | |
84 "Failed to map shared memory for PPB_Audio_Shared."); | 98 "Failed to map shared memory for PPB_Audio_Shared."); |
85 } | 99 } |
86 | 100 |
87 StartThread(); | 101 StartThread(); |
88 } | 102 } |
89 | 103 |
90 void PPB_Audio_Shared::StartThread() { | 104 void PPB_Audio_Shared::StartThread() { |
91 // Don't start the thread unless all our state is set up correctly. | 105 // Don't start the thread unless all our state is set up correctly. |
92 if (!playing_ || !callback_ || !socket_.get() || !shared_memory_->memory()) | 106 if (!playing_ || !callback_ || !socket_.get() || !shared_memory_->memory()) |
93 return; | 107 return; |
108 // Clear contents of shm buffer before starting audio thread. This will | |
109 // prevent a burst of static if for some reason the audio thread doesn't | |
110 // start up quickly enough. | |
111 memset(shared_memory_->memory(), 0, shared_memory_size_); | |
112 #if !defined(OS_NACL) | |
94 DCHECK(!audio_thread_.get()); | 113 DCHECK(!audio_thread_.get()); |
95 audio_thread_.reset(new base::DelegateSimpleThread( | 114 audio_thread_.reset(new base::DelegateSimpleThread( |
96 this, "plugin_audio_thread")); | 115 this, "plugin_audio_thread")); |
97 audio_thread_->Start(); | 116 audio_thread_->Start(); |
117 #else | |
118 // Use NaCl's special API for IRT code that creates threads that call back | |
119 // into user code. | |
120 if (NULL == thread_functions.thread_create || | |
121 NULL == thread_functions.thread_join) | |
122 return; | |
123 | |
124 int result = thread_functions.thread_create(&thread_id_, CallRun, this); | |
125 DCHECK_EQ(result, 0); | |
126 thread_active_ = true; | |
127 #endif | |
98 } | 128 } |
99 | 129 |
100 void PPB_Audio_Shared::StopThread() { | 130 void PPB_Audio_Shared::StopThread() { |
101 // Shut down the socket to escape any hanging |Receive|s. | 131 // Shut down the socket to escape any hanging |Receive|s. |
102 if (socket_.get()) | 132 if (socket_.get()) |
103 socket_->Shutdown(); | 133 socket_->Shutdown(); |
134 #if !defined(OS_NACL) | |
104 if (audio_thread_.get()) { | 135 if (audio_thread_.get()) { |
105 audio_thread_->Join(); | 136 audio_thread_->Join(); |
106 audio_thread_.reset(); | 137 audio_thread_.reset(); |
107 } | 138 } |
139 #else | |
140 if (thread_active_) { | |
141 int result = thread_functions.thread_join(thread_id_); | |
142 DCHECK_EQ(0, result); | |
143 thread_active_ = false; | |
144 } | |
145 #endif | |
108 } | 146 } |
109 | 147 |
148 #if defined(OS_NACL) | |
149 // static | |
150 void PPB_Audio_Shared::SetThreadFunctions( | |
151 const struct PP_ThreadFunctions* functions) { | |
152 DCHECK(thread_functions.thread_create == NULL); | |
153 DCHECK(thread_functions.thread_join == NULL); | |
154 thread_functions = *functions; | |
155 } | |
156 | |
157 // static | |
158 void PPB_Audio_Shared::CallRun(void* self) { | |
159 PPB_Audio_Shared* audio = static_cast<PPB_Audio_Shared*>(self); | |
160 audio->Run(); | |
161 } | |
162 #endif | |
163 | |
110 void PPB_Audio_Shared::Run() { | 164 void PPB_Audio_Shared::Run() { |
111 int pending_data; | 165 int pending_data; |
112 void* buffer = shared_memory_->memory(); | 166 void* buffer = shared_memory_->memory(); |
113 | 167 |
114 while (sizeof(pending_data) == | 168 while (sizeof(pending_data) == |
115 socket_->Receive(&pending_data, sizeof(pending_data)) && | 169 socket_->Receive(&pending_data, sizeof(pending_data)) && |
116 pending_data != kPauseMark) { | 170 pending_data != kPauseMark) { |
117 callback_(buffer, shared_memory_size_, user_data_); | 171 callback_(buffer, shared_memory_size_, user_data_); |
118 | 172 |
119 // Let the host know we are done. | 173 // Let the host know we are done. |
120 SetActualDataSizeInBytes(shared_memory_.get(), shared_memory_size_, | 174 SetActualDataSizeInBytes(shared_memory_.get(), shared_memory_size_, |
121 shared_memory_size_); | 175 shared_memory_size_); |
122 } | 176 } |
123 } | 177 } |
124 | 178 |
125 } // namespace ppapi | 179 } // namespace ppapi |
OLD | NEW |