[go: nahoru, domu]

blob: 69062cbe0617df96e44dcc6028db8617badfba28 [file] [log] [blame]
Avi Drissmandb497b32022-09-15 19:47:281// Copyright 2012 The Chromium Authors
victorhsieh@chromium.orgcc123872012-11-16 07:53:082// 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
avie029c4132015-12-23 06:45:227#include <stddef.h>
8
Avi Drissman821ca3092023-01-11 22:42:159#include "base/functional/bind.h"
victorhsieh@chromium.orgcc123872012-11-16 07:53:0810#include "ppapi/c/dev/ppp_video_capture_dev.h"
11#include "ppapi/proxy/dispatch_reply_message.h"
12#include "ppapi/proxy/plugin_dispatcher.h"
13#include "ppapi/proxy/plugin_globals.h"
14#include "ppapi/proxy/plugin_resource_tracker.h"
15#include "ppapi/proxy/ppapi_messages.h"
16#include "ppapi/proxy/ppb_buffer_proxy.h"
17#include "ppapi/proxy/resource_message_params.h"
victorhsieh@chromium.orgcc123872012-11-16 07:53:0818#include "ppapi/shared_impl/proxy_lock.h"
19#include "ppapi/shared_impl/tracked_callback.h"
20
21namespace ppapi {
22namespace proxy {
23
24VideoCaptureResource::VideoCaptureResource(
25 Connection connection,
26 PP_Instance instance,
27 PluginDispatcher* dispatcher)
28 : PluginResource(connection, instance),
29 open_state_(BEFORE_OPEN),
scherkus@chromium.orga2f53dc2013-04-30 01:06:3530 enumeration_helper_(this) {
victorhsieh@chromium.orgcc123872012-11-16 07:53:0831 SendCreate(RENDERER, PpapiHostMsg_VideoCapture_Create());
32
33 ppp_video_capture_impl_ = static_cast<const PPP_VideoCapture_Dev*>(
34 dispatcher->local_get_interface()(PPP_VIDEO_CAPTURE_DEV_INTERFACE));
35}
36
37VideoCaptureResource::~VideoCaptureResource() {
38}
39
40void VideoCaptureResource::OnReplyReceived(
41 const ResourceMessageReplyParams& params,
42 const IPC::Message& msg) {
yzshen@chromium.org33eccce2012-12-10 22:15:1043 if (enumeration_helper_.HandleReply(params, msg))
44 return;
45
victorhsieh@chromium.orgcc123872012-11-16 07:53:0846 if (params.sequence()) {
47 PluginResource::OnReplyReceived(params, msg);
48 return;
49 }
50
jam@chromium.orgdade5f82014-05-13 21:59:2151 PPAPI_BEGIN_MESSAGE_MAP(VideoCaptureResource, msg)
victorhsieh@chromium.orgcc123872012-11-16 07:53:0852 PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL(
53 PpapiPluginMsg_VideoCapture_OnDeviceInfo,
54 OnPluginMsgOnDeviceInfo)
55 PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL(
56 PpapiPluginMsg_VideoCapture_OnStatus,
57 OnPluginMsgOnStatus)
58 PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL(
59 PpapiPluginMsg_VideoCapture_OnError,
60 OnPluginMsgOnError)
61 PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL(
62 PpapiPluginMsg_VideoCapture_OnBufferReady,
63 OnPluginMsgOnBufferReady)
64 PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL_UNHANDLED(NOTREACHED())
jam@chromium.orgdade5f82014-05-13 21:59:2165 PPAPI_END_MESSAGE_MAP()
victorhsieh@chromium.orgcc123872012-11-16 07:53:0866}
67
yzshen@chromium.org33eccce2012-12-10 22:15:1068int32_t VideoCaptureResource::EnumerateDevices(
69 const PP_ArrayOutput& output,
70 scoped_refptr<TrackedCallback> callback) {
71 return enumeration_helper_.EnumerateDevices(output, callback);
72}
victorhsieh@chromium.orgcc123872012-11-16 07:53:0873
yzshen@chromium.org33eccce2012-12-10 22:15:1074int32_t VideoCaptureResource::MonitorDeviceChange(
75 PP_MonitorDeviceChangeCallback callback,
76 void* user_data) {
77 return enumeration_helper_.MonitorDeviceChange(callback, user_data);
victorhsieh@chromium.orgcc123872012-11-16 07:53:0878}
79
80int32_t VideoCaptureResource::Open(
81 const std::string& device_id,
82 const PP_VideoCaptureDeviceInfo_Dev& requested_info,
83 uint32_t buffer_count,
84 scoped_refptr<TrackedCallback> callback) {
85 if (open_state_ != BEFORE_OPEN)
86 return PP_ERROR_FAILED;
87
88 if (TrackedCallback::IsPending(open_callback_))
89 return PP_ERROR_INPROGRESS;
90
91 open_callback_ = callback;
92
93 Call<PpapiPluginMsg_VideoCapture_OpenReply>(
94 RENDERER,
95 PpapiHostMsg_VideoCapture_Open(device_id, requested_info, buffer_count),
Anand K Mistry9182c2a72021-03-17 04:40:0896 base::BindOnce(&VideoCaptureResource::OnPluginMsgOpenReply, this));
victorhsieh@chromium.orgcc123872012-11-16 07:53:0897 return PP_OK_COMPLETIONPENDING;
98}
99
100int32_t VideoCaptureResource::StartCapture() {
101 if (open_state_ != OPENED)
102 return PP_ERROR_FAILED;
103
victorhsieh@chromium.orgcc123872012-11-16 07:53:08104 Post(RENDERER, PpapiHostMsg_VideoCapture_StartCapture());
105 return PP_OK;
106}
107
108int32_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
115int32_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
123void 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
135int32_t VideoCaptureResource::EnumerateDevicesSync(
136 const PP_ArrayOutput& devices) {
yzshen@chromium.org33eccce2012-12-10 22:15:10137 return enumeration_helper_.EnumerateDevicesSync(devices);
138}
victorhsieh@chromium.orgcc123872012-11-16 07:53:08139
yzshen@chromium.org33eccce2012-12-10 22:15:10140void VideoCaptureResource::LastPluginRefWasDeleted() {
141 enumeration_helper_.LastPluginRefWasDeleted();
victorhsieh@chromium.orgcc123872012-11-16 07:53:08142}
143
144void VideoCaptureResource::OnPluginMsgOnDeviceInfo(
145 const ResourceMessageReplyParams& params,
146 const struct PP_VideoCaptureDeviceInfo_Dev& info,
147 const std::vector<HostResource>& buffers,
148 uint32_t buffer_size) {
149 if (!ppp_video_capture_impl_)
150 return;
151
Matthew Caryfc3757f2019-07-30 21:32:46152 std::vector<base::UnsafeSharedMemoryRegion> regions;
153 for (size_t i = 0; i < params.handles().size(); ++i) {
154 base::UnsafeSharedMemoryRegion region;
155 params.TakeUnsafeSharedMemoryRegionAtIndex(i, &region);
156 DCHECK_EQ(buffer_size, region.GetSize());
157 regions.push_back(std::move(region));
158 }
159 CHECK(regions.size() == buffers.size());
victorhsieh@chromium.orgcc123872012-11-16 07:53:08160
161 PluginResourceTracker* tracker =
162 PluginGlobals::Get()->plugin_resource_tracker();
dchengced92242016-04-07 00:00:12163 std::unique_ptr<PP_Resource[]> resources(new PP_Resource[buffers.size()]);
victorhsieh@chromium.orgcc123872012-11-16 07:53:08164 for (size_t i = 0; i < buffers.size(); ++i) {
165 // We assume that the browser created a new set of resources.
166 DCHECK(!tracker->PluginResourceForHostResource(buffers[i]));
167 resources[i] = ppapi::proxy::PPB_Buffer_Proxy::AddProxyResource(
Matthew Caryfc3757f2019-07-30 21:32:46168 buffers[i], std::move(regions[i]));
victorhsieh@chromium.orgcc123872012-11-16 07:53:08169 }
170
171 buffer_in_use_ = std::vector<bool>(buffers.size());
172
173 CallWhileUnlocked(ppp_video_capture_impl_->OnDeviceInfo,
174 pp_instance(),
175 pp_resource(),
176 &info,
brettw669d47b12015-02-13 21:17:38177 static_cast<uint32_t>(buffers.size()),
dmichael36e91cd2014-09-11 16:57:30178 resources.get());
victorhsieh@chromium.orgcc123872012-11-16 07:53:08179
180 for (size_t i = 0; i < buffers.size(); ++i)
181 tracker->ReleaseResource(resources[i]);
182}
183
184void VideoCaptureResource::OnPluginMsgOnStatus(
185 const ResourceMessageReplyParams& params,
186 uint32_t status) {
187 switch (status) {
188 case PP_VIDEO_CAPTURE_STATUS_STARTING:
189 case PP_VIDEO_CAPTURE_STATUS_STOPPING:
190 // Those states are not sent by the browser.
191 NOTREACHED();
192 break;
193 }
194 if (ppp_video_capture_impl_) {
195 CallWhileUnlocked(ppp_video_capture_impl_->OnStatus,
196 pp_instance(),
197 pp_resource(),
198 status);
199 }
200}
201
202void VideoCaptureResource::OnPluginMsgOnError(
203 const ResourceMessageReplyParams& params,
204 uint32_t error_code) {
205 open_state_ = CLOSED;
206 if (ppp_video_capture_impl_) {
207 CallWhileUnlocked(ppp_video_capture_impl_->OnError,
208 pp_instance(),
209 pp_resource(),
210 error_code);
211 }
212}
213
214void VideoCaptureResource::OnPluginMsgOnBufferReady(
215 const ResourceMessageReplyParams& params,
216 uint32_t buffer) {
217 SetBufferInUse(buffer);
218 if (ppp_video_capture_impl_) {
219 CallWhileUnlocked(ppp_video_capture_impl_->OnBufferReady,
220 pp_instance(),
221 pp_resource(),
222 buffer);
223 }
224}
225
226void VideoCaptureResource::OnPluginMsgOpenReply(
227 const ResourceMessageReplyParams& params) {
228 if (open_state_ == BEFORE_OPEN && params.result() == PP_OK)
229 open_state_ = OPENED;
230
231 // The callback may have been aborted by Close().
232 if (TrackedCallback::IsPending(open_callback_))
233 open_callback_->Run(params.result());
234}
235
victorhsieh@chromium.orgcc123872012-11-16 07:53:08236void VideoCaptureResource::SetBufferInUse(uint32_t buffer_index) {
yzshen@chromium.org33eccce2012-12-10 22:15:10237 CHECK(buffer_index < buffer_in_use_.size());
victorhsieh@chromium.orgcc123872012-11-16 07:53:08238 buffer_in_use_[buffer_index] = true;
239}
240
241} // namespace proxy
242} // namespace ppapi