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 open_state_(BEFORE_OPEN), | |
24 has_pending_enum_devices_callback_(false) { | |
25 if (!sent_create_to_renderer()) | |
yzshen1
2012/11/06 06:51:40
You don't need to test this condition.
victorhsieh
2012/11/08 09:20:18
Done.
| |
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 (has_pending_enum_devices_callback_) | |
64 return PP_ERROR_INPROGRESS; | |
65 | |
66 has_pending_enum_devices_callback_ = true; | |
67 | |
68 Call<PpapiPluginMsg_VideoCapture_EnumerateDevicesReply>( | |
69 RENDERER, | |
70 PpapiHostMsg_VideoCapture_EnumerateDevices(), | |
71 base::Bind(&VideoCaptureResource::OnEnumerateDevicesComplete, | |
72 this, | |
73 devices, | |
74 callback)); | |
75 return PP_OK_COMPLETIONPENDING; | |
76 } | |
77 | |
78 int32_t VideoCaptureResource::Open( | |
79 const std::string& device_id, | |
80 const PP_VideoCaptureDeviceInfo_Dev& requested_info, | |
81 uint32_t buffer_count, | |
82 scoped_refptr<TrackedCallback> callback) { | |
83 if (open_state_ != BEFORE_OPEN) | |
84 return PP_ERROR_FAILED; | |
85 | |
86 if (TrackedCallback::IsPending(open_callback_)) | |
87 return PP_ERROR_INPROGRESS; | |
88 | |
89 open_callback_ = callback; | |
90 | |
91 Call<PpapiPluginMsg_VideoCapture_OpenReply>( | |
92 RENDERER, | |
93 PpapiHostMsg_VideoCapture_Open(device_id, requested_info, buffer_count), | |
94 base::Bind(&VideoCaptureResource::OnOpenComplete, this)); | |
95 return PP_OK_COMPLETIONPENDING; | |
96 } | |
97 | |
98 int32_t VideoCaptureResource::StartCapture() { | |
99 if (open_state_ != OPENED) | |
100 return PP_ERROR_FAILED; | |
101 | |
yzshen1
2012/11/06 06:51:40
I notice that the previous code will do a SetStatu
victorhsieh
2012/11/08 09:20:18
SetStatus checks the current state before jumping
yzshen1
2012/11/10 01:14:40
What is the reason to keep the status_ state machi
victorhsieh
2012/11/13 03:10:53
The idea to keep status_ on the host when I first
yzshen1
2012/11/14 06:54:16
IMO, it is easier to ensure the implementation has
| |
102 buffer_in_use_.clear(); | |
103 Post(RENDERER, PpapiHostMsg_VideoCapture_StartCapture()); | |
104 return PP_OK; | |
105 } | |
106 | |
107 int32_t VideoCaptureResource::ReuseBuffer(uint32_t buffer) { | |
108 if (buffer >= buffer_in_use_.size() || !buffer_in_use_[buffer]) | |
109 return PP_ERROR_BADARGUMENT; | |
110 Post(RENDERER, PpapiHostMsg_VideoCapture_ReuseBuffer(buffer)); | |
111 return PP_OK; | |
112 } | |
113 | |
114 int32_t VideoCaptureResource::StopCapture() { | |
115 if (open_state_ != OPENED) | |
116 return PP_ERROR_FAILED; | |
117 | |
yzshen1
2012/11/06 06:51:40
I notice that the previous code will do a SetStatu
victorhsieh
2012/11/08 09:20:18
Similarly to STARTING, the preceding states that e
| |
118 Post(RENDERER, PpapiHostMsg_VideoCapture_StopCapture()); | |
119 return PP_OK; | |
120 } | |
121 | |
122 void VideoCaptureResource::Close() { | |
yzshen1
2012/11/06 06:51:40
Please make sure the second and subsequent Close()
victorhsieh
2012/11/08 09:20:18
Done.
| |
123 Post(RENDERER, PpapiHostMsg_VideoCapture_Close()); | |
124 | |
125 open_state_ = CLOSED; | |
126 | |
127 if (TrackedCallback::IsPending(open_callback_)) | |
128 open_callback_->PostAbort(); | |
129 } | |
130 | |
131 void VideoCaptureResource::OnDeviceInfo( | |
132 const ResourceMessageReplyParams& params, | |
133 const struct PP_VideoCaptureDeviceInfo_Dev& info, | |
134 const std::vector<HostResource>& buffers, | |
135 uint32_t buffer_size) { | |
136 if (!ppp_video_capture_impl_) | |
137 return; | |
138 | |
139 std::vector<base::SharedMemoryHandle> handles; | |
140 params.GetAllSharedMemoryHandles(&handles); | |
141 DCHECK(handles.size() == buffers.size()); | |
yzshen1
2012/11/06 06:51:40
Please use CHECK().
victorhsieh
2012/11/08 09:20:18
Done.
| |
142 | |
143 scoped_array<PP_Resource> resources(new PP_Resource[buffers.size()]); | |
144 for (size_t i = 0; i < buffers.size(); ++i) { | |
145 resources[i] = ppapi::proxy::PPB_Buffer_Proxy::AddProxyResource( | |
yzshen1
2012/11/06 06:51:40
The resources are leaked!
You should release them
victorhsieh
2012/11/08 09:20:18
Done. Please advise if this is not correct.
| |
146 buffers[i], handles[i], buffer_size); | |
147 } | |
148 | |
149 buffer_in_use_ = std::vector<bool>(buffers.size()); | |
150 | |
151 ppp_video_capture_impl_->OnDeviceInfo( | |
152 pp_instance(), | |
153 pp_resource(), | |
154 &info, | |
155 buffers.size(), | |
156 resources.get()); | |
157 } | |
158 | |
159 void VideoCaptureResource::OnStatus( | |
160 const ResourceMessageReplyParams& params, | |
161 uint32_t status) { | |
162 if (ppp_video_capture_impl_) | |
163 ppp_video_capture_impl_->OnStatus(pp_instance(), pp_resource(), status); | |
164 } | |
165 | |
166 void VideoCaptureResource::OnError( | |
167 const ResourceMessageReplyParams& params, | |
168 uint32_t error_code) { | |
169 if (ppp_video_capture_impl_) | |
170 ppp_video_capture_impl_->OnError(pp_instance(), pp_resource(), error_code); | |
171 } | |
172 | |
173 void VideoCaptureResource::OnBufferReady( | |
174 const ResourceMessageReplyParams& params, | |
175 uint32_t buffer) { | |
176 SetBufferInUse(buffer); | |
177 if (ppp_video_capture_impl_) { | |
178 ppp_video_capture_impl_->OnBufferReady(pp_instance(), pp_resource(), | |
179 buffer); | |
180 } | |
181 } | |
182 | |
183 void VideoCaptureResource::OnOpenComplete( | |
184 const ResourceMessageReplyParams& params) { | |
185 if (open_state_ == BEFORE_OPEN && params.result() == PP_OK) | |
186 open_state_ = OPENED; | |
187 | |
188 // The callback may have been aborted by Close(), or the open operation is | |
189 // completed synchronously. | |
yzshen1
2012/11/06 06:51:40
the 'synchronously' part is not correct in this ca
victorhsieh
2012/11/08 09:20:18
Done.
| |
190 if (TrackedCallback::IsPending(open_callback_)) | |
191 TrackedCallback::ClearAndRun(&open_callback_, params.result()); | |
192 } | |
193 | |
194 void VideoCaptureResource::OnEnumerateDevicesComplete( | |
195 PP_Resource* devices_output, | |
196 scoped_refptr<TrackedCallback> callback, | |
197 const ResourceMessageReplyParams& params, | |
198 const std::vector<DeviceRefData>& devices) { | |
199 DCHECK(has_pending_enum_devices_callback_); | |
yzshen1
2012/11/06 06:51:40
- you should set has_pending_enum_devices_callback
victorhsieh
2012/11/08 09:20:18
Done.
| |
200 | |
201 if (params.result() == PP_OK && devices_output) { | |
202 devices_data_ = devices; | |
203 | |
204 // devices_output points to the resource array of PP_ArrayOutput allocated | |
205 // in VideoCapture_Dev. | |
yzshen1
2012/11/06 06:51:40
This is not accurate. Users can use c interface di
victorhsieh
2012/11/08 09:20:18
Done.
| |
206 *devices_output = PPB_DeviceRef_Shared::CreateResourceArray( | |
207 OBJECT_IS_PROXY, pp_instance(), devices); | |
208 } | |
209 | |
210 TrackedCallback::ClearAndRun(&callback, params.result()); | |
211 } | |
212 | |
213 void VideoCaptureResource::SetBufferInUse(uint32_t buffer_index) { | |
214 DCHECK(buffer_index < buffer_in_use_.size()); | |
215 buffer_in_use_[buffer_index] = true; | |
216 } | |
217 | |
218 } // namespace proxy | |
219 } // namespace ppapi | |
OLD | NEW |