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

Side by Side Diff: native_client_sdk/src/examples/api/media_stream_video/media_stream_video.cc

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

Powered by Google App Engine
This is Rietveld 408576698