/* * * AiyaCameraDrawer.java * * Created by Wuwang on 2016/11/18 * Copyright © 2016年 深圳哎吖科技. All rights reserved. */ package com.aiyaapp.camera.sdk.widget; import java.nio.ByteBuffer; import java.util.Queue; import java.util.concurrent.LinkedBlockingQueue; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; import android.content.res.Resources; import android.graphics.SurfaceTexture; import android.hardware.Camera; import android.opengl.GLES11Ext; import android.opengl.GLES20; import android.opengl.GLSurfaceView; import com.aiyaapp.camera.sdk.base.FrameCallback; import com.aiyaapp.camera.sdk.base.Log; import com.aiyaapp.camera.sdk.filter.AFilter; import com.aiyaapp.camera.sdk.filter.EasyGlUtils; import com.aiyaapp.camera.sdk.filter.MatrixUtils; import com.aiyaapp.camera.sdk.filter.GroupFilter; import com.aiyaapp.camera.sdk.filter.NoFilter; import com.aiyaapp.camera.sdk.filter.PrepareFilter; import com.aiyaapp.camera.sdk.filter.ProcessFilter; /** * Description: */ @Deprecated public class AiyaCameraDrawer implements GLSurfaceView.Renderer { private float[] EM=new float[16]; //用于更改大小的变换矩阵 private float[] SM=new float[16]; //用于显示的变换矩阵 private float[] OM; //用于后台绘制的变换矩阵 private int width, height; private SurfaceTexture mSurfaceTexture; // private AFilter mBeauty; //美颜滤镜 // private AFilter mNoFilter; //无滤镜 // private AFilter mNowFilter; //当前滤镜 private AFilter mShowFilter; //用于显示到界面上 private FrameCallback mFrameCallback; //每帧处理的回调 private int frameCallbackWidth, frameCallbackHeight; //回调数据的宽高 private boolean oneShotCallback = false; //是否回调 private boolean isKeepCallback = false; //是否一直回调 private ByteBuffer[] outPutBuffer = new ByteBuffer[3]; private Queue<byte[]> cameraByteQueue; private int indexOutput = 0; private boolean update = false; private float[] infos = new float[20]; private AFilter mPreFilter; //数据准备的Filter,track和保存 private AFilter mProcessFilter; private GroupFilter mBeFilter; private GroupFilter mAfFilter; private int textureIndex = 0; //创建离屏buffer private int[] fFrame = new int[1]; private int[] fTexture = new int[1]; private int mPreviewWidth=0,mPreviewHeight=0; private boolean isPreviewSizeChanged=false; public static final int PARAMS_TYPE_FILTER = 0; public AiyaCameraDrawer(Resources res) { cameraByteQueue = new LinkedBlockingQueue<>(); // mBeauty = new Beauty(res); // mNoFilter = new NoFilter(res); // mNowFilter = mNoFilter; mPreFilter = new PrepareFilter(res); mProcessFilter=new ProcessFilter(res); mShowFilter = new NoFilter(res); mBeFilter=new GroupFilter(res); mAfFilter=new GroupFilter(res); //必须传入上下翻转的矩阵 // OM= MatrixUtils.getOriginalMatrix(); // MatrixUtils.flip(OM,false,true); } public void addFilter(AFilter filter,boolean beforeTrack){ // filter.setMatrix(OM); if(beforeTrack){ mBeFilter.addFilter(filter); }else{ mAfFilter.addFilter(filter); } } @Override public void onSurfaceCreated(GL10 gl, EGLConfig config) { int texture = createTextureID(); mSurfaceTexture = new SurfaceTexture(texture); mPreFilter.create(); mPreFilter.setTextureId(texture); mProcessFilter.create(); // mBeauty.create(); // mNoFilter.create(); mShowFilter.create(); mBeFilter.create(); mAfFilter.create(); } public SurfaceTexture getTexture() { return mSurfaceTexture; } public void update(byte[] bytes) { cameraByteQueue.add(bytes); this.update = true; } @Override public void onSurfaceChanged(GL10 gl, int width, int height) { cameraByteQueue.clear(); this.width = width; this.height = height; if(this.isPreviewSizeChanged){ isPreviewSizeChanged=false; deleteFrameBuffer(); GLES20.glGenFramebuffers(1,fFrame,0); EasyGlUtils.genTexturesWithParameter(1,fTexture,0,GLES20.GL_RGBA,mPreviewWidth,mPreviewHeight); mPreFilter.setSize(mPreviewWidth,mPreviewHeight); mBeFilter.setSize(mPreviewWidth,mPreviewHeight); mAfFilter.setSize(mPreviewWidth,mPreviewHeight); mProcessFilter.setSize(mPreviewWidth,mPreviewHeight); } MatrixUtils.getShowMatrix(SM,mPreviewWidth, mPreviewHeight, width, height); MatrixUtils.flip(SM,false,true); if (frameCallbackWidth != 0 && frameCallbackHeight != 0) { MatrixUtils.getShowMatrix(EM,mPreviewWidth, mPreviewHeight, frameCallbackWidth, frameCallbackHeight); MatrixUtils.flip(EM,false,true); } mShowFilter.setMatrix(SM); // if (OM == null) { // OM = MatrixUtils.getOriginalMatrix(); // MatrixUtils.flip(OM, false, true); // } // mBeauty.setMatrix(OM); // mNoFilter.setMatrix(OM); } public void setParams(int type,int ... params){ } @Override public void onDrawFrame(GL10 gl) { if (update) { update = false; mSurfaceTexture.updateTexImage(); } //在离屏Buffer中绘制track的数据,并交给track处理 long start=System.currentTimeMillis(); mPreFilter.draw(); Log.e("track read------------------------>"+(System.currentTimeMillis()-start)); start=System.currentTimeMillis(); mBeFilter.setTextureId(mPreFilter.getOutputTexture()); mBeFilter.draw(); Log.e("before filter------------------------>"+(System.currentTimeMillis()-start)); start=System.currentTimeMillis(); //获取缓存的texture绘制并处理 mProcessFilter.setTextureId(mBeFilter.getOutputTexture()); mProcessFilter.draw(); Log.e("process------------------------>"+(System.currentTimeMillis()-start)); start=System.currentTimeMillis(); mAfFilter.setTextureId(mProcessFilter.getOutputTexture()); mAfFilter.draw(); Log.e("after filter------------------------>"+(System.currentTimeMillis()-start)); Log.e("show data index->" + textureIndex); //显示出刚才绘制的内容 GLES20.glViewport(0, 0, width, height); mShowFilter.setTextureId(mAfFilter.getOutputTexture()); mShowFilter.draw(); Log.e("beauty------------------------>"+(System.currentTimeMillis()-start)); callbackIfNeeded(); byte[] d = cameraByteQueue.poll(); if (mCamera != null && d != null) { mCamera.addCallbackBuffer(d); } } /** * 设置帧数据回调 * @param width 希望得到的图片宽度 * @param height 希望得到的图片高度 * @param frameCallback 回调 */ public void setFrameCallback(int width, int height, FrameCallback frameCallback) { this.frameCallbackWidth =width; this.frameCallbackHeight = height; if (frameCallbackWidth > 0 && frameCallbackHeight > 0) { if(outPutBuffer!=null){ outPutBuffer=new ByteBuffer[3]; } MatrixUtils.getShowMatrix(EM,mPreviewWidth, mPreviewHeight, frameCallbackWidth,frameCallbackHeight); MatrixUtils.flip(EM,false,true); this.mFrameCallback = frameCallback; } else { this.mFrameCallback = null; } } /** * 设置是否开启对每一帧数据的捕获 * @param isKeepCallback */ public void setKeepCallback(boolean isKeepCallback){ this.isKeepCallback=isKeepCallback; } /** * 设置是否去捕获下一帧数据 * @param oneShotCallback */ public void setOneShotCallback(boolean oneShotCallback){ this.oneShotCallback=oneShotCallback; } private Camera mCamera; public void setCamera(Camera camera) { this.mCamera = camera; } public void setPreviewSize(int width,int height){ if(this.mPreviewWidth!=width||this.mPreviewHeight!=height){ this.mPreviewWidth=width; this.mPreviewHeight=height; this.isPreviewSizeChanged=true; } } //需要回调,则缩放图片到指定大小,读取数据并回调 private void callbackIfNeeded() { if (mFrameCallback != null && (oneShotCallback || isKeepCallback)) { indexOutput = indexOutput++ >= 2 ? 0 : indexOutput; if (outPutBuffer[indexOutput] == null) { outPutBuffer[indexOutput] = ByteBuffer.allocate(frameCallbackWidth * frameCallbackHeight*4); } GLES20.glViewport(0, 0, frameCallbackWidth, frameCallbackHeight); EasyGlUtils.bindFrameTexture(fFrame[0],fTexture[0]); mShowFilter.setMatrix(EM); mShowFilter.draw(); frameCallback(); oneShotCallback = false; EasyGlUtils.unBindFrameBuffer(); mShowFilter.setMatrix(SM); } } //读取数据并回调 private void frameCallback(){ GLES20.glReadPixels(0, 0, frameCallbackWidth, frameCallbackHeight, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, outPutBuffer[indexOutput]); mFrameCallback.onFrame(outPutBuffer[indexOutput].array(),mSurfaceTexture.getTimestamp()); } //根据摄像头设置纹理映射坐标 public void setCameraId(int id) { mPreFilter.setFlag(id); } //创建显示摄像头原始数据的OES TEXTURE private int createTextureID() { int[] texture = new int[1]; GLES20.glGenTextures(1, texture, 0); GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, texture[0]); GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR); GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR); GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE); GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE); return texture[0]; } private void deleteFrameBuffer() { GLES20.glDeleteFramebuffers(1, fFrame, 0); GLES20.glDeleteTextures(1, fTexture, 0); } }