Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(820)

Side by Side Diff: ppapi/examples/video_capture/video_capture.cc

Issue 9234064: Implement device enumeration for PPB_VideoCapture_Dev. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Changes in response to Antoine's comments. Created 8 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <assert.h> 5 #include <assert.h>
6 #include <string.h> 6 #include <string.h>
7 7
8 #include <map> 8 #include <map>
9 #include <vector> 9 #include <vector>
10 10
11 #include "ppapi/c/pp_errors.h" 11 #include "ppapi/c/pp_errors.h"
12 #include "ppapi/c/ppb_opengles2.h" 12 #include "ppapi/c/ppb_opengles2.h"
13 #include "ppapi/cpp/dev/buffer_dev.h" 13 #include "ppapi/cpp/dev/buffer_dev.h"
14 #include "ppapi/cpp/dev/device_ref_dev.h"
14 #include "ppapi/cpp/dev/video_capture_dev.h" 15 #include "ppapi/cpp/dev/video_capture_dev.h"
15 #include "ppapi/cpp/dev/video_capture_client_dev.h" 16 #include "ppapi/cpp/dev/video_capture_client_dev.h"
16 #include "ppapi/cpp/completion_callback.h" 17 #include "ppapi/cpp/completion_callback.h"
17 #include "ppapi/cpp/graphics_3d_client.h" 18 #include "ppapi/cpp/graphics_3d_client.h"
18 #include "ppapi/cpp/graphics_3d.h" 19 #include "ppapi/cpp/graphics_3d.h"
19 #include "ppapi/cpp/instance.h" 20 #include "ppapi/cpp/instance.h"
20 #include "ppapi/cpp/module.h" 21 #include "ppapi/cpp/module.h"
21 #include "ppapi/cpp/rect.h" 22 #include "ppapi/cpp/rect.h"
23 #include "ppapi/cpp/var.h"
22 #include "ppapi/lib/gl/include/GLES2/gl2.h" 24 #include "ppapi/lib/gl/include/GLES2/gl2.h"
23 #include "ppapi/utility/completion_callback_factory.h" 25 #include "ppapi/utility/completion_callback_factory.h"
24 26
25 // Assert |context_| isn't holding any GL Errors. Done as a macro instead of a 27 // Assert |context_| isn't holding any GL Errors. Done as a macro instead of a
26 // function to preserve line number information in the failure message. 28 // function to preserve line number information in the failure message.
27 #define assertNoGLError() \ 29 #define assertNoGLError() \
28 assert(!gles2_if_->GetError(context_->pp_resource())); 30 assert(!gles2_if_->GetError(context_->pp_resource()));
29 31
30 namespace { 32 namespace {
31 33
(...skipping 10 matching lines...) Expand all
42 class VCDemoInstance : public pp::Instance, 44 class VCDemoInstance : public pp::Instance,
43 public pp::Graphics3DClient, 45 public pp::Graphics3DClient,
44 public pp::VideoCaptureClient_Dev { 46 public pp::VideoCaptureClient_Dev {
45 public: 47 public:
46 VCDemoInstance(PP_Instance instance, pp::Module* module); 48 VCDemoInstance(PP_Instance instance, pp::Module* module);
47 virtual ~VCDemoInstance(); 49 virtual ~VCDemoInstance();
48 50
49 // pp::Instance implementation (see PPP_Instance). 51 // pp::Instance implementation (see PPP_Instance).
50 virtual void DidChangeView(const pp::Rect& position, 52 virtual void DidChangeView(const pp::Rect& position,
51 const pp::Rect& clip_ignored); 53 const pp::Rect& clip_ignored);
54 virtual void HandleMessage(const pp::Var& message_data);
52 55
53 // pp::Graphics3DClient implementation. 56 // pp::Graphics3DClient implementation.
54 virtual void Graphics3DContextLost() { 57 virtual void Graphics3DContextLost() {
55 InitGL(); 58 InitGL();
56 CreateYUVTextures(); 59 CreateYUVTextures();
57 Render(); 60 Render();
58 } 61 }
59 62
60 virtual void OnDeviceInfo(PP_Resource resource, 63 virtual void OnDeviceInfo(PP_Resource resource,
61 const PP_VideoCaptureDeviceInfo_Dev& info, 64 const PP_VideoCaptureDeviceInfo_Dev& info,
62 const std::vector<pp::Buffer_Dev>& buffers) { 65 const std::vector<pp::Buffer_Dev>& buffers) {
63 capture_info_ = info; 66 capture_info_ = info;
64 buffers_ = buffers; 67 buffers_ = buffers;
65 CreateYUVTextures(); 68 CreateYUVTextures();
66 } 69 }
67 70
68 virtual void OnStatus(PP_Resource resource, uint32_t status) { 71 virtual void OnStatus(PP_Resource resource, uint32_t status) {
72 status_ = static_cast<PP_VideoCaptureStatus_Dev>(status);
73 if (status_ == PP_VIDEO_CAPTURE_STATUS_STOPPED)
74 StartCapture();
69 } 75 }
70 76
71 virtual void OnError(PP_Resource resource, uint32_t error) { 77 virtual void OnError(PP_Resource resource, uint32_t error) {
72 } 78 }
73 79
74 virtual void OnBufferReady(PP_Resource resource, uint32_t buffer) { 80 virtual void OnBufferReady(PP_Resource resource, uint32_t buffer) {
75 const char* data = static_cast<const char*>(buffers_[buffer].data()); 81 const char* data = static_cast<const char*>(buffers_[buffer].data());
76 int32_t width = capture_info_.width; 82 int32_t width = capture_info_.width;
77 int32_t height = capture_info_.height; 83 int32_t height = capture_info_.height;
78 gles2_if_->ActiveTexture(context_->pp_resource(), GL_TEXTURE0); 84 gles2_if_->ActiveTexture(context_->pp_resource(), GL_TEXTURE0);
(...skipping 21 matching lines...) Expand all
100 needs_paint_ = true; 106 needs_paint_ = true;
101 else 107 else
102 Render(); 108 Render();
103 } 109 }
104 110
105 private: 111 private:
106 void Render(); 112 void Render();
107 113
108 // GL-related functions. 114 // GL-related functions.
109 void InitGL(); 115 void InitGL();
110 void InitializeCapture();
111 GLuint CreateTexture(int32_t width, int32_t height, int unit); 116 GLuint CreateTexture(int32_t width, int32_t height, int unit);
112 void CreateGLObjects(); 117 void CreateGLObjects();
113 void CreateShader(GLuint program, GLenum type, const char* source, int size); 118 void CreateShader(GLuint program, GLenum type, const char* source, int size);
114 void PaintFinished(int32_t result); 119 void PaintFinished(int32_t result);
115 void CreateYUVTextures(); 120 void CreateYUVTextures();
116 121
122 void EnumerateDevicesFinished(int32_t result);
123 void StartCapture();
124
117 pp::Size position_size_; 125 pp::Size position_size_;
118 bool is_painting_; 126 bool is_painting_;
119 bool needs_paint_; 127 bool needs_paint_;
120 GLuint texture_y_; 128 GLuint texture_y_;
121 GLuint texture_u_; 129 GLuint texture_u_;
122 GLuint texture_v_; 130 GLuint texture_v_;
123 pp::VideoCapture_Dev video_capture_; 131 pp::VideoCapture_Dev video_capture_;
124 PP_VideoCaptureDeviceInfo_Dev capture_info_; 132 PP_VideoCaptureDeviceInfo_Dev capture_info_;
125 std::vector<pp::Buffer_Dev> buffers_; 133 std::vector<pp::Buffer_Dev> buffers_;
126 pp::CompletionCallbackFactory<VCDemoInstance> callback_factory_; 134 pp::CompletionCallbackFactory<VCDemoInstance> callback_factory_;
127 135
128 // Unowned pointers. 136 // Unowned pointers.
129 const struct PPB_OpenGLES2* gles2_if_; 137 const struct PPB_OpenGLES2* gles2_if_;
130 138
131 // Owned data. 139 // Owned data.
132 pp::Graphics3D* context_; 140 pp::Graphics3D* context_;
141
142 bool page_initialized_;
143 PP_VideoCaptureStatus_Dev status_;
144 std::vector<pp::DeviceRef_Dev> devices_;
145
146 // >= 0 means index of |devices_|;
147 // -1 means the default device;
148 // -2 means no pending request to start capture.
149 int pending_start_capture_device_;
133 }; 150 };
134 151
135 VCDemoInstance::VCDemoInstance(PP_Instance instance, pp::Module* module) 152 VCDemoInstance::VCDemoInstance(PP_Instance instance, pp::Module* module)
136 : pp::Instance(instance), 153 : pp::Instance(instance),
137 pp::Graphics3DClient(this), 154 pp::Graphics3DClient(this),
138 pp::VideoCaptureClient_Dev(this), 155 pp::VideoCaptureClient_Dev(this),
139 is_painting_(false), 156 is_painting_(false),
140 needs_paint_(false), 157 needs_paint_(false),
141 texture_y_(0), 158 texture_y_(0),
142 texture_u_(0), 159 texture_u_(0),
143 texture_v_(0), 160 texture_v_(0),
144 video_capture_(*this), 161 video_capture_(*this),
145 callback_factory_(this), 162 callback_factory_(this),
146 context_(NULL) { 163 context_(NULL),
164 page_initialized_(false),
165 status_(PP_VIDEO_CAPTURE_STATUS_STOPPED),
166 pending_start_capture_device_(-2) {
147 gles2_if_ = static_cast<const struct PPB_OpenGLES2*>( 167 gles2_if_ = static_cast<const struct PPB_OpenGLES2*>(
148 module->GetBrowserInterface(PPB_OPENGLES2_INTERFACE)); 168 module->GetBrowserInterface(PPB_OPENGLES2_INTERFACE));
149 assert(gles2_if_); 169 assert(gles2_if_);
150 InitializeCapture(); 170
171 capture_info_.width = 320;
172 capture_info_.height = 240;
173 capture_info_.frames_per_second = 30;
151 } 174 }
152 175
153 VCDemoInstance::~VCDemoInstance() { 176 VCDemoInstance::~VCDemoInstance() {
154 delete context_; 177 delete context_;
155 } 178 }
156 179
157 void VCDemoInstance::DidChangeView( 180 void VCDemoInstance::DidChangeView(
158 const pp::Rect& position, const pp::Rect& clip_ignored) { 181 const pp::Rect& position, const pp::Rect& clip_ignored) {
159 if (position.width() == 0 || position.height() == 0) 182 if (position.width() == 0 || position.height() == 0)
160 return; 183 return;
161 if (position.size() == position_size_) 184 if (position.size() == position_size_)
162 return; 185 return;
163 186
164 position_size_ = position.size(); 187 position_size_ = position.size();
165 188
166 // Initialize graphics. 189 // Initialize graphics.
167 InitGL(); 190 InitGL();
168 191
169 Render(); 192 Render();
170 } 193 }
171 194
172 void VCDemoInstance::InitializeCapture() { 195 void VCDemoInstance::HandleMessage(const pp::Var& message_data) {
173 capture_info_.width = 320; 196 if (message_data.is_string()) {
174 capture_info_.height = 240; 197 std::string event = message_data.AsString();
175 capture_info_.frames_per_second = 30; 198 if (event == "PageInitialized") {
176 199 pp::CompletionCallback callback = callback_factory_.NewCallback(
177 video_capture_.StartCapture(capture_info_, 4); 200 &VCDemoInstance::EnumerateDevicesFinished);
201 video_capture_.EnumerateDevices(callback);
202 } else if (event == "UseDefault") {
203 pending_start_capture_device_ = -1;
204 StartCapture();
205 }
206 } else if (message_data.is_number()) {
207 int index = message_data.AsInt();
208 if (index >= 0 && index < static_cast<int>(devices_.size())) {
209 pending_start_capture_device_= index;
210 StartCapture();
211 } else {
212 assert(false);
213 }
214 }
178 } 215 }
179 216
180 void VCDemoInstance::InitGL() { 217 void VCDemoInstance::InitGL() {
181 assert(position_size_.width() && position_size_.height()); 218 assert(position_size_.width() && position_size_.height());
182 is_painting_ = false; 219 is_painting_ = false;
183 220
184 delete context_; 221 delete context_;
185 int32_t attributes[] = { 222 int32_t attributes[] = {
186 PP_GRAPHICS3DATTRIB_ALPHA_SIZE, 0, 223 PP_GRAPHICS3DATTRIB_ALPHA_SIZE, 0,
187 PP_GRAPHICS3DATTRIB_BLUE_SIZE, 8, 224 PP_GRAPHICS3DATTRIB_BLUE_SIZE, 8,
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
357 int32_t width = capture_info_.width; 394 int32_t width = capture_info_.width;
358 int32_t height = capture_info_.height; 395 int32_t height = capture_info_.height;
359 texture_y_ = CreateTexture(width, height, 0); 396 texture_y_ = CreateTexture(width, height, 0);
360 397
361 width /= 2; 398 width /= 2;
362 height /= 2; 399 height /= 2;
363 texture_u_ = CreateTexture(width, height, 1); 400 texture_u_ = CreateTexture(width, height, 1);
364 texture_v_ = CreateTexture(width, height, 2); 401 texture_v_ = CreateTexture(width, height, 2);
365 } 402 }
366 403
404 void VCDemoInstance::EnumerateDevicesFinished(int32_t result) {
405 static const char* const kDelimiter = "#__#";
406
407 if (result == PP_OK) {
408 std::string device_names;
409 video_capture_.GetDevices(&devices_);
410 for (size_t index = 0; index < devices_.size(); ++index) {
411 pp::Var name = devices_[index].GetName();
412 assert(name.is_string());
413
414 if (index != 0)
415 device_names += kDelimiter;
416 device_names += name.AsString();
417 }
418 PostMessage(pp::Var(device_names));
419 } else {
420 PostMessage(pp::Var("EnumerationFailed"));
421 }
422 }
423
424 void VCDemoInstance::StartCapture() {
425 if (status_ != PP_VIDEO_CAPTURE_STATUS_STOPPED) {
426 video_capture_.StopCapture();
427 return;
428 }
429
430 if (pending_start_capture_device_ > -2 &&
431 pending_start_capture_device_ < static_cast<int>(devices_.size())) {
432 video_capture_.StartCapture(
433 pending_start_capture_device_ == -1 ?
434 pp::DeviceRef_Dev() : devices_[pending_start_capture_device_],
435 capture_info_, 4);
436 }
437 pending_start_capture_device_ = -2;
438 }
439
367 pp::Instance* VCDemoModule::CreateInstance(PP_Instance instance) { 440 pp::Instance* VCDemoModule::CreateInstance(PP_Instance instance) {
368 return new VCDemoInstance(instance, this); 441 return new VCDemoInstance(instance, this);
369 } 442 }
370 443
371 } // anonymous namespace 444 } // anonymous namespace
372 445
373 namespace pp { 446 namespace pp {
374 // Factory function for your specialization of the Module object. 447 // Factory function for your specialization of the Module object.
375 Module* CreateModule() { 448 Module* CreateModule() {
376 return new VCDemoModule(); 449 return new VCDemoModule();
377 } 450 }
378 } // namespace pp 451 } // namespace pp
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698