Plugin Power Saver: Force SW rendering for peripheral plugins.
[chromium-blink-merge.git] / ppapi / proxy / video_capture_resource.cc
blob5c95ed8171023b7fd8b8c4afeba5ff39ea3f5e50
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.
5 #include "ppapi/proxy/video_capture_resource.h"
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"
15 #include "ppapi/shared_impl/proxy_lock.h"
16 #include "ppapi/shared_impl/tracked_callback.h"
18 namespace ppapi {
19 namespace proxy {
21 VideoCaptureResource::VideoCaptureResource(
22 Connection connection,
23 PP_Instance instance,
24 PluginDispatcher* dispatcher)
25 : PluginResource(connection, instance),
26 open_state_(BEFORE_OPEN),
27 enumeration_helper_(this) {
28 SendCreate(RENDERER, PpapiHostMsg_VideoCapture_Create());
30 ppp_video_capture_impl_ = static_cast<const PPP_VideoCapture_Dev*>(
31 dispatcher->local_get_interface()(PPP_VIDEO_CAPTURE_DEV_INTERFACE));
34 VideoCaptureResource::~VideoCaptureResource() {
37 void VideoCaptureResource::OnReplyReceived(
38 const ResourceMessageReplyParams& params,
39 const IPC::Message& msg) {
40 if (enumeration_helper_.HandleReply(params, msg))
41 return;
43 if (params.sequence()) {
44 PluginResource::OnReplyReceived(params, msg);
45 return;
48 PPAPI_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 PPAPI_END_MESSAGE_MAP()
65 int32_t VideoCaptureResource::EnumerateDevices(
66 const PP_ArrayOutput& output,
67 scoped_refptr<TrackedCallback> callback) {
68 return enumeration_helper_.EnumerateDevices(output, callback);
71 int32_t VideoCaptureResource::MonitorDeviceChange(
72 PP_MonitorDeviceChangeCallback callback,
73 void* user_data) {
74 return enumeration_helper_.MonitorDeviceChange(callback, user_data);
77 int32_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;
85 if (TrackedCallback::IsPending(open_callback_))
86 return PP_ERROR_INPROGRESS;
88 open_callback_ = callback;
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;
97 int32_t VideoCaptureResource::StartCapture() {
98 if (open_state_ != OPENED)
99 return PP_ERROR_FAILED;
101 Post(RENDERER, PpapiHostMsg_VideoCapture_StartCapture());
102 return PP_OK;
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;
112 int32_t VideoCaptureResource::StopCapture() {
113 if (open_state_ != OPENED)
114 return PP_ERROR_FAILED;
116 Post(RENDERER, PpapiHostMsg_VideoCapture_StopCapture());
117 return PP_OK;
120 void VideoCaptureResource::Close() {
121 if (open_state_ == CLOSED)
122 return;
124 Post(RENDERER, PpapiHostMsg_VideoCapture_Close());
126 open_state_ = CLOSED;
128 if (TrackedCallback::IsPending(open_callback_))
129 open_callback_->PostAbort();
132 int32_t VideoCaptureResource::EnumerateDevicesSync(
133 const PP_ArrayOutput& devices) {
134 return enumeration_helper_.EnumerateDevicesSync(devices);
137 void VideoCaptureResource::LastPluginRefWasDeleted() {
138 enumeration_helper_.LastPluginRefWasDeleted();
141 void 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;
149 std::vector<base::SharedMemoryHandle> handles;
150 params.TakeAllSharedMemoryHandles(&handles);
151 CHECK(handles.size() == buffers.size());
153 PluginResourceTracker* tracker =
154 PluginGlobals::Get()->plugin_resource_tracker();
155 scoped_ptr<PP_Resource[]> resources(new PP_Resource[buffers.size()]);
156 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);
163 buffer_in_use_ = std::vector<bool>(buffers.size());
165 CallWhileUnlocked(ppp_video_capture_impl_->OnDeviceInfo,
166 pp_instance(),
167 pp_resource(),
168 &info,
169 buffers.size(),
170 resources.get());
172 for (size_t i = 0; i < buffers.size(); ++i)
173 tracker->ReleaseResource(resources[i]);
176 void 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;
186 if (ppp_video_capture_impl_) {
187 CallWhileUnlocked(ppp_video_capture_impl_->OnStatus,
188 pp_instance(),
189 pp_resource(),
190 status);
194 void 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);
206 void 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);
218 void VideoCaptureResource::OnPluginMsgOpenReply(
219 const ResourceMessageReplyParams& params) {
220 if (open_state_ == BEFORE_OPEN && params.result() == PP_OK)
221 open_state_ = OPENED;
223 // The callback may have been aborted by Close().
224 if (TrackedCallback::IsPending(open_callback_))
225 open_callback_->Run(params.result());
228 void VideoCaptureResource::SetBufferInUse(uint32_t buffer_index) {
229 CHECK(buffer_index < buffer_in_use_.size());
230 buffer_in_use_[buffer_index] = true;
233 } // namespace proxy
234 } // namespace ppapi