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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: content/common/gpu/media/gles2_external_texture_copier.cc
diff --git a/content/common/gpu/media/gles2_external_texture_copier.cc b/content/common/gpu/media/gles2_external_texture_copier.cc
new file mode 100644
index 0000000000000000000000000000000000000000..7da6b6cf5438bf01d984d0a2c0d25a0edd63d64f
--- /dev/null
+++ b/content/common/gpu/media/gles2_external_texture_copier.cc
@@ -0,0 +1,275 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/common/gpu/media/gles2_external_texture_copier.h"
+
+#include "base/logging.h"
+
+namespace content {
+
+static void checkGlError(const char* op) {
+ for (GLint error = glGetError(); error; error = glGetError()) {
+ LOG(ERROR) << "after " << op <<" glError (0x" << std::hex << error << ")";
+ NOTREACHED();
+ }
+}
+
+static const char g_vertex_shader[] =
+ "uniform mat4 uMVPMatrix;\n"
+ "uniform mat4 uSTMatrix;\n"
+ "attribute vec4 aPosition;\n"
+ "attribute vec4 aTextureCoord;\n"
+ "varying vec2 vTextureCoord;\n"
+ "void main() {\n"
+ " gl_Position = uMVPMatrix * aPosition;\n"
+ " vTextureCoord = (uSTMatrix * aTextureCoord).xy;\n"
+ "}\n";
+
+static const char g_fragment_shader[] =
+ "#extension GL_OES_EGL_image_external : require\n"
+ "precision mediump float;\n"
+ "varying vec2 vTextureCoord;\n"
+ "uniform samplerExternalOES sTexture;\n"
+ "void main() {\n"
+ " gl_FragColor = texture2D(sTexture, vTextureCoord);\n"
+ "}\n";
+
+enum { kVerticeStride = 5 * sizeof(float) };
+
+static const GLfloat g_vertices[] = {
+ -1.0f, -1.0f, 0, 0.f, 0.f,
+ 1.0f, -1.0f, 0, 1.f, 0.f,
+ -1.0f, 1.0f, 0, 0.f, 1.f,
+ 1.0f, 1.0f, 0, 1.f, 1.f,
+};
+
+// Due to the absence of matrix functions in NDK, a pre-calculated matrix
+// is used. g_mvp_matrix = P * L * I
+// Matrix.setLookAtM(L, 0, 0, 0, 2, 0, 0, 0, 0, -1, 0);
+// Matrix.orthoM(P, 0, -1, 1, -1, 1, 1, 3);
+// Matrix.setIdentityM(I, 0);
+// TODO(dwkang): currently, (0, -1, 0) is used for the up vector.
+// figure out why up vector (0, 1, 0) generates flipped screen.
+static const GLfloat g_mvp_matrix[] = {
+ 1.f, 0.f, 0.f, 0.f,
+ 0.f, -1.f, 0.f, 0.f,
+ 0.f, 0.f, -1.f, 0.f,
+ 0.f, 0.f, 0.f, 1.f,
+};
+
+static GLuint LoadShader(GLenum shaderType, const char* pSource) {
+ GLuint shader = glCreateShader(shaderType);
+ if (shader) {
+ glShaderSource(shader, 1, &pSource, NULL);
+ glCompileShader(shader);
+ GLint compiled = 0;
+ glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
+ if (!compiled) {
+ GLint infoLen = 0;
+ glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
+ if (infoLen) {
+ char* buf = (char*) malloc(infoLen);
+ if (buf) {
+ glGetShaderInfoLog(shader, infoLen, NULL, buf);
+ LOG(ERROR) << "Could not compile shader : " << buf;
+ free(buf);
+ }
+ glDeleteShader(shader);
+ shader = 0;
+ }
+ }
+ }
+ return shader;
+}
+
+static GLuint CreateProgram(
+ const char* pVertexSource, const char* pFragmentSource) {
+ GLuint vertexShader = LoadShader(GL_VERTEX_SHADER, pVertexSource);
+ if (!vertexShader) {
+ return 0;
+ }
+
+ GLuint pixelShader = LoadShader(GL_FRAGMENT_SHADER, pFragmentSource);
+ if (!pixelShader) {
+ return 0;
+ }
+
+ GLuint program = glCreateProgram();
+ if (program) {
+ glAttachShader(program, vertexShader);
+ checkGlError("glAttachShader");
+ glAttachShader(program, pixelShader);
+ checkGlError("glAttachShader");
+ glLinkProgram(program);
+ GLint linkStatus = GL_FALSE;
+ glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
+ if (linkStatus != GL_TRUE) {
+ GLint bufLength = 0;
+ glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
+ if (bufLength) {
+ char* buf = (char*) malloc(bufLength);
+ if (buf) {
+ glGetProgramInfoLog(program, bufLength, NULL, buf);
+ LOG(ERROR) << "Could not link program: "<< buf;
+ free(buf);
+ }
+ }
+ glDeleteProgram(program);
+ program = 0;
+ }
+ }
+ return program;
+}
+
+Gles2ExternalTextureCopier::Gles2ExternalTextureCopier()
+ : initialized_(false),
+ width_(0),
+ height_(0),
+ framebuffer_id_(0),
+ renderbuffer_id_(0),
+ program_(0),
+ position_handle_(0),
+ st_matrix_handle_(0),
+ mvp_matrix_handle_(0),
+ texture_handle_(0) {
+ memset(st_matrix_, 0, sizeof(st_matrix_));
+}
+
+Gles2ExternalTextureCopier::~Gles2ExternalTextureCopier() {
+ if (initialized_) {
+ glDeleteFramebuffers(1, &framebuffer_id_);
+ glDeleteRenderbuffers(1, &renderbuffer_id_);
+ }
+}
+
+bool Gles2ExternalTextureCopier::SetupGraphics() {
+ program_ = CreateProgram(g_vertex_shader, g_fragment_shader);
+ if (!program_) {
+ LOG(ERROR) << "Could not create program.";
+ return false;
+ }
+ position_handle_ = glGetAttribLocation(program_, "aPosition");
+ checkGlError("glGetAttribLocation");
+
+ texture_handle_ = glGetAttribLocation(program_, "aTextureCoord");
+ checkGlError("glGetAttribLocation aTextureCoord");
+
+ mvp_matrix_handle_ = glGetUniformLocation(program_, "uMVPMatrix");
+ checkGlError("glGetUniformLocation uMVPMatrix");
+
+ st_matrix_handle_ = glGetUniformLocation(program_, "uSTMatrix");
+ checkGlError("glGetUniformLocation uSTMatrix");
+
+ return true;
+}
+
+void Gles2ExternalTextureCopier::RenderFrame(int w, int h, GLuint texture_id) {
+ glViewport(0, 0, w, h);
+ checkGlError("glViewport");
+
+ 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.
+ checkGlError("glClear");
+
+ glUseProgram(program_);
+ checkGlError("glUseProgram");
+
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture_id);
+ checkGlError("glBindTexture");
+
+ glVertexAttribPointer(
+ position_handle_, 3, GL_FLOAT, GL_FALSE, kVerticeStride, g_vertices);
+ checkGlError("glVertexAttribPointer vPositionHandle");
+ glEnableVertexAttribArray(position_handle_);
+ checkGlError("glEnableVertexAttribArray vPositionHandle");
+
+ glVertexAttribPointer(
+ texture_handle_, 2, GL_FLOAT, GL_FALSE, kVerticeStride, g_vertices + 3);
+ checkGlError("glVertexAttribPointer aTextureHandle");
+ glEnableVertexAttribArray(texture_handle_);
+ checkGlError("glEnableVertexAttribArray aTextureHandle");
+
+ glUniformMatrix4fv(mvp_matrix_handle_, 1, GL_FALSE, g_mvp_matrix);
+ checkGlError("glUniformMatrix4fv uMVPMatrixHandle");
+
+ glUniformMatrix4fv(st_matrix_handle_, 1, GL_FALSE, st_matrix_);
+ checkGlError("glUniformMatrix4fv uSTMatrixHandle");
+
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ checkGlError("glDrawArrays");
+}
+
+bool Gles2ExternalTextureCopier::Init(int32 width, int32 height) {
+ if (initialized_) {
+ LOG(ERROR) << "Init should not be called twice.";
+ return false;
+ }
+
+ width_ = width;
+ height_ = height;
+
+ SetupGraphics();
+ if (!SetupFrameBuffer()) {
+ LOG(ERROR) << "Failed to create a framebuffer.";
+ return false;
+ }
+
+ initialized_ = true;
+ return initialized_;
+}
+
+bool Gles2ExternalTextureCopier::Copy(
+ GLuint source_texture_id, GLenum source_target,
+ float transfrom_matrix[16],
+ GLuint destination_texture_id, GLenum destination_target) {
+ if (!initialized_) {
+ return false;
+ }
+ if (source_target != GL_TEXTURE_EXTERNAL_OES
+ || destination_target != GL_TEXTURE_2D) {
+ LOG(ERROR) << "Unsupported texture targets: source("
+ << source_target << ") destination(" << destination_target << ")";
+ return false;
+ }
+
+ 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.
+
+ glBindFramebuffer(GL_FRAMEBUFFER, framebuffer_id_);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
+ destination_texture_id, 0);
+ GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+ if (status != GL_FRAMEBUFFER_COMPLETE) {
+ LOG(ERROR) << "Framebuffer is not complete: " << status;
+ return false;
+ }
+ glBindFramebuffer(GL_FRAMEBUFFER, framebuffer_id_);
+ checkGlError("glBindFramebuffer framebuffer_id_");
+ RenderFrame(width_, height_, source_texture_id);
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ checkGlError("glBindFramebuffer 0");
+
+ return true;
+}
+
+bool Gles2ExternalTextureCopier::SetupFrameBuffer() {
+ GLuint framebuffer;
+ glGenFramebuffers(1, &framebuffer);
+ glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
+
+ GLuint depthbuffer;
+ glGenRenderbuffers(1, &depthbuffer);
+
+ glBindRenderbuffer(GL_RENDERBUFFER, depthbuffer);
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width_, height_);
+ glFramebufferRenderbuffer(
+ GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthbuffer);
+ checkGlError("glFramebufferRenderbuffer");
+
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ framebuffer_id_ = framebuffer;
+ renderbuffer_id_ = depthbuffer;
+ return true;
+}
+
+} // namespace content

Powered by Google App Engine
This is Rietveld 408576698