diff --git a/app/src/main/java/com/example/gsyvideoplayer/DetailFilterActivity.java b/app/src/main/java/com/example/gsyvideoplayer/DetailFilterActivity.java index 84d2210a68a62439fe3c6d2abc574889c83d0005..311a9b0bca5ac50a51211879947b66e0f563cad1 100644 --- a/app/src/main/java/com/example/gsyvideoplayer/DetailFilterActivity.java +++ b/app/src/main/java/com/example/gsyvideoplayer/DetailFilterActivity.java @@ -1,6 +1,7 @@ package com.example.gsyvideoplayer; import android.graphics.Color; +import android.opengl.Matrix; import android.os.Bundle; import android.support.v4.widget.NestedScrollView; import android.view.View; @@ -45,6 +46,9 @@ import com.shuyu.gsyvideoplayer.listener.LockClickListener; import com.shuyu.gsyvideoplayer.utils.GSYVideoType; import com.shuyu.gsyvideoplayer.video.base.GSYBaseVideoPlayer; +import java.util.Timer; +import java.util.TimerTask; + import butterknife.BindView; import butterknife.ButterKnife; @@ -71,6 +75,10 @@ public class DetailFilterActivity extends GSYBaseActivityDetail { @BindView(R.id.jump) Button jump; + @BindView(R.id.change_anima) + Button anima; + + private int type = 0; private int backupRendType; @@ -79,6 +87,12 @@ public class DetailFilterActivity extends GSYBaseActivityDetail { private String url = "http://baobab.wdjcdn.com/14564977406580.mp4"; + private Timer timer = new Timer(); + + private TaskLocal mTimerTask; + + private int percentage = 1; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -118,6 +132,15 @@ public class DetailFilterActivity extends GSYBaseActivityDetail { //startActivity(new Intent(DetailControlActivity.this, MainActivity.class)); } }); + + anima.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + cancelTask(); + mTimerTask = new TaskLocal(); + timer.schedule(mTimerTask, 0, 50); + } + }); } @Override @@ -152,6 +175,27 @@ public class DetailFilterActivity extends GSYBaseActivityDetail { protected void onDestroy() { super.onDestroy(); GSYVideoType.setRenderType(backupRendType); + cancelTask(); + } + + private void cancelTask() { + if (mTimerTask != null) { + mTimerTask.cancel(); + mTimerTask = null; + } + } + + private class TaskLocal extends TimerTask { + @Override + public void run() { + float[] transform = new float[16]; + Matrix.setRotateM(transform, 0, 360 * percentage / 100, 0, 0, 1.0f); + detailPlayer.setMatrixGL(transform); + percentage++; + if (percentage > 100) { + percentage = 1; + } + } } private void loadCover(ImageView imageView, String url) { diff --git a/app/src/main/res/layout/activity_detail_filter.xml b/app/src/main/res/layout/activity_detail_filter.xml index 93c944023f504c07f594f63564a3877bb03af33c..17579709a695282c1160c234cff4a23f244ce35b 100644 --- a/app/src/main/res/layout/activity_detail_filter.xml +++ b/app/src/main/res/layout/activity_detail_filter.xml @@ -46,13 +46,20 @@ android:layout_margin="10dp" android:text="切换效果" /> + diff --git a/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/GSYRenderView.java b/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/GSYRenderView.java index 958a3f1e34e47746a9f4aa58e001bf992d2d158a..a7a99f197b35f611a454b4a65b4485235ca100ac 100644 --- a/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/GSYRenderView.java +++ b/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/GSYRenderView.java @@ -152,7 +152,7 @@ public class GSYRenderView { /** * 添加播放的view */ - public void addGLView(Context context, ViewGroup textureViewContainer, int rotate, GSYVideoGLView.onGSYSurfaceListener gsySurfaceListener, GSYVideoGLView.ShaderInterface effect) { + public void addGLView(Context context, ViewGroup textureViewContainer, int rotate, GSYVideoGLView.onGSYSurfaceListener gsySurfaceListener, GSYVideoGLView.ShaderInterface effect, float[] transform) { if (textureViewContainer.getChildCount() > 0) { textureViewContainer.removeAllViews(); } @@ -163,6 +163,10 @@ public class GSYRenderView { mShowView = gsyVideoGLView; + if (transform != null && transform.length == 16) { + gsyVideoGLView.setMVPMatrix(transform); + } + int params = getTextureParams(); if (textureViewContainer instanceof RelativeLayout) { diff --git a/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/GSYVideoGLView.java b/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/GSYVideoGLView.java index 5c95c24616a3e78a45073385f2c14c6d1d3e105d..2912b9e8818bab5d3918fe131ed7210f81b74a17 100644 --- a/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/GSYVideoGLView.java +++ b/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/GSYVideoGLView.java @@ -2,24 +2,13 @@ package com.shuyu.gsyvideoplayer; import android.annotation.SuppressLint; import android.content.Context; -import android.graphics.SurfaceTexture; -import android.opengl.GLES20; import android.opengl.GLSurfaceView; -import android.opengl.Matrix; import android.util.AttributeSet; -import android.util.Log; import android.view.Surface; import com.shuyu.gsyvideoplayer.utils.MeasureHelper; import com.shuyu.gsyvideoplayer.effect.NoEffect; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.FloatBuffer; - -import javax.microedition.khronos.egl.EGLConfig; -import javax.microedition.khronos.opengles.GL10; - /** * 在videffects的基础上调整的 @@ -31,7 +20,7 @@ public class GSYVideoGLView extends GLSurfaceView { private static final String TAG = GSYVideoGLView.class.getName(); - private VideoRender mRenderer; + private GSYVideoGLViewSimpleRender mRenderer; private Context mContext; @@ -62,7 +51,7 @@ public class GSYVideoGLView extends GLSurfaceView { private void init(Context context) { mContext = context; setEGLContextClientVersion(2); - mRenderer = new VideoRender(); + mRenderer = new GSYVideoGLViewSimpleRender(); measureHelper = new MeasureHelper(this); setRenderer(mRenderer); mRenderer.setSurfaceView(GSYVideoGLView.this); @@ -80,6 +69,12 @@ public class GSYVideoGLView extends GLSurfaceView { } } + public void setMVPMatrix(float[] MVPMatrix) { + if (MVPMatrix != null) { + mRenderer.setMVPMatrix(MVPMatrix); + } + } + @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { if (GSYVideoManager.instance().getMediaPlayer() != null) { @@ -111,261 +106,4 @@ public class GSYVideoGLView extends GLSurfaceView { return measureHelper.getMeasuredWidth(); } - private static class VideoRender implements Renderer, SurfaceTexture.OnFrameAvailableListener { - private static String TAG = VideoRender.class.getName(); - - private static final int FLOAT_SIZE_BYTES = 4; - private static final int TRIANGLE_VERTICES_DATA_STRIDE_BYTES = 5 * FLOAT_SIZE_BYTES; - private static final int TRIANGLE_VERTICES_DATA_POS_OFFSET = 0; - private static final int TRIANGLE_VERTICES_DATA_UV_OFFSET = 3; - private static final int GL_TEXTURE_EXTERNAL_OES = 0x8D65; - - private final float[] mTriangleVerticesData = { - // X, Y, Z, U, V - -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,}; - - private FloatBuffer mTriangleVertices; - - private final String mVertexShader = "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"; - private float[] mMVPMatrix = new float[16]; - private float[] mSTMatrix = new float[16]; - - private int mProgram; - private int mTextureID[] = new int[2]; - private int muMVPMatrixHandle; - private int muSTMatrixHandle; - private int maPositionHandle; - private int maTextureHandle; - private boolean updateSurface = false; - - private SurfaceTexture mSurface; - - private onGSYSurfaceListener mGSYSurfaceListener; - - private ShaderInterface mEffect = new NoEffect(); - - private GLSurfaceView mSurfaceView; - - - public void setEffect(ShaderInterface shaderEffect) { - if (shaderEffect != null) - mEffect = shaderEffect; - } - - public VideoRender() { - mTriangleVertices = ByteBuffer - .allocateDirect( - mTriangleVerticesData.length * FLOAT_SIZE_BYTES) - .order(ByteOrder.nativeOrder()).asFloatBuffer(); - mTriangleVertices.put(mTriangleVerticesData).position(0); - - Matrix.setIdentityM(mSTMatrix, 0); - } - - public void setGSYSurfaceListener(onGSYSurfaceListener onSurfaceListener) { - this.mGSYSurfaceListener = onSurfaceListener; - } - - public void setSurfaceView(GLSurfaceView surfaceView) { - this.mSurfaceView = surfaceView; - } - - @Override - public void onDrawFrame(GL10 glUnused) { - synchronized (this) { - if (updateSurface) { - mSurface.updateTexImage(); - mSurface.getTransformMatrix(mSTMatrix); - updateSurface = false; - } - } - mProgram = createProgram(mVertexShader, mEffect.getShader(mSurfaceView)); - GLES20.glClearColor(0.0f, 1.0f, 0.0f, 1.0f); - GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT - | GLES20.GL_COLOR_BUFFER_BIT); - - GLES20.glUseProgram(mProgram); - checkGlError("glUseProgram"); - - GLES20.glActiveTexture(GLES20.GL_TEXTURE0); - GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureID[0]); - - mTriangleVertices.position(TRIANGLE_VERTICES_DATA_POS_OFFSET); - GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT, - false, TRIANGLE_VERTICES_DATA_STRIDE_BYTES, - mTriangleVertices); - checkGlError("glVertexAttribPointer maPosition"); - GLES20.glEnableVertexAttribArray(maPositionHandle); - checkGlError("glEnableVertexAttribArray maPositionHandle"); - - mTriangleVertices.position(TRIANGLE_VERTICES_DATA_UV_OFFSET); - GLES20.glVertexAttribPointer(maTextureHandle, 3, GLES20.GL_FLOAT, - false, TRIANGLE_VERTICES_DATA_STRIDE_BYTES, - mTriangleVertices); - checkGlError("glVertexAttribPointer maTextureHandle"); - GLES20.glEnableVertexAttribArray(maTextureHandle); - checkGlError("glEnableVertexAttribArray maTextureHandle"); - - Matrix.setIdentityM(mMVPMatrix, 0); - GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mMVPMatrix, - 0); - GLES20.glUniformMatrix4fv(muSTMatrixHandle, 1, false, mSTMatrix, 0); - - GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); - checkGlError("glDrawArrays"); - GLES20.glFinish(); - - } - - @Override - public void onSurfaceChanged(GL10 glUnused, int width, int height) { - GLES20.glViewport(0, 0, width, height); - } - - @Override - public void onSurfaceCreated(GL10 glUnused, EGLConfig config) { - - mProgram = createProgram(mVertexShader, mEffect.getShader(mSurfaceView)); - if (mProgram == 0) { - return; - } - maPositionHandle = GLES20 - .glGetAttribLocation(mProgram, "aPosition"); - checkGlError("glGetAttribLocation aPosition"); - if (maPositionHandle == -1) { - throw new RuntimeException( - "Could not get attrib location for aPosition"); - } - maTextureHandle = GLES20.glGetAttribLocation(mProgram, - "aTextureCoord"); - checkGlError("glGetAttribLocation aTextureCoord"); - if (maTextureHandle == -1) { - throw new RuntimeException( - "Could not get attrib location for aTextureCoord"); - } - - muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, - "uMVPMatrix"); - checkGlError("glGetUniformLocation uMVPMatrix"); - if (muMVPMatrixHandle == -1) { - throw new RuntimeException( - "Could not get attrib location for uMVPMatrix"); - } - - muSTMatrixHandle = GLES20.glGetUniformLocation(mProgram, - "uSTMatrix"); - checkGlError("glGetUniformLocation uSTMatrix"); - if (muSTMatrixHandle == -1) { - throw new RuntimeException( - "Could not get attrib location for uSTMatrix"); - } - - // int[] textures = new int[1]; - GLES20.glGenTextures(2, mTextureID, 0); - // GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureID[0]); - - // mTextureID = textures[0]; - GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureID[0]); - checkGlError("glBindTexture mTextureID"); - - // GLES20.glTexParameterf(GL_TEXTURE_EXTERNAL_OES, - // GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST); - // GLES20.glTexParameterf(GL_TEXTURE_EXTERNAL_OES, - // GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); - GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, - GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); - GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, - GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); - GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, - GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); - GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, - GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); - - /* - * Create the SurfaceTexture that will feed this textureID, and pass - * it to the MediaPlayer - */ - mSurface = new SurfaceTexture(mTextureID[0]); - mSurface.setOnFrameAvailableListener(this); - - Surface surface = new Surface(mSurface); - if (mGSYSurfaceListener != null) { - mGSYSurfaceListener.onSurfaceAvailable(surface); - } - //surface.release(); - } - - @Override - synchronized public void onFrameAvailable(SurfaceTexture surface) { - updateSurface = true; - } - - private int loadShader(int shaderType, String source) { - int shader = GLES20.glCreateShader(shaderType); - if (shader != 0) { - GLES20.glShaderSource(shader, source); - GLES20.glCompileShader(shader); - int[] compiled = new int[1]; - GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, - compiled, 0); - if (compiled[0] == 0) { - Log.e(TAG, "Could not compile shader " + shaderType + ":"); - Log.e(TAG, GLES20.glGetShaderInfoLog(shader)); - GLES20.glDeleteShader(shader); - shader = 0; - } - } - return shader; - } - - private int createProgram(String vertexSource, String fragmentSource) { - int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexSource); - if (vertexShader == 0) { - return 0; - } - int pixelShader = loadShader(GLES20.GL_FRAGMENT_SHADER, - fragmentSource); - if (pixelShader == 0) { - return 0; - } - - int program = GLES20.glCreateProgram(); - if (program != 0) { - GLES20.glAttachShader(program, vertexShader); - checkGlError("glAttachShader"); - GLES20.glAttachShader(program, pixelShader); - checkGlError("glAttachShader"); - GLES20.glLinkProgram(program); - int[] linkStatus = new int[1]; - GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, - linkStatus, 0); - if (linkStatus[0] != GLES20.GL_TRUE) { - Log.e(TAG, "Could not link program: "); - Log.e(TAG, GLES20.glGetProgramInfoLog(program)); - GLES20.glDeleteProgram(program); - program = 0; - } - } - return program; - } - - private void checkGlError(String op) { - int error; - while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) { - Log.e(TAG, op + ": glError " + error); - throw new RuntimeException(op + ": glError " + error); - } - } - - } - } diff --git a/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/GSYVideoGLViewSimpleRender.java b/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/GSYVideoGLViewSimpleRender.java new file mode 100644 index 0000000000000000000000000000000000000000..0a04bf0f0b6801469e0ef43fa27856cdfc8339a6 --- /dev/null +++ b/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/GSYVideoGLViewSimpleRender.java @@ -0,0 +1,279 @@ +package com.shuyu.gsyvideoplayer; + +import android.annotation.SuppressLint; +import android.graphics.SurfaceTexture; +import android.opengl.GLES20; +import android.opengl.GLSurfaceView; +import android.opengl.Matrix; +import android.util.Log; +import android.view.Surface; + +import com.shuyu.gsyvideoplayer.effect.NoEffect; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.FloatBuffer; + +import javax.microedition.khronos.egl.EGLConfig; +import javax.microedition.khronos.opengles.GL10; + + +/** + * 在videffects的基础上调整的 + *
+ * 原 @author sheraz.khilji + */ +@SuppressLint("ViewConstructor") +public class GSYVideoGLViewSimpleRender implements GLSurfaceView.Renderer, SurfaceTexture.OnFrameAvailableListener { + + private static String TAG = GSYVideoGLViewSimpleRender.class.getName(); + + private static final int FLOAT_SIZE_BYTES = 4; + private static final int TRIANGLE_VERTICES_DATA_STRIDE_BYTES = 5 * FLOAT_SIZE_BYTES; + private static final int TRIANGLE_VERTICES_DATA_POS_OFFSET = 0; + private static final int TRIANGLE_VERTICES_DATA_UV_OFFSET = 3; + private static final int GL_TEXTURE_EXTERNAL_OES = 0x8D65; + + private final float[] mTriangleVerticesData = { + // X, Y, Z, U, V + -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,}; + + private FloatBuffer mTriangleVertices; + + private final String mVertexShader = "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"; + private float[] mMVPMatrix = new float[16]; + private float[] mSTMatrix = new float[16]; + + private int mProgram; + private int mTextureID[] = new int[2]; + private int muMVPMatrixHandle; + private int muSTMatrixHandle; + private int maPositionHandle; + private int maTextureHandle; + private boolean updateSurface = false; + private boolean mChangeMVPMatrix = false; + + private SurfaceTexture mSurface; + + private GSYVideoGLView.onGSYSurfaceListener mGSYSurfaceListener; + + private GSYVideoGLView.ShaderInterface mEffect = new NoEffect(); + + private GLSurfaceView mSurfaceView; + + + public void setEffect(GSYVideoGLView.ShaderInterface shaderEffect) { + if (shaderEffect != null) + mEffect = shaderEffect; + } + + public GSYVideoGLViewSimpleRender() { + mTriangleVertices = ByteBuffer + .allocateDirect( + mTriangleVerticesData.length * FLOAT_SIZE_BYTES) + .order(ByteOrder.nativeOrder()).asFloatBuffer(); + mTriangleVertices.put(mTriangleVerticesData).position(0); + + Matrix.setIdentityM(mSTMatrix, 0); + Matrix.setIdentityM(mMVPMatrix, 0); + } + + public void setGSYSurfaceListener(GSYVideoGLView.onGSYSurfaceListener onSurfaceListener) { + this.mGSYSurfaceListener = onSurfaceListener; + } + + public void setSurfaceView(GLSurfaceView surfaceView) { + this.mSurfaceView = surfaceView; + } + + public void setMVPMatrix(float[] MVPMatrix) { + this.mMVPMatrix = MVPMatrix; + mChangeMVPMatrix = true; + } + + @Override + public void onDrawFrame(GL10 glUnused) { + synchronized (this) { + if (updateSurface) { + mSurface.updateTexImage(); + mSurface.getTransformMatrix(mSTMatrix); + updateSurface = false; + } + } + mProgram = createProgram(mVertexShader, mEffect.getShader(mSurfaceView)); + GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT + | GLES20.GL_COLOR_BUFFER_BIT); + + GLES20.glUseProgram(mProgram); + checkGlError("glUseProgram"); + + GLES20.glActiveTexture(GLES20.GL_TEXTURE0); + GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureID[0]); + + mTriangleVertices.position(TRIANGLE_VERTICES_DATA_POS_OFFSET); + GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT, + false, TRIANGLE_VERTICES_DATA_STRIDE_BYTES, + mTriangleVertices); + checkGlError("glVertexAttribPointer maPosition"); + GLES20.glEnableVertexAttribArray(maPositionHandle); + checkGlError("glEnableVertexAttribArray maPositionHandle"); + + mTriangleVertices.position(TRIANGLE_VERTICES_DATA_UV_OFFSET); + GLES20.glVertexAttribPointer(maTextureHandle, 3, GLES20.GL_FLOAT, + false, TRIANGLE_VERTICES_DATA_STRIDE_BYTES, + mTriangleVertices); + checkGlError("glVertexAttribPointer maTextureHandle"); + GLES20.glEnableVertexAttribArray(maTextureHandle); + checkGlError("glEnableVertexAttribArray maTextureHandle"); + + GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mMVPMatrix, + 0); + GLES20.glUniformMatrix4fv(muSTMatrixHandle, 1, false, mSTMatrix, 0); + + GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); + checkGlError("glDrawArrays"); + GLES20.glFinish(); + + } + + @Override + public void onSurfaceChanged(GL10 glUnused, int width, int height) { + GLES20.glViewport(0, 0, width, height); + } + + @Override + public void onSurfaceCreated(GL10 glUnused, EGLConfig config) { + + mProgram = createProgram(mVertexShader, mEffect.getShader(mSurfaceView)); + if (mProgram == 0) { + return; + } + maPositionHandle = GLES20 + .glGetAttribLocation(mProgram, "aPosition"); + checkGlError("glGetAttribLocation aPosition"); + if (maPositionHandle == -1) { + throw new RuntimeException( + "Could not get attrib location for aPosition"); + } + maTextureHandle = GLES20.glGetAttribLocation(mProgram, + "aTextureCoord"); + checkGlError("glGetAttribLocation aTextureCoord"); + if (maTextureHandle == -1) { + throw new RuntimeException( + "Could not get attrib location for aTextureCoord"); + } + + muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, + "uMVPMatrix"); + checkGlError("glGetUniformLocation uMVPMatrix"); + if (muMVPMatrixHandle == -1) { + throw new RuntimeException( + "Could not get attrib location for uMVPMatrix"); + } + + muSTMatrixHandle = GLES20.glGetUniformLocation(mProgram, + "uSTMatrix"); + checkGlError("glGetUniformLocation uSTMatrix"); + if (muSTMatrixHandle == -1) { + throw new RuntimeException( + "Could not get attrib location for uSTMatrix"); + } + + GLES20.glGenTextures(2, mTextureID, 0); + + GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureID[0]); + checkGlError("glBindTexture mTextureID"); + + GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, + GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); + GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, + GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); + GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, + GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); + GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, + GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); + + mSurface = new SurfaceTexture(mTextureID[0]); + mSurface.setOnFrameAvailableListener(this); + + Surface surface = new Surface(mSurface); + if (mGSYSurfaceListener != null) { + mGSYSurfaceListener.onSurfaceAvailable(surface); + } + } + + @Override + synchronized public void onFrameAvailable(SurfaceTexture surface) { + updateSurface = true; + } + + private int loadShader(int shaderType, String source) { + int shader = GLES20.glCreateShader(shaderType); + if (shader != 0) { + GLES20.glShaderSource(shader, source); + GLES20.glCompileShader(shader); + int[] compiled = new int[1]; + GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, + compiled, 0); + if (compiled[0] == 0) { + Log.e(TAG, "Could not compile shader " + shaderType + ":"); + Log.e(TAG, GLES20.glGetShaderInfoLog(shader)); + GLES20.glDeleteShader(shader); + shader = 0; + } + } + return shader; + } + + private int createProgram(String vertexSource, String fragmentSource) { + int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexSource); + if (vertexShader == 0) { + return 0; + } + int pixelShader = loadShader(GLES20.GL_FRAGMENT_SHADER, + fragmentSource); + if (pixelShader == 0) { + return 0; + } + + int program = GLES20.glCreateProgram(); + if (program != 0) { + GLES20.glAttachShader(program, vertexShader); + checkGlError("glAttachShader"); + GLES20.glAttachShader(program, pixelShader); + checkGlError("glAttachShader"); + GLES20.glLinkProgram(program); + int[] linkStatus = new int[1]; + GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, + linkStatus, 0); + if (linkStatus[0] != GLES20.GL_TRUE) { + Log.e(TAG, "Could not link program: "); + Log.e(TAG, GLES20.glGetProgramInfoLog(program)); + GLES20.glDeleteProgram(program); + program = 0; + } + } + return program; + } + + private void checkGlError(String op) { + int error; + while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) { + Log.e(TAG, op + ": glError " + error); + throw new RuntimeException(op + ": glError " + error); + } + } + +} + + diff --git a/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/video/base/GSYTextureRenderView.java b/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/video/base/GSYTextureRenderView.java index cbf6f9a10439149276f0384c742c4248848212a4..06ac1ec6421843fb44060dd5ff2f124a4e8b4cc9 100644 --- a/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/video/base/GSYTextureRenderView.java +++ b/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/video/base/GSYTextureRenderView.java @@ -41,6 +41,8 @@ public abstract class GSYTextureRenderView extends FrameLayout implements Textur //滤镜 protected GSYVideoGLView.ShaderInterface mEffectFilter = new NoEffect(); + protected float[] mMatrixGL = null; + //画面选择角度 protected int mRotate; @@ -133,7 +135,7 @@ public abstract class GSYTextureRenderView extends FrameLayout implements Textur mTextureView.addSurfaceView(getContext(), mTextureViewContainer, mRotate, this); return; } else if (GSYVideoType.getRenderType() == GSYVideoType.GLSURFACE) { - mTextureView.addGLView(getContext(), mTextureViewContainer, mRotate, this, mEffectFilter); + mTextureView.addGLView(getContext(), mTextureViewContainer, mRotate, this, mEffectFilter, mMatrixGL); return; } mTextureView.addTextureView(getContext(), mTextureViewContainer, mRotate, this); @@ -210,4 +212,14 @@ public abstract class GSYTextureRenderView extends FrameLayout implements Textur gsyVideoGLView.setEffect(effectFilter); } } + + public void setMatrixGL(float[] matrixGL) { + this.mMatrixGL = matrixGL; + if (mTextureView != null && mTextureView.getShowView() instanceof GSYVideoGLView + && mMatrixGL != null && mMatrixGL.length == 16) { + GSYVideoGLView gsyVideoGLView = + (GSYVideoGLView) mTextureView.getShowView(); + gsyVideoGLView.setMVPMatrix(mMatrixGL); + } + } } diff --git a/gsyVideoPlayer/build.gradle b/gsyVideoPlayer/build.gradle index 8c4d733cf77265ec0140031c0e954e03cabe6737..7a0d3e3973a5fc08359757866ae983871c0e01d8 100644 --- a/gsyVideoPlayer/build.gradle +++ b/gsyVideoPlayer/build.gradle @@ -31,7 +31,7 @@ android { dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) - //compile project(':gsyVideoPlayer-java') + compile project(':gsyVideoPlayer-java') //compile project(':gsyVideoPlayer-armv5') //compile project(':gsyVideoPlayer-armv7a') //compile project(':gsyVideoPlayer-armv64') @@ -41,7 +41,7 @@ dependencies { //更多配置版so,增加了concat,rtsp,mpeg,crypto //compile project(':gsyVideoPlayer-ex_so') - compile 'com.shuyu:gsyVideoPlayer-java:2.0.8' + //compile 'com.shuyu:gsyVideoPlayer-java:2.0.8' compile 'com.shuyu:gsyVideoPlayer-armv5:2.0.8' compile 'com.shuyu:gsyVideoPlayer-armv7a:2.0.8'