From 8aaa4be3ad1a2e51fb90e3589dc832230b76a448 Mon Sep 17 00:00:00 2001 From: shuyu <359369982@qq.com> Date: Sat, 16 Sep 2017 22:03:55 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BA=86=E6=BB=A4=E9=95=9C?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=20(2017-09-16=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gsyvideoplayer/GSYApplication.java | 1 + .../shuyu/gsyvideoplayer/GSYRenderView.java | 56 ++- .../shuyu/gsyvideoplayer/GSYVideoGLView.java | 369 ++++++++++++++++++ .../builder/GSYVideoOptionBuilder.java | 14 + .../gsyvideoplayer/effect/AutoFixEffect.java | 90 +++++ .../effect/BlackAndWhiteEffect.java | 36 ++ .../effect/BrightnessEffect.java | 46 +++ .../gsyvideoplayer/effect/ContrastEffect.java | 44 +++ .../effect/CrossProcessEffect.java | 48 +++ .../effect/DocumentaryEffect.java | 116 ++++++ .../gsyvideoplayer/effect/DuotoneEffect.java | 74 ++++ .../effect/FillLightEffect.java | 67 ++++ .../gsyvideoplayer/effect/GammaEffect.java | 46 +++ .../gsyvideoplayer/effect/GrainEffect.java | 105 +++++ .../effect/GreyScaleEffect.java | 35 ++ .../gsyvideoplayer/effect/HueEffect.java | 71 ++++ .../effect/InvertColorsEffect.java | 37 ++ .../gsyvideoplayer/effect/LamoishEffect.java | 160 ++++++++ .../shuyu/gsyvideoplayer/effect/NoEffect.java | 33 ++ .../effect/PosterizeEffect.java | 36 ++ .../effect/SaturationEffect.java | 89 +++++ .../gsyvideoplayer/effect/SepiaEffect.java | 51 +++ .../effect/SharpnessEffect.java | 83 ++++ .../effect/TemperatureEffect.java | 57 +++ .../gsyvideoplayer/effect/TintEffect.java | 65 +++ .../gsyvideoplayer/effect/VignetteEffect.java | 97 +++++ .../gsyvideoplayer/utils/GSYVideoType.java | 4 + .../video/base/GSYTextureRenderView.java | 39 +- .../video/base/GSYVideoView.java | 4 + 29 files changed, 1963 insertions(+), 10 deletions(-) create mode 100644 gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/GSYVideoGLView.java create mode 100644 gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/AutoFixEffect.java create mode 100644 gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/BlackAndWhiteEffect.java create mode 100644 gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/BrightnessEffect.java create mode 100644 gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/ContrastEffect.java create mode 100644 gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/CrossProcessEffect.java create mode 100644 gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/DocumentaryEffect.java create mode 100644 gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/DuotoneEffect.java create mode 100644 gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/FillLightEffect.java create mode 100644 gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/GammaEffect.java create mode 100644 gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/GrainEffect.java create mode 100644 gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/GreyScaleEffect.java create mode 100644 gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/HueEffect.java create mode 100644 gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/InvertColorsEffect.java create mode 100644 gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/LamoishEffect.java create mode 100644 gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/NoEffect.java create mode 100644 gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/PosterizeEffect.java create mode 100644 gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/SaturationEffect.java create mode 100644 gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/SepiaEffect.java create mode 100644 gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/SharpnessEffect.java create mode 100644 gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/TemperatureEffect.java create mode 100644 gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/TintEffect.java create mode 100644 gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/VignetteEffect.java diff --git a/app/src/main/java/com/example/gsyvideoplayer/GSYApplication.java b/app/src/main/java/com/example/gsyvideoplayer/GSYApplication.java index 95e284b..27ac44c 100644 --- a/app/src/main/java/com/example/gsyvideoplayer/GSYApplication.java +++ b/app/src/main/java/com/example/gsyvideoplayer/GSYApplication.java @@ -28,5 +28,6 @@ public class GSYApplication extends Application { //GSYVideoType.setShowType(GSYVideoType.SCREEN_MATCH_FULL); //GSYVideoType.setShowType(GSYVideoType.SCREEN_TYPE_FULL); //GSYVideoType.setRenderType(GSYVideoType.SUFRACE); + GSYVideoType.setRenderType(GSYVideoType.GLSURFACE); } } 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 47447eb..958a3f1 100644 --- a/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/GSYRenderView.java +++ b/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/GSYRenderView.java @@ -29,7 +29,8 @@ public class GSYRenderView { } public void requestLayout() { - mShowView.requestLayout(); + if (mShowView != null) + mShowView.requestLayout(); } public float getRotation() { @@ -37,7 +38,8 @@ public class GSYRenderView { } public void setRotation(float rotation) { - mShowView.setRotation(rotation); + if (mShowView != null) + mShowView.setRotation(rotation); } public void invalidate() { @@ -52,6 +54,10 @@ public class GSYRenderView { return mShowView.getHeight(); } + public View getShowView() { + return mShowView; + } + /** * 暂停时初始化位图 */ @@ -70,7 +76,24 @@ public class GSYRenderView { } public void setLayoutParams(ViewGroup.LayoutParams layoutParams) { - mShowView.setLayoutParams(layoutParams); + if (mShowView != null) + mShowView.setLayoutParams(layoutParams); + } + + public void onResume() { + if (mShowView instanceof GSYVideoGLView) { + GSYVideoGLView gsyVideoGLView = (GSYVideoGLView) mShowView; + gsyVideoGLView.requestLayout(); + gsyVideoGLView.onResume(); + } + } + + public void onPause() { + if (mShowView instanceof GSYVideoGLView) { + GSYVideoGLView gsyVideoGLView = (GSYVideoGLView) mShowView; + gsyVideoGLView.requestLayout(); + gsyVideoGLView.onPause(); + } } /** @@ -126,6 +149,33 @@ public class GSYRenderView { } } + /** + * 添加播放的view + */ + public void addGLView(Context context, ViewGroup textureViewContainer, int rotate, GSYVideoGLView.onGSYSurfaceListener gsySurfaceListener, GSYVideoGLView.ShaderInterface effect) { + if (textureViewContainer.getChildCount() > 0) { + textureViewContainer.removeAllViews(); + } + GSYVideoGLView gsyVideoGLView = new GSYVideoGLView(context); + gsyVideoGLView.setEffect(effect); + gsyVideoGLView.setGSYSurfaceListener(gsySurfaceListener); + gsyVideoGLView.setRotation(rotate); + + mShowView = gsyVideoGLView; + + int params = getTextureParams(); + + if (textureViewContainer instanceof RelativeLayout) { + RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(params, params); + layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT); + textureViewContainer.addView(gsyVideoGLView, layoutParams); + } else if (textureViewContainer instanceof FrameLayout) { + FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(params, params); + layoutParams.gravity = Gravity.CENTER; + textureViewContainer.addView(gsyVideoGLView, layoutParams); + } + } + /** * 获取布局参数 * diff --git a/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/GSYVideoGLView.java b/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/GSYVideoGLView.java new file mode 100644 index 0000000..3628923 --- /dev/null +++ b/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/GSYVideoGLView.java @@ -0,0 +1,369 @@ +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; + + +/** + * 原 @author sheraz.khilji + */ +@SuppressLint("ViewConstructor") +public class GSYVideoGLView extends GLSurfaceView { + + private static final String TAG = GSYVideoGLView.class.getName(); + + private VideoRender mRenderer; + + private Context mContext; + + private ShaderInterface mEffect = new NoEffect(); + + private MeasureHelper measureHelper; + + private onGSYSurfaceListener mGSYSurfaceListener; + + public interface onGSYSurfaceListener { + void onSurfaceAvailable(Surface surface); + } + + public interface ShaderInterface { + String getShader(GLSurfaceView mGlSurfaceView); + } + + public GSYVideoGLView(Context context) { + super(context); + init(context); + } + + public GSYVideoGLView(Context context, AttributeSet attrs) { + super(context, attrs); + init(context); + } + + private void init(Context context) { + mContext = context; + setEGLContextClientVersion(2); + mRenderer = new VideoRender(); + measureHelper = new MeasureHelper(this); + setRenderer(mRenderer); + mRenderer.setSurfaceView(GSYVideoGLView.this); + } + + public void setGSYSurfaceListener(onGSYSurfaceListener mGSYSurfaceListener) { + this.mGSYSurfaceListener = mGSYSurfaceListener; + mRenderer.setGSYSurfaceListener(this.mGSYSurfaceListener); + } + + public void setEffect(ShaderInterface shaderEffect) { + if (shaderEffect != null) { + mEffect = shaderEffect; + mRenderer.setEffect(mEffect); + } + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + if (GSYVideoManager.instance().getMediaPlayer() != null) { + try { + int videoWidth = GSYVideoManager.instance().getCurrentVideoWidth(); + int videoHeight = GSYVideoManager.instance().getCurrentVideoHeight(); + + int videoSarNum = GSYVideoManager.instance().getMediaPlayer().getVideoSarNum(); + int videoSarDen = GSYVideoManager.instance().getMediaPlayer().getVideoSarDen(); + + if (videoWidth > 0 && videoHeight > 0) { + measureHelper.setVideoSampleAspectRatio(videoSarNum, videoSarDen); + measureHelper.setVideoSize(videoWidth, videoHeight); + } + measureHelper.setVideoRotation((int) getRotation()); + measureHelper.doMeasure(widthMeasureSpec, heightMeasureSpec); + } catch (Exception e) { + e.printStackTrace(); + } + } + setMeasuredDimension(measureHelper.getMeasuredWidth(), measureHelper.getMeasuredHeight()); + } + + public int getSizeH() { + return measureHelper.getMeasuredHeight(); + } + + public int getSizeW() { + 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/builder/GSYVideoOptionBuilder.java b/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/builder/GSYVideoOptionBuilder.java index 9197ed7..56f147c 100644 --- a/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/builder/GSYVideoOptionBuilder.java +++ b/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/builder/GSYVideoOptionBuilder.java @@ -3,6 +3,8 @@ package com.shuyu.gsyvideoplayer.builder; import android.graphics.drawable.Drawable; import android.view.View; +import com.shuyu.gsyvideoplayer.GSYVideoGLView; +import com.shuyu.gsyvideoplayer.effect.NoEffect; import com.shuyu.gsyvideoplayer.listener.LockClickListener; import com.shuyu.gsyvideoplayer.listener.StandardVideoAllCallBack; import com.shuyu.gsyvideoplayer.listener.VideoAllCallBack; @@ -135,6 +137,9 @@ public class GSYVideoOptionBuilder { //滑动dialog进度条样式 protected Drawable mDialogProgressBarDrawable; + //滤镜 + protected GSYVideoGLView.ShaderInterface mEffectFilter = new NoEffect(); + /** * 全屏动画 * @@ -460,6 +465,14 @@ public class GSYVideoOptionBuilder { return this; } + /** + * 设置滤镜效果 + */ + public GSYVideoOptionBuilder setEffectFilter(GSYVideoGLView.ShaderInterface effectFilter) { + this.mEffectFilter = effectFilter; + return this; + } + public void build(StandardGSYVideoPlayer gsyVideoPlayer) { if (mStandardVideoAllCallBack != null) { gsyVideoPlayer.setStandardVideoAllCallBack(mStandardVideoAllCallBack); @@ -521,6 +534,7 @@ public class GSYVideoOptionBuilder { gsyVideoPlayer.setIsTouchWiget(mIsTouchWiget); gsyVideoPlayer.setIsTouchWigetFull(mIsTouchWigetFull); gsyVideoPlayer.setNeedShowWifiTip(mNeedShowWifiTip); + gsyVideoPlayer.setEffectFilter(mEffectFilter); if (mEnlargeImageRes > 0) { gsyVideoPlayer.setEnlargeImageRes(mEnlargeImageRes); } diff --git a/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/AutoFixEffect.java b/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/AutoFixEffect.java new file mode 100644 index 0000000..f697bcd --- /dev/null +++ b/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/AutoFixEffect.java @@ -0,0 +1,90 @@ +package com.shuyu.gsyvideoplayer.effect; + +import android.opengl.GLSurfaceView; + +import com.shuyu.gsyvideoplayer.GSYVideoGLView.ShaderInterface; + +/** + * Attempts to auto-fix the video based on histogram equalization. + * + * @author sheraz.khilji + */ +public class AutoFixEffect implements ShaderInterface { + private float scale; + + /** + * Initialize Effect + * + * @param scale Float, between 0 and 1. Zero means no adjustment, while 1 + * indicates the maximum amount of adjustment. + */ + public AutoFixEffect(float scale) { + if (scale < 0.0f) + scale = 0.0f; + if (scale > 1.0f) + scale = 1.0f; + + this.scale = scale; + } + + @Override + public String getShader(GLSurfaceView mGlSurfaceView) { + + String shader = "#extension GL_OES_EGL_image_external : require\n" + + "precision mediump float;\n" + + "uniform samplerExternalOES tex_sampler_0;\n" + + "uniform samplerExternalOES tex_sampler_1;\n" + + "uniform samplerExternalOES tex_sampler_2;\n" + + " float scale;\n" + " float shift_scale;\n" + + " float hist_offset;\n" + " float hist_scale;\n" + + " float density_offset;\n" + " float density_scale;\n" + + "varying vec2 vTextureCoord;\n" + "void main() {\n" + + " shift_scale = " + + (1.0f / 256f) + + ";\n" + + " hist_offset = " + + (0.5f / 766f) + + ";\n" + + " hist_scale = " + + (765f / 766f) + + ";\n" + + " density_offset = " + + (0.5f / 1024f) + + ";\n" + + " density_scale = " + + (1023f / 1024f) + + ";\n" + + " scale = " + + scale + + ";\n" + + " const vec3 weights = vec3(0.33333, 0.33333, 0.33333);\n" + + " vec4 color = texture2D(tex_sampler_0, vTextureCoord);\n" + + " float energy = dot(color.rgb, weights);\n" + + " float mask_value = energy - 0.5;\n" + + " float alpha;\n" + + " if (mask_value > 0.0) {\n" + + " alpha = (pow(2.0 * mask_value, 1.5) - 1.0) * scale + 1.0;\n" + + " } else { \n" + + " alpha = (pow(2.0 * mask_value, 2.0) - 1.0) * scale + 1.0;\n" + + " }\n" + + " float index = energy * hist_scale + hist_offset;\n" + + " vec4 temp = texture2D(tex_sampler_1, vec2(index, 0.5));\n" + + " float value = temp.g + temp.r * shift_scale;\n" + + " index = value * density_scale + density_offset;\n" + + " temp = texture2D(tex_sampler_2, vec2(index, 0.5));\n" + + " value = temp.g + temp.r * shift_scale;\n" + + " float dst_energy = energy * alpha + value * (1.0 - alpha);\n" + + " float max_energy = energy / max(color.r, max(color.g, color.b));\n" + + " if (dst_energy > max_energy) {\n" + + " dst_energy = max_energy;\n" + + " }\n" + + " if (energy == 0.0) {\n" + + " gl_FragColor = color;\n" + + " } else {\n" + + " gl_FragColor = vec4(color.rgb * dst_energy / energy, color.a);\n" + + " }\n" + "}\n"; + + return shader; + + } +} diff --git a/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/BlackAndWhiteEffect.java b/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/BlackAndWhiteEffect.java new file mode 100644 index 0000000..d31db35 --- /dev/null +++ b/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/BlackAndWhiteEffect.java @@ -0,0 +1,36 @@ +package com.shuyu.gsyvideoplayer.effect; + +import android.opengl.GLSurfaceView; + +import com.shuyu.gsyvideoplayer.GSYVideoGLView.ShaderInterface; + +/** + * Converts the video into black and white colors + * + * @author sheraz.khilji + */ +public class BlackAndWhiteEffect implements ShaderInterface { + /** + * Initialize Effect + */ + public BlackAndWhiteEffect() { + } + + @Override + public String getShader(GLSurfaceView mGlSurfaceView) { + + String shader = "#extension GL_OES_EGL_image_external : require\n" + + "precision mediump float;\n" + + "varying vec2 vTextureCoord;\n" + + "uniform samplerExternalOES sTexture;\n" + "void main() {\n" + + " vec4 color = texture2D(sTexture, vTextureCoord);\n" + + " float colorR = (color.r + color.g + color.b) / 3.0;\n" + + " float colorG = (color.r + color.g + color.b) / 3.0;\n" + + " float colorB = (color.r + color.g + color.b) / 3.0;\n" + + " gl_FragColor = vec4(colorR, colorG, colorB, color.a);\n" + + "}\n"; + + return shader; + + } +} diff --git a/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/BrightnessEffect.java b/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/BrightnessEffect.java new file mode 100644 index 0000000..39b0cf7 --- /dev/null +++ b/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/BrightnessEffect.java @@ -0,0 +1,46 @@ +package com.shuyu.gsyvideoplayer.effect; + +import android.opengl.GLSurfaceView; + +import com.shuyu.gsyvideoplayer.GSYVideoGLView.ShaderInterface; + + +/** + * Adjusts the brightness of the video. + * + * @author sheraz.khilji + */ +public class BrightnessEffect implements ShaderInterface { + private float brightnessValue; + + /** + * Initialize Effect + * + * @param brightnessvalue Range should be between 0.1- 2.0 with 1.0 being normal. + */ + public BrightnessEffect(float brightnessvalue) { + if (brightnessvalue < 0.1f) + brightnessvalue = 0.1f; + if (brightnessvalue > 2.0f) + brightnessvalue = 2.0f; + + this.brightnessValue = brightnessvalue; + } + + @Override + public String getShader(GLSurfaceView mGlSurfaceView) { + + String shader = "#extension GL_OES_EGL_image_external : require\n" + + "precision mediump float;\n" + + "uniform samplerExternalOES sTexture;\n" + + "float brightness ;\n" + "varying vec2 vTextureCoord;\n" + + "void main() {\n" + " brightness =" + brightnessValue + + ";\n" + + " vec4 color = texture2D(sTexture, vTextureCoord);\n" + + " gl_FragColor = brightness * color;\n" + "}\n"; + + return shader; + + } + +} diff --git a/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/ContrastEffect.java b/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/ContrastEffect.java new file mode 100644 index 0000000..55510ed --- /dev/null +++ b/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/ContrastEffect.java @@ -0,0 +1,44 @@ +package com.shuyu.gsyvideoplayer.effect; + +import android.opengl.GLSurfaceView; + +import com.shuyu.gsyvideoplayer.GSYVideoGLView.ShaderInterface; + +/** + * Adjusts the contrast of the video. + * + * @author sheraz.khilji + */ +public class ContrastEffect implements ShaderInterface { + private float contrast; + + /** + * Initialize Effect + * + * @param contrast Range should be between 0.1- 2.0 with 1.0 being normal. + */ + public ContrastEffect(float contrast) { + if (contrast < 0.1f) + contrast = 0.1f; + if (contrast > 2.0f) + contrast = 2.0f; + + this.contrast = contrast; + } + + @Override + public String getShader(GLSurfaceView mGlSurfaceView) { + + String shader = "#extension GL_OES_EGL_image_external : require\n" + + "precision mediump float;\n" + + "uniform samplerExternalOES sTexture;\n" + + " float contrast;\n" + "varying vec2 vTextureCoord;\n" + + "void main() {\n" + " contrast =" + contrast + ";\n" + + " vec4 color = texture2D(sTexture, vTextureCoord);\n" + + " color -= 0.5;\n" + " color *= contrast;\n" + + " color += 0.5;\n" + " gl_FragColor = color;\n" + "}\n"; + return shader; + + } + +} diff --git a/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/CrossProcessEffect.java b/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/CrossProcessEffect.java new file mode 100644 index 0000000..b49ab0b --- /dev/null +++ b/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/CrossProcessEffect.java @@ -0,0 +1,48 @@ +package com.shuyu.gsyvideoplayer.effect; + +import android.opengl.GLSurfaceView; + +import com.shuyu.gsyvideoplayer.GSYVideoGLView.ShaderInterface; + + +/** + * Applies a cross process effect on video, in which the red and green channels + * are enhanced while the blue channel is restricted. + * + * @author sheraz.khilji + */ +public class CrossProcessEffect implements ShaderInterface { + + /** + * Initialize Effect + */ + public CrossProcessEffect() { + } + + @Override + public String getShader(GLSurfaceView mGlSurfaceView) { + + String shader = "#extension GL_OES_EGL_image_external : require\n" + + "precision mediump float;\n" + + "uniform samplerExternalOES sTexture;\n" + + "varying vec2 vTextureCoord;\n" + "void main() {\n" + + " vec4 color = texture2D(sTexture, vTextureCoord);\n" + + " vec3 ncolor = vec3(0.0, 0.0, 0.0);\n" + " float value;\n" + + " if (color.r < 0.5) {\n" + " value = color.r;\n" + + " } else {\n" + " value = 1.0 - color.r;\n" + " }\n" + + " float red = 4.0 * value * value * value;\n" + + " if (color.r < 0.5) {\n" + " ncolor.r = red;\n" + + " } else {\n" + " ncolor.r = 1.0 - red;\n" + " }\n" + + " if (color.g < 0.5) {\n" + " value = color.g;\n" + + " } else {\n" + " value = 1.0 - color.g;\n" + " }\n" + + " float green = 2.0 * value * value;\n" + + " if (color.g < 0.5) {\n" + " ncolor.g = green;\n" + + " } else {\n" + " ncolor.g = 1.0 - green;\n" + " }\n" + + " ncolor.b = color.b * 0.5 + 0.25;\n" + + " gl_FragColor = vec4(ncolor.rgb, color.a);\n" + "}\n"; + + return shader; + + } + +} diff --git a/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/DocumentaryEffect.java b/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/DocumentaryEffect.java new file mode 100644 index 0000000..c9f64e2 --- /dev/null +++ b/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/DocumentaryEffect.java @@ -0,0 +1,116 @@ +package com.shuyu.gsyvideoplayer.effect; + +import android.opengl.GLSurfaceView; + +import com.shuyu.gsyvideoplayer.GSYVideoGLView.ShaderInterface; + +import java.util.Date; +import java.util.Random; + +/** + * Applies black and white documentary style effect on video.. + * + * @author sheraz.khilji + */ +public class DocumentaryEffect implements ShaderInterface { + private int mWidth; + private int mHeight; + private Random mRandom; + + /** + * Initialize Effect + */ + public DocumentaryEffect() { + + } + + /** + * Init all values that will be used by this shader. + * + * @param mGlSurfaceView which is responsible for displaying your video + */ + private void initValues(GLSurfaceView mGlSurfaceView) { + mWidth = mGlSurfaceView.getWidth(); + mHeight = mGlSurfaceView.getHeight(); + mRandom = new Random(new Date().getTime()); + } + + @Override + public String getShader(GLSurfaceView mGlSurfaceView) { + initValues(mGlSurfaceView); + float scale[] = new float[2]; + if (mWidth > mHeight) { + scale[0] = 1f; + scale[1] = ((float) mHeight) / mWidth; + } else { + scale[0] = ((float) mWidth) / mHeight; + scale[1] = 1f; + } + float max_dist = ((float) Math.sqrt(scale[0] * scale[0] + scale[1] + * scale[1])) * 0.5f; + + float seed[] = {mRandom.nextFloat(), mRandom.nextFloat()}; + + String scaleString[] = new String[2]; + String seedString[] = new String[2]; + + scaleString[0] = "scale[0] = " + scale[0] + ";\n"; + scaleString[1] = "scale[1] = " + scale[1] + ";\n"; + + seedString[0] = "seed[0] = " + seed[0] + ";\n"; + seedString[1] = "seed[1] = " + seed[1] + ";\n"; + + String inv_max_distString = "inv_max_dist = " + 1.0f / max_dist + ";\n"; + String stepsizeString = "stepsize = " + 1.0f / 255.0f + ";\n"; + + String shader = "#extension GL_OES_EGL_image_external : require\n" + + "precision mediump float;\n" + + "uniform samplerExternalOES sTexture;\n" + + " vec2 seed;\n" + + " float stepsize;\n" + + " float inv_max_dist;\n" + + " vec2 scale;\n" + + "varying vec2 vTextureCoord;\n" + + "float rand(vec2 loc) {\n" + + " float theta1 = dot(loc, vec2(0.9898, 0.233));\n" + + " float theta2 = dot(loc, vec2(12.0, 78.0));\n" + + " float value = cos(theta1) * sin(theta2) + sin(theta1) * cos(theta2);\n" + + + // keep value of part1 in range: (2^-14 to 2^14). + " float temp = mod(197.0 * value, 1.0) + value;\n" + + " float part1 = mod(220.0 * temp, 1.0) + temp;\n" + + " float part2 = value * 0.5453;\n" + + " float part3 = cos(theta1 + theta2) * 0.43758;\n" + + " return fract(part1 + part2 + part3);\n" + + "}\n" + + "void main() {\n" + // Parameters that were created above + + scaleString[0] + + scaleString[1] + + seedString[0] + + seedString[1] + + inv_max_distString + + stepsizeString + + // black white + + " vec4 color = texture2D(sTexture, vTextureCoord);\n" + + " float dither = rand(vTextureCoord + seed);\n" + + " vec3 xform = clamp(2.0 * color.rgb, 0.0, 1.0);\n" + + " vec3 temp = clamp(2.0 * (color.rgb + stepsize), 0.0, 1.0);\n" + + " vec3 new_color = clamp(xform + (temp - xform) * (dither - 0.5), 0.0, 1.0);\n" + + + // grayscale + " float gray = dot(new_color, vec3(0.299, 0.587, 0.114));\n" + + " new_color = vec3(gray, gray, gray);\n" + + + // vignette + " vec2 coord = vTextureCoord - vec2(0.5, 0.5);\n" + + " float dist = length(coord * scale);\n" + + " float lumen = 0.85 / (1.0 + exp((dist * inv_max_dist - 0.83) * 20.0)) + 0.15;\n" + + " gl_FragColor = vec4(new_color * lumen, color.a);\n" + + "}\n"; + + return shader; + + } +} diff --git a/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/DuotoneEffect.java b/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/DuotoneEffect.java new file mode 100644 index 0000000..f39b6a7 --- /dev/null +++ b/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/DuotoneEffect.java @@ -0,0 +1,74 @@ +package com.shuyu.gsyvideoplayer.effect; + +import android.graphics.Color; +import android.opengl.GLSurfaceView; + +import com.shuyu.gsyvideoplayer.GSYVideoGLView.ShaderInterface; + + +/** + * Representation of video using only two color tones. + * + * @author sheraz.khilji + */ +public class DuotoneEffect implements ShaderInterface { + // Default values + private int mFirstColor = Color.MAGENTA; + private int mSecondColor = Color.YELLOW; + + /** + * Initialize effect + * + * @param mFirstColor Integer, representing an ARGB color with 8 bits per channel. + * May be created using Color class. + * @param mSecondColor Integer, representing an ARGB color with 8 bits per channel. + * May be created using Color class. + */ + public DuotoneEffect(int mFirstColor, int mSecondColor) { + this.mFirstColor = mFirstColor; + this.mSecondColor = mSecondColor; + } + + @Override + public String getShader(GLSurfaceView mGlSurfaceView) { + float first[] = {Color.red(mFirstColor) / 255f, + Color.green(mFirstColor) / 255f, Color.blue(mFirstColor) / 255f}; + float second[] = {Color.red(mSecondColor) / 255f, + Color.green(mSecondColor) / 255f, + Color.blue(mSecondColor) / 255f}; + + String firstColorString[] = new String[3]; + String secondColorString[] = new String[3]; + + firstColorString[0] = "first[0] = " + first[0] + ";\n"; + firstColorString[1] = "first[1] = " + first[1] + ";\n"; + firstColorString[2] = "first[2] = " + first[2] + ";\n"; + + secondColorString[0] = "second[0] = " + second[0] + ";\n"; + secondColorString[1] = "second[1] = " + second[1] + ";\n"; + secondColorString[2] = "second[2] = " + second[2] + ";\n"; + + String shader = "#extension GL_OES_EGL_image_external : require\n" + + "precision mediump float;\n" + + "uniform samplerExternalOES sTexture;\n" + + " vec3 first;\n" + + " vec3 second;\n" + + "varying vec2 vTextureCoord;\n" + + "void main() {\n" + // Parameters that were created above + + firstColorString[0] + + firstColorString[1] + + firstColorString[2] + + secondColorString[0] + + secondColorString[1] + + secondColorString[2] + + + " vec4 color = texture2D(sTexture, vTextureCoord);\n" + + " float energy = (color.r + color.g + color.b) * 0.3333;\n" + + " vec3 new_color = (1.0 - energy) * first + energy * second;\n" + + " gl_FragColor = vec4(new_color.rgb, color.a);\n" + "}\n"; + + return shader; + + } +} diff --git a/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/FillLightEffect.java b/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/FillLightEffect.java new file mode 100644 index 0000000..446897b --- /dev/null +++ b/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/FillLightEffect.java @@ -0,0 +1,67 @@ +package com.shuyu.gsyvideoplayer.effect; + +import android.opengl.GLSurfaceView; + +import com.shuyu.gsyvideoplayer.GSYVideoGLView.ShaderInterface; + + +/** + * Applies back-light filling to the video. + * + * @author sheraz.khilji + */ +public class FillLightEffect implements ShaderInterface { + private float strength = 0f; + + /** + * Initialize Effect + * + * @param strength Float, between 0 and 1. 0 means no change. + */ + public FillLightEffect(float strength) { + if (strength < 0.0f) + strength = 0f; + if (strength > 1.0f) + strength = 1f; + + this.strength = strength; + } + + @Override + public String getShader(GLSurfaceView mGlSurfaceView) { + float fade_gamma = 0.3f; + float amt = 1.0f - strength; + float mult = 1.0f / (amt * 0.7f + 0.3f); + float faded = fade_gamma + (1.0f - fade_gamma) * mult; + float igamma = 1.0f / faded; + + String multString = "mult = " + mult + ";\n"; + String igammaString = "igamma = " + igamma + ";\n"; + + String shader = "#extension GL_OES_EGL_image_external : require\n" + + "precision mediump float;\n" + + "uniform samplerExternalOES sTexture;\n" + + " float mult;\n" + + " float igamma;\n" + + "varying vec2 vTextureCoord;\n" + + "void main()\n" + + "{\n" + // Parameters that were created above + + multString + + igammaString + + + " const vec3 color_weights = vec3(0.25, 0.5, 0.25);\n" + + " vec4 color = texture2D(sTexture, vTextureCoord);\n" + + " float lightmask = dot(color.rgb, color_weights);\n" + + " float backmask = (1.0 - lightmask);\n" + + " vec3 ones = vec3(1.0, 1.0, 1.0);\n" + + " vec3 diff = pow(mult * color.rgb, igamma * ones) - color.rgb;\n" + + " diff = min(diff, 1.0);\n" + + " vec3 new_color = min(color.rgb + diff * backmask, 1.0);\n" + + " gl_FragColor = vec4(new_color, color.a);\n" + "}\n"; + + return shader; + + } + +} diff --git a/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/GammaEffect.java b/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/GammaEffect.java new file mode 100644 index 0000000..679731e --- /dev/null +++ b/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/GammaEffect.java @@ -0,0 +1,46 @@ +package com.shuyu.gsyvideoplayer.effect; + +import android.opengl.GLSurfaceView; + +import com.shuyu.gsyvideoplayer.GSYVideoGLView.ShaderInterface; + +/** + * Apply Gamma Effect on Video being played + */ +public class GammaEffect implements ShaderInterface { + private float gammaValue; + + /** + * Initialize Effect + * + * @param gammaValue Range should be between 0.0 - 2.0 with 1.0 being normal. + */ + public GammaEffect(float gammaValue) { + if (gammaValue < 0.0f) + gammaValue = 0.0f; + if (gammaValue > 2.0f) + gammaValue = 2.0f; + this.gammaValue = gammaValue; + + } + + @Override + public String getShader(GLSurfaceView mGlSurfaceView) { + + String shader = "#extension GL_OES_EGL_image_external : require\n" + + "precision mediump float;\n" + + + "varying vec2 vTextureCoord;\n" + + "uniform samplerExternalOES sTexture;\n" + + "float gamma=" + gammaValue + ";\n" + + + "void main() {\n" + + + "vec4 textureColor = texture2D(sTexture, vTextureCoord);\n" + + "gl_FragColor = vec4(pow(textureColor.rgb, vec3(gamma)), textureColor.w);\n" + + + "}\n"; + + return shader; + } +} \ No newline at end of file diff --git a/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/GrainEffect.java b/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/GrainEffect.java new file mode 100644 index 0000000..4934907 --- /dev/null +++ b/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/GrainEffect.java @@ -0,0 +1,105 @@ +package com.shuyu.gsyvideoplayer.effect; + +import android.opengl.GLSurfaceView; + +import com.shuyu.gsyvideoplayer.GSYVideoGLView.ShaderInterface; + +import java.util.Date; +import java.util.Random; + +/** + * Applies film grain effect to video. + * + * @author sheraz.khilji + */ +public class GrainEffect implements ShaderInterface { + private int mWidth; + private int mHeight; + private float strength; + private Random mRandom; + + /** + * Initialize Effect + * + * @param strength Float, between 0 and 1. Zero means no distortion, while 1 + * indicates the maximum amount of adjustment. + */ + public GrainEffect(float strength) { + if (strength < 0.0f) + strength = 0.0f; + if (strength > 1.0f) + strength = 1.0f; + this.strength = strength; + } + + /** + * Init all values that will be used by this shader. + * + * @param mGlSurfaceView which is responsible for displaying your video + */ + private void initValues(GLSurfaceView mGlSurfaceView) { + mWidth = mGlSurfaceView.getWidth(); + mHeight = mGlSurfaceView.getHeight(); + mRandom = new Random(new Date().getTime()); + } + + @Override + public String getShader(GLSurfaceView mGlSurfaceView) { + initValues(mGlSurfaceView); + + float seed[] = {mRandom.nextFloat(), mRandom.nextFloat()}; + String scaleString = "scale = " + strength + ";\n"; + String seedString[] = new String[2]; + seedString[0] = "seed[0] = " + seed[0] + ";\n"; + seedString[1] = "seed[1] = " + seed[1] + ";\n"; + String stepX = "stepX = " + 0.5f / mWidth + ";\n"; + String stepY = "stepY = " + 0.5f / mHeight + ";\n"; + + // locString[1] = "loc[1] = loc[1]+" + seedString[1] + ";\n"; + + String shader = "#extension GL_OES_EGL_image_external : require\n" + + "precision mediump float;\n" + + " vec2 seed;\n" + + "varying vec2 vTextureCoord;\n" + + "uniform samplerExternalOES tex_sampler_0;\n" + + "uniform samplerExternalOES tex_sampler_1;\n" + + "float scale;\n" + + " float stepX;\n" + + " float stepY;\n" + + "float rand(vec2 loc) {\n" + + " float theta1 = dot(loc, vec2(0.9898, 0.233));\n" + + " float theta2 = dot(loc, vec2(12.0, 78.0));\n" + + " float value = cos(theta1) * sin(theta2) + sin(theta1) * cos(theta2);\n" + + + // keep value of part1 in range: (2^-14 to 2^14). + " float temp = mod(197.0 * value, 1.0) + value;\n" + + " float part1 = mod(220.0 * temp, 1.0) + temp;\n" + + " float part2 = value * 0.5453;\n" + + " float part3 = cos(theta1 + theta2) * 0.43758;\n" + + " float sum = (part1 + part2 + part3);\n" + + " return fract(sum)*scale;\n" + + "}\n" + + "void main() {\n" + // Parameters that were created above + + seedString[0] + + seedString[1] + + scaleString + + stepX + + stepY + + " float noise = texture2D(tex_sampler_1, vTextureCoord + vec2(-stepX, -stepY)).r * 0.224;\n" + + " noise += texture2D(tex_sampler_1, vTextureCoord + vec2(-stepX, stepY)).r * 0.224;\n" + + " noise += texture2D(tex_sampler_1, vTextureCoord + vec2(stepX, -stepY)).r * 0.224;\n" + + " noise += texture2D(tex_sampler_1, vTextureCoord + vec2(stepX, stepY)).r * 0.224;\n" + + " noise += 0.4448;\n" + + " noise *= scale;\n" + + " vec4 color = texture2D(tex_sampler_0, vTextureCoord);\n" + + " float energy = 0.33333 * color.r + 0.33333 * color.g + 0.33333 * color.b;\n" + + " float mask = (1.0 - sqrt(energy));\n" + + " float weight = 1.0 - 1.333 * mask * noise;\n" + + " gl_FragColor = vec4(color.rgb * weight, color.a);\n" + + " gl_FragColor = gl_FragColor+vec4(rand(vTextureCoord + seed), rand(vTextureCoord + seed),rand(vTextureCoord + seed),1);\n" + + "}\n"; + return shader; + + } +} diff --git a/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/GreyScaleEffect.java b/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/GreyScaleEffect.java new file mode 100644 index 0000000..ac9ddaf --- /dev/null +++ b/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/GreyScaleEffect.java @@ -0,0 +1,35 @@ +package com.shuyu.gsyvideoplayer.effect; + +import android.opengl.GLSurfaceView; + +import com.shuyu.gsyvideoplayer.GSYVideoGLView.ShaderInterface; + + +/** + * Converts video to GreyScale. + * + * @author sheraz.khilji + */ +public class GreyScaleEffect implements ShaderInterface { + /** + * Initialize Effect + */ + public GreyScaleEffect() { + } + + @Override + public String getShader(GLSurfaceView mGlSurfaceView) { + + String shader = "#extension GL_OES_EGL_image_external : require\n" + + "precision mediump float;\n" + + "uniform samplerExternalOES sTexture;\n" + + "varying vec2 vTextureCoord;\n" + "void main() {\n" + + " vec4 color = texture2D(sTexture, vTextureCoord);\n" + + " float y = dot(color, vec4(0.299, 0.587, 0.114, 0));\n" + + " gl_FragColor = vec4(y, y, y, color.a);\n" + "}\n"; + ; + + return shader; + + } +} diff --git a/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/HueEffect.java b/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/HueEffect.java new file mode 100644 index 0000000..971f43c --- /dev/null +++ b/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/HueEffect.java @@ -0,0 +1,71 @@ +package com.shuyu.gsyvideoplayer.effect; + +import android.opengl.GLSurfaceView; + +import com.shuyu.gsyvideoplayer.GSYVideoGLView.ShaderInterface; + + +/** + * Apply Hue effect on the video being played + */ +public class HueEffect implements ShaderInterface { + float hueValue; + + /** + * Initialize Effect + *

+ * Hue value chart + * + * @param hueDegrees Range of value should be between 0 to 360 degrees as described in the image above + */ + public HueEffect(float hueDegrees) { +// manipulating input value so that we can map it on 360 degree circle + hueValue = ((hueDegrees - 45) / 45f + 0.5f) * -1; + + } + + @Override + public String getShader(GLSurfaceView mGlSurfaceView) { + + String shader = "#extension GL_OES_EGL_image_external : require\n" + + "precision mediump float;\n" + + + "varying vec2 vTextureCoord;\n" + + "uniform samplerExternalOES sTexture;\n" + + "float hue=" + hueValue + ";\n" + + + "void main() {\n" + + + "vec4 kRGBToYPrime = vec4 (0.299, 0.587, 0.114, 0.0);\n" + + "vec4 kRGBToI = vec4 (0.595716, -0.274453, -0.321263, 0.0);\n" + + "vec4 kRGBToQ = vec4 (0.211456, -0.522591, 0.31135, 0.0);\n" + + + "vec4 kYIQToR = vec4 (1.0, 0.9563, 0.6210, 0.0);\n" + + "vec4 kYIQToG = vec4 (1.0, -0.2721, -0.6474, 0.0);\n" + + "vec4 kYIQToB = vec4 (1.0, -1.1070, 1.7046, 0.0);\n" + + + + "vec4 color = texture2D(sTexture, vTextureCoord);\n" + + + "float YPrime = dot(color, kRGBToYPrime);\n" + + "float I = dot(color, kRGBToI);\n" + + "float Q = dot(color, kRGBToQ);\n" + + + "float chroma = sqrt (I * I + Q * Q);\n" + + + "Q = chroma * sin (hue);\n" + + + "I = chroma * cos (hue);\n" + + + "vec4 yIQ = vec4 (YPrime, I, Q, 0.0);\n" + + + "color.r = dot (yIQ, kYIQToR);\n" + + "color.g = dot (yIQ, kYIQToG);\n" + + "color.b = dot (yIQ, kYIQToB);\n" + + "gl_FragColor = color;\n" + + + "}\n"; + + return shader; + } +} \ No newline at end of file diff --git a/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/InvertColorsEffect.java b/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/InvertColorsEffect.java new file mode 100644 index 0000000..78fa349 --- /dev/null +++ b/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/InvertColorsEffect.java @@ -0,0 +1,37 @@ +package com.shuyu.gsyvideoplayer.effect; + +import android.opengl.GLSurfaceView; + +import com.shuyu.gsyvideoplayer.GSYVideoGLView.ShaderInterface; + + +/** + * Inverts the video colors. This can also be known as negative Effect. + * + * @author sheraz.khilji + */ +public class InvertColorsEffect implements ShaderInterface { + /** + * Initialize Effect + */ + public InvertColorsEffect() { + } + + @Override + public String getShader(GLSurfaceView mGlSurfaceView) { + + String shader = "#extension GL_OES_EGL_image_external : require\n" + + "precision mediump float;\n" + + "varying vec2 vTextureCoord;\n" + + "uniform samplerExternalOES sTexture;\n" + "void main() {\n" + + " vec4 color = texture2D(sTexture, vTextureCoord);\n" + + " float colorR = (1.0 - color.r) / 1.0;\n" + + " float colorG = (1.0 - color.g) / 1.0;\n" + + " float colorB = (1.0 - color.b) / 1.0;\n" + + " gl_FragColor = vec4(colorR, colorG, colorB, color.a);\n" + + "}\n"; + + return shader; + + } +} diff --git a/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/LamoishEffect.java b/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/LamoishEffect.java new file mode 100644 index 0000000..81be30e --- /dev/null +++ b/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/LamoishEffect.java @@ -0,0 +1,160 @@ +package com.shuyu.gsyvideoplayer.effect; + +import android.opengl.GLSurfaceView; + +import com.shuyu.gsyvideoplayer.GSYVideoGLView.ShaderInterface; + +import java.util.Date; +import java.util.Random; + +/** + * Applies lomo-camera style effect to video. + * + * @author sheraz.khilji + */ +public class LamoishEffect implements ShaderInterface { + private int mWidth; + private int mHeight; + private Random mRandom; + + /** + * Initialize Effect + */ + public LamoishEffect() { + + } + + /** + * Init all values that will be used by this shader. + * + * @param mGlSurfaceView which is responsible for displaying your video + */ + private void initValues(GLSurfaceView mGlSurfaceView) { + mWidth = mGlSurfaceView.getWidth(); + mHeight = mGlSurfaceView.getHeight(); + mRandom = new Random(new Date().getTime()); + } + + @Override + public String getShader(GLSurfaceView mGlSurfaceView) { + initValues(mGlSurfaceView); + float scale[] = new float[2]; + if (mWidth > mHeight) { + scale[0] = 1f; + scale[1] = ((float) mHeight) / mWidth; + } else { + scale[0] = ((float) mWidth) / mHeight; + scale[1] = 1f; + } + float max_dist = ((float) Math.sqrt(scale[0] * scale[0] + scale[1] + * scale[1])) * 0.5f; + + float seed[] = {mRandom.nextFloat(), mRandom.nextFloat()}; + + String scaleString[] = new String[2]; + String seedString[] = new String[2]; + + scaleString[0] = "scale[0] = " + scale[0] + ";\n"; + scaleString[1] = "scale[1] = " + scale[1] + ";\n"; + + seedString[0] = "seed[0] = " + seed[0] + ";\n"; + seedString[1] = "seed[1] = " + seed[1] + ";\n"; + + String inv_max_distString = "inv_max_dist = " + 1.0f / max_dist + ";\n"; + String stepsizeString = "stepsize = " + 1.0f / 255.0f + ";\n"; + String stepsizeXString = "stepsizeX = " + 1.0f / mWidth + ";\n"; + String stepsizeYString = "stepsizeY = " + 1.0f / mHeight + ";\n"; + + String shader = "#extension GL_OES_EGL_image_external : require\n" + + "precision mediump float;\n" + + "uniform samplerExternalOES sTexture;\n" + + " vec2 seed;\n" + + " float stepsizeX;\n" + + " float stepsizeY;\n" + + " float stepsize;\n" + + " vec2 scale;\n" + + " float inv_max_dist;\n" + + "varying vec2 vTextureCoord;\n" + + "float rand(vec2 loc) {\n" + + " float theta1 = dot(loc, vec2(0.9898, 0.233));\n" + + " float theta2 = dot(loc, vec2(12.0, 78.0));\n" + + " float value = cos(theta1) * sin(theta2) + sin(theta1) * cos(theta2);\n" + + + // keep value of part1 in range: (2^-14 to 2^14). + " float temp = mod(197.0 * value, 1.0) + value;\n" + + " float part1 = mod(220.0 * temp, 1.0) + temp;\n" + + " float part2 = value * 0.5453;\n" + + " float part3 = cos(theta1 + theta2) * 0.43758;\n" + + " return fract(part1 + part2 + part3);\n" + "}\n" + + "void main() {\n" + // Parameters that were created above + + scaleString[0] + + scaleString[1] + + seedString[0] + + seedString[1] + + inv_max_distString + + stepsizeString + + stepsizeXString + + stepsizeYString + // sharpen + + " vec3 nbr_color = vec3(0.0, 0.0, 0.0);\n" + + " vec2 coord;\n" + + " vec4 color = texture2D(sTexture, vTextureCoord);\n" + + " coord.x = vTextureCoord.x - 0.5 * stepsizeX;\n" + + " coord.y = vTextureCoord.y - stepsizeY;\n" + + " nbr_color += texture2D(sTexture, coord).rgb - color.rgb;\n" + + " coord.x = vTextureCoord.x - stepsizeX;\n" + + " coord.y = vTextureCoord.y + 0.5 * stepsizeY;\n" + + " nbr_color += texture2D(sTexture, coord).rgb - color.rgb;\n" + + " coord.x = vTextureCoord.x + stepsizeX;\n" + + " coord.y = vTextureCoord.y - 0.5 * stepsizeY;\n" + + " nbr_color += texture2D(sTexture, coord).rgb - color.rgb;\n" + + " coord.x = vTextureCoord.x + stepsizeX;\n" + + " coord.y = vTextureCoord.y + 0.5 * stepsizeY;\n" + + " nbr_color += texture2D(sTexture, coord).rgb - color.rgb;\n" + + " vec3 s_color = vec3(color.rgb + 0.3 * nbr_color);\n" + + + // cross process + " vec3 c_color = vec3(0.0, 0.0, 0.0);\n" + + " float value;\n" + + " if (s_color.r < 0.5) {\n" + + " value = s_color.r;\n" + + " } else {\n" + + " value = 1.0 - s_color.r;\n" + + " }\n" + + " float red = 4.0 * value * value * value;\n" + + " if (s_color.r < 0.5) {\n" + + " c_color.r = red;\n" + + " } else {\n" + + " c_color.r = 1.0 - red;\n" + + " }\n" + + " if (s_color.g < 0.5) {\n" + + " value = s_color.g;\n" + + " } else {\n" + + " value = 1.0 - s_color.g;\n" + + " }\n" + + " float green = 2.0 * value * value;\n" + + " if (s_color.g < 0.5) {\n" + + " c_color.g = green;\n" + + " } else {\n" + + " c_color.g = 1.0 - green;\n" + + " }\n" + + " c_color.b = s_color.b * 0.5 + 0.25;\n" + + + // blackwhite + " float dither = rand(vTextureCoord + seed);\n" + + " vec3 xform = clamp((c_color.rgb - 0.15) * 1.53846, 0.0, 1.0);\n" + + " vec3 temp = clamp((color.rgb + stepsize - 0.15) * 1.53846, 0.0, 1.0);\n" + + " vec3 bw_color = clamp(xform + (temp - xform) * (dither - 0.5), 0.0, 1.0);\n" + + + // vignette + " coord = vTextureCoord - vec2(0.5, 0.5);\n" + + " float dist = length(coord * scale);\n" + + " float lumen = 0.85 / (1.0 + exp((dist * inv_max_dist - 0.73) * 20.0)) + 0.15;\n" + + " gl_FragColor = vec4(bw_color * lumen, color.a);\n" + "}\n"; + ; + + return shader; + + } +} diff --git a/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/NoEffect.java b/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/NoEffect.java new file mode 100644 index 0000000..f904d7f --- /dev/null +++ b/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/NoEffect.java @@ -0,0 +1,33 @@ +package com.shuyu.gsyvideoplayer.effect; + +import android.opengl.GLSurfaceView; + +import com.shuyu.gsyvideoplayer.GSYVideoGLView.ShaderInterface; + + +/** + * Displays the normal video without any effect. + * + * @author sheraz.khilji + */ +public class NoEffect implements ShaderInterface { + /** + * Initialize + */ + public NoEffect() { + } + + @Override + public String getShader(GLSurfaceView mGlSurfaceView) { + + String 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"; + + return shader; + + } +} \ No newline at end of file diff --git a/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/PosterizeEffect.java b/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/PosterizeEffect.java new file mode 100644 index 0000000..41740f6 --- /dev/null +++ b/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/PosterizeEffect.java @@ -0,0 +1,36 @@ +package com.shuyu.gsyvideoplayer.effect; + +import android.opengl.GLSurfaceView; + +import com.shuyu.gsyvideoplayer.GSYVideoGLView.ShaderInterface; + + +/** + * Applies Posterization effect to video. + * + * @author sheraz.khilji + */ +public class PosterizeEffect implements ShaderInterface { + /** + * Initialize Effect + */ + public PosterizeEffect() { + } + + @Override + public String getShader(GLSurfaceView mGlSurfaceView) { + + String shader = "#extension GL_OES_EGL_image_external : require\n" + + "precision mediump float;\n" + + "uniform samplerExternalOES sTexture;\n" + + "varying vec2 vTextureCoord;\n" + "void main() {\n" + + " vec4 color = texture2D(sTexture, vTextureCoord);\n" + + " vec3 pcolor;\n" + + " pcolor.r = (color.r >= 0.5) ? 0.75 : 0.25;\n" + + " pcolor.g = (color.g >= 0.5) ? 0.75 : 0.25;\n" + + " pcolor.b = (color.b >= 0.5) ? 0.75 : 0.25;\n" + + " gl_FragColor = vec4(pcolor, color.a);\n" + "}\n"; + return shader; + + } +} diff --git a/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/SaturationEffect.java b/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/SaturationEffect.java new file mode 100644 index 0000000..d25ede9 --- /dev/null +++ b/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/SaturationEffect.java @@ -0,0 +1,89 @@ +package com.shuyu.gsyvideoplayer.effect; + +import android.opengl.GLSurfaceView; + +import com.shuyu.gsyvideoplayer.GSYVideoGLView.ShaderInterface; + +/** + * Adjusts color saturation of video. There is still some issue with this + * effect. + * + * @author sheraz.khilji + */ +public class SaturationEffect implements ShaderInterface { + private float scale = 0f; + + /** + * Initialize Effect + * + * @param scale Float, between -1 and 1. 0 means no change, while -1 indicates + * full desaturation, i.e. grayscale. + */ + public SaturationEffect(float scale) { + + this.scale = scale; + } + + @Override + public String getShader(GLSurfaceView mGlSurfaceView) { + float shift = 1.0f / 255.0f; + float weights[] = {2f / 8f, 5f / 8f, 1f / 8f}; + float exponents[] = new float[3]; + + String weightsString[] = new String[3]; + String exponentsString[] = new String[3]; + exponentsString[0] = ""; + exponentsString[1] = ""; + exponentsString[2] = ""; + String scaleString = ""; + + if (scale > 0.0f) { + exponents[0] = (0.9f * scale) + 1.0f; + exponents[1] = (2.1f * scale) + 1.0f; + exponents[2] = (2.7f * scale) + 1.0f; + exponentsString[0] = "exponents[0] = " + exponents[0] + ";\n"; + exponentsString[1] = "exponents[1] = " + exponents[1] + ";\n"; + exponentsString[2] = "exponents[2] = " + exponents[2] + ";\n"; + } else + scaleString = "scale = " + (1.0f + scale) + ";\n"; + + weightsString[0] = "weights[0] = " + weights[0] + ";\n"; + weightsString[1] = "weights[1] = " + weights[1] + ";\n"; + weightsString[2] = "weights[2] = " + weights[2] + ";\n"; + String shiftString = "shift = " + shift + ";\n"; + + String shader = "#extension GL_OES_EGL_image_external : require\n" + + "precision mediump float;\n" + + "uniform samplerExternalOES sTexture;\n" + " float scale;\n" + + " float shift;\n" + " vec3 weights;\n" + " vec3 exponents;\n" + + "varying vec2 vTextureCoord;\n" + "void main() {\n" + // Parameters that were created above + + weightsString[0] + + weightsString[1] + + weightsString[2] + + shiftString + + scaleString + + " vec4 oldcolor = texture2D(sTexture, vTextureCoord);\n" + + " float kv = dot(oldcolor.rgb, weights) + shift;\n" + + " vec3 new_color = scale * oldcolor.rgb + (1.0 - scale) * kv;\n" + + " gl_FragColor= vec4(new_color, oldcolor.a);\n" + // Parameters that were created above + + weightsString[0] + + weightsString[1] + + weightsString[2] + + exponentsString[0] + + exponentsString[1] + + exponentsString[2] + + " vec4 color = texture2D(sTexture, vTextureCoord);\n" + + " float de = dot(color.rgb, weights);\n" + + " float inv_de = 1.0 / de;\n" + + " vec3 verynew_color = de * pow(color.rgb * inv_de, exponents);\n" + + " float max_color = max(max(max(verynew_color.r, verynew_color.g), verynew_color.b), 1.0);\n" + + " gl_FragColor = gl_FragColor+vec4(verynew_color / max_color, color.a);\n" + + "}\n"; + + return shader; + + } + +} diff --git a/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/SepiaEffect.java b/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/SepiaEffect.java new file mode 100644 index 0000000..1353d5a --- /dev/null +++ b/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/SepiaEffect.java @@ -0,0 +1,51 @@ +package com.shuyu.gsyvideoplayer.effect; + +import android.opengl.GLSurfaceView; + +import com.shuyu.gsyvideoplayer.GSYVideoGLView.ShaderInterface; + +/** + * Converts video to Sepia tone. + * + * @author sheraz.khilji + */ +public class SepiaEffect implements ShaderInterface { + /** + * Initialize Effect + */ + public SepiaEffect() { + } + + @Override + public String getShader(GLSurfaceView mGlSurfaceView) { + float weights[] = {805.0f / 2048.0f, 715.0f / 2048.0f, + 557.0f / 2048.0f, 1575.0f / 2048.0f, 1405.0f / 2048.0f, + 1097.0f / 2048.0f, 387.0f / 2048.0f, 344.0f / 2048.0f, + 268.0f / 2048.0f}; + String matrixString[] = new String[9]; + + matrixString[0] = " matrix[0][0]=" + weights[0] + ";\n"; + matrixString[1] = " matrix[0][1]=" + weights[1] + ";\n"; + matrixString[2] = " matrix[0][2]=" + weights[2] + ";\n"; + matrixString[3] = " matrix[1][0]=" + weights[3] + ";\n"; + matrixString[4] = " matrix[1][1]=" + weights[4] + ";\n"; + matrixString[5] = " matrix[1][2]=" + weights[5] + ";\n"; + matrixString[6] = " matrix[2][0]=" + weights[6] + ";\n"; + matrixString[7] = " matrix[2][1]=" + weights[7] + ";\n"; + matrixString[8] = " matrix[2][2]=" + weights[8] + ";\n"; + + String shader = "#extension GL_OES_EGL_image_external : require\n" + + "precision mediump float;\n" + + "uniform samplerExternalOES sTexture;\n" + " mat3 matrix;\n" + + "varying vec2 vTextureCoord;\n" + "void main() {\n" + + matrixString[0] + matrixString[1] + matrixString[2] + + matrixString[3] + matrixString[4] + matrixString[5] + + matrixString[6] + matrixString[7] + matrixString[8] + + " vec4 color = texture2D(sTexture, vTextureCoord);\n" + + " vec3 new_color = min(matrix * color.rgb, 1.0);\n" + + " gl_FragColor = vec4(new_color.rgb, color.a);\n" + "}\n"; + + return shader; + + } +} diff --git a/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/SharpnessEffect.java b/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/SharpnessEffect.java new file mode 100644 index 0000000..40912c7 --- /dev/null +++ b/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/SharpnessEffect.java @@ -0,0 +1,83 @@ +package com.shuyu.gsyvideoplayer.effect; + +import android.opengl.GLSurfaceView; + +import com.shuyu.gsyvideoplayer.GSYVideoGLView.ShaderInterface; + +/** + * Sharpens the video. + * + * @author sheraz.khilji + */ +public class SharpnessEffect implements ShaderInterface { + private int mWidth; + private int mHeight; + private float scale = 0f; + + /** + * Initialize Effect + * + * @param scale Float, between 0 and 1. 0 means no change. + */ + public SharpnessEffect(float scale) { + if (scale < 0.0f) + scale = 0.0f; + if (scale > 1.0f) + scale = 1.0f; + + this.scale = scale; + } + + /** + * Init all values that will be used by this shader. + * + * @param mGlSurfaceView which is responsible for displaying your video + */ + private void initValues(GLSurfaceView mGlSurfaceView) { + mWidth = mGlSurfaceView.getWidth(); + mHeight = mGlSurfaceView.getHeight(); + } + + @Override + public String getShader(GLSurfaceView mGlSurfaceView) { + initValues(mGlSurfaceView); + + String stepsizeXString = "stepsizeX = " + 1.0f / mWidth + ";\n"; + String stepsizeYString = "stepsizeY = " + 1.0f / mHeight + ";\n"; + String scaleString = "scale = " + scale + ";\n"; + + String shader = "#extension GL_OES_EGL_image_external : require\n" + + "precision mediump float;\n" + + "uniform samplerExternalOES sTexture;\n" + + " float scale;\n" + + " float stepsizeX;\n" + + " float stepsizeY;\n" + + "varying vec2 vTextureCoord;\n" + + "void main() {\n" + // Parameters that were created above + + stepsizeXString + + stepsizeYString + + scaleString + + " vec3 nbr_color = vec3(0.0, 0.0, 0.0);\n" + + " vec2 coord;\n" + + " vec4 color = texture2D(sTexture, vTextureCoord);\n" + + " coord.x = vTextureCoord.x - 0.5 * stepsizeX;\n" + + " coord.y = vTextureCoord.y - stepsizeY;\n" + + " nbr_color += texture2D(sTexture, coord).rgb - color.rgb;\n" + + " coord.x = vTextureCoord.x - stepsizeX;\n" + + " coord.y = vTextureCoord.y + 0.5 * stepsizeY;\n" + + " nbr_color += texture2D(sTexture, coord).rgb - color.rgb;\n" + + " coord.x = vTextureCoord.x + stepsizeX;\n" + + " coord.y = vTextureCoord.y - 0.5 * stepsizeY;\n" + + " nbr_color += texture2D(sTexture, coord).rgb - color.rgb;\n" + + " coord.x = vTextureCoord.x + stepsizeX;\n" + + " coord.y = vTextureCoord.y + 0.5 * stepsizeY;\n" + + " nbr_color += texture2D(sTexture, coord).rgb - color.rgb;\n" + + " gl_FragColor = vec4(color.rgb - 2.0 * scale * nbr_color, color.a);\n" + + "}\n"; + + return shader; + + } + +} diff --git a/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/TemperatureEffect.java b/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/TemperatureEffect.java new file mode 100644 index 0000000..77d426b --- /dev/null +++ b/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/TemperatureEffect.java @@ -0,0 +1,57 @@ +package com.shuyu.gsyvideoplayer.effect; + +import android.opengl.GLSurfaceView; + +import com.shuyu.gsyvideoplayer.GSYVideoGLView.ShaderInterface; + +/** + * Adjusts color temperature of the video. + * + * @author sheraz.khilji + */ +public class TemperatureEffect implements ShaderInterface { + private float scale = 0f; + + /** + * Initialize Effect + * + * @param scale Float, between 0 and 1, with 0 indicating cool, and 1 + * indicating warm. A value of of 0.5 indicates no change. + */ + public TemperatureEffect(float scale) { + if (scale < 0.0f) + scale = 0.0f; + if (scale > 1.0f) + scale = 1.0f; + this.scale = scale; + + } + + @Override + public String getShader(GLSurfaceView mGlSurfaceView) { + + String scaleString = "scale = " + (2.0f * scale - 1.0f) + ";\n"; + + String shader = "#extension GL_OES_EGL_image_external : require\n" + + "precision mediump float;\n" + + "uniform samplerExternalOES sTexture;\n" + + " float scale;\n" + + "varying vec2 vTextureCoord;\n" + + "void main() {\n" // Parameters that were created above + + scaleString + + " vec4 color = texture2D(sTexture, vTextureCoord);\n" + + " vec3 new_color = color.rgb;\n" + + " new_color.r = color.r + color.r * ( 1.0 - color.r) * scale;\n" + + " new_color.b = color.b - color.b * ( 1.0 - color.b) * scale;\n" + + " if (scale > 0.0) { \n" + + " new_color.g = color.g + color.g * ( 1.0 - color.g) * scale * 0.25;\n" + + " }\n" + + " float max_value = max(new_color.r, max(new_color.g, new_color.b));\n" + + " if (max_value > 1.0) { \n" + + " new_color /= max_value;\n" + " } \n" + + " gl_FragColor = vec4(new_color, color.a);\n" + "}\n"; + + return shader; + + } +} diff --git a/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/TintEffect.java b/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/TintEffect.java new file mode 100644 index 0000000..4619627 --- /dev/null +++ b/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/TintEffect.java @@ -0,0 +1,65 @@ +package com.shuyu.gsyvideoplayer.effect; + +import android.graphics.Color; +import android.opengl.GLSurfaceView; + +import com.shuyu.gsyvideoplayer.GSYVideoGLView.ShaderInterface; + + +/** + * Tints the video with specified color.. + * + * @author sheraz.khilji + */ +public class TintEffect implements ShaderInterface { + private int mTint = 0xFF0000FF; + + /** + * Initialize Effect + * + * @param color Integer, representing an ARGB color with 8 bits per channel. + * May be created using Color class. + */ + public TintEffect(int color) { + this.mTint = color; + + } + + @Override + public String getShader(GLSurfaceView mGlSurfaceView) { + float color_ratio[] = {0.21f, 0.71f, 0.07f}; + String color_ratioString[] = new String[3]; + color_ratioString[0] = "color_ratio[0] = " + color_ratio[0] + ";\n"; + color_ratioString[1] = "color_ratio[1] = " + color_ratio[1] + ";\n"; + color_ratioString[2] = "color_ratio[2] = " + color_ratio[2] + ";\n"; + + float tint_color[] = {Color.red(mTint) / 255f, + Color.green(mTint) / 255f, Color.blue(mTint) / 255f}; + + String tintString[] = new String[3]; + tintString[0] = "tint[0] = " + tint_color[0] + ";\n"; + tintString[1] = "tint[1] = " + tint_color[1] + ";\n"; + tintString[2] = "tint[2] = " + tint_color[2] + ";\n"; + + String shader = "#extension GL_OES_EGL_image_external : require\n" + + "precision mediump float;\n" + + "uniform samplerExternalOES sTexture;\n" + + " vec3 tint;\n" + + " vec3 color_ratio;\n" + + "varying vec2 vTextureCoord;\n" + + "void main() {\n" + // Parameters that were created above + + color_ratioString[0] + + color_ratioString[1] + + color_ratioString[2] + + tintString[0] + + tintString[1] + + tintString[2] + + " vec4 color = texture2D(sTexture, vTextureCoord);\n" + + " float avg_color = dot(color_ratio, color.rgb);\n" + + " vec3 new_color = min(0.8 * avg_color + 0.2 * tint, 1.0);\n" + + " gl_FragColor = vec4(new_color.rgb, color.a);\n" + "}\n"; + return shader; + + } +} diff --git a/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/VignetteEffect.java b/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/VignetteEffect.java new file mode 100644 index 0000000..ce459bc --- /dev/null +++ b/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/effect/VignetteEffect.java @@ -0,0 +1,97 @@ +package com.shuyu.gsyvideoplayer.effect; + +import android.opengl.GLSurfaceView; + +import com.shuyu.gsyvideoplayer.GSYVideoGLView.ShaderInterface; + + +/** + * Applies lomo-camera style effect to video. + * + * @author sheraz.khilji + */ +public class VignetteEffect implements ShaderInterface { + private int mWidth = 0; + private int mHeight = 0; + private float mScale = 0f; + private final float mShade = 0.85f; + + /** + * Initialize Effect + * + * @param scale Float, between 0 and 1. 0 means no change. + */ + public VignetteEffect(float scale) { + if (scale < 0.0f) + scale = 0.0f; + if (scale > 1.0f) + scale = 1.0f; + this.mScale = scale; + + } + + /** + * Init all values that will be used by this shader. + * + * @param mGlSurfaceView which is responsible for displaying your video + */ + private void initValues(GLSurfaceView mGlSurfaceView) { + mWidth = mGlSurfaceView.getWidth(); + mHeight = mGlSurfaceView.getHeight(); + } + + @Override + public String getShader(GLSurfaceView mGlSurfaceView) { + initValues(mGlSurfaceView); + float scale[] = new float[2]; + if (mWidth > mHeight) { + scale[0] = 1f; + scale[1] = ((float) mHeight) / mWidth; + } else { + scale[0] = ((float) mWidth) / mHeight; + scale[1] = 1f; + } + float max_dist = ((float) Math.sqrt(scale[0] * scale[0] + scale[1] + * scale[1])) * 0.5f; + + String scaleString[] = new String[2]; + + scaleString[0] = "scale[0] = " + scale[0] + ";\n"; + scaleString[1] = "scale[1] = " + scale[1] + ";\n"; + String inv_max_distString = "inv_max_dist = " + 1.0f / max_dist + ";\n"; + String shadeString = "shade = " + mShade + ";\n"; + + // The 'range' is between 1.3 to 0.6. When scale is zero then range is + // 1.3 + // which means no vignette at all because the luminousity difference is + // less than 1/256 and will cause nothing. + String rangeString = "range = " + + (1.30f - (float) Math.sqrt(mScale) * 0.7f) + ";\n"; + + String shader = "#extension GL_OES_EGL_image_external : require\n" + + "precision mediump float;\n" + + "uniform samplerExternalOES sTexture;\n" + + " float range;\n" + + " float inv_max_dist;\n" + + " float shade;\n" + + " vec2 scale;\n" + + "varying vec2 vTextureCoord;\n" + + "void main() {\n" + // Parameters that were created above + + scaleString[0] + + scaleString[1] + + inv_max_distString + + shadeString + + rangeString + + " const float slope = 20.0;\n" + + " vec2 coord = vTextureCoord - vec2(0.5, 0.5);\n" + + " float dist = length(coord * scale);\n" + + " float lumen = shade / (1.0 + exp((dist * inv_max_dist - range) * slope)) + (1.0 - shade);\n" + + " vec4 color = texture2D(sTexture, vTextureCoord);\n" + + " gl_FragColor = vec4(color.rgb * lumen, color.a);\n" + + "}\n"; + + return shader; + + } +} diff --git a/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/utils/GSYVideoType.java b/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/utils/GSYVideoType.java index 0c7153a..2a9abf9 100644 --- a/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/utils/GSYVideoType.java +++ b/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/utils/GSYVideoType.java @@ -26,6 +26,10 @@ public class GSYVideoType { public final static int IJKEXOPLAYER = 1; + + //gl + public final static int GLSURFACE = 2; + //surface public final static int SUFRACE = 1; 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 bf6eed3..b8eb11c 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 @@ -7,20 +7,16 @@ import android.support.annotation.AttrRes; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.util.AttributeSet; -import android.view.Gravity; import android.view.Surface; import android.view.SurfaceHolder; -import android.view.SurfaceView; import android.view.TextureView; -import android.view.View; import android.view.ViewGroup; import android.widget.FrameLayout; -import android.widget.RelativeLayout; import com.shuyu.gsyvideoplayer.GSYRenderView; -import com.shuyu.gsyvideoplayer.GSYSurfaceView; -import com.shuyu.gsyvideoplayer.GSYTextureView; +import com.shuyu.gsyvideoplayer.GSYVideoGLView; import com.shuyu.gsyvideoplayer.GSYVideoManager; +import com.shuyu.gsyvideoplayer.effect.NoEffect; import com.shuyu.gsyvideoplayer.utils.GSYVideoType; /** @@ -28,7 +24,7 @@ import com.shuyu.gsyvideoplayer.utils.GSYVideoType; * Created by guoshuyu on 2017/8/2. */ -public abstract class GSYTextureRenderView extends FrameLayout implements TextureView.SurfaceTextureListener, SurfaceHolder.Callback2 { +public abstract class GSYTextureRenderView extends FrameLayout implements TextureView.SurfaceTextureListener, SurfaceHolder.Callback2, GSYVideoGLView.onGSYSurfaceListener { //native绘制 protected Surface mSurface; @@ -42,6 +38,9 @@ public abstract class GSYTextureRenderView extends FrameLayout implements Textur //满屏填充暂停为徒 protected Bitmap mFullPauseBitmap; + //滤镜 + protected GSYVideoGLView.ShaderInterface mEffectFilter = new NoEffect(); + //画面选择角度 protected int mRotate; @@ -106,6 +105,11 @@ public abstract class GSYTextureRenderView extends FrameLayout implements Textur public void surfaceRedrawNeeded(SurfaceHolder holder) { } + /******************** GLSurfaceView ****************************/ + @Override + public void onSurfaceAvailable(Surface surface) { + pauseLogic(surface, false); + } /** * 暂停逻辑 @@ -128,6 +132,9 @@ public abstract class GSYTextureRenderView extends FrameLayout implements Textur if (GSYVideoType.getRenderType() == GSYVideoType.SUFRACE) { mTextureView.addSurfaceView(getContext(), mTextureViewContainer, mRotate, this); return; + } else if (GSYVideoType.getRenderType() == GSYVideoType.GLSURFACE) { + mTextureView.addGLView(getContext(), mTextureViewContainer, mRotate, this, mEffectFilter); + return; } mTextureView.addTextureView(getContext(), mTextureViewContainer, mRotate, this); @@ -171,6 +178,13 @@ public abstract class GSYTextureRenderView extends FrameLayout implements Textur } + protected GSYVideoGLView getGSYVideoGLSView() { + if (mTextureView.getShowView() instanceof GSYVideoGLView) { + return (GSYVideoGLView)mTextureView.getShowView(); + } + return null; + } + //暂停时使用绘制画面显示暂停、避免黑屏 protected abstract void showPauseCover(); @@ -180,4 +194,15 @@ public abstract class GSYTextureRenderView extends FrameLayout implements Textur //小屏幕绘制层 protected abstract void setSmallVideoTextureView(); + + public GSYVideoGLView.ShaderInterface getEffectFilter() { + return mEffectFilter; + } + + /** + * 设置滤镜效果 + */ + public void setEffectFilter(GSYVideoGLView.ShaderInterface effectFilter) { + this.mEffectFilter = effectFilter; + } } diff --git a/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/video/base/GSYVideoView.java b/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/video/base/GSYVideoView.java index fb09b4a..e3e7ac7 100644 --- a/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/video/base/GSYVideoView.java +++ b/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/video/base/GSYVideoView.java @@ -495,6 +495,10 @@ public abstract class GSYVideoView extends GSYTextureRenderView implements GSYMe listenerNetWorkState(); mHadPlay = true; + + if (mTextureView != null) { + mTextureView.onResume(); + } } @Override -- GitLab