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

Side by Side Diff: content/common/gpu/media/gles2_external_texture_copier.cc

Issue 11973010: AndroidVDA by using Android's MediaCodec API. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 7 years, 11 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 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/common/gpu/media/gles2_external_texture_copier.h"
6
7 #include "base/logging.h"
8
9 namespace content {
10
11 static void checkGlError(const char* op) {
12 for (GLint error = glGetError(); error; error = glGetError()) {
13 LOG(ERROR) << "after " << op <<" glError (0x" << std::hex << error << ")";
14 NOTREACHED();
15 }
16 }
17
18 static const char g_vertex_shader[] =
19 "uniform mat4 uMVPMatrix;\n"
20 "uniform mat4 uSTMatrix;\n"
21 "attribute vec4 aPosition;\n"
22 "attribute vec4 aTextureCoord;\n"
23 "varying vec2 vTextureCoord;\n"
24 "void main() {\n"
25 " gl_Position = uMVPMatrix * aPosition;\n"
26 " vTextureCoord = (uSTMatrix * aTextureCoord).xy;\n"
27 "}\n";
28
29 static const char g_fragment_shader[] =
30 "#extension GL_OES_EGL_image_external : require\n"
31 "precision mediump float;\n"
32 "varying vec2 vTextureCoord;\n"
33 "uniform samplerExternalOES sTexture;\n"
34 "void main() {\n"
35 " gl_FragColor = texture2D(sTexture, vTextureCoord);\n"
36 "}\n";
37
38 enum { kVerticeStride = 5 * sizeof(float) };
39
40 static const GLfloat g_vertices[] = {
41 -1.0f, -1.0f, 0, 0.f, 0.f,
42 1.0f, -1.0f, 0, 1.f, 0.f,
43 -1.0f, 1.0f, 0, 0.f, 1.f,
44 1.0f, 1.0f, 0, 1.f, 1.f,
45 };
46
47 // Due to the absence of matrix functions in NDK, a pre-calculated matrix
48 // is used. g_mvp_matrix = P * L * I
49 // Matrix.setLookAtM(L, 0, 0, 0, 2, 0, 0, 0, 0, -1, 0);
50 // Matrix.orthoM(P, 0, -1, 1, -1, 1, 1, 3);
51 // Matrix.setIdentityM(I, 0);
52 // TODO(dwkang): currently, (0, -1, 0) is used for the up vector.
53 // figure out why up vector (0, 1, 0) generates flipped screen.
54 static const GLfloat g_mvp_matrix[] = {
55 1.f, 0.f, 0.f, 0.f,
56 0.f, -1.f, 0.f, 0.f,
57 0.f, 0.f, -1.f, 0.f,
58 0.f, 0.f, 0.f, 1.f,
59 };
60
61 static GLuint LoadShader(GLenum shaderType, const char* pSource) {
62 GLuint shader = glCreateShader(shaderType);
63 if (shader) {
64 glShaderSource(shader, 1, &pSource, NULL);
65 glCompileShader(shader);
66 GLint compiled = 0;
67 glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
68 if (!compiled) {
69 GLint infoLen = 0;
70 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
71 if (infoLen) {
72 char* buf = (char*) malloc(infoLen);
73 if (buf) {
74 glGetShaderInfoLog(shader, infoLen, NULL, buf);
75 LOG(ERROR) << "Could not compile shader : " << buf;
76 free(buf);
77 }
78 glDeleteShader(shader);
79 shader = 0;
80 }
81 }
82 }
83 return shader;
84 }
85
86 static GLuint CreateProgram(
87 const char* pVertexSource, const char* pFragmentSource) {
88 GLuint vertexShader = LoadShader(GL_VERTEX_SHADER, pVertexSource);
89 if (!vertexShader) {
90 return 0;
91 }
92
93 GLuint pixelShader = LoadShader(GL_FRAGMENT_SHADER, pFragmentSource);
94 if (!pixelShader) {
95 return 0;
96 }
97
98 GLuint program = glCreateProgram();
99 if (program) {
100 glAttachShader(program, vertexShader);
101 checkGlError("glAttachShader");
102 glAttachShader(program, pixelShader);
103 checkGlError("glAttachShader");
104 glLinkProgram(program);
105 GLint linkStatus = GL_FALSE;
106 glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
107 if (linkStatus != GL_TRUE) {
108 GLint bufLength = 0;
109 glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
110 if (bufLength) {
111 char* buf = (char*) malloc(bufLength);
112 if (buf) {
113 glGetProgramInfoLog(program, bufLength, NULL, buf);
114 LOG(ERROR) << "Could not link program: "<< buf;
115 free(buf);
116 }
117 }
118 glDeleteProgram(program);
119 program = 0;
120 }
121 }
122 return program;
123 }
124
125 Gles2ExternalTextureCopier::Gles2ExternalTextureCopier()
126 : initialized_(false),
127 width_(0),
128 height_(0),
129 framebuffer_id_(0),
130 renderbuffer_id_(0),
131 program_(0),
132 position_handle_(0),
133 st_matrix_handle_(0),
134 mvp_matrix_handle_(0),
135 texture_handle_(0) {
136 memset(st_matrix_, 0, sizeof(st_matrix_));
137 }
138
139 Gles2ExternalTextureCopier::~Gles2ExternalTextureCopier() {
140 if (initialized_) {
141 glDeleteFramebuffers(1, &framebuffer_id_);
142 glDeleteRenderbuffers(1, &renderbuffer_id_);
143 }
144 }
145
146 bool Gles2ExternalTextureCopier::SetupGraphics() {
147 program_ = CreateProgram(g_vertex_shader, g_fragment_shader);
148 if (!program_) {
149 LOG(ERROR) << "Could not create program.";
150 return false;
151 }
152 position_handle_ = glGetAttribLocation(program_, "aPosition");
153 checkGlError("glGetAttribLocation");
154
155 texture_handle_ = glGetAttribLocation(program_, "aTextureCoord");
156 checkGlError("glGetAttribLocation aTextureCoord");
157
158 mvp_matrix_handle_ = glGetUniformLocation(program_, "uMVPMatrix");
159 checkGlError("glGetUniformLocation uMVPMatrix");
160
161 st_matrix_handle_ = glGetUniformLocation(program_, "uSTMatrix");
162 checkGlError("glGetUniformLocation uSTMatrix");
163
164 return true;
165 }
166
167 void Gles2ExternalTextureCopier::RenderFrame(int w, int h, GLuint texture_id) {
168 glViewport(0, 0, w, h);
169 checkGlError("glViewport");
170
171 glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
ycheo (away) 2013/01/17 08:34:44 Remove a space after the opening parenthesis.
dwkang1 2013/01/18 07:14:08 Done.
172 checkGlError("glClear");
173
174 glUseProgram(program_);
175 checkGlError("glUseProgram");
176
177 glActiveTexture(GL_TEXTURE0);
178 glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture_id);
179 checkGlError("glBindTexture");
180
181 glVertexAttribPointer(
182 position_handle_, 3, GL_FLOAT, GL_FALSE, kVerticeStride, g_vertices);
183 checkGlError("glVertexAttribPointer vPositionHandle");
184 glEnableVertexAttribArray(position_handle_);
185 checkGlError("glEnableVertexAttribArray vPositionHandle");
186
187 glVertexAttribPointer(
188 texture_handle_, 2, GL_FLOAT, GL_FALSE, kVerticeStride, g_vertices + 3);
189 checkGlError("glVertexAttribPointer aTextureHandle");
190 glEnableVertexAttribArray(texture_handle_);
191 checkGlError("glEnableVertexAttribArray aTextureHandle");
192
193 glUniformMatrix4fv(mvp_matrix_handle_, 1, GL_FALSE, g_mvp_matrix);
194 checkGlError("glUniformMatrix4fv uMVPMatrixHandle");
195
196 glUniformMatrix4fv(st_matrix_handle_, 1, GL_FALSE, st_matrix_);
197 checkGlError("glUniformMatrix4fv uSTMatrixHandle");
198
199 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
200 checkGlError("glDrawArrays");
201 }
202
203 bool Gles2ExternalTextureCopier::Init(int32 width, int32 height) {
204 if (initialized_) {
205 LOG(ERROR) << "Init should not be called twice.";
206 return false;
207 }
208
209 width_ = width;
210 height_ = height;
211
212 SetupGraphics();
213 if (!SetupFrameBuffer()) {
214 LOG(ERROR) << "Failed to create a framebuffer.";
215 return false;
216 }
217
218 initialized_ = true;
219 return initialized_;
220 }
221
222 bool Gles2ExternalTextureCopier::Copy(
223 GLuint source_texture_id, GLenum source_target,
224 float transfrom_matrix[16],
225 GLuint destination_texture_id, GLenum destination_target) {
226 if (!initialized_) {
227 return false;
228 }
229 if (source_target != GL_TEXTURE_EXTERNAL_OES
230 || destination_target != GL_TEXTURE_2D) {
231 LOG(ERROR) << "Unsupported texture targets: source("
232 << source_target << ") destination(" << destination_target << ")";
233 return false;
234 }
235
236 memcpy(st_matrix_, transfrom_matrix, sizeof(st_matrix_));
ycheo (away) 2013/01/17 08:34:44 What's the reason to copy transform_matrix to st_m
dwkang1 2013/01/18 07:14:08 Because I did this in a hurry? ;-) Fixed.
237
238 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer_id_);
239 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
240 destination_texture_id, 0);
241 GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
242 if (status != GL_FRAMEBUFFER_COMPLETE) {
243 LOG(ERROR) << "Framebuffer is not complete: " << status;
244 return false;
245 }
246 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer_id_);
247 checkGlError("glBindFramebuffer framebuffer_id_");
248 RenderFrame(width_, height_, source_texture_id);
249 glBindFramebuffer(GL_FRAMEBUFFER, 0);
250 checkGlError("glBindFramebuffer 0");
251
252 return true;
253 }
254
255 bool Gles2ExternalTextureCopier::SetupFrameBuffer() {
256 GLuint framebuffer;
257 glGenFramebuffers(1, &framebuffer);
258 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
259
260 GLuint depthbuffer;
261 glGenRenderbuffers(1, &depthbuffer);
262
263 glBindRenderbuffer(GL_RENDERBUFFER, depthbuffer);
264 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width_, height_);
265 glFramebufferRenderbuffer(
266 GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthbuffer);
267 checkGlError("glFramebufferRenderbuffer");
268
269 glBindFramebuffer(GL_FRAMEBUFFER, 0);
270 framebuffer_id_ = framebuffer;
271 renderbuffer_id_ = depthbuffer;
272 return true;
273 }
274
275 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698