diff --git a/samples/android/tutorial-4-opencl/.cproject b/samples/android/tutorial-4-opencl/.cproject index 9f3b5fd84f..90fc6c97f0 100644 --- a/samples/android/tutorial-4-opencl/.cproject +++ b/samples/android/tutorial-4-opencl/.cproject @@ -5,6 +5,7 @@ + @@ -12,7 +13,6 @@ - @@ -28,7 +28,7 @@ diff --git a/samples/android/tutorial-4-opencl/jni/Android.mk b/samples/android/tutorial-4-opencl/jni/Android.mk index fa44bf8c53..dacd0f665c 100644 --- a/samples/android/tutorial-4-opencl/jni/Android.mk +++ b/samples/android/tutorial-4-opencl/jni/Android.mk @@ -21,7 +21,7 @@ endif LOCAL_C_INCLUDES += $(OPENCL_SDK)/include LOCAL_LDLIBS += -L$(OPENCL_SDK)/lib/$(TARGET_ARCH_ABI) -lOpenCL -LOCAL_MODULE := JNIrender -LOCAL_SRC_FILES := jni.c GLrender.cpp CLprocessor.cpp +LOCAL_MODULE := JNIpart +LOCAL_SRC_FILES := jni.c CLprocessor.cpp LOCAL_LDLIBS += -llog -lGLESv2 -lEGL include $(BUILD_SHARED_LIBRARY) \ No newline at end of file diff --git a/samples/android/tutorial-4-opencl/jni/CLprocessor.cpp b/samples/android/tutorial-4-opencl/jni/CLprocessor.cpp index a46cac4247..b7bf530b97 100644 --- a/samples/android/tutorial-4-opencl/jni/CLprocessor.cpp +++ b/samples/android/tutorial-4-opencl/jni/CLprocessor.cpp @@ -2,6 +2,7 @@ #define CL_USE_DEPRECATED_OPENCL_1_1_APIS /*let's give a chance for OpenCL 1.1 devices*/ #include +#include #include #include @@ -82,7 +83,7 @@ cl::CommandQueue theQueue; cl::Program theProgB2B, theProgI2B, theProgI2I; bool haveOpenCL = false; -void initCL() +extern "C" void initCL() { dumpCLinfo(); @@ -144,14 +145,19 @@ void initCL() LOGD("initCL completed"); } -void closeCL() +extern "C" void closeCL() { } #define GL_TEXTURE_2D 0x0DE1 void procOCL_I2I(int texIn, int texOut, int w, int h) { - if(!haveOpenCL) return; + LOGD("Processing OpenCL Direct (image2d)"); + if(!haveOpenCL) + { + LOGE("OpenCL isn't initialized"); + return; + } LOGD("procOCL_I2I(%d, %d, %d, %d)", texIn, texOut, w, h); cl::ImageGL imgIn (theContext, CL_MEM_READ_ONLY, GL_TEXTURE_2D, 0, texIn); @@ -185,7 +191,12 @@ void procOCL_I2I(int texIn, int texOut, int w, int h) void procOCL_OCV(int texIn, int texOut, int w, int h) { - if(!haveOpenCL) return; + LOGD("Processing OpenCL via OpenCV"); + if(!haveOpenCL) + { + LOGE("OpenCL isn't initialized"); + return; + } int64_t t = getTimeMs(); cl::ImageGL imgIn (theContext, CL_MEM_READ_ONLY, GL_TEXTURE_2D, 0, texIn); @@ -219,3 +230,60 @@ void procOCL_OCV(int texIn, int texOut, int w, int h) cv::ocl::finish(); LOGD("uploading results to texture costs %d ms", getTimeInterval(t)); } + +void drawFrameProcCPU(int w, int h, int texOut) +{ + LOGD("Processing on CPU"); + int64_t t; + + // let's modify pixels in FBO texture in C++ code (on CPU) + const int BUFF_SIZE = 1<<24;//2k*2k*4; + static char tmpBuff[BUFF_SIZE]; + if(w*h > BUFF_SIZE) + { + LOGE("Internal temp buffer is too small, can't make CPU frame processing"); + return; + } + + // read + t = getTimeMs(); + // expecting FBO to be bound + glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, tmpBuff); + LOGD("glReadPixels() costs %d ms", getTimeInterval(t)); + + // modify + t = getTimeMs(); + cv::Mat m(h, w, CV_8UC4, tmpBuff); + cv::Laplacian(m, m, CV_8U); + m *= 10; + LOGD("Laplacian() costs %d ms", getTimeInterval(t)); + + // write back + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, texOut); + t = getTimeMs(); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, tmpBuff); + LOGD("glTexSubImage2D() costs %d ms", getTimeInterval(t)); +} + + +enum ProcMode {PROC_MODE_NO_PROC=0, PROC_MODE_CPU=1, PROC_MODE_OCL_DIRECT=2, PROC_MODE_OCL_OCV=3}; + +extern "C" void processFrame(int tex1, int tex2, int w, int h, int mode) +{ + switch(mode) + { + //case PROC_MODE_NO_PROC: + case PROC_MODE_CPU: + drawFrameProcCPU(w, h, tex2); + break; + case PROC_MODE_OCL_DIRECT: + procOCL_I2I(tex1, tex2, w, h); + break; + case PROC_MODE_OCL_OCV: + procOCL_OCV(tex1, tex2, w, h); + break; + default: + LOGE("Unexpected processing mode: %d", mode); + } +} diff --git a/samples/android/tutorial-4-opencl/jni/GLrender.cpp b/samples/android/tutorial-4-opencl/jni/GLrender.cpp deleted file mode 100644 index 5c2862026a..0000000000 --- a/samples/android/tutorial-4-opencl/jni/GLrender.cpp +++ /dev/null @@ -1,375 +0,0 @@ -#include -#include - -#include -#include - -#include "common.hpp" - -float vertices[] = { - -1.0f, -1.0f, - -1.0f, 1.0f, - 1.0f, -1.0f, - 1.0f, 1.0f -}; -float texCoordOES[] = { - 0.0f, 1.0f, - 0.0f, 0.0f, - 1.0f, 1.0f, - 1.0f, 0.0f -}; -float texCoord2D[] = { - 0.0f, 0.0f, - 0.0f, 1.0f, - 1.0f, 0.0f, - 1.0f, 1.0f -}; - -const char vss[] = \ - "attribute vec2 vPosition;\n" \ - "attribute vec2 vTexCoord;\n" \ - "varying vec2 texCoord;\n" \ - "void main() {\n" \ - " texCoord = vTexCoord;\n" \ - " gl_Position = vec4 ( vPosition, 0.0, 1.0 );\n" \ - "}"; - -const char fssOES[] = \ - "#extension GL_OES_EGL_image_external : require\n" \ - "precision mediump float;\n" \ - "uniform samplerExternalOES sTexture;\n" \ - "varying vec2 texCoord;\n" \ - "void main() {\n" \ - " gl_FragColor = texture2D(sTexture,texCoord);\n" \ - "}"; - -const char fss2D[] = \ - "precision mediump float;\n" \ - "uniform sampler2D sTexture;\n" \ - "varying vec2 texCoord;\n" \ - "void main() {\n" \ - " gl_FragColor = texture2D(sTexture,texCoord);\n" \ - "}"; - -GLuint progOES = 0; -GLuint prog2D = 0; - -GLint vPosOES, vTCOES; -GLint vPos2D, vTC2D; - -GLuint FBOtex = 0, FBOtex2 = 0; -GLuint FBO = 0; - -GLuint texOES = 0; -int texWidth = 0, texHeight = 0; - -enum ProcMode {PROC_MODE_NO_PROC=0, PROC_MODE_CPU=1, PROC_MODE_OCL_DIRECT=2, PROC_MODE_OCL_OCV=3}; - -ProcMode procMode = PROC_MODE_NO_PROC; - -static inline void deleteTex(GLuint* tex) -{ - if(tex && *tex) - { - glDeleteTextures(1, tex); - *tex = 0; - } -} - -static void releaseFBO() -{ - if (FBO != 0) - { - glBindFramebuffer(GL_FRAMEBUFFER, 0); - glDeleteFramebuffers(1, &FBO); - FBO = 0; - } - deleteTex(&FBOtex); - deleteTex(&FBOtex2); - glDeleteProgram(prog2D); - prog2D = 0; -} - -static inline void logShaderCompileError(GLuint shader, bool isProgram = false) -{ - GLchar msg[512]; - msg[0] = 0; - GLsizei len; - if(isProgram) - glGetProgramInfoLog(shader, sizeof(msg)-1, &len, msg); - else - glGetShaderInfoLog(shader, sizeof(msg)-1, &len, msg); - LOGE("Could not compile shader/program: %s", msg); -} - -static int makeShaderProg(const char* vss, const char* fss) -{ - LOGD("makeShaderProg: setup GL_VERTEX_SHADER"); - GLuint vshader = glCreateShader(GL_VERTEX_SHADER); - const GLchar* text = vss; - glShaderSource(vshader, 1, &text, 0); - glCompileShader(vshader); - GLint compiled; - glGetShaderiv(vshader, GL_COMPILE_STATUS, &compiled); - if (!compiled) { - logShaderCompileError(vshader); - glDeleteShader(vshader); - vshader = 0; - } - - LOGD("makeShaderProg: setup GL_FRAGMENT_SHADER"); - GLuint fshader = glCreateShader(GL_FRAGMENT_SHADER); - text = fss; - glShaderSource(fshader, 1, &text, 0); - glCompileShader(fshader); - glGetShaderiv(fshader, GL_COMPILE_STATUS, &compiled); - if (!compiled) { - logShaderCompileError(fshader); - glDeleteShader(fshader); - fshader = 0; - } - - LOGD("makeShaderProg: glCreateProgram"); - GLuint program = glCreateProgram(); - glAttachShader(program, vshader); - glAttachShader(program, fshader); - glLinkProgram(program); - GLint linked; - glGetProgramiv(program, GL_LINK_STATUS, &linked); - if (!linked) - { - logShaderCompileError(program, true); - glDeleteProgram(program); - program = 0; - } - glValidateProgram(program); - GLint validated; - glGetProgramiv(program, GL_VALIDATE_STATUS, &validated); - if (!validated) - { - logShaderCompileError(program, true); - glDeleteProgram(program); - program = 0; - } - - if(vshader) glDeleteShader(vshader); - if(fshader) glDeleteShader(fshader); - - return program; -} - - -static void initFBO(int width, int height) -{ - LOGD("initFBO(%d, %d)", width, height); - releaseFBO(); - - glGenTextures(1, &FBOtex2); - glBindTexture(GL_TEXTURE_2D, FBOtex2); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - - glGenTextures(1, &FBOtex); - glBindTexture(GL_TEXTURE_2D, FBOtex); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - - //int hFBO; - glGenFramebuffers(1, &FBO); - glBindFramebuffer(GL_FRAMEBUFFER, FBO); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, FBOtex, 0); - LOGD("initFBO status: %d", glGetError()); - - if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) - LOGE("initFBO failed: %d", glCheckFramebufferStatus(GL_FRAMEBUFFER)); - - prog2D = makeShaderProg(vss, fss2D); - vPos2D = glGetAttribLocation(prog2D, "vPosition"); - vTC2D = glGetAttribLocation(prog2D, "vTexCoord"); - glEnableVertexAttribArray(vPos2D); - glEnableVertexAttribArray(vTC2D); -} - -void drawTex(int tex, GLenum texType, GLuint fbo) -{ - int64_t t = getTimeMs(); - //draw texture to FBO or to screen - glBindFramebuffer(GL_FRAMEBUFFER, fbo); - glViewport(0, 0, texWidth, texHeight); - - glClear(GL_COLOR_BUFFER_BIT); - - GLuint prog = texType == GL_TEXTURE_EXTERNAL_OES ? progOES : prog2D; - GLint vPos = texType == GL_TEXTURE_EXTERNAL_OES ? vPosOES : vPos2D; - GLint vTC = texType == GL_TEXTURE_EXTERNAL_OES ? vTCOES : vTC2D; - float* texCoord = texType == GL_TEXTURE_EXTERNAL_OES ? texCoordOES : texCoord2D; - glUseProgram(prog); - glVertexAttribPointer(vPos, 2, GL_FLOAT, false, 4*2, vertices); - glVertexAttribPointer(vTC, 2, GL_FLOAT, false, 4*2, texCoord); - - glActiveTexture(GL_TEXTURE0); - glBindTexture(texType, tex); - glUniform1i(glGetUniformLocation(prog, "sTexture"), 0); - - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - glFlush(); - LOGD("drawTex(%u) costs %d ms", tex, getTimeInterval(t)); -} - -void drawFrameOrig() -{ - drawTex(texOES, GL_TEXTURE_EXTERNAL_OES, 0); -} - -void procCPU(char* buff, int w, int h) -{ - int64_t t = getTimeMs(); - cv::Mat m(h, w, CV_8UC4, buff); - cv::Laplacian(m, m, CV_8U); - m *= 10; - LOGD("procCPU() costs %d ms", getTimeInterval(t)); -} - -void drawFrameProcCPU() -{ - int64_t t; - drawTex(texOES, GL_TEXTURE_EXTERNAL_OES, FBO); - - // let's modify pixels in FBO texture in C++ code (on CPU) - const int BUFF_SIZE = 1<<24;//2k*2k*4; - static char tmpBuff[BUFF_SIZE]; - if(texWidth*texHeight > BUFF_SIZE) - { - LOGE("Internal temp buffer is too small, can't make CPU frame processing"); - return; - } - - // read - t = getTimeMs(); - glReadPixels(0, 0, texWidth, texHeight, GL_RGBA, GL_UNSIGNED_BYTE, tmpBuff); - LOGD("glReadPixels() costs %d ms", getTimeInterval(t)); - - // modify - procCPU(tmpBuff, texWidth, texHeight); - - // write back - t = getTimeMs(); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, texWidth, texHeight, GL_RGBA, GL_UNSIGNED_BYTE, tmpBuff); - LOGD("glTexSubImage2D() costs %d ms", getTimeInterval(t)); - - // render to screen - drawTex(FBOtex, GL_TEXTURE_2D, 0); -} - -void procOCL_I2I(int texIn, int texOut, int w, int h); -void procOCL_OCV(int texIn, int texOut, int w, int h); -void drawFrameProcOCL() -{ - drawTex(texOES, GL_TEXTURE_EXTERNAL_OES, FBO); - - // modify pixels in FBO texture using OpenCL and CL-GL interop - procOCL_I2I(FBOtex, FBOtex2, texWidth, texHeight); - - // render to screen - drawTex(FBOtex2, GL_TEXTURE_2D, 0); -} - -void drawFrameProcOCLOCV() -{ - drawTex(texOES, GL_TEXTURE_EXTERNAL_OES, FBO); - - // modify pixels in FBO texture using OpenCL and CL-GL interop - procOCL_OCV(FBOtex, FBOtex2, texWidth, texHeight); - - // render to screen - drawTex(FBOtex2, GL_TEXTURE_2D, 0); -} - -extern "C" void drawFrame() -{ - LOGD("*** drawFrame() ***"); - int64_t t = getTimeMs(); - - switch(procMode) - { - case PROC_MODE_NO_PROC: drawFrameOrig(); break; - case PROC_MODE_CPU: drawFrameProcCPU(); break; - case PROC_MODE_OCL_DIRECT: drawFrameProcOCL(); break; - case PROC_MODE_OCL_OCV: drawFrameProcOCLOCV(); break; - default: drawFrameOrig(); - } - - glFinish(); - LOGD("*** drawFrame() costs %d ms ***", getTimeInterval(t)); -} - -void closeCL(); -extern "C" void closeGL() -{ - closeCL(); - LOGD("closeGL"); - deleteTex(&texOES); - - glUseProgram(0); - glDeleteProgram(progOES); - progOES = 0; - - releaseFBO(); -} - -void initCL(); -extern "C" int initGL() -{ - LOGD("initGL"); - - closeGL(); - - const char* vs = (const char*)glGetString(GL_VERSION); - LOGD("GL_VERSION = %s", vs); - - progOES = makeShaderProg(vss, fssOES); - vPosOES = glGetAttribLocation(progOES, "vPosition"); - vTCOES = glGetAttribLocation(progOES, "vTexCoord"); - glEnableVertexAttribArray(vPosOES); - glEnableVertexAttribArray(vTCOES); - - glClearColor(1.0f, 1.0f, 1.0f, 1.0f); - - texOES = 0; - glGenTextures(1, &texOES); - glBindTexture(GL_TEXTURE_EXTERNAL_OES, texOES); - glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - - initCL(); - - return texOES; -} - -extern "C" void changeSize(int width, int height) -{ - const int MAX_W=1<<11, MAX_H=1<<11; - LOGD("changeSize: %dx%d", width, height); - texWidth = width <= MAX_W ? width : MAX_W; - texHeight = height <= MAX_H ? height : MAX_H; - initFBO(texWidth, texHeight); -} - -extern "C" void setProcessingMode(int mode) -{ - switch(mode) - { - case PROC_MODE_NO_PROC: procMode = PROC_MODE_NO_PROC; break; - case PROC_MODE_CPU: procMode = PROC_MODE_CPU; break; - case PROC_MODE_OCL_DIRECT: procMode = PROC_MODE_OCL_DIRECT; break; - case PROC_MODE_OCL_OCV: procMode = PROC_MODE_OCL_OCV; break; - } -} diff --git a/samples/android/tutorial-4-opencl/jni/common.hpp b/samples/android/tutorial-4-opencl/jni/common.hpp index 20b882a9f1..2923803f25 100644 --- a/samples/android/tutorial-4-opencl/jni/common.hpp +++ b/samples/android/tutorial-4-opencl/jni/common.hpp @@ -1,5 +1,5 @@ #include -#define LOG_TAG "JNIRenderer" +#define LOG_TAG "JNIpart" //#define LOGD(...) #define LOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)) #define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)) diff --git a/samples/android/tutorial-4-opencl/jni/jni.c b/samples/android/tutorial-4-opencl/jni/jni.c index 7be35a0003..0c48ab6063 100644 --- a/samples/android/tutorial-4-opencl/jni/jni.c +++ b/samples/android/tutorial-4-opencl/jni/jni.c @@ -1,32 +1,20 @@ #include -int initGL(); -void closeGL(); -void changeSize(int width, int height); -void drawFrame(); -void setProcessingMode(int mode); +int initCL(); +void closeCL(); +void processFrame(int tex1, int tex2, int w, int h, int mode); -JNIEXPORT jint JNICALL Java_org_opencv_samples_tutorial4_NativeGLRenderer_initGL(JNIEnv * env, jclass cls) +JNIEXPORT jint JNICALL Java_org_opencv_samples_tutorial4_NativePart_initCL(JNIEnv * env, jclass cls) { - return initGL(); + return initCL(); } -JNIEXPORT void JNICALL Java_org_opencv_samples_tutorial4_NativeGLRenderer_closeGL(JNIEnv * env, jclass cls) +JNIEXPORT void JNICALL Java_org_opencv_samples_tutorial4_NativePart_closeCL(JNIEnv * env, jclass cls) { - closeGL(); + closeCL(); } -JNIEXPORT void JNICALL Java_org_opencv_samples_tutorial4_NativeGLRenderer_changeSize(JNIEnv * env, jclass cls, jint width, jint height) +JNIEXPORT void JNICALL Java_org_opencv_samples_tutorial4_NativePart_processFrame(JNIEnv * env, jclass cls, jint tex1, jint tex2, jint w, jint h, jint mode) { - changeSize(width, height); -} - -JNIEXPORT void JNICALL Java_org_opencv_samples_tutorial4_NativeGLRenderer_drawFrame(JNIEnv * env, jclass cls) -{ - drawFrame(); -} - -JNIEXPORT void JNICALL Java_org_opencv_samples_tutorial4_NativeGLRenderer_setProcessingMode(JNIEnv * env, jclass cls, jint mode) -{ - setProcessingMode(mode); + processFrame(tex1, tex2, w, h, mode); } diff --git a/samples/android/tutorial-4-opencl/src/org/opencv/samples/tutorial4/Camera2Renderer.java b/samples/android/tutorial-4-opencl/src/org/opencv/samples/tutorial4/Camera2Renderer.java deleted file mode 100644 index 217268a78f..0000000000 --- a/samples/android/tutorial-4-opencl/src/org/opencv/samples/tutorial4/Camera2Renderer.java +++ /dev/null @@ -1,281 +0,0 @@ -package org.opencv.samples.tutorial4; - -import java.util.Arrays; -import java.util.concurrent.Semaphore; -import java.util.concurrent.TimeUnit; - -import android.annotation.SuppressLint; -import android.content.Context; -import android.graphics.SurfaceTexture; -import android.hardware.camera2.CameraAccessException; -import android.hardware.camera2.CameraCaptureSession; -import android.hardware.camera2.CameraCharacteristics; -import android.hardware.camera2.CameraDevice; -import android.hardware.camera2.CameraManager; -import android.hardware.camera2.CaptureRequest; -import android.hardware.camera2.params.StreamConfigurationMap; -import android.os.Handler; -import android.os.HandlerThread; -import android.util.Log; -import android.util.Size; -import android.view.Surface; - -@SuppressLint("NewApi") public class Camera2Renderer extends MyGLRendererBase { - - protected final String LOGTAG = "Camera2Renderer"; - private CameraDevice mCameraDevice; - private CameraCaptureSession mCaptureSession; - private CaptureRequest.Builder mPreviewRequestBuilder; - private String mCameraID; - private Size mPreviewSize = new Size(1280, 720); - - private HandlerThread mBackgroundThread; - private Handler mBackgroundHandler; - private Semaphore mCameraOpenCloseLock = new Semaphore(1); - - Camera2Renderer(MyGLSurfaceView view) { - super(view); - } - - public void onResume() { - stopBackgroundThread(); - super.onResume(); - startBackgroundThread(); - } - - public void onPause() { - super.onPause(); - stopBackgroundThread(); - } - - boolean cacPreviewSize(final int width, final int height) { - Log.i(LOGTAG, "cacPreviewSize: "+width+"x"+height); - if(mCameraID == null) - return false; - CameraManager manager = (CameraManager) mView.getContext() - .getSystemService(Context.CAMERA_SERVICE); - try { - CameraCharacteristics characteristics = manager - .getCameraCharacteristics(mCameraID); - StreamConfigurationMap map = characteristics - .get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP); - int bestWidth = 0, bestHeight = 0; - float aspect = (float)width / height; - for (Size psize : map.getOutputSizes(SurfaceTexture.class)) { - int w = psize.getWidth(), h = psize.getHeight(); - Log.d(LOGTAG, "trying size: "+w+"x"+h); - if ( width >= w && height >= h && - bestWidth <= w && bestHeight <= h && - Math.abs(aspect - (float)w/h) < 0.2 ) { - bestWidth = w; - bestHeight = h; - } - } - Log.i(LOGTAG, "best size: "+bestWidth+"x"+bestHeight); - if( mPreviewSize.getWidth() == bestWidth && - mPreviewSize.getHeight() == bestHeight ) - return false; - else { - mPreviewSize = new Size(bestWidth, bestHeight); - return true; - } - } catch (CameraAccessException e) { - Log.e(LOGTAG, "cacPreviewSize - Camera Access Exception"); - } catch (IllegalArgumentException e) { - Log.e(LOGTAG, "cacPreviewSize - Illegal Argument Exception"); - } catch (SecurityException e) { - Log.e(LOGTAG, "cacPreviewSize - Security Exception"); - } - return false; - } - - protected void openCamera() { - Log.i(LOGTAG, "openCamera"); - //closeCamera(); - CameraManager manager = (CameraManager) mView.getContext() - .getSystemService(Context.CAMERA_SERVICE); - try { - for (String cameraID : manager.getCameraIdList()) { - CameraCharacteristics characteristics = manager - .getCameraCharacteristics(cameraID); - if (characteristics.get(CameraCharacteristics.LENS_FACING) == CameraCharacteristics.LENS_FACING_FRONT) - continue; - - mCameraID = cameraID; - break; - } - if (!mCameraOpenCloseLock.tryAcquire(2500, TimeUnit.MILLISECONDS)) { - throw new RuntimeException( - "Time out waiting to lock camera opening."); - } - manager.openCamera(mCameraID, mStateCallback, mBackgroundHandler); - } catch (CameraAccessException e) { - Log.e(LOGTAG, "OpenCamera - Camera Access Exception"); - } catch (IllegalArgumentException e) { - Log.e(LOGTAG, "OpenCamera - Illegal Argument Exception"); - } catch (SecurityException e) { - Log.e(LOGTAG, "OpenCamera - Security Exception"); - } catch (InterruptedException e) { - Log.e(LOGTAG, "OpenCamera - Interrupted Exception"); - } - } - - protected void closeCamera() { - Log.i(LOGTAG, "closeCamera"); - try { - mCameraOpenCloseLock.acquire(); - if (null != mCaptureSession) { - mCaptureSession.close(); - mCaptureSession = null; - } - if (null != mCameraDevice) { - mCameraDevice.close(); - mCameraDevice = null; - } - } catch (InterruptedException e) { - throw new RuntimeException( - "Interrupted while trying to lock camera closing.", e); - } finally { - mCameraOpenCloseLock.release(); - } - } - - private final CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() { - - @Override - public void onOpened(CameraDevice cameraDevice) { - mCameraDevice = cameraDevice; - mCameraOpenCloseLock.release(); - createCameraPreviewSession(); - } - - @Override - public void onDisconnected(CameraDevice cameraDevice) { - cameraDevice.close(); - mCameraDevice = null; - mCameraOpenCloseLock.release(); - } - - @Override - public void onError(CameraDevice cameraDevice, int error) { - cameraDevice.close(); - mCameraDevice = null; - mCameraOpenCloseLock.release(); - } - - }; - - private void createCameraPreviewSession() { - Log.i(LOGTAG, "createCameraPreviewSession"); - try { - mCameraOpenCloseLock.acquire(); - if (null == mCameraDevice) { - mCameraOpenCloseLock.release(); - Log.e(LOGTAG, "createCameraPreviewSession: camera isn't opened"); - return; - } - if (null != mCaptureSession) { - mCameraOpenCloseLock.release(); - Log.e(LOGTAG, "createCameraPreviewSession: mCaptureSession is already started"); - return; - } - if(null == mSTex) { - mCameraOpenCloseLock.release(); - Log.e(LOGTAG, "createCameraPreviewSession: preview SurfaceTexture is null"); - return; - } - Log.d(LOGTAG, "starting preview "+mPreviewSize.getWidth()+"x"+mPreviewSize.getHeight()); - mSTex.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight()); - - Surface surface = new Surface(mSTex); - - mPreviewRequestBuilder = mCameraDevice - .createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); - mPreviewRequestBuilder.addTarget(surface); - - mCameraDevice.createCaptureSession(Arrays.asList(surface), - new CameraCaptureSession.StateCallback() { - @Override - public void onConfigured( - CameraCaptureSession cameraCaptureSession) { - mCaptureSession = cameraCaptureSession; - try { - mPreviewRequestBuilder - .set(CaptureRequest.CONTROL_AF_MODE, - CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE); - mPreviewRequestBuilder - .set(CaptureRequest.CONTROL_AE_MODE, - CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH); - - mCaptureSession.setRepeatingRequest( - mPreviewRequestBuilder.build(), null, - mBackgroundHandler); - Log.i(LOGTAG, "CameraPreviewSession has been started"); - } catch (CameraAccessException e) { - Log.e(LOGTAG, "createCaptureSession failed"); - } - mCameraOpenCloseLock.release(); - } - - @Override - public void onConfigureFailed( - CameraCaptureSession cameraCaptureSession) { - Log.e(LOGTAG, "createCameraPreviewSession failed"); - mCameraOpenCloseLock.release(); - } - }, mBackgroundHandler); - } catch (CameraAccessException e) { - Log.e(LOGTAG, "createCameraPreviewSession"); - } catch (InterruptedException e) { - throw new RuntimeException( - "Interrupted while createCameraPreviewSession", e); - } - finally { - //mCameraOpenCloseLock.release(); - } - } - - private void startBackgroundThread() { - Log.i(LOGTAG, "startBackgroundThread"); - mBackgroundThread = new HandlerThread("CameraBackground"); - mBackgroundThread.start(); - mBackgroundHandler = new Handler(mBackgroundThread.getLooper()); - } - - private void stopBackgroundThread() { - Log.i(LOGTAG, "stopBackgroundThread"); - if(mBackgroundThread == null) - return; - mBackgroundThread.quitSafely(); - try { - mBackgroundThread.join(); - mBackgroundThread = null; - mBackgroundHandler = null; - } catch (InterruptedException e) { - Log.e(LOGTAG, "stopBackgroundThread"); - } - } - - @Override - protected void setCameraPreviewSize(int width, int height) { - Log.i(LOGTAG, "setCameraPreviewSize("+width+"x"+height+")"); - try { - mCameraOpenCloseLock.acquire(); - if( !cacPreviewSize(width, height) ) { - mCameraOpenCloseLock.release(); - return; - } - if (null != mCaptureSession) { - Log.d(LOGTAG, "closing existing previewSession"); - mCaptureSession.close(); - mCaptureSession = null; - } - mCameraOpenCloseLock.release(); - createCameraPreviewSession(); - } catch (InterruptedException e) { - mCameraOpenCloseLock.release(); - throw new RuntimeException( - "Interrupted while setCameraPreviewSize.", e); - } - } -} diff --git a/samples/android/tutorial-4-opencl/src/org/opencv/samples/tutorial4/CameraRenderer.java b/samples/android/tutorial-4-opencl/src/org/opencv/samples/tutorial4/CameraRenderer.java deleted file mode 100644 index 692ab9884e..0000000000 --- a/samples/android/tutorial-4-opencl/src/org/opencv/samples/tutorial4/CameraRenderer.java +++ /dev/null @@ -1,75 +0,0 @@ -package org.opencv.samples.tutorial4; - -import java.io.IOException; -import java.util.List; - -import android.hardware.Camera; -import android.hardware.Camera.Size; -import android.util.Log; - -@SuppressWarnings("deprecation") -public class CameraRenderer extends MyGLRendererBase { - - protected final String LOGTAG = "CameraRenderer"; - private Camera mCamera; - boolean mPreviewStarted = false; - - CameraRenderer(MyGLSurfaceView view) { - super(view); - } - - protected void closeCamera() { - Log.i(LOGTAG, "closeCamera"); - if(mCamera != null) { - mCamera.stopPreview(); - mPreviewStarted = false; - mCamera.release(); - mCamera = null; - } - } - - protected void openCamera() { - Log.i(LOGTAG, "openCamera"); - closeCamera(); - mCamera = Camera.open(); - try { - mCamera.setPreviewTexture(mSTex); - } catch (IOException ioe) { - Log.e(LOGTAG, "setPreviewTexture() failed: " + ioe.getMessage()); - } - } - - public void setCameraPreviewSize(int width, int height) { - Log.i(LOGTAG, "setCameraPreviewSize: "+width+"x"+height); - if(mCamera == null) - return; - if(mPreviewStarted) { - mCamera.stopPreview(); - mPreviewStarted = false; - } - Camera.Parameters param = mCamera.getParameters(); - List psize = param.getSupportedPreviewSizes(); - int bestWidth = 0, bestHeight = 0; - if (psize.size() > 0) { - float aspect = (float)width / height; - for (Size size : psize) { - int w = size.width, h = size.height; - Log.d("Renderer", "checking camera preview size: "+w+"x"+h); - if ( w <= width && h <= height && - w >= bestWidth && h >= bestHeight && - Math.abs(aspect - (float)w/h) < 0.2 ) { - bestWidth = w; - bestHeight = h; - } - } - if(bestWidth > 0 && bestHeight > 0) { - param.setPreviewSize(bestWidth, bestHeight); - Log.i(LOGTAG, "size: "+bestWidth+" x "+bestHeight); - } - } - param.set("orientation", "landscape"); - mCamera.setParameters(param); - mCamera.startPreview(); - mPreviewStarted = true; - } -} diff --git a/samples/android/tutorial-4-opencl/src/org/opencv/samples/tutorial4/MyGLRendererBase.java b/samples/android/tutorial-4-opencl/src/org/opencv/samples/tutorial4/MyGLRendererBase.java deleted file mode 100644 index f3abe87b39..0000000000 --- a/samples/android/tutorial-4-opencl/src/org/opencv/samples/tutorial4/MyGLRendererBase.java +++ /dev/null @@ -1,117 +0,0 @@ -package org.opencv.samples.tutorial4; - -import javax.microedition.khronos.egl.EGLConfig; -import javax.microedition.khronos.opengles.GL10; - -import android.graphics.SurfaceTexture; -import android.opengl.GLES20; -import android.opengl.GLSurfaceView; -import android.os.Handler; -import android.os.Looper; -import android.util.Log; -import android.widget.TextView; - -public abstract class MyGLRendererBase implements GLSurfaceView.Renderer, SurfaceTexture.OnFrameAvailableListener { - protected final String LOGTAG = "MyGLRendererBase"; - protected int frameCounter; - protected long lastNanoTime; - - protected SurfaceTexture mSTex; - protected MyGLSurfaceView mView; - protected TextView mFpsText; - - protected boolean mGLInit = false; - protected boolean mTexUpdate = false; - - MyGLRendererBase(MyGLSurfaceView view) { - mView = view; - } - - protected abstract void openCamera(); - protected abstract void closeCamera(); - protected abstract void setCameraPreviewSize(int width, int height); - - public void setFpsTextView(TextView fpsTV) - { - mFpsText = fpsTV; - } - - public void onResume() { - Log.i(LOGTAG, "onResume"); - frameCounter = 0; - lastNanoTime = System.nanoTime(); - } - - public void onPause() { - Log.i(LOGTAG, "onPause"); - mGLInit = false; - mTexUpdate = false; - closeCamera(); - if(mSTex != null) { - mSTex.release(); - mSTex = null; - NativeGLRenderer.closeGL(); - } - } - - @Override - public synchronized void onFrameAvailable(SurfaceTexture surfaceTexture) { - //Log.i(LOGTAG, "onFrameAvailable"); - mTexUpdate = true; - mView.requestRender(); - } - - @Override - public void onDrawFrame(GL10 gl) { - //Log.i(LOGTAG, "onDrawFrame"); - if (!mGLInit) - return; - - synchronized (this) { - if (mTexUpdate) { - mSTex.updateTexImage(); - mTexUpdate = false; - } - } - NativeGLRenderer.drawFrame(); - - // log FPS - frameCounter++; - if(frameCounter >= 10) - { - final int fps = (int) (frameCounter * 1e9 / (System.nanoTime() - lastNanoTime)); - Log.i(LOGTAG, "drawFrame() FPS: "+fps); - if(mFpsText != null) { - Runnable fpsUpdater = new Runnable() { - public void run() { - mFpsText.setText("FPS: " + fps); - } - }; - new Handler(Looper.getMainLooper()).post(fpsUpdater); - } - frameCounter = 0; - lastNanoTime = System.nanoTime(); - } - } - - @Override - public void onSurfaceChanged(GL10 gl, int surfaceWidth, int surfaceHeight) { - Log.i(LOGTAG, "onSurfaceChanged("+surfaceWidth+"x"+surfaceHeight+")"); - NativeGLRenderer.changeSize(surfaceWidth, surfaceHeight); - setCameraPreviewSize(surfaceWidth, surfaceHeight); - } - - @Override - public void onSurfaceCreated(GL10 gl, EGLConfig config) { - Log.i(LOGTAG, "onSurfaceCreated"); - String strGLVersion = GLES20.glGetString(GLES20.GL_VERSION); - if (strGLVersion != null) - Log.i(LOGTAG, "OpenGL ES version: " + strGLVersion); - - int hTex = NativeGLRenderer.initGL(); - mSTex = new SurfaceTexture(hTex); - mSTex.setOnFrameAvailableListener(this); - openCamera(); - mGLInit = true; - } -} diff --git a/samples/android/tutorial-4-opencl/src/org/opencv/samples/tutorial4/MyGLSurfaceView.java b/samples/android/tutorial-4-opencl/src/org/opencv/samples/tutorial4/MyGLSurfaceView.java index 8556b41816..edaf34631c 100644 --- a/samples/android/tutorial-4-opencl/src/org/opencv/samples/tutorial4/MyGLSurfaceView.java +++ b/samples/android/tutorial-4-opencl/src/org/opencv/samples/tutorial4/MyGLSurfaceView.java @@ -1,59 +1,29 @@ package org.opencv.samples.tutorial4; +import org.opencv.android.CameraGLSurfaceView; + import android.app.Activity; import android.content.Context; -import android.opengl.GLSurfaceView; +import android.os.Handler; +import android.os.Looper; import android.util.AttributeSet; +import android.util.Log; import android.view.MotionEvent; import android.view.SurfaceHolder; import android.widget.TextView; +import android.widget.Toast; -public class MyGLSurfaceView extends GLSurfaceView { +public class MyGLSurfaceView extends CameraGLSurfaceView implements CameraGLSurfaceView.CameraTextureListener { - MyGLRendererBase mRenderer; + static final String LOGTAG = "MyGLSurfaceView"; + protected int procMode = NativePart.PROCESSING_MODE_NO_PROCESSING; + static final String[] procModeName = new String[] {"No Processing", "CPU", "OpenCL Direct", "OpenCL via OpenCV"}; + protected int frameCounter; + protected long lastNanoTime; + TextView mFpsText = null; public MyGLSurfaceView(Context context, AttributeSet attrs) { super(context, attrs); - - if(android.os.Build.VERSION.SDK_INT >= 21) - mRenderer = new Camera2Renderer(this); - else - mRenderer = new CameraRenderer(this); - - setEGLContextClientVersion(2); - setRenderer(mRenderer); - setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY); - } - - public void setFpsTextView(TextView tv) { - mRenderer.setFpsTextView(tv); - } - - @Override - public void surfaceCreated(SurfaceHolder holder) { - super.surfaceCreated(holder); - } - - @Override - public void surfaceDestroyed(SurfaceHolder holder) { - super.surfaceDestroyed(holder); - } - - @Override - public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { - super.surfaceChanged(holder, format, w, h); - } - - @Override - public void onResume() { - super.onResume(); - mRenderer.onResume(); - } - - @Override - public void onPause() { - mRenderer.onPause(); - super.onPause(); } @Override @@ -62,4 +32,81 @@ public class MyGLSurfaceView extends GLSurfaceView { ((Activity)getContext()).openOptionsMenu(); return true; } + + @Override + public void surfaceCreated(SurfaceHolder holder) { + super.surfaceCreated(holder); + //NativePart.initCL(); + } + + @Override + public void surfaceDestroyed(SurfaceHolder holder) { + //NativePart.closeCL(); + super.surfaceDestroyed(holder); + } + + public void setProcessingMode(int newMode) { + if(newMode>=0 && newMode= 30) + { + final int fps = (int) (frameCounter * 1e9 / (System.nanoTime() - lastNanoTime)); + Log.i(LOGTAG, "drawFrame() FPS: "+fps); + if(mFpsText != null) { + Runnable fpsUpdater = new Runnable() { + public void run() { + mFpsText.setText("FPS: " + fps); + } + }; + new Handler(Looper.getMainLooper()).post(fpsUpdater); + } else { + Log.d(LOGTAG, "mFpsText == null"); + mFpsText = (TextView)((Activity) getContext()).findViewById(R.id.fps_text_view); + } + frameCounter = 0; + lastNanoTime = System.nanoTime(); + } + + + if(procMode == NativePart.PROCESSING_MODE_NO_PROCESSING) + return false; + + NativePart.processFrame(texIn, texOut, width, height, procMode); + return true; + } } diff --git a/samples/android/tutorial-4-opencl/src/org/opencv/samples/tutorial4/NativeGLRenderer.java b/samples/android/tutorial-4-opencl/src/org/opencv/samples/tutorial4/NativePart.java similarity index 51% rename from samples/android/tutorial-4-opencl/src/org/opencv/samples/tutorial4/NativeGLRenderer.java rename to samples/android/tutorial-4-opencl/src/org/opencv/samples/tutorial4/NativePart.java index 8d9216c97c..e5f11ba3ae 100644 --- a/samples/android/tutorial-4-opencl/src/org/opencv/samples/tutorial4/NativeGLRenderer.java +++ b/samples/android/tutorial-4-opencl/src/org/opencv/samples/tutorial4/NativePart.java @@ -1,10 +1,10 @@ package org.opencv.samples.tutorial4; -public class NativeGLRenderer { +public class NativePart { static { System.loadLibrary("opencv_java3"); - System.loadLibrary("JNIrender"); + System.loadLibrary("JNIpart"); } public static final int PROCESSING_MODE_NO_PROCESSING = 0; @@ -12,9 +12,7 @@ public class NativeGLRenderer { public static final int PROCESSING_MODE_OCL_DIRECT = 2; public static final int PROCESSING_MODE_OCL_OCV = 3; - public static native int initGL(); - public static native void closeGL(); - public static native void drawFrame(); - public static native void changeSize(int width, int height); - public static native void setProcessingMode(int mode); + public static native int initCL(); + public static native void closeCL(); + public static native void processFrame(int tex1, int tex2, int w, int h, int mode); } diff --git a/samples/android/tutorial-4-opencl/src/org/opencv/samples/tutorial4/Tutorial4Activity.java b/samples/android/tutorial-4-opencl/src/org/opencv/samples/tutorial4/Tutorial4Activity.java index 56b416c808..0be55df65e 100644 --- a/samples/android/tutorial-4-opencl/src/org/opencv/samples/tutorial4/Tutorial4Activity.java +++ b/samples/android/tutorial-4-opencl/src/org/opencv/samples/tutorial4/Tutorial4Activity.java @@ -29,8 +29,8 @@ public class Tutorial4Activity extends Activity { //setContentView(mView); setContentView(R.layout.activity); mView = (MyGLSurfaceView) findViewById(R.id.my_gl_surface_view); + mView.setCameraTextureListener(mView); TextView tv = (TextView)findViewById(R.id.fps_text_view); - mView.setFpsTextView(tv); mProcMode = (TextView)findViewById(R.id.proc_mode_text_view); runOnUiThread(new Runnable() { public void run() { @@ -38,7 +38,8 @@ public class Tutorial4Activity extends Activity { } }); - NativeGLRenderer.setProcessingMode(NativeGLRenderer.PROCESSING_MODE_NO_PROCESSING); } + mView.setProcessingMode(NativePart.PROCESSING_MODE_NO_PROCESSING); + } @Override protected void onPause() { @@ -68,7 +69,7 @@ public class Tutorial4Activity extends Activity { mProcMode.setText("Processing mode: No Processing"); } }); - NativeGLRenderer.setProcessingMode(NativeGLRenderer.PROCESSING_MODE_NO_PROCESSING); + mView.setProcessingMode(NativePart.PROCESSING_MODE_NO_PROCESSING); return true; case R.id.cpu: runOnUiThread(new Runnable() { @@ -76,7 +77,7 @@ public class Tutorial4Activity extends Activity { mProcMode.setText("Processing mode: CPU"); } }); - NativeGLRenderer.setProcessingMode(NativeGLRenderer.PROCESSING_MODE_CPU); + mView.setProcessingMode(NativePart.PROCESSING_MODE_CPU); return true; case R.id.ocl_direct: runOnUiThread(new Runnable() { @@ -84,7 +85,7 @@ public class Tutorial4Activity extends Activity { mProcMode.setText("Processing mode: OpenCL direct"); } }); - NativeGLRenderer.setProcessingMode(NativeGLRenderer.PROCESSING_MODE_OCL_DIRECT); + mView.setProcessingMode(NativePart.PROCESSING_MODE_OCL_DIRECT); return true; case R.id.ocl_ocv: runOnUiThread(new Runnable() { @@ -92,7 +93,7 @@ public class Tutorial4Activity extends Activity { mProcMode.setText("Processing mode: OpenCL via OpenCV (TAPI)"); } }); - NativeGLRenderer.setProcessingMode(NativeGLRenderer.PROCESSING_MODE_OCL_OCV); + mView.setProcessingMode(NativePart.PROCESSING_MODE_OCL_OCV); return true; default: return false;