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