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

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

Powered by Google App Engine
This is Rietveld 408576698