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

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

Powered by Google App Engine
This is Rietveld 408576698