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

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

Issue 150403006: [PPAPI][MediaStream] Support configure for video input. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix build errors Created 6 years, 9 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 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 <vector>
6
5 #include "ppapi/c/pp_errors.h" 7 #include "ppapi/c/pp_errors.h"
6 #include "ppapi/c/ppb_opengles2.h" 8 #include "ppapi/c/ppb_opengles2.h"
7 #include "ppapi/cpp/completion_callback.h" 9 #include "ppapi/cpp/completion_callback.h"
8 #include "ppapi/cpp/graphics_3d.h" 10 #include "ppapi/cpp/graphics_3d.h"
9 #include "ppapi/cpp/graphics_3d_client.h" 11 #include "ppapi/cpp/graphics_3d_client.h"
10 #include "ppapi/cpp/instance.h" 12 #include "ppapi/cpp/instance.h"
11 #include "ppapi/cpp/media_stream_video_track.h" 13 #include "ppapi/cpp/media_stream_video_track.h"
12 #include "ppapi/cpp/module.h" 14 #include "ppapi/cpp/module.h"
13 #include "ppapi/cpp/rect.h" 15 #include "ppapi/cpp/rect.h"
14 #include "ppapi/cpp/var.h" 16 #include "ppapi/cpp/var.h"
15 #include "ppapi/cpp/video_frame.h" 17 #include "ppapi/cpp/video_frame.h"
16 #include "ppapi/lib/gl/include/GLES2/gl2.h" 18 #include "ppapi/lib/gl/include/GLES2/gl2.h"
19 #include "ppapi/lib/gl/include/GLES2/gl2ext.h"
17 #include "ppapi/utility/completion_callback_factory.h" 20 #include "ppapi/utility/completion_callback_factory.h"
18 21
19 // When compiling natively on Windows, PostMessage can be #define-d to 22 // When compiling natively on Windows, PostMessage can be #define-d to
20 // something else. 23 // something else.
21 #ifdef PostMessage 24 #ifdef PostMessage
22 #undef PostMessage 25 #undef PostMessage
23 #endif 26 #endif
24 27
25 // Assert |context_| isn't holding any GL Errors. Done as a macro instead of a 28 // 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. 29 // function to preserve line number information in the failure message.
(...skipping 19 matching lines...) Expand all
46 virtual ~MediaStreamVideoDemoInstance(); 49 virtual ~MediaStreamVideoDemoInstance();
47 50
48 // pp::Instance implementation (see PPP_Instance). 51 // pp::Instance implementation (see PPP_Instance).
49 virtual void DidChangeView(const pp::Rect& position, 52 virtual void DidChangeView(const pp::Rect& position,
50 const pp::Rect& clip_ignored); 53 const pp::Rect& clip_ignored);
51 virtual void HandleMessage(const pp::Var& message_data); 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 CreateTextures();
57 Render(); 60 Render();
58 } 61 }
59 62
60 private: 63 private:
64 void DrawYUV();
65 void DrawRGB();
61 void Render(); 66 void Render();
62 67
63 // GL-related functions. 68 // GL-related functions.
64 void InitGL(); 69 void InitGL();
65 GLuint CreateTexture(int32_t width, int32_t height, int unit); 70 GLuint CreateTexture(int32_t width, int32_t height, int unit, bool rgba);
66 void CreateGLObjects(); 71 void CreateGLObjects();
67 void CreateShader(GLuint program, GLenum type, const char* source, int size); 72 void CreateShader(GLuint program, GLenum type, const char* source, int size);
68 void PaintFinished(int32_t result); 73 void PaintFinished(int32_t result);
69 void CreateYUVTextures(); 74 void CreateTextures();
75 void ConfigureTrack();
70 76
71 // Callback that is invoked when new frames are recevied. 77
78 // MediaStreamVideoTrack callbacks.
79 void OnConfigure(int32_t result);
72 void OnGetFrame(int32_t result, pp::VideoFrame frame); 80 void OnGetFrame(int32_t result, pp::VideoFrame frame);
73 81
74 pp::Size position_size_; 82 pp::Size position_size_;
75 bool is_painting_; 83 bool is_painting_;
76 bool needs_paint_; 84 bool needs_paint_;
85 bool is_bgra_;
86 GLuint program_yuv_;
87 GLuint program_rgb_;
88 GLuint buffer_;
77 GLuint texture_y_; 89 GLuint texture_y_;
78 GLuint texture_u_; 90 GLuint texture_u_;
79 GLuint texture_v_; 91 GLuint texture_v_;
92 GLuint texture_rgb_;
80 pp::MediaStreamVideoTrack video_track_; 93 pp::MediaStreamVideoTrack video_track_;
81 pp::CompletionCallbackFactory<MediaStreamVideoDemoInstance> callback_factory_; 94 pp::CompletionCallbackFactory<MediaStreamVideoDemoInstance> callback_factory_;
95 std::vector<int32_t> attrib_list_;
96
97 // MediaStreamVideoTrack attributes:
98 bool need_config_;
99 PP_VideoFrame_Format attrib_format_;
100 int32_t attrib_width_;
101 int32_t attrib_height_;
82 102
83 // Unowned pointers. 103 // Unowned pointers.
84 const struct PPB_OpenGLES2* gles2_if_; 104 const struct PPB_OpenGLES2* gles2_if_;
85 105
86 // Owned data. 106 // Owned data.
87 pp::Graphics3D* context_; 107 pp::Graphics3D* context_;
88 108
89 pp::Size frame_size_; 109 pp::Size frame_size_;
90 }; 110 };
91 111
92 MediaStreamVideoDemoInstance::MediaStreamVideoDemoInstance( 112 MediaStreamVideoDemoInstance::MediaStreamVideoDemoInstance(
93 PP_Instance instance, pp::Module* module) 113 PP_Instance instance, pp::Module* module)
94 : pp::Instance(instance), 114 : pp::Instance(instance),
95 pp::Graphics3DClient(this), 115 pp::Graphics3DClient(this),
96 is_painting_(false), 116 is_painting_(false),
97 needs_paint_(false), 117 needs_paint_(false),
118 is_bgra_(false),
98 texture_y_(0), 119 texture_y_(0),
99 texture_u_(0), 120 texture_u_(0),
100 texture_v_(0), 121 texture_v_(0),
122 texture_rgb_(0),
101 callback_factory_(this), 123 callback_factory_(this),
124 need_config_(false),
125 attrib_format_(PP_VIDEOFRAME_FORMAT_I420),
126 attrib_width_(0),
127 attrib_height_(0),
102 context_(NULL) { 128 context_(NULL) {
103 gles2_if_ = static_cast<const struct PPB_OpenGLES2*>( 129 gles2_if_ = static_cast<const struct PPB_OpenGLES2*>(
104 module->GetBrowserInterface(PPB_OPENGLES2_INTERFACE)); 130 module->GetBrowserInterface(PPB_OPENGLES2_INTERFACE));
105 PP_DCHECK(gles2_if_); 131 PP_DCHECK(gles2_if_);
106 } 132 }
107 133
108 MediaStreamVideoDemoInstance::~MediaStreamVideoDemoInstance() { 134 MediaStreamVideoDemoInstance::~MediaStreamVideoDemoInstance() {
109 delete context_; 135 delete context_;
110 } 136 }
111 137
112 void MediaStreamVideoDemoInstance::DidChangeView( 138 void MediaStreamVideoDemoInstance::DidChangeView(
113 const pp::Rect& position, const pp::Rect& clip_ignored) { 139 const pp::Rect& position, const pp::Rect& clip_ignored) {
114 if (position.width() == 0 || position.height() == 0) 140 if (position.width() == 0 || position.height() == 0)
115 return; 141 return;
116 if (position.size() == position_size_) 142 if (position.size() == position_size_)
117 return; 143 return;
118 144
119 position_size_ = position.size(); 145 position_size_ = position.size();
120 146
121 // Initialize graphics. 147 // Initialize graphics.
122 InitGL(); 148 InitGL();
123 Render(); 149 Render();
124 } 150 }
125 151
126 void MediaStreamVideoDemoInstance::HandleMessage(const pp::Var& var_message) { 152 void MediaStreamVideoDemoInstance::HandleMessage(const pp::Var& var_message) {
127 if (!var_message.is_dictionary()) 153 if (!var_message.is_dictionary())
128 return; 154 return;
155
129 pp::VarDictionary var_dictionary_message(var_message); 156 pp::VarDictionary var_dictionary_message(var_message);
130 pp::Var var_track = var_dictionary_message.Get("track"); 157 std::string command = var_dictionary_message.Get("command").AsString();
131 if (!var_track.is_resource())
132 return;
133 158
134 pp::Resource resource_track = var_track.AsResource(); 159 if (command == "init") {
135 160 pp::Var var_track = var_dictionary_message.Get("track");
136 video_track_ = pp::MediaStreamVideoTrack(resource_track); 161 if (!var_track.is_resource())
137 162 return;
138 video_track_.GetFrame(callback_factory_.NewCallbackWithOutput( 163 pp::Resource resource_track = var_track.AsResource();
139 &MediaStreamVideoDemoInstance::OnGetFrame)); 164 video_track_ = pp::MediaStreamVideoTrack(resource_track);
165 ConfigureTrack();
166 } else if (command == "format") {
167 std::string str_format = var_dictionary_message.Get("format").AsString();
168 if (str_format == "YV12") {
169 attrib_format_ = PP_VIDEOFRAME_FORMAT_YV12;
170 } else if (str_format == "I420") {
171 attrib_format_ = PP_VIDEOFRAME_FORMAT_I420;
172 } else if (str_format == "BGRA") {
173 attrib_format_ = PP_VIDEOFRAME_FORMAT_BGRA;
174 } else {
175 attrib_format_ = PP_VIDEOFRAME_FORMAT_UNKNOWN;
176 }
177 need_config_ = true;
178 } else if (command == "size") {
179 attrib_width_ = var_dictionary_message.Get("width").AsInt();
180 attrib_height_ = var_dictionary_message.Get("height").AsInt();
181 need_config_ = true;
182 }
140 } 183 }
141 184
142 void MediaStreamVideoDemoInstance::InitGL() { 185 void MediaStreamVideoDemoInstance::InitGL() {
143 PP_DCHECK(position_size_.width() && position_size_.height()); 186 PP_DCHECK(position_size_.width() && position_size_.height());
144 is_painting_ = false; 187 is_painting_ = false;
145 188
146 delete context_; 189 delete context_;
147 int32_t attributes[] = { 190 int32_t attributes[] = {
148 PP_GRAPHICS3DATTRIB_ALPHA_SIZE, 0, 191 PP_GRAPHICS3DATTRIB_ALPHA_SIZE, 0,
149 PP_GRAPHICS3DATTRIB_BLUE_SIZE, 8, 192 PP_GRAPHICS3DATTRIB_BLUE_SIZE, 8,
(...skipping 15 matching lines...) Expand all
165 gles2_if_->Clear(context_->pp_resource(), GL_COLOR_BUFFER_BIT); 208 gles2_if_->Clear(context_->pp_resource(), GL_COLOR_BUFFER_BIT);
166 gles2_if_->Viewport(context_->pp_resource(), 0, 0, 209 gles2_if_->Viewport(context_->pp_resource(), 0, 0,
167 position_size_.width(), position_size_.height()); 210 position_size_.width(), position_size_.height());
168 211
169 BindGraphics(*context_); 212 BindGraphics(*context_);
170 AssertNoGLError(); 213 AssertNoGLError();
171 214
172 CreateGLObjects(); 215 CreateGLObjects();
173 } 216 }
174 217
218 void MediaStreamVideoDemoInstance::DrawYUV() {
219 PP_Resource context = context_->pp_resource();
220 static const float kColorMatrix[9] = {
221 1.1643828125f, 1.1643828125f, 1.1643828125f,
222 0.0f, -0.39176171875f, 2.017234375f,
223 1.59602734375f, -0.81296875f, 0.0f
224 };
225
226 gles2_if_->UseProgram(context, program_yuv_);
227 gles2_if_->Uniform1i(context, gles2_if_->GetUniformLocation(
228 context, program_yuv_, "y_texture"), 0);
229 gles2_if_->Uniform1i(context, gles2_if_->GetUniformLocation(
230 context, program_yuv_, "u_texture"), 1);
231 gles2_if_->Uniform1i(context, gles2_if_->GetUniformLocation(
232 context, program_yuv_, "v_texture"), 2);
233 gles2_if_->UniformMatrix3fv(
234 context,
235 gles2_if_->GetUniformLocation(context, program_yuv_, "color_matrix"),
236 1, GL_FALSE, kColorMatrix);
237 AssertNoGLError();
238
239 GLint pos_location = gles2_if_->GetAttribLocation(
240 context, program_yuv_, "a_position");
241 GLint tc_location = gles2_if_->GetAttribLocation(
242 context, program_yuv_, "a_texCoord");
243 AssertNoGLError();
244 gles2_if_->EnableVertexAttribArray(context, pos_location);
245 gles2_if_->VertexAttribPointer(context, pos_location, 2,
246 GL_FLOAT, GL_FALSE, 0, 0);
247 gles2_if_->EnableVertexAttribArray(context, tc_location);
248 gles2_if_->VertexAttribPointer(
249 context, tc_location, 2, GL_FLOAT, GL_FALSE, 0,
250 static_cast<float*>(0) + 16); // Skip position coordinates.
251 AssertNoGLError();
252
253 gles2_if_->DrawArrays(context, GL_TRIANGLE_STRIP, 0, 4);
254 AssertNoGLError();
255 }
256
257 void MediaStreamVideoDemoInstance::DrawRGB() {
258 PP_Resource context = context_->pp_resource();
259 gles2_if_->UseProgram(context, program_rgb_);
260 gles2_if_->Uniform1i(context,
261 gles2_if_->GetUniformLocation(context, program_rgb_, "rgb_texture"), 3);
262 AssertNoGLError();
263
264 GLint pos_location = gles2_if_->GetAttribLocation(
265 context, program_rgb_, "a_position");
266 GLint tc_location = gles2_if_->GetAttribLocation(
267 context, program_rgb_, "a_texCoord");
268 AssertNoGLError();
269 gles2_if_->EnableVertexAttribArray(context, pos_location);
270 gles2_if_->VertexAttribPointer(context, pos_location, 2,
271 GL_FLOAT, GL_FALSE, 0, 0);
272 gles2_if_->EnableVertexAttribArray(context, tc_location);
273 gles2_if_->VertexAttribPointer(
274 context, tc_location, 2, GL_FLOAT, GL_FALSE, 0,
275 static_cast<float*>(0) + 16); // Skip position coordinates.
276 AssertNoGLError();
277
278 gles2_if_->DrawArrays(context, GL_TRIANGLE_STRIP, 4, 4);
279 }
280
175 void MediaStreamVideoDemoInstance::Render() { 281 void MediaStreamVideoDemoInstance::Render() {
176 PP_DCHECK(!is_painting_); 282 PP_DCHECK(!is_painting_);
177 is_painting_ = true; 283 is_painting_ = true;
178 needs_paint_ = false; 284 needs_paint_ = false;
285
179 if (texture_y_) { 286 if (texture_y_) {
180 gles2_if_->DrawArrays(context_->pp_resource(), GL_TRIANGLE_STRIP, 0, 4); 287 DrawRGB();
288 DrawYUV();
181 } else { 289 } else {
182 gles2_if_->Clear(context_->pp_resource(), GL_COLOR_BUFFER_BIT); 290 gles2_if_->Clear(context_->pp_resource(), GL_COLOR_BUFFER_BIT);
183 } 291 }
184 pp::CompletionCallback cb = callback_factory_.NewCallback( 292 pp::CompletionCallback cb = callback_factory_.NewCallback(
185 &MediaStreamVideoDemoInstance::PaintFinished); 293 &MediaStreamVideoDemoInstance::PaintFinished);
186 context_->SwapBuffers(cb); 294 context_->SwapBuffers(cb);
187 } 295 }
188 296
189 void MediaStreamVideoDemoInstance::PaintFinished(int32_t result) { 297 void MediaStreamVideoDemoInstance::PaintFinished(int32_t result) {
190 is_painting_ = false; 298 is_painting_ = false;
191 if (needs_paint_) 299 if (needs_paint_)
192 Render(); 300 Render();
193 } 301 }
194 302
195 GLuint MediaStreamVideoDemoInstance::CreateTexture( 303 GLuint MediaStreamVideoDemoInstance::CreateTexture(
196 int32_t width, int32_t height, int unit) { 304 int32_t width, int32_t height, int unit, bool rgba) {
197 GLuint texture_id; 305 GLuint texture_id;
198 gles2_if_->GenTextures(context_->pp_resource(), 1, &texture_id); 306 gles2_if_->GenTextures(context_->pp_resource(), 1, &texture_id);
199 AssertNoGLError(); 307 AssertNoGLError();
308
200 // Assign parameters. 309 // Assign parameters.
201 gles2_if_->ActiveTexture(context_->pp_resource(), GL_TEXTURE0 + unit); 310 gles2_if_->ActiveTexture(context_->pp_resource(), GL_TEXTURE0 + unit);
202 gles2_if_->BindTexture(context_->pp_resource(), GL_TEXTURE_2D, texture_id); 311 gles2_if_->BindTexture(context_->pp_resource(), GL_TEXTURE_2D, texture_id);
203 gles2_if_->TexParameteri( 312 gles2_if_->TexParameteri(
204 context_->pp_resource(), GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, 313 context_->pp_resource(), GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
205 GL_NEAREST); 314 GL_NEAREST);
206 gles2_if_->TexParameteri( 315 gles2_if_->TexParameteri(
207 context_->pp_resource(), GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, 316 context_->pp_resource(), GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
208 GL_NEAREST); 317 GL_NEAREST);
209 gles2_if_->TexParameterf( 318 gles2_if_->TexParameterf(
210 context_->pp_resource(), GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, 319 context_->pp_resource(), GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
211 GL_CLAMP_TO_EDGE); 320 GL_CLAMP_TO_EDGE);
212 gles2_if_->TexParameterf( 321 gles2_if_->TexParameterf(
213 context_->pp_resource(), GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, 322 context_->pp_resource(), GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
214 GL_CLAMP_TO_EDGE); 323 GL_CLAMP_TO_EDGE);
215
216 // Allocate texture. 324 // Allocate texture.
217 gles2_if_->TexImage2D( 325 gles2_if_->TexImage2D(
218 context_->pp_resource(), GL_TEXTURE_2D, 0, GL_LUMINANCE, width, height, 0, 326 context_->pp_resource(), GL_TEXTURE_2D, 0,
219 GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL); 327 rgba ? GL_BGRA_EXT : GL_LUMINANCE,
328 width, height, 0,
329 rgba ? GL_BGRA_EXT : GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);
220 AssertNoGLError(); 330 AssertNoGLError();
221 return texture_id; 331 return texture_id;
222 } 332 }
223 333
224 void MediaStreamVideoDemoInstance::CreateGLObjects() { 334 void MediaStreamVideoDemoInstance::CreateGLObjects() {
225 // Code and constants for shader. 335 // Code and constants for shader.
226 static const char kVertexShader[] = 336 static const char kVertexShader[] =
227 "varying vec2 v_texCoord; \n" 337 "varying vec2 v_texCoord; \n"
228 "attribute vec4 a_position; \n" 338 "attribute vec4 a_position; \n"
229 "attribute vec2 a_texCoord; \n" 339 "attribute vec2 a_texCoord; \n"
230 "void main() \n" 340 "void main() \n"
231 "{ \n" 341 "{ \n"
232 " v_texCoord = a_texCoord; \n" 342 " v_texCoord = a_texCoord; \n"
233 " gl_Position = a_position; \n" 343 " gl_Position = a_position; \n"
234 "}"; 344 "}";
235 345
236 static const char kFragmentShader[] = 346 static const char kFragmentShaderYUV[] =
237 "precision mediump float; \n" 347 "precision mediump float; \n"
238 "varying vec2 v_texCoord; \n" 348 "varying vec2 v_texCoord; \n"
239 "uniform sampler2D y_texture; \n" 349 "uniform sampler2D y_texture; \n"
240 "uniform sampler2D u_texture; \n" 350 "uniform sampler2D u_texture; \n"
241 "uniform sampler2D v_texture; \n" 351 "uniform sampler2D v_texture; \n"
242 "uniform mat3 color_matrix; \n" 352 "uniform mat3 color_matrix; \n"
243 "void main() \n" 353 "void main() \n"
244 "{ \n" 354 "{ \n"
245 " vec3 yuv; \n" 355 " vec3 yuv; \n"
246 " yuv.x = texture2D(y_texture, v_texCoord).r; \n" 356 " yuv.x = texture2D(y_texture, v_texCoord).r; \n"
247 " yuv.y = texture2D(u_texture, v_texCoord).r; \n" 357 " yuv.y = texture2D(u_texture, v_texCoord).r; \n"
248 " yuv.z = texture2D(v_texture, v_texCoord).r; \n" 358 " yuv.z = texture2D(v_texture, v_texCoord).r; \n"
249 " vec3 rgb = color_matrix * (yuv - vec3(0.0625, 0.5, 0.5));\n" 359 " vec3 rgb = color_matrix * (yuv - vec3(0.0625, 0.5, 0.5));\n"
250 " gl_FragColor = vec4(rgb, 1.0); \n" 360 " gl_FragColor = vec4(rgb, 1.0); \n"
251 "}"; 361 "}";
252 362
253 static const float kColorMatrix[9] = { 363 static const char kFragmentShaderRGB[] =
254 1.1643828125f, 1.1643828125f, 1.1643828125f, 364 "precision mediump float; \n"
255 0.0f, -0.39176171875f, 2.017234375f, 365 "varying vec2 v_texCoord; \n"
256 1.59602734375f, -0.81296875f, 0.0f 366 "uniform sampler2D rgb_texture; \n"
257 }; 367 "void main() \n"
368 "{ \n"
369 " gl_FragColor = texture2D(rgb_texture, v_texCoord); \n"
370 "}";
258 371
259 PP_Resource context = context_->pp_resource(); 372 PP_Resource context = context_->pp_resource();
260 373
261 // Create shader program. 374 // Create shader programs.
262 GLuint program = gles2_if_->CreateProgram(context); 375 program_yuv_ = gles2_if_->CreateProgram(context);
263 CreateShader(program, GL_VERTEX_SHADER, kVertexShader, sizeof(kVertexShader)); 376 CreateShader(program_yuv_, GL_VERTEX_SHADER,
264 CreateShader( 377 kVertexShader, sizeof(kVertexShader));
265 program, GL_FRAGMENT_SHADER, kFragmentShader, sizeof(kFragmentShader)); 378 CreateShader(program_yuv_, GL_FRAGMENT_SHADER,
266 gles2_if_->LinkProgram(context, program); 379 kFragmentShaderYUV, sizeof(kFragmentShaderYUV));
267 gles2_if_->UseProgram(context, program); 380 gles2_if_->LinkProgram(context, program_yuv_);
268 gles2_if_->DeleteProgram(context, program); 381 AssertNoGLError();
269 gles2_if_->Uniform1i( 382
270 context, gles2_if_->GetUniformLocation(context, program, "y_texture"), 0); 383 program_rgb_ = gles2_if_->CreateProgram(context);
271 gles2_if_->Uniform1i( 384 CreateShader(program_rgb_, GL_VERTEX_SHADER,
272 context, gles2_if_->GetUniformLocation(context, program, "u_texture"), 1); 385 kVertexShader, sizeof(kVertexShader));
273 gles2_if_->Uniform1i( 386 CreateShader(program_rgb_, GL_FRAGMENT_SHADER,
274 context, gles2_if_->GetUniformLocation(context, program, "v_texture"), 2); 387 kFragmentShaderRGB, sizeof(kFragmentShaderRGB));
275 gles2_if_->UniformMatrix3fv( 388 gles2_if_->LinkProgram(context, program_rgb_);
276 context,
277 gles2_if_->GetUniformLocation(context, program, "color_matrix"),
278 1, GL_FALSE, kColorMatrix);
279 AssertNoGLError(); 389 AssertNoGLError();
280 390
281 // Assign vertex positions and texture coordinates to buffers for use in 391 // Assign vertex positions and texture coordinates to buffers for use in
282 // shader program. 392 // shader program.
283 static const float kVertices[] = { 393 static const float kVertices[] = {
284 -1, 1, -1, -1, 1, 1, 1, -1, // Position coordinates. 394 -1, 1, -1, -1, 0, 1, 0, -1, // Position coordinates.
395 0, 1, 0, -1, 1, 1, 1, -1, // Position coordinates.
396 0, 0, 0, 1, 1, 0, 1, 1, // Texture coordinates.
285 0, 0, 0, 1, 1, 0, 1, 1, // Texture coordinates. 397 0, 0, 0, 1, 1, 0, 1, 1, // Texture coordinates.
286 }; 398 };
287 399
288 GLuint buffer; 400 gles2_if_->GenBuffers(context, 1, &buffer_);
289 gles2_if_->GenBuffers(context, 1, &buffer); 401 gles2_if_->BindBuffer(context, GL_ARRAY_BUFFER, buffer_);
290 gles2_if_->BindBuffer(context, GL_ARRAY_BUFFER, buffer);
291 gles2_if_->BufferData(context, GL_ARRAY_BUFFER, 402 gles2_if_->BufferData(context, GL_ARRAY_BUFFER,
292 sizeof(kVertices), kVertices, GL_STATIC_DRAW); 403 sizeof(kVertices), kVertices, GL_STATIC_DRAW);
293 AssertNoGLError(); 404 AssertNoGLError();
294 GLint pos_location = gles2_if_->GetAttribLocation(
295 context, program, "a_position");
296 GLint tc_location = gles2_if_->GetAttribLocation(
297 context, program, "a_texCoord");
298 AssertNoGLError();
299 gles2_if_->EnableVertexAttribArray(context, pos_location);
300 gles2_if_->VertexAttribPointer(context, pos_location, 2,
301 GL_FLOAT, GL_FALSE, 0, 0);
302 gles2_if_->EnableVertexAttribArray(context, tc_location);
303 gles2_if_->VertexAttribPointer(
304 context, tc_location, 2, GL_FLOAT, GL_FALSE, 0,
305 static_cast<float*>(0) + 8); // Skip position coordinates.
306 AssertNoGLError();
307 } 405 }
308 406
309 void MediaStreamVideoDemoInstance::CreateShader( 407 void MediaStreamVideoDemoInstance::CreateShader(
310 GLuint program, GLenum type, const char* source, int size) { 408 GLuint program, GLenum type, const char* source, int size) {
311 PP_Resource context = context_->pp_resource(); 409 PP_Resource context = context_->pp_resource();
312 GLuint shader = gles2_if_->CreateShader(context, type); 410 GLuint shader = gles2_if_->CreateShader(context, type);
313 gles2_if_->ShaderSource(context, shader, 1, &source, &size); 411 gles2_if_->ShaderSource(context, shader, 1, &source, &size);
314 gles2_if_->CompileShader(context, shader); 412 gles2_if_->CompileShader(context, shader);
315 gles2_if_->AttachShader(context, program, shader); 413 gles2_if_->AttachShader(context, program, shader);
316 gles2_if_->DeleteShader(context, shader); 414 gles2_if_->DeleteShader(context, shader);
317 } 415 }
318 416
319 void MediaStreamVideoDemoInstance::CreateYUVTextures() { 417 void MediaStreamVideoDemoInstance::CreateTextures() {
320 int32_t width = frame_size_.width(); 418 int32_t width = frame_size_.width();
321 int32_t height = frame_size_.height(); 419 int32_t height = frame_size_.height();
322 if (width == 0 || height == 0) 420 if (width == 0 || height == 0)
323 return; 421 return;
324 if (texture_y_) 422 if (texture_y_)
325 gles2_if_->DeleteTextures(context_->pp_resource(), 1, &texture_y_); 423 gles2_if_->DeleteTextures(context_->pp_resource(), 1, &texture_y_);
326 if (texture_u_) 424 if (texture_u_)
327 gles2_if_->DeleteTextures(context_->pp_resource(), 1, &texture_u_); 425 gles2_if_->DeleteTextures(context_->pp_resource(), 1, &texture_u_);
328 if (texture_v_) 426 if (texture_v_)
329 gles2_if_->DeleteTextures(context_->pp_resource(), 1, &texture_v_); 427 gles2_if_->DeleteTextures(context_->pp_resource(), 1, &texture_v_);
330 texture_y_ = CreateTexture(width, height, 0); 428 if (texture_rgb_)
429 gles2_if_->DeleteTextures(context_->pp_resource(), 1, &texture_rgb_);
430 texture_y_ = CreateTexture(width, height, 0, false);
331 431
332 width /= 2; 432 texture_u_ = CreateTexture(width / 2, height / 2, 1, false);
333 height /= 2; 433 texture_v_ = CreateTexture(width / 2, height / 2, 2, false);
334 texture_u_ = CreateTexture(width, height, 1); 434 texture_rgb_ = CreateTexture(width, height, 3, true);
335 texture_v_ = CreateTexture(width, height, 2); 435 }
436
437 void MediaStreamVideoDemoInstance::ConfigureTrack() {
438 const int32_t attrib_list[] = {
439 PP_MEDIASTREAMVIDEOTRACK_ATTRIB_FORMAT, attrib_format_,
440 PP_MEDIASTREAMVIDEOTRACK_ATTRIB_WIDTH, attrib_width_,
441 PP_MEDIASTREAMVIDEOTRACK_ATTRIB_HEIGHT, attrib_height_,
442 PP_MEDIASTREAMVIDEOTRACK_ATTRIB_NONE
443 };
444 video_track_.Configure(attrib_list, callback_factory_.NewCallback(
445 &MediaStreamVideoDemoInstance::OnConfigure));
446 }
447
448 void MediaStreamVideoDemoInstance::OnConfigure(int32_t result) {
449 video_track_.GetFrame(callback_factory_.NewCallbackWithOutput(
450 &MediaStreamVideoDemoInstance::OnGetFrame));
336 } 451 }
337 452
338 void MediaStreamVideoDemoInstance::OnGetFrame( 453 void MediaStreamVideoDemoInstance::OnGetFrame(
339 int32_t result, pp::VideoFrame frame) { 454 int32_t result, pp::VideoFrame frame) {
340 if (result != PP_OK) 455 if (result != PP_OK)
341 return; 456 return;
342 const char* data = static_cast<const char*>(frame.GetDataBuffer()); 457 const char* data = static_cast<const char*>(frame.GetDataBuffer());
343 pp::Size size; 458 pp::Size size;
344 frame.GetSize(&size); 459 frame.GetSize(&size);
345 460
346 if (size != frame_size_) { 461 if (size != frame_size_) {
347 frame_size_ = size; 462 frame_size_ = size;
348 CreateYUVTextures(); 463 CreateTextures();
349 } 464 }
350 465
466 is_bgra_ = (frame.GetFormat() == PP_VIDEOFRAME_FORMAT_BGRA);
467
351 int32_t width = frame_size_.width(); 468 int32_t width = frame_size_.width();
352 int32_t height = frame_size_.height(); 469 int32_t height = frame_size_.height();
353 gles2_if_->ActiveTexture(context_->pp_resource(), GL_TEXTURE0); 470 if (!is_bgra_) {
354 gles2_if_->TexSubImage2D( 471 gles2_if_->ActiveTexture(context_->pp_resource(), GL_TEXTURE0);
355 context_->pp_resource(), GL_TEXTURE_2D, 0, 0, 0, width, height, 472 gles2_if_->TexSubImage2D(
356 GL_LUMINANCE, GL_UNSIGNED_BYTE, data); 473 context_->pp_resource(), GL_TEXTURE_2D, 0, 0, 0, width, height,
474 GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
357 475
358 data += width * height; 476 data += width * height;
359 width /= 2; 477 width /= 2;
360 height /= 2; 478 height /= 2;
361 479
362 gles2_if_->ActiveTexture(context_->pp_resource(), GL_TEXTURE1); 480 gles2_if_->ActiveTexture(context_->pp_resource(), GL_TEXTURE1);
363 gles2_if_->TexSubImage2D( 481 gles2_if_->TexSubImage2D(
364 context_->pp_resource(), GL_TEXTURE_2D, 0, 0, 0, width, height, 482 context_->pp_resource(), GL_TEXTURE_2D, 0, 0, 0, width, height,
365 GL_LUMINANCE, GL_UNSIGNED_BYTE, data); 483 GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
366 484
367 data += width * height; 485 data += width * height;
368 gles2_if_->ActiveTexture(context_->pp_resource(), GL_TEXTURE2); 486 gles2_if_->ActiveTexture(context_->pp_resource(), GL_TEXTURE2);
369 gles2_if_->TexSubImage2D( 487 gles2_if_->TexSubImage2D(
370 context_->pp_resource(), GL_TEXTURE_2D, 0, 0, 0, width, height, 488 context_->pp_resource(), GL_TEXTURE_2D, 0, 0, 0, width, height,
371 GL_LUMINANCE, GL_UNSIGNED_BYTE, data); 489 GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
490 } else {
491 gles2_if_->ActiveTexture(context_->pp_resource(), GL_TEXTURE3);
492 gles2_if_->TexSubImage2D(
493 context_->pp_resource(), GL_TEXTURE_2D, 0, 0, 0, width, height,
494 GL_BGRA_EXT, GL_UNSIGNED_BYTE, data);
495 }
372 496
373 if (is_painting_) 497 if (is_painting_)
374 needs_paint_ = true; 498 needs_paint_ = true;
375 else 499 else
376 Render(); 500 Render();
377 501
378 video_track_.RecycleFrame(frame); 502 video_track_.RecycleFrame(frame);
379 video_track_.GetFrame(callback_factory_.NewCallbackWithOutput( 503 if (need_config_) {
380 &MediaStreamVideoDemoInstance::OnGetFrame)); 504 ConfigureTrack();
505 need_config_ = false;
506 } else {
507 video_track_.GetFrame(callback_factory_.NewCallbackWithOutput(
508 &MediaStreamVideoDemoInstance::OnGetFrame));
509 }
381 } 510 }
382 511
383 pp::Instance* MediaStreamVideoModule::CreateInstance(PP_Instance instance) { 512 pp::Instance* MediaStreamVideoModule::CreateInstance(PP_Instance instance) {
384 return new MediaStreamVideoDemoInstance(instance, this); 513 return new MediaStreamVideoDemoInstance(instance, this);
385 } 514 }
386 515
387 } // anonymous namespace 516 } // anonymous namespace
388 517
389 namespace pp { 518 namespace pp {
390 // Factory function for your specialization of the Module object. 519 // Factory function for your specialization of the Module object.
391 Module* CreateModule() { 520 Module* CreateModule() {
392 return new MediaStreamVideoModule(); 521 return new MediaStreamVideoModule();
393 } 522 }
394 } // namespace pp 523 } // namespace pp
OLDNEW
« no previous file with comments | « ppapi/cpp/media_stream_video_track.h ('k') | ppapi/examples/media_stream_video/media_stream_video.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698