| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |