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/ppapi_messages.h" | |
11 #include "ppapi/proxy/ppb_buffer_proxy.h" | |
12 #include "ppapi/proxy/resource_message_params.h" | |
13 #include "ppapi/shared_impl/tracked_callback.h" | |
14 | |
15 namespace ppapi { | |
16 namespace proxy { | |
17 | |
18 VideoCaptureResource::VideoCaptureResource( | |
19 Connection connection, | |
20 PP_Instance instance, | |
21 PluginDispatcher* dispatcher) | |
22 : PluginResource(connection, instance), | |
23 devices_(NULL), | |
24 open_state_(BEFORE_OPEN) { | |
25 if (!sent_create_to_renderer()) | |
26 SendCreate(RENDERER, PpapiHostMsg_VideoCapture_Create()); | |
27 | |
28 ppp_video_capture_impl_ = static_cast<const PPP_VideoCapture_Dev*>( | |
29 dispatcher->local_get_interface()(PPP_VIDEO_CAPTURE_DEV_INTERFACE)); | |
30 } | |
31 | |
32 VideoCaptureResource::~VideoCaptureResource() { | |
33 } | |
34 | |
35 void VideoCaptureResource::OnReplyReceived( | |
36 const ResourceMessageReplyParams& params, | |
37 const IPC::Message& msg) { | |
38 if (params.sequence()) { | |
39 PluginResource::OnReplyReceived(params, msg); | |
40 return; | |
41 } | |
42 | |
43 IPC_BEGIN_MESSAGE_MAP(VideoCaptureResource, msg) | |
44 PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL( | |
45 PpapiPluginMsg_VideoCapture_OnDeviceInfo, | |
46 OnDeviceInfo) | |
47 PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL( | |
48 PpapiPluginMsg_VideoCapture_OnStatus, | |
49 OnStatus) | |
50 PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL( | |
51 PpapiPluginMsg_VideoCapture_OnError, | |
52 OnError) | |
53 PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL( | |
54 PpapiPluginMsg_VideoCapture_OnBufferReady, | |
55 OnBufferReady) | |
56 PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL_UNHANDLED(NOTREACHED()) | |
57 IPC_END_MESSAGE_MAP() | |
58 } | |
59 | |
60 int32_t VideoCaptureResource::EnumerateDevices( | |
61 PP_Resource* devices, | |
62 scoped_refptr<TrackedCallback> callback) { | |
63 if (TrackedCallback::IsPending(enumerate_devices_callback_)) | |
64 return PP_ERROR_INPROGRESS; | |
65 | |
66 devices_ = devices; | |
67 enumerate_devices_callback_ = callback; | |
68 | |
69 Call<PpapiPluginMsg_VideoCapture_EnumerateDevicesReply>( | |
70 RENDERER, | |
71 PpapiHostMsg_VideoCapture_EnumerateDevices(), | |
72 base::Bind(&VideoCaptureResource::OnEnumerateDevicesComplete, this)); | |
brettw
2012/10/31 23:50:26
Cool thing you can do here: Set "devices" and the
victorhsieh
2012/11/02 04:28:47
Done. Thanks for the hint. But I didn't apply th
| |
73 return PP_OK_COMPLETIONPENDING; | |
74 } | |
75 | |
76 int32_t VideoCaptureResource::Open( | |
77 const std::string& device_id, | |
78 const PP_VideoCaptureDeviceInfo_Dev& requested_info, | |
79 uint32_t buffer_count, | |
80 scoped_refptr<TrackedCallback> callback) { | |
81 if (open_state_ != BEFORE_OPEN) | |
82 return PP_ERROR_FAILED; | |
83 | |
84 if (TrackedCallback::IsPending(open_callback_)) | |
85 return PP_ERROR_INPROGRESS; | |
86 | |
87 open_callback_ = callback; | |
88 | |
89 Call<PpapiPluginMsg_VideoCapture_OpenReply>( | |
90 RENDERER, | |
91 PpapiHostMsg_VideoCapture_Open(device_id, requested_info, buffer_count), | |
92 base::Bind(&VideoCaptureResource::OnOpenComplete, this)); | |
93 return PP_OK_COMPLETIONPENDING; | |
94 } | |
95 | |
96 int32_t VideoCaptureResource::StartCapture() { | |
97 if (open_state_ != OPENED) | |
98 return PP_ERROR_FAILED; | |
99 | |
100 buffer_in_use_.clear(); | |
101 Post(RENDERER, PpapiHostMsg_VideoCapture_StartCapture()); | |
102 return PP_OK; | |
103 } | |
104 | |
105 int32_t VideoCaptureResource::ReuseBuffer(uint32_t buffer) { | |
106 if (buffer >= buffer_in_use_.size() || !buffer_in_use_[buffer]) | |
107 return PP_ERROR_BADARGUMENT; | |
108 Post(RENDERER, PpapiHostMsg_VideoCapture_ReuseBuffer(buffer)); | |
109 return PP_OK; | |
110 } | |
111 | |
112 int32_t VideoCaptureResource::StopCapture() { | |
113 if (open_state_ != OPENED) | |
114 return PP_ERROR_FAILED; | |
115 | |
116 Post(RENDERER, PpapiHostMsg_VideoCapture_StopCapture()); | |
117 return PP_OK; | |
118 } | |
119 | |
120 void VideoCaptureResource::Close() { | |
121 Post(RENDERER, PpapiHostMsg_VideoCapture_Close()); | |
122 | |
123 open_state_ = CLOSED; | |
124 | |
125 if (TrackedCallback::IsPending(open_callback_)) | |
126 open_callback_->PostAbort(); | |
127 } | |
128 | |
129 void VideoCaptureResource::OnDeviceInfo( | |
130 const ResourceMessageReplyParams& params, | |
131 const struct PP_VideoCaptureDeviceInfo_Dev& info, | |
132 const std::vector<HostResource>& buffers, | |
133 uint32_t buffer_size) { | |
134 if (!ppp_video_capture_impl_) | |
135 return; | |
136 | |
137 std::vector<base::SharedMemoryHandle> handles; | |
138 params.GetAllSharedMemoryHandles(&handles); | |
139 DCHECK(handles.size() == buffers.size()); | |
140 | |
141 scoped_array<PP_Resource> resources(new PP_Resource[buffers.size()]); | |
142 for (size_t i = 0; i < buffers.size(); ++i) { | |
143 resources[i] = ppapi::proxy::PPB_Buffer_Proxy::AddProxyResource( | |
144 buffers[i], handles[i], buffer_size); | |
145 } | |
146 | |
147 buffer_in_use_ = std::vector<bool>(buffers.size()); | |
148 | |
149 ppp_video_capture_impl_->OnDeviceInfo( | |
150 pp_instance(), | |
151 pp_resource(), | |
152 &info, | |
153 buffers.size(), | |
154 resources.get()); | |
155 } | |
156 | |
157 void VideoCaptureResource::OnStatus( | |
158 const ResourceMessageReplyParams& params, | |
159 uint32_t status) { | |
160 if (ppp_video_capture_impl_) | |
161 ppp_video_capture_impl_->OnStatus(pp_instance(), pp_resource(), status); | |
162 } | |
163 | |
164 void VideoCaptureResource::OnError( | |
165 const ResourceMessageReplyParams& params, | |
166 uint32_t error_code) { | |
167 if (ppp_video_capture_impl_) | |
168 ppp_video_capture_impl_->OnError(pp_instance(), pp_resource(), error_code); | |
169 } | |
170 | |
171 void VideoCaptureResource::OnBufferReady( | |
172 const ResourceMessageReplyParams& params, | |
173 uint32_t buffer) { | |
174 SetBufferInUse(buffer); | |
175 if (ppp_video_capture_impl_) { | |
176 ppp_video_capture_impl_->OnBufferReady(pp_instance(), pp_resource(), | |
177 buffer); | |
178 } | |
179 } | |
180 | |
181 void VideoCaptureResource::OnOpenComplete( | |
182 const ResourceMessageReplyParams& params) { | |
183 if (open_state_ == BEFORE_OPEN && params.result() == PP_OK) | |
184 open_state_ = OPENED; | |
185 | |
186 // The callback may have been aborted by Close(), or the open operation is | |
187 // completed synchronously. | |
188 if (TrackedCallback::IsPending(open_callback_)) | |
189 TrackedCallback::ClearAndRun(&open_callback_, params.result()); | |
190 } | |
191 | |
192 void VideoCaptureResource::OnEnumerateDevicesComplete( | |
193 const ResourceMessageReplyParams& params, | |
194 const std::vector<DeviceRefData>& devices) { | |
195 DCHECK(TrackedCallback::IsPending(enumerate_devices_callback_)); | |
196 | |
197 if (params.result() == PP_OK && devices_) { | |
198 devices_data_ = devices; | |
199 | |
200 // devices_ points to the resource array of PP_ArrayOutput allocated in | |
201 // VideoCapture_Dev. | |
202 *devices_ = PPB_DeviceRef_Shared::CreateResourceArray( | |
203 OBJECT_IS_PROXY, pp_instance(), devices); | |
204 } | |
205 devices_ = NULL; | |
206 | |
207 TrackedCallback::ClearAndRun(&enumerate_devices_callback_, params.result()); | |
208 } | |
209 | |
210 void VideoCaptureResource::SetBufferInUse(uint32_t buffer_index) { | |
211 DCHECK(buffer_index < buffer_in_use_.size()); | |
212 buffer_in_use_[buffer_index] = true; | |
213 } | |
214 | |
215 } // namespace proxy | |
216 } // namespace ppapi | |
OLD | NEW |