Skip to content

Commit daad105

Browse files
committed
1. fix crash of face detection. 2. Add new demo for data buffer callback
1 parent a10c97f commit daad105

File tree

12 files changed

+143
-144
lines changed

12 files changed

+143
-144
lines changed

cgeDemo/src/main/java/org/wysaid/cgeDemo/CameraDemoActivity.java

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -236,12 +236,8 @@ public void onClick(View v) {
236236

237237
mCameraView.setOnCreateCallback(new CameraRecordGLSurfaceView.OnCreateCallback() {
238238
@Override
239-
public void createOver(boolean success) {
240-
if (success) {
241-
Log.i(LOG_TAG, "view create OK");
242-
} else {
243-
Log.e(LOG_TAG, "view create failed!");
244-
}
239+
public void createOver() {
240+
Log.i(LOG_TAG, "view onCreate");
245241
}
246242
});
247243

cgeDemo/src/main/java/org/wysaid/cgeDemo/FaceTrackingDemoActivity.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,9 @@ protected void onCreate(Bundle savedInstanceState) {
2626

2727
mCameraView.setOnCreateCallback(new CameraGLSurfaceView.OnCreateCallback() {
2828
@Override
29-
public void createOver(boolean success) {
30-
if(success) {
31-
FaceTrackingDemo demo = new FaceTrackingDemo();
32-
mCameraView.setTrackingProc(demo);
33-
}
29+
public void createOver() {
30+
FaceTrackingDemo demo = new FaceTrackingDemo();
31+
mCameraView.setTrackingProc(demo);
3432
}
3533
});
3634
}

cgeDemo/src/main/java/org/wysaid/cgeDemo/demoUtils/FaceTrackingDemo.java

Lines changed: 61 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
package org.wysaid.cgeDemo.demoUtils;
22

3+
import android.graphics.Bitmap;
4+
import android.graphics.Canvas;
5+
import android.graphics.Matrix;
6+
import android.graphics.Rect;
37
import android.opengl.GLES20;
48
import android.util.Log;
59

610
import org.wysaid.common.Common;
11+
import org.wysaid.common.FrameBufferObject;
712
import org.wysaid.common.ProgramObject;
813
import org.wysaid.nativePort.CGEFaceTracker;
9-
import org.wysaid.nativePort.CGEFrameRenderer;
1014
import org.wysaid.view.TrackingCameraGLSurfaceView;
1115

1216
import java.nio.ByteBuffer;
@@ -26,8 +30,9 @@ public class FaceTrackingDemo implements TrackingCameraGLSurfaceView.TrackingPro
2630
"uniform vec2 canvasSize;\n" +
2731
"void main()\n" +
2832
"{\n" +
29-
" gl_PointSize = 3.0;\n" +
33+
" gl_PointSize = 10.0;\n" +
3034
" gl_Position = vec4((vPosition / canvasSize) * 2.0 - 1.0, 0.0, 1.0);\n" +
35+
" gl_Position.y = -gl_Position.y;\n" + // Mirror on screen.
3136
"}";
3237

3338
protected static final String FSH = "" +
@@ -38,16 +43,20 @@ public class FaceTrackingDemo implements TrackingCameraGLSurfaceView.TrackingPro
3843
" gl_FragColor = color;\n" +
3944
"}";
4045

41-
CGEFaceTracker mTracker;
42-
int mWidth, mHeight;
43-
int mOriginWidth, mOriginHeight;
44-
int mMaxSize = 240;
45-
ByteBuffer mImageCacheBuffer;
46-
ProgramObject mProgramObject;
47-
CGEFaceTracker.FaceResult mFaceResult;
46+
private int mOriginWidth, mOriginHeight;
47+
private int mMaxSize = 320;
48+
private ByteBuffer mImageCacheBuffer;
49+
private Bitmap mBitmapSrc, mBitmapDst;
50+
private Matrix mTransformMatrix;
51+
private Canvas mTransformCanvas;
52+
protected CGEFaceTracker mTracker;
53+
protected int mWidth, mHeight;
54+
protected int[] mFaceTrackingLock = new int[0];
55+
protected ProgramObject mProgramObject;
56+
protected CGEFaceTracker.FaceResult mFaceResult;
4857

4958
@Override
50-
public boolean setup(CGEFrameRenderer renderer, int width, int height) {
59+
public boolean setup(int width, int height) {
5160
mTracker = CGEFaceTracker.createFaceTracker();
5261
mProgramObject = new ProgramObject();
5362
mProgramObject.bindAttribLocation("vPosition", 0);
@@ -84,55 +93,65 @@ public void resize(int width, int height) {
8493
mProgramObject.sendUniformf("canvasSize", mWidth, mHeight);
8594
mProgramObject.sendUniformf("color", 1, 0, 0, 0);
8695

87-
mImageCacheBuffer = ByteBuffer.allocateDirect(mWidth * mHeight * 4).order(ByteOrder.nativeOrder());
96+
mImageCacheBuffer = ByteBuffer.allocateDirect(mWidth * mHeight).order(ByteOrder.nativeOrder());
97+
mBitmapSrc = Bitmap.createBitmap(mOriginHeight, mOriginWidth, Bitmap.Config.ALPHA_8);
98+
mBitmapDst = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.ALPHA_8);
99+
mTransformMatrix = new Matrix();
100+
mTransformMatrix.setScale(scaling, -scaling);
101+
mTransformMatrix.postRotate(90);
102+
mTransformMatrix.postTranslate(-mWidth / 2, -mHeight / 2);
103+
mTransformMatrix.postRotate(180);
104+
mTransformMatrix.postTranslate(mWidth / 2, mHeight / 2);
105+
mTransformCanvas = new Canvas(mBitmapDst);
106+
mTransformCanvas.setMatrix(mTransformMatrix);
88107
}
89108

109+
90110
@Override
91-
public void processTracking(CGEFrameRenderer renderer) {
92-
if (mImageCacheBuffer == null) {
111+
public void processTracking(ByteBuffer luminanceBuffer) {
112+
if (luminanceBuffer == null) {
93113
return;
94114
}
95115

116+
mBitmapSrc.copyPixelsFromBuffer(luminanceBuffer.position(0));
117+
mTransformCanvas.drawBitmap(mBitmapSrc, 0.0f, 0.0f, null);
118+
mBitmapDst.copyPixelsToBuffer(mImageCacheBuffer.position(0));
119+
96120
long tm = System.currentTimeMillis();
97121

98-
//A simple but risky trick. Please choose a better way to receive the buffer.
99-
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
100-
GLES20.glViewport(0, 0, mWidth, mHeight);
101-
renderer.drawCache();
102-
//You may have a better way to avoid calling of readpixel.
103-
GLES20.glReadPixels(0, 0, mWidth, mHeight, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, mImageCacheBuffer.rewind());
104-
105-
long readPixelTime = System.currentTimeMillis() - tm;
106-
107-
//No matter what the rgb order is, only gray space is used at last.
108-
//So just call this.
109-
boolean ret = mTracker.detectFaceWithBGRABuffer(mImageCacheBuffer, mWidth, mHeight, mWidth * 4);
110-
if (ret) {
111-
//The processTracking & render function is in the same thread for this demo.
112-
//So no sync code here.
113-
mFaceResult = mTracker.getFaceResult();
114-
} else {
115-
mFaceResult = null;
122+
mImageCacheBuffer.position(0);
123+
boolean ret = mTracker.detectFaceWithGrayBuffer(mImageCacheBuffer, mWidth, mHeight, mWidth);
124+
125+
synchronized (mFaceTrackingLock) {
126+
if (ret) {
127+
mFaceResult = mTracker.getFaceResult();
128+
} else {
129+
mFaceResult = null;
130+
}
116131
}
117132

118133
long totalTime = System.currentTimeMillis() - tm;
119-
Log.i(Common.LOG_TAG, String.format("read pixel time: %g, tracking time: %g, total: %g", readPixelTime / 1000.0f, (totalTime - readPixelTime) / 1000.0f, totalTime / 1000.0f));
134+
Log.i(Common.LOG_TAG, String.format("tracking time: %g s", totalTime / 1000.0f));
120135
}
121136

122137
@Override
123-
public void render(CGEFrameRenderer renderer) {
124-
if (mProgramObject == null || mFaceResult == null)
125-
return;
138+
public void render(TrackingCameraGLSurfaceView glView) {
126139

127-
renderer.bindImageFBO();
128-
GLES20.glViewport(0, 0, mOriginWidth, mOriginHeight);
140+
glView.drawCurrentFrame();
129141

130-
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
131-
GLES20.glEnableVertexAttribArray(0);
132-
GLES20.glVertexAttribPointer(0, 2, GLES20.GL_FLOAT, false, 0, mFaceResult.faceKeyPoints.position(0));
142+
synchronized (mFaceTrackingLock) {
143+
if (mProgramObject == null || mFaceResult == null)
144+
return;
133145

134-
mProgramObject.bind();
135-
GLES20.glDrawArrays(GLES20.GL_POINTS, 0, 66);
146+
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
147+
GLES20.glEnableVertexAttribArray(0);
148+
GLES20.glVertexAttribPointer(0, 2, GLES20.GL_FLOAT, false, 0, mFaceResult.faceKeyPoints.position(0));
149+
150+
mProgramObject.bind();
151+
GLES20.glDrawArrays(GLES20.GL_POINTS, 0, 66);
152+
}
153+
154+
GLES20.glFinish();
136155
}
137156

138157
@Override

library/src/main/java/org/wysaid/view/CameraGLSurfaceView.java

Lines changed: 12 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,7 @@
1818
import javax.microedition.khronos.opengles.GL10;
1919

2020
/**
21-
* @Author: wangyang
22-
* @Mail: admin@wysaid.org
23-
* @Date: 10/04/2018
24-
* @Description:
21+
* Created by wangyang on 15/7/17.
2522
*/
2623

2724
public class CameraGLSurfaceView extends GLSurfaceView implements GLSurfaceView.Renderer {
@@ -42,8 +39,8 @@ public CameraGLSurfaceView(Context context, AttributeSet attrs) {
4239

4340
public int mMaxTextureSize = 0;
4441

45-
public int mViewWidth;
46-
public int mViewHeight;
42+
protected int mViewWidth;
43+
protected int mViewHeight;
4744

4845
protected int mRecordWidth = 480;
4946
protected int mRecordHeight = 640;
@@ -94,14 +91,18 @@ public synchronized boolean setFlashLightMode(String mode) {
9491
return true;
9592
}
9693

97-
public int mMaxPreviewWidth = 1280;
98-
public int mMaxPreviewHeight = 1280;
94+
protected int mMaxPreviewWidth = 1280;
95+
protected int mMaxPreviewHeight = 1280;
9996

10097
public static class Viewport {
10198
public int x, y, width, height;
10299
}
103100

104-
public Viewport mDrawViewport = new Viewport();
101+
protected Viewport mDrawViewport = new Viewport();
102+
103+
public Viewport getDrawViewport() {
104+
return mDrawViewport;
105+
}
105106

106107
//The max preview size. Change it to 1920+ if you want to preview with 1080P
107108
void setMaxPreviewSize(int w, int h) {
@@ -201,7 +202,7 @@ public void surfaceDestroyed(SurfaceHolder holder) {
201202
}
202203

203204
public interface OnCreateCallback {
204-
void createOver(boolean success);
205+
void createOver();
205206
}
206207

207208
protected OnCreateCallback mOnCreateCallback;
@@ -224,19 +225,8 @@ public void onSurfaceCreated(GL10 gl, EGLConfig config) {
224225
GLES20.glGetIntegerv(GLES20.GL_MAX_TEXTURE_SIZE, texSize, 0);
225226
mMaxTextureSize = texSize[0];
226227

227-
requestRender();
228-
229-
// if (!cameraInstance().isCameraOpened()) {
230-
//
231-
// int facing = mIsCameraBackForward ? Camera.CameraInfo.CAMERA_FACING_BACK : Camera.CameraInfo.CAMERA_FACING_FRONT;
232-
//
233-
// if (!cameraInstance().tryOpenCamera(null, facing)) {
234-
// Log.e(LOG_TAG, "相机启动失败!!");
235-
// }
236-
// }
237-
238228
if (mOnCreateCallback != null) {
239-
mOnCreateCallback.createOver(cameraInstance().getCameraDevice() != null);
229+
mOnCreateCallback.createOver();
240230
}
241231
}
242232

library/src/main/java/org/wysaid/view/CameraGLSurfaceViewWithBuffer.java

Lines changed: 35 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -31,17 +31,18 @@ public class CameraGLSurfaceViewWithBuffer extends CameraGLSurfaceView implement
3131
protected byte[] mPreviewBuffer0;
3232
protected byte[] mPreviewBuffer1;
3333
protected TextureDrawerNV12ToRGB mYUVDrawer;
34-
// TextureDrawer mTextureDrawer;
3534
protected int mTextureY, mTextureUV;
3635
protected int mTextureWidth, mTextureHeight;
3736
protected ByteBuffer mBufferY, mBufferUV;
3837
protected int mYSize, mUVSize;
3938
protected int mBufferSize;
4039
protected SurfaceTexture mSurfaceTexture;
41-
// protected int mTextureID;
40+
protected boolean mBufferUpdated = false;
41+
protected final int[] mBufferUpdateLock = new int[0];
4242

4343
public CameraGLSurfaceViewWithBuffer(Context context, AttributeSet attrs) {
4444
super(context, attrs);
45+
setRenderMode(RENDERMODE_CONTINUOUSLY);
4546
}
4647

4748
@Override
@@ -100,12 +101,22 @@ protected void resizeTextures() {
100101
}
101102

102103
protected void updateTextures() {
103-
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
104-
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureY);
105-
GLES20.glTexSubImage2D(GLES20.GL_TEXTURE_2D, 0, 0, 0, mTextureWidth, mTextureHeight, GLES20.GL_LUMINANCE, GLES20.GL_UNSIGNED_BYTE, mBufferY.position(0));
106-
GLES20.glActiveTexture(GLES20.GL_TEXTURE1);
107-
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureUV);
108-
GLES20.glTexSubImage2D(GLES20.GL_TEXTURE_2D, 0, 0, 0, mTextureWidth / 2, mTextureHeight / 2, GLES20.GL_LUMINANCE_ALPHA, GLES20.GL_UNSIGNED_BYTE, mBufferUV.position(0));
104+
if(mBufferUpdated) {
105+
synchronized (mBufferUpdateLock) {
106+
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
107+
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureY);
108+
GLES20.glTexSubImage2D(GLES20.GL_TEXTURE_2D, 0, 0, 0, mTextureWidth, mTextureHeight, GLES20.GL_LUMINANCE, GLES20.GL_UNSIGNED_BYTE, mBufferY.position(0));
109+
GLES20.glActiveTexture(GLES20.GL_TEXTURE1);
110+
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureUV);
111+
GLES20.glTexSubImage2D(GLES20.GL_TEXTURE_2D, 0, 0, 0, mTextureWidth / 2, mTextureHeight / 2, GLES20.GL_LUMINANCE_ALPHA, GLES20.GL_UNSIGNED_BYTE, mBufferUV.position(0));
112+
mBufferUpdated = false;
113+
}
114+
} else {
115+
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
116+
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureY);
117+
GLES20.glActiveTexture(GLES20.GL_TEXTURE1);
118+
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureUV);
119+
}
109120
}
110121

111122
@Override
@@ -199,28 +210,35 @@ public void onSurfaceChanged(GL10 gl, int width, int height) {
199210
}
200211
}
201212

202-
@Override
203-
public void onDrawFrame(GL10 gl) {
204-
213+
public void drawCurrentFrame() {
205214
if(mYUVDrawer == null) {
206215
return;
207216
}
208217

209218
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
210-
updateTextures();
211219
GLES20.glClearColor(0,0,0,1);
212220
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
213221
GLES20.glViewport(mDrawViewport.x, mDrawViewport.y, mDrawViewport.width, mDrawViewport.height);
222+
updateTextures();
214223
mYUVDrawer.drawTextures();
215224
}
216225

226+
@Override
227+
public void onDrawFrame(GL10 gl) {
228+
drawCurrentFrame();
229+
}
230+
217231
@Override
218232
public void onPreviewFrame(byte[] data, Camera camera) {
219-
mBufferY.position(0);
220-
mBufferUV.position(0);
221-
mBufferY.put(data, 0, mYSize);
222-
mBufferUV.put(data, mYSize, mUVSize);
233+
234+
synchronized (mBufferUpdateLock) {
235+
mBufferY.position(0);
236+
mBufferUV.position(0);
237+
mBufferY.put(data, 0, mYSize);
238+
mBufferUV.put(data, mYSize, mUVSize);
239+
mBufferUpdated = true;
240+
}
241+
223242
camera.addCallbackBuffer(data);
224-
requestRender();
225243
}
226244
}

library/src/main/java/org/wysaid/view/CameraGLSurfaceViewWithTexture.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ public void setOnCreateCallback(final OnCreateCallback callback) {
8383
queueEvent(new Runnable() {
8484
@Override
8585
public void run() {
86-
callback.createOver(cameraInstance().getCameraDevice() != null);
86+
callback.createOver();
8787
}
8888
});
8989
}
@@ -95,8 +95,6 @@ public CameraGLSurfaceViewWithTexture(Context context, AttributeSet attrs) {
9595

9696
@Override
9797
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
98-
super.onSurfaceCreated(gl, config);
99-
10098
mFrameRecorder = new CGEFrameRecorder();
10199
mIsTransformMatrixSet = false;
102100
if (!mFrameRecorder.init(mRecordWidth, mRecordHeight, mRecordWidth, mRecordHeight)) {
@@ -110,6 +108,8 @@ public void onSurfaceCreated(GL10 gl, EGLConfig config) {
110108
mTextureID = Common.genSurfaceTextureID();
111109
mSurfaceTexture = new SurfaceTexture(mTextureID);
112110
mSurfaceTexture.setOnFrameAvailableListener(this);
111+
112+
super.onSurfaceCreated(gl, config);
113113
}
114114

115115
protected void onRelease() {

0 commit comments

Comments
 (0)