OLD | NEW |
---|---|
(Empty) | |
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. | |
4 | |
5 #include "ppapi/proxy/video_capture_resource.h" | |
6 | |
7 #include "ppapi/c/dev/ppp_video_capture_dev.h" | |
8 #include "ppapi/proxy/dispatch_reply_message.h" | |
9 #include "ppapi/proxy/plugin_dispatcher.h" | |
10 #include "ppapi/proxy/plugin_globals.h" | |
11 #include "ppapi/proxy/plugin_resource_tracker.h" | |
12 #include "ppapi/proxy/ppapi_messages.h" | |
13 #include "ppapi/proxy/ppb_buffer_proxy.h" | |
14 #include "ppapi/proxy/resource_message_params.h" | |
15 #include "ppapi/shared_impl/tracked_callback.h" | |
16 | |
17 namespace ppapi { | |
18 namespace proxy { | |
19 | |
20 VideoCaptureResource::VideoCaptureResource( | |
21 Connection connection, | |
22 PP_Instance instance, | |
23 PluginDispatcher* dispatcher) | |
24 : PluginResource(connection, instance), | |
25 open_state_(BEFORE_OPEN), | |
26 has_pending_enum_devices_callback_(false) { | |
27 SendCreate(RENDERER, PpapiHostMsg_VideoCapture_Create()); | |
28 | |
29 ppp_video_capture_impl_ = static_cast<const PPP_VideoCapture_Dev*>( | |
30 dispatcher->local_get_interface()(PPP_VIDEO_CAPTURE_DEV_INTERFACE)); | |
31 } | |
32 | |
33 VideoCaptureResource::~VideoCaptureResource() { | |
34 } | |
35 | |
36 void VideoCaptureResource::OnReplyReceived( | |
37 const ResourceMessageReplyParams& params, | |
38 const IPC::Message& msg) { | |
39 if (params.sequence()) { | |
40 PluginResource::OnReplyReceived(params, msg); | |
41 return; | |
42 } | |
43 | |
44 IPC_BEGIN_MESSAGE_MAP(VideoCaptureResource, msg) | |
45 PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL( | |
46 PpapiPluginMsg_VideoCapture_OnDeviceInfo, | |
47 OnPluginMsgOnDeviceInfo) | |
48 PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL( | |
49 PpapiPluginMsg_VideoCapture_OnStatus, | |
50 OnPluginMsgOnStatus) | |
51 PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL( | |
52 PpapiPluginMsg_VideoCapture_OnError, | |
53 OnPluginMsgOnError) | |
54 PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL( | |
55 PpapiPluginMsg_VideoCapture_OnBufferReady, | |
56 OnPluginMsgOnBufferReady) | |
57 PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL_UNHANDLED(NOTREACHED()) | |
58 IPC_END_MESSAGE_MAP() | |
59 } | |
60 | |
61 int32_t VideoCaptureResource::EnumerateDevices( | |
62 PP_Resource* devices, | |
63 scoped_refptr<TrackedCallback> callback) { | |
64 if (has_pending_enum_devices_callback_) | |
65 return PP_ERROR_INPROGRESS; | |
66 | |
67 has_pending_enum_devices_callback_ = true; | |
68 | |
69 Call<PpapiPluginMsg_VideoCapture_EnumerateDevicesReply>( | |
70 RENDERER, | |
71 PpapiHostMsg_VideoCapture_EnumerateDevices(), | |
72 base::Bind(&VideoCaptureResource::OnPluginMsgEnumerateDevicesReply, | |
73 this, | |
74 devices, | |
75 callback)); | |
76 return PP_OK_COMPLETIONPENDING; | |
77 } | |
78 | |
79 int32_t VideoCaptureResource::Open( | |
80 const std::string& device_id, | |
81 const PP_VideoCaptureDeviceInfo_Dev& requested_info, | |
82 uint32_t buffer_count, | |
83 scoped_refptr<TrackedCallback> callback) { | |
84 if (open_state_ != BEFORE_OPEN) | |
85 return PP_ERROR_FAILED; | |
86 | |
87 if (TrackedCallback::IsPending(open_callback_)) | |
88 return PP_ERROR_INPROGRESS; | |
89 | |
90 open_callback_ = callback; | |
91 | |
92 Call<PpapiPluginMsg_VideoCapture_OpenReply>( | |
93 RENDERER, | |
94 PpapiHostMsg_VideoCapture_Open(device_id, requested_info, buffer_count), | |
95 base::Bind(&VideoCaptureResource::OnPluginMsgOpenReply, this)); | |
96 return PP_OK_COMPLETIONPENDING; | |
97 } | |
98 | |
99 int32_t VideoCaptureResource::StartCapture() { | |
100 if (open_state_ != OPENED) | |
101 return PP_ERROR_FAILED; | |
102 | |
103 buffer_in_use_.clear(); | |
104 Post(RENDERER, PpapiHostMsg_VideoCapture_StartCapture()); | |
105 return PP_OK; | |
106 } | |
107 | |
108 int32_t VideoCaptureResource::ReuseBuffer(uint32_t buffer) { | |
109 if (buffer >= buffer_in_use_.size() || !buffer_in_use_[buffer]) | |
110 return PP_ERROR_BADARGUMENT; | |
111 Post(RENDERER, PpapiHostMsg_VideoCapture_ReuseBuffer(buffer)); | |
112 return PP_OK; | |
113 } | |
114 | |
115 int32_t VideoCaptureResource::StopCapture() { | |
116 if (open_state_ != OPENED) | |
117 return PP_ERROR_FAILED; | |
118 | |
119 Post(RENDERER, PpapiHostMsg_VideoCapture_StopCapture()); | |
120 return PP_OK; | |
121 } | |
122 | |
123 void VideoCaptureResource::Close() { | |
124 if (open_state_ == CLOSED) | |
125 return; | |
126 | |
127 Post(RENDERER, PpapiHostMsg_VideoCapture_Close()); | |
128 | |
129 open_state_ = CLOSED; | |
130 | |
131 if (TrackedCallback::IsPending(open_callback_)) | |
132 open_callback_->PostAbort(); | |
133 } | |
134 | |
135 const std::vector<DeviceRefData>& | |
136 VideoCaptureResource::GetDeviceRefData() const { | |
yzshen1
2012/11/10 01:14:40
Why do you need this method?
victorhsieh
2012/11/13 03:10:53
Removed.
| |
137 return devices_data_; | |
138 } | |
139 | |
140 void VideoCaptureResource::OnPluginMsgOnDeviceInfo( | |
141 const ResourceMessageReplyParams& params, | |
142 const struct PP_VideoCaptureDeviceInfo_Dev& info, | |
143 const std::vector<HostResource>& buffers, | |
144 uint32_t buffer_size) { | |
145 if (!ppp_video_capture_impl_) | |
146 return; | |
147 | |
148 std::vector<base::SharedMemoryHandle> handles; | |
149 params.TakeAllSharedMemoryHandles(&handles); | |
150 CHECK(handles.size() == buffers.size()); | |
151 | |
152 PluginResourceTracker* tracker = | |
153 PluginGlobals::Get()->plugin_resource_tracker(); | |
154 scoped_array<PP_Resource> resources(new PP_Resource[buffers.size()]); | |
155 for (size_t i = 0; i < buffers.size(); ++i) { | |
156 // We assume that the browser created a new set of resources. | |
157 DCHECK(!tracker->PluginResourceForHostResource(buffers[i])); | |
158 resources[i] = ppapi::proxy::PPB_Buffer_Proxy::AddProxyResource( | |
159 buffers[i], handles[i], buffer_size); | |
160 } | |
161 | |
162 buffer_in_use_ = std::vector<bool>(buffers.size()); | |
163 | |
164 ppp_video_capture_impl_->OnDeviceInfo( | |
yzshen1
2012/11/10 01:14:40
I think we need CallWhileUnlocked() for all the ca
victorhsieh
2012/11/13 03:10:53
Done. I have no idea about when we should lock/un
yzshen1
2012/11/14 06:54:16
Please see https://docs.google.com/a/google.com/do
victorhsieh
2012/11/14 08:22:27
Thanks!
| |
165 pp_instance(), | |
166 pp_resource(), | |
167 &info, | |
168 buffers.size(), | |
169 resources.get()); | |
170 | |
171 for (size_t i = 0; i < buffers.size(); ++i) | |
172 tracker->ReleaseResource(resources[i]); | |
173 } | |
174 | |
175 void VideoCaptureResource::OnPluginMsgOnStatus( | |
176 const ResourceMessageReplyParams& params, | |
177 uint32_t status) { | |
178 switch (status) { | |
179 case PP_VIDEO_CAPTURE_STATUS_STARTING: | |
180 case PP_VIDEO_CAPTURE_STATUS_STOPPING: | |
181 // Those states are not sent by the browser. | |
182 NOTREACHED(); | |
183 break; | |
184 } | |
185 if (ppp_video_capture_impl_) | |
186 ppp_video_capture_impl_->OnStatus(pp_instance(), pp_resource(), status); | |
187 } | |
188 | |
189 void VideoCaptureResource::OnPluginMsgOnError( | |
190 const ResourceMessageReplyParams& params, | |
191 uint32_t error_code) { | |
192 open_state_ = CLOSED; | |
193 if (ppp_video_capture_impl_) | |
194 ppp_video_capture_impl_->OnError(pp_instance(), pp_resource(), error_code); | |
195 } | |
196 | |
197 void VideoCaptureResource::OnPluginMsgOnBufferReady( | |
198 const ResourceMessageReplyParams& params, | |
199 uint32_t buffer) { | |
200 SetBufferInUse(buffer); | |
201 if (ppp_video_capture_impl_) { | |
202 ppp_video_capture_impl_->OnBufferReady(pp_instance(), pp_resource(), | |
203 buffer); | |
204 } | |
205 } | |
206 | |
207 void VideoCaptureResource::OnPluginMsgOpenReply( | |
208 const ResourceMessageReplyParams& params) { | |
209 if (open_state_ == BEFORE_OPEN && params.result() == PP_OK) | |
210 open_state_ = OPENED; | |
211 | |
212 // The callback may have been aborted by Close(). | |
213 if (TrackedCallback::IsPending(open_callback_)) | |
214 open_callback_->Run(params.result()); | |
215 } | |
216 | |
217 void VideoCaptureResource::OnPluginMsgEnumerateDevicesReply( | |
218 PP_Resource* devices_output, | |
219 scoped_refptr<TrackedCallback> callback, | |
220 const ResourceMessageReplyParams& params, | |
221 const std::vector<DeviceRefData>& devices) { | |
222 if (!TrackedCallback::IsPending(callback)) | |
223 return; | |
224 | |
225 DCHECK(has_pending_enum_devices_callback_); | |
226 has_pending_enum_devices_callback_ = false; | |
227 | |
228 if (params.result() == PP_OK && devices_output) { | |
229 devices_data_ = devices; | |
230 | |
231 // devices_output points to the resource array of PP_ArrayOutput. In C++, | |
232 // it's typically allocated in VideoCapture_Dev. | |
233 *devices_output = PPB_DeviceRef_Shared::CreateResourceArray( | |
234 OBJECT_IS_PROXY, pp_instance(), devices); | |
235 } | |
236 | |
237 callback->Run(params.result()); | |
238 } | |
239 | |
240 void VideoCaptureResource::SetBufferInUse(uint32_t buffer_index) { | |
241 DCHECK(buffer_index < buffer_in_use_.size()); | |
242 buffer_in_use_[buffer_index] = true; | |
243 } | |
244 | |
245 } // namespace proxy | |
246 } // namespace ppapi | |
OLD | NEW |