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

Side by Side Diff: webrtc/modules/video_render/android/video_render_opengles20.cc

Issue 1912143002: Delete video_render module. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Move -framework flags from legacy_objc_api_tests.gyp to legacy_objc_api.gyp. Created 4 years, 7 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
(Empty)
1 /*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include <GLES2/gl2.h>
12 #include <GLES2/gl2ext.h>
13
14 #include <stdio.h>
15 #include <stdlib.h>
16
17 #include "webrtc/modules/video_render/android/video_render_opengles20.h"
18
19 //#define ANDROID_LOG
20
21 #ifdef ANDROID_LOG
22 #include <android/log.h>
23 #include <stdio.h>
24
25 #undef WEBRTC_TRACE
26 #define WEBRTC_TRACE(a,b,c,...) __android_log_print(ANDROID_LOG_DEBUG, "*WEBRTC N*", __VA_ARGS__)
27 #else
28 #include "webrtc/system_wrappers/include/trace.h"
29 #endif
30
31 namespace webrtc {
32
33 const char VideoRenderOpenGles20::g_indices[] = { 0, 3, 2, 0, 2, 1 };
34
35 const char VideoRenderOpenGles20::g_vertextShader[] = {
36 "attribute vec4 aPosition;\n"
37 "attribute vec2 aTextureCoord;\n"
38 "varying vec2 vTextureCoord;\n"
39 "void main() {\n"
40 " gl_Position = aPosition;\n"
41 " vTextureCoord = aTextureCoord;\n"
42 "}\n" };
43
44 // The fragment shader.
45 // Do YUV to RGB565 conversion.
46 const char VideoRenderOpenGles20::g_fragmentShader[] = {
47 "precision mediump float;\n"
48 "uniform sampler2D Ytex;\n"
49 "uniform sampler2D Utex,Vtex;\n"
50 "varying vec2 vTextureCoord;\n"
51 "void main(void) {\n"
52 " float nx,ny,r,g,b,y,u,v;\n"
53 " mediump vec4 txl,ux,vx;"
54 " nx=vTextureCoord[0];\n"
55 " ny=vTextureCoord[1];\n"
56 " y=texture2D(Ytex,vec2(nx,ny)).r;\n"
57 " u=texture2D(Utex,vec2(nx,ny)).r;\n"
58 " v=texture2D(Vtex,vec2(nx,ny)).r;\n"
59
60 //" y = v;\n"+
61 " y=1.1643*(y-0.0625);\n"
62 " u=u-0.5;\n"
63 " v=v-0.5;\n"
64
65 " r=y+1.5958*v;\n"
66 " g=y-0.39173*u-0.81290*v;\n"
67 " b=y+2.017*u;\n"
68 " gl_FragColor=vec4(r,g,b,1.0);\n"
69 "}\n" };
70
71 VideoRenderOpenGles20::VideoRenderOpenGles20(int32_t id) :
72 _id(id),
73 _textureWidth(-1),
74 _textureHeight(-1) {
75 WEBRTC_TRACE(kTraceDebug, kTraceVideoRenderer, _id, "%s: id %d",
76 __FUNCTION__, (int) _id);
77
78 const GLfloat vertices[20] = {
79 // X, Y, Z, U, V
80 -1, -1, 0, 0, 1, // Bottom Left
81 1, -1, 0, 1, 1, //Bottom Right
82 1, 1, 0, 1, 0, //Top Right
83 -1, 1, 0, 0, 0 }; //Top Left
84
85 memcpy(_vertices, vertices, sizeof(_vertices));
86 }
87
88 VideoRenderOpenGles20::~VideoRenderOpenGles20() {
89 }
90
91 int32_t VideoRenderOpenGles20::Setup(int32_t width, int32_t height) {
92 WEBRTC_TRACE(kTraceDebug, kTraceVideoRenderer, _id,
93 "%s: width %d, height %d", __FUNCTION__, (int) width,
94 (int) height);
95
96 printGLString("Version", GL_VERSION);
97 printGLString("Vendor", GL_VENDOR);
98 printGLString("Renderer", GL_RENDERER);
99 printGLString("Extensions", GL_EXTENSIONS);
100
101 int maxTextureImageUnits[2];
102 int maxTextureSize[2];
103 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, maxTextureImageUnits);
104 glGetIntegerv(GL_MAX_TEXTURE_SIZE, maxTextureSize);
105
106 WEBRTC_TRACE(kTraceDebug, kTraceVideoRenderer, _id,
107 "%s: number of textures %d, size %d", __FUNCTION__,
108 (int) maxTextureImageUnits[0], (int) maxTextureSize[0]);
109
110 _program = createProgram(g_vertextShader, g_fragmentShader);
111 if (!_program) {
112 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
113 "%s: Could not create program", __FUNCTION__);
114 return -1;
115 }
116
117 int positionHandle = glGetAttribLocation(_program, "aPosition");
118 checkGlError("glGetAttribLocation aPosition");
119 if (positionHandle == -1) {
120 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
121 "%s: Could not get aPosition handle", __FUNCTION__);
122 return -1;
123 }
124
125 int textureHandle = glGetAttribLocation(_program, "aTextureCoord");
126 checkGlError("glGetAttribLocation aTextureCoord");
127 if (textureHandle == -1) {
128 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
129 "%s: Could not get aTextureCoord handle", __FUNCTION__);
130 return -1;
131 }
132
133 // set the vertices array in the shader
134 // _vertices contains 4 vertices with 5 coordinates.
135 // 3 for (xyz) for the vertices and 2 for the texture
136 glVertexAttribPointer(positionHandle, 3, GL_FLOAT, false,
137 5 * sizeof(GLfloat), _vertices);
138 checkGlError("glVertexAttribPointer aPosition");
139
140 glEnableVertexAttribArray(positionHandle);
141 checkGlError("glEnableVertexAttribArray positionHandle");
142
143 // set the texture coordinate array in the shader
144 // _vertices contains 4 vertices with 5 coordinates.
145 // 3 for (xyz) for the vertices and 2 for the texture
146 glVertexAttribPointer(textureHandle, 2, GL_FLOAT, false, 5
147 * sizeof(GLfloat), &_vertices[3]);
148 checkGlError("glVertexAttribPointer maTextureHandle");
149 glEnableVertexAttribArray(textureHandle);
150 checkGlError("glEnableVertexAttribArray textureHandle");
151
152 glUseProgram(_program);
153 int i = glGetUniformLocation(_program, "Ytex");
154 checkGlError("glGetUniformLocation");
155 glUniform1i(i, 0); /* Bind Ytex to texture unit 0 */
156 checkGlError("glUniform1i Ytex");
157
158 i = glGetUniformLocation(_program, "Utex");
159 checkGlError("glGetUniformLocation Utex");
160 glUniform1i(i, 1); /* Bind Utex to texture unit 1 */
161 checkGlError("glUniform1i Utex");
162
163 i = glGetUniformLocation(_program, "Vtex");
164 checkGlError("glGetUniformLocation");
165 glUniform1i(i, 2); /* Bind Vtex to texture unit 2 */
166 checkGlError("glUniform1i");
167
168 glViewport(0, 0, width, height);
169 checkGlError("glViewport");
170 return 0;
171 }
172
173 // SetCoordinates
174 // Sets the coordinates where the stream shall be rendered.
175 // Values must be between 0 and 1.
176 int32_t VideoRenderOpenGles20::SetCoordinates(int32_t zOrder,
177 const float left,
178 const float top,
179 const float right,
180 const float bottom) {
181 if ((top > 1 || top < 0) || (right > 1 || right < 0) ||
182 (bottom > 1 || bottom < 0) || (left > 1 || left < 0)) {
183 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
184 "%s: Wrong coordinates", __FUNCTION__);
185 return -1;
186 }
187
188 // X, Y, Z, U, V
189 // -1, -1, 0, 0, 1, // Bottom Left
190 // 1, -1, 0, 1, 1, //Bottom Right
191 // 1, 1, 0, 1, 0, //Top Right
192 // -1, 1, 0, 0, 0 //Top Left
193
194 // Bottom Left
195 _vertices[0] = (left * 2) - 1;
196 _vertices[1] = -1 * (2 * bottom) + 1;
197 _vertices[2] = zOrder;
198
199 //Bottom Right
200 _vertices[5] = (right * 2) - 1;
201 _vertices[6] = -1 * (2 * bottom) + 1;
202 _vertices[7] = zOrder;
203
204 //Top Right
205 _vertices[10] = (right * 2) - 1;
206 _vertices[11] = -1 * (2 * top) + 1;
207 _vertices[12] = zOrder;
208
209 //Top Left
210 _vertices[15] = (left * 2) - 1;
211 _vertices[16] = -1 * (2 * top) + 1;
212 _vertices[17] = zOrder;
213
214 return 0;
215 }
216
217 int32_t VideoRenderOpenGles20::Render(const VideoFrame& frameToRender) {
218 if (frameToRender.IsZeroSize()) {
219 return -1;
220 }
221
222 WEBRTC_TRACE(kTraceDebug, kTraceVideoRenderer, _id, "%s: id %d",
223 __FUNCTION__, (int) _id);
224
225 glUseProgram(_program);
226 checkGlError("glUseProgram");
227
228 if (_textureWidth != (GLsizei) frameToRender.width() ||
229 _textureHeight != (GLsizei) frameToRender.height()) {
230 SetupTextures(frameToRender);
231 }
232 UpdateTextures(frameToRender);
233
234 glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, g_indices);
235 checkGlError("glDrawArrays");
236
237 return 0;
238 }
239
240 GLuint VideoRenderOpenGles20::loadShader(GLenum shaderType,
241 const char* pSource) {
242 GLuint shader = glCreateShader(shaderType);
243 if (shader) {
244 glShaderSource(shader, 1, &pSource, NULL);
245 glCompileShader(shader);
246 GLint compiled = 0;
247 glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
248 if (!compiled) {
249 GLint infoLen = 0;
250 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
251 if (infoLen) {
252 char* buf = (char*) malloc(infoLen);
253 if (buf) {
254 glGetShaderInfoLog(shader, infoLen, NULL, buf);
255 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
256 "%s: Could not compile shader %d: %s",
257 __FUNCTION__, shaderType, buf);
258 free(buf);
259 }
260 glDeleteShader(shader);
261 shader = 0;
262 }
263 }
264 }
265 return shader;
266 }
267
268 GLuint VideoRenderOpenGles20::createProgram(const char* pVertexSource,
269 const char* pFragmentSource) {
270 GLuint vertexShader = loadShader(GL_VERTEX_SHADER, pVertexSource);
271 if (!vertexShader) {
272 return 0;
273 }
274
275 GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pFragmentSource);
276 if (!pixelShader) {
277 return 0;
278 }
279
280 GLuint program = glCreateProgram();
281 if (program) {
282 glAttachShader(program, vertexShader);
283 checkGlError("glAttachShader");
284 glAttachShader(program, pixelShader);
285 checkGlError("glAttachShader");
286 glLinkProgram(program);
287 GLint linkStatus = GL_FALSE;
288 glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
289 if (linkStatus != GL_TRUE) {
290 GLint bufLength = 0;
291 glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
292 if (bufLength) {
293 char* buf = (char*) malloc(bufLength);
294 if (buf) {
295 glGetProgramInfoLog(program, bufLength, NULL, buf);
296 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
297 "%s: Could not link program: %s",
298 __FUNCTION__, buf);
299 free(buf);
300 }
301 }
302 glDeleteProgram(program);
303 program = 0;
304 }
305 }
306 return program;
307 }
308
309 void VideoRenderOpenGles20::printGLString(const char *name, GLenum s) {
310 const char *v = (const char *) glGetString(s);
311 WEBRTC_TRACE(kTraceDebug, kTraceVideoRenderer, _id, "GL %s = %s\n",
312 name, v);
313 }
314
315 void VideoRenderOpenGles20::checkGlError(const char* op) {
316 #ifdef ANDROID_LOG
317 for (GLint error = glGetError(); error; error = glGetError()) {
318 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
319 "after %s() glError (0x%x)\n", op, error);
320 }
321 #else
322 return;
323 #endif
324 }
325
326 static void InitializeTexture(int name, int id, int width, int height) {
327 glActiveTexture(name);
328 glBindTexture(GL_TEXTURE_2D, id);
329 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
330 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
331 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
332 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
333 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, width, height, 0,
334 GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);
335 }
336
337 void VideoRenderOpenGles20::SetupTextures(const VideoFrame& frameToRender) {
338 WEBRTC_TRACE(kTraceDebug, kTraceVideoRenderer, _id,
339 "%s: width %d, height %d", __FUNCTION__,
340 frameToRender.width(), frameToRender.height());
341
342 const GLsizei width = frameToRender.width();
343 const GLsizei height = frameToRender.height();
344
345 glGenTextures(3, _textureIds); //Generate the Y, U and V texture
346 InitializeTexture(GL_TEXTURE0, _textureIds[0], width, height);
347 InitializeTexture(GL_TEXTURE1, _textureIds[1], width / 2, height / 2);
348 InitializeTexture(GL_TEXTURE2, _textureIds[2], width / 2, height / 2);
349
350 checkGlError("SetupTextures");
351
352 _textureWidth = width;
353 _textureHeight = height;
354 }
355
356 // Uploads a plane of pixel data, accounting for stride != width*bpp.
357 static void GlTexSubImage2D(GLsizei width, GLsizei height, int stride,
358 const uint8_t* plane) {
359 if (stride == width) {
360 // Yay! We can upload the entire plane in a single GL call.
361 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_LUMINANCE,
362 GL_UNSIGNED_BYTE,
363 static_cast<const GLvoid*>(plane));
364 } else {
365 // Boo! Since GLES2 doesn't have GL_UNPACK_ROW_LENGTH and Android doesn't
366 // have GL_EXT_unpack_subimage we have to upload a row at a time. Ick.
367 for (int row = 0; row < height; ++row) {
368 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, row, width, 1, GL_LUMINANCE,
369 GL_UNSIGNED_BYTE,
370 static_cast<const GLvoid*>(plane + (row * stride)));
371 }
372 }
373 }
374
375 void VideoRenderOpenGles20::UpdateTextures(const VideoFrame& frameToRender) {
376 const GLsizei width = frameToRender.width();
377 const GLsizei height = frameToRender.height();
378
379 glActiveTexture(GL_TEXTURE0);
380 glBindTexture(GL_TEXTURE_2D, _textureIds[0]);
381 GlTexSubImage2D(width, height, frameToRender.stride(kYPlane),
382 frameToRender.buffer(kYPlane));
383
384 glActiveTexture(GL_TEXTURE1);
385 glBindTexture(GL_TEXTURE_2D, _textureIds[1]);
386 GlTexSubImage2D(width / 2, height / 2, frameToRender.stride(kUPlane),
387 frameToRender.buffer(kUPlane));
388
389 glActiveTexture(GL_TEXTURE2);
390 glBindTexture(GL_TEXTURE_2D, _textureIds[2]);
391 GlTexSubImage2D(width / 2, height / 2, frameToRender.stride(kVPlane),
392 frameToRender.buffer(kVPlane));
393
394 checkGlError("UpdateTextures");
395 }
396
397 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698