blob: af5c62e0a08027ceb40a0667ca658fabed1b5823 [file] [log] [blame]
[email protected]cc123872012-11-16 07:53:081// 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"
[email protected]cc123872012-11-16 07:53:0815#include "ppapi/shared_impl/proxy_lock.h"
16#include "ppapi/shared_impl/tracked_callback.h"
17
18namespace ppapi {
19namespace proxy {
20
21VideoCaptureResource::VideoCaptureResource(
22 Connection connection,
23 PP_Instance instance,
24 PluginDispatcher* dispatcher)
25 : PluginResource(connection, instance),
26 open_state_(BEFORE_OPEN),
[email protected]33eccce2012-12-10 22:15:1027 ALLOW_THIS_IN_INITIALIZER_LIST(enumeration_helper_(this)) {
[email protected]cc123872012-11-16 07:53:0828 SendCreate(RENDERER, PpapiHostMsg_VideoCapture_Create());
29
30 ppp_video_capture_impl_ = static_cast<const PPP_VideoCapture_Dev*>(
31 dispatcher->local_get_interface()(PPP_VIDEO_CAPTURE_DEV_INTERFACE));
32}
33
34VideoCaptureResource::~VideoCaptureResource() {
35}
36
37void VideoCaptureResource::OnReplyReceived(
38 const ResourceMessageReplyParams& params,
39 const IPC::Message& msg) {
[email protected]33eccce2012-12-10 22:15:1040 if (enumeration_helper_.HandleReply(params, msg))
41 return;
42
[email protected]cc123872012-11-16 07:53:0843 if (params.sequence()) {
44 PluginResource::OnReplyReceived(params, msg);
45 return;
46 }
47
48 IPC_BEGIN_MESSAGE_MAP(VideoCaptureResource, msg)
49 PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL(
50 PpapiPluginMsg_VideoCapture_OnDeviceInfo,
51 OnPluginMsgOnDeviceInfo)
52 PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL(
53 PpapiPluginMsg_VideoCapture_OnStatus,
54 OnPluginMsgOnStatus)
55 PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL(
56 PpapiPluginMsg_VideoCapture_OnError,
57 OnPluginMsgOnError)
58 PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL(
59 PpapiPluginMsg_VideoCapture_OnBufferReady,
60 OnPluginMsgOnBufferReady)
61 PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL_UNHANDLED(NOTREACHED())
62 IPC_END_MESSAGE_MAP()
63}
64
[email protected]33eccce2012-12-10 22:15:1065int32_t VideoCaptureResource::EnumerateDevices0_2(
[email protected]cc123872012-11-16 07:53:0866 PP_Resource* devices,
67 scoped_refptr<TrackedCallback> callback) {
[email protected]33eccce2012-12-10 22:15:1068 return enumeration_helper_.EnumerateDevices0_2(devices, callback);
69}
[email protected]cc123872012-11-16 07:53:0870
[email protected]33eccce2012-12-10 22:15:1071int32_t VideoCaptureResource::EnumerateDevices(
72 const PP_ArrayOutput& output,
73 scoped_refptr<TrackedCallback> callback) {
74 return enumeration_helper_.EnumerateDevices(output, callback);
75}
[email protected]cc123872012-11-16 07:53:0876
[email protected]33eccce2012-12-10 22:15:1077int32_t VideoCaptureResource::MonitorDeviceChange(
78 PP_MonitorDeviceChangeCallback callback,
79 void* user_data) {
80 return enumeration_helper_.MonitorDeviceChange(callback, user_data);
[email protected]cc123872012-11-16 07:53:0881}
82
83int32_t VideoCaptureResource::Open(
84 const std::string& device_id,
85 const PP_VideoCaptureDeviceInfo_Dev& requested_info,
86 uint32_t buffer_count,
87 scoped_refptr<TrackedCallback> callback) {
88 if (open_state_ != BEFORE_OPEN)
89 return PP_ERROR_FAILED;
90
91 if (TrackedCallback::IsPending(open_callback_))
92 return PP_ERROR_INPROGRESS;
93
94 open_callback_ = callback;
95
96 Call<PpapiPluginMsg_VideoCapture_OpenReply>(
97 RENDERER,
98 PpapiHostMsg_VideoCapture_Open(device_id, requested_info, buffer_count),
99 base::Bind(&VideoCaptureResource::OnPluginMsgOpenReply, this));
100 return PP_OK_COMPLETIONPENDING;
101}
102
103int32_t VideoCaptureResource::StartCapture() {
104 if (open_state_ != OPENED)
105 return PP_ERROR_FAILED;
106
[email protected]cc123872012-11-16 07:53:08107 Post(RENDERER, PpapiHostMsg_VideoCapture_StartCapture());
108 return PP_OK;
109}
110
111int32_t VideoCaptureResource::ReuseBuffer(uint32_t buffer) {
112 if (buffer >= buffer_in_use_.size() || !buffer_in_use_[buffer])
113 return PP_ERROR_BADARGUMENT;
114 Post(RENDERER, PpapiHostMsg_VideoCapture_ReuseBuffer(buffer));
115 return PP_OK;
116}
117
118int32_t VideoCaptureResource::StopCapture() {
119 if (open_state_ != OPENED)
120 return PP_ERROR_FAILED;
121
122 Post(RENDERER, PpapiHostMsg_VideoCapture_StopCapture());
123 return PP_OK;
124}
125
126void VideoCaptureResource::Close() {
127 if (open_state_ == CLOSED)
128 return;
129
130 Post(RENDERER, PpapiHostMsg_VideoCapture_Close());
131
132 open_state_ = CLOSED;
133
134 if (TrackedCallback::IsPending(open_callback_))
135 open_callback_->PostAbort();
136}
137
138int32_t VideoCaptureResource::EnumerateDevicesSync(
139 const PP_ArrayOutput& devices) {
[email protected]33eccce2012-12-10 22:15:10140 return enumeration_helper_.EnumerateDevicesSync(devices);
141}
[email protected]cc123872012-11-16 07:53:08142
[email protected]33eccce2012-12-10 22:15:10143void VideoCaptureResource::LastPluginRefWasDeleted() {
144 enumeration_helper_.LastPluginRefWasDeleted();
[email protected]cc123872012-11-16 07:53:08145}
146
147void VideoCaptureResource::OnPluginMsgOnDeviceInfo(
148 const ResourceMessageReplyParams& params,
149 const struct PP_VideoCaptureDeviceInfo_Dev& info,
150 const std::vector<HostResource>& buffers,
151 uint32_t buffer_size) {
152 if (!ppp_video_capture_impl_)
153 return;
154
155 std::vector<base::SharedMemoryHandle> handles;
156 params.TakeAllSharedMemoryHandles(&handles);
157 CHECK(handles.size() == buffers.size());
158
159 PluginResourceTracker* tracker =
160 PluginGlobals::Get()->plugin_resource_tracker();
[email protected]e8328952013-04-09 17:35:42161 scoped_ptr<PP_Resource[]> resources(new PP_Resource[buffers.size()]);
[email protected]cc123872012-11-16 07:53:08162 for (size_t i = 0; i < buffers.size(); ++i) {
163 // We assume that the browser created a new set of resources.
164 DCHECK(!tracker->PluginResourceForHostResource(buffers[i]));
165 resources[i] = ppapi::proxy::PPB_Buffer_Proxy::AddProxyResource(
166 buffers[i], handles[i], buffer_size);
167 }
168
169 buffer_in_use_ = std::vector<bool>(buffers.size());
170
171 CallWhileUnlocked(ppp_video_capture_impl_->OnDeviceInfo,
172 pp_instance(),
173 pp_resource(),
174 &info,
175 static_cast<uint32_t>(buffers.size()),
176 const_cast<const PP_Resource*>(resources.get()));
177
178 for (size_t i = 0; i < buffers.size(); ++i)
179 tracker->ReleaseResource(resources[i]);
180}
181
182void VideoCaptureResource::OnPluginMsgOnStatus(
183 const ResourceMessageReplyParams& params,
184 uint32_t status) {
185 switch (status) {
186 case PP_VIDEO_CAPTURE_STATUS_STARTING:
187 case PP_VIDEO_CAPTURE_STATUS_STOPPING:
188 // Those states are not sent by the browser.
189 NOTREACHED();
190 break;
191 }
192 if (ppp_video_capture_impl_) {
193 CallWhileUnlocked(ppp_video_capture_impl_->OnStatus,
194 pp_instance(),
195 pp_resource(),
196 status);
197 }
198}
199
200void VideoCaptureResource::OnPluginMsgOnError(
201 const ResourceMessageReplyParams& params,
202 uint32_t error_code) {
203 open_state_ = CLOSED;
204 if (ppp_video_capture_impl_) {
205 CallWhileUnlocked(ppp_video_capture_impl_->OnError,
206 pp_instance(),
207 pp_resource(),
208 error_code);
209 }
210}
211
212void VideoCaptureResource::OnPluginMsgOnBufferReady(
213 const ResourceMessageReplyParams& params,
214 uint32_t buffer) {
215 SetBufferInUse(buffer);
216 if (ppp_video_capture_impl_) {
217 CallWhileUnlocked(ppp_video_capture_impl_->OnBufferReady,
218 pp_instance(),
219 pp_resource(),
220 buffer);
221 }
222}
223
224void VideoCaptureResource::OnPluginMsgOpenReply(
225 const ResourceMessageReplyParams& params) {
226 if (open_state_ == BEFORE_OPEN && params.result() == PP_OK)
227 open_state_ = OPENED;
228
229 // The callback may have been aborted by Close().
230 if (TrackedCallback::IsPending(open_callback_))
231 open_callback_->Run(params.result());
232}
233
[email protected]cc123872012-11-16 07:53:08234void VideoCaptureResource::SetBufferInUse(uint32_t buffer_index) {
[email protected]33eccce2012-12-10 22:15:10235 CHECK(buffer_index < buffer_in_use_.size());
[email protected]cc123872012-11-16 07:53:08236 buffer_in_use_[buffer_index] = true;
237}
238
239} // namespace proxy
240} // namespace ppapi