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

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: Update 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 video_track_.GetFrame(callback_factory_.NewCallbackWithOutput(
156 &MediaStreamVideoDemoInstance::OnGetFrame));
157 } else if (command == "format") {
158 std::string str_format = var_dictionary_message.Get("format").AsString();
159 PP_VideoFrame_Format format = PP_VIDEOFRAME_FORMAT_UNKNOWN;
160 if (str_format == "YV12") {
161 format = PP_VIDEOFRAME_FORMAT_YV12;
162 } else if (str_format == "I420") {
163 format = PP_VIDEOFRAME_FORMAT_I420;
164 } else if (str_format == "BGRA") {
165 format = PP_VIDEOFRAME_FORMAT_BGRA;
166 }
136 167
137 video_track_ = pp::MediaStreamVideoTrack(resource_track); 168 attrib_list_.clear();
138 169 attrib_list_.push_back(PP_MEDIASTREAMVIDEOTRACK_ATTRIB_FORMAT);
139 video_track_.GetFrame(callback_factory_.NewCallbackWithOutput( 170 attrib_list_.push_back(format);
140 &MediaStreamVideoDemoInstance::OnGetFrame)); 171 attrib_list_.push_back(PP_MEDIASTREAMVIDEOTRACK_ATTRIB_NONE);
172 } else if (command == "size") {
173 attrib_list_.clear();
174 attrib_list_.push_back(PP_MEDIASTREAMVIDEOTRACK_ATTRIB_WIDTH);
175 attrib_list_.push_back(var_dictionary_message.Get("width").AsInt());
176 attrib_list_.push_back(PP_MEDIASTREAMVIDEOTRACK_ATTRIB_HEIGHT);
177 attrib_list_.push_back(var_dictionary_message.Get("height").AsInt());
178 attrib_list_.push_back(PP_MEDIASTREAMVIDEOTRACK_ATTRIB_NONE);
179 }
141 } 180 }
142 181
143 void MediaStreamVideoDemoInstance::InitGL() { 182 void MediaStreamVideoDemoInstance::InitGL() {
144 PP_DCHECK(position_size_.width() && position_size_.height()); 183 PP_DCHECK(position_size_.width() && position_size_.height());
145 is_painting_ = false; 184 is_painting_ = false;
146 185
147 delete context_; 186 delete context_;
148 int32_t attributes[] = { 187 int32_t attributes[] = {
149 PP_GRAPHICS3DATTRIB_ALPHA_SIZE, 0, 188 PP_GRAPHICS3DATTRIB_ALPHA_SIZE, 0,
150 PP_GRAPHICS3DATTRIB_BLUE_SIZE, 8, 189 PP_GRAPHICS3DATTRIB_BLUE_SIZE, 8,
(...skipping 15 matching lines...) Expand all
166 gles2_if_->Clear(context_->pp_resource(), GL_COLOR_BUFFER_BIT); 205 gles2_if_->Clear(context_->pp_resource(), GL_COLOR_BUFFER_BIT);
167 gles2_if_->Viewport(context_->pp_resource(), 0, 0, 206 gles2_if_->Viewport(context_->pp_resource(), 0, 0,
168 position_size_.width(), position_size_.height()); 207 position_size_.width(), position_size_.height());
169 208
170 BindGraphics(*context_); 209 BindGraphics(*context_);
171 AssertNoGLError(); 210 AssertNoGLError();
172 211
173 CreateGLObjects(); 212 CreateGLObjects();
174 } 213 }
175 214
215 void MediaStreamVideoDemoInstance::DrawYUV() {
216 PP_Resource context = context_->pp_resource();
217 static const float kColorMatrix[9] = {
218 1.1643828125f, 1.1643828125f, 1.1643828125f,
219 0.0f, -0.39176171875f, 2.017234375f,
220 1.59602734375f, -0.81296875f, 0.0f
221 };
222
223 gles2_if_->UseProgram(context, program_yuv_);
224 gles2_if_->Uniform1i(context, gles2_if_->GetUniformLocation(
225 context, program_yuv_, "y_texture"), 0);
226 gles2_if_->Uniform1i(context, gles2_if_->GetUniformLocation(
227 context, program_yuv_, "u_texture"), 1);
228 gles2_if_->Uniform1i(context, gles2_if_->GetUniformLocation(
229 context, program_yuv_, "v_texture"), 2);
230 gles2_if_->UniformMatrix3fv(
231 context,
232 gles2_if_->GetUniformLocation(context, program_yuv_, "color_matrix"),
233 1, GL_FALSE, kColorMatrix);
234 AssertNoGLError();
235
236 GLint pos_location = gles2_if_->GetAttribLocation(
237 context, program_yuv_, "a_position");
238 GLint tc_location = gles2_if_->GetAttribLocation(
239 context, program_yuv_, "a_texCoord");
240 AssertNoGLError();
241 gles2_if_->EnableVertexAttribArray(context, pos_location);
242 gles2_if_->VertexAttribPointer(context, pos_location, 2,
243 GL_FLOAT, GL_FALSE, 0, 0);
244 gles2_if_->EnableVertexAttribArray(context, tc_location);
245 gles2_if_->VertexAttribPointer(
246 context, tc_location, 2, GL_FLOAT, GL_FALSE, 0,
247 static_cast<float*>(0) + 16); // Skip position coordinates.
248 AssertNoGLError();
249
250 gles2_if_->DrawArrays(context, GL_TRIANGLE_STRIP, 0, 4);
251 AssertNoGLError();
252 }
253
254 void MediaStreamVideoDemoInstance::DrawRGB() {
255 PP_Resource context = context_->pp_resource();
256 gles2_if_->UseProgram(context, program_rgb_);
257 gles2_if_->Uniform1i(context,
258 gles2_if_->GetUniformLocation(context, program_rgb_, "rgb_texture"), 3);
259 AssertNoGLError();
260
261 GLint pos_location = gles2_if_->GetAttribLocation(
262 context, program_rgb_, "a_position");
263 GLint tc_location = gles2_if_->GetAttribLocation(
264 context, program_rgb_, "a_texCoord");
265 AssertNoGLError();
266 gles2_if_->EnableVertexAttribArray(context, pos_location);
267 gles2_if_->VertexAttribPointer(context, pos_location, 2,
268 GL_FLOAT, GL_FALSE, 0, 0);
269 gles2_if_->EnableVertexAttribArray(context, tc_location);
270 gles2_if_->VertexAttribPointer(
271 context, tc_location, 2, GL_FLOAT, GL_FALSE, 0,
272 static_cast<float*>(0) + 16); // Skip position coordinates.
273 AssertNoGLError();
274
275 gles2_if_->DrawArrays(context, GL_TRIANGLE_STRIP, 4, 4);
276 }
277
176 void MediaStreamVideoDemoInstance::Render() { 278 void MediaStreamVideoDemoInstance::Render() {
177 PP_DCHECK(!is_painting_); 279 PP_DCHECK(!is_painting_);
178 is_painting_ = true; 280 is_painting_ = true;
179 needs_paint_ = false; 281 needs_paint_ = false;
282
180 if (texture_y_) { 283 if (texture_y_) {
181 gles2_if_->DrawArrays(context_->pp_resource(), GL_TRIANGLE_STRIP, 0, 4); 284 DrawRGB();
285 DrawYUV();
182 } else { 286 } else {
183 gles2_if_->Clear(context_->pp_resource(), GL_COLOR_BUFFER_BIT); 287 gles2_if_->Clear(context_->pp_resource(), GL_COLOR_BUFFER_BIT);
184 } 288 }
185 pp::CompletionCallback cb = callback_factory_.NewCallback( 289 pp::CompletionCallback cb = callback_factory_.NewCallback(
186 &MediaStreamVideoDemoInstance::PaintFinished); 290 &MediaStreamVideoDemoInstance::PaintFinished);
187 context_->SwapBuffers(cb); 291 context_->SwapBuffers(cb);
188 } 292 }
189 293
190 void MediaStreamVideoDemoInstance::PaintFinished(int32_t result) { 294 void MediaStreamVideoDemoInstance::PaintFinished(int32_t result) {
191 is_painting_ = false; 295 is_painting_ = false;
192 if (needs_paint_) 296 if (needs_paint_)
193 Render(); 297 Render();
194 } 298 }
195 299
196 GLuint MediaStreamVideoDemoInstance::CreateTexture( 300 GLuint MediaStreamVideoDemoInstance::CreateTexture(
197 int32_t width, int32_t height, int unit) { 301 int32_t width, int32_t height, int unit, bool rgba) {
198 GLuint texture_id; 302 GLuint texture_id;
199 gles2_if_->GenTextures(context_->pp_resource(), 1, &texture_id); 303 gles2_if_->GenTextures(context_->pp_resource(), 1, &texture_id);
200 AssertNoGLError(); 304 AssertNoGLError();
305
201 // Assign parameters. 306 // Assign parameters.
202 gles2_if_->ActiveTexture(context_->pp_resource(), GL_TEXTURE0 + unit); 307 gles2_if_->ActiveTexture(context_->pp_resource(), GL_TEXTURE0 + unit);
203 gles2_if_->BindTexture(context_->pp_resource(), GL_TEXTURE_2D, texture_id); 308 gles2_if_->BindTexture(context_->pp_resource(), GL_TEXTURE_2D, texture_id);
204 gles2_if_->TexParameteri( 309 gles2_if_->TexParameteri(
205 context_->pp_resource(), GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, 310 context_->pp_resource(), GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
206 GL_NEAREST); 311 GL_NEAREST);
207 gles2_if_->TexParameteri( 312 gles2_if_->TexParameteri(
208 context_->pp_resource(), GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, 313 context_->pp_resource(), GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
209 GL_NEAREST); 314 GL_NEAREST);
210 gles2_if_->TexParameterf( 315 gles2_if_->TexParameterf(
211 context_->pp_resource(), GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, 316 context_->pp_resource(), GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
212 GL_CLAMP_TO_EDGE); 317 GL_CLAMP_TO_EDGE);
213 gles2_if_->TexParameterf( 318 gles2_if_->TexParameterf(
214 context_->pp_resource(), GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, 319 context_->pp_resource(), GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
215 GL_CLAMP_TO_EDGE); 320 GL_CLAMP_TO_EDGE);
216
217 // Allocate texture. 321 // Allocate texture.
218 gles2_if_->TexImage2D( 322 gles2_if_->TexImage2D(
219 context_->pp_resource(), GL_TEXTURE_2D, 0, GL_LUMINANCE, width, height, 0, 323 context_->pp_resource(), GL_TEXTURE_2D, 0,
220 GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL); 324 rgba ? GL_BGRA_EXT : GL_LUMINANCE,
325 width, height, 0,
326 rgba ? GL_BGRA_EXT : GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);
221 AssertNoGLError(); 327 AssertNoGLError();
222 return texture_id; 328 return texture_id;
223 } 329 }
224 330
225 void MediaStreamVideoDemoInstance::CreateGLObjects() { 331 void MediaStreamVideoDemoInstance::CreateGLObjects() {
226 // Code and constants for shader. 332 // Code and constants for shader.
227 static const char kVertexShader[] = 333 static const char kVertexShader[] =
228 "varying vec2 v_texCoord; \n" 334 "varying vec2 v_texCoord; \n"
229 "attribute vec4 a_position; \n" 335 "attribute vec4 a_position; \n"
230 "attribute vec2 a_texCoord; \n" 336 "attribute vec2 a_texCoord; \n"
231 "void main() \n" 337 "void main() \n"
232 "{ \n" 338 "{ \n"
233 " v_texCoord = a_texCoord; \n" 339 " v_texCoord = a_texCoord; \n"
234 " gl_Position = a_position; \n" 340 " gl_Position = a_position; \n"
235 "}"; 341 "}";
236 342
237 static const char kFragmentShader[] = 343 static const char kFragmentShaderYUV[] =
238 "precision mediump float; \n" 344 "precision mediump float; \n"
239 "varying vec2 v_texCoord; \n" 345 "varying vec2 v_texCoord; \n"
240 "uniform sampler2D y_texture; \n" 346 "uniform sampler2D y_texture; \n"
241 "uniform sampler2D u_texture; \n" 347 "uniform sampler2D u_texture; \n"
242 "uniform sampler2D v_texture; \n" 348 "uniform sampler2D v_texture; \n"
243 "uniform mat3 color_matrix; \n" 349 "uniform mat3 color_matrix; \n"
244 "void main() \n" 350 "void main() \n"
245 "{ \n" 351 "{ \n"
246 " vec3 yuv; \n" 352 " vec3 yuv; \n"
247 " yuv.x = texture2D(y_texture, v_texCoord).r; \n" 353 " yuv.x = texture2D(y_texture, v_texCoord).r; \n"
248 " yuv.y = texture2D(u_texture, v_texCoord).r; \n" 354 " yuv.y = texture2D(u_texture, v_texCoord).r; \n"
249 " yuv.z = texture2D(v_texture, v_texCoord).r; \n" 355 " yuv.z = texture2D(v_texture, v_texCoord).r; \n"
250 " vec3 rgb = color_matrix * (yuv - vec3(0.0625, 0.5, 0.5));\n" 356 " vec3 rgb = color_matrix * (yuv - vec3(0.0625, 0.5, 0.5));\n"
251 " gl_FragColor = vec4(rgb, 1.0); \n" 357 " gl_FragColor = vec4(rgb, 1.0); \n"
252 "}"; 358 "}";
253 359
254 static const float kColorMatrix[9] = { 360 static const char kFragmentShaderRGB[] =
255 1.1643828125f, 1.1643828125f, 1.1643828125f, 361 "precision mediump float; \n"
256 0.0f, -0.39176171875f, 2.017234375f, 362 "varying vec2 v_texCoord; \n"
257 1.59602734375f, -0.81296875f, 0.0f 363 "uniform sampler2D rgb_texture; \n"
258 }; 364 "void main() \n"
365 "{ \n"
366 " gl_FragColor = texture2D(rgb_texture, v_texCoord); \n"
367 "}";
259 368
260 PP_Resource context = context_->pp_resource(); 369 PP_Resource context = context_->pp_resource();
261 370
262 // Create shader program. 371 // Create shader programs.
263 GLuint program = gles2_if_->CreateProgram(context); 372 program_yuv_ = gles2_if_->CreateProgram(context);
264 CreateShader(program, GL_VERTEX_SHADER, kVertexShader, sizeof(kVertexShader)); 373 CreateShader(program_yuv_, GL_VERTEX_SHADER,
265 CreateShader( 374 kVertexShader, sizeof(kVertexShader));
266 program, GL_FRAGMENT_SHADER, kFragmentShader, sizeof(kFragmentShader)); 375 CreateShader(program_yuv_, GL_FRAGMENT_SHADER,
267 gles2_if_->LinkProgram(context, program); 376 kFragmentShaderYUV, sizeof(kFragmentShaderYUV));
268 gles2_if_->UseProgram(context, program); 377 gles2_if_->LinkProgram(context, program_yuv_);
269 gles2_if_->DeleteProgram(context, program); 378 AssertNoGLError();
270 gles2_if_->Uniform1i( 379
271 context, gles2_if_->GetUniformLocation(context, program, "y_texture"), 0); 380 program_rgb_ = gles2_if_->CreateProgram(context);
272 gles2_if_->Uniform1i( 381 CreateShader(program_rgb_, GL_VERTEX_SHADER,
273 context, gles2_if_->GetUniformLocation(context, program, "u_texture"), 1); 382 kVertexShader, sizeof(kVertexShader));
274 gles2_if_->Uniform1i( 383 CreateShader(program_rgb_, GL_FRAGMENT_SHADER,
275 context, gles2_if_->GetUniformLocation(context, program, "v_texture"), 2); 384 kFragmentShaderRGB, sizeof(kFragmentShaderRGB));
276 gles2_if_->UniformMatrix3fv( 385 gles2_if_->LinkProgram(context, program_rgb_);
277 context,
278 gles2_if_->GetUniformLocation(context, program, "color_matrix"),
279 1, GL_FALSE, kColorMatrix);
280 AssertNoGLError(); 386 AssertNoGLError();
281 387
282 // Assign vertex positions and texture coordinates to buffers for use in 388 // Assign vertex positions and texture coordinates to buffers for use in
283 // shader program. 389 // shader program.
284 static const float kVertices[] = { 390 static const float kVertices[] = {
285 -1, 1, -1, -1, 1, 1, 1, -1, // Position coordinates. 391 -1, 1, -1, -1, 0, 1, 0, -1, // Position coordinates.
392 0, 1, 0, -1, 1, 1, 1, -1, // Position coordinates.
393 0, 0, 0, 1, 1, 0, 1, 1, // Texture coordinates.
286 0, 0, 0, 1, 1, 0, 1, 1, // Texture coordinates. 394 0, 0, 0, 1, 1, 0, 1, 1, // Texture coordinates.
287 }; 395 };
288 396
289 GLuint buffer; 397 gles2_if_->GenBuffers(context, 1, &buffer_);
290 gles2_if_->GenBuffers(context, 1, &buffer); 398 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, 399 gles2_if_->BufferData(context, GL_ARRAY_BUFFER,
293 sizeof(kVertices), kVertices, GL_STATIC_DRAW); 400 sizeof(kVertices), kVertices, GL_STATIC_DRAW);
294 AssertNoGLError(); 401 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 } 402 }
309 403
310 void MediaStreamVideoDemoInstance::CreateShader( 404 void MediaStreamVideoDemoInstance::CreateShader(
311 GLuint program, GLenum type, const char* source, int size) { 405 GLuint program, GLenum type, const char* source, int size) {
312 PP_Resource context = context_->pp_resource(); 406 PP_Resource context = context_->pp_resource();
313 GLuint shader = gles2_if_->CreateShader(context, type); 407 GLuint shader = gles2_if_->CreateShader(context, type);
314 gles2_if_->ShaderSource(context, shader, 1, &source, &size); 408 gles2_if_->ShaderSource(context, shader, 1, &source, &size);
315 gles2_if_->CompileShader(context, shader); 409 gles2_if_->CompileShader(context, shader);
316 gles2_if_->AttachShader(context, program, shader); 410 gles2_if_->AttachShader(context, program, shader);
317 gles2_if_->DeleteShader(context, shader); 411 gles2_if_->DeleteShader(context, shader);
318 } 412 }
319 413
320 void MediaStreamVideoDemoInstance::CreateYUVTextures() { 414 void MediaStreamVideoDemoInstance::CreateTextures() {
321 int32_t width = frame_size_.width(); 415 int32_t width = frame_size_.width();
322 int32_t height = frame_size_.height(); 416 int32_t height = frame_size_.height();
323 if (width == 0 || height == 0) 417 if (width == 0 || height == 0)
324 return; 418 return;
325 if (texture_y_) 419 if (texture_y_)
326 gles2_if_->DeleteTextures(context_->pp_resource(), 1, &texture_y_); 420 gles2_if_->DeleteTextures(context_->pp_resource(), 1, &texture_y_);
327 if (texture_u_) 421 if (texture_u_)
328 gles2_if_->DeleteTextures(context_->pp_resource(), 1, &texture_u_); 422 gles2_if_->DeleteTextures(context_->pp_resource(), 1, &texture_u_);
329 if (texture_v_) 423 if (texture_v_)
330 gles2_if_->DeleteTextures(context_->pp_resource(), 1, &texture_v_); 424 gles2_if_->DeleteTextures(context_->pp_resource(), 1, &texture_v_);
331 texture_y_ = CreateTexture(width, height, 0); 425 if (texture_rgb_)
426 gles2_if_->DeleteTextures(context_->pp_resource(), 1, &texture_rgb_);
427 texture_y_ = CreateTexture(width, height, 0, false);
332 428
333 width /= 2; 429 texture_u_ = CreateTexture(width / 2, height / 2, 1, false);
334 height /= 2; 430 texture_v_ = CreateTexture(width / 2, height / 2, 2, false);
335 texture_u_ = CreateTexture(width, height, 1); 431 texture_rgb_ = CreateTexture(width, height, 3, true);
336 texture_v_ = CreateTexture(width, height, 2); 432 }
433
434 void MediaStreamVideoDemoInstance::OnConfigure(int32_t result) {
435 video_track_.GetFrame(callback_factory_.NewCallbackWithOutput(
436 &MediaStreamVideoDemoInstance::OnGetFrame));
337 } 437 }
338 438
339 void MediaStreamVideoDemoInstance::OnGetFrame( 439 void MediaStreamVideoDemoInstance::OnGetFrame(
340 int32_t result, pp::VideoFrame frame) { 440 int32_t result, pp::VideoFrame frame) {
341 if (result != PP_OK) 441 if (result != PP_OK)
342 return; 442 return;
343 const char* data = static_cast<const char*>(frame.GetDataBuffer()); 443 const char* data = static_cast<const char*>(frame.GetDataBuffer());
344 pp::Size size; 444 pp::Size size;
345 frame.GetSize(&size); 445 frame.GetSize(&size);
346 446
347 if (size != frame_size_) { 447 if (size != frame_size_) {
348 frame_size_ = size; 448 frame_size_ = size;
349 CreateYUVTextures(); 449 CreateTextures();
350 } 450 }
351 451
452 is_bgra_ = (frame.GetFormat() == PP_VIDEOFRAME_FORMAT_BGRA);
453
352 int32_t width = frame_size_.width(); 454 int32_t width = frame_size_.width();
353 int32_t height = frame_size_.height(); 455 int32_t height = frame_size_.height();
354 gles2_if_->ActiveTexture(context_->pp_resource(), GL_TEXTURE0); 456 if (!is_bgra_) {
355 gles2_if_->TexSubImage2D( 457 gles2_if_->ActiveTexture(context_->pp_resource(), GL_TEXTURE0);
356 context_->pp_resource(), GL_TEXTURE_2D, 0, 0, 0, width, height, 458 gles2_if_->TexSubImage2D(
357 GL_LUMINANCE, GL_UNSIGNED_BYTE, data); 459 context_->pp_resource(), GL_TEXTURE_2D, 0, 0, 0, width, height,
460 GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
358 461
359 data += width * height; 462 data += width * height;
360 width /= 2; 463 width /= 2;
361 height /= 2; 464 height /= 2;
362 465
363 gles2_if_->ActiveTexture(context_->pp_resource(), GL_TEXTURE1); 466 gles2_if_->ActiveTexture(context_->pp_resource(), GL_TEXTURE1);
364 gles2_if_->TexSubImage2D( 467 gles2_if_->TexSubImage2D(
365 context_->pp_resource(), GL_TEXTURE_2D, 0, 0, 0, width, height, 468 context_->pp_resource(), GL_TEXTURE_2D, 0, 0, 0, width, height,
366 GL_LUMINANCE, GL_UNSIGNED_BYTE, data); 469 GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
367 470
368 data += width * height; 471 data += width * height;
369 gles2_if_->ActiveTexture(context_->pp_resource(), GL_TEXTURE2); 472 gles2_if_->ActiveTexture(context_->pp_resource(), GL_TEXTURE2);
370 gles2_if_->TexSubImage2D( 473 gles2_if_->TexSubImage2D(
371 context_->pp_resource(), GL_TEXTURE_2D, 0, 0, 0, width, height, 474 context_->pp_resource(), GL_TEXTURE_2D, 0, 0, 0, width, height,
372 GL_LUMINANCE, GL_UNSIGNED_BYTE, data); 475 GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
476 } else {
477 gles2_if_->ActiveTexture(context_->pp_resource(), GL_TEXTURE3);
478 gles2_if_->TexSubImage2D(
479 context_->pp_resource(), GL_TEXTURE_2D, 0, 0, 0, width, height,
480 GL_BGRA_EXT, GL_UNSIGNED_BYTE, data);
481 }
373 482
374 if (is_painting_) 483 if (is_painting_)
375 needs_paint_ = true; 484 needs_paint_ = true;
376 else 485 else
377 Render(); 486 Render();
378 487
379 video_track_.RecycleFrame(frame); 488 video_track_.RecycleFrame(frame);
380 video_track_.GetFrame(callback_factory_.NewCallbackWithOutput( 489 if (attrib_list_.empty()) {
381 &MediaStreamVideoDemoInstance::OnGetFrame)); 490 video_track_.GetFrame(callback_factory_.NewCallbackWithOutput(
491 &MediaStreamVideoDemoInstance::OnGetFrame));
492 } else {
493 video_track_.Configure(attrib_list_.data(), callback_factory_.NewCallback(
494 &MediaStreamVideoDemoInstance::OnConfigure));
495 attrib_list_.clear();
496 }
382 } 497 }
383 498
384 pp::Instance* MediaStreamVideoModule::CreateInstance(PP_Instance instance) { 499 pp::Instance* MediaStreamVideoModule::CreateInstance(PP_Instance instance) {
385 return new MediaStreamVideoDemoInstance(instance, this); 500 return new MediaStreamVideoDemoInstance(instance, this);
386 } 501 }
387 502
388 } // anonymous namespace 503 } // anonymous namespace
389 504
390 namespace pp { 505 namespace pp {
391 // Factory function for your specialization of the Module object. 506 // Factory function for your specialization of the Module object.
392 Module* CreateModule() { 507 Module* CreateModule() {
393 return new MediaStreamVideoModule(); 508 return new MediaStreamVideoModule();
394 } 509 }
395 } // namespace pp 510 } // namespace pp
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698