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

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

Issue 134643002: [PPAPI] Add media stream video track example (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix build issues Created 6 years, 11 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
« no previous file with comments | « no previous file | ppapi/examples/media_stream_video/media_stream_video.html » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2014 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 <stdlib.h>
6 #include <string.h>
7
8 #include <map>
9 #include <vector>
10
11 #include "ppapi/c/dev/ppb_video_capture_dev.h"
12 #include "ppapi/c/pp_errors.h" 5 #include "ppapi/c/pp_errors.h"
13 #include "ppapi/c/ppb_opengles2.h" 6 #include "ppapi/c/ppb_opengles2.h"
14 #include "ppapi/cpp/dev/buffer_dev.h"
15 #include "ppapi/cpp/dev/device_ref_dev.h"
16 #include "ppapi/cpp/dev/video_capture_dev.h"
17 #include "ppapi/cpp/dev/video_capture_client_dev.h"
18 #include "ppapi/cpp/completion_callback.h" 7 #include "ppapi/cpp/completion_callback.h"
8 #include "ppapi/cpp/dev/var_resource_dev.h"
9 #include "ppapi/cpp/graphics_3d.h"
19 #include "ppapi/cpp/graphics_3d_client.h" 10 #include "ppapi/cpp/graphics_3d_client.h"
20 #include "ppapi/cpp/graphics_3d.h"
21 #include "ppapi/cpp/instance.h" 11 #include "ppapi/cpp/instance.h"
12 #include "ppapi/cpp/media_stream_video_track.h"
22 #include "ppapi/cpp/module.h" 13 #include "ppapi/cpp/module.h"
23 #include "ppapi/cpp/rect.h" 14 #include "ppapi/cpp/rect.h"
24 #include "ppapi/cpp/var.h" 15 #include "ppapi/cpp/var.h"
16 #include "ppapi/cpp/video_frame.h"
25 #include "ppapi/lib/gl/include/GLES2/gl2.h" 17 #include "ppapi/lib/gl/include/GLES2/gl2.h"
26 #include "ppapi/utility/completion_callback_factory.h" 18 #include "ppapi/utility/completion_callback_factory.h"
27 19
28 // When compiling natively on Windows, PostMessage can be #define-d to 20 // When compiling natively on Windows, PostMessage can be #define-d to
29 // something else. 21 // something else.
30 #ifdef PostMessage 22 #ifdef PostMessage
31 #undef PostMessage 23 #undef PostMessage
32 #endif 24 #endif
33 25
34 // Assert |context_| isn't holding any GL Errors. Done as a macro instead of a 26 // Assert |context_| isn't holding any GL Errors. Done as a macro instead of a
35 // function to preserve line number information in the failure message. 27 // function to preserve line number information in the failure message.
36 #define AssertNoGLError() \ 28 #define AssertNoGLError() \
37 PP_DCHECK(!gles2_if_->GetError(context_->pp_resource())); 29 PP_DCHECK(!gles2_if_->GetError(context_->pp_resource()));
38 30
39 namespace { 31 namespace {
40 32
41 const char* const kDelimiter = "#__#";
42
43 // This object is the global object representing this plugin library as long 33 // This object is the global object representing this plugin library as long
44 // as it is loaded. 34 // as it is loaded.
45 class VCDemoModule : public pp::Module { 35 class MediaStreamVideoModule : public pp::Module {
46 public: 36 public:
47 VCDemoModule() : pp::Module() {} 37 MediaStreamVideoModule() : pp::Module() {}
48 virtual ~VCDemoModule() {} 38 virtual ~MediaStreamVideoModule() {}
49 39
50 virtual pp::Instance* CreateInstance(PP_Instance instance); 40 virtual pp::Instance* CreateInstance(PP_Instance instance);
51 }; 41 };
52 42
53 class VCDemoInstance : public pp::Instance, 43 class MediaStreamVideoDemoInstance : public pp::Instance,
54 public pp::Graphics3DClient, 44 public pp::Graphics3DClient {
55 public pp::VideoCaptureClient_Dev {
56 public: 45 public:
57 VCDemoInstance(PP_Instance instance, pp::Module* module); 46 MediaStreamVideoDemoInstance(PP_Instance instance, pp::Module* module);
58 virtual ~VCDemoInstance(); 47 virtual ~MediaStreamVideoDemoInstance();
59 48
60 // pp::Instance implementation (see PPP_Instance). 49 // pp::Instance implementation (see PPP_Instance).
61 virtual void DidChangeView(const pp::Rect& position, 50 virtual void DidChangeView(const pp::Rect& position,
62 const pp::Rect& clip_ignored); 51 const pp::Rect& clip_ignored);
63 virtual void HandleMessage(const pp::Var& message_data); 52 virtual void HandleMessage(const pp::Var& message_data);
64 53
65 // pp::Graphics3DClient implementation. 54 // pp::Graphics3DClient implementation.
66 virtual void Graphics3DContextLost() { 55 virtual void Graphics3DContextLost() {
67 InitGL(); 56 InitGL();
68 CreateYUVTextures(); 57 CreateYUVTextures();
69 Render(); 58 Render();
70 } 59 }
71 60
72 virtual void OnDeviceInfo(PP_Resource resource,
73 const PP_VideoCaptureDeviceInfo_Dev& info,
74 const std::vector<pp::Buffer_Dev>& buffers) {
75 capture_info_ = info;
76 buffers_ = buffers;
77 CreateYUVTextures();
78 }
79
80 virtual void OnStatus(PP_Resource resource, uint32_t status) {
81 }
82
83 virtual void OnError(PP_Resource resource, uint32_t error) {
84 }
85
86 virtual void OnBufferReady(PP_Resource resource, uint32_t buffer) {
87 const char* data = static_cast<const char*>(buffers_[buffer].data());
88 int32_t width = capture_info_.width;
89 int32_t height = capture_info_.height;
90 gles2_if_->ActiveTexture(context_->pp_resource(), GL_TEXTURE0);
91 gles2_if_->TexSubImage2D(
92 context_->pp_resource(), GL_TEXTURE_2D, 0, 0, 0, width, height,
93 GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
94
95 data += width * height;
96 width /= 2;
97 height /= 2;
98
99 gles2_if_->ActiveTexture(context_->pp_resource(), GL_TEXTURE1);
100 gles2_if_->TexSubImage2D(
101 context_->pp_resource(), GL_TEXTURE_2D, 0, 0, 0, width, height,
102 GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
103
104 data += width * height;
105 gles2_if_->ActiveTexture(context_->pp_resource(), GL_TEXTURE2);
106 gles2_if_->TexSubImage2D(
107 context_->pp_resource(), GL_TEXTURE_2D, 0, 0, 0, width, height,
108 GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
109
110 video_capture_.ReuseBuffer(buffer);
111 if (is_painting_)
112 needs_paint_ = true;
113 else
114 Render();
115 }
116
117 private: 61 private:
118 void Render(); 62 void Render();
119 63
120 // GL-related functions. 64 // GL-related functions.
121 void InitGL(); 65 void InitGL();
122 GLuint CreateTexture(int32_t width, int32_t height, int unit); 66 GLuint CreateTexture(int32_t width, int32_t height, int unit);
123 void CreateGLObjects(); 67 void CreateGLObjects();
124 void CreateShader(GLuint program, GLenum type, const char* source, int size); 68 void CreateShader(GLuint program, GLenum type, const char* source, int size);
125 void PaintFinished(int32_t result); 69 void PaintFinished(int32_t result);
126 void CreateYUVTextures(); 70 void CreateYUVTextures();
127 71
128 void Open(const pp::DeviceRef_Dev& device); 72 // Callback that is invoked when new frames are recevied.
129 void Stop(); 73 void OnGetFrame(int32_t result, pp::VideoFrame frame);
130 void Start();
131 void EnumerateDevicesFinished(int32_t result,
132 std::vector<pp::DeviceRef_Dev>& devices);
133 void OpenFinished(int32_t result);
134
135 static void MonitorDeviceChangeCallback(void* user_data,
136 uint32_t device_count,
137 const PP_Resource devices[]);
138 74
139 pp::Size position_size_; 75 pp::Size position_size_;
140 bool is_painting_; 76 bool is_painting_;
141 bool needs_paint_; 77 bool needs_paint_;
142 GLuint texture_y_; 78 GLuint texture_y_;
143 GLuint texture_u_; 79 GLuint texture_u_;
144 GLuint texture_v_; 80 GLuint texture_v_;
145 pp::VideoCapture_Dev video_capture_; 81 pp::MediaStreamVideoTrack video_track_;
146 PP_VideoCaptureDeviceInfo_Dev capture_info_; 82 pp::CompletionCallbackFactory<MediaStreamVideoDemoInstance> callback_factory_;
147 std::vector<pp::Buffer_Dev> buffers_;
148 pp::CompletionCallbackFactory<VCDemoInstance> callback_factory_;
149 83
150 // Unowned pointers. 84 // Unowned pointers.
151 const struct PPB_OpenGLES2* gles2_if_; 85 const struct PPB_OpenGLES2* gles2_if_;
152 86
153 // Owned data. 87 // Owned data.
154 pp::Graphics3D* context_; 88 pp::Graphics3D* context_;
155 89
156 std::vector<pp::DeviceRef_Dev> enumerate_devices_; 90 pp::Size frame_size_;
157 std::vector<pp::DeviceRef_Dev> monitor_devices_;
158 }; 91 };
159 92
160 VCDemoInstance::VCDemoInstance(PP_Instance instance, pp::Module* module) 93 MediaStreamVideoDemoInstance::MediaStreamVideoDemoInstance(
94 PP_Instance instance, pp::Module* module)
161 : pp::Instance(instance), 95 : pp::Instance(instance),
162 pp::Graphics3DClient(this), 96 pp::Graphics3DClient(this),
163 pp::VideoCaptureClient_Dev(this),
164 is_painting_(false), 97 is_painting_(false),
165 needs_paint_(false), 98 needs_paint_(false),
166 texture_y_(0), 99 texture_y_(0),
167 texture_u_(0), 100 texture_u_(0),
168 texture_v_(0), 101 texture_v_(0),
169 video_capture_(this),
170 callback_factory_(this), 102 callback_factory_(this),
171 context_(NULL) { 103 context_(NULL) {
172 gles2_if_ = static_cast<const struct PPB_OpenGLES2*>( 104 gles2_if_ = static_cast<const struct PPB_OpenGLES2*>(
173 module->GetBrowserInterface(PPB_OPENGLES2_INTERFACE)); 105 module->GetBrowserInterface(PPB_OPENGLES2_INTERFACE));
174 PP_DCHECK(gles2_if_); 106 PP_DCHECK(gles2_if_);
175
176 capture_info_.width = 320;
177 capture_info_.height = 240;
178 capture_info_.frames_per_second = 30;
179 } 107 }
180 108
181 VCDemoInstance::~VCDemoInstance() { 109 MediaStreamVideoDemoInstance::~MediaStreamVideoDemoInstance() {
182 video_capture_.MonitorDeviceChange(NULL, NULL);
183 delete context_; 110 delete context_;
184 } 111 }
185 112
186 void VCDemoInstance::DidChangeView( 113 void MediaStreamVideoDemoInstance::DidChangeView(
187 const pp::Rect& position, const pp::Rect& clip_ignored) { 114 const pp::Rect& position, const pp::Rect& clip_ignored) {
188 if (position.width() == 0 || position.height() == 0) 115 if (position.width() == 0 || position.height() == 0)
189 return; 116 return;
190 if (position.size() == position_size_) 117 if (position.size() == position_size_)
191 return; 118 return;
192 119
193 position_size_ = position.size(); 120 position_size_ = position.size();
194 121
195 // Initialize graphics. 122 // Initialize graphics.
196 InitGL(); 123 InitGL();
197
198 Render(); 124 Render();
199 } 125 }
200 126
201 void VCDemoInstance::HandleMessage(const pp::Var& message_data) { 127 void MediaStreamVideoDemoInstance::HandleMessage(const pp::Var& var_message) {
202 if (message_data.is_string()) { 128 if (!var_message.is_dictionary())
203 std::string event = message_data.AsString(); 129 return;
204 if (event == "PageInitialized") { 130 pp::VarDictionary var_dictionary_message(var_message);
205 int32_t result = video_capture_.MonitorDeviceChange( 131 pp::Var var_track = var_dictionary_message.Get("track");
206 &VCDemoInstance::MonitorDeviceChangeCallback, this); 132 if (!var_track.is_resource())
207 if (result != PP_OK) 133 return;
208 PostMessage(pp::Var("MonitorDeviceChangeFailed"));
209 134
210 pp::CompletionCallbackWithOutput<std::vector<pp::DeviceRef_Dev> > 135 pp::Resource resource_track = pp::VarResource_Dev(var_track).AsResource();
211 callback = callback_factory_.NewCallbackWithOutput( 136
212 &VCDemoInstance::EnumerateDevicesFinished); 137 video_track_ = pp::MediaStreamVideoTrack(resource_track);
213 result = video_capture_.EnumerateDevices(callback); 138
214 if (result != PP_OK_COMPLETIONPENDING) 139 video_track_.GetFrame(callback_factory_.NewCallbackWithOutput(
215 PostMessage(pp::Var("EnumerationFailed")); 140 &MediaStreamVideoDemoInstance::OnGetFrame));
216 } else if (event == "UseDefault") {
217 Open(pp::DeviceRef_Dev());
218 } else if (event == "Stop") {
219 Stop();
220 } else if (event == "Start") {
221 Start();
222 } else if (event.find("Monitor:") == 0) {
223 std::string index_str = event.substr(strlen("Monitor:"));
224 int index = atoi(index_str.c_str());
225 if (index >= 0 && index < static_cast<int>(monitor_devices_.size()))
226 Open(monitor_devices_[index]);
227 else
228 PP_NOTREACHED();
229 } else if (event.find("Enumerate:") == 0) {
230 std::string index_str = event.substr(strlen("Enumerate:"));
231 int index = atoi(index_str.c_str());
232 if (index >= 0 && index < static_cast<int>(enumerate_devices_.size()))
233 Open(enumerate_devices_[index]);
234 else
235 PP_NOTREACHED();
236 }
237 }
238 } 141 }
239 142
240 void VCDemoInstance::InitGL() { 143 void MediaStreamVideoDemoInstance::InitGL() {
241 PP_DCHECK(position_size_.width() && position_size_.height()); 144 PP_DCHECK(position_size_.width() && position_size_.height());
242 is_painting_ = false; 145 is_painting_ = false;
243 146
244 delete context_; 147 delete context_;
245 int32_t attributes[] = { 148 int32_t attributes[] = {
246 PP_GRAPHICS3DATTRIB_ALPHA_SIZE, 0, 149 PP_GRAPHICS3DATTRIB_ALPHA_SIZE, 0,
247 PP_GRAPHICS3DATTRIB_BLUE_SIZE, 8, 150 PP_GRAPHICS3DATTRIB_BLUE_SIZE, 8,
248 PP_GRAPHICS3DATTRIB_GREEN_SIZE, 8, 151 PP_GRAPHICS3DATTRIB_GREEN_SIZE, 8,
249 PP_GRAPHICS3DATTRIB_RED_SIZE, 8, 152 PP_GRAPHICS3DATTRIB_RED_SIZE, 8,
250 PP_GRAPHICS3DATTRIB_DEPTH_SIZE, 0, 153 PP_GRAPHICS3DATTRIB_DEPTH_SIZE, 0,
(...skipping 12 matching lines...) Expand all
263 gles2_if_->Clear(context_->pp_resource(), GL_COLOR_BUFFER_BIT); 166 gles2_if_->Clear(context_->pp_resource(), GL_COLOR_BUFFER_BIT);
264 gles2_if_->Viewport(context_->pp_resource(), 0, 0, 167 gles2_if_->Viewport(context_->pp_resource(), 0, 0,
265 position_size_.width(), position_size_.height()); 168 position_size_.width(), position_size_.height());
266 169
267 BindGraphics(*context_); 170 BindGraphics(*context_);
268 AssertNoGLError(); 171 AssertNoGLError();
269 172
270 CreateGLObjects(); 173 CreateGLObjects();
271 } 174 }
272 175
273 void VCDemoInstance::Render() { 176 void MediaStreamVideoDemoInstance::Render() {
274 PP_DCHECK(!is_painting_); 177 PP_DCHECK(!is_painting_);
275 is_painting_ = true; 178 is_painting_ = true;
276 needs_paint_ = false; 179 needs_paint_ = false;
277 if (texture_y_) { 180 if (texture_y_) {
278 gles2_if_->DrawArrays(context_->pp_resource(), GL_TRIANGLE_STRIP, 0, 4); 181 gles2_if_->DrawArrays(context_->pp_resource(), GL_TRIANGLE_STRIP, 0, 4);
279 } else { 182 } else {
280 gles2_if_->Clear(context_->pp_resource(), GL_COLOR_BUFFER_BIT); 183 gles2_if_->Clear(context_->pp_resource(), GL_COLOR_BUFFER_BIT);
281 } 184 }
282 pp::CompletionCallback cb = callback_factory_.NewCallback( 185 pp::CompletionCallback cb = callback_factory_.NewCallback(
283 &VCDemoInstance::PaintFinished); 186 &MediaStreamVideoDemoInstance::PaintFinished);
284 context_->SwapBuffers(cb); 187 context_->SwapBuffers(cb);
285 } 188 }
286 189
287 void VCDemoInstance::PaintFinished(int32_t result) { 190 void MediaStreamVideoDemoInstance::PaintFinished(int32_t result) {
288 is_painting_ = false; 191 is_painting_ = false;
289 if (needs_paint_) 192 if (needs_paint_)
290 Render(); 193 Render();
291 } 194 }
292 195
293 GLuint VCDemoInstance::CreateTexture(int32_t width, int32_t height, int unit) { 196 GLuint MediaStreamVideoDemoInstance::CreateTexture(
197 int32_t width, int32_t height, int unit) {
294 GLuint texture_id; 198 GLuint texture_id;
295 gles2_if_->GenTextures(context_->pp_resource(), 1, &texture_id); 199 gles2_if_->GenTextures(context_->pp_resource(), 1, &texture_id);
296 AssertNoGLError(); 200 AssertNoGLError();
297 // Assign parameters. 201 // Assign parameters.
298 gles2_if_->ActiveTexture(context_->pp_resource(), GL_TEXTURE0 + unit); 202 gles2_if_->ActiveTexture(context_->pp_resource(), GL_TEXTURE0 + unit);
299 gles2_if_->BindTexture(context_->pp_resource(), GL_TEXTURE_2D, texture_id); 203 gles2_if_->BindTexture(context_->pp_resource(), GL_TEXTURE_2D, texture_id);
300 gles2_if_->TexParameteri( 204 gles2_if_->TexParameteri(
301 context_->pp_resource(), GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, 205 context_->pp_resource(), GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
302 GL_NEAREST); 206 GL_NEAREST);
303 gles2_if_->TexParameteri( 207 gles2_if_->TexParameteri(
304 context_->pp_resource(), GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, 208 context_->pp_resource(), GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
305 GL_NEAREST); 209 GL_NEAREST);
306 gles2_if_->TexParameterf( 210 gles2_if_->TexParameterf(
307 context_->pp_resource(), GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, 211 context_->pp_resource(), GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
308 GL_CLAMP_TO_EDGE); 212 GL_CLAMP_TO_EDGE);
309 gles2_if_->TexParameterf( 213 gles2_if_->TexParameterf(
310 context_->pp_resource(), GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, 214 context_->pp_resource(), GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
311 GL_CLAMP_TO_EDGE); 215 GL_CLAMP_TO_EDGE);
312 216
313 // Allocate texture. 217 // Allocate texture.
314 gles2_if_->TexImage2D( 218 gles2_if_->TexImage2D(
315 context_->pp_resource(), GL_TEXTURE_2D, 0, GL_LUMINANCE, width, height, 0, 219 context_->pp_resource(), GL_TEXTURE_2D, 0, GL_LUMINANCE, width, height, 0,
316 GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL); 220 GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);
317 AssertNoGLError(); 221 AssertNoGLError();
318 return texture_id; 222 return texture_id;
319 } 223 }
320 224
321 void VCDemoInstance::CreateGLObjects() { 225 void MediaStreamVideoDemoInstance::CreateGLObjects() {
322 // Code and constants for shader. 226 // Code and constants for shader.
323 static const char kVertexShader[] = 227 static const char kVertexShader[] =
324 "varying vec2 v_texCoord; \n" 228 "varying vec2 v_texCoord; \n"
325 "attribute vec4 a_position; \n" 229 "attribute vec4 a_position; \n"
326 "attribute vec2 a_texCoord; \n" 230 "attribute vec2 a_texCoord; \n"
327 "void main() \n" 231 "void main() \n"
328 "{ \n" 232 "{ \n"
329 " v_texCoord = a_texCoord; \n" 233 " v_texCoord = a_texCoord; \n"
330 " gl_Position = a_position; \n" 234 " gl_Position = a_position; \n"
331 "}"; 235 "}";
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
396 gles2_if_->EnableVertexAttribArray(context, pos_location); 300 gles2_if_->EnableVertexAttribArray(context, pos_location);
397 gles2_if_->VertexAttribPointer(context, pos_location, 2, 301 gles2_if_->VertexAttribPointer(context, pos_location, 2,
398 GL_FLOAT, GL_FALSE, 0, 0); 302 GL_FLOAT, GL_FALSE, 0, 0);
399 gles2_if_->EnableVertexAttribArray(context, tc_location); 303 gles2_if_->EnableVertexAttribArray(context, tc_location);
400 gles2_if_->VertexAttribPointer( 304 gles2_if_->VertexAttribPointer(
401 context, tc_location, 2, GL_FLOAT, GL_FALSE, 0, 305 context, tc_location, 2, GL_FLOAT, GL_FALSE, 0,
402 static_cast<float*>(0) + 8); // Skip position coordinates. 306 static_cast<float*>(0) + 8); // Skip position coordinates.
403 AssertNoGLError(); 307 AssertNoGLError();
404 } 308 }
405 309
406 void VCDemoInstance::CreateShader( 310 void MediaStreamVideoDemoInstance::CreateShader(
407 GLuint program, GLenum type, const char* source, int size) { 311 GLuint program, GLenum type, const char* source, int size) {
408 PP_Resource context = context_->pp_resource(); 312 PP_Resource context = context_->pp_resource();
409 GLuint shader = gles2_if_->CreateShader(context, type); 313 GLuint shader = gles2_if_->CreateShader(context, type);
410 gles2_if_->ShaderSource(context, shader, 1, &source, &size); 314 gles2_if_->ShaderSource(context, shader, 1, &source, &size);
411 gles2_if_->CompileShader(context, shader); 315 gles2_if_->CompileShader(context, shader);
412 gles2_if_->AttachShader(context, program, shader); 316 gles2_if_->AttachShader(context, program, shader);
413 gles2_if_->DeleteShader(context, shader); 317 gles2_if_->DeleteShader(context, shader);
414 } 318 }
415 319
416 void VCDemoInstance::CreateYUVTextures() { 320 void MediaStreamVideoDemoInstance::CreateYUVTextures() {
417 int32_t width = capture_info_.width; 321 int32_t width = frame_size_.width();
418 int32_t height = capture_info_.height; 322 int32_t height = frame_size_.height();
323 if (width == 0 || height == 0)
324 return;
325 if (texture_y_)
326 gles2_if_->DeleteTextures(context_->pp_resource(), 1, &texture_y_);
327 if (texture_u_)
328 gles2_if_->DeleteTextures(context_->pp_resource(), 1, &texture_u_);
329 if (texture_v_)
330 gles2_if_->DeleteTextures(context_->pp_resource(), 1, &texture_v_);
419 texture_y_ = CreateTexture(width, height, 0); 331 texture_y_ = CreateTexture(width, height, 0);
420 332
421 width /= 2; 333 width /= 2;
422 height /= 2; 334 height /= 2;
423 texture_u_ = CreateTexture(width, height, 1); 335 texture_u_ = CreateTexture(width, height, 1);
424 texture_v_ = CreateTexture(width, height, 2); 336 texture_v_ = CreateTexture(width, height, 2);
425 } 337 }
426 338
427 void VCDemoInstance::Open(const pp::DeviceRef_Dev& device) { 339 void MediaStreamVideoDemoInstance::OnGetFrame(
428 pp::CompletionCallback callback = callback_factory_.NewCallback( 340 int32_t result, pp::VideoFrame frame) {
429 &VCDemoInstance::OpenFinished); 341 if (result != PP_OK)
430 int32_t result = video_capture_.Open(device, capture_info_, 4, callback); 342 return;
431 if (result != PP_OK_COMPLETIONPENDING) 343 const char* data = static_cast<const char*>(frame.GetDataBuffer());
432 PostMessage(pp::Var("OpenFailed")); 344 pp::Size size;
345 PP_DCHECK(frame.GetSize(&size));
346 if (size != frame_size_) {
347 frame_size_ = size;
348 CreateYUVTextures();
349 }
350
351 int32_t width = frame_size_.width();
352 int32_t height = frame_size_.height();
353 gles2_if_->ActiveTexture(context_->pp_resource(), GL_TEXTURE0);
354 gles2_if_->TexSubImage2D(
355 context_->pp_resource(), GL_TEXTURE_2D, 0, 0, 0, width, height,
356 GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
357
358 data += width * height;
359 width /= 2;
360 height /= 2;
361
362 gles2_if_->ActiveTexture(context_->pp_resource(), GL_TEXTURE1);
363 gles2_if_->TexSubImage2D(
364 context_->pp_resource(), GL_TEXTURE_2D, 0, 0, 0, width, height,
365 GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
366
367 data += width * height;
368 gles2_if_->ActiveTexture(context_->pp_resource(), GL_TEXTURE2);
369 gles2_if_->TexSubImage2D(
370 context_->pp_resource(), GL_TEXTURE_2D, 0, 0, 0, width, height,
371 GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
372
373 if (is_painting_)
374 needs_paint_ = true;
375 else
376 Render();
377
378 video_track_.RecycleFrame(frame);
379 video_track_.GetFrame(callback_factory_.NewCallbackWithOutput(
380 &MediaStreamVideoDemoInstance::OnGetFrame));
433 } 381 }
434 382
435 void VCDemoInstance::Stop() { 383 pp::Instance* MediaStreamVideoModule::CreateInstance(PP_Instance instance) {
436 if (video_capture_.StopCapture() != PP_OK) 384 return new MediaStreamVideoDemoInstance(instance, this);
437 PostMessage(pp::Var("StopFailed"));
438 }
439
440 void VCDemoInstance::Start() {
441 if (video_capture_.StartCapture() != PP_OK)
442 PostMessage(pp::Var("StartFailed"));
443 }
444
445 void VCDemoInstance::EnumerateDevicesFinished(
446 int32_t result,
447 std::vector<pp::DeviceRef_Dev>& devices) {
448 if (result == PP_OK) {
449 enumerate_devices_.swap(devices);
450 std::string device_names = "Enumerate:";
451 for (size_t index = 0; index < enumerate_devices_.size(); ++index) {
452 pp::Var name = enumerate_devices_[index].GetName();
453 PP_DCHECK(name.is_string());
454
455 if (index != 0)
456 device_names += kDelimiter;
457 device_names += name.AsString();
458 }
459 PostMessage(pp::Var(device_names));
460 } else {
461 PostMessage(pp::Var("EnumerationFailed"));
462 }
463 }
464
465 void VCDemoInstance::OpenFinished(int32_t result) {
466 if (result == PP_OK)
467 Start();
468 else
469 PostMessage(pp::Var("OpenFailed"));
470 }
471
472 // static
473 void VCDemoInstance::MonitorDeviceChangeCallback(void* user_data,
474 uint32_t device_count,
475 const PP_Resource devices[]) {
476 VCDemoInstance* thiz = static_cast<VCDemoInstance*>(user_data);
477
478 std::string device_names = "Monitor:";
479 thiz->monitor_devices_.clear();
480 thiz->monitor_devices_.reserve(device_count);
481 for (size_t index = 0; index < device_count; ++index) {
482 thiz->monitor_devices_.push_back(pp::DeviceRef_Dev(devices[index]));
483 pp::Var name = thiz->monitor_devices_.back().GetName();
484 PP_DCHECK(name.is_string());
485
486 if (index != 0)
487 device_names += kDelimiter;
488 device_names += name.AsString();
489 }
490 thiz->PostMessage(pp::Var(device_names));
491 }
492
493 pp::Instance* VCDemoModule::CreateInstance(PP_Instance instance) {
494 return new VCDemoInstance(instance, this);
495 } 385 }
496 386
497 } // anonymous namespace 387 } // anonymous namespace
498 388
499 namespace pp { 389 namespace pp {
500 // Factory function for your specialization of the Module object. 390 // Factory function for your specialization of the Module object.
501 Module* CreateModule() { 391 Module* CreateModule() {
502 return new VCDemoModule(); 392 return new MediaStreamVideoModule();
503 } 393 }
504 } // namespace pp 394 } // namespace pp
OLDNEW
« no previous file with comments | « no previous file | ppapi/examples/media_stream_video/media_stream_video.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698