[go: nahoru, domu]

blob: 5c95ed8171023b7fd8b8c4afeba5ff39ea3f5e50 [file] [log] [blame]
victorhsieh@chromium.orgcc123872012-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"
victorhsieh@chromium.orgcc123872012-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),
scherkus@chromium.orga2f53dc2013-04-30 01:06:3527 enumeration_helper_(this) {
victorhsieh@chromium.orgcc123872012-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) {
yzshen@chromium.org33eccce2012-12-10 22:15:1040 if (enumeration_helper_.HandleReply(params, msg))
41 return;
42
victorhsieh@chromium.orgcc123872012-11-16 07:53:0843 if (params.sequence()) {
44 PluginResource::OnReplyReceived(params, msg);
45 return;
46 }
47
jam@chromium.orgdade5f82014-05-13 21:59:2148 PPAPI_BEGIN_MESSAGE_MAP(VideoCaptureResource, msg)
victorhsieh@chromium.orgcc123872012-11-16 07:53:0849 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())
jam@chromium.orgdade5f82014-05-13 21:59:2162 PPAPI_END_MESSAGE_MAP()
victorhsieh@chromium.orgcc123872012-11-16 07:53:0863}
64
yzshen@chromium.org33eccce2012-12-10 22:15:1065int32_t VideoCaptureResource::EnumerateDevices(
66 const PP_ArrayOutput& output,
67 scoped_refptr<TrackedCallback> callback) {
68 return enumeration_helper_.EnumerateDevices(output, callback);
69}
victorhsieh@chromium.orgcc123872012-11-16 07:53:0870
yzshen@chromium.org33eccce2012-12-10 22:15:1071int32_t VideoCaptureResource::MonitorDeviceChange(
72 PP_MonitorDeviceChangeCallback callback,
73 void* user_data) {
74 return enumeration_helper_.MonitorDeviceChange(callback, user_data);
victorhsieh@chromium.orgcc123872012-11-16 07:53:0875}
76
77int32_t VideoCaptureResource::Open(
78 const std::string& device_id,
79 const PP_VideoCaptureDeviceInfo_Dev& requested_info,
80 uint32_t buffer_count,
81 scoped_refptr<TrackedCallback> callback) {
82 if (open_state_ != BEFORE_OPEN)
83 return PP_ERROR_FAILED;
84
85 if (TrackedCallback::IsPending(open_callback_))
86 return PP_ERROR_INPROGRESS;
87
88 open_callback_ = callback;
89
90 Call<PpapiPluginMsg_VideoCapture_OpenReply>(
91 RENDERER,
92 PpapiHostMsg_VideoCapture_Open(device_id, requested_info, buffer_count),
93 base::Bind(&VideoCaptureResource::OnPluginMsgOpenReply, this));
94 return PP_OK_COMPLETIONPENDING;
95}
96
97int32_t VideoCaptureResource::StartCapture() {
98 if (open_state_ != OPENED)
99 return PP_ERROR_FAILED;
100
victorhsieh@chromium.orgcc123872012-11-16 07:53:08101 Post(RENDERER, PpapiHostMsg_VideoCapture_StartCapture());
102 return PP_OK;
103}
104
105int32_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
112int32_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
120void VideoCaptureResource::Close() {
121 if (open_state_ == CLOSED)
122 return;
123
124 Post(RENDERER, PpapiHostMsg_VideoCapture_Close());
125
126 open_state_ = CLOSED;
127
128 if (TrackedCallback::IsPending(open_callback_))
129 open_callback_->PostAbort();
130}
131
132int32_t VideoCaptureResource::EnumerateDevicesSync(
133 const PP_ArrayOutput& devices) {
yzshen@chromium.org33eccce2012-12-10 22:15:10134 return enumeration_helper_.EnumerateDevicesSync(devices);
135}
victorhsieh@chromium.orgcc123872012-11-16 07:53:08136
yzshen@chromium.org33eccce2012-12-10 22:15:10137void VideoCaptureResource::LastPluginRefWasDeleted() {
138 enumeration_helper_.LastPluginRefWasDeleted();
victorhsieh@chromium.orgcc123872012-11-16 07:53:08139}
140
141void VideoCaptureResource::OnPluginMsgOnDeviceInfo(
142 const ResourceMessageReplyParams& params,
143 const struct PP_VideoCaptureDeviceInfo_Dev& info,
144 const std::vector<HostResource>& buffers,
145 uint32_t buffer_size) {
146 if (!ppp_video_capture_impl_)
147 return;
148
149 std::vector<base::SharedMemoryHandle> handles;
150 params.TakeAllSharedMemoryHandles(&handles);
151 CHECK(handles.size() == buffers.size());
152
153 PluginResourceTracker* tracker =
154 PluginGlobals::Get()->plugin_resource_tracker();
dcheng@chromium.orge8328952013-04-09 17:35:42155 scoped_ptr<PP_Resource[]> resources(new PP_Resource[buffers.size()]);
victorhsieh@chromium.orgcc123872012-11-16 07:53:08156 for (size_t i = 0; i < buffers.size(); ++i) {
157 // We assume that the browser created a new set of resources.
158 DCHECK(!tracker->PluginResourceForHostResource(buffers[i]));
159 resources[i] = ppapi::proxy::PPB_Buffer_Proxy::AddProxyResource(
160 buffers[i], handles[i], buffer_size);
161 }
162
163 buffer_in_use_ = std::vector<bool>(buffers.size());
164
165 CallWhileUnlocked(ppp_video_capture_impl_->OnDeviceInfo,
166 pp_instance(),
167 pp_resource(),
168 &info,
dmichael36e91cd2014-09-11 16:57:30169 buffers.size(),
170 resources.get());
victorhsieh@chromium.orgcc123872012-11-16 07:53:08171
172 for (size_t i = 0; i < buffers.size(); ++i)
173 tracker->ReleaseResource(resources[i]);
174}
175
176void VideoCaptureResource::OnPluginMsgOnStatus(
177 const ResourceMessageReplyParams& params,
178 uint32_t status) {
179 switch (status) {
180 case PP_VIDEO_CAPTURE_STATUS_STARTING:
181 case PP_VIDEO_CAPTURE_STATUS_STOPPING:
182 // Those states are not sent by the browser.
183 NOTREACHED();
184 break;
185 }
186 if (ppp_video_capture_impl_) {
187 CallWhileUnlocked(ppp_video_capture_impl_->OnStatus,
188 pp_instance(),
189 pp_resource(),
190 status);
191 }
192}
193
194void VideoCaptureResource::OnPluginMsgOnError(
195 const ResourceMessageReplyParams& params,
196 uint32_t error_code) {
197 open_state_ = CLOSED;
198 if (ppp_video_capture_impl_) {
199 CallWhileUnlocked(ppp_video_capture_impl_->OnError,
200 pp_instance(),
201 pp_resource(),
202 error_code);
203 }
204}
205
206void VideoCaptureResource::OnPluginMsgOnBufferReady(
207 const ResourceMessageReplyParams& params,
208 uint32_t buffer) {
209 SetBufferInUse(buffer);
210 if (ppp_video_capture_impl_) {
211 CallWhileUnlocked(ppp_video_capture_impl_->OnBufferReady,
212 pp_instance(),
213 pp_resource(),
214 buffer);
215 }
216}
217
218void VideoCaptureResource::OnPluginMsgOpenReply(
219 const ResourceMessageReplyParams& params) {
220 if (open_state_ == BEFORE_OPEN && params.result() == PP_OK)
221 open_state_ = OPENED;
222
223 // The callback may have been aborted by Close().
224 if (TrackedCallback::IsPending(open_callback_))
225 open_callback_->Run(params.result());
226}
227
victorhsieh@chromium.orgcc123872012-11-16 07:53:08228void VideoCaptureResource::SetBufferInUse(uint32_t buffer_index) {
yzshen@chromium.org33eccce2012-12-10 22:15:10229 CHECK(buffer_index < buffer_in_use_.size());
victorhsieh@chromium.orgcc123872012-11-16 07:53:08230 buffer_in_use_[buffer_index] = true;
231}
232
233} // namespace proxy
234} // namespace ppapi